summaryrefslogtreecommitdiff
path: root/Build/source/texk/texlive
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/texk/texlive
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/texlive')
-rw-r--r--Build/source/texk/texlive/ChangeLog250
-rw-r--r--Build/source/texk/texlive/Makefile.am22
-rw-r--r--Build/source/texk/texlive/Makefile.in1133
-rw-r--r--Build/source/texk/texlive/ac/texlive.ac11
-rw-r--r--Build/source/texk/texlive/ac/withenable.ac8
-rw-r--r--Build/source/texk/texlive/aclocal.m41169
-rwxr-xr-xBuild/source/texk/texlive/configure4967
-rw-r--r--Build/source/texk/texlive/configure.ac36
-rw-r--r--Build/source/texk/texlive/linked_scripts/ChangeLog287
-rw-r--r--Build/source/texk/texlive/linked_scripts/Makefile.am387
-rw-r--r--Build/source/texk/texlive/linked_scripts/Makefile.in811
-rw-r--r--Build/source/texk/texlive/linked_scripts/README31
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/a2ping/a2ping.pl2584
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/accfonts/mkt1font1012
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/accfonts/vpl2ovp1085
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/accfonts/vpl2vpl994
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/adhocfilelist/adhocfilelist.sh212
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/albatross/albatross.sh17
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/arara/arara.sh17
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/attachfile2/pdfatfi.pl218
-rw-r--r--Build/source/texk/texlive/linked_scripts/authorindex/authorindex586
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/bib2gls/bib2gls.sh22
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/bib2gls/convertgls2bib.sh15
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/bibexport/bibexport.sh350
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/bundledoc/arlatex288
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/bundledoc/bundledoc905
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/cachepic/cachepic.tlu231
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/checkcites/checkcites.lua869
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/checklistings/checklistings.sh446
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/chklref/chklref.pl337
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/cjk-gs-integrate/cjk-gs-integrate.pl2861
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/clojure-pamphlet/pamphletangler170
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/cluttex/cluttex.lua3541
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl166
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/context2
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/contextjit5
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/ctxtools2
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/luatools2
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun27647
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrunjit5
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/pstopdf2
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/texexec2
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/context/stubs/unix/texmfstart2
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/convbkmk/convbkmk.rb584
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/crossrefware/bbl2bib.pl350
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/crossrefware/bibdoiadd.pl299
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/crossrefware/bibmradd.pl212
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/crossrefware/biburl2doi.pl136
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/crossrefware/bibzbladd.pl205
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/crossrefware/ltx2crossrefxml.pl461
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat21
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl801
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ctanbib/ctanbib204
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ctanify/ctanify716
-rw-r--r--Build/source/texk/texlive/linked_scripts/ctanupload/ctanupload.pl554
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/de-macro/de-macro1097
-rw-r--r--Build/source/texk/texlive/linked_scripts/diadia/diadia.lua298
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/dosepsbin/dosepsbin.pl457
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/dtxgen/dtxgen462
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/dviasm/dviasm.py1259
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/dviinfox/dviinfox.pl366
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ebong/ebong.py346
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/epspdf/epspdf.tlu2690
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/epspdf/epspdftk.tcl756
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/epstopdf/epstopdf.pl1006
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/exceltex/exceltex824
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fig4latex/fig4latex158
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/findhyph/findhyph422
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/afm2afm500
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/autoinst4510
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/ot2kpx932
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fragmaster/fragmaster.pl569
-rw-r--r--Build/source/texk/texlive/linked_scripts/getmap/getmapdl.lua870
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/git-latexdiff/git-latexdiff907
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/glossaries/makeglossaries1679
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/glossaries/makeglossaries-lite.lua563
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl219
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/installfont/installfont-tl614
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl3456
-rw-r--r--Build/source/texk/texlive/linked_scripts/ketcindy/ketcindy.pl203
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/kotex-utils/jamo-normalize.pl6648
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/kotex-utils/komkindex.pl917
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/kotex-utils/ttf2kotexfont.pl818
-rw-r--r--Build/source/texk/texlive/linked_scripts/l3build/l3build.lua197
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latex-git-log/latex-git-log370
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latex-papersize/latex-papersize.py216
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latex2man/latex2man2052
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latex2nemeth/latex2nemeth3
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexdiff/latexdiff-vc.pl824
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexdiff/latexdiff.pl5643
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexdiff/latexrevise.pl556
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexfileversion/latexfileversion118
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexindent/latexindent.pl81
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexmk/latexmk.pl10187
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexpand/latexpand665
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/light-latex-make/llmk.lua1559
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/lilyglyphs/lily-glyph-commands.py136
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/lilyglyphs/lily-image-commands.py321
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/lilyglyphs/lily-rebuild-pdfs.py142
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/listbib/listbib245
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/listings-ext/listings-ext.sh359
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ltxfileinfo/ltxfileinfo421
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ltximg/ltximg.pl3284
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua1645
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/lwarp/lwarpmk.lua914
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/m-tx/m-tx.lua5
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/make4ht/make4ht126
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/makedtx/makedtx.pl1022
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/match_parens/match_parens214
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/mathspic/mathspic.pl3336
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/mf2pt1/mf2pt1.pl1091
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/mkgrkindex/mkgrkindex289
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/mkjobtexmf/mkjobtexmf.pl995
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/mkpic/mkpic864
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/multibibliography/multibibliography.pl154
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/musixtex/musixflx.lua1071
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/musixtex/musixtex.lua634
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pax/pdfannotextractor.pl433
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2318
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pdfcrop/pdfcrop.pl1263
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pdfjam/pdfjam1292
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pdflatexpicscale/pdflatexpicscale.pl258
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pdftex-quiet/pdftex-quiet120
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pdfxup/pdfxup1587
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pedigree-perl/pedigree.pl544
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/perltex/perltex.pl503
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/petri-nets/pn2pdf211
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pfarrei/a5toa4.tlu37
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pfarrei/pfarrei.tlu153
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pkfix-helper/pkfix-helper1826
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pkfix/pkfix.pl886
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pmxchords/pmxchords.lua244
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pst-pdf/ps4pdf157
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pst2pdf/pst2pdf.pl2303
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-sys.sh24
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-user.sh24
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap.pl583
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-fontmap-creator.pl590
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ptex2pdf/ptex2pdf.lua497
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/purifyeps/purifyeps529
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pygmentex/pygmentex.py516
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pythontex/depythontex.py23
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pythontex/pythontex.py62
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/rubik/rubikrotation.pl2926
-rw-r--r--Build/source/texk/texlive/linked_scripts/scripts.lst190
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/simpdftex/simpdftex669
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/spix/spix.py145
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/splitindex/splitindex.pl212
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/srcredact/srcredact.pl521
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl1085
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/svn-multi/svn-multi.pl372
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook204
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texcount/texcount.pl4017
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texdef/texdef.pl950
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texdiff/texdiff554
-rw-r--r--Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten411
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texdoc/texdoc.tlu47
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texfot/texfot.pl422
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/allcm.sh118
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/allneeded.sh46
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/dvi2fax.sh41
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/dvired.sh98
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/e2pall.pl89
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/fontinst.sh16
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/kpsetool.sh118
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/kpsewhere.sh63
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/ps2frag.sh11
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/pslatex.sh46
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/rubibtex.sh110
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/rumakeindex.sh77
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/texconfig-dialog.sh496
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/texconfig-sys.sh33
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/texconfig.sh1449
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive-extra/texlinks.sh333
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/fmtutil-sys.sh25
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/fmtutil-user.sh25
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/fmtutil.pl1488
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/mktexlsr236
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/mktexmf151
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/mktexpk284
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/mktextfm182
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/rungs.tlu43
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/tlmgr.pl10130
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/updmap-sys.sh25
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/updmap-user.sh25
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlive/updmap.pl2542
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texliveonfly/texliveonfly.py384
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texloganalyser/texloganalyser426
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texosquery/texosquery4
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh15
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh15
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texosquery/texosquery.sh15
-rw-r--r--Build/source/texk/texlive/linked_scripts/texplate/texplate.sh17
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/thumbpdf/thumbpdf.pl1604
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/tikztosvg/tikztosvg203
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/tlcockpit/tlcockpit.sh20
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/tlshell/tlshell.tcl2761
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/typeoutfileinfo/typeoutfileinfo.sh52
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ulqda/ulqda.pl295
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/urlbst/urlbst889
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/vpe/vpe.pl430
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/webquiz/webquiz.py1124
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/wordcount/wordcount.sh79
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/xindex/xindex.lua252
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/yplan/yplan326
-rwxr-xr-xBuild/source/texk/texlive/tests/updmap-cmdline-test.pl21
-rw-r--r--Build/source/texk/texlive/tl_support/ChangeLog906
-rw-r--r--Build/source/texk/texlive/tl_support/Makefile.am101
-rw-r--r--Build/source/texk/texlive/tl_support/Makefile.in707
-rw-r--r--Build/source/texk/texlive/tl_support/README13
-rw-r--r--Build/source/texk/texlive/tl_support/allcm.128
-rw-r--r--Build/source/texk/texlive/tl_support/allec.128
-rw-r--r--Build/source/texk/texlive/tl_support/allneeded.130
-rw-r--r--Build/source/texk/texlive/tl_support/dvi2fax.122
-rw-r--r--Build/source/texk/texlive/tl_support/dvired.163
-rw-r--r--Build/source/texk/texlive/tl_support/e2pall.155
-rw-r--r--Build/source/texk/texlive/tl_support/fmtutil.1196
-rw-r--r--Build/source/texk/texlive/tl_support/fmtutil.cnf158
-rw-r--r--Build/source/texk/texlive/tl_support/fmtutil.cnf.577
-rw-r--r--Build/source/texk/texlive/tl_support/fmtutil.help2man22
-rw-r--r--Build/source/texk/texlive/tl_support/fontinst.145
-rw-r--r--Build/source/texk/texlive/tl_support/kpsetool.1106
-rw-r--r--Build/source/texk/texlive/tl_support/kpsewhere.150
-rw-r--r--Build/source/texk/texlive/tl_support/mktexlsr.149
-rw-r--r--Build/source/texk/texlive/tl_support/mktexmf.162
-rw-r--r--Build/source/texk/texlive/tl_support/mktexpk.1120
-rw-r--r--Build/source/texk/texlive/tl_support/mktextfm.192
-rw-r--r--Build/source/texk/texlive/tl_support/ps2frag.141
-rw-r--r--Build/source/texk/texlive/tl_support/pslatex.144
-rw-r--r--Build/source/texk/texlive/tl_support/rubibtex.163
-rw-r--r--Build/source/texk/texlive/tl_support/rumakeindex.163
-rwxr-xr-xBuild/source/texk/texlive/tl_support/tcfmgr391
-rw-r--r--Build/source/texk/texlive/tl_support/tcfmgr.map9
-rw-r--r--Build/source/texk/texlive/tl_support/texconfig.1216
-rw-r--r--Build/source/texk/texlive/tl_support/texlinks.166
-rw-r--r--Build/source/texk/texlive/tl_support/updmap.1374
-rw-r--r--Build/source/texk/texlive/tl_support/updmap.cfg.5155
-rw-r--r--Build/source/texk/texlive/tl_support/updmap.help2man106
-rw-r--r--Build/source/texk/texlive/w32_wrapper/README8
-rw-r--r--Build/source/texk/texlive/w32_wrapper/bitmap2eps.icobin3262 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w32_wrapper/bitmap2eps.svg525
-rw-r--r--Build/source/texk/texlive/w32_wrapper/calldll.c13
-rw-r--r--Build/source/texk/texlive/w32_wrapper/callexe.c43
-rwxr-xr-xBuild/source/texk/texlive/w32_wrapper/context/mtxrun.dllbin7680 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w32_wrapper/context/mtxrun.exebin4608 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w32_wrapper/context/mtxrun_dll.c306
-rw-r--r--Build/source/texk/texlive/w32_wrapper/context/mtxrun_exe.c8
-rw-r--r--Build/source/texk/texlive/w32_wrapper/context/readme.txt40
-rw-r--r--Build/source/texk/texlive/w32_wrapper/readme.txt225
-rwxr-xr-xBuild/source/texk/texlive/w32_wrapper/runscript.dllbin3584 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w32_wrapper/runscript.exebin1536 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w32_wrapper/runscript.tlu941
-rw-r--r--Build/source/texk/texlive/w32_wrapper/runscript_dll.c121
-rw-r--r--Build/source/texk/texlive/w32_wrapper/runscript_exe.c15
-rw-r--r--Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c348
-rw-r--r--Build/source/texk/texlive/w32_wrapper/tlmgr-gui.txt77
-rw-r--r--Build/source/texk/texlive/w32_wrapper/tlmgr.icobin4286 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w32_wrapper/tlmgr.svg245
-rw-r--r--Build/source/texk/texlive/w32_wrapper/wrunscript_exe.c27
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/README8
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.icobin3262 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg525
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/calldll.c13
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/callexe.c43
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dllbin7680 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exebin4608 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c306
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c8
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt40
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dllbin112742 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/readme.txt229
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/runscript.dllbin17920 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/runscript.exebin16384 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/runscript.tlu928
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c127
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/runscript_exe.c15
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/texlua.dllbin255860 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w64_mingw_wrapper/texlua.exebin6250496 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c310
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt77
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.icobin4286 -> 0 bytes
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg245
-rw-r--r--Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c27
-rwxr-xr-xBuild/source/texk/texlive/w64_wrapper/context/mtxrun.dllbin18432 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w64_wrapper/context/mtxrun.exebin15360 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w64_wrapper/runscript.dllbin16896 -> 0 bytes
-rwxr-xr-xBuild/source/texk/texlive/w64_wrapper/runscript.exebin16896 -> 0 bytes
287 files changed, 0 insertions, 196776 deletions
diff --git a/Build/source/texk/texlive/ChangeLog b/Build/source/texk/texlive/ChangeLog
deleted file mode 100644
index 5d696ffd237..00000000000
--- a/Build/source/texk/texlive/ChangeLog
+++ /dev/null
@@ -1,250 +0,0 @@
-2020-01-31 Karl Berry <karl@tug.org>
-
-
- * tl_support: rename subdirectory from tl_scripts, since there is
- only one (sub)script list.
- * configure.ac (AC_CONFIG_FILES): change generation.
-
-2015-07-10 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Better dependencies for 'make check'.
-
-2014-11-18 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * w64_wrapper/runscript.{dll,exe}: Now compiled with Mingw64 to
- make them independent from msvcr100.dll.
-
-2014-11-17 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * w64_wrapper: Directory with WIN64 executables.
- * Makefile.am: Add the new directory.
-
-2014-07-15 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * w32_wrapper/callexe.c: Replace the deprecated spawnvp() by
- _spawnvp(), they differ for 64-bit MinGW.
-
-2014-06-16 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Drop the obsolete ACLOCAL_AMFLAGS.
-
-2013-12-19 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * ac/texlive.ac: New file for '--disable-linked-scripts'.
- * Makefile.am, ac/withenable.ac, configure.ac: Add a configure
- option to skip the linked scripts and still run texlinks.
-
-2013-07-05 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tl_scripts/Makefile.am: Moved Makefile fragments to ../../am/.
-
-2013-04-19 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tests/updmap-cmdline-test.pl: Adapt to updmap.pl again moved.
-
-2013-04-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am, configure.ac: Drop subdirectory context/.
-
-2013-01-24 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tests/updmap-cmdline-test.pl: Adapt to updmap.pl now moved.
-
-2013-01-24 Karl Berry <karl@tug.org>
-
- * tl_scripts: new subdir.
- * Makefile.am (SUBDIRS): add it.
- * configure.ac (AC_CONFIG_FILES): output its Makefile.
- (WIN32_WRAP): new conditional.
-
-2012-08-13 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * w32_wrapper/runscript.dll (new): DLL for runscript.exe.
- * w32_wrapper/context/* (new): ConTeXt wrapper (src and bin).
-
-2012-08-07 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tests/ (new): Moved from ../tetex/ to here and adapted.
- * Makefile.am: Adapted.
-
-2012-04-15 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tests/ (removed): Moved from here to ../tetex/.
- * Makefile.am: Adapted.
-
-2012-04-14 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tests/ (new): Moved from ../tetex/ to here and adapted.
- * Makefile.am: Adapted.
-
-2011-09-10 Reinhard Kotucha <reinhard.kotucha@web.de>
-
- * w32_wrapper/runscript.tlu: added -dDisableFAPI=true to psview
- argument list. Needed by gs-9.xx
-
-2010-12-22 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * configure.ac: Added KPSE_CHECK_WIN32.
- * context/{ctxtools,mptopdf,pstopdf,texexec,texmfstart}.man:
- Moved from ../tetex/context/ to here.
- * context/Makefile.am: Adapted.
- For WIN32 skip the shell scripts.
-
-2010-05-30 Karl Berry <karl@tug.org>
-
- * configure.ac: add context subdir, 2010.
- * context: new subdir.
-
-2009-12-14 Karl Berry <karl@tug.org>
-
- * *.bat, old format scripts: remove, obsolete.
- * Makefile.am: don't distribute them.
-
-2009-09-22 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tl-w32-starter.bat (removed): Replaced ...
- * tl-w32-wrapper.cmd (new): ... by this.
- * Makefile.am (EXTRA_DIST): Adapted.
-
-2009-11-25 Karl Berry <karl@tug.org>
-
- * Makefile.am (dist_man1_MANS): remove this, as getnonfreefonts
- will now be separate from TeX Live.
-
-2009-09-22 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * runscript*, Makefile.am: New version of Win32 wrapper.
-
-2009-09-16 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * runscript.{c,exe} (new): Win32 wrapper.
- * Makefile.am: Add the new files.
-
-2009-07-25 Karl Berry <karl@tug.org>
-
- * tl-w32-starter.bat: fix inconsistent "copyright" and "public domain".
-
-2009-05-07 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- Adapt to TL2009 build system.
-
-2009-04-03 Karl Berry <karl@tug.org>
-
- * Makefile.am (EXTRA_DIST): remove texdoc.man from list.
- * texdoc.man: remove file; maintained separately now
- (http://tug.org/texdoc)
-
-2009-03-29 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): perltex name.
-
-2009-03-28 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add splitindex.pl.
-
-2009-03-24 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add svn-multi.pl.
-
-2009-03-23 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add purifyeps, pkfix-helper,
- fragmaster.pl.
-
-2009-03-10 Karl Berry <karl@tug.org>
-
- * Makefile.in (install-exec): also make a link to our man
- directory, ../../texmf/doc/man, for the sake of those man programs
- which can use it. Suggested by Dick Koch.
-
-2009-02-26 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add texloganalyser.
-
-2008-11-13 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add latex2man.
-
-2008-10-12 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add latexmk.pl.
-
-2008-10-06 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): pdfannotextractor now has a .pl
- wrapper from Heiko.
-
-2008-09-28 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): mtxrun and luatools now link to
- the .lua files instead of stubs. tldev mail from mojca,
- 25 Sep 2008 11:38:14.
-
-2008-07-11 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): mistyped epsf for eps.
-
-2008-07-04 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add pst2pdf.pl.
-
-2008-06-03 Karl Berry <karl@tug.org>
-
- * Makefile.in (install-linked-scripts): call tr with '[A-Z]' '[a-z]'
- instead of just A-Z. Perhaps it will be more portable.
-
-2008-06-01 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add rungs.tlu.
-
-2008-05-25 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add dviasm.py
-
-2008-05-20 Karl Berry <karl@tug.org>
-
- * wordcount.sh: remove, since we have texcount (TeXcount.pl)
- and the license of wordcount.sh is problematic.
- * Makefile.in (LIVESCRIPTS): remove wordcount.sh
-
-2008-05-19 Karl Berry <karl@tug.org>
-
- * Makefile.in (LIVESCRIPTS): remove pdfthumb, we want the one in
- LINKED_SCRIPTS. Ditto getnonfreefonts.
-
- * vpe,
- * texdoc: remove, the masters are in texmf/scripts now.
- * pdfthumb: remove, we use the lua wrapper now.
-
-2008-05-18 Karl Berry <karl@tug.org>
-
- * Makefile.in (install-linked-scripts): change from Peter M to
- support non-multiplatform builds.
-
-2008-05-11 Norbert Preining <preining@logic.at>
-
- * Makefile.in: add texdoc.tlu to the LINKED_SCRIPTS, it will
- replace texdoc from tetex.
-
-2008-05-06 Karl Berry <karl@tug.org>
-
- * ebong: need #!/usr/bin/env python. From vvv.
-
-2008-03-14 Karl Berry <karl@tug.org>
-
- * ppower4: remove.
- * Makefile: don't install it. (Symlink installed in
- tetex/Makefile.in instead.)
-
-2008-02-29 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * configure.in: added AC_CONFIG_HEADERS (moved
- from ../kpathsea/common.ac to here) and
- updated (AC_SET_MAKE -> AC_PROG_MAKE_SET).
-
-2008-01-30 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- Convert from autoconf-2.13 to autoconf-2.59+:
- * Makefile.in: Add @configure_input@ line.
- * aclocal.m4 (new): Generated (aclocal -I ../m4).
- * configure: Regenerated (autoconf).
diff --git a/Build/source/texk/texlive/Makefile.am b/Build/source/texk/texlive/Makefile.am
deleted file mode 100644
index ccf19b0e11d..00000000000
--- a/Build/source/texk/texlive/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-## $Id$
-## Makefile.am for the TeX Live subdirectory texk/texlive/
-##
-## Copyright 2015-2020 Karl Berry <tex-live@tug.org>
-## Copyright 2009-2014 Peter Breitenlohner <tex-live@tug.org>
-## You may freely use, modify and/or distribute this file.
-##
-SUBDIRS = tl_support
-if LINKED_SCRIPTS
-SUBDIRS += linked_scripts
-endif LINKED_SCRIPTS
-
-## Windows wrapper and sources.
-##
-EXTRA_DIST = w32_wrapper w64_wrapper
-
-## Tests
-##
-TEST_EXTENSIONS = .pl
-TESTS = tests/updmap-cmdline-test.pl
-EXTRA_DIST += $(TESTS)
-
diff --git a/Build/source/texk/texlive/Makefile.in b/Build/source/texk/texlive/Makefile.in
deleted file mode 100644
index 8a39ffd8c6c..00000000000
--- a/Build/source/texk/texlive/Makefile.in
+++ /dev/null
@@ -1,1133 +0,0 @@
-# Makefile.in generated by automake 1.16.3 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-@LINKED_SCRIPTS_TRUE@am__append_1 = linked_scripts
-subdir = .
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../../m4/kpse-win32.m4 \
- $(top_srcdir)/../../version.ac $(top_srcdir)/ac/texlive.ac \
- $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
- $(am__configure_deps) $(am__DIST_COMMON)
-am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
- configure.lineno config.status.lineno
-mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 =
-SOURCES =
-DIST_SOURCES =
-RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
- ctags-recursive dvi-recursive html-recursive info-recursive \
- install-data-recursive install-dvi-recursive \
- install-exec-recursive install-html-recursive \
- install-info-recursive install-pdf-recursive \
- install-ps-recursive install-recursive installcheck-recursive \
- installdirs-recursive pdf-recursive ps-recursive \
- tags-recursive uninstall-recursive
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
- distclean-recursive maintainer-clean-recursive
-am__recursive_targets = \
- $(RECURSIVE_TARGETS) \
- $(RECURSIVE_CLEAN_TARGETS) \
- $(am__extra_recursive_targets)
-AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
- cscope check recheck distdir distdir-am dist dist-all \
- distcheck
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-# Read a list of newline-separated strings from the standard input,
-# and print each of them once, without duplicates. Input order is
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
- BEGIN { nonempty = 0; } \
- { items[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique. This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
- list='$(am__tagged_files)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-CSCOPE = cscope
-am__tty_colors_dummy = \
- mgn= red= grn= lgn= blu= brg= std=; \
- am__color_tests=no
-am__tty_colors = { \
- $(am__tty_colors_dummy); \
- if test "X$(AM_COLOR_TESTS)" = Xno; then \
- am__color_tests=no; \
- elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
- am__color_tests=yes; \
- elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
- am__color_tests=yes; \
- fi; \
- if test $$am__color_tests = yes; then \
- red=''; \
- grn=''; \
- lgn=''; \
- blu=''; \
- mgn=''; \
- brg=''; \
- std=''; \
- fi; \
-}
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
- test -z "$$files" \
- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
- $(am__cd) "$$dir" && rm -f $$files; }; \
- }
-am__recheck_rx = ^[ ]*:recheck:[ ]*
-am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
-am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
-# A command that, given a newline-separated list of test names on the
-# standard input, print the name of the tests that are to be re-run
-# upon "make recheck".
-am__list_recheck_tests = $(AWK) '{ \
- recheck = 1; \
- while ((rc = (getline line < ($$0 ".trs"))) != 0) \
- { \
- if (rc < 0) \
- { \
- if ((getline line2 < ($$0 ".log")) < 0) \
- recheck = 0; \
- break; \
- } \
- else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
- { \
- recheck = 0; \
- break; \
- } \
- else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
- { \
- break; \
- } \
- }; \
- if (recheck) \
- print $$0; \
- close ($$0 ".trs"); \
- close ($$0 ".log"); \
-}'
-# A command that, given a newline-separated list of test names on the
-# standard input, create the global log from their .trs and .log files.
-am__create_global_log = $(AWK) ' \
-function fatal(msg) \
-{ \
- print "fatal: making $@: " msg | "cat >&2"; \
- exit 1; \
-} \
-function rst_section(header) \
-{ \
- print header; \
- len = length(header); \
- for (i = 1; i <= len; i = i + 1) \
- printf "="; \
- printf "\n\n"; \
-} \
-{ \
- copy_in_global_log = 1; \
- global_test_result = "RUN"; \
- while ((rc = (getline line < ($$0 ".trs"))) != 0) \
- { \
- if (rc < 0) \
- fatal("failed to read from " $$0 ".trs"); \
- if (line ~ /$(am__global_test_result_rx)/) \
- { \
- sub("$(am__global_test_result_rx)", "", line); \
- sub("[ ]*$$", "", line); \
- global_test_result = line; \
- } \
- else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
- copy_in_global_log = 0; \
- }; \
- if (copy_in_global_log) \
- { \
- rst_section(global_test_result ": " $$0); \
- while ((rc = (getline line < ($$0 ".log"))) != 0) \
- { \
- if (rc < 0) \
- fatal("failed to read from " $$0 ".log"); \
- print line; \
- }; \
- printf "\n"; \
- }; \
- close ($$0 ".trs"); \
- close ($$0 ".log"); \
-}'
-# Restructured Text title.
-am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
-# Solaris 10 'make', and several other traditional 'make' implementations,
-# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
-# by disabling -e (using the XSI extension "set +e") if it's set.
-am__sh_e_setup = case $$- in *e*) set +e;; esac
-# Default flags passed to test drivers.
-am__common_driver_flags = \
- --color-tests "$$am__color_tests" \
- --enable-hard-errors "$$am__enable_hard_errors" \
- --expect-failure "$$am__expect_failure"
-# To be inserted before the command running the test. Creates the
-# directory for the log if needed. Stores in $dir the directory
-# containing $f, in $tst the test, in $log the log. Executes the
-# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
-# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
-# will run the test scripts (or their associated LOG_COMPILER, if
-# thy have one).
-am__check_pre = \
-$(am__sh_e_setup); \
-$(am__vpath_adj_setup) $(am__vpath_adj) \
-$(am__tty_colors); \
-srcdir=$(srcdir); export srcdir; \
-case "$@" in \
- */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
- *) am__odir=.;; \
-esac; \
-test "x$$am__odir" = x"." || test -d "$$am__odir" \
- || $(MKDIR_P) "$$am__odir" || exit $$?; \
-if test -f "./$$f"; then dir=./; \
-elif test -f "$$f"; then dir=; \
-else dir="$(srcdir)/"; fi; \
-tst=$$dir$$f; log='$@'; \
-if test -n '$(DISABLE_HARD_ERRORS)'; then \
- am__enable_hard_errors=no; \
-else \
- am__enable_hard_errors=yes; \
-fi; \
-case " $(XFAIL_TESTS) " in \
- *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
- am__expect_failure=yes;; \
- *) \
- am__expect_failure=no;; \
-esac; \
-$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
-# A shell command to get the names of the tests scripts with any registered
-# extension removed (i.e., equivalently, the names of the test logs, with
-# the '.log' extension removed). The result is saved in the shell variable
-# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
-# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
-# since that might cause problem with VPATH rewrites for suffix-less tests.
-# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
-am__set_TESTS_bases = \
- bases='$(TEST_LOGS)'; \
- bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
- bases=`echo $$bases`
-AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
-RECHECK_LOGS = $(TEST_LOGS)
-TEST_SUITE_LOG = test-suite.log
-am__test_logs1 = $(TESTS:=.log)
-am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
-TEST_LOGS = $(am__test_logs2:.pl.log=.log)
-PL_LOG_DRIVER = $(SHELL) $(top_srcdir)/../../build-aux/test-driver
-PL_LOG_COMPILE = $(PL_LOG_COMPILER) $(AM_PL_LOG_FLAGS) $(PL_LOG_FLAGS)
-am__set_b = \
- case '$@' in \
- */*) \
- case '$*' in \
- */*) b='$*';; \
- *) b=`echo '$@' | sed 's/\.log$$//'`; \
- esac;; \
- *) \
- b='$*';; \
- esac
-DIST_SUBDIRS = tl_support linked_scripts
-am__DIST_COMMON = $(srcdir)/Makefile.in \
- $(top_srcdir)/../../build-aux/compile \
- $(top_srcdir)/../../build-aux/install-sh \
- $(top_srcdir)/../../build-aux/missing \
- $(top_srcdir)/../../build-aux/test-driver \
- ../../build-aux/ar-lib ../../build-aux/compile \
- ../../build-aux/config.guess ../../build-aux/config.sub \
- ../../build-aux/depcomp ../../build-aux/install-sh \
- ../../build-aux/ltmain.sh ../../build-aux/missing \
- ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-am__remove_distdir = \
- if test -d "$(distdir)"; then \
- find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -rf "$(distdir)" \
- || { sleep 5 && rm -rf "$(distdir)"; }; \
- else :; fi
-am__post_remove_distdir = $(am__remove_distdir)
-am__relativize = \
- dir0=`pwd`; \
- sed_first='s,^\([^/]*\)/.*$$,\1,'; \
- sed_rest='s,^[^/]*/*,,'; \
- sed_last='s,^.*/\([^/]*\)$$,\1,'; \
- sed_butlast='s,/*[^/]*$$,,'; \
- while test -n "$$dir1"; do \
- first=`echo "$$dir1" | sed -e "$$sed_first"`; \
- if test "$$first" != "."; then \
- if test "$$first" = ".."; then \
- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
- else \
- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
- if test "$$first2" = "$$first"; then \
- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
- else \
- dir2="../$$dir2"; \
- fi; \
- dir0="$$dir0"/"$$first"; \
- fi; \
- fi; \
- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
- done; \
- reldir="$$dir2"
-DIST_ARCHIVES = $(distdir).tar.gz
-GZIP_ENV = --best
-DIST_TARGETS = dist-gzip
-# Exists only to be overridden by the user if desired.
-AM_DISTCHECK_DVI_TARGET = dvi
-distuninstallcheck_listfiles = find . -type f -print
-am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
- | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
-distcleancheck_listfiles = find . -type f -print
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EXEEXT = @EXEEXT@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-WIN_WRAPPER = @WIN_WRAPPER@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-SUBDIRS = tl_support $(am__append_1)
-EXTRA_DIST = w32_wrapper w64_wrapper $(TESTS)
-TEST_EXTENSIONS = .pl
-TESTS = tests/updmap-cmdline-test.pl
-all: all-recursive
-
-.SUFFIXES:
-.SUFFIXES: .log .pl .pl$(EXEEXT) .trs
-am--refresh: Makefile
- @:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
- $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- echo ' $(SHELL) ./config.status'; \
- $(SHELL) ./config.status;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- $(SHELL) ./config.status --recheck
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- $(am__cd) $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
-$(am__aclocal_m4_deps):
-
-# This directory's subdirectories are mostly independent; you can cd
-# into them and run 'make' without going through this Makefile.
-# To change the values of 'make' variables: instead of editing Makefiles,
-# (1) if the variable is set in 'config.status', edit 'config.status'
-# (which will cause the Makefiles to be regenerated when you run 'make');
-# (2) otherwise, pass the desired values on the 'make' command line.
-$(am__recursive_targets):
- @fail=; \
- if $(am__make_keepgoing); then \
- failcom='fail=yes'; \
- else \
- failcom='exit 1'; \
- fi; \
- dot_seen=no; \
- target=`echo $@ | sed s/-recursive//`; \
- case "$@" in \
- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
- *) list='$(SUBDIRS)' ;; \
- esac; \
- for subdir in $$list; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- dot_seen=yes; \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done; \
- if test "$$dot_seen" = "no"; then \
- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
- fi; test -z "$$fail"
-
-ID: $(am__tagged_files)
- $(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-recursive
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- set x; \
- here=`pwd`; \
- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
- include_option=--etags-include; \
- empty_fix=.; \
- else \
- include_option=--include; \
- empty_fix=; \
- fi; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test ! -f $$subdir/TAGS || \
- set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
- fi; \
- done; \
- $(am__define_uniq_tagged_files); \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: ctags-recursive
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- $(am__define_uniq_tagged_files); \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-cscope: cscope.files
- test ! -s cscope.files \
- || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
-clean-cscope:
- -rm -f cscope.files
-cscope.files: clean-cscope cscopelist
-cscopelist: cscopelist-recursive
-
-cscopelist-am: $(am__tagged_files)
- list='$(am__tagged_files)'; \
- case "$(srcdir)" in \
- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
- *) sdir=$(subdir)/$(srcdir) ;; \
- esac; \
- for i in $$list; do \
- if test -f "$$i"; then \
- echo "$(subdir)/$$i"; \
- else \
- echo "$$sdir/$$i"; \
- fi; \
- done >> $(top_builddir)/cscope.files
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
- -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
-
-# Recover from deleted '.trs' file; this should ensure that
-# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
-# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
-# to avoid problems with "make -n".
-.log.trs:
- rm -f $< $@
- $(MAKE) $(AM_MAKEFLAGS) $<
-
-# Leading 'am--fnord' is there to ensure the list of targets does not
-# expand to empty, as could happen e.g. with make check TESTS=''.
-am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
-am--force-recheck:
- @:
-
-$(TEST_SUITE_LOG): $(TEST_LOGS)
- @$(am__set_TESTS_bases); \
- am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
- redo_bases=`for i in $$bases; do \
- am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
- done`; \
- if test -n "$$redo_bases"; then \
- redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
- redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
- if $(am__make_dryrun); then :; else \
- rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
- fi; \
- fi; \
- if test -n "$$am__remaking_logs"; then \
- echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
- "recursion detected" >&2; \
- elif test -n "$$redo_logs"; then \
- am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
- fi; \
- if $(am__make_dryrun); then :; else \
- st=0; \
- errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
- for i in $$redo_bases; do \
- test -f $$i.trs && test -r $$i.trs \
- || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
- test -f $$i.log && test -r $$i.log \
- || { echo "$$errmsg $$i.log" >&2; st=1; }; \
- done; \
- test $$st -eq 0 || exit 1; \
- fi
- @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
- ws='[ ]'; \
- results=`for b in $$bases; do echo $$b.trs; done`; \
- test -n "$$results" || results=/dev/null; \
- all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
- pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
- fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
- skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
- xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
- xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
- error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
- if test `expr $$fail + $$xpass + $$error` -eq 0; then \
- success=true; \
- else \
- success=false; \
- fi; \
- br='==================='; br=$$br$$br$$br$$br; \
- result_count () \
- { \
- if test x"$$1" = x"--maybe-color"; then \
- maybe_colorize=yes; \
- elif test x"$$1" = x"--no-color"; then \
- maybe_colorize=no; \
- else \
- echo "$@: invalid 'result_count' usage" >&2; exit 4; \
- fi; \
- shift; \
- desc=$$1 count=$$2; \
- if test $$maybe_colorize = yes && test $$count -gt 0; then \
- color_start=$$3 color_end=$$std; \
- else \
- color_start= color_end=; \
- fi; \
- echo "$${color_start}# $$desc $$count$${color_end}"; \
- }; \
- create_testsuite_report () \
- { \
- result_count $$1 "TOTAL:" $$all "$$brg"; \
- result_count $$1 "PASS: " $$pass "$$grn"; \
- result_count $$1 "SKIP: " $$skip "$$blu"; \
- result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
- result_count $$1 "FAIL: " $$fail "$$red"; \
- result_count $$1 "XPASS:" $$xpass "$$red"; \
- result_count $$1 "ERROR:" $$error "$$mgn"; \
- }; \
- { \
- echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
- $(am__rst_title); \
- create_testsuite_report --no-color; \
- echo; \
- echo ".. contents:: :depth: 2"; \
- echo; \
- for b in $$bases; do echo $$b; done \
- | $(am__create_global_log); \
- } >$(TEST_SUITE_LOG).tmp || exit 1; \
- mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
- if $$success; then \
- col="$$grn"; \
- else \
- col="$$red"; \
- test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
- fi; \
- echo "$${col}$$br$${std}"; \
- echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
- echo "$${col}$$br$${std}"; \
- create_testsuite_report --maybe-color; \
- echo "$$col$$br$$std"; \
- if $$success; then :; else \
- echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
- if test -n "$(PACKAGE_BUGREPORT)"; then \
- echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
- fi; \
- echo "$$col$$br$$std"; \
- fi; \
- $$success || exit 1
-
-check-TESTS:
- @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
- @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
- @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
- @set +e; $(am__set_TESTS_bases); \
- log_list=`for i in $$bases; do echo $$i.log; done`; \
- trs_list=`for i in $$bases; do echo $$i.trs; done`; \
- log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
- $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
- exit $$?;
-recheck: all
- @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
- @set +e; $(am__set_TESTS_bases); \
- bases=`for i in $$bases; do echo $$i; done \
- | $(am__list_recheck_tests)` || exit 1; \
- log_list=`for i in $$bases; do echo $$i.log; done`; \
- log_list=`echo $$log_list`; \
- $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
- am__force_recheck=am--force-recheck \
- TEST_LOGS="$$log_list"; \
- exit $$?
-.pl.log:
- @p='$<'; \
- $(am__set_b); \
- $(am__check_pre) $(PL_LOG_DRIVER) --test-name "$$f" \
- --log-file $$b.log --trs-file $$b.trs \
- $(am__common_driver_flags) $(AM_PL_LOG_DRIVER_FLAGS) $(PL_LOG_DRIVER_FLAGS) -- $(PL_LOG_COMPILE) \
- "$$tst" $(AM_TESTS_FD_REDIRECT)
-@am__EXEEXT_TRUE@.pl$(EXEEXT).log:
-@am__EXEEXT_TRUE@ @p='$<'; \
-@am__EXEEXT_TRUE@ $(am__set_b); \
-@am__EXEEXT_TRUE@ $(am__check_pre) $(PL_LOG_DRIVER) --test-name "$$f" \
-@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
-@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_PL_LOG_DRIVER_FLAGS) $(PL_LOG_DRIVER_FLAGS) -- $(PL_LOG_COMPILE) \
-@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
-
-distdir: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) distdir-am
-
-distdir-am: $(DISTFILES)
- $(am__remove_distdir)
- test -d "$(distdir)" || mkdir "$(distdir)"
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- $(am__make_dryrun) \
- || test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
- $(am__relativize); \
- new_distdir=$$reldir; \
- dir1=$$subdir; dir2="$(top_distdir)"; \
- $(am__relativize); \
- new_top_distdir=$$reldir; \
- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
- ($(am__cd) $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$new_top_distdir" \
- distdir="$$new_distdir" \
- am__remove_distdir=: \
- am__skip_length_check=: \
- am__skip_mode_fix=: \
- distdir) \
- || exit 1; \
- fi; \
- done
- -test -n "$(am__skip_mode_fix)" \
- || find "$(distdir)" -type d ! -perm -755 \
- -exec chmod u+rwx,go+rx {} \; -o \
- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
- || chmod -R a+r "$(distdir)"
-dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
- $(am__post_remove_distdir)
-
-dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
- $(am__post_remove_distdir)
-
-dist-lzip: distdir
- tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
- $(am__post_remove_distdir)
-
-dist-xz: distdir
- tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
- $(am__post_remove_distdir)
-
-dist-zstd: distdir
- tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
- $(am__post_remove_distdir)
-
-dist-tarZ: distdir
- @echo WARNING: "Support for distribution archives compressed with" \
- "legacy program 'compress' is deprecated." >&2
- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__post_remove_distdir)
-
-dist-shar: distdir
- @echo WARNING: "Support for shar distribution archives is" \
- "deprecated." >&2
- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
- shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
- $(am__post_remove_distdir)
-
-dist-zip: distdir
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__post_remove_distdir)
-
-dist dist-all:
- $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
- $(am__post_remove_distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- case '$(DIST_ARCHIVES)' in \
- *.tar.gz*) \
- eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
- *.tar.bz2*) \
- bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lz*) \
- lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
- *.tar.xz*) \
- xz -dc $(distdir).tar.xz | $(am__untar) ;;\
- *.tar.Z*) \
- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
- *.shar.gz*) \
- eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
- *.zip*) \
- unzip $(distdir).zip ;;\
- *.tar.zst*) \
- zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
- esac
- chmod -R a-w $(distdir)
- chmod u+w $(distdir)
- mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
- chmod a-w $(distdir)
- test -d $(distdir)/_build || exit 0; \
- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
- && am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build/sub \
- && ../../configure \
- $(AM_DISTCHECK_CONFIGURE_FLAGS) \
- $(DISTCHECK_CONFIGURE_FLAGS) \
- --srcdir=../.. --prefix="$$dc_install_base" \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
- distuninstallcheck \
- && chmod -R a-w "$$dc_install_base" \
- && ({ \
- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
- } || { rm -rf "$$dc_destdir"; exit 1; }) \
- && rm -rf "$$dc_destdir" \
- && $(MAKE) $(AM_MAKEFLAGS) dist \
- && rm -rf $(DIST_ARCHIVES) \
- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
- && cd "$$am__cwd" \
- || exit 1
- $(am__post_remove_distdir)
- @(echo "$(distdir) archives ready for distribution: "; \
- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
- sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
-distuninstallcheck:
- @test -n '$(distuninstallcheck_dir)' || { \
- echo 'ERROR: trying to run $@ with an empty' \
- '$$(distuninstallcheck_dir)' >&2; \
- exit 1; \
- }; \
- $(am__cd) '$(distuninstallcheck_dir)' || { \
- echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
- exit 1; \
- }; \
- test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left after uninstall:" ; \
- if test -n "$(DESTDIR)"; then \
- echo " (check DESTDIR support)"; \
- fi ; \
- $(distuninstallcheck_listfiles) ; \
- exit 1; } >&2
-distcleancheck: distclean
- @if test '$(srcdir)' = . ; then \
- echo "ERROR: distcleancheck can only run from a VPATH build" ; \
- exit 1 ; \
- fi
- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left in build directory after distclean:" ; \
- $(distcleancheck_listfiles) ; \
- exit 1; } >&2
-check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-recursive
-all-am: Makefile
-installdirs: installdirs-recursive
-installdirs-am:
-install: install-recursive
-install-exec: install-exec-recursive
-install-data: install-data-recursive
-uninstall: uninstall-recursive
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-recursive
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
- -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
- -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
- -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-recursive
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-recursive
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -f Makefile
-distclean-am: clean-am distclean-generic distclean-tags
-
-dvi: dvi-recursive
-
-dvi-am:
-
-html: html-recursive
-
-html-am:
-
-info: info-recursive
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-recursive
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-recursive
-
-install-html-am:
-
-install-info: install-info-recursive
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-recursive
-
-install-pdf-am:
-
-install-ps: install-ps-recursive
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-recursive
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf $(top_srcdir)/autom4te.cache
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-recursive
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-recursive
-
-pdf-am:
-
-ps: ps-recursive
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: $(am__recursive_targets) check-am install-am install-strip
-
-.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
- am--refresh check check-TESTS check-am clean clean-cscope \
- clean-generic cscope cscopelist-am ctags ctags-am dist \
- dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
- dist-xz dist-zip dist-zstd distcheck distclean \
- distclean-generic distclean-tags distcleancheck distdir \
- distuninstallcheck dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- installdirs-am maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-generic pdf pdf-am ps ps-am recheck \
- tags tags-am uninstall uninstall-am
-
-.PRECIOUS: Makefile
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Build/source/texk/texlive/ac/texlive.ac b/Build/source/texk/texlive/ac/texlive.ac
deleted file mode 100644
index 07ffe2db813..00000000000
--- a/Build/source/texk/texlive/ac/texlive.ac
+++ /dev/null
@@ -1,11 +0,0 @@
-## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/
-dnl
-dnl Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org>
-dnl You may freely use, modify and/or distribute this file.
-dnl
-## configure options for texlive
-m4_define_default([kpse_indent_26], [26])[]dnl
-AC_ARG_ENABLE([linked-scripts],
- AS_HELP_STRING([--disable-linked-scripts],
- [do not install the linked scripts],
- kpse_indent_26))[]dnl
diff --git a/Build/source/texk/texlive/ac/withenable.ac b/Build/source/texk/texlive/ac/withenable.ac
deleted file mode 100644
index 950c1b5083e..00000000000
--- a/Build/source/texk/texlive/ac/withenable.ac
+++ /dev/null
@@ -1,8 +0,0 @@
-## texk/texlive/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/
-dnl
-dnl Copyright (C) 2009-2013 Peter Breitenlohner <tex-live@tug.org>
-dnl You may freely use, modify and/or distribute this file.
-dnl
-## configure options and TL libraries required for texlive
-KPSE_ENABLE_PROG([texlive], , , [TeX Live scripts])
-m4_include(kpse_TL[texk/texlive/ac/texlive.ac])
diff --git a/Build/source/texk/texlive/aclocal.m4 b/Build/source/texk/texlive/aclocal.m4
deleted file mode 100644
index 7a0239dab89..00000000000
--- a/Build/source/texk/texlive/aclocal.m4
+++ /dev/null
@@ -1,1169 +0,0 @@
-# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
-
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
-[m4_warning([this file was generated for autoconf 2.69.
-You have another version of autoconf. It may work, but is not guaranteed to.
-If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-
-# Copyright (C) 2002-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-# (This private macro should not be called outside this file.)
-AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.16'
-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
-dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.16.3], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
-])
-
-# _AM_AUTOCONF_VERSION(VERSION)
-# -----------------------------
-# aclocal traces this macro to find the Autoconf version.
-# This is a private macro too. Using m4_define simplifies
-# the logic in aclocal, which can simply ignore this definition.
-m4_define([_AM_AUTOCONF_VERSION], [])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.3])dnl
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-
-# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
-# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is '.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright (C) 1997-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ([2.52])dnl
- m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])dnl
-AC_SUBST([$1_FALSE])dnl
-_AM_SUBST_NOTMAKE([$1_TRUE])dnl
-_AM_SUBST_NOTMAKE([$1_FALSE])dnl
-m4_define([_AM_COND_VALUE_$1], [$2])dnl
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
-fi])])
-
-# Copyright (C) 1999-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-
-# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
- [$1], [CXX], [depcc="$CXX" am_compiler_list=],
- [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
- [$1], [UPC], [depcc="$UPC" am_compiler_list=],
- [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named 'D' -- because '-MD' means "put the output
- # in D".
- rm -rf conftest.dir
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- am__universal=false
- m4_case([$1], [CC],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac],
- [CXX],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac])
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
- # Solaris 10 /bin/sh.
- echo '/* dummy */' > sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with '-c' and '-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle '-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs.
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # After this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested.
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok '-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-AM_CONDITIONAL([am__fastdep$1], [
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
-AC_DEFUN([AM_SET_DEPDIR],
-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE([dependency-tracking], [dnl
-AS_HELP_STRING(
- [--enable-dependency-tracking],
- [do not reject slow dependency extractors])
-AS_HELP_STRING(
- [--disable-dependency-tracking],
- [speeds up one-time build])])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
- am__nodep='_no'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
-AC_SUBST([am__nodep])dnl
-_AM_SUBST_NOTMAKE([am__nodep])dnl
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright (C) 1999-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[{
- # Older Autoconf quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- # TODO: see whether this extra hack can be removed once we start
- # requiring Autoconf 2.70 or later.
- AS_CASE([$CONFIG_FILES],
- [*\'*], [eval set x "$CONFIG_FILES"],
- [*], [set x $CONFIG_FILES])
- shift
- # Used to flag and report bootstrapping failures.
- am_rc=0
- for am_mf
- do
- # Strip MF so we end up with the name of the file.
- am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile which includes
- # dependency-tracking related rules and includes.
- # Grep'ing the whole file directly is not great: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
- || continue
- am_dirpart=`AS_DIRNAME(["$am_mf"])`
- am_filepart=`AS_BASENAME(["$am_mf"])`
- AM_RUN_LOG([cd "$am_dirpart" \
- && sed -e '/# am--include-marker/d' "$am_filepart" \
- | $MAKE -f - am--depfiles]) || am_rc=$?
- done
- if test $am_rc -ne 0; then
- AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
- for automatic dependency tracking. If GNU make was not used, consider
- re-running the configure script with MAKE="gmake" (or whatever is
- necessary). You can also try re-running configure with the
- '--disable-dependency-tracking' option to at least be able to build
- the package (albeit without support for automatic dependency tracking).])
- fi
- AS_UNSET([am_dirpart])
- AS_UNSET([am_filepart])
- AS_UNSET([am_mf])
- AS_UNSET([am_rc])
- rm -f conftest-deps.mk
-}
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking is enabled.
-# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
-# order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
-
-# Do all the work for Automake. -*- Autoconf -*-
-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This macro actually does too much. Some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
-m4_define([AC_PROG_CC],
-m4_defn([AC_PROG_CC])
-[_AM_PROG_CC_C_O
-])
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.65])dnl
-dnl Autoconf wants to disallow AM_ names. We explicitly allow
-dnl the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])dnl
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-AC_SUBST([CYGPATH_W])
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[AC_DIAGNOSE([obsolete],
- [$0: two- and three-arguments forms are deprecated.])
-m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(
- m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
- [ok:ok],,
- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
- AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
-AM_MISSING_PROG([AUTOCONF], [autoconf])
-AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
-AM_MISSING_PROG([AUTOHEADER], [autoheader])
-AM_MISSING_PROG([MAKEINFO], [makeinfo])
-AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-# For better backward compatibility. To be removed once Automake 1.9.x
-# dies out for good. For more background, see:
-# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
-AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target (and possibly the TAP driver). The
-# system "awk" is bad on some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
- [_AM_PROG_TAR([v7])])])
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES([CC])],
- [m4_define([AC_PROG_CC],
- m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES([CXX])],
- [m4_define([AC_PROG_CXX],
- m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES([OBJC])],
- [m4_define([AC_PROG_OBJC],
- m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
- [_AM_DEPENDENCIES([OBJCXX])],
- [m4_define([AC_PROG_OBJCXX],
- m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
-])
-AC_REQUIRE([AM_SILENT_RULES])dnl
-dnl The testsuite driver may need to know about EXEEXT, so add the
-dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
-dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
-AC_CONFIG_COMMANDS_PRE(dnl
-[m4_provide_if([_AM_COMPILER_EXEEXT],
- [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-
-Please tell bug-automake@gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
-
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <https://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
- fi
-fi
-dnl The trailing newline in this macro's definition is deliberate, for
-dnl backward compatibility and to allow trailing 'dnl'-style comments
-dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
-])
-
-dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
-dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
-dnl mangled by Autoconf and run in a shell conditional statement.
-m4_define([_AC_COMPILER_EXEEXT],
-m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. The stamp files are numbered to have different names.
-
-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
-# loop where config.status creates the headers, so we can generate
-# our stamp files there.
-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
-[# Compute $1's index in $config_headers.
-_am_arg=$1
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-AC_SUBST([install_sh])])
-
-# Copyright (C) 2003-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot. For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-AC_SUBST([am__leading_dot])])
-
-# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
-# From Jim Meyering
-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_MAINTAINER_MODE([DEFAULT-MODE])
-# ----------------------------------
-# Control maintainer-specific portions of Makefiles.
-# Default is to disable them, unless 'enable' is passed literally.
-# For symmetry, 'disable' may be passed as well. Anyway, the user
-# can override the default with the --enable/--disable switch.
-AC_DEFUN([AM_MAINTAINER_MODE],
-[m4_case(m4_default([$1], [disable]),
- [enable], [m4_define([am_maintainer_other], [disable])],
- [disable], [m4_define([am_maintainer_other], [enable])],
- [m4_define([am_maintainer_other], [enable])
- m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
- dnl maintainer-mode's default is 'disable' unless 'enable' is passed
- AC_ARG_ENABLE([maintainer-mode],
- [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
- am_maintainer_other[ make rules and dependencies not useful
- (and sometimes confusing) to the casual installer])],
- [USE_MAINTAINER_MODE=$enableval],
- [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
- AC_MSG_RESULT([$USE_MAINTAINER_MODE])
- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
- MAINT=$MAINTAINER_MODE_TRUE
- AC_SUBST([MAINT])dnl
-]
-)
-
-# Check to see how 'make' treats includes. -*- Autoconf -*-
-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check whether make has an 'include' directive that can support all
-# the idioms we need for our automatic dependency tracking code.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
-cat > confinc.mk << 'END'
-am__doit:
- @echo this is the am__doit target >confinc.out
-.PHONY: am__doit
-END
-am__include="#"
-am__quote=
-# BSD make does it like this.
-echo '.include "confinc.mk" # ignored' > confmf.BSD
-# Other make implementations (GNU, Solaris 10, AIX) do it like this.
-echo 'include confinc.mk # ignored' > confmf.GNU
-_am_result=no
-for s in GNU BSD; do
- AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
- AS_CASE([$?:`cat confinc.out 2>/dev/null`],
- ['0:this is the am__doit target'],
- [AS_CASE([$s],
- [BSD], [am__include='.include' am__quote='"'],
- [am__include='include' am__quote=''])])
- if test "$am__include" != "#"; then
- _am_result="yes ($s style)"
- break
- fi
-done
-rm -f confinc.* confmf.*
-AC_MSG_RESULT([${_am_result}])
-AC_SUBST([am__include])])
-AC_SUBST([am__quote])])
-
-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
-# Copyright (C) 1997-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it is modern enough.
-# If it is, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([missing])dnl
-if test x"${MISSING+set}" != xset; then
- MISSING="\${SHELL} '$am_aux_dir/missing'"
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --is-lightweight"; then
- am_missing_run="$MISSING "
-else
- am_missing_run=
- AC_MSG_WARN(['missing' script is too old or missing])
-fi
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# --------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-# Copyright (C) 1999-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_PROG_CC_C_O
-# ---------------
-# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
-# to automatically call this.
-AC_DEFUN([_AM_PROG_CC_C_O],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([compile])dnl
-AC_LANG_PUSH([C])dnl
-AC_CACHE_CHECK(
- [whether $CC understands -c and -o together],
- [am_cv_prog_cc_c_o],
- [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
- # Make sure it works both with $CC and with simple cc.
- # Following AC_PROG_CC_C_O, we do the test twice because some
- # compilers refuse to overwrite an existing .o file with -o,
- # though they will create one.
- am_cv_prog_cc_c_o=yes
- for am_i in 1 2; do
- if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
- && test -f conftest2.$ac_objext; then
- : OK
- else
- am_cv_prog_cc_c_o=no
- break
- fi
- done
- rm -f core conftest*
- unset am_i])
-if test "$am_cv_prog_cc_c_o" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-AC_LANG_POP([C])])
-
-# For backward compatibility.
-AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_RUN_LOG(COMMAND)
-# -------------------
-# Run COMMAND, save the exit status in ac_status, and log it.
-# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
-AC_DEFUN([AM_RUN_LOG],
-[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
- ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- (exit $ac_status); }])
-
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[[\\\"\#\$\&\'\`$am_lf]]*)
- AC_MSG_ERROR([unsafe absolute working directory name]);;
-esac
-case $srcdir in
- *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
-esac
-
-# Do 'set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- am_has_slept=no
- for am_try in 1 2; do
- echo "timestamp, slept: $am_has_slept" > conftest.file
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
- alias in your environment])
- fi
- if test "$[2]" = conftest.file || test $am_try -eq 2; then
- break
- fi
- # Just in case.
- sleep 1
- am_has_slept=yes
- done
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT([yes])
-# If we didn't sleep, we still need to ensure time stamps of config.status and
-# generated files are strictly newer.
-am_sleep_pid=
-if grep 'slept: no' conftest.file >/dev/null 2>&1; then
- ( sleep 1 ) &
- am_sleep_pid=$!
-fi
-AC_CONFIG_COMMANDS_PRE(
- [AC_MSG_CHECKING([that generated files are newer than configure])
- if test -n "$am_sleep_pid"; then
- # Hide warnings about reused PIDs.
- wait $am_sleep_pid 2>/dev/null
- fi
- AC_MSG_RESULT([done])])
-rm -f conftest.file
-])
-
-# Copyright (C) 2009-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_SILENT_RULES([DEFAULT])
-# --------------------------
-# Enable less verbose build rules; with the default set to DEFAULT
-# ("yes" being less verbose, "no" or empty being verbose).
-AC_DEFUN([AM_SILENT_RULES],
-[AC_ARG_ENABLE([silent-rules], [dnl
-AS_HELP_STRING(
- [--enable-silent-rules],
- [less verbose build output (undo: "make V=1")])
-AS_HELP_STRING(
- [--disable-silent-rules],
- [verbose build output (undo: "make V=0")])dnl
-])
-case $enable_silent_rules in @%:@ (((
- yes) AM_DEFAULT_VERBOSITY=0;;
- no) AM_DEFAULT_VERBOSITY=1;;
- *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
-esac
-dnl
-dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
-dnl do not support nested variable expansions.
-dnl See automake bug#9928 and bug#10237.
-am_make=${MAKE-make}
-AC_CACHE_CHECK([whether $am_make supports nested variables],
- [am_cv_make_support_nested_variables],
- [if AS_ECHO([['TRUE=$(BAR$(V))
-BAR0=false
-BAR1=true
-V=1
-am__doit:
- @$(TRUE)
-.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
- am_cv_make_support_nested_variables=yes
-else
- am_cv_make_support_nested_variables=no
-fi])
-if test $am_cv_make_support_nested_variables = yes; then
- dnl Using '$V' instead of '$(V)' breaks IRIX make.
- AM_V='$(V)'
- AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
-else
- AM_V=$AM_DEFAULT_VERBOSITY
- AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
-fi
-AC_SUBST([AM_V])dnl
-AM_SUBST_NOTMAKE([AM_V])dnl
-AC_SUBST([AM_DEFAULT_V])dnl
-AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
-AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
-AM_BACKSLASH='\'
-AC_SUBST([AM_BACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
-])
-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_STRIP
-# ---------------------
-# One issue with vendor 'install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in "make install-strip", and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using 'strip' when the user
-# run "make install-strip". However 'strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the 'STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# Copyright (C) 2006-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
-# This macro is traced by Automake.
-AC_DEFUN([_AM_SUBST_NOTMAKE])
-
-# AM_SUBST_NOTMAKE(VARIABLE)
-# --------------------------
-# Public sister of _AM_SUBST_NOTMAKE.
-AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
-
-# Check how to create a tarball. -*- Autoconf -*-
-
-# Copyright (C) 2004-2020 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of 'v7', 'ustar', or 'pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-# tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-# $(am__untar) < result.tar
-#
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility. Yes, it's still used
-# in the wild :-( We should find a proper way to deprecate it ...
-AC_SUBST([AMTAR], ['$${TAR-tar}'])
-
-# We'll loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-
-m4_if([$1], [v7],
- [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
-
- [m4_case([$1],
- [ustar],
- [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
- # There is notably a 21 bits limit for the UID and the GID. In fact,
- # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
- # and bug#13588).
- am_max_uid=2097151 # 2^21 - 1
- am_max_gid=$am_max_uid
- # The $UID and $GID variables are not portable, so we need to resort
- # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
- # below are definitely unexpected, so allow the users to see them
- # (that is, avoid stderr redirection).
- am_uid=`id -u || echo unknown`
- am_gid=`id -g || echo unknown`
- AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
- if test $am_uid -le $am_max_uid; then
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- _am_tools=none
- fi
- AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
- if test $am_gid -le $am_max_gid; then
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- _am_tools=none
- fi],
-
- [pax],
- [],
-
- [m4_fatal([Unknown tar format])])
-
- AC_MSG_CHECKING([how to create a $1 tar archive])
-
- # Go ahead even if we have the value already cached. We do so because we
- # need to set the values for the 'am__tar' and 'am__untar' variables.
- _am_tools=${am_cv_prog_tar_$1-$_am_tools}
-
- for _am_tool in $_am_tools; do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar; do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
-
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
-
- # tar/untar a dummy directory, and stop if the command works.
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
- rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- AM_RUN_LOG([cat conftest.dir/file])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
- done
- rm -rf conftest.dir
-
- AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
- AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
-m4_include([../../m4/kpse-win32.m4])
diff --git a/Build/source/texk/texlive/configure b/Build/source/texk/texlive/configure
deleted file mode 100755
index b42f08b75b5..00000000000
--- a/Build/source/texk/texlive/configure
+++ /dev/null
@@ -1,4967 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for TeX Live Scripts 2021.
-#
-# Report bugs to <tex-k@tug.org>.
-#
-#
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
-#
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Use a proper internal environment variable to ensure we don't fall
- # into an infinite loop, continuously re-executing ourselves.
- if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
- _as_can_reexec=no; export _as_can_reexec;
- # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
- fi
- # We don't want this to propagate to other subprocesses.
- { _as_can_reexec=; unset _as_can_reexec;}
-if test "x$CONFIG_SHELL" = x; then
- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '\${1+\"\$@\"}'='\"\$@\"'
- setopt NO_GLOB_SUBST
-else
- case \`(set -o) 2>/dev/null\` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-"
- as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
- exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1
-test -x / || exit 1"
- as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
- as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
- eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
- if (eval "$as_required") 2>/dev/null; then :
- as_have_required=yes
-else
- as_have_required=no
-fi
- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- as_found=:
- case $as_dir in #(
- /*)
- for as_base in sh bash ksh sh5; do
- # Try only shells that exist, to save several forks.
- as_shell=$as_dir/$as_base
- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
- CONFIG_SHELL=$as_shell as_have_required=yes
- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
- break 2
-fi
-fi
- done;;
- esac
- as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
- CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
- if test "x$CONFIG_SHELL" != x; then :
- export CONFIG_SHELL
- # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
-fi
-
- if test x$as_have_required = xno; then :
- $as_echo "$0: This script requires a shell more modern than all"
- $as_echo "$0: the shells that I found on your system."
- if test x${ZSH_VERSION+set} = xset ; then
- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
- $as_echo "$0: be upgraded to zsh 4.3.4 or later."
- else
- $as_echo "$0: Please tell bug-autoconf@gnu.org and tex-k@tug.org
-$0: about your system, including any error possibly output
-$0: before this message. Then install a modern shell, or
-$0: manually run the script under such a shell if you do
-$0: have one."
- fi
- exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
- test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
- fi
- $as_echo "$as_me: error: $2" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
- # already done that, so ensure we don't try to do so again and fall
- # in an infinite loop. This has already happened in practice.
- _as_can_reexec=no; export _as_can_reexec
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -pR'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -pR'
- fi
-else
- as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-test -n "$DJDIR" || exec 7<&0 </dev/null
-exec 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME='TeX Live Scripts'
-PACKAGE_TARNAME='tex-live-scripts'
-PACKAGE_VERSION='2021'
-PACKAGE_STRING='TeX Live Scripts 2021'
-PACKAGE_BUGREPORT='tex-k@tug.org'
-PACKAGE_URL=''
-
-ac_unique_file="linked_scripts/ChangeLog"
-ac_subst_vars='am__EXEEXT_FALSE
-am__EXEEXT_TRUE
-LTLIBOBJS
-LIBOBJS
-WIN32_WRAP_FALSE
-WIN32_WRAP_TRUE
-WIN_WRAPPER
-WIN32_FALSE
-WIN32_TRUE
-LN_S
-am__fastdepCC_FALSE
-am__fastdepCC_TRUE
-CCDEPMODE
-am__nodep
-AMDEPBACKSLASH
-AMDEP_FALSE
-AMDEP_TRUE
-am__include
-DEPDIR
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-LINKED_SCRIPTS_FALSE
-LINKED_SCRIPTS_TRUE
-MAINT
-MAINTAINER_MODE_FALSE
-MAINTAINER_MODE_TRUE
-AM_BACKSLASH
-AM_DEFAULT_VERBOSITY
-AM_DEFAULT_V
-AM_V
-am__untar
-am__tar
-AMTAR
-am__leading_dot
-SET_MAKE
-AWK
-mkdir_p
-MKDIR_P
-INSTALL_STRIP_PROGRAM
-STRIP
-install_sh
-MAKEINFO
-AUTOHEADER
-AUTOMAKE
-AUTOCONF
-ACLOCAL
-VERSION
-PACKAGE
-CYGPATH_W
-am__isrc
-INSTALL_DATA
-INSTALL_SCRIPT
-INSTALL_PROGRAM
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL
-am__quote'
-ac_subst_files=''
-ac_user_opts='
-enable_option_checking
-enable_silent_rules
-enable_maintainer_mode
-enable_linked_scripts
-enable_dependency_tracking
-'
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *=) ac_optarg= ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- case $ac_envvar in #(
- '' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
- esac
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error $? "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
- case $enable_option_checking in
- no) ;;
- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
- esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- # Remove trailing slashes.
- case $ac_val in
- */ )
- ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
- eval $ac_var=\$ac_val;;
- esac
- # Be sure to have absolute directory names.
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error $? "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error $? "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_myself" : 'X\(//\)[^/]' \| \
- X"$as_myself" : 'X\(//\)$' \| \
- X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
- pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures TeX Live Scripts 2021 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking ...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root
- [DATAROOTDIR/doc/tex-live-scripts]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-
-Program names:
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM run sed PROGRAM on installed program names
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
- case $ac_init_help in
- short | recursive ) echo "Configuration of TeX Live Scripts 2021:";;
- esac
- cat <<\_ACEOF
-
-Optional Features:
- --disable-option-checking ignore unrecognized --enable/--with options
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-silent-rules less verbose build output (undo: "make V=1")
- --disable-silent-rules verbose build output (undo: "make V=0")
- --enable-maintainer-mode
- enable make rules and dependencies not useful (and
- sometimes confusing) to the casual installer
- --disable-linked-scripts
- do not install the linked scripts
- --enable-dependency-tracking
- do not reject slow dependency extractors
- --disable-dependency-tracking
- speeds up one-time build
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <tex-k@tug.org>.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" ||
- { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
- continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-TeX Live Scripts configure 2021
-generated by GNU Autoconf 2.69
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by TeX Live Scripts $as_me 2021, which was
-generated by GNU Autoconf 2.69. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- $as_echo "PATH: $as_dir"
- done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
- 2)
- as_fn_append ac_configure_args1 " '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- as_fn_append ac_configure_args " '$ac_arg'"
- ;;
- esac
- done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- $as_echo "## ---------------- ##
-## Cache variables. ##
-## ---------------- ##"
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- $as_echo "## ----------------- ##
-## Output variables. ##
-## ----------------- ##"
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- $as_echo "## ------------------- ##
-## File substitutions. ##
-## ------------------- ##"
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- $as_echo "## ----------- ##
-## confdefs.h. ##
-## ----------- ##"
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- $as_echo "$as_me: caught signal $ac_signal"
- $as_echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
- # We do not want a PATH search for config.site.
- case $CONFIG_SITE in #((
- -*) ac_site_file1=./$CONFIG_SITE;;
- */*) ac_site_file1=$CONFIG_SITE;;
- *) ac_site_file1=./$CONFIG_SITE;;
- esac
-elif test "x$prefix" != xNONE; then
- ac_site_file1=$prefix/share/config.site
- ac_site_file2=$prefix/etc/config.site
-else
- ac_site_file1=$ac_default_prefix/share/config.site
- ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
- test "x$ac_site_file" = xNONE && continue
- if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file" \
- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special files
- # actually), so we avoid doing that. DJGPP emulates it as a regular file.
- if test /dev/null != "$cache_file" && test -f "$cache_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- # differences in whitespace do not lead to failure.
- ac_old_val_w=`echo x $ac_old_val`
- ac_new_val_w=`echo x $ac_new_val`
- if test "$ac_old_val_w" != "$ac_new_val_w"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- ac_cache_corrupted=:
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
- eval $ac_var=\$ac_old_val
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) as_fn_append ac_configure_args " '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-ac_aux_dir=
-for ac_dir in ../../build-aux "$srcdir"/../../build-aux; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../build-aux \"$srcdir\"/../../build-aux" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
-
-
-am__api_version='1.16'
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-# Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
-if test -z "$INSTALL"; then
-if ${ac_cv_path_install+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
- ./ | .// | /[cC]/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- rm -rf conftest.one conftest.two conftest.dir
- echo one > conftest.one
- echo two > conftest.two
- mkdir conftest.dir
- if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
- test -s conftest.one && test -s conftest.two &&
- test -s conftest.dir/conftest.one &&
- test -s conftest.dir/conftest.two
- then
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- fi
- done
- done
- ;;
-esac
-
- done
-IFS=$as_save_IFS
-
-rm -rf conftest.one conftest.two conftest.dir
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- INSTALL=$ac_install_sh
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
-$as_echo_n "checking whether build environment is sane... " >&6; }
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[\\\"\#\$\&\'\`$am_lf]*)
- as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
-esac
-case $srcdir in
- *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
- as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
-esac
-
-# Do 'set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- am_has_slept=no
- for am_try in 1 2; do
- echo "timestamp, slept: $am_has_slept" > conftest.file
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
- alias in your environment" "$LINENO" 5
- fi
- if test "$2" = conftest.file || test $am_try -eq 2; then
- break
- fi
- # Just in case.
- sleep 1
- am_has_slept=yes
- done
- test "$2" = conftest.file
- )
-then
- # Ok.
- :
-else
- as_fn_error $? "newly created file is older than distributed files!
-Check your system clock" "$LINENO" 5
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-# If we didn't sleep, we still need to ensure time stamps of config.status and
-# generated files are strictly newer.
-am_sleep_pid=
-if grep 'slept: no' conftest.file >/dev/null 2>&1; then
- ( sleep 1 ) &
- am_sleep_pid=$!
-fi
-
-rm -f conftest.file
-
-test "$program_prefix" != NONE &&
- program_transform_name="s&^&$program_prefix&;$program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
- program_transform_name="s&\$&$program_suffix&;$program_transform_name"
-# Double any \ or $.
-# By default was `s,x,x', remove it if useless.
-ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
-
-if test x"${MISSING+set}" != xset; then
- MISSING="\${SHELL} '$am_aux_dir/missing'"
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --is-lightweight"; then
- am_missing_run="$MISSING "
-else
- am_missing_run=
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
-fi
-
-if test x"${install_sh+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-
-# Installed binaries are usually stripped using 'strip' when the user
-# run "make install-strip". However 'strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the 'STRIP' environment variable to overrule this program.
-if test "$cross_compiling" != no; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_STRIP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_STRIP="${ac_tool_prefix}strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_STRIP"; then
- ac_ct_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_STRIP="strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_ct_STRIP
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
-$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
-if test -z "$MKDIR_P"; then
- if ${ac_cv_path_mkdir+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in mkdir gmkdir; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
- case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
- 'mkdir (GNU coreutils) '* | \
- 'mkdir (coreutils) '* | \
- 'mkdir (fileutils) '4.1*)
- ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
- break 3;;
- esac
- done
- done
- done
-IFS=$as_save_IFS
-
-fi
-
- test -d ./--version && rmdir ./--version
- if test "${ac_cv_path_mkdir+set}" = set; then
- MKDIR_P="$ac_cv_path_mkdir -p"
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for MKDIR_P within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- MKDIR_P="$ac_install_sh -d"
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
-$as_echo "$MKDIR_P" >&6; }
-
-for ac_prog in gawk mawk nawk awk
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AWK+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_AWK="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$AWK" && break
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
-set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
- @echo '@@@%%%=$(MAKE)=@@@%%%'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
-case `${MAKE-make} -f conftest.make 2>/dev/null` in
- *@@@%%%=?*=@@@%%%*)
- eval ac_cv_prog_make_${ac_make}_set=yes;;
- *)
- eval ac_cv_prog_make_${ac_make}_set=no;;
-esac
-rm -f conftest.make
-fi
-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- SET_MAKE=
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-
-# Check whether --enable-silent-rules was given.
-if test "${enable_silent_rules+set}" = set; then :
- enableval=$enable_silent_rules;
-fi
-
-case $enable_silent_rules in # (((
- yes) AM_DEFAULT_VERBOSITY=0;;
- no) AM_DEFAULT_VERBOSITY=1;;
- *) AM_DEFAULT_VERBOSITY=1;;
-esac
-am_make=${MAKE-make}
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
-$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
-if ${am_cv_make_support_nested_variables+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if $as_echo 'TRUE=$(BAR$(V))
-BAR0=false
-BAR1=true
-V=1
-am__doit:
- @$(TRUE)
-.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
- am_cv_make_support_nested_variables=yes
-else
- am_cv_make_support_nested_variables=no
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
-$as_echo "$am_cv_make_support_nested_variables" >&6; }
-if test $am_cv_make_support_nested_variables = yes; then
- AM_V='$(V)'
- AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
-else
- AM_V=$AM_DEFAULT_VERBOSITY
- AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
-fi
-AM_BACKSLASH='\'
-
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- am__isrc=' -I$(srcdir)'
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-
-
-# Define the identity of the package.
- PACKAGE='tex-live-scripts'
- VERSION='2021'
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE "$PACKAGE"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define VERSION "$VERSION"
-_ACEOF
-
-# Some tools Automake needs.
-
-ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
-
-
-AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
-
-
-AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
-
-
-AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
-
-
-MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
-
-# For better backward compatibility. To be removed once Automake 1.9.x
-# dies out for good. For more background, see:
-# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
-mkdir_p='$(MKDIR_P)'
-
-# We need awk for the "check" target (and possibly the TAP driver). The
-# system "awk" is bad on some platforms.
-# Always define AMTAR for backward compatibility. Yes, it's still used
-# in the wild :-( We should find a proper way to deprecate it ...
-AMTAR='$${TAR-tar}'
-
-
-# We'll loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar pax cpio none'
-
-am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
-
-
-
-
-
-
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-
-Please tell bug-automake@gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
-
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <https://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
- fi
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
-$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
- # Check whether --enable-maintainer-mode was given.
-if test "${enable_maintainer_mode+set}" = set; then :
- enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
-else
- USE_MAINTAINER_MODE=no
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
-$as_echo "$USE_MAINTAINER_MODE" >&6; }
- if test $USE_MAINTAINER_MODE = yes; then
- MAINTAINER_MODE_TRUE=
- MAINTAINER_MODE_FALSE='#'
-else
- MAINTAINER_MODE_TRUE='#'
- MAINTAINER_MODE_FALSE=
-fi
-
- MAINT=$MAINTAINER_MODE_TRUE
-
-
-
-# Configure options for texlive also shown at the TeX Live top-level.
-## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/
-## configure options for texlive
-# Check whether --enable-linked-scripts was given.
-if test "${enable_linked_scripts+set}" = set; then :
- enableval=$enable_linked_scripts;
-fi
-
- if test "x$enable_linked_scripts" != xno; then
- LINKED_SCRIPTS_TRUE=
- LINKED_SCRIPTS_FALSE='#'
-else
- LINKED_SCRIPTS_TRUE='#'
- LINKED_SCRIPTS_FALSE=
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- fi
- rm -f conftest.er1 conftest.err
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link_default") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile. We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-if test -z "$ac_file"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
- { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
- if { ac_try='./conftest$ac_cv_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GCC=yes
-else
- GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-else
- CFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
- xno)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
-if ${am_cv_prog_cc_c_o+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- # Make sure it works both with $CC and with simple cc.
- # Following AC_PROG_CC_C_O, we do the test twice because some
- # compilers refuse to overwrite an existing .o file with -o,
- # though they will create one.
- am_cv_prog_cc_c_o=yes
- for am_i in 1 2; do
- if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
- ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } \
- && test -f conftest2.$ac_objext; then
- : OK
- else
- am_cv_prog_cc_c_o=no
- break
- fi
- done
- rm -f core conftest*
- unset am_i
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
-$as_echo "$am_cv_prog_cc_c_o" >&6; }
-if test "$am_cv_prog_cc_c_o" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-DEPDIR="${am__leading_dot}deps"
-
-ac_config_commands="$ac_config_commands depfiles"
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
-$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
-cat > confinc.mk << 'END'
-am__doit:
- @echo this is the am__doit target >confinc.out
-.PHONY: am__doit
-END
-am__include="#"
-am__quote=
-# BSD make does it like this.
-echo '.include "confinc.mk" # ignored' > confmf.BSD
-# Other make implementations (GNU, Solaris 10, AIX) do it like this.
-echo 'include confinc.mk # ignored' > confmf.GNU
-_am_result=no
-for s in GNU BSD; do
- { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
- (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- case $?:`cat confinc.out 2>/dev/null` in #(
- '0:this is the am__doit target') :
- case $s in #(
- BSD) :
- am__include='.include' am__quote='"' ;; #(
- *) :
- am__include='include' am__quote='' ;;
-esac ;; #(
- *) :
- ;;
-esac
- if test "$am__include" != "#"; then
- _am_result="yes ($s style)"
- break
- fi
-done
-rm -f confinc.* confmf.*
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
-$as_echo "${_am_result}" >&6; }
-
-# Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then :
- enableval=$enable_dependency_tracking;
-fi
-
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
- am__nodep='_no'
-fi
- if test "x$enable_dependency_tracking" != xno; then
- AMDEP_TRUE=
- AMDEP_FALSE='#'
-else
- AMDEP_TRUE='#'
- AMDEP_FALSE=
-fi
-
-
-
-depcc="$CC" am_compiler_list=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CC_dependencies_compiler_type+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named 'D' -- because '-MD' means "put the output
- # in D".
- rm -rf conftest.dir
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_CC_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
- fi
- am__universal=false
- case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
- # Solaris 10 /bin/sh.
- echo '/* dummy */' > sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with '-c' and '-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle '-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs.
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # After this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested.
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok '-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_CC_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_CC_dependencies_compiler_type=none
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
-
- if
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
- am__fastdepCC_TRUE=
- am__fastdepCC_FALSE='#'
-else
- am__fastdepCC_TRUE='#'
- am__fastdepCC_FALSE=
-fi
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
-$as_echo_n "checking whether ln -s works... " >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
-$as_echo "no, using $LN_S" >&6; }
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
-set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
- @echo '@@@%%%=$(MAKE)=@@@%%%'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
-case `${MAKE-make} -f conftest.make 2>/dev/null` in
- *@@@%%%=?*=@@@%%%*)
- eval ac_cv_prog_make_${ac_make}_set=yes;;
- *)
- eval ac_cv_prog_make_${ac_make}_set=no;;
-esac
-rm -f conftest.make
-fi
-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- SET_MAKE=
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for native WIN32 or MINGW32" >&5
-$as_echo_n "checking for native WIN32 or MINGW32... " >&6; }
-if ${kpse_cv_have_win32+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifndef WIN32
- choke me
-#endif
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifndef __MINGW32__
- choke me
-#endif
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- kpse_cv_have_win32=mingw32
-else
- kpse_cv_have_win32=native
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- kpse_cv_have_win32=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_have_win32" >&5
-$as_echo "$kpse_cv_have_win32" >&6; }
-
- if test "x$kpse_cv_have_win32" != xno; then
- WIN32_TRUE=
- WIN32_FALSE='#'
-else
- WIN32_TRUE='#'
- WIN32_FALSE=
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for WIN64" >&5
-$as_echo_n "checking for WIN64... " >&6; }
-if ${kpse_cv_have_win64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifndef _WIN64
- choke me
-#endif
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- kpse_cv_have_win64=yes
-else
- kpse_cv_have_win64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_have_win64" >&5
-$as_echo "$kpse_cv_have_win64" >&6; }
-case $kpse_cv_have_win64 in #(
- yes) :
- if test "x$kpse_cv_have_win32=xmingw"; then :
- WIN_WRAPPER=w64_mingw_wrapper
-else
- WIN_WRAPPER=w64_wrapper
-fi ;; #(
- *) :
- WIN_WRAPPER=w32_wrapper ;;
-esac
-
- if test -r "$srcdir/../../texk/texlive/$WIN_WRAPPER/runscript.exe"; then
- WIN32_WRAP_TRUE=
- WIN32_WRAP_FALSE='#'
-else
- WIN32_WRAP_TRUE='#'
- WIN32_WRAP_FALSE=
-fi
-
-
-
-ac_config_files="$ac_config_files Makefile linked_scripts/Makefile tl_support/Makefile"
-
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
-
- (set) 2>&1 |
- case $as_nl`(ac_space=' '; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- # `set' does not quote correctly, so add quotes: double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \.
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- if test "x$cache_file" != "x/dev/null"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
- if test ! -f "$cache_file" || test -h "$cache_file"; then
- cat confcache >"$cache_file"
- else
- case $cache_file in #(
- */* | ?:*)
- mv -f confcache "$cache_file"$$ &&
- mv -f "$cache_file"$$ "$cache_file" ;; #(
- *)
- mv -f confcache "$cache_file" ;;
- esac
- fi
- fi
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Transform confdefs.h into DEFS.
-# Protect against shell expansion while executing Makefile rules.
-# Protect against Makefile macro expansion.
-#
-# If the first sed substitution is executed (which looks for macros that
-# take arguments), then branch to the quote section. Otherwise,
-# look for a macro that doesn't take arguments.
-ac_script='
-:mline
-/\\$/{
- N
- s,\\\n,,
- b mline
-}
-t clear
-:clear
-s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
-t quote
-s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
-t quote
-b any
-:quote
-s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
-s/\[/\\&/g
-s/\]/\\&/g
-s/\$/$$/g
-H
-:any
-${
- g
- s/^\n//
- s/\n/ /g
- p
-}
-'
-DEFS=`sed -n "$ac_script" confdefs.h`
-
-
-ac_libobjs=
-ac_ltlibobjs=
-U=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
- # will be set to the directory where LIBOBJS objects are built.
- as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
-$as_echo_n "checking that generated files are newer than configure... " >&6; }
- if test -n "$am_sleep_pid"; then
- # Hide warnings about reused PIDs.
- wait $am_sleep_pid 2>/dev/null
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
-$as_echo "done" >&6; }
- if test -n "$EXEEXT"; then
- am__EXEEXT_TRUE=
- am__EXEEXT_FALSE='#'
-else
- am__EXEEXT_TRUE='#'
- am__EXEEXT_FALSE=
-fi
-
-if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
- as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${LINKED_SCRIPTS_TRUE}" && test -z "${LINKED_SCRIPTS_FALSE}"; then
- as_fn_error $? "conditional \"LINKED_SCRIPTS\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
- as_fn_error $? "conditional \"AMDEP\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
- as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then
- as_fn_error $? "conditional \"WIN32\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-if test -z "${WIN32_WRAP_TRUE}" && test -z "${WIN32_WRAP_FALSE}"; then
- as_fn_error $? "conditional \"WIN32_WRAP\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
-
-: "${CONFIG_STATUS=./config.status}"
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
- fi
- $as_echo "$as_me: error: $2" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -pR'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -pR'
- fi
-else
- as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
- test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by TeX Live Scripts $as_me 2021, which was
-generated by GNU Autoconf 2.69. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-case $ac_config_files in *"
-"*) set x $ac_config_files; shift; ac_config_files=$*;;
-esac
-
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_files="$ac_config_files"
-config_commands="$ac_config_commands"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration. Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
- -h, --help print this help, then exit
- -V, --version print version number and configuration settings, then exit
- --config print configuration, then exit
- -q, --quiet, --silent
- do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
-
-Configuration files:
-$config_files
-
-Configuration commands:
-$config_commands
-
-Report bugs to <tex-k@tug.org>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
-ac_cs_version="\\
-TeX Live Scripts config.status 2021
-configured by $0, generated by GNU Autoconf 2.69,
- with options \\"\$ac_cs_config\\"
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-INSTALL='$INSTALL'
-MKDIR_P='$MKDIR_P'
-AWK='$AWK'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=?*)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- --*=)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=
- ac_shift=:
- ;;
- *)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- $as_echo "$ac_cs_version"; exit ;;
- --config | --confi | --conf | --con | --co | --c )
- $as_echo "$ac_cs_config"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- '') as_fn_error $? "missing file argument" ;;
- esac
- as_fn_append CONFIG_FILES " '$ac_optarg'"
- ac_need_defaults=false;;
- --he | --h | --help | --hel | -h )
- $as_echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) as_fn_error $? "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
- *) as_fn_append ac_config_targets " $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
- set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
- shift
- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
- CONFIG_SHELL='$SHELL'
- export CONFIG_SHELL
- exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-#
-# INIT-COMMANDS
-#
-AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
- case $ac_config_target in
- "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- "linked_scripts/Makefile") CONFIG_FILES="$CONFIG_FILES linked_scripts/Makefile" ;;
- "tl_support/Makefile") CONFIG_FILES="$CONFIG_FILES tl_support/Makefile" ;;
-
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
- test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp= ac_tmp=
- trap 'exit_status=$?
- : "${ac_tmp:=$tmp}"
- { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
-' 0
- trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-ac_tmp=$tmp
-
-# Set up the scripts for CONFIG_FILES section.
-# No need to generate them if there are no CONFIG_FILES.
-# This happens for instance with `./config.status config.h'.
-if test -n "$CONFIG_FILES"; then
-
-
-ac_cr=`echo X | tr X '\015'`
-# On cygwin, bash can eat \r inside `` if the user requested igncr.
-# But we know of no other shell where ac_cr would be empty at this
-# point, so we can use a bashism as a fallback.
-if test "x$ac_cr" = x; then
- eval ac_cr=\$\'\\r\'
-fi
-ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
-if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\\r'
-else
- ac_cs_awk_cr=$ac_cr
-fi
-
-echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
-_ACEOF
-
-
-{
- echo "cat >conf$$subs.awk <<_ACEOF" &&
- echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
- echo "_ACEOF"
-} >conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- . ./conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-
- ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
- if test $ac_delim_n = $ac_delim_num; then
- break
- elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-rm -f conf$$subs.sh
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
-_ACEOF
-sed -n '
-h
-s/^/S["/; s/!.*/"]=/
-p
-g
-s/^[^!]*!//
-:repl
-t repl
-s/'"$ac_delim"'$//
-t delim
-:nl
-h
-s/\(.\{148\}\)..*/\1/
-t more1
-s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
-p
-n
-b repl
-:more1
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t nl
-:delim
-h
-s/\(.\{148\}\)..*/\1/
-t more2
-s/["\\]/\\&/g; s/^/"/; s/$/"/
-p
-b
-:more2
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t delim
-' <conf$$subs.awk | sed '
-/^[^""]/{
- N
- s/\n//
-}
-' >>$CONFIG_STATUS || ac_write_fail=1
-rm -f conf$$subs.awk
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACAWK
-cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
- for (key in S) S_is_set[key] = 1
- FS = ""
-
-}
-{
- line = $ 0
- nfields = split(line, field, "@")
- substed = 0
- len = length(field[1])
- for (i = 2; i < nfields; i++) {
- key = field[i]
- keylen = length(key)
- if (S_is_set[key]) {
- value = S[key]
- line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
- len += length(value) + length(field[++i])
- substed = 1
- } else
- len += 1 + keylen
- }
-
- print line
-}
-
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
- sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
-else
- cat
-fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
-_ACEOF
-
-# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
-h
-s///
-s/^/:/
-s/[ ]*$/:/
-s/:\$(srcdir):/:/g
-s/:\${srcdir}:/:/g
-s/:@srcdir@:/:/g
-s/^:*//
-s/:*$//
-x
-s/\(=[ ]*\).*/\1/
-G
-s/\n//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-fi # test -n "$CONFIG_FILES"
-
-
-eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
-shift
-for ac_tag
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
- :[FH]-) ac_tag=-:-;;
- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
- esac
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$ac_tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
- esac
- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
- as_fn_append ac_file_inputs " '$ac_f'"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input='Generated from '`
- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
- `' by configure.'
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
- fi
- # Neutralize special characters interpreted by sed in replacement strings.
- case $configure_input in #(
- *\&* | *\|* | *\\* )
- ac_sed_conf_input=`$as_echo "$configure_input" |
- sed 's/[\\\\&|]/\\\\&/g'`;; #(
- *) ac_sed_conf_input=$configure_input;;
- esac
-
- case $ac_tag in
- *:-:* | *:-) cat >"$ac_tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- as_dir="$ac_dir"; as_fn_mkdir_p
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
- case $INSTALL in
- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
- esac
- ac_MKDIR_P=$MKDIR_P
- case $MKDIR_P in
- [\\/$]* | ?:[\\/]* ) ;;
- */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
- esac
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
-ac_sed_dataroot='
-/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p'
-case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_sed_extra="$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s|@configure_input@|$ac_sed_conf_input|;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@top_build_prefix@&$ac_top_build_prefix&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-s&@INSTALL@&$ac_INSTALL&;t t
-s&@MKDIR_P@&$ac_MKDIR_P&;t t
-$ac_datarootdir_hack
-"
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
- >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
- "$ac_tmp/out"`; test -z "$ac_out"; } &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&2;}
-
- rm -f "$ac_tmp/stdin"
- case $ac_file in
- -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
- *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
- esac \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
- ;;
-
-
- :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
-$as_echo "$as_me: executing $ac_file commands" >&6;}
- ;;
- esac
-
-
- case $ac_file$ac_mode in
- "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Older Autoconf quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- # TODO: see whether this extra hack can be removed once we start
- # requiring Autoconf 2.70 or later.
- case $CONFIG_FILES in #(
- *\'*) :
- eval set x "$CONFIG_FILES" ;; #(
- *) :
- set x $CONFIG_FILES ;; #(
- *) :
- ;;
-esac
- shift
- # Used to flag and report bootstrapping failures.
- am_rc=0
- for am_mf
- do
- # Strip MF so we end up with the name of the file.
- am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile which includes
- # dependency-tracking related rules and includes.
- # Grep'ing the whole file directly is not great: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
- || continue
- am_dirpart=`$as_dirname -- "$am_mf" ||
-$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$am_mf" : 'X\(//\)[^/]' \| \
- X"$am_mf" : 'X\(//\)$' \| \
- X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$am_mf" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- am_filepart=`$as_basename -- "$am_mf" ||
-$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
- X"$am_mf" : 'X\(//\)$' \| \
- X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$am_mf" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- { echo "$as_me:$LINENO: cd "$am_dirpart" \
- && sed -e '/# am--include-marker/d' "$am_filepart" \
- | $MAKE -f - am--depfiles" >&5
- (cd "$am_dirpart" \
- && sed -e '/# am--include-marker/d' "$am_filepart" \
- | $MAKE -f - am--depfiles) >&5 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } || am_rc=$?
- done
- if test $am_rc -ne 0; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "Something went wrong bootstrapping makefile fragments
- for automatic dependency tracking. If GNU make was not used, consider
- re-running the configure script with MAKE=\"gmake\" (or whatever is
- necessary). You can also try re-running configure with the
- '--disable-dependency-tracking' option to at least be able to build
- the package (albeit without support for automatic dependency tracking).
-See \`config.log' for more details" "$LINENO" 5; }
- fi
- { am_dirpart=; unset am_dirpart;}
- { am_filepart=; unset am_filepart;}
- { am_mf=; unset am_mf;}
- { am_rc=; unset am_rc;}
- rm -f conftest-deps.mk
-}
- ;;
-
- esac
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit 1
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
-
diff --git a/Build/source/texk/texlive/configure.ac b/Build/source/texk/texlive/configure.ac
deleted file mode 100644
index 16a1d83b71f..00000000000
--- a/Build/source/texk/texlive/configure.ac
+++ /dev/null
@@ -1,36 +0,0 @@
-dnl $Id$
-dnl Process this file with autoconf to produce a configure script.
-dnl
-dnl Copyright 2014-2020 Karl Berry <tex-live@tug.org>
-dnl Copyright 2009-2013 Peter Breitenlohner <tex-live@tug.org>
-dnl
-dnl This file is free software; the copyright holder
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-m4_include([../../version.ac])[] dnl define tex_live_version
-AC_INIT([TeX Live Scripts], tex_live_version(), [tex-k@tug.org])
-AC_PREREQ([2.65])
-AC_CONFIG_SRCDIR([linked_scripts/ChangeLog])
-AC_CONFIG_AUX_DIR([../../build-aux])
-AC_CONFIG_MACRO_DIR([../../m4])
-
-AM_INIT_AUTOMAKE([foreign])
-AM_MAINTAINER_MODE
-
-# Configure options for texlive also shown at the TeX Live top-level.
-m4_include([ac/texlive.ac])
-AM_CONDITIONAL([LINKED_SCRIPTS], [test "x$enable_linked_scripts" != xno])
-
-AC_PROG_CC
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-
-KPSE_COND_WIN32_WRAP
-
-AC_CONFIG_FILES([Makefile
- linked_scripts/Makefile
- tl_support/Makefile])
-
-AC_OUTPUT
diff --git a/Build/source/texk/texlive/linked_scripts/ChangeLog b/Build/source/texk/texlive/linked_scripts/ChangeLog
deleted file mode 100644
index 45e69c6a134..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ChangeLog
+++ /dev/null
@@ -1,287 +0,0 @@
-2020-01-23 Karl Berry <karl@tug.org>
-
- * Makefile.am (texmf_shell_scripts): allcm.sh and allneeded.sh
- in the new texlive-extra/ belong here instead of texmf_other_scripts,
- since there is no Windows wrapper for them.
-
-2019-12-29 Karl Berry <karl@tug.org>
-
- * Makefile.am (texmf_other_scripts): add mktexlsr mktexmf
- mktexpk mktextfm, now maintained under Master.
- (bin_links): add mktexlsr:texhash.
-
-2016-04-10 Karl Berry <karl@tug.org>
-
- * Makefile.am (texmf_other_scripts): remove m-tx and pmx2pdf.
-
-2015-04-20 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (texmf_other_scripts): Add fmtutil-sys.sh and
- updmap-sys.sh (maintained under Master).
-
-2015-04-12 Norbert Preining <norbert@preining.info>
-
- * Makefile.am (texmf_other_scripts): add fmtutil
-
-2014-11-17 Karl Berry <karl@tug.org>
-
- * Makefile.am: Use WIN_WRAPPER (w32_wrapper or w64_wrapper).
-
-2014-07-18 Karl Berry <karl@tug.org>
-
- * Makefile.am (bin_links): mkluatexfontdb gone.
-
-2014-05-19 Karl Berry <karl@tug.org>
-
- * Makefile.am (texmf_context_scripts): add contextjit, mtxrunjit.
- Remove ctxtools and pstopdf, which are not to be user-level
- executables any more even though they remain in stubs, per Hans.
-
-2013-04-16 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am [WIN32], ../w32_wrapper/context/mtxrun.{dll,exe}:
- Update ConTeXt wrappers (from Hans).
-
-2013-04-15 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am [WIN32]: Install runscript.* and ConTeXt wrappers.
-
-2013-02-21 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am [WIN32]: Install arara.exe wrapper.
-
-2013-02-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (texmf_scriptsdir): Change texmf => texmf-dist.
- Change man dir link accordingly.
-
-2013-01-24 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am [WIN32]: Install {rungs,tlmgr}.exe wrappers.
-
-2012-09-09 Karl Berry <karl@tug.org>
-
- * Makefile.am (echo-shell-scripts): new target for
- check-wrapper-consistency.
-
-2012-08-09 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (installdirs-local): Make sure $(bindir) exists.
-
-2012-08-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * fmtutil*, tcfmgr*, texconfig*, texlinks* (new): Moved from
- ../../tetex/ to ./tetex/.
- * Makefile.am: Moved run-texlinks rule from /../tetex/ to here.
-
-2012-08-07 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * updmap.help2man, tetex/all*, tetex/dvi2fax*, tetex/dvired*,
- tetex/fontinst*, tetex/kpsetool*, tetex/kpsewhere*,
- tetex/ps2frag*, tetex/pslatex*, tetex/rubibtex*,
- tetex/rumakeindex*, tetex/updmap* (new): Moved from ../../tetex/
- to here.
- * Makefile.am: Added man1_links and rule for xupdmap.1.
-
-2012-08-06 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (texmf_*_scripts): Move a2ping/, simpdftex/,
- tetex/, and texdoc/ scripts from texmf/ to texmf-dist/.
-
- * tetex/{e2pall,texdoctk}.1, thumbpdf/thumbpdf.1 (new):
- Moved from ../../tetex/{e2pall,texdoctk,thumbpdf}.man to here.
- * Makefile.am: Added dist_man_MANS.
-
-2012-07-28 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (bin_links) [WIN32]: Skip shell script links.
-
-2011-12-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Rename the target scripts.tmp into scripts-list
- and make it available independent of maintainer mode.
- * README: Mention 'make scripts-list'.
-
-2011-12-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: More ${prefix} => $(datarootdir).
-
-2011-12-06 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Replace ${prefix}/texmf => $(datarootdir)/texmf.
-
-2011-12-05 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (uninstall-hook): Only remove man if it is a link.
-
-2011-12-03 Karl Berry <karl@tug.org>
-
- * Makefile.am (install-data-hook): only create the man link if it
- is a link already, and if TL_INSTALL_OMIT_MAN_LINK is unset
- in the environment. Report from Bruce Dubbs, 18 Nov 2011 18:56:22.
-
-2011-09-14 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (scripts.tmp): List each file on a separate line.
-
-2011-09-09 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (install-data-hook): Use new shell script relpath
- to compute relative path for linked scripts, mainly for distros.
-
-2011-07-29 Karl Berry <karl@tug.org>
-
- * Makefile.am (texmf_dist_other_scripts): add urlbst.
-
-2011-05-30 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (bin_links): Move mpost:metafun and mpost:mfplain
- from here to ../../web2c/mplibdir/am/mplib.am, where we also
- install the call_mpost.exe wrapper binary for WIN32/MinGW.
-
-2011-05-28 Karl Berry <karl@tug.org>
-
- * Makefile.am (bin_links): add mpost:metafun and mpost:mfplain
- since mpost no longer has mem files.
-
-2011-02-28 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * scripts.lst (new): Lists of texmf and texmf-dist scripts.
- * Makefile.am: If necessary, create/update scripts.lst
-
-2011-01-29 Karl Berry <karl@tug.org>
-
- * Makefile.am (texmf_dist_perl_scripts): add sty2dtx.pl.
-
-2010-12-29 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am [WIN32]: Install wrapper binary for bin_links
- (handled as aliases by runscript.tlu).
-
-2010-12-27 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (texmf_dist_perl_scripts): epspdf => epspdf.rb,
- epspdftk => epspdftk.tcl.
-
-2010-12-23 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (install-links): Check symlink creation.
-
-2010-12-23 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Distinguish shell and perl (or lua, ...) scripts.
- [WIN32]: Skip symlinks from bindir to texmf*/scripts/; install
- wrapper binaries for perl scripts.
-
-2010-05-30 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): remove context scripts.
- * context: remove subdir. We will install copies, not links.
-
-2010-05-25 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): context scripts for 2010.
-
-2010-04-11 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_scriptx_SCRIPTS): add bundledoc.
-
-2010-03-09 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): add de-macro.
-
-2010-01-11 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (install-links): Avoid dangling man symlink.
-
-2009-12-16 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): .pl for latexrevise
- and latexdiff-vc.
-
-2009-11-28 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): add bibexport.sh.
-
-2009-11-26 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): perltex is now perltex.pl.
-
-2009-11-26 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (bin_links): Remove getnonfreefonts-sys.
-
-2009-11-25 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_scriptx_SCRIPTS): remove getnonfreefonts.
-
-2009-10-15 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (bin_links): New list of symlinks within bindir.
- (install-links, uninstall-hook): Use `bin_links'.
-
-2009-10-15 Manuel Pégourié-Gonnard <mpg@elzevir.fr>
-
- * Makefile.am (install-links): create repstopdf as a link to epstopdf.
-
-2009-10-05 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): move epstopdf.pl here,
- from nobase_dist_scriptx_SCRIPTS.
-
-2009-10-05 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (uninstall-hook): remove listings-ext.sh symlink.
-
-2009-09-05 Karl Berry <karl@tug.org>
-
- * Makefile.am (install-links): we want listings-ext.sh in the
- bindir, not just listings-ext.
-
-2009-08-28 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): remove exatools
- pdftrimwhite texfind texshow, obsolete context scripts.
-
-2009-08-17 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (uninstall-hook): remove rpdfcrop symlink.
-
-2009-07-24 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): add mkgrkindex.
-
-2009-07-23 Karl Berry <karl@tug.org>
-
- * Makefile.am (install-links): create rpdfcrop as a link to pdfcrop.
-
-2009-06-03 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_scriptx_SCRIPTS): remove ps2eps.pl,
- it is installed in utils/ps2eps, and we can't easily separate
- it since the package also includes a C program.
-
-2009-05-21 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): move pkfix here
- (texmf-dist instead of texmf).
-
-2009-05-18 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): add ulqda.pl.
-
-2009-05-14 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): pdfthumb.texlua and
- ppower4.texlua are now pdfthumb.tlu and ppower4.tlu.
-
-2009-05-08 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): TeXcount.pl is now
- texcount.pl.
-
-2009-04-11 Karl Berry <karl@tug.org>
-
- * Makefile.am (nobase_dist_script_SCRIPTS): add accfonts scripts.
-
-(This ChangeLog public domain.)
diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.am b/Build/source/texk/texlive/linked_scripts/Makefile.am
deleted file mode 100644
index 3a698bb4652..00000000000
--- a/Build/source/texk/texlive/linked_scripts/Makefile.am
+++ /dev/null
@@ -1,387 +0,0 @@
-## $Id$
-## Makefile.am for the TeX Live subdirectory texk/texlive/linked_scripts/
-##
-## Copyright 2016-2020 Karl Berry <tex-live@tug.org>
-## Copyright 2009-2015 Peter Breitenlohner <tex-live@tug.org>
-## You may freely use, modify and/or distribute this file.
-##
-## TeX Live's extra scripts.
-
-## Build lists of scripts.
-##
-scripts-list: Makefile
- @echo "Create $@"
- @echo "texmf_scripts='" >$@
- @for f in $(nobase_dist_texmf_scripts_SCRIPTS); do echo "$$f"; done >>$@
- @echo "'" >>$@
- cmp -s $(srcdir)/scripts.lst $@ || cp -f $@ $(srcdir)/scripts.lst
-
-if MAINTAINER_MODE
-all-local: scripts-list
-else !MAINTAINER_MODE
-all-local:
-endif !MAINTAINER_MODE
-
-DISTCLEANFILES = scripts-list
-
-EXTRA_DIST = scripts.lst
-
-## Make sure $(bindir) exists
-##
-installdirs-local:
- $(MKDIR_P) $(DESTDIR)$(bindir)
-
-# Copies of these scripts exist here for the sake of avoiding
-# dangling symlinks produced by `make install'.
-# The instances in texmf* are the masters (except when it is CTAN).
-#
-## We distinguish several classes of scripts according to their
-## type: `shell', `context', or `other'.
-##
-## On Unix systems a symlink from $(bindir) to the script is installed
-## for all of them; on Windows nothing is installed in $(bindir) for
-## `shell' scripts whereas for `other' (usually perl, lua, ...) scripts
-## the standard wrapper ../$(WIN_WRAPPER)/runscript.exe is installed or
-## the ConTeXt wrapper ../$(WIN_WRAPPER)/context/mtxrun.exe for
-## `context' scripts.
-##
-## WIN_WRAPPER is w32_wrapper for 32-bit or w64_wrapper for 64-bit.
-##
-## The "shell" list aren't just shell scripts, in either direction.
-## Some /bin/sh scripts are listed as `other' or `context'
-## scripts because they are correctly handled by the wrapper binaries.
-## Conversely, some non-sh scripts are listed as `shell' because they
-## depend on shell scripts or otherwise aren't useful on Windows.
-##
-texmf_scriptsdir = $(datarootdir)/texmf-dist/scripts
-texmf_shell_scripts = \
- adhocfilelist/adhocfilelist.sh \
- bibexport/bibexport.sh \
- checklistings/checklistings.sh \
- ctanbib/ctanbib \
- dtxgen/dtxgen \
- git-latexdiff/git-latexdiff \
- installfont/installfont-tl \
- latexfileversion/latexfileversion \
- listbib/listbib \
- listings-ext/listings-ext.sh \
- ltxfileinfo/ltxfileinfo \
- pdfbook2/pdfbook2 \
- pdfjam/pdfjam \
- pdftex-quiet/pdftex-quiet \
- pdfxup/pdfxup \
- pst-pdf/ps4pdf \
- simpdftex/simpdftex \
- texlive-extra/allcm.sh \
- texlive-extra/allneeded.sh \
- texlive-extra/dvi2fax.sh \
- texlive-extra/dvired.sh \
- texlive-extra/fontinst.sh \
- texlive-extra/kpsetool.sh \
- texlive-extra/kpsewhere.sh \
- texlive-extra/ps2frag.sh \
- texlive-extra/pslatex.sh \
- texlive-extra/rubibtex.sh \
- texlive-extra/rumakeindex.sh \
- texlive-extra/texconfig-dialog.sh \
- texlive-extra/texconfig-sys.sh \
- texlive-extra/texconfig.sh \
- texlive-extra/texlinks.sh \
- texosquery/texosquery.sh \
- texosquery/texosquery-jre5.sh \
- texosquery/texosquery-jre8.sh \
- tikztosvg/tikztosvg \
- typeoutfileinfo/typeoutfileinfo.sh \
- wordcount/wordcount.sh
-
-texmf_other_scripts = \
- a2ping/a2ping.pl \
- accfonts/mkt1font \
- accfonts/vpl2ovp \
- accfonts/vpl2vpl \
- albatross/albatross.sh \
- arara/arara.sh \
- attachfile2/pdfatfi.pl \
- authorindex/authorindex \
- bib2gls/bib2gls.sh \
- bib2gls/convertgls2bib.sh \
- bundledoc/arlatex \
- bundledoc/bundledoc \
- cachepic/cachepic.tlu \
- checkcites/checkcites.lua \
- chklref/chklref.pl \
- cjk-gs-integrate/cjk-gs-integrate.pl \
- clojure-pamphlet/pamphletangler \
- cluttex/cluttex.lua \
- context/perl/mptopdf.pl \
- convbkmk/convbkmk.rb \
- crossrefware/bbl2bib.pl \
- crossrefware/bibdoiadd.pl \
- crossrefware/bibmradd.pl \
- crossrefware/biburl2doi.pl \
- crossrefware/bibzbladd.pl \
- crossrefware/ltx2crossrefxml.pl \
- ctan-o-mat/ctan-o-mat.pl \
- ctanify/ctanify \
- ctanupload/ctanupload.pl \
- de-macro/de-macro \
- diadia/diadia.lua \
- dosepsbin/dosepsbin.pl \
- dviasm/dviasm.py \
- dviinfox/dviinfox.pl \
- ebong/ebong.py \
- epspdf/epspdf.tlu \
- epspdf/epspdftk.tcl \
- epstopdf/epstopdf.pl \
- exceltex/exceltex \
- fig4latex/fig4latex \
- findhyph/findhyph \
- fontools/afm2afm \
- fontools/autoinst \
- fontools/ot2kpx \
- fragmaster/fragmaster.pl \
- getmap/getmapdl.lua \
- glossaries/makeglossaries \
- glossaries/makeglossaries-lite.lua \
- hyperxmp/hyperxmp-add-bytecount.pl \
- jfmutil/jfmutil.pl \
- ketcindy/ketcindy.pl \
- kotex-utils/jamo-normalize.pl \
- kotex-utils/komkindex.pl \
- kotex-utils/ttf2kotexfont.pl \
- l3build/l3build.lua \
- latex-git-log/latex-git-log \
- latex-papersize/latex-papersize.py \
- latex2man/latex2man \
- latex2nemeth/latex2nemeth \
- latexdiff/latexdiff-vc.pl \
- latexdiff/latexdiff.pl \
- latexdiff/latexrevise.pl \
- latexindent/latexindent.pl \
- latexmk/latexmk.pl \
- latexpand/latexpand \
- light-latex-make/llmk.lua \
- lilyglyphs/lily-glyph-commands.py \
- lilyglyphs/lily-image-commands.py \
- lilyglyphs/lily-rebuild-pdfs.py \
- ltximg/ltximg.pl \
- luaotfload/luaotfload-tool.lua \
- lwarp/lwarpmk.lua \
- m-tx/m-tx.lua \
- makedtx/makedtx.pl \
- make4ht/make4ht \
- match_parens/match_parens \
- mathspic/mathspic.pl \
- mf2pt1/mf2pt1.pl \
- mkgrkindex/mkgrkindex \
- mkjobtexmf/mkjobtexmf.pl \
- mkpic/mkpic \
- multibibliography/multibibliography.pl \
- musixtex/musixflx.lua \
- musixtex/musixtex.lua \
- pax/pdfannotextractor.pl \
- pdfcrop/pdfcrop.pl \
- pdflatexpicscale/pdflatexpicscale.pl \
- pedigree-perl/pedigree.pl \
- perltex/perltex.pl \
- petri-nets/pn2pdf \
- pfarrei/a5toa4.tlu \
- pfarrei/pfarrei.tlu \
- pkfix-helper/pkfix-helper \
- pkfix/pkfix.pl \
- pmxchords/pmxchords.lua \
- pst2pdf/pst2pdf.pl \
- ptex-fontmaps/kanji-config-updmap-sys.sh \
- ptex-fontmaps/kanji-config-updmap-user.sh \
- ptex-fontmaps/kanji-config-updmap.pl \
- ptex-fontmaps/kanji-fontmap-creator.pl \
- ptex2pdf/ptex2pdf.lua \
- purifyeps/purifyeps \
- pygmentex/pygmentex.py \
- pythontex/depythontex.py \
- pythontex/pythontex.py \
- rubik/rubikrotation.pl \
- spix/spix.py \
- splitindex/splitindex.pl \
- srcredact/srcredact.pl \
- sty2dtx/sty2dtx.pl \
- svn-multi/svn-multi.pl \
- tex4ebook/tex4ebook \
- texcount/texcount.pl \
- texdef/texdef.pl \
- texdiff/texdiff \
- texdirflatten/texdirflatten \
- texdoc/texdoc.tlu \
- texfot/texfot.pl \
- texlive/fmtutil-sys.sh \
- texlive/fmtutil-user.sh \
- texlive/fmtutil.pl \
- texlive/mktexlsr \
- texlive/mktexmf \
- texlive/mktexpk \
- texlive/mktextfm \
- texlive/rungs.tlu \
- texlive/tlmgr.pl \
- texlive/updmap-sys.sh \
- texlive/updmap-user.sh \
- texlive/updmap.pl \
- texlive-extra/e2pall.pl \
- texliveonfly/texliveonfly.py \
- texloganalyser/texloganalyser \
- texplate/texplate.sh \
- thumbpdf/thumbpdf.pl \
- tlcockpit/tlcockpit.sh \
- tlshell/tlshell.tcl \
- ulqda/ulqda.pl \
- urlbst/urlbst \
- vpe/vpe.pl \
- webquiz/webquiz.py \
- xindex/xindex.lua \
- yplan/yplan
-
-texmf_context_scripts = \
- context/stubs/unix/context \
- context/stubs/unix/contextjit \
- context/stubs/unix/luatools \
- context/stubs/unix/mtxrun \
- context/stubs/unix/mtxrunjit \
- context/stubs/unix/texexec \
- context/stubs/unix/texmfstart
-
-EXTRA_DIST += \
- context/stubs/unix/ctxtools \
- context/stubs/unix/pstopdf
-
-nobase_dist_texmf_scripts_SCRIPTS = \
- $(texmf_shell_scripts) \
- $(texmf_other_scripts) \
- $(texmf_context_scripts)
-
-## Symlinks within $(bindir): FILE:LINK here means "ln -s FILE LINK" is done.
-bin_links = \
- allcm:allec \
- cluttex:clxelatex \
- cluttex:cllualatex \
- epstopdf:repstopdf \
- fmtutil:mktexfmt \
- kpsetool:kpsexpand \
- kpsetool:kpsepath \
- mktexlsr:texhash \
- pdfcrop:rpdfcrop \
- texdef:latexdef
-
-#
-# The idea is to install the scripts themselves in texmf*/scripts, and
-# have bin/arch/foo be a symlink to, say,
-# ../../texmf-dist/scripts/foo/foo.pl. That way we save a bit of disk
-# space, but more importantly omit duplication, and most
-# importantly of all make it possible to invoke the same Perl script on
-# Windows (see ../$(WIN_WRAPPER)).
-#
-# The installation into texmf*/scripts is ideally done with ctan2tl.
-# The copy of the wrapper for Windows is also done by ctan2tl. (And
-# for shell scripts, its addition must be undone by hand.) The
-# check-wrapper-consistency script checks after the fact for problems.
-#
-# We also keep a copy of all the scripts here and install into the runtime.
-# This is purely for other distro builders, so symlinks are not dangling in
-# the inst/bin dir (it is meaningless in native TL). We have not yet
-# written the auto-update to ensure linked_scripts is actually up to date
-# with the masters in Master/texmf*/scripts, but one day.
-#
-# We support native builds, multiplatform or not, as well as distro builds.
-#
-EXTRA_DIST += ../../../build-aux/relpath
-relpath = $(SHELL) $(top_srcdir)/../../build-aux/relpath
-runscript = $(top_srcdir)/$(WIN_WRAPPER)/runscript.exe
-ctxscript = $(top_srcdir)/$(WIN_WRAPPER)/context/mtxrun.exe
-install-data-hook: installdirs-local
-if WIN32
- @for s in $(texmf_other_scripts); do \
- t=`basename $$s | sed 's,\.[^/]*$$,,' | tr '[A-Z]' '[a-z]'`; \
- echo "$(INSTALL_SCRIPT) '$(runscript)' '$(DESTDIR)$(bindir)/$$t.exe'"; \
- $(INSTALL_SCRIPT) $(runscript) $(DESTDIR)$(bindir)/$$t.exe; \
- done
- $(INSTALL_SCRIPT) $(top_srcdir)/$(WIN_WRAPPER)/runscript.dll $(DESTDIR)$(bindir)
- $(INSTALL_SCRIPT) $(top_srcdir)/$(WIN_WRAPPER)/runscript.exe $(DESTDIR)$(bindir)
- $(INSTALL_SCRIPT) $(top_srcdir)/w32_wrapper/runscript.tlu $(DESTDIR)$(bindir)
- @for s in $(texmf_context_scripts); do \
- t=`basename $$s | sed 's,\.[^/]*$$,,' | tr '[A-Z]' '[a-z]'`; \
- echo "$(INSTALL_SCRIPT) '$(ctxscript)' '$(DESTDIR)$(bindir)/$$t.exe'"; \
- $(INSTALL_SCRIPT) $(ctxscript) $(DESTDIR)$(bindir)/$$t.exe; \
- done
- $(INSTALL_SCRIPT) $(top_srcdir)/$(WIN_WRAPPER)/context/mtxrun.dll $(DESTDIR)$(bindir)
- $(INSTALL_SCRIPT) $(srcdir)/context/stubs/unix/mtxrun $(DESTDIR)$(bindir)/mtxrun.lua
- @for s in $(bin_links); do \
- link=`echo $$s | sed 's,.*:,,'`; \
- echo "$(INSTALL_SCRIPT) '$(runscript)' '$(DESTDIR)$(bindir)/$$link.exe'"; \
- $(INSTALL_SCRIPT) $(runscript) $(DESTDIR)$(bindir)/$$link.exe || exit 1; \
- done
-else !WIN32
-## Name the link as the basename, removing any extension,
-## except for listings-ext.sh, which is documented as that name.
-## Downcase for the sake of TeXcount.pl -> texcount.
- @REL=`$(relpath) '$(DESTDIR)' '$(bindir)' '$(datarootdir)'`; \
- if test -z "$$REL"; then \
- echo 'unable to compute relative path for linked scripts' >&2; \
- exit 1; \
- fi; \
- cd $(DESTDIR)$(bindir) && \
- for s in $(nobase_dist_texmf_scripts_SCRIPTS); do \
- target=`basename $$s | tr '[A-Z]' '[a-z]'`; \
- echo "$$s" | grep listings-ext.sh >/dev/null \
- || target=`echo $$target | sed 's,\.[^/]*$$,,'`; \
- rm -f $$target; \
- echo "creating link '$$target' -> '$$REL/texmf-dist/scripts/$$s'"; \
- $(LN_S) $$REL/texmf-dist/scripts/$$s $$target || exit 1; \
- done && \
- for s in $(bin_links); do \
- link=`echo $$s | sed 's,.*:,,'`; \
- file=`echo $$s | sed 's,:.*,,'`; \
- rm -f $$link; \
- echo "creating link '$$link' -> '$$file'"; \
- $(LN_S) $$file $$link || exit 1; \
- done && \
-## man dir link for those mans which can use it, but don't overwrite a
-## real file, e.g., /usr/bin/man.
- if test -d "$$REL/texmf-dist/doc/man" \
- && test -z "$(TL_INSTALL_OMIT_MAN_LINK)" \
- && (test -h man || test ! -e man); then \
- echo "creating link 'man' -> '$$REL/texmf-dist/doc/man'"; \
- rm -f man; \
- (ln -s "$$REL/texmf-dist/doc/man" man || :); \
- else :; fi
-endif !WIN32
-
-.PHONY: install-links
-install-links:
-
-## For WIN32 (MinGW or native) we have wrapper binaries with .exe,
-## for Cygwin and Unix we have symlinks without .exe.
-if WIN32
-WINEXT = $(EXEEXT)
-endif WIN32
-
-uninstall-hook:
- @for s in $(nobase_dist_texmf_scripts_SCRIPTS); do \
- target=`basename $$s | tr '[A-Z]' '[a-z]'`; \
- echo "$$s" | grep listings-ext.sh >/dev/null \
- || target=`echo $$target | sed 's,\.[^/]*$$,,'`; \
- rm -f $(DESTDIR)$(bindir)/$$target$(WINEXT); \
- done
- @for s in $(bin_links); do \
- link=`echo $$s | sed 's,.*:,,'`; \
- rm -f $(DESTDIR)$(bindir)/$$link$(WINEXT); \
- done
-if !WIN32
- if test -h $(DESTDIR)$(bindir)/man; then \
- rm -f $(DESTDIR)$(bindir)/man; \
- else :; fi
-endif !WIN32
-
-##
-## This target is invoked by check-wrapper-consistency (run from cron).
-.PHONY: echo-shell-scripts
-shell_scripts = $(texmf_shell_scripts) $(texmf_context_scripts)
-echo-shell-scripts:
- @echo $(shell_scripts)
diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.in b/Build/source/texk/texlive/linked_scripts/Makefile.in
deleted file mode 100644
index e64e3117b7d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/Makefile.in
+++ /dev/null
@@ -1,811 +0,0 @@
-# Makefile.in generated by automake 1.16.3 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-subdir = linked_scripts
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../../m4/kpse-win32.m4 \
- $(top_srcdir)/../../version.ac $(top_srcdir)/ac/texlive.ac \
- $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am \
- $(nobase_dist_texmf_scripts_SCRIPTS) $(am__DIST_COMMON)
-mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
- test -z "$$files" \
- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
- $(am__cd) "$$dir" && rm -f $$files; }; \
- }
-am__installdirs = "$(DESTDIR)$(texmf_scriptsdir)"
-SCRIPTS = $(nobase_dist_texmf_scripts_SCRIPTS)
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 =
-SOURCES =
-DIST_SOURCES =
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in ChangeLog README
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EXEEXT = @EXEEXT@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-WIN_WRAPPER = @WIN_WRAPPER@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-DISTCLEANFILES = scripts-list
-
-#
-# The idea is to install the scripts themselves in texmf*/scripts, and
-# have bin/arch/foo be a symlink to, say,
-# ../../texmf-dist/scripts/foo/foo.pl. That way we save a bit of disk
-# space, but more importantly omit duplication, and most
-# importantly of all make it possible to invoke the same Perl script on
-# Windows (see ../$(WIN_WRAPPER)).
-#
-# The installation into texmf*/scripts is ideally done with ctan2tl.
-# The copy of the wrapper for Windows is also done by ctan2tl. (And
-# for shell scripts, its addition must be undone by hand.) The
-# check-wrapper-consistency script checks after the fact for problems.
-#
-# We also keep a copy of all the scripts here and install into the runtime.
-# This is purely for other distro builders, so symlinks are not dangling in
-# the inst/bin dir (it is meaningless in native TL). We have not yet
-# written the auto-update to ensure linked_scripts is actually up to date
-# with the masters in Master/texmf*/scripts, but one day.
-#
-# We support native builds, multiplatform or not, as well as distro builds.
-#
-EXTRA_DIST = scripts.lst context/stubs/unix/ctxtools \
- context/stubs/unix/pstopdf ../../../build-aux/relpath
-
-# Copies of these scripts exist here for the sake of avoiding
-# dangling symlinks produced by `make install'.
-# The instances in texmf* are the masters (except when it is CTAN).
-#
-texmf_scriptsdir = $(datarootdir)/texmf-dist/scripts
-texmf_shell_scripts = \
- adhocfilelist/adhocfilelist.sh \
- bibexport/bibexport.sh \
- checklistings/checklistings.sh \
- ctanbib/ctanbib \
- dtxgen/dtxgen \
- git-latexdiff/git-latexdiff \
- installfont/installfont-tl \
- latexfileversion/latexfileversion \
- listbib/listbib \
- listings-ext/listings-ext.sh \
- ltxfileinfo/ltxfileinfo \
- pdfbook2/pdfbook2 \
- pdfjam/pdfjam \
- pdftex-quiet/pdftex-quiet \
- pdfxup/pdfxup \
- pst-pdf/ps4pdf \
- simpdftex/simpdftex \
- texlive-extra/allcm.sh \
- texlive-extra/allneeded.sh \
- texlive-extra/dvi2fax.sh \
- texlive-extra/dvired.sh \
- texlive-extra/fontinst.sh \
- texlive-extra/kpsetool.sh \
- texlive-extra/kpsewhere.sh \
- texlive-extra/ps2frag.sh \
- texlive-extra/pslatex.sh \
- texlive-extra/rubibtex.sh \
- texlive-extra/rumakeindex.sh \
- texlive-extra/texconfig-dialog.sh \
- texlive-extra/texconfig-sys.sh \
- texlive-extra/texconfig.sh \
- texlive-extra/texlinks.sh \
- texosquery/texosquery.sh \
- texosquery/texosquery-jre5.sh \
- texosquery/texosquery-jre8.sh \
- tikztosvg/tikztosvg \
- typeoutfileinfo/typeoutfileinfo.sh \
- wordcount/wordcount.sh
-
-texmf_other_scripts = \
- a2ping/a2ping.pl \
- accfonts/mkt1font \
- accfonts/vpl2ovp \
- accfonts/vpl2vpl \
- albatross/albatross.sh \
- arara/arara.sh \
- attachfile2/pdfatfi.pl \
- authorindex/authorindex \
- bib2gls/bib2gls.sh \
- bib2gls/convertgls2bib.sh \
- bundledoc/arlatex \
- bundledoc/bundledoc \
- cachepic/cachepic.tlu \
- checkcites/checkcites.lua \
- chklref/chklref.pl \
- cjk-gs-integrate/cjk-gs-integrate.pl \
- clojure-pamphlet/pamphletangler \
- cluttex/cluttex.lua \
- context/perl/mptopdf.pl \
- convbkmk/convbkmk.rb \
- crossrefware/bbl2bib.pl \
- crossrefware/bibdoiadd.pl \
- crossrefware/bibmradd.pl \
- crossrefware/biburl2doi.pl \
- crossrefware/bibzbladd.pl \
- crossrefware/ltx2crossrefxml.pl \
- ctan-o-mat/ctan-o-mat.pl \
- ctanify/ctanify \
- ctanupload/ctanupload.pl \
- de-macro/de-macro \
- diadia/diadia.lua \
- dosepsbin/dosepsbin.pl \
- dviasm/dviasm.py \
- dviinfox/dviinfox.pl \
- ebong/ebong.py \
- epspdf/epspdf.tlu \
- epspdf/epspdftk.tcl \
- epstopdf/epstopdf.pl \
- exceltex/exceltex \
- fig4latex/fig4latex \
- findhyph/findhyph \
- fontools/afm2afm \
- fontools/autoinst \
- fontools/ot2kpx \
- fragmaster/fragmaster.pl \
- getmap/getmapdl.lua \
- glossaries/makeglossaries \
- glossaries/makeglossaries-lite.lua \
- hyperxmp/hyperxmp-add-bytecount.pl \
- jfmutil/jfmutil.pl \
- ketcindy/ketcindy.pl \
- kotex-utils/jamo-normalize.pl \
- kotex-utils/komkindex.pl \
- kotex-utils/ttf2kotexfont.pl \
- l3build/l3build.lua \
- latex-git-log/latex-git-log \
- latex-papersize/latex-papersize.py \
- latex2man/latex2man \
- latex2nemeth/latex2nemeth \
- latexdiff/latexdiff-vc.pl \
- latexdiff/latexdiff.pl \
- latexdiff/latexrevise.pl \
- latexindent/latexindent.pl \
- latexmk/latexmk.pl \
- latexpand/latexpand \
- light-latex-make/llmk.lua \
- lilyglyphs/lily-glyph-commands.py \
- lilyglyphs/lily-image-commands.py \
- lilyglyphs/lily-rebuild-pdfs.py \
- ltximg/ltximg.pl \
- luaotfload/luaotfload-tool.lua \
- lwarp/lwarpmk.lua \
- m-tx/m-tx.lua \
- makedtx/makedtx.pl \
- make4ht/make4ht \
- match_parens/match_parens \
- mathspic/mathspic.pl \
- mf2pt1/mf2pt1.pl \
- mkgrkindex/mkgrkindex \
- mkjobtexmf/mkjobtexmf.pl \
- mkpic/mkpic \
- multibibliography/multibibliography.pl \
- musixtex/musixflx.lua \
- musixtex/musixtex.lua \
- pax/pdfannotextractor.pl \
- pdfcrop/pdfcrop.pl \
- pdflatexpicscale/pdflatexpicscale.pl \
- pedigree-perl/pedigree.pl \
- perltex/perltex.pl \
- petri-nets/pn2pdf \
- pfarrei/a5toa4.tlu \
- pfarrei/pfarrei.tlu \
- pkfix-helper/pkfix-helper \
- pkfix/pkfix.pl \
- pmxchords/pmxchords.lua \
- pst2pdf/pst2pdf.pl \
- ptex-fontmaps/kanji-config-updmap-sys.sh \
- ptex-fontmaps/kanji-config-updmap-user.sh \
- ptex-fontmaps/kanji-config-updmap.pl \
- ptex-fontmaps/kanji-fontmap-creator.pl \
- ptex2pdf/ptex2pdf.lua \
- purifyeps/purifyeps \
- pygmentex/pygmentex.py \
- pythontex/depythontex.py \
- pythontex/pythontex.py \
- rubik/rubikrotation.pl \
- spix/spix.py \
- splitindex/splitindex.pl \
- srcredact/srcredact.pl \
- sty2dtx/sty2dtx.pl \
- svn-multi/svn-multi.pl \
- tex4ebook/tex4ebook \
- texcount/texcount.pl \
- texdef/texdef.pl \
- texdiff/texdiff \
- texdirflatten/texdirflatten \
- texdoc/texdoc.tlu \
- texfot/texfot.pl \
- texlive/fmtutil-sys.sh \
- texlive/fmtutil-user.sh \
- texlive/fmtutil.pl \
- texlive/mktexlsr \
- texlive/mktexmf \
- texlive/mktexpk \
- texlive/mktextfm \
- texlive/rungs.tlu \
- texlive/tlmgr.pl \
- texlive/updmap-sys.sh \
- texlive/updmap-user.sh \
- texlive/updmap.pl \
- texlive-extra/e2pall.pl \
- texliveonfly/texliveonfly.py \
- texloganalyser/texloganalyser \
- texplate/texplate.sh \
- thumbpdf/thumbpdf.pl \
- tlcockpit/tlcockpit.sh \
- tlshell/tlshell.tcl \
- ulqda/ulqda.pl \
- urlbst/urlbst \
- vpe/vpe.pl \
- webquiz/webquiz.py \
- xindex/xindex.lua \
- yplan/yplan
-
-texmf_context_scripts = \
- context/stubs/unix/context \
- context/stubs/unix/contextjit \
- context/stubs/unix/luatools \
- context/stubs/unix/mtxrun \
- context/stubs/unix/mtxrunjit \
- context/stubs/unix/texexec \
- context/stubs/unix/texmfstart
-
-nobase_dist_texmf_scripts_SCRIPTS = \
- $(texmf_shell_scripts) \
- $(texmf_other_scripts) \
- $(texmf_context_scripts)
-
-bin_links = \
- allcm:allec \
- cluttex:clxelatex \
- cluttex:cllualatex \
- epstopdf:repstopdf \
- fmtutil:mktexfmt \
- kpsetool:kpsexpand \
- kpsetool:kpsepath \
- mktexlsr:texhash \
- pdfcrop:rpdfcrop \
- texdef:latexdef
-
-relpath = $(SHELL) $(top_srcdir)/../../build-aux/relpath
-runscript = $(top_srcdir)/$(WIN_WRAPPER)/runscript.exe
-ctxscript = $(top_srcdir)/$(WIN_WRAPPER)/context/mtxrun.exe
-@WIN32_TRUE@WINEXT = $(EXEEXT)
-shell_scripts = $(texmf_shell_scripts) $(texmf_context_scripts)
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign linked_scripts/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign linked_scripts/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-nobase_dist_texmf_scriptsSCRIPTS: $(nobase_dist_texmf_scripts_SCRIPTS)
- @$(NORMAL_INSTALL)
- @list='$(nobase_dist_texmf_scripts_SCRIPTS)'; test -n "$(texmf_scriptsdir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(texmf_scriptsdir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(texmf_scriptsdir)" || exit 1; \
- fi; \
- $(am__nobase_strip_setup); \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n' \
- -e "s|$$srcdirstrip/||" -e 'h;s|[^/]*$$||; s|^$$|.|' \
- -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) { files[d] = files[d] " " $$1; \
- if (++n[d] == $(am__install_max)) { \
- print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
- else { print "f", d "/" $$4, $$1 } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- case $$type in \
- d) echo " $(MKDIR_P) '$(DESTDIR)$(texmf_scriptsdir)/$$dir'"; \
- $(MKDIR_P) "$(DESTDIR)$(texmf_scriptsdir)/$$dir" || exit $$?;; \
- f) \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(texmf_scriptsdir)$$dir'"; \
- $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(texmf_scriptsdir)$$dir" || exit $$?; \
- } \
- ;; esac \
- ; done
-
-uninstall-nobase_dist_texmf_scriptsSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(nobase_dist_texmf_scripts_SCRIPTS)'; test -n "$(texmf_scriptsdir)" || exit 0; \
- $(am__nobase_strip_setup); \
- files=`$(am__nobase_strip) \
- -e 'h;s,.*/,,;$(transform);x;s|[^/]*$$||;G;s,\n,,'`; \
- dir='$(DESTDIR)$(texmf_scriptsdir)'; $(am__uninstall_files_from_dir)
-tags TAGS:
-
-ctags CTAGS:
-
-cscope cscopelist:
-
-
-distdir: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) distdir-am
-
-distdir-am: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(SCRIPTS) all-local
-installdirs: installdirs-local
- for dir in "$(DESTDIR)$(texmf_scriptsdir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
- -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-nobase_dist_texmf_scriptsSCRIPTS
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-data-hook
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-nobase_dist_texmf_scriptsSCRIPTS
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
-.MAKE: install-am install-data-am install-strip uninstall-am
-
-.PHONY: all all-am all-local check check-am clean clean-generic \
- cscopelist-am ctags-am distclean distclean-generic distdir dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-data-hook install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-nobase_dist_texmf_scriptsSCRIPTS install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs installdirs-local \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \
- uninstall-am uninstall-hook \
- uninstall-nobase_dist_texmf_scriptsSCRIPTS
-
-.PRECIOUS: Makefile
-
-
-scripts-list: Makefile
- @echo "Create $@"
- @echo "texmf_scripts='" >$@
- @for f in $(nobase_dist_texmf_scripts_SCRIPTS); do echo "$$f"; done >>$@
- @echo "'" >>$@
- cmp -s $(srcdir)/scripts.lst $@ || cp -f $@ $(srcdir)/scripts.lst
-
-@MAINTAINER_MODE_TRUE@all-local: scripts-list
-@MAINTAINER_MODE_FALSE@all-local:
-
-installdirs-local:
- $(MKDIR_P) $(DESTDIR)$(bindir)
-install-data-hook: installdirs-local
-@WIN32_TRUE@ @for s in $(texmf_other_scripts); do \
-@WIN32_TRUE@ t=`basename $$s | sed 's,\.[^/]*$$,,' | tr '[A-Z]' '[a-z]'`; \
-@WIN32_TRUE@ echo "$(INSTALL_SCRIPT) '$(runscript)' '$(DESTDIR)$(bindir)/$$t.exe'"; \
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(runscript) $(DESTDIR)$(bindir)/$$t.exe; \
-@WIN32_TRUE@ done
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(top_srcdir)/$(WIN_WRAPPER)/runscript.dll $(DESTDIR)$(bindir)
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(top_srcdir)/$(WIN_WRAPPER)/runscript.exe $(DESTDIR)$(bindir)
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(top_srcdir)/w32_wrapper/runscript.tlu $(DESTDIR)$(bindir)
-@WIN32_TRUE@ @for s in $(texmf_context_scripts); do \
-@WIN32_TRUE@ t=`basename $$s | sed 's,\.[^/]*$$,,' | tr '[A-Z]' '[a-z]'`; \
-@WIN32_TRUE@ echo "$(INSTALL_SCRIPT) '$(ctxscript)' '$(DESTDIR)$(bindir)/$$t.exe'"; \
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(ctxscript) $(DESTDIR)$(bindir)/$$t.exe; \
-@WIN32_TRUE@ done
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(top_srcdir)/$(WIN_WRAPPER)/context/mtxrun.dll $(DESTDIR)$(bindir)
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(srcdir)/context/stubs/unix/mtxrun $(DESTDIR)$(bindir)/mtxrun.lua
-@WIN32_TRUE@ @for s in $(bin_links); do \
-@WIN32_TRUE@ link=`echo $$s | sed 's,.*:,,'`; \
-@WIN32_TRUE@ echo "$(INSTALL_SCRIPT) '$(runscript)' '$(DESTDIR)$(bindir)/$$link.exe'"; \
-@WIN32_TRUE@ $(INSTALL_SCRIPT) $(runscript) $(DESTDIR)$(bindir)/$$link.exe || exit 1; \
-@WIN32_TRUE@ done
-@WIN32_FALSE@ @REL=`$(relpath) '$(DESTDIR)' '$(bindir)' '$(datarootdir)'`; \
-@WIN32_FALSE@ if test -z "$$REL"; then \
-@WIN32_FALSE@ echo 'unable to compute relative path for linked scripts' >&2; \
-@WIN32_FALSE@ exit 1; \
-@WIN32_FALSE@ fi; \
-@WIN32_FALSE@ cd $(DESTDIR)$(bindir) && \
-@WIN32_FALSE@ for s in $(nobase_dist_texmf_scripts_SCRIPTS); do \
-@WIN32_FALSE@ target=`basename $$s | tr '[A-Z]' '[a-z]'`; \
-@WIN32_FALSE@ echo "$$s" | grep listings-ext.sh >/dev/null \
-@WIN32_FALSE@ || target=`echo $$target | sed 's,\.[^/]*$$,,'`; \
-@WIN32_FALSE@ rm -f $$target; \
-@WIN32_FALSE@ echo "creating link '$$target' -> '$$REL/texmf-dist/scripts/$$s'"; \
-@WIN32_FALSE@ $(LN_S) $$REL/texmf-dist/scripts/$$s $$target || exit 1; \
-@WIN32_FALSE@ done && \
-@WIN32_FALSE@ for s in $(bin_links); do \
-@WIN32_FALSE@ link=`echo $$s | sed 's,.*:,,'`; \
-@WIN32_FALSE@ file=`echo $$s | sed 's,:.*,,'`; \
-@WIN32_FALSE@ rm -f $$link; \
-@WIN32_FALSE@ echo "creating link '$$link' -> '$$file'"; \
-@WIN32_FALSE@ $(LN_S) $$file $$link || exit 1; \
-@WIN32_FALSE@ done && \
-@WIN32_FALSE@ if test -d "$$REL/texmf-dist/doc/man" \
-@WIN32_FALSE@ && test -z "$(TL_INSTALL_OMIT_MAN_LINK)" \
-@WIN32_FALSE@ && (test -h man || test ! -e man); then \
-@WIN32_FALSE@ echo "creating link 'man' -> '$$REL/texmf-dist/doc/man'"; \
-@WIN32_FALSE@ rm -f man; \
-@WIN32_FALSE@ (ln -s "$$REL/texmf-dist/doc/man" man || :); \
-@WIN32_FALSE@ else :; fi
-
-.PHONY: install-links
-install-links:
-
-uninstall-hook:
- @for s in $(nobase_dist_texmf_scripts_SCRIPTS); do \
- target=`basename $$s | tr '[A-Z]' '[a-z]'`; \
- echo "$$s" | grep listings-ext.sh >/dev/null \
- || target=`echo $$target | sed 's,\.[^/]*$$,,'`; \
- rm -f $(DESTDIR)$(bindir)/$$target$(WINEXT); \
- done
- @for s in $(bin_links); do \
- link=`echo $$s | sed 's,.*:,,'`; \
- rm -f $(DESTDIR)$(bindir)/$$link$(WINEXT); \
- done
-@WIN32_FALSE@ if test -h $(DESTDIR)$(bindir)/man; then \
-@WIN32_FALSE@ rm -f $(DESTDIR)$(bindir)/man; \
-@WIN32_FALSE@ else :; fi
-
-.PHONY: echo-shell-scripts
-echo-shell-scripts:
- @echo $(shell_scripts)
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Build/source/texk/texlive/linked_scripts/README b/Build/source/texk/texlive/linked_scripts/README
deleted file mode 100644
index d512a83ddb5..00000000000
--- a/Build/source/texk/texlive/linked_scripts/README
+++ /dev/null
@@ -1,31 +0,0 @@
-$Id$
-Copyright (C) 2012 Norbert Preining <tex-live@tug.org>
-You may freely use, modify and/or distribute this file.
-
-source/texk/texlive/linked_scripts
-==================================
-This directory contains copies of the scripts that are shipped within
-TeX Live. See more discussion, rationale, etc., in ./Makefile.am.
-
-Steps to add a new script (take your time, do it right):
-
-* svn mkdir the directory with the package name, and add the script
-
-* add the dir/script-name to Makefile.am in the respective section
- (shell vs general interpreter, texmf vs texmf-dist)
-
-* add the package/script to ctan2tds so that is found and installed
- automatically (%specialscripts), etc.
-
-* get ctan2tl to run properly
-
-* cd .. && autoreconf -v
- But only commit the results of this last if you have the same version
- of GNU m4, libtool, autoconf, automake, etc., installed that were
- already used (generally the latest official releases). And if you
- have installed the original versions straight from ftp.gnu.org for
- yourself -- don't use versions from distro packages.
-
-* make -C BLD/texk/texlive/linked_scripts scripts-list
- where BLD is the build tree, to update the file scripts.lst in the
- source tree (or manually update that file).
diff --git a/Build/source/texk/texlive/linked_scripts/a2ping/a2ping.pl b/Build/source/texk/texlive/linked_scripts/a2ping/a2ping.pl
deleted file mode 100755
index b639fb9d2af..00000000000
--- a/Build/source/texk/texlive/linked_scripts/a2ping/a2ping.pl
+++ /dev/null
@@ -1,2584 +0,0 @@
-#! /bin/sh
-eval '(exit $?0)' && eval 'PERL_BADLANG=x;export PERL_BADLANG;: \
-;exec perl -x -- "$0" ${1+"$@"};#'if 0;
-eval 'setenv PERL_BADLANG x;exec perl -x -- "$0" $argv:q;#'.q+
-#!perl -w
-package Htex::a2ping; $0=~/(.*)/s;unshift@INC,'.';do($1);die$@if$@;__END__+if !1;
-# Don't touch/remove any lines above; http://www.inf.bme.hu/~pts/justlib
-#
-# This program is free software, licensed under the GNU GPL, >=2.0.
-# This software comes with absolutely NO WARRANTY. Use at your own risk!
-#
-# !! Ghostcript compute pipe too slow
-# $ a2ping.pl -v debrecen-hyph.ps debrecen-hyph.pdf
-# a2ping.pl ... -- Written by <pts@fazekas.hu> from April 2003.
-# This is free software, GNU GPL >=2.0. There is NO WARRANTY.
-# (epstopdf 2.7 Copyright 1998-2001 by Sebastian Rahtz et al.)
-# * Strongest BoundingBox comment: %%HiResBoundingBox:
-# * Doing --PaperSize unchanged
-# * Output filename: debrecen-hyph.pdf
-# * Output FileFormat: PDF
-# * Ghostscript ps2pdf command: gs -dSAFER
-# * Compression: zip
-# * Input filename: debrecen-hyph.ps
-# * Computing BBox info from non-EPS PS file
-# * Ghostscript compute pipe: gs -dSAFER -dWRITESYSTEMDICT -dNOPAUSE -sDEVICE=bbox -sFN=debrecen-hyph.ps /tmp/a2ping_pl-16977-298938572-c.tgs 2>&1
-# * Applying BoundingBox from Compute-GS T-: 71 81 539 769
-# * Applying HiResBoundingBox from Compute-GS T-H: 71.837998 81.971997 538.235984 768.113977
-# * Scanning header for BoundingBox
-# * Applying BoundingBox from ADSC T-: 0 0 596 842
-# * Final BoundingBox: 0 0 596 842
-# * Ghostscript ps2pdf pipe: gs -dSAFER -q -dBATCH -sDEVICE=pdfwrite -sOutputFile=debrecen-hyph.pdf -
-# * Done OK, created PDF file debrecen-hyph.pdf (338451 bytes)
-#
-package just; BEGIN{$INC{'just.pm'}='just.pm'}
-BEGIN{ $just::VERSION=2 }
-sub end(){1}
-sub main(){}
-
-BEGIN{$ INC{'strict.pm'}='strict.pm'} {
-package strict;
-use just;
-# by pts@fazekas.hu at Wed Jan 10 12:42:08 CET 2001
-require 5.002;
-sub bits {
- (grep{'refs'eq$_}@_ && 2)|
- (grep{'subs'eq$_}@_ && 0x200)|
- (grep{'vars'eq$_}@_ && 0x400)|
- ($@ || 0x602)
-}
-sub import { shift; $^H |= bits @_ }
-sub unimport { shift; $^H &= ~ bits @_ }
-just::end}
-
-BEGIN{$ INC{'integer.pm'}='integer.pm'} {
-package integer;
-use just;
-# by pts@fazekas.hu at Wed Jan 10 12:42:08 CET 2001
-sub import { $^H |= 1 }
-sub unimport { $^H &= ~1 }
-just::end}
-
-BEGIN{$ INC{'Pts/string.pm'}='Pts/string.pm'} {
-package Pts::string;
-# by pts@fazekas.hu at Sat Dec 21 21:32:18 CET 2002
-use just;
-use integer;
-use strict;
-
-#** @param $_[0] a string
-#** @param $_[1] index of first bit to return. Bit 128 of byte 0 is index 0.
-#** @param $_[2] number of bits to return (<=32)
-#** @return an integer (negative on overflow), bit at $_[1] is its MSB
-sub get_bits_msb($$$) {
- # assume: use integer;
- my $loop=$_[1];
- my $count=$_[2];
- my $ret=0;
- ($ret+=$ret+(1&(vec($_[0],$loop>>3,8)>>(7-($loop&7)))), $loop++) while $count--!=0;
- $ret
-}
-
-#** @param $_[0] a string
-#** @return value if $_[0] represents a floating point numeric constant
-#** in the C language (without the LU etc. modifiers) -- or undef. Returns
-#** undef for integer constants
-sub c_floatval($) {
- my $S=$_[0];
- no integer; # very important; has local scope
- return 0.0+$S if $S=~/\A[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.])(?:[eE][+-]?[0-9]+)?\Z(?!\n)/;
- undef
-}
-
-#** @param $_[0] a string
-#** @return value if $_[0] represents a floating point or integer numeric
-#** constant in the C language (without the LU etc. modifiers) -- or undef
-sub c_numval($) {
- my $S=$_[0];
- no integer; # very important; has local scope
- return 0+$S if $S=~/\A[+-]?(?:[0-9]*\.[0-9]+(?:[eE][+-]?[0-9]+)?|[0-9]+\.?)\Z(?!\n)/;
- undef
-}
-
-#** @param $_[0] a string
-#** @return the integer value of $_[0] in C -- or undef
-sub c_intval($) {
- my $S=$_[0];
- my $neg=1;
- $neg=-1 if $S=~s@\A([+-])@@ and '-'eq$1;
- return $neg*hex $1 if $S=~/\A0[xX]([0-9a-fA-F]+)\Z(?!\n)/;
- return $neg*oct $1 if $S=~/\A0([0-7]+)\Z(?!\n)/;
- return $neg*$1 if $S=~/\A([0-9]+)\Z(?!\n)/;
- undef
-}
-
-sub import {
- no strict 'refs';
- my $package = (caller())[0];
- shift; # my package
- for my $p (@_ ? @_ : qw{get_bits_msb c_floatval c_numval c_intval}) { *{$package."::$p"}=\&{$p} }
-}
-
-just::end}
-
-BEGIN{$ INC{'Htex/dimen.pm'}='Htex/dimen.pm'} {
-package Htex::dimen;
-# by pts@fazekas.hu at Sat Dec 21 21:26:15 CET 2002
-use just;
-use integer;
-use strict;
-use Pts::string qw(c_numval);
-
-my %bp_mul;
-{ no integer; %bp_mul=(
- 'bp'=>1, # 1 bp = 1 bp (big point)
- 'in'=>72, # 1 in = 72 bp (inch)
- 'pt'=>72/72.27, # 1 pt = 72/72.27 bp (point)
- 'pc'=>12*72/72.27, # 1 pc = 12*72/72.27 bp (pica)
- 'dd'=>1238/1157*72/72.27, # 1 dd = 1238/1157*72/72.27 bp (didot point) [about 1.06601110141206 bp]
- 'cc'=>12*1238/1157*72/72.27, # 1 cc = 12*1238/1157*72/72.27 bp (cicero)
- 'sp'=>72/72.27/65536, # 1 sp = 72/72.27/65536 bp (scaled point)
- 'cm'=>72/2.54, # 1 cm = 72/2.54 bp (centimeter)
- 'mm'=>7.2/2.54, # 1 mm = 7.2/2.54 bp (millimeter)
-) }
-
-#** @param $_[0] a (real or integer) number, optionally postfixed by a
-#** TeX dimension specifier (default=bp)
-#** @return the number in bp, or undef
-sub dimen2bp($) {
- no integer;
- my $S=$_[0];
- my $mul;
- $mul=$bp_mul{$1} if $S=~s/\s*([a-z][a-z0-9]+)\Z(?!\n)// and exists $bp_mul{$1};
- my $val=c_numval($S);
- $val*=$mul if defined $val and defined $mul;
- $val
-}
-
-just::end}
-
-BEGIN{$ INC{'Htex/papers.pm'}='Htex/papers.pm'} {
-package Htex::papers;
-# contains paper size information
-# by pts@fazekas.hu at Sun Dec 22 00:30:58 CET 2002
-use just;
-use integer;
-use strict;
-use Htex::dimen;
-
-my @papers=(
-#
-# paper.txt
-# by pts@fazekas.hu at Tue Jan 16 18:21:59 CET 2001
-# by pts@fazekas.hu at Tue Jan 16 19:13:16 CET 2001
-#
-# Examined: dvips, gs, libpaperg
-#
-# all units are measured in Big Points (bp)
-# 72 bp == 1 in
-# 2.54 cm == 1 in
-#
-# papername width height
-qw{Comm10 297 684},
-qw{Monarch 279 540},
-qw{halfexecutive 378 522},
-
-qw{Legal 612 1008},
-qw{Statement 396 612},
-qw{Tabloid 792 1224},
-qw{Ledger 1224 792},
-qw{Folio 612 936},
-qw{Quarto 610 780},
-qw{7x9 504 648},
-qw{9x11 648 792},
-qw{9x12 648 864},
-qw{10x13 720 936},
-qw{10x14 720 1008},
-qw{Executive 540 720},
-
-qw{ISOB0 2835 4008},
-qw{ISOB1 2004 2835},
-qw{ISOB2 1417 2004},
-qw{ISOB3 1001 1417},
-qw{ISOB4 709 1001},
-qw{ISOB5 499 709},
-qw{ISOB6 354 499},
-qw{ISOB7 249 354},
-qw{ISOB8 176 249},
-qw{ISOB9 125 176},
-qw{ISOB10 88 125},
-qw{jisb0 2916 4128},
-qw{jisb1 2064 2916},
-qw{jisb2 1458 2064},
-qw{jisb3 1032 1458},
-qw{jisb4 729 1032},
-qw{jisb5 516 729},
-qw{jisb6 363 516},
-
-qw{C7 230 323},
-qw{DL 312 624},
-
-qw{a3 842 1190}, # defined by Adobe
-qw{a4 595 842}, # defined by Adobe; must precede a4small
-
-# a4small should be a4 with an ImagingBBox of [25 25 570 817].},
-qw{a4small 595 842},
-qw{letter 612 792}, # must precede lettersmall
-# lettersmall should be letter with an ImagingBBox of [25 25 587 767].
-qw{lettersmall 612 792},
-# note should be letter (or some other size) with the ImagingBBox
-# shrunk by 25 units on all 4 sides.
-qw{note 612 792},
-qw{letterLand 792 612},
-# End of Adobe-defined page sizes
-
-qw{a0 2380 3368},
-qw{a1 1684 2380},
-qw{a2 1190 1684},
-qw{a5 421 595},
-qw{a6 297 421},
-qw{a7 210 297},
-qw{a8 148 210},
-qw{a9 105 148},
-qw{a10 74 105},
-qw{b0 2836 4008},
-qw{b1 2004 2836},
-qw{b2 1418 2004},
-qw{b3 1002 1418},
-qw{b4 709 1002},
-qw{b5 501 709}, # defined by Adobe
-
-qw{a0Land 3368 2380},
-qw{a1Land 2380 1684},
-qw{a2Land 1684 1190},
-qw{a3Land 1190 842},
-qw{a4Land 842 595},
-qw{a5Land 595 421},
-qw{a6Land 421 297},
-qw{a7Land 297 210},
-qw{a8Land 210 148},
-qw{a9Land 148 105},
-qw{a10Land 105 74},
-qw{b0Land 4008 2836},
-qw{b1Land 2836 2004},
-qw{b2Land 2004 1418},
-qw{b3Land 1418 1002},
-qw{b4Land 1002 709},
-qw{b5Land 709 501},
-
-qw{c0 2600 3677},
-qw{c1 1837 2600},
-qw{c2 1298 1837},
-qw{c3 918 1298},
-qw{c4 649 918},
-qw{c5 459 649},
-qw{c6 323 459},
-
-# vvv U.S. CAD standard paper sizes
-qw{archE 2592 3456},
-qw{archD 1728 2592},
-qw{archC 1296 1728},
-qw{archB 864 1296},
-qw{archA 648 864},
-
-qw{flsa 612 936}, # U.S. foolscap
-qw{flse 612 936}, # European foolscap
-qw{halfletter 396 612},
-qw{csheet 1224 1584}, # ANSI C 17x22
-qw{dsheet 1584 2448}, # ANSI D 22x34
-qw{esheet 2448 3168}, # ANSI E 34x44
-qw{17x22 1224 1584}, # ANSI C 17x22
-qw{22x34 1584 2448}, # ANSI D 22x34
-qw{34x44 2448 3168}, # ANSI E 34x44
-);
-
-#** Converts a numeric paper size to a well-defined paper name. Tolerance is
-#** 8.5bp
-#** @param $_[0] width, in bp
-#** @param $_[1] height, in bp
-#** @return () or ("papername", ret.paper.width.bp, ret.paper.height.bp)
-sub valid_bp($$;$$) {
- no integer;
- my ($W1,$H1)=(defined$_[2]?$_[2]:0,defined$_[3]?$_[3]:0);
- my ($WW,$HH)=(Htex::dimen::dimen2bp($_[0])-$W1, Htex::dimen::dimen2bp($_[1])-$H1);
- # Dat: 1mm == 720/254bp; 3mm =~ 8.5bp
- no integer;
- for (my $I=0; $I<@papers; $I+=3) {
- return @papers[$I,$I+1,$I+2] if abs($papers[$I+1]-$WW)<=8.5 and abs($papers[$I+2]-$HH)<=8.5;
- }
- ()
-}
-
-#** @param $_[0] (width width_unit "," height height_unit)
-#** @return () or ("papername", width.bp, height.bp)
-sub valid($) { # valid_papersize
- my $S=lc$_[0];
- $S=~/^\s*(\d+(\.\d+)?)\s*([a-z][a-z0-9]+)\s*,\s*(\d+(\.\d+)?)\s*([a-z][a-z0-9]+)\s*\Z(?!\n)/ ?
- valid_bp("$1$3","$4$6") : ();
-}
-
-#** @param $_[0] (width width_unit? ("," || "x") height height_unit?) || (papername)
-#** @return () or ("papername"?, width.bp, height.bp)
-sub any($) {
- my $S=lc$_[0];
- if ($S=~/\A[a-z]\w+\Z(?!\n)/) {
- for (my $I=0; $I<@papers; $I+=3) {
- return @papers[$I,$I+1,$I+2] if lc($papers[$I]) eq $S;
- }
- }
- return () if $S!~/^\s*(\d+(\.\d+)?)\s*((?:[a-z][a-z0-9]+)?)\s*[,xX]\s*(\d+(\.\d+)?)\s*((?:[a-z][a-z0-9]+)?)\s*\Z(?!\n)/;
- # ^^^ Dat: [xX] is xdvi-style, [,] is dvips-style spec
- my($w,$h)=($1.$3, $4.$6);
- my @L=valid_bp($w,$h);
- @L ? @L : (undef,Htex::dimen::dimen2bp($w),Htex::dimen::dimen2bp($h))
-}
-
-just::end}
-
-BEGIN{$ INC{'Htex/a2ping.pm'}='Htex/a2ping.pm'}
-
-package Htex::a2ping;
-# a2ping.pl -- convert between PS, EPS and PDF and other page description formats
-# by pts@fazekas.hu et al. at Wed Apr 16 14:54:13 CEST 2003
-# a2ping.pa created at Sun Apr 20 22:25:47 2003
-#
-# This file contains perldoc(1) documentation. Search for `=head1'.
-# See revision history at end of this file.
-#
-
-use just +1; # a JustLib application
-use strict;
-use integer;
-use Htex::papers;
-BEGIN { $Htex::a2ping::VERSION="2.84p" }
-
-# Imp: option to ignore `%%Orientation: Portrait', which gs respects and rotates by 90 degrees if necessary
-# Imp: gs(704?!) sometimes finds too small bbox, see Univers.eps
-# Imp: respect bbox in METAPOST %! (not EPS), don't use Compute-GS T-
-# Imp: -sPDFPassword=...
-# Imp: `a2ping.pl -v jf.eps pdf1: t.pdf' PDF1: must be forced to have --below
-# Imp: option to `clip' an EPS to the specified bbox -- does file size decrease?
-# Imp: fix bug a2ping -v ~/a2ping_bug.ps a2ping_bug.pdf; running type1fix on
-# all fonts with dff.pl has fixed the problem
-# Imp: post-process PNG etc. written by sam2p
-# Imp: better help and docs
-# Imp: respect full /MediaBox for a PDF -> EPS|PDF1 conversion
-# Imp: --ll x,y command line option
-# Imp: Htex/a2ping.pa -v ../image/tuzv.ps t.pdf (1st and second page different)
-# Imp: also save+restore /pdfmark ??
-# Imp: fix /MediaBox an all PDF pages if !$ll_zero
-# Imp: PDF -> PDF1 conversion with gs -sDEVICE=pdfwrite
-# Imp: direct PDF to PCL5 conversion with gs
-# Imp: remove %%BeginDefaults | %%PageMedia: plain | %%EndDefaults (pdftops(1))
-# Imp: fix completely bogus margin and papersize handling:
-# ../justlib2/Htex/a2ping.pa --duplex=force-short -v -p:a3 -r force-unknown tuzv.ps t.pdf
-# Imp: careful distinction between PDF and PDF1
-# Imp: psnup support (-1 -2 -3 -4 ...)
-# Imp: idempotent PS -> PS, add other header
-# Imp: use convert(1) etc.
-# Imp: possibly disable compute-pipe
-# Imp: $header_remove_p ??
-# Imp: --leftright option instead of --below
-# Imp: pdfboxes.pl, get offset from gs
-# Imp: detect error messages from GS, abort...
-# Imp: use all pdftops + gs + acroread
-# Imp: possibly accept /PageSize from %%DocumentMedia
-# Imp: /DocumentMedia seems to screw up sub-pt placement in gv(1)
-#
-# Dat: example: a2ping.pl --extra=-c:ijg:50 -r86 nn1.eps nn1.jpg
-# Dat: calling ``showpage'' is not required for -sDEVICE=pdfwrite with gs 6.50,
-# but -sDEVICE=pgmraw depends on it
-# Dat: the functionality of pdfboxes.pl cannot be provided here with a shorter
-# implementation, because gs always outputs the content stream of the PDF
-# objects first
-# Dat: pdftops -eps writes negative bbox correctly
-# Dat: markedEPS: include pdfmarks
-# Dat: gs 7.04 gdevdjet.[ch], gdevdljm.[ch]
-# Dat: to be undeffed in setpagedevice: /.MarginsHWResolution /PageSize
-# /ImagingBBox /HWResolution /HWSize /.MediaSize (we undef all)
-
-### program identification
-my $program = "a2ping.pl";
-my $filedate="2019-11-17"; # See also $Htex::a2ping::VERSION.
-my $copyright = "Written by <pts\@fazekas.hu> from April 2003.
-This is free software, GNU GPL >=2.0. There is NO WARRANTY.
-(epstopdf 2.7 Copyright 1998-2001 by Sebastian Rahtz et al.)\n";
-# "Contains modifications by pts\@fazekas.hu";
-my $title = "$program $Htex::a2ping::VERSION, $filedate -- $copyright\n";
-
-### ghostscript command name
-my($quote,$GS)=("'","gs");
-($quote,$GS) = ("\"","gswin32c") if $^O eq 'MSWin32' or $^O =~ /cygwin/i;
-
-# --- help functions
-
-sub fnq($) {
- my $fn=$_[0];
- return $fn if $fn!~y@-a-zA-Z0-9/.+_@@c;
- $fn=~s@'@\\'@g if $quote eq "'";
- $quote.$fn.$quote
-}
-
-sub debug {
- print STDERR "* @_\n" if $::opt_verbose;
-}
-sub warning {
- print STDERR "$0: warning: @_\n";
-}
-sub error {
- my $s=$title; $title="";
- die "$s$0: @_\n";
-}
-
-# unlink temporary files?
-my $tmpunlink_p=1;
-my $tmpsig=1;
-my %tmpfiles;
-my $tmpdir=exists $ENV{TMPDIR} ? $ENV{TMPDIR} : '/tmp';
-$tmpdir="." if (!-d $tmpdir or !-w $tmpdir) and -w '.';
-sub cleanup() {
- unlink keys %tmpfiles;
- exit 125;
-}
-END { unlink keys %tmpfiles; }
-sub temp_unlink($) {
- if (defined $_[0] and exists $tmpfiles{$_[0]}) {
- unlink $_[0] if $tmpunlink_p;
- delete $tmpfiles{$_[0]};
- }
-}
-sub temp_prefix() {
- my $prog0=$program;
- $prog0=~y@a-zA-Z0-9@_@c;
- if ($tmpsig) {
- $tmpsig=0;
- $SIG{INT}=$SIG{TERM}=$SIG{HUP}=$SIG{QUIT}=\&cleanup;
- }
- return "$tmpdir/$prog0-$$-".int(rand(1<<30))."-"; # 30: nonnegative
-}
-
-#** @return arg rounded down to int
-sub myfloor($) {
- # Dat: Perl int() rounds towards zero
- no integer;
- $_[0]==int($_[0]) ? $_[0] : $_[0] < 0 ? -int(1-$_[0]) : int($_[0])
-}
-
-#** @return arg rounded up to int
-sub myceil($) {
- no integer; #### BUGFIX at Wed Nov 15 17:23:29 CET 2006
- $_[0]==int($_[0]) ? $_[0] : 1+ ($_[0] < 0 ? -int(-$_[0]) : int($_[0]));
-}
-
-just::main;
-
-# ---
-
-sub FL_PAGE1_STOP(){1} # is file format single-page?
-sub FL_SET_PAGESIZE_OK(){2}
-sub FL_PDFMARK(){4}
-sub FL_NEED_SHOWPAGE(){8} # does gs -sDEVICE=... need showpage?
-sub FL_SAMPLED(){16} # is it a sampled (raster, pixel-based)
-sub FL_ANY_ORIGIN_OK(){32} # (llx,lly) may be anything, not just (0,0)
-sub FL_HAS_ANTIALIAS(){64}
-sub FL_VIA_SAM2P(){128} # sam2p(1) should convert PNM to such a format
-sub FL_OK_SAM2P(){256} # sam2p(1) can convert PNM to such a format
-
-my %fmts=( # Name=>[flags]
- 'EPS'=>[FL_PAGE1_STOP],
- 'markedEPS'=>[FL_PAGE1_STOP|FL_PDFMARK], # Imp: should we have FL_SET_PAGESIZE_OK?
- 'PDF1'=>[FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_PDFMARK],
- 'PDF'=>[FL_SET_PAGESIZE_OK|FL_PDFMARK|FL_ANY_ORIGIN_OK],
- 'PS'=>[FL_SET_PAGESIZE_OK|FL_ANY_ORIGIN_OK],
- 'markedPS'=>[FL_SET_PAGESIZE_OK|FL_PDFMARK|FL_ANY_ORIGIN_OK],
- 'PCL5'=>[FL_SET_PAGESIZE_OK|FL_ANY_ORIGIN_OK],
- # ^^^ Dat: no FL_HAS_ANTIALIAS -- would need lj5gray, which is loonger
- # ^^^ Dat: no FL_SAMPLED, because cannot set resolution
- 'PBM'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_OK_SAM2P], # Dat FL_HAS_ANTIALIAS produces obscure image
- 'PGM'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_OK_SAM2P],
- 'PPM'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_OK_SAM2P],
- # Now come the FileFormats supported via sam2p
- 'PNG'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_VIA_SAM2P],
- 'XWD'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_VIA_SAM2P],
- 'BMP'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_VIA_SAM2P],
- 'TIFF'=>[FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_VIA_SAM2P],
- 'JPEG'=>[FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_VIA_SAM2P],
- 'GIF'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_VIA_SAM2P], # Imp: disable antialias for few colors?
- 'XPM'=> [FL_PAGE1_STOP|FL_SET_PAGESIZE_OK|FL_NEED_SHOWPAGE|FL_SAMPLED|FL_HAS_ANTIALIAS|FL_VIA_SAM2P], # Imp: disable antialias for few colors?
-);
-my %fmt_aliases=qw(MARKEDPS markedPS MARKEDEPS markedEPS PCL PCL5
- UNMARKEDPS PS UNMARKEDEPS EPS EPDF PDF1 MEPS markedEPS);
-# Dat: .ps will be unmarked PS
-# Imp: sometimes markedEPS for .eps?
-my %fmt_exts=qw(eps EPS epsi EPS epsf EPS eps2 EPS ps PS ps2 PS
- pcl PCL5 pcl5 PCL5 pbm PBM pgm PGM pnm PPM ppm PPM pdf PDF png PNG
- xwd XWD bmp BMP rle BMP tif TIFF tiff TIFF jpg JPEG jpe JPEG
- jpg JPEG gif GIF xpm XPM);
-
-### usage
-# vvv deprecated options:
-# --outfile=<file>: write result to <file>
-# --debug: verbose debug informations (default: $bool[$::opt_verbose])
-# --(no)filter: d. read standard input (default: false)
-# --(no)gs d. run Ghostscript to create PDF
-my $usage=
-"${title}Usage: $program [options] <inputfile> [[<outformat>:] <outputfile>]
-Run with --doc to read documentation as a UNIX man(1) page.
-Options: --help print this help message
---(no)compress use compression (def: best)
---(no)hires scan HiResBoundingBox (def: yes)
---(no)exact scan ExactBoundingBox (def: no)
---(no)verbose verbose debug informations (def: no)
---(no)below allow below+left_from baseline (def: no)
---(no)tmpunlink unlink temporary files (def: yes)
---(no)antialias render shades at outlines (def: scale3no) (=scale3yes =no =yes)
---(no)lossy allow lossy image filters (EPS->PDF) (def: yes)
---(no)keepoldmediabox keep only old, [0 0]-based MediaBox in PDF (def: no)
---gs-cmd= path to Ghostscript (def: gs or gswin32c)
---gs-ccmd= path to Ghostscript, 4 bbox calc (def: gs or gswin32c)
---gsextra= extra arg to gs
---extra= extra arg to external prg (i.e pdftops)
---bboxfrom= adsc|compute-gs|pagesize (def: guess)
---papersize= unchanged|force-unknown|600bpx5cm (def: default) (bp)
---threshold= min color for 1 in 8->1 bit conv (def: 128)
-Possible input formats: PS EPS PDF JPEG GIF TIFF PNG PNM PCX BMP LBM XPM TGA
-Possible output formats: @{[sort keys %fmts]}
-Examples for producing 'test.pdf':
- * $program test.eps
- * produce postscript | $program -v - test.pdf
-Example: look for HiResBoundingBox and produce corrected PostScript:
- * $program -d --nogs -hires test.ps>testcorr.ps
-";
-sub errorUsage {
- die "$usage\U!\E!\U!\E Error: @_\n";
-}
-
-# --- @ARGV parsing
-
-### default option values
-my @extra=();
-my @gsextra=();
-#** Output file format (string)
-my $FileFormat=undef;
-$::opt_help=0;
-$::opt_verbose=0;
-my %vals_compression=map{$_=>1} qw(best none flate zip);
-$::opt_compression='best';
-#** Prefer %%HiResBoundingBox over %%BoundingBox, but emit both
-$::opt_hires=1;
-$::opt_exact=0;
-# $::opt_filter=0; # deprecated
-# $::opt_outputfile=undef; # deprecated
-$::opt_below=undef;
-$::opt_keepoldmediabox=0;
-$::opt_lossy=1;
-$::opt_antialias=undef; # render shades at path outlines for better readability
-$::opt_gs_cmd=undef;
-$::opt_extra="";
-$::opt_duplex="default";
-$::opt_threshold=128;
-my %vals_antialias=map{$_=>1} qw(no yes scale3yes scale3no);
-my %vals_duplex=map{$_=>1} qw(force-unknown force-simplex force-long
- force-short unchanged default-simplex default-long default-short);
-# ^^^ short: duplex printing, will bind short edge of paper (ideal for
-# duplexing psnup -2)
-#** Dat: force-unknown is forced by /setpagedevice/load def
-$::opt_resolution="default"; # unchanged force-unknown 600x600 (DPI)
-$::opt_papersize="default"; # unchanged force-unknown 600bpx600cm (bp)
-#** --bboxfrom=adsc sets %%BoundingBox from the 1st page if no ADSC comment in non-EPS ps
-my %vals_bboxfrom=map{$_=>1} qw(adsc compute-gs guess pagesize);
-$::opt_bboxfrom="guess";
-my $InputFilename;
-my $OutputFilename;
-
-sub is_page1_stop() { 0!=($fmts{$FileFormat}[0]&FL_PAGE1_STOP) }
-sub is_set_pagesize_ok() { 0!=($fmts{$FileFormat}[0]&FL_SET_PAGESIZE_OK) }
-sub is_pdfmark() { 0!=($fmts{$FileFormat}[0]&FL_PDFMARK) }
-sub is_need_showpage() { 0!=($fmts{$FileFormat}[0]&FL_NEED_SHOWPAGE) }
-sub is_sampled() { 0!=($fmts{$FileFormat}[0]&FL_SAMPLED) }
-sub is_any_origin_ok() { 0!=($fmts{$FileFormat}[0]&FL_ANY_ORIGIN_OK) }
-sub is_has_antialias() { 0!=($fmts{$FileFormat}[0]&FL_HAS_ANTIALIAS) }
-sub is_via_sam2p() { 0!=($fmts{$FileFormat}[0]&FL_VIA_SAM2P) }
-sub is_ok_sam2p() { 0!=($fmts{$FileFormat}[0]&FL_OK_SAM2P) }
-
-# ---
-
-sub show_doc() {
- # run `pod2man __FILE__ | man -l -', same as `perldoc __FILE', but perldoc(1)
- # is missing from some Debian sites that have pod2man.
- my @path=split/:+/,$ENV{PATH};
- my $pod2man_='pod2man --center="a2ping: advanced PS, PDF, EPS converter" ';
- $pod2man_=q~perl -ne 'if($a>1){print}elsif($a&&/^=head1/){$a=2}else{$a=!/\S/}' ~
- if !grep { -x "$_/pod2man" } @path;
- my $pager='';
- for my $pageri ((defined $ENV{PAGER} ? $ENV{PAGER}: ''),'less','most','more','view - ','vim -R - ','vi - ','joe -rdonly -asis -','pager') {
- next if $pageri!~/^(\S+)/;
- my $pagert="/$1";
- if (grep { -x $_.$pagert } @path) { $pager=$pageri; last }
- }
- $pager=q~perl -pe 's@\010_@@g;s@.\010@@gs' | ~.$pager
- if substr($pager,-2)eq' ' or $pager=~/\A(?:view|vim?|joe|emacs|mcedit|nano|nano-tiny|ae)\b/;
- # ^^^ Dat: these cannot handle underline/bold backspace directly
- $ENV{PAGER}=$pager;
- my $man='';
- if (substr($pod2man_,0,5)ne 'perl ') {
- $man=' | man -l -'; # calls $PAGER
- if ((!grep { -x "$_/man" } @path) or qx(man -l 2>&1)=~/\binvalid option\b/) {
- $man=' | nroff -Tlatin1 -mandoc'; # Linux, no need for eqn(1), tbl(1) etc.
- if (!grep { -x "$_/nroff" } @path) { $man='' } # just write it
- }
- }
- my $cmd=$pod2man_.fnq(__FILE__).$man;
- if ($cmd!~/[|] man -l -\Z(?!\n)/) {
- if (!length $pager) {
- die unless open PIPE, "$cmd|";
- print while sysread PIPE, $_, 4096;
- die "$0: error showing doc\n" unless close PIPE;
- exit 0;
- }
- $cmd.=' | $PAGER';
- }
- ##die $cmd;
- $ENV{LESS}="" if !defined $ENV{LESS};
- $ENV{LESS}="$ENV{LESS}R"; # show ANSI escapes
- die "$0: exec ($cmd) failed: $!\n" if !exec $cmd;
-}
-
-die $usage if !@ARGV or (1==@ARGV and $ARGV[0] eq '-h' or $ARGV[0] eq '--help'
- or $ARGV[0] eq 'help');
-show_doc() if 1==@ARGV and $ARGV[0] eq '--doc' or $ARGV[0] eq 'doc';
-
-{ my($I,$optname,$optval);
- my %optmap=qw(o outputfile outfile outputfile r resolution h help
- f filter d verbose v verbose debug verbose p papersize
- c compression compress compression h hires b below e exact x extra);
- #** Options that have a mandatory argument
- my %argopt1=qw(outputfile 1 duplex 1 resolution 1 extra 1 compression 1 gs-cmd 1
- gs-ccmd 1
- papersize 1 paper 1 bboxfrom 1 antialias 1 gsextra 1 threshold 1); # 1 arg
- my %argnone=qw(help 1 verbose 1 noverbose 1 nocompress 1 noantialias 1); # 0 arg
- my %argmaybe=qw(); # 0 or 1 arg
- my %argbool=qw(hires 1 exact 1 below 1 gs 1 filter 1 tmpunlink 1
- approx 1 lossy 1 keepoldmediabox 1); # boolean arg
- # Dat: --noverbose --nocompress
- my $opts_ok=1;
- for ($I=0; $I<@ARGV; $I++) {
- if ($ARGV[$I]eq '--') {
- $OutputFilename=$InputFilename if defined $InputFilename and
- !defined $OutputFilename and $opts_ok;
- $opts_ok=0;
- } elsif ($opts_ok and $ARGV[$I]=~/\A--+(\w[\w-]*)(?:[:=](.*))?\Z(?!\n)/s) {
- $optname=lc$1; $optval=$2;
- } elsif ($opts_ok and $ARGV[$I]=~/\A-(\w)(.*)\Z(?!\n)/s) {
- $optname=lc$1;
- if (length($2)==0) { $optval=undef }
- elsif (index(":=",substr($2,0,1))>=0) { $optval=substr($2,1) }
- else { $optval=$2 }
- } elsif ($opts_ok and !defined $FileFormat and defined $InputFilename and $ARGV[$I]=~s@\A(\w+):@@) {
- my $fmtag=uc$1;
- # errorUsage "invalid FileFormat tag: $fmtag" if $fmtag!~s@:\Z(?!\n)@@;
- if (exists $fmts{$fmtag}) { $FileFormat=$fmtag }
- elsif (exists $fmt_aliases{$fmtag}) { $FileFormat=$fmt_aliases{$fmtag} }
- else { errorUsage "Unknown FileFormat tag: $fmtag" }
- if (0!=length($ARGV[$I])) {
- errorUsage "Multiple output filenames" if defined $OutputFilename;
- $OutputFilename=$ARGV[$I];
- }
- next
- } elsif (!defined $InputFilename) { $InputFilename=$ARGV[$I]; next }
- elsif (!defined $OutputFilename) { $OutputFilename=$ARGV[$I]; next }
- else { errorUsage "Too many arguments (multiple input/output files?)" }
- $optname=$optmap{$optname} if exists $optmap{$optname};
- if (exists $argopt1{$optname} and !defined $optval) {
- errorUsage "Argument expected for --$optname" if $I==@ARGV;
- $optval=$ARGV[++$I];
- }
- # Dat: $optname and $optval are now correct
- errorUsage "No argument expected for --$optname=$optval" if exists $argnone{$optname} and defined $optval;
- if (substr($optname,0,2)eq"no" and exists $argbool{substr($optname,2)}) {
- $optname=substr($optname,2);
- errorUsage "No argument expected for no --no$optname=$optval" if defined $optval;
- $optval="no";
- }
- if (exists $argbool{$optname}) {
- # same as sam2p GenBuffer::parseBool, understands:
- # on true yes ja igen oui enable 1 true vrai? right sure allowed
- # off false no nein nem non disable 0 false faux? wrong nope disallowed
- $optval=(!defined($optval) or 0==length($optval)
- or $optval=~/\Ao[nu]/i or $optval!~/\A[fndw0]/i) ? 1 : 0;
- } elsif (!exists $argopt1{$optname} and !exists $argnone{$optname} and !exists $argmaybe{$optname}) {
- errorUsage "Unknown option --$optname, see --help"
- }
- # vvv application-specific
- if ($optname eq "help") { die $usage }
- elsif ($optname eq "help") { show_doc() }
- elsif ($optname eq "noverbose") { $::opt_verbose=0 }
- elsif ($optname eq "nocompress") { $::opt_compression='none' }
- elsif ($optname eq "verbose") { $::opt_verbose++ }
- elsif ($optname eq "hires") { $::opt_hires =$optval }
- elsif ($optname eq "exact") { $::opt_exact =$optval }
- elsif ($optname eq "below") { $::opt_below =$optval }
- elsif ($optname eq "keepoldmediabox") { $::opt_keepoldmediabox=$optval }
- elsif ($optname eq "lossy") { $::opt_lossy =$optval }
- elsif ($optname eq "approx") { $::opt_approx=$optval }
- elsif ($optname eq "threshold") { $::opt_threshold=$optval+0 } # Imp: accept only int 0..256
- elsif ($optname eq "filter") {
- # errorUsage "Multiple input filenames" if defined $InputFilename;
- # $InputFilename='-';
- errorUsage "Multiple output filenames" if defined $OutputFilename;
- $OutputFilename='-';
- } elsif ($optname eq "tmpunlink") { $tmpunlink_p=$optval }
- elsif ($optname eq "gs") { $FileFormat=$optval ? 'PDF1' : 'markedEPS' }
- elsif ($optname eq "compression") {
- errorUsage "--$optname expects one of: @{[keys%vals_compression]}" if !exists $vals_compression{$optval};
- $::opt_compression=$optval;
- $::opt_compression='zip' if $::opt_compression eq 'flate';
- } elsif ($optname eq "outputfile") {
- errorUsage "Multiple output filenames" if defined $OutputFilename;
- $OutputFilename=$optval;
- } elsif ($optname eq "gs-cmd") {
- errorUsage "Multiple --gs-cmd" if defined $::opt_gs_cmd;
- $::opt_gs_cmd=$optval;
- } elsif ($optname eq "gs-ccmd") {
- errorUsage "Multiple --gs-ccmd" if defined $::opt_gs_ccmd;
- $::opt_gs_ccmd=$optval;
- } elsif ($optname eq "extra") { push @extra, $optval }
- elsif ($optname eq "gsextra") { push @gsextra, $optval }
- elsif ($optname eq "duplex") {
- errorUsage "--$optname expects one of: @{[keys%vals_duplex]}" if !exists $vals_duplex{$optval};
- $::opt_duplex=$optval
- } elsif ($optname eq "bboxfrom") {
- errorUsage "--$optname expects one of: @{[keys%vals_bboxfrom]}" if !exists $vals_bboxfrom{$optval};
- $::opt_bboxfrom=$optval
- } elsif ($optname eq "noantialias") {
- $::opt_antialias='no'
- } elsif ($optname eq "antialias") {
- errorUsage "--$optname expects one of: @{[keys%vals_antialias]}" if !exists $vals_antialias{$optval};
- $::opt_antialias=$optval
- } elsif ($optname eq "resolution") {
- if ($optval eq "unchanged" or $optval eq "force-unknown") { }
- elsif ($optval=~/^(\d+(?:[.]\d+)?)\Z(?!\n)/) { $optval="$1x$1" }
- elsif ($optval=~/^(\d+(?:[.]\d+)?[x,]\d+(?:[.]\d+)?)\Z(?!\n)/) { }
- else { errorUsage "--Resultion expects unchanged | force-unknown | DPI | XDPIxYDPI" }
- $::opt_resolution=$optval
- } elsif ($optname eq "papersize" or $optname eq"paper") {
- if ($optval eq "unchanged" or $optval eq "force-unknown") { $::opt_papersize=$optval }
- else {
- my @L=Htex::papers::any($optval);
- errorUsage "invalid or unknown for --papersize" if !@L;
- $::opt_papersize="$L[1],$L[2]" # width, height
- }
- } else { die } # unreachable
- } # NEXT opt
- errorUsage "Too many arguments (multiple input/output files?)" if $I!=@ARGV;
- # splice @ARGV, 0, $I;
-}
-
-$GS=$::opt_gs_cmd if defined $::opt_gs_cmd;
-my $CGS=$GS;
-$CGS=$::opt_gs_ccmd if defined $::opt_gs_ccmd;
-# vvv SUXX: (r) file doesn't work with gs 8.5x -DSAFER
-# -dNOSAFER to override SAFER activated by default since gs 9.50
-$GS.= " -dNOSAFER"; # -dWRITESYSTEMDICT
-$CGS.=" -dNOSAFER"; # -dWRITESYSTEMDICT
-
-### get input and output filename
-if (!defined $InputFilename and defined $OutputFilename) { # --filter
- $InputFilename='-';
-} elsif (!defined $InputFilename) {
- errorUsage "Input filename missing"
-} elsif (!defined $OutputFilename) {
- $FileFormat='PDF1' if !defined $FileFormat;
- if ($FileFormat eq 'PDF1' or $FileFormat eq 'PDF') {
- if (($OutputFilename=$InputFilename) ne '-') {
- $OutputFilename =~ s/\.[^\.]*$//;
- $OutputFilename .= ".pdf";
- }
- } else {
- $OutputFilename = '-'; # standard output
- }
-}
-print STDERR $title if $::opt_verbose;
-$title="";
-
-# Dat: no more @ARGV
-errorUsage "please specify <outformat>" if
- !defined $FileFormat and ($OutputFilename!~m@[.]([^/.]+)\Z(?!\n)@ or
- !defined($FileFormat=$fmt_exts{lc$1}));
-$::opt_below=is_any_origin_ok() if !defined $::opt_below;
-error "--below=1 invalid for FileFormat $FileFormat" if $::opt_below and
- !is_any_origin_ok() and $FileFormat ne 'PDF1' and $FileFormat ne 'EPS' and
- $FileFormat ne 'markedEPS';
-error "--below=0 invalid for FileFormat $FileFormat" if !$::opt_below and
- is_any_origin_ok();
-$::opt_antialias=is_has_antialias() ?
- (is_sampled() ? 'scale3no' : 'yes') : 'no' if
- !defined $::opt_antialias;
-
-if ($FileFormat eq 'PBM' and ($::opt_antialias eq 'scale3yes' or
- $::opt_antialias eq 'scale3no')) {
-} elsif ($::opt_antialias ne 'no' and !is_has_antialias()) {
- $::opt_antialias='no';
- warning "--AntiAlias ignored for FileFormat $FileFormat"
-}
-if ($::opt_antialias eq 'scale3no' or $::opt_antialias eq 'scale3yes') {
- $::opt_resolution="72,72" if $::opt_resolution eq 'unchanged' or $::opt_resolution eq 'force-unknown' or $::opt_resolution eq 'default';
- # ^^^ GS raster default
- my @L=split/[,x]/,$::opt_resolution;
- @L=(@L,@L); # Imp: ..
- $L[0]*=3; $L[1]*=3;
- $::opt_resolution="$L[0],$L[0]";
-}
-
-### option compress
-my $GSOPTS=join(" ",map{fnq$_}@gsextra);
-# $GSOPTS.=" -r72 -sPAPERSIZE=a4 "; # default -- will be overridden by `setpagedevice'
-# ^^^ Dat: default does only harm; user should specify on command line
-
-### option BoundingBox types
-#**** pts ****
-# scan all of them and find the best
-{ my $BBprint = "%%BoundingBox:";
- $BBprint = "%%HiResBoundingBox:" if $::opt_hires;
- $BBprint = "%%ExactBoundingBox:" if $::opt_exact;
- debug "Strongest BoundingBox comment:", $BBprint;
-}
-my $BBregex='%%(Hi[Rr]es|Exact|)BoundingBox:';
-
-if (!is_set_pagesize_ok()) {
- if ($::opt_papersize ne'default' and $::opt_papersize ne'force-unknown') {
- error "Cannot set --PaperSize for FileFormat $FileFormat"
- } else { $::opt_papersize='force-unknown' }
-} elsif ($::opt_papersize eq'default') { $::opt_papersize='unchanged' }
-
-if ($::opt_resolution eq'default') { $::opt_resolution='force-unknown' }
-error "Cannot set --Resolution for FileFormat $FileFormat (must be markedPS or sampled)"
- if $FileFormat ne 'markedPS' and !is_sampled()
- and $::opt_resolution ne'force-unknown';
-error "Bad --Resolution=$::opt_resolution" if $::opt_resolution ne 'unchanged'
- and $::opt_resolution ne 'force-unknown' and $::opt_resolution!~/\A(\d+)+[,x](\d+)\Z(?!\n)/;
-
-if ($FileFormat ne 'markedPS' and $FileFormat ne 'PCL5') {
- if ($::opt_duplex ne'default' and $::opt_duplex ne'force-unknown') {
- error "Cannot set --Duplex for FileFormat $FileFormat (must be markedPS or PCL5)"
- } else { $::opt_duplex='force-unknown' }
-} elsif ($::opt_duplex eq'default') { $::opt_duplex='force-unknown' }
-
-debug "Doing --PaperSize $::opt_papersize" if $::opt_papersize ne 'force-unknown';
-debug "Doing --Duplex $::opt_duplex" if $::opt_duplex ne 'force-unknown';
-debug "Doing --Resolution $::opt_resolution" if $::opt_resolution ne 'force-unknown';
-debug "Doing --AntiAlias=$::opt_antialias" if $::opt_antialias ne 'no';
-
-### option outfile
-if ($OutputFilename eq '-') {
- debug "Output file: standard output";
-} else {
- debug "Output filename: $OutputFilename";
- #error "$OutputFilename: won't overwrite input file with itself"
- # if $OutputFilename eq $InputFilename;
-}
-
-### option gs
-debug "Output FileFormat: $FileFormat";
-$::opt_compression='zip' if $::opt_compression ne 'none';
-if ($FileFormat eq 'PDF' or $FileFormat eq 'PDF1') {
- debug "Ghostscript ps2pdf command: $GS $GSOPTS";
- debug "Compression: $::opt_compression";
-} elsif ($FileFormat eq 'PCL5') {
- debug "Ghostscript ps2ljet command: $GS $GSOPTS";
-} elsif (is_sampled()) {
- debug "Ghostscript ps2sampled command: $GS $GSOPTS";
-}
-
-#**** pts ****
-sub read_error() { error "read $InputFilename: $!" }
-my $in_mac_p=0; # 0: "\n" or "\r\n" is line terminator; 1: "\r" is line terminator
-my $bytes_left=-1; # -1==unlimited
-my $already_read=0;
-sub dem1($){defined$_[0]?$_[0]:-1}
-#** @param $_[0] number of bytes to read, or undef to read a line
-#** @return the string read
-sub readIN(;$) {
- my $S;
- ## return "" if $bytes_left==0;
- ## print STDERR "READ($_[0])\n";
- if (defined $_[0]) { read_error if 0>dem1 read IN, $S, $_[0] }
- else {
- $!=0; # clean up error code
- if ($in_mac_p) {
- local $/="\r";
- $S=~s@\r\Z(?!\n)@\n@ if defined($S=<IN>);
- } else { $S=<IN> }
- read_error if !defined($S) and $!;
- $S="" if !defined $S; # EOF
- }
- if ($bytes_left<0) { # unlimited
- } elsif (length($S)>=$bytes_left) {
- $S=substr($S, 0, $bytes_left);
- $bytes_left=0;
- } else { $bytes_left-=length($S) }
- $already_read+=length($S);
- $S
-}
-
-sub open_OUT() {
- error "Cannot write outfile '$OutputFilename'" unless
- open(OUT, $OutputFilename eq '-' ? ">-" : "> $OutputFilename")
-}
-
-#** @param $_[0] temp file extension (e.g ".img")
-#** @param $_[1] preprint
-#** @param $_[2] bool: force pipe even if seekable?
-sub fix_pipe_in($$$) {
- my $c="";
- if ($_[2] or (length($c=readIN(1))!=0 and !seek IN,-1,1)) { # we cannot seek back
- # Dat: ^^^ test seekability instead of $InputFilename eq '-'
- my($ext,$preprint)=@_;
- my $tifn;
- # $ext=$1 if $InputFilename=~/[.](\w+)\Z(?!\n)/; # never true
- $tifn=temp_prefix()."M$ext";
- error "Cannot open temp input: $tifn" unless open TI, "> $tifn";
- $tmpfiles{$tifn}=1;
- die unless print TI $preprint, $c;
- print TI or die while length($_=readIN 4096);
- die unless close TI;
- $InputFilename=$tifn;
- debug "Temp input file: $InputFilename";
- die unless open IN, "< $tifn";
- die unless seek IN, length($preprint), 0;
- $already_read=length($preprint);
- $bytes_left=-1; # unlimited, since readIN() has copied only part
- # $bytes_left++ if $bytes_left>=0; # ungetc($c)
- # temp_unlink $tifn; # do it later (at END{})
- } else {
- $already_read--; $bytes_left++ if $bytes_left>=0; # BUGFIX at Fri May 14 00:21:18 CEST 2004
- }
-}
-
-my $temp_out_fn;
-
-#** Does overwrite $temp_out_fn. Fine.
-sub fix_force_out($) {
- my($ext)=$_[0];
- # $ext=$1 if $InputFilename=~/[.](\w+)\Z(?!\n)/; # never true
- $temp_out_fn=temp_prefix()."O$ext";
- # error "Cannot save output: $!" unless open SAVEOUT, ">&OUT"; # always STDOUT; maybe not open yet
- error "Cannot open temp output: $temp_out_fn" unless open OUT, "> $temp_out_fn";
- $tmpfiles{$temp_out_fn}=1;
- # $OutputFilename=$temp_out_fn;
- debug "Temp output file: $temp_out_fn";
- # temp_unlink $temp_out_fn; # do it later (at END{})
- return $temp_out_fn;
-}
-
-#** @param $_[0] temp file extension (e.g ".img")
-#** @return new output filename
-sub fix_pipe_out($) {
- if (!defined $temp_out_fn) {
- return $OutputFilename if $OutputFilename ne '-';
- return fix_force_out($_[0]);
- }
- $temp_out_fn
-}
-sub fix_close_out() {
- # error "closing filter out: $? $!" unless close OUT;
- if (defined $temp_out_fn) {
- my $buf;
- die unless open FCO, "< $temp_out_fn";
- print STDOUT $buf while sysread FCO, $buf, 4096;
- die unless close FCO;
- temp_unlink $temp_out_fn;
- undef $temp_out_fn;
- }
-}
-
-sub do_system {
- my($progname)=splice@_,0,1;
- debug "Running: $progname @extra @_";
- error "prog $progname failed: $? $!"
- if 0!=system $progname, @extra, @_; # Dat: non-zero exit() or not found
-}
-
-sub do_exec {
- my($progname)=splice@_,0,1;
- if (scalar keys %tmpfiles) {
- # Cannot exec() right now, because we have to unlink some temporary files
- # later.
- do_system $progname, @_;
- } else {
- debug "Execing: $progname @extra @_";
- 1 if exec $progname, @extra, @_;
- # ^^^ Dat: $OutputFilename eq '-' should be OK
- error "exec failed: $!";
- }
- exit(0);
-}
-
-#sub shq($) {
-# my $S=$_[0];
-# return $S if $S!~y@A-Za-z0-9_,:./-@@c and length($S)>0;
-# $S=~s@'@'\\''@g;
-# return "'$S'"
-#}
-
-### open input file
-if ($InputFilename eq '-') {
- debug "Input file: standard input";
- open(IN, "<&STDIN") or error "cannot open standard input";
-} else {
- # -f $InputFilename or error "input file missing: $InputFilename"; # Imp: named pipe?
- open(IN,"< $InputFilename") or error "cannot open input file: $InputFilename";
- debug "Input filename:", $InputFilename;
- if ($InputFilename eq $OutputFilename) {
- # error "same input and output file: $InputFilename";
- my $ext=$InputFilename=~m@([.][^./]+)\Z(?!\n)@ ? $1 : "";
- binmode IN; $bytes_left=-1;
- fix_pipe_in($ext, "", 1); # Dat: defined later
- }
-}
-binmode IN;
-
-#** Dat: uses $FileFormat, $InputFileName, $OutputFileName
-#** @param $S prepend to pipe
-sub run_sam2p($$) {
- my($approx_p,$S)=@_;
- # Imp: why isn't sam2p(1) PNG -> PNG idempotent?
- my $tfmt=$FileFormat eq'markedEPS' || $FileFormat eq 'EPS' ? 'EPS'
- : $FileFormat eq'markedPS' || $FileFormat eq 'PS' ? 'PS' # Dat: emits no /PageSize
- : $FileFormat eq'PDF1' || $FileFormat eq 'PDF' ? 'PDF'
- : undef;
- if (defined $tfmt) {}
- elsif (is_via_sam2p() or is_ok_sam2p()) {$tfmt=$FileFormat; $::opt_approx=1}
- else { error "sam2p doesn't support our FileFormat $FileFormat" }
- fix_pipe_in ".img", $S, 0;
- if ($approx_p) {
- if ($tfmt eq 'GIF') {
- # Dat: reduce palette to 8-bit if necessary
- my @args=('sam2p',@extra,"$tfmt:",'--',$InputFilename,$OutputFilename);
- debug "Running: @args";
- my $cmd=join(' ',map{fnq$_}@args)." 2>&1";
- my $res=readpipe($cmd);
- if ($res=~/\binvalid combination, no applicable OutputRule\b/) {
- # Dat: reduce palette to 8-bit
- #die "NOR";
- my $have_convert_p;
- my $have_pnmquant_p=0;
- for my $dir (split/:/,$ENV{PATH}) {
- if ((-f"$dir/pnmquant")) { $have_pnmquant_p=1 }
- }
- if (!$have_pnmquant_p) {
- $have_convert_p=0;
- for my $dir (split/:/,$ENV{PATH}) {
- if ((-f"$dir/convert")) { $have_convert_p=1 }
- }
- }
- my $cmd;
- if ($have_pnmquant_p) {
- my @args1=('sam2p','PPM:','--',$InputFilename,'-');
- my @args2=('sam2p',@extra,"$tfmt:",'--','-',$OutputFilename);
- $cmd=join(' ',map{fnq$_}@args1)." | pnmquant 256 | ".
- join(' ',map{fnq$_}@args2);
- } elsif ($have_convert_p) {
- my @args1=('sam2p','PPM:','--',$InputFilename,'-');
- my @args2=('sam2p',@extra,"$tfmt:",'--','-',$OutputFilename);
- # vvv Dat: `convert - GIF:-' does quantize (and emits GIF)
- $cmd=join(' ',map{fnq$_}@args1)." | convert - GIF:- | ".
- join(' ',map{fnq$_}@args2);
- }
- debug "Running pipe: $cmd";
- exec($cmd);
- } elsif ($? !=0) { die $res }
- # die $cmd;
- #debug "Running: $progname @extra @_";
- #error "prog $progname failed: $? $!"
- #if 0!=system $progname, @extra, @_; # Dat: non-zero exit() or not found
- }
- do_exec('sam2p', ("$tfmt:", '--', $InputFilename, $OutputFilename));
- } else {
- warning "post-processing of sam2p PDF output increases file size" if $tfmt eq 'PDF';
- $tfmt='EPS' if $tfmt eq 'PDF'; # Imp: PDF1<->PDF
- close IN;
- my $tpfn=temp_prefix()."Psimg";
- error "Cannot open temp pipe dest: $tpfn" unless open TP, "> $tpfn";
- $tmpfiles{$tpfn}=1;
- die unless close TP;
- do_system('sam2p', ("$tfmt:", '--', $InputFilename, $tpfn));
- error "Cannot open temp pipe src: $tpfn" unless open IN, "< $tpfn";
- $already_read=0; $bytes_left=-1;
- $InputFilename=$tpfn; # '-'
- goto SCAN_AGAIN
- }
-}
-
-#** Force this value for %%HiResBoundingBox if a %BoundingBox is read
-my $force_hiresbbox_value;
-
-### scan first line, check for DOS EPSF (and remove DOS headers)
-my $header;
-{ SCAN_AGAIN:
- my $S;
- $_=$header="";
- read_error if 0>read IN, $S, 4;
- error "$InputFilename: empty file" if 0==length($S);
- $already_read+=length($S);
- ##print tell(IN)." bar=$already_read\n";
- my $iff="?"; # Input File Format
- # vvv be permissive, since we have only 4 chars
- if ($S eq "\211PNG") { $iff="PNG" }
- elsif ($S=~/\A(\377+\330)\377/) { $iff="JPEG" }
- elsif ($S eq "MM\000\052" or $S eq "II\052\000") { $iff="TIFF" }
- elsif ($S=~m@\AP([1-6])[\s#]@) { $iff="PNM" }
- elsif ($S=~/\ABM/) { $iff="BMP" }
- elsif ($S eq "GIF8") { $iff="GIF" }
- elsif ($S eq "FORM") { $iff="LBM" }
- elsif ($S eq "/* X" or $S eq "/*XP") { $iff="XPM" }
- elsif ($S=~/\A\12[\0-\005]\001[\001-\10]/) { $iff="PCX" }
- elsif ($S=~/\A[\36-\77](?:\001[\001\11]|\0[\002\12\003\13])\0/) { $iff="TGA" }
- elsif ($S eq "\305\320\323\306") { $iff="DOS-EPSF" }
- elsif ($S eq "\033%-1") { $iff="UEL" }
- elsif (substr($S,0,1)eq'%') { $iff="P" } # PS, EPS or PDF
-
- # PNG JPEG TIFF PNM BMP GIF LBM XPM PCX TGA
- if ($iff eq "DOS-EPSF") { # DOS EPSF header
- read_error if 30-4>read IN, $S, 30-4, 4;
- my ($eheader,$ps_ofs,$ps_len,$wmf_ofs,$wmf_len,$tif_ofs,$tif_len,$checksum)=
- unpack"A4VVVVVVv", $S;
- $already_read+=30-4;
- error "$InputFilename: bad DOS EPS" if $eheader ne "\305\320\323\306" or $ps_ofs<30;
- my($ps_end, $wmf_end, $tif_end)=($ps_ofs+$ps_len, $wmf_ofs+$wmf_len, $tif_ofs+$tif_len);
- $ps_ofs-=30;
- if (!seek IN, $ps_ofs, 1) {
- while ($ps_ofs>4096) { $ps_ofs-=4096; readIN 4096 }
- read_in $ps_ofs if $ps_ofs>0;
- }
- $bytes_left=($ps_end>$wmf_end and $ps_end>$tif_end) ? -1 : $ps_len;
- $S=readIN(1);
- } elsif ($iff eq "UEL") { # HP PJL UEL, untested
- $S.=readIN;
- $S=substr($S,1);
- error "$InputFilename: bad HP PJL UEL header: ".(~chomp($S)&&$S)
- if $S!~/\A\\e?%-12345X\@PJL ENTER LANGUAGE\s*=\s*POSTSCRIPT\s*\r?$/i;
- 1 while length($S=readIN())!=0 and substr($S,0,4)ne'%!PS';
- die "$InputFilename: premature HP PJL UEL header" if length($S)==0;
- } elsif ($iff eq "P") {
- # no-op yet, see later
- } elsif ($iff eq "?") {
- error "unknown input image format: $InputFilename";
- } else { # source file is in some raster graphics format
- run_sam2p($::opt_approx,$S);
- goto SCAN_AGAIN
- }
-
- # now deal with PS, EPS and PDF
- if (substr($S,0,1) eq '%') {
- { my $max=128;
- my $C;
- while (length($S)<$max and defined($C=readIN(1)) and
- $C ne "\n" and $C ne "\r") { $S.=$C }
- error "couldn't find end of PS/PDF header line in $max bytes\n" if
- length($S)>=$max or !defined($C);
- $C=($C eq "\r") ? readIN(1) : "NONE";
- if (!defined$C or ($C ne "\n" and $C ne "NONE")) {
- use IO::Handle; # Dat: needed for ungetc
- IN->ungetc(ord($C)) if defined $C;
- debug "MAC \\r detected";
- $in_mac_p=1;
- } elsif ($C eq "\n") { # Dat: \r\n, DOS CRLF
- $in_mac_p=0; $S.="\r";
- } else { $in_mac_p=0 }
- $S.="\n";
- } # $S.=readIN;
- if (substr($S,0,4)eq'%PDF') {
- # error "$InputFilename: won't read a PDF file";
- if ($FileFormat eq 'PDF') { # convert PDF to PDF
- # !! PDF->PS->PDF
- open_OUT();
- $_=$S;
- debug "Doing a bit-by-bit copy";
- do {
- error "input error: $!" unless print OUT;
- } while (length($_=readIN 4096));
- close OUT; close IN;
- exit 0;
- } elsif ($FileFormat eq 'PDF1') { # Dat: remove extra pages by running pdftops and gs -sDEVICE=pdfwrite
- # !! Imp: possibly Run MetaPost output through full dvips (texc.pro) when prologues:=0
- # !! Imp: add full dvips %* font comment when prologues:=1 (design sizes missing :-()
- # Dat: no way to use $::opt_approx, because it doesn't remove extra pages
- fix_pipe_in ".pdf", $S, 0; # in case of stdin
- # Imp: option to open pdftops pipe instead of temp file
- # Dat: we rather use a temp file here for safety and early error detection
- do_input_pdftops: # come from EPS: and markedEPS:
- close IN; # after fix_pipe_in()
- my $tpfn=temp_prefix()."Peps";
- error "Cannot open temp pipe dest: $tpfn" unless open TP, "> $tpfn";
- $tmpfiles{$tpfn}=1;
- die unless close TP;
- do_system qw(pdftops -f 1 -l 1 -eps -- ), $InputFilename, $tpfn;
- error "Cannot open temp pipe src: $tpfn" unless open IN, "< $tpfn";
- $already_read=0; $bytes_left=-1;
- $InputFilename=$tpfn; # '-'
- goto SCAN_AGAIN
- } elsif ($FileFormat eq 'EPS' or $FileFormat eq 'markedEPS') { # convert PDF to EPS
- # Dat: limitation: markedEPS and EPS are treated the same
- # vvv Dat: pdftops(1) is part of the xpdf package
- # vvv Dat: pdftops(1) can emit to stdout
- fix_pipe_in ".pdf", $S, 0;
- if ($::opt_approx) {
- do_exec qw(pdftops -f 1 -l 1 -eps --), $InputFilename, $OutputFilename;
- } else { goto do_input_pdftops }
- } elsif ($FileFormat eq 'PS' or $FileFormat eq 'markedPS') {
- # Dat: limitation: markedEPS and EPS are treated the same
- fix_pipe_in ".pdf", $S, 0;
- close IN;
- # vvv we must query the BoundingBox first
- my $cmd="pdftops -f 1 -l 1 -eps ".fnq($InputFilename)." -";
- debug "pdftops bbox pipe: $cmd";
- error "pipe: $!" unless open PIPE, "$cmd |";
- my $line;
- error "expected PS document" if !defined($line=<PIPE>) or $line!~/^%!PS-Adobe-\d.*EPSF-\d/;
- my @L; # $papersize_x, $papersize_y
- while (<PIPE>) {
- last if /^%%EndComments/ or !/^%/;
- @L=($1,$2) if /^%%(?:Hires|Exact)BoundingBox:\s*\S+\s*\S+\s*(\S+)\s*(\S+)\s*$/i;
- @L=($1,$2) if /^%%BoundingBox:\s*\S+\s*\S+\s*(\S+)\s*(\S+)\s*$/i and !@L;
- # ^^^ Dat: HiRes has priority
- # ^^^ Dat: ignore llx and lly coordinates
- }
- 1 while read PIPE, $line, 4096;
- error "closing PIPE: $?" unless close PIPE;
- error "BoundingBox not found in pdftops output" if !@L;
- debug "Got PaperSize: @L";
-
- # vvv Dat: pdftops without -eps doesn't report HiResBoundingBox,
- # so we force it here
- # at Wed Nov 15 17:19:23 CET 2006
- $::opt_bboxfrom='adsc' if $::opt_bboxfrom eq 'guess';
- $force_hiresbbox_value="0 0 @L";
-
- #die defined $L[1];
- $L[0]=myceil $L[0]; $L[1]=myceil $L[1]; # Dat: pdftops expects integer papersize :-( )
- if ($::opt_approx) {
- # vvv Dat: even pdftops 3.01 accepts only integer for -paperw and paperh
- do_exec 'pdftops', '-paperw', myfloor($L[0]+0.5), '-paperh', myfloor($L[1]+0.5), $InputFilename, $OutputFilename;
- } else {
- my $tpfn=temp_prefix()."Pps";
- error "Cannot open temp pipe dest: $tpfn" unless open TP, "> $tpfn";
- $tmpfiles{$tpfn}=1;
- die unless close TP;
- do_system 'pdftops', '-paperw', myfloor($L[0]+0.5), '-paperh', myfloor($L[1]+0.5), $InputFilename, $tpfn;
- error "Cannot open temp pipe src: $tpfn" unless open IN, "< $tpfn";
- $already_read=0; $bytes_left=-1;
- $InputFilename=$tpfn; # '-'
- goto SCAN_AGAIN
- }
- } elsif (is_ok_sam2p() or is_via_sam2p()) {
- # Dat: PDF to GIF conversion
- run_sam2p(1,$S);
- }
-
- error "cannot create from PDF: FileFormat $FileFormat";
- OK:
- }
- error "$InputFilename: EPS DSC must be %!PS-Adobe" if substr($S,0,4)ne'%!PS';
- # ^^^ Dat: mpost outputs "%!PS\n"
- } else {
- warning "$InputFilename: no PS ADSC header, BoundingBox not found\n"
- }
- $header=$S;
-}
-
-# Dat: Now we are converting from PS|EPS to EPS|markedEPS|PDF|PCL5|PGM
-# So we're converting from PS|EPS with Ghostscript
-
-### variables and pattern for BoundingBox search
-my $bbxpatt = '[0-9eE\.\-]';
-my $BBValues = "\\s*($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)"; # protect backslashes: "\\" gets '\'
-
-my $ll_zero=0; # ($llx,$lly)==(0,0) in the output file
-my $need_grestore=0; # 0 v 1
-#** Applies %%*BoundingBox, %%EndComments, special setpagedevice, gsave..translate
-#** @param $_[0] llx, may be undef to signify that bbox is undetected
-#** @param $_[1] lly
-#** @param $_[2] urx
-#** @param $_[3] ury
-#** @param $_[4] after_correct PostScript code (resolution, page size)
-#** @return PostScript code to be printed after the header
-sub CorrectBoundingBox($$$$$$$) {
- no integer;
- my $bbx="";
- my $pagedev_mark="";
- my $translate="";
- my ($llx, $lly, $urx, $ury, $after_correct, $fontsdefs, $is_restored) = @_;
- if (defined $llx) {
- my ($xoffset, $yoffset) = (0, 0);
- my $old_bbox="$llx $lly $urx $ury"; # debug "Old BoundingBox: $old_bbox";
- # my ($width, $height) = ($urx - $llx, $ury - $lly);
- ($xoffset, $yoffset) = (-$llx, -$lly);
- # $::opt_below=0 if $lly>=0; # always move to (0,0)
- # my ($urxh,$uryh)=($urx,$ury);
- # my $no_translate=$::opt_below;
- #die $no_translate;
- ($llx,$lly,$urx,$ury)=(0,0,$urx-$llx,$ury-$lly) if !$::opt_below;
- $urx=1 if $urx<=0; # Dat: GS dislikes empty image; fix also negative image
- $ury=1 if $ury<=0;
- my($px,$py)=($urx,$ury);
- ($px,$py)=($1+0,$2+0) if $after_correct=~m@/PageSize\s*\[(\S+)\s+(\S+)+\]@;
- my @paper=Htex::papers::any("$px,$py");
- $paper[0]=defined $paper[0] ? "%%DocumentPaperSizes: $paper[0]\n" : "";
- $bbx.="%%BoundingBox: ".myfloor($llx)." ".myfloor($lly)." ".
- myceil($urx)." ". myceil($ury)."\n";
- $bbx.="%%HiResBoundingBox: $llx $lly $urx $ury\n".
- "%%ExactBoundingBox: $llx $lly $urx $ury\n" if myfloor($llx)!=$llx
- or myfloor($lly)!=$lly or myceil($urx)!=$urx or myceil($ury)!=$ury;
- $bbx.="%%DocumentMedia: plain $px $py 0 () ()\n". # like pdftops(1)
- "$paper[0]";
- # ^^^ Imp: can DocumentMedia be non-integer? As of us, it can.
- # vvv we output a second /MediaBox here, and we'll remove the first one
- # (written by GS) later
- # vvv Dat: old version of Ghostscript insisted on an integer /CropBox (??).
- # we do not force it now
- $pagedev_mark.="mark /CropBox [$llx $lly $urx $ury] /PAGE pdfmark\n" if is_pdfmark();
- # die "$xoffset $yoffset $::opt_below";
- if ($xoffset==0 and $yoffset==0) { #**** pts ****
- $need_grestore=0;
- $ll_zero=1; # Dat: we do not insert extra /MediaBox here, gs -sDEVICE=pdfwrite will do
- } elsif ($::opt_below) {
- # Do not translate (set (0,0) to the origin) with --below or multi-page
- # file formats.
- $need_grestore=0;
- $ll_zero=0; # fix /MediaBox because it become non-(0,0)-based
- $pagedev_mark.="mark /MediaBox [$llx $lly $urx $ury] /PAGE pdfmark\n" if
- is_pdfmark(); # $FileFormat eq 'markedEPS' or $FileFormat eq 'markedPS';
- # Dat: markedPS and contains pdfmark!
- } else {
- # debug "Offset:", $xoffset, $yoffset; # no new information, see -$llx, -$lly
- $xoffset=0 if $xoffset==0; # get rid of `-0'
- $yoffset=0 if $yoffset==0; # get rid of `-0'
- if ($is_restored) { $translate="" } # save..restore does gsave..grestore
- else { $translate="gsave "; $need_grestore=1 }
- $ll_zero=0;
- # vvv the /MediaBox is different from what gs dumps
- # $pagedev_mark=~s@/PageSize\s*\[[^\]]*]@/PageSize [$urx $ury]@; # BUGFIX at Tue Apr 22 10:08:17 CEST 2003
- $pagedev_mark.="mark /MediaBox [$llx $lly $urx $ury] /PAGE pdfmark\n" if is_pdfmark();
- $translate.="$xoffset $yoffset translate\n"
- }
- my $new_bbox="$llx $lly $urx $ury";
- if ($old_bbox eq $new_bbox) {
- debug "Final (HiRes)BoundingBox: $new_bbox";
- } else {
- debug "Old (HiRes)BoundingBox: $old_bbox";
- debug "Final corrected (HiRes)BoundingBox: $new_bbox";
- }
- $pagedev_mark="/pdfmark where{pop}{/pdfmark/cleartomark load def}ifelse\n$pagedev_mark"
- if length($pagedev_mark)!=0;
- }
- # vvv Imp: `<<' -> `dict'
- # Dat: it is inherently impossible to tell GS that it shouldn't
- # recompress the images already compressed in the EPS file, but keep
- # them in their original, compressed form. So we rather instruct GS to
- # recompress
- # !! Dat: /CompatibilityLevel 1.3 %PDF-1.2 -- Dat: 1.2 won't embed Courier
- my $markpagedevices="";
- my $imagesopts=($::opt_lossy ? "
-/AutoFilterMonoImages true
-/AutoFilterGrayImages true
-/AutoFilterColorImages true
-/MonoImageFilter /CCITTFaxEncode
-/GrayImageFilter /DCTEncode
-/ColorImageFilter /DCTEncode
-" : "
-/AutoFilterMonoImages false
-/AutoFilterGrayImages false
-/AutoFilterColorImages false
-/MonoImageFilter /LZWEncode
-/GrayImageFilter /LZWEncode
-/ColorImageFilter /LZWEncode
-"); # Dat: assumes new, patent-free LZW
- if (is_pdfmark()) {
- # Dat: CompatibilityLevel 1.3 is required for font embedding & all /FlateDecode
- $markpagedevices="
-/CompatibilityLevel 1.3 %PDF-1.3
-/EmbedAllFonts true
-/Optimize true % ignored by gs-6.70
-/AutoRotatePages /None
-/UseFlateCompression ".($::opt_compression ne 'none'?"true":"false")."
-/AutoPositionEPSFiles false
-/ConvertImagesToIndexed false
-/DownsampleMonoImages false
-/DownsampleGrayImages false
-/DownsampleColorImages false
-/EncodeMonoImages true
-/EncodeGrayImages true
-/EncodeColorImages true
-/AntiAliasMonoImages false
-/AntiAliasGrayImages false
-/AntiAliasColorImages false\n$imagesopts";
- $markpagedevices=(length($markpagedevices)!=0 ? "<< $markpagedevices >> setpagedevice\n" : "");
- $markpagedevices.="1 dict dup /ImagingBBox null put setpagedevice\n";
- $markpagedevices.="1 dict dup /Policies 1 dict dup /PageSize 3 put put setpagedevice\n"; # ripped from pdftops(1)
- }
- my $setpagesize="";
- # die defined $urx;
- # die is_set_pagesize_ok();
- # die $after_correct;
- if (defined $urx and is_set_pagesize_ok()
- and $::opt_papersize ne'force-unknown'
- and $after_correct!~m@/PageSize\s*\[@) { # Imp: m@/Pagesize ugly
- # Dat: true for FileFormat PGM
- # Dat: emit /PageSize even for PDF1
- # Dat: Ghostscript 6.70 rounds /PageSize down, but we need up when creating /MediaBox for PDF
- $setpagesize="2 dict dup /PageSize [".myceil($urx)." ".myceil($ury)."] put setpagedevice\n";
- # ^^^ Dat: PLRM.pdf doesn't forbid a non-integer /PageSize
- }
- my $bsetup=is_page1_stop()?"":"%%BeginSetup\n%%EndSetup\n";
- # ^^^ Dat: CUPS inserts its setpagedevice calls for /Duplex and /PageSize
- # etc. just after the %%BeginSetup line (or, if missing, puts it in
- # front of the first %%Page). We'd like this execution order: CUPS,
- # ours, PStoPS (or psnup). (When we come after CUPS, we'll have a
- # chance to override its settings.) So we emit a fake
- # %%BeginSetup..%%EndSetup pair just before our code doing
- # `setpagedevice'.
- # !! ?? run pstops first, and then a2ping.pl
- # !! why does a PDF -> PS conversion need $is_restored?
- # vvv Dat: `mark' is necessary, because pstops 1.17 from xpdf(1) emits lines
- # lines leaving `false' on the stack:
- # %%BeginResource: font SKPOPP+LMRoman12-Regular
- # %!PS-AdobeFont-1.0: LMRoman12-Regular 0.86
- # %%CreationDate: 4th August (Monday) 2003
- # % Generated by MetaType1 (a MetaPost-based engine)
- # % CM sources: copyright (C) 1997 AMS, all rights reserved; METATYPE1/Type 1 ver
- # % ADL: 694 194 112
- # %%EndComments
- # FontDirectory/LMRoman12-Regular known{/LMRoman12-Regular findfont dup/UniqueID
- # /UniqueID get 0 eq exch/FontType get 1 eq and}{pop false}ifelse
- # {save true}{false}ifelse}{false}ifelse
- my $save=$is_restored?"save mark\n":"";
- $bbx.$fontsdefs."%%EndComments\n".$bsetup.$setpagesize.$markpagedevices.$pagedev_mark.$after_correct.$save.$translate
-}
-
-### scan header
-my $to_OUT="";
-my $after_code="";
-my $do_fix_tumble=0;
-my $is_restored=0;
-if (1<length($header)) {
- my($llx,$lly,$urx,$ury);
- my($bbtype)='-'; # None
- my $allow_adsc_bb=1;
- my $after_correct="";
- my $do_bb_line=sub { # sub do_bbline($$)
- no integer;
- # Decreasing precedence of various BoundingBoxes:
- # The last valid *bbox entry has effect.
- # Active policy:
- # normal mode : BoundingBox ExactBoundingBox HiResBoundingBox
- # --hires mode: HiResBoundingBox BoundingBox ExactBoundingBox
- # --exact mode: ExactBoundingBox BoundingBox HiResBoundingBox
- # -hi -ex mode: ExactBoundingBox HiResBoundingBox BoundingBox
- # Another possible policy:
- # normal mode : BoundingBox HiResBoundingBox==ExactBoundingBox
- # --hires mode: HiResBoundingBox ExactBoundingBox BoundingBox
- # --exact mode: ExactBoundingBox HiResBoundingBox BoundingBox
- # -hi -ex mode: ExactBoundingBox==HiResBoundingBox BoundingBox
- my($S,$from)=@_;
- return if $S!~/^(?:$BBregex|set)$BBValues/oi;
- # print STDERR "($S)\n";
- my $E1=defined$1 ? $1 : "+";
- my $T=!defined($1) ? 'S' : uc substr $1,0,1; # '' || 'H' || 'E'
- # debug "Trying BoundingBox T-$bbtype: $llx $lly $urx $ury";
- if ($T eq 'S'
- or !$::opt_hires and !$::opt_exact and ($T eq '' or ($bbtype ne '' and ($T eq 'E' or $bbtype ne 'E')))
- or $::opt_hires and !$::opt_exact and ($T eq 'H' or ($bbtype ne 'H' and ($T eq '' or $bbtype ne '')))
- or $::opt_exact and !$::opt_hires and ($T eq 'E' or ($bbtype ne 'E' and ($T eq '' or $bbtype ne '')))
- or $::opt_exact and $::opt_hires and ($T eq 'E' or ($bbtype ne 'E' and ($T eq 'H' or $bbtype ne 'H')))
- ) {
- # if ($allow_bb) {
- ($bbtype,$llx,$lly,$urx,$ury)=($T,$2+0,$3+0,$4+0,$5+0);
- debug "Applying ${E1}BoundingBox$from T-$bbtype: $llx $lly $urx $ury";
- # }
- } else {
- my @L=($2+0,$3+0,$4+0,$5+0); # convert 0.00 to 0
- debug "Ignoring ${E1}BoundingBox$from T-$bbtype: @L";
- }
- # Dat: don't do $do_bb_line=sub{};# same as $allow_bb=0;
- };
- $header=~s@\r\n?\Z(?!\n)@@;
- my $after_comments=""; # after %%EndComments
- # my $res;
- { my $headEPSF;
- my $headPS="PS-Adobe-3.0";
- # vvv Imp: run this correction even w/o input EPS header
- if ($header!~s/\s+(EPSF-[.\d]+)$// or $::opt_bboxfrom ne 'guess') { # a PS not an EPS already
- # This is the compute-pipe routine.
- # To convert an [E]PS to an EPS:
- # -- find the end of the 1st page in the code, and remove everything after it
- # -- `pop' off the execution stack after the 1st page
- # -- `end' the dictionary stack after the 1st page
- # -- change the ADSC magic `%!PS-Adobe-...' to `%!PS-Adobe-3.0 EPSF-3.0'
- # -- remove the `%%Pages', `%%DocumentPaperSizes', `%%PageOrder:'
- # (Ascending) comment from the ADSC header
- # -- possibly remove the `%%Page' ADSC comment [no]
- # -- ignore calls to = setpage setpagemargin setpageparams .setpagesize
- # setpagedevice setpagetype setprintername setresolution a4 letter ...
- # -- surround the code by save ... pop* end* restore (implies gsave ... grestore)
- # -- possibly ignore calls to showpage [showpage is forced]
- $headEPSF=" EPSF-3.0";
- debug "Computing BBox info from non-EPS PS file";
- fix_pipe_in 'i.ps', "%!$headPS\n", 0;
- my $tfn=temp_prefix()."c.tgs";
- error "temp open $tfn: $!" unless open F, "> $tfn";
- $tmpfiles{$tfn}=1;
- ##print tell(IN)." car=$already_read\n";
- die "$0: $!\n" unless print F "% this is temporary gs command file created by $program".'
-/DOCUT true def
-/MAINFILE FN (r) file def
-/DICTCOUNT countdictstack def
-count /OPCOUNT exch def
-<</BeginPage { % <PageCount> BeginPage -
- dup 1 eq {
- count OPCOUNT sub 1 sub (pop-count==) ..print ===
- countdictstack DICTCOUNT sub (end-count==) ..print ===
- DOCUT { (cut-offset==) ..print MAINFILE fileposition === flush } if
- (bbox-success\n) ..print
- quit
- } if
- }
- % Run the previous contents of /BeginPage: {--.callbeginpage--}
- [exch aload pop currentpagedevice /BeginPage get aload pop] cvx
->> setpagedevice
-
-% vvv do these after our call to /setpagedevice
-currentglobal true setglobal
-systemdict begin
-/..paper.redef<< >>def
-/..print/print load def
-/setpageparams{pop pop pop pop (\nset-called-4==/setpageparams\n) ..print flush}def
-/setpage{pop pop pop (\nset-called-3==/setpage\n) ..print flush}def
-/setpagesize{pop pop (\nset-called-2==/setpagesize\n) ..print flush}def
-/.setpagesize{pop pop (\nset-called-2==/.setpagesize\n) ..print flush}def
-/setpagemargin{pop (\nset-called-1==/setpagemargin\n) ..print flush}def
-{% anti-Windows-printer-driver `%%[ ProductName:` etc.
- dup type/stringtype eq{
- dup length 3 ge{
- dup 0 3 getinterval (%%[) eq{
- (\nset-called-1==/=\n) ..print flush
- (\nset-called-1==/print\n) ..print flush
- }if}if}if
- pop
-}
-dup/= exch def /print exch def
-/setpagedevice{pop (\nset-called-1==/setpagedevice\n) ..print flush}def
-/..sdict <<
- /PageSize { % [. .] PageSize -
- dup type /arraytype eq {
- dup length 2 ge {
- dup 0 get type dup /integertype eq exch /realtype eq or {
- dup 1 get type dup /integertype eq exch /realtype eq or {
- (\npapersize-x==) ..print dup 0 get ===
- (\npapersize-y==) ..print dup 1 get === (\n) ..print
- } if
- } if
- } if
- } if
- pop
- }
- /HWResolution { % [. .] PageSize -
- dup type /arraytype eq {
- dup length 2 ge {
- dup 0 get type dup /integertype eq exch /realtype eq or {
- dup 1 get type dup /integertype eq exch /realtype eq or {
- (\nresolution-x==) ..print dup 0 get ===
- (\nresolution-y==) ..print dup 1 get === (\n) ..print
- } if
- } if
- } if
- } if
- pop
- }
- /Duplex { % [. .] PageSize -
- dup type /booleantype eq {
- (\nsides-duplex==) ..print dup === (\n) ..print
- } if
- pop
- }
- /Tumble { % [. .] PageSize -
- dup type /booleantype eq {
- (\nsides-tumble==) ..print dup === (\n) ..print
- } if
- pop
- }
->> def
-%/.setpagesize{pop pop (hehehe\n) print} def
-% /a4{(hehehe\n) ..print} def % doesn"t work, has to be put into userdict
-/setpagedevice{
- { % <key> <val>
- exch dup ..sdict exch known { % run all keys known in ..sdict
- ..sdict exch get exec
- } {pop pop} ifelse
- } forall
- (\nset-called-1==/setpagedevice\n) ..print flush
-}def
-/setpagetype{pop (\nset-called-1==/setpagetype\n) ..print flush}def
-/setprintername{pop (\nset-called-1==/setprintername\n) ..print flush}def
-/setresolution{pop (\nset-called-1==/setresolution\n) ..print flush}def
-[ % Dat: fixed at Mon May 19 14:32:31 CEST 2003
- statusdict /.pagetypenames 2 copy known {get}{pop pop{}}ifelse
- % ^^^ Dat: may be {/a4 STRICT {(%END SIZES) .skipeof} if /a5}
- { /11x17/a3/a4/a4small/b5/ledger/legal/letter % GS 7.04
- /lettersmall/note/a0/a1/a2/a5/a6/a7/a8/a9/c0/c1/c2/c3/c4/c5/c6
- /a10/b0/b1/b2/b3/b4/b5/b6
- /isob0/isob1/isob2/isob3/isob4/isob5/isob6
- /jisb0/jisb1/jisb2/jisb3/jisb4/jisb5/jisb6
- /archE/archD/archC/archB/archA/flsa/flse/halfletter
- /tabloid/csheet/dsheet/esheet/executivepage/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/folio/quarto
- }
-]{{
- dup type /nametype eq { dup xcheck not { % Dat: fixed
- % dup ===
- dup ..paper.redef exch known {pop} {
- dup ..paper.redef exch null put
- dup userdict exch 2 copy known { 2 copy get
- 1 index userdict exch undef
- % Stack: /a4 userdict /a4 {...}
- % 3 copy pop undef
- 4 2 roll exch undef
- } { exch pop pop {} } ifelse
- % Stack: /a4 {595 842 //.setpagesize --exec--}
- % Stack: /a4 {595 842 {/statusdict --.systemvar-- --begin-- .setpagesize --end--} --exec--}
- { /get exec /pop (\nset-called-0==) ..print === flush } % dump
- dup length array copy cvx % make a copy for subsequent invocations
- 2 copy exch 0 exch put exch pop % change /get to {...}
- 2 copy exch 2 exch put % change /pop to /a4
- def % overwrite it in systemdict
- } ifelse
- true
- } if } if
- pop
-}forall} forall
-end % systemdict
-setglobal
-systemdict readonly pop
-
-(bbox-begin\n) ..print
-MAINFILE cvx exec
-(add-showpage==1\n) ..print
-/DOCUT false def
-showpage quit
-';
- die unless close F;
- # vvv Imp: make it work on Win32 (no >&1 redirection)
- my $gs3=$CGS. # "-dPAGE1QUIT=".($FileFormat eq 'EPS' or $FileFormat eq 'markedEPS' ? 'quit' : '{}').
- " -dWRITESYSTEMDICT -dNOPAUSE -sDEVICE=bbox -sFN=".fnq($InputFilename)." ".fnq($tfn)." 2>&1";
- debug "Ghostscript compute pipe: $gs3";
- my $res=`$gs3`;
- ## die $res;
- temp_unlink $tfn;
- ## print STDERR $res;
- error $?==11 ? "segmentation fault in $GS" : "not a GS output from $GS ($?)"
- if !defined $res # BUGFIX at Sun Mar 7 18:51:34 CET 2004
- or $res!~s/\A(?:\w+ Ghostscript \d|Copyright .* artofcode ).*\n// # AFPL Ghostscript 6.50 (2000-12-02)
- or $res!~s/.*?^bbox-begin\n//m;
- if ($res!~s/\nbbox-success\n\Z(?!\n)/\n/) {
- warning # not `error', mpost(1) `prologues:=0; ... btex fonts' output won't compile
- "BBox discovery was not successful";
- # !! continue only if MetaPost output?
- goto SKIP_BBOX_DISC;
- }
- #: Copyright (C) 2000 Aladdin Enterprises, Menlo Park, CA. All rights reserved.
- #: This software comes with NO WARRANTY: see the file PUBLIC for details.
- #: set-called-0==/a4
- #: %%BoundingBox: 56 41 539 783
- #: %%HiResBoundingBox: 56.645998 41.849999 538.811984 782.351976
- #: pop-count==0
- #: end-count==1
- #: cut-offset==81898
- my $pop_count=0;
- my $end_count=0;
- my $cut_offset=-1;
- my $papersize_x=undef; # page_width
- my $papersize_y=undef; # page_height
- my $resolution_x=undef;
- my $resolution_y=undef;
- my $duplexi=0;
- my $tumblei=0;
- my %H;
- my $undefs="";
- my $bbc=0; # required
- for my $line (split/\n/, $res) {
- if ($line=~/^$BBregex$BBValues/oi) { $do_bb_line->($line," from Compute-GS"); $bbc++ }
- elsif ($line=~m@^set-called-(\d+)==/(\S+)$@) {
- if (not exists $H{$2}) {
- $H{$2}=1;
- $undefs.="/$2".(
- $1==0 ? "{}def\n" :
- $1==1 ? "/pop load def\n" :
- "{".("pop "x$1)."}bind def\n"
- );
- }
- # Dat: Safe, restorable, EPS-wise: /setpagedevice {pop} def
- # Dat: Smart, documentwise /a4 dup where{dup wcheck{exch{}put}{pop{}def}ifelse}{pop}ifelse
- }
- elsif ($line=~/^pop-count==(\d+)$/) { $pop_count=$1+0 }
- elsif ($line=~/^end-count==(\d+)$/) { $end_count=$1+0 }
- elsif ($line=~/^cut-offset==(\d+)$/) { $cut_offset=$1+0 }
- elsif ($line=~/^papersize-x==([-+0-9eE.]+)$/) { no integer; $papersize_x=$1+0 }
- elsif ($line=~/^papersize-y==([-+0-9eE.]+)$/) { no integer; $papersize_y=$1+0 }
- elsif ($line=~/^resolution-x==([-+0-9eE.]+)$/) { no integer; $resolution_x=$1+0 }
- elsif ($line=~/^resolution-y==([-+0-9eE.]+)$/) { no integer; $resolution_y=$1+0 }
- elsif ($line=~/^sides-duplex==true$/) { $duplexi=1 }
- elsif ($line=~/^sides-dumplex==false$/) { $duplexi=2 }
- elsif ($line=~/^sides-tumble==true$/) { $tumblei=1 }
- elsif ($line=~/^sides-tumble==false$/) { $tumblei=2 }
- elsif ($line=~/^add-showpage==\d+$/) { } # !!
- elsif (length($line)==0 or $line=~/^(?:Copyright |This software )/) {}
- elsif ($line=~/^Loading (\S+) font from.*[.][.][.]/) { debug "GS builtin font used: $1" }
- else { debug "unknown line ($line)" }
- }
- undef $papersize_y if !defined $papersize_x;
- die unless $allow_adsc_bb==1;
- # Dat: This only applies when converting fron non-EPS PS:
- # Setting $allow_adsc_bb=0|1 now would disallow/allow the %%BoundingBox
- # etc. ADSC comment override the bbox computed by -sDEVICE=bbox.
- # When converting PS -> EPS, the PS file usually contains
- # `%%BoundingBox: 0 0 paperwidth paperheight', but the figure
- # itself is smaller.
- $bbtype='-';
- ## die "$papersize_x;;"; # PDF -sPAPERSIZE=a4
- #if ($::opt_papersize ne 'force-unknown' and $::opt_papersize ne 'unchanged') {
- # # override bbox
- # ($llx,$lly)=(0,0);
- # ($urx,$ury)=split/,/,$::opt_papersize;
- #} elsif (!is_page1_stop() and defined $papersize_x and defined $papersize_y) {
- #}
- debug "PaperSize wd=${papersize_x}bp ht=${papersize_y}bp" if defined $papersize_x;
- if ($::opt_papersize eq 'force-unknown' or ($::opt_papersize eq 'unchanged' and !defined $papersize_x)) {}
- elsif ($::opt_papersize ne 'unchanged') {
- die if is_page1_stop();
- ($papersize_x,$papersize_y)=split/,/,$::opt_papersize;
- goto do_force_papersize
- } else {
- # Dat: no $do_bb_line here, because we've done it with $bbc++, and we'll also do it later
- do_force_papersize:
- die if is_page1_stop();
- # vvv ($llx,$lly,$urx,$ury)=(0,0,$papersize_x,$papersize_y);
- # $do_bb_line->("set 0 0 $papersize_x $papersize_y"," from /PageSize");
- $after_correct.="1 dict dup /PageSize [".myceil($papersize_x)." ".myceil($papersize_y)."] put setpagedevice\n";
- # ^^^ Dat: both PS and markedPS would benefit from /PaperSize
- # ^^^ Dat: will be put after CorrectBoundingBox
- # Dat: unneeded: $allow_adsc_bb=0 if $FileFormat eq 'PDF'; # force this into /CropBox (otherwise only /MediaBox)
- }
- if (defined $papersize_x and ($::opt_bboxfrom eq 'papersize' or ($::opt_bboxfrom eq 'guess' and is_set_pagesize_ok()))) {
- $allow_adsc_bb=0;
- $do_bb_line->("set 0 0 $papersize_x $papersize_y"," from /PageSize"); # does ($llx,$lly,$urx,$ury)=(0,0,$papersize_x,$papersize_y);
- }
- $allow_adsc_bb=0 if ($::opt_bboxfrom eq 'compute-gs') ? ($bbc!=0)
- : ($::opt_bboxfrom eq 'guess') ? ($bbc!=0 and is_page1_stop()) # Imp: is is_page1_stop() OK here?
- : 0;
- if (!is_page1_stop()) {
- $pop_count=$end_count=0; # assume PS is correct
- $cut_offset=-1;
- }
- # if ($FileFormat ne 'EPS' and $FileFormat ne 'PS') { # device-specific (marked)
- # ^^^ Dat: $::opt_resolution and $::opt_duplex are already 'force-unknown' if $FileFormat is appropriate
- {
- $::opt_resolution=$resolution_x.','.$resolution_y if
- $::opt_resolution eq 'unchanged' and defined $resolution_x and defined $resolution_y;
-
- # vvv Imp: move down like $::opt_resolution
- if ($::opt_duplex eq 'force-unknown' or ($::opt_duplex eq 'unchanged' and $duplexi==0)) { $do_fix_tumble=($duplexi==1 && $tumblei==1) }
- elsif ($::opt_duplex eq 'force-simplex') { do_simplex: $after_correct.="1 dict dup /Duplex false put setpagedevice\n" }
- elsif ($::opt_duplex eq 'force-long' ) { do_long: $after_correct.="2 dict dup /Duplex true put dup /Tumble false put setpagedevice\n" }
- elsif ($::opt_duplex eq 'force-short') { do_short: $do_fix_tumble=1; $after_correct.="2 dict dup /Duplex true put dup /Tumble true put setpagedevice\n" }
- else {
- $duplexi ||= $::opt_duplex eq 'default-simplex' ? 2 : 1;
- $tumblei ||= $::opt_duplex eq 'default-short' ? 1 : 2;
- goto do_simplex if $duplexi!=1;
- goto do_long if $tumblei!=1;
- goto do_short;
- }
- }
- # vvv Dat: save...restore is _always_ necessary to undo the changes made
- # by the file itself (??)
- # vvv BUGFIX (only EPS) at Tue Feb 8 21:40:11 CET 2005
- # vvv Dat: now with PS output it is possible that garbage is left on
- # the stack (see the `LMRoman' example above)
- $is_restored=1 if $FileFormat eq'EPS' or $FileFormat eq'markedEPS';
- $after_comments.=$undefs; # after our precious setpagedevice calls
- # debug "pop_count=$pop_count;";
- # debug "end_count=$end_count;";
- # debug "cut_offset=$cut_offset;";
- $after_code.=("pop\n"x$pop_count).("end\n"x$end_count);
- if ($cut_offset>=0 and ($bytes_left==-1 or $cut_offset<$bytes_left)) {
- $bytes_left=$cut_offset-$already_read;
- ##print tell(IN)." ar=$already_read\n";
- debug "Cutting after showpage at $cut_offset -> $bytes_left";
- # ^^^ Dat: cutting after `showpage' makes PS -> EPS conversion easy
- # sleep 1000;
- }
- # Dat: don't unlink $tifn yet, we'll continue scanning it
- # Imp: verify EPS created
- } else { $headEPSF=" $1" }
- SKIP_BBOX_DISC:
- if ($::opt_resolution eq 'force-unknown' or $::opt_resolution eq 'unchanged') {}
- else { $after_correct.="1 dict dup /HWResolution [@{[split/[x,]/,$::opt_resolution]}] put setpagedevice\n" }
- # ^^^ Dat: syntax already ok for $::opt_resolution
- $after_correct.="2 dict dup /TextAlphaBits 4 put dup /GraphicsAlphaBits 4 put setpagedevice\n" if
- $::opt_antialias eq 'yes' or $::opt_antialias eq 'scale3yes';
-
- $headEPSF="" if $FileFormat ne 'EPS' and $FileFormat ne 'markedEPS';
- $headPS=$1 if $header=~s/(PS-Adobe-[.\d]+)$//;
- $to_OUT.="%!$headPS$headEPSF\n";
- }
-
- debug "Scanning header for BoundingBox";
- my $do_atend=0;
- my $doing_atend=0;
- my $saved_pos;
- my $saved_bytes_left;
- my $creator_metapost_p=0; # HiResBoundingBox: after EndProlog
- my $creator_adobeps_p=0;
- my $had_pages=is_page1_stop(); # Dat: don't put `Pages:' to target EPS
- my $fontsdefs="";
- my %fontsnames;
- my @creator;
- read_again: while (length($_=readIN)) {
- #print STDERR "(($_))\n";
- ### end of header
- next unless /\S/;
- y@\r@@d; chomp;
- if (!$doing_atend) {
- if (/^%%EndComments\b/i) {
- # Dat: EPSI created by ImageMagick has BeginDefaults+EndDefaults+BeginPreview
- # Dat: PS output by ADOBEPS4.DRV has BeginDefaults+PageBoundingBox+ViewingOrientation+PageFeatures+EndDefaults
- 1 while length($_=readIN) and !/\S/;
- if (!/^%%BeginDefaults\b/i) { y@\r@@d; chomp; $after_comments.="$_\n"; last }
- 1 while length($_=readIN) and !/\S/;
- if (!/^%%EndDefaults\b/i) { y@\r@@d; chomp; $after_comments.="%%BeginDefaults\n$_\n"; last }
- next
- } elsif (/^%%EndDefaults\b/i) { # EPSI created by ImageMagick
- } elsif (/^%%Creator:\s*ADOBEPS/i) { # ADOBEPS4.DRV
- # Emits ``%%BoundingBox 1 1 ...' instead of `0 0'
- $creator_adobeps_p=1;
- } elsif (/^%%Creator:\s*MetaPost\b/i) {
- $creator_metapost_p=1;
- } elsif ((substr($_,0,2)ne'%%' and substr($_,0,7)ne'%*Font:' and
- substr($_,0,5)ne'%ADO_' and !/^%AI\d_/ # Dat: %ADO_DSC_..., %AI7_Thumbnail
- and substr($_,0,5)ne'%EPS ') # epsincl.mp
- or !$creator_metapost_p and substr($_,0,5)eq'%%End'
- or /^%%Begin(?:Prolog|Setup)\b/i
- ) { $after_comments.="$_\n"; last }
- }
- if (/^%%BeginPreview\b/i) { # remove EPSI preview ballast ****pts****
- while (1) {
- error "Missing EPSI %%EndPreview" if !length($_=readIN);
- last if /^%%EndPreview\b/;
- y@\r@@d; chomp
- }
- } elsif (/^%%Creator:\s*(.*)/i) {
- push @creator, $1;
- $creator[-1]=~s@\s+\Z(?!\n)@@;
- $creator[-1]=~s@, a2ping .*@@; # remove old
- } elsif (/^%%(?:DocumentPaperSizes|PageOrder|DocumentMedia):/i) {
- # silently ignore these -- will be recalculated
- } elsif (/^%%Pages:\s+(\d+)\s*/i and !$had_pages) { # Not `%%Pages: (atend)'
- # Dat: don't `$do_atend=1' only for %%Pages
- $to_OUT.="$_\n"; $had_pages=1
- } elsif (/^%%Pages:/i) {
- # silently ignore these -- not significant for EPS
- } elsif (/^$BBregex$BBValues/oi) { ### BoundingBox with values
- s@($BBregex)\s*1\s+1\s+@$1 0 0 @ if $creator_adobeps_p;
- # vvv $bbtype may be possibly already set by compute-gs
- if ($allow_adsc_bb) {
- $do_bb_line->($_," from ADSC");
- if ($force_hiresbbox_value) {
- $do_bb_line->("%%HiResBoundingBox: $force_hiresbbox_value"," from ADSC");
- }
- }
- } elsif (/^$BBregex\s*\(atend\)/oi) {
- ### BoundingBox with (atend)
- debug "At end $1BoundingBox";
- # warning "Cannot look for BoundingBox in the trailer with option --filter" if $::opt_filter;
- # ^^^ Dat: may be seekable anyway, omit warning
- $do_atend=1
- } elsif (/^%%Page:/i and !$creator_metapost_p) { # at Thu Sep 25 15:59:52 CEST 2003
- $after_comments.="$_\n"; last
- } elsif (/^%(?:ADO_DSC_|AI\d_)/) { # Dat: example: %ADO_DSC_Encoding: MacOS Roman
- $to_OUT.="%$_\n";
- } elsif (/^%\*Font:\s+(\S+)\s+/) { # mpost(1) output
- ## debug $_;
- $fontsdefs.="$_\n"; # put in front (before `gsave ... translate')
- $fontsnames{$1}=1;
- } elsif (substr($_,0,5) eq '%EPS ') { # epsincl.mp
- $after_correct.="$_\n" if !$doing_atend; # before `gsave'
- } elsif ($doing_atend or /^%%End/) {
- # we might be in mid-line
- } else {
- $to_OUT.="$_\n"
- }
- }
- if ($doing_atend) { # already read (atend); restore file position
- seek(IN, $saved_pos, 0) or error "Input unseekable, cannot go back to line `: (atend)'";
- $bytes_left=$saved_bytes_left;
- } elsif ($do_atend) { # seek to near EOF and try again
- # error "Cannot leave line `: (atend)'" if ($saved_pos=tell IN)<0 or !seek(IN,0,1);
- fix_pipe_in "j.ps", $to_OUT, 0;
- die if ($saved_pos=tell IN)<0;
- $saved_bytes_left=$bytes_left;
- # vvv get the very last *BoundingBox entry from the last 4096 bytes
- if ($bytes_left>4096) {
- die unless seek(IN, $bytes_left-4096, 1);
- $bytes_left=4096;
- } elsif ($bytes_left<0) {
- die unless seek(IN, -4096, 2) or seek(IN, 0,0); # Dat: 0,0 for short files
- }
- $doing_atend=1; goto read_again;
- }
- # if (!$had_pages) { debug "Lying %%Pages: 1"; $to_OUT.="%%Pages: 1\n" }
- # ^^^ Dat: rather not lie !! go to (atend) if command line
- # vvv Dat: $bbtype ne'-' would be a bad idea
- warning "BoundingBox not found, try --bboxfrom=compute-gs" if !defined $llx; # !! compute-gs
- push @creator, "$program $Htex::a2ping::VERSION"; # if "@creator"!~/\ba2ping\b/;
- $to_OUT.="%%Creator: ".join(", ",@creator)."\n"; # before CorrectBoundingBox to be before `gsave' etc.
- $to_OUT.=CorrectBoundingBox $llx, $lly, $urx, $ury, $after_correct, $fontsdefs, $is_restored;
- $to_OUT.=$after_comments;
- if (%fontsnames) { # !! save .. restore
- $to_OUT.="{@{[sort keys%fontsnames]}}{\ndup where{pop pop}{cvlit dup def}ifelse}forall\n";
- $to_OUT.="/fshow where{pop}{/fshow{exch findfont exch scalefont setfont show}bind def}ifelse\n";
- }
-}
-
-### open output file or pipe (do this as late as possible)
-my $do_scale3_pnm=0;
-my $scale3_pnm_fn;
-my @pnm2sampled_cmd;
-if ($FileFormat eq 'PDF' or $FileFormat eq 'PDF1') {
- my $ofn=$ll_zero ? $OutputFilename : fix_pipe_out('.pdf');
- my $pipe = "$GS -q -dBATCH -sDEVICE=pdfwrite $GSOPTS -sOutputFile=".fnq($ofn)." -";
- debug "Ghostscript ps2pdf pipe:", $pipe;
- open(OUT, "| $pipe") or error "Cannot open Ghostscript pipe";
-} elsif ($FileFormat eq 'PCL5') {
- my $ofn=$do_fix_tumble ? fix_pipe_out('.pcl5') : $OutputFilename;
- # vvv ljet4 cannot do duplex, ljet4d can
- my $pipe = "$GS -q -dBATCH -sDEVICE=ljet4d $GSOPTS -sOutputFile=".fnq($ofn)." -";
- debug "Ghostscript ps2ljet pipe:", $pipe;
- open(OUT, "| $pipe") or error "Cannot open Ghostscript pipe";
-} elsif ($FileFormat eq 'PBM' or $FileFormat eq 'PGM' or $FileFormat eq 'PPM'
- or is_via_sam2p()) {
- $do_scale3_pnm=($::opt_antialias eq'scale3no' or $::opt_antialias eq 'scale3yes');
- my $device=$FileFormat eq 'PPM' || is_via_sam2p() ? 'ppmraw' :
- $FileFormat eq 'PBM' && $::opt_antialias eq 'no' ? 'pbmraw' : 'pgmraw';
- # Dat: -sDEVICE=pgm is ASCII, pgmraw is binary
- my $pipe ="$GS -q -dBATCH -sDEVICE=$device ";
- # $pipe.="-dTextAlphaBits=4 -dGraphicsAlphaBits=4 " if $::opt_antialias; # Dat: already done
- my $ofn=$OutputFilename;
- if (is_via_sam2p()) {
- # Dat: fortunately the following file format names are commin in sam2p(1)
- # and a2ping.pl: PNG XWD BMP TIFF JPEG GIF XPM
- @pnm2sampled_cmd=('sam2p',"$FileFormat:",'--'); # Imp: use convert(1) if no sam2p(1)
- $ofn=fix_force_out('SS.pnm');
- push @pnm2sampled_cmd, $ofn, $OutputFilename;
- }
- if ($do_scale3_pnm) {
- $scale3_pnm_fn=$ofn;
- $ofn=fix_force_out('S3.pnm') if $do_scale3_pnm;
- # ^^^ Dat: this must be the last call to fix_force_out()
- }
- $pipe.="$GSOPTS -sOutputFile=".fnq($ofn)." -";
- debug "Ghostscript ps2raster pipe:", $pipe;
- open(OUT, "| $pipe") or error "Cannot open Ghostscript pipe";
-} else { open_OUT() }
-
-my $unlink_OutputFilename;
-END { unlink $unlink_OutputFilename if defined $unlink_OutputFilename }
-$unlink_OutputFilename=$OutputFilename;
-
-die unless binmode OUT;
-#die $to_OUT;
-# !! remove setpagedevice from EPS->EPS, but keep EPS->PGM
-# vvv needed by EPS->PGM conversion !!
-if (is_need_showpage() and is_page1_stop()) {
- $to_OUT.="/showpage{showpage quit}bind def\n"; # don't call showpage twice
- $after_code.="showpage\n";
-}
-error "write OUT" if !print OUT $to_OUT;
-$to_OUT="";
-
-### print rest of file
-sub OVERLAP_LENGTH(){4096} # `%%TrailerLength: 1162' by ADOBEPS4.DRV
-my $extra_trailer="%%Trailer\n";
-##undef $unlink_OutputFilename; die;
-{ my $overlap=""; # keeps OVERLAP_LENGTH chars
- my $S;
- # print OUT while length($_=readIN 4096);
- while (length($S=readIN 4096)) { # Dat: 4096>=OVERLAP_LENGTH
- #if (length($S)<OVERLAP_LENGTH) { $S="$overlap$S"; $overlap=""; }
- #die if length($S)<OVERLAP_LENGTH; # happens sometimes
- #print OUT $overlap, substr($S,0,length($S)-OVERLAP_LENGTH());
- #$overlap=substr($S,-OVERLAP_LENGTH(),OVERLAP_LENGTH);
- next if length($overlap.=$S)<OVERLAP_LENGTH;
- print OUT substr($overlap,0,length($overlap)-OVERLAP_LENGTH());
- $overlap=substr($overlap,-OVERLAP_LENGTH());
- }
- if ($overlap=~s@\r?\n%%Trailer\r?\n(.*?)\Z(?!\n)@\n%%Trailer\n@s) {
- my $S=$1;
- $S=~y@\r@@d;
- $S=~s@\n%%TrailerLength:.*$@@m; # ADOBEPS4.DRV
- $overlap.=$S;
- $extra_trailer="";
- }
- $overlap=~s@(?:[\n\r\0\f]+%%EOF)?[\n\r\0\f]*\Z(?!\n)@@;
- # vvv Dat: would move %%Trailer after dvips output `end userdict /end-hook known{end-hook}if'
- # $overlap=~s@(?:[\n\r\0\f]+%%Trailer)?(?:[\n\r\0\f]+%%EOF)?[\n\r\0\f]+\Z(?!\n)@@;
- print OUT $overlap;
-}
-
-### close files
-error "closing IN: $?" unless close IN;
-# ^^^ SUXX: gs always exit(0), if exists
-# vvv Dat: $after_code is pop+end
-print OUT "\n$extra_trailer$after_code",
- ("grestore\n"x$need_grestore),
- ("cleartomark restore\n"x$is_restored),
- "%%EOF\n";
-error "closing gs filter: $? $!" unless close OUT;
-
-# --- PNM scaling routines for --antialias=scale3*
-
-sub pnm_gettok($) {
- my ($fh,$S,$C)=($_[0],"");
- while (1) {
- die "unexpected EOF" if !defined($C=getc($fh));
- if ($C eq'#') { <$fh> } # ignore rest of line
- elsif ($C=~y@ \n\r\t@@) { last if length($S)!=0 }
- else { $S.=$C }
- }
- $S
-}
-
-my @div9=(0,0,0,0,0,map { $_, $_, $_, $_, $_, $_, $_, $_, $_ } 1..255, 255);
-
-#** @param $_[0] length always divisible by 3
-sub p5_avg_lines($$$$) {
- use integer;
- my $len=length($_[0]);
- my $olen=$len/3;
- while ($len>0) {
- vec($_[3],--$olen,8)=$div9[
- vec($_[0],$len-1,8)+vec($_[0],$len-2,8)+vec($_[0],$len-3,8)+
- vec($_[1],$len-1,8)+vec($_[1],$len-2,8)+vec($_[1],$len-3,8)+
- vec($_[2],$len-1,8)+vec($_[2],$len-2,8)+vec($_[2],$len-3,8)];
- $len-=3;
- }
-}
-
-#** @param $_[0] length always divisible by 9
-sub p6_avg_lines($$$$) {
- # Imp: why is it lighter than: convert -scale '33.3333%' a3.pbm a3r.pgm
- use integer;
- my $len=length($_[0]);
- my $olen=$len/3;
- while ($len>0) {
- vec($_[3],--$olen,8)=$div9[
- vec($_[0],$len-1,8)+vec($_[0],$len-4,8)+vec($_[0],$len-7,8)+
- vec($_[1],$len-1,8)+vec($_[1],$len-4,8)+vec($_[1],$len-7,8)+
- vec($_[2],$len-1,8)+vec($_[2],$len-4,8)+vec($_[2],$len-7,8)];
- $len-=6 if 0==--$len%3;
- }
-}
-
-# ---
-
-if (!$ll_zero and ($FileFormat eq 'PDF' or $FileFormat eq 'PDF1')) { # correct /MediaBox if not (0,0)-based
- ### ****pts**** remove incorrect /MediaBox produced by gs
- my $tfn=temp_prefix()."p.tgs";
- error "temp open $tfn: $!" unless open F, "> $tfn";
- $tmpfiles{$tfn}=1;
- # vvv Dat: doesn't work with gs 8.53: Error: /undefined in readxrefentry
- die unless print F "% this is temporary gs command file created by $program".'
- GS_PDF_ProcSet begin
- pdfdict begin
- FN (r) file pdfopen begin
- % vvv keep file offsets, because `pdffindpageref` overrides it with contents
- /OFT Objects 0 get dup length array copy def
- % vvv Dat: the generation number is assumed to be 0
- % vvv Dat: modifies Objects[0]
- 1 pdffindpageref 0 get
- Objects 0 OFT put
- %===
- %print_xref
- { readxrefentry } stopped { Objects exch lget } if
- ===
- currentdict pdfclose end end end
- ';
- die unless close F;
-
- my $gs2="$GS -dNODISPLAY -dBATCH -sFN=".fnq(fix_pipe_out(undef))." -q ".fnq($tfn);
- debug "Ghostscript dup pipe: $gs2";
- my $offset=`$gs2`;
- #die $offset;
- chomp $offset;
- temp_unlink $tfn;
- if ($offset=~/\A\d+\Z(?!\n)/) {
- # Dat: now $offsets is a file position containing our /Page object
- die unless open F, "+< ".fix_pipe_out(undef);
- die unless binmode F;
- die unless seek F, $offset+=0, 0;
- my $pageobj;
- die unless 32<read F, $pageobj, 4096;
- if ($::opt_keepoldmediabox) {
- if ($pageobj=~m@\A(.*?/Type\s*/Page\b.*?/MediaBox\s*\[0 0 [^\]]*\].*?)((?:/CropBox\s*\[[^\]]+\]\s*)?/MediaBox\s*\[[^\]]+\])@s) {
- substr($pageobj, length($1), length($2))=" "x length($2);
- # ^^^ overwrite first buggy /MediaBox definition with spaces
- die unless seek F, $offset, 0;
- die unless print F $pageobj;
- debug "new /MediaBox destroyed.";
- } else {
- debug "warning: double /MediaBox not found at $offset";
- }
- } else {
- if ($pageobj=~m@\A(.*?/Type\s*/Page\b.*?)(/MediaBox\s*\[0 0 [^\]]*\]).*?/MediaBox\b@s) {
- substr($pageobj, length($1), length($2))=" "x length($2);
- # ^^^ overwrite first buggy /MediaBox definition with spaces
- die unless seek F, $offset, 0;
- die unless print F $pageobj;
- debug "old /MediaBox destroyed.";
- } else {
- debug "warning: double /MediaBox not found at $offset";
- }
- }
- die unless close F;
- } else {
- debug "warning: gs failed to locate double /MediaBox";
- }
-}
-if ($FileFormat eq 'PCL5' and $do_fix_tumble) {
- # stupid Ghostscript ignores /Tumble true with -sDEVICE=ljet4
- # 2 dict dup /Duplex true /Tumble false put setpagedevice % long HP PCL5e "\033&l1S"
- # 2 dict dup /Duplex true /Tumble true put setpagedevice % short HP PCL5e "\033&l2S"
- # 2 dict dup /Duplex false /Tumble false put setpagedevice % simplex HP PCL5e "\033&l0S"
- # HP PCL5e gs header "\033E\033&l2A\033&l1S\033&l0o0l0E\033&l-180u36Z"
- die unless open F, "+< ".fix_pipe_out(undef);
- die unless binmode F;
- my $pageobj;
- die unless 32<read F, $pageobj, 4096;
- if ($pageobj=~s@\033&l1S.*@\033&l2S@s) {
- die unless seek F, 0, 0;
- die unless print F $pageobj;
- debug "fixed /Tumble true (short).";
- } elsif ($pageobj=~m@\033&l0S@) {
- debug "no need to fix to /Tumble.";
- } else {
- debug "warning: /Duplex /Tumble settings not found"
- }
- die unless close F;
-}
-if ($do_scale3_pnm) {
- # Imp: scale down the file in place, ovoid early overwrite
- # Imp: possibly call an external C program that is faster
- debug "Scaling down PNM by 3x3";
- die unless open F, "> $scale3_pnm_fn";
- die unless binmode F;
- die unless open FIN, "< ".fix_pipe_out(undef);
- my $hd;
- die "PNMraw expected\n" if read(FIN,$hd,2)!=2 or $hd!~/\AP[456]/;
- my $wd=pnm_gettok(*FIN); die "width expected\n" if $wd!~/\A(\d+)\Z(?!\n)/;
- my $wd3=$hd eq 'P4' ? ($wd+7)>>3 : $hd eq 'P5' ? $wd : $wd*3; # bw/grayscale/RGB
- my $ht=pnm_gettok(*FIN); die "height expected\n" if $ht!~/\A(\d+)\Z(?!\n)/;
- if ($hd ne 'P4') {
- my $mx=pnm_gettok(*FIN); die "max==255 expected, got: $mx\n" if $mx ne '255';
- }
- $wd+=0; $ht+=0;
- { use integer;
- my $phd=($hd eq 'P5' and $FileFormat eq 'PBM') ? "P4 ".(($wd+2)/3)." ".(($ht+2)/3)."\n"
- : ($hd eq 'P6' ? 'P6' : 'P5')."\n# reduced-3x3\n".
- (($wd+2)/3)." ".(($ht+2)/3)." 255\n";
- die if !print F $phd;
- }
-
- my($l1,$l2,$l3);
- my $ret="";
- if ($hd eq 'P4') {
- while ($ht>0) {
- die "full row expected1\n" if $wd3!=read FIN, $l1, $wd3;
- if (--$ht==0) { $l2=$l1 }
- else {
- die "full row expected2\n" if $wd3!=read FIN, $l2, $wd3;
- if (--$ht==0) { $l3=$l2 } # Imp: adjust 2/3 weight
- else { $ht--;
- die "full row expected3\n" if $wd3!=read FIN, $l3, $wd3;
- }
- }
- $l1=unpack("B$wd",$l1); $l1=~y@10@\000\377@; $l1.=substr($l1,-3+length($l1)%3) if length($l1)%3!=0;
- $l2=unpack("B$wd",$l2); $l2=~y@10@\000\377@; $l2.=substr($l2,-3+length($l2)%3) if length($l2)%3!=0;
- $l3=unpack("B$wd",$l3); $l3=~y@10@\000\377@; $l3.=substr($l3,-3+length($l3)%3) if length($l3)%3!=0;
- p5_avg_lines($l1, $l2, $l3, $ret);
- die if !print F $ret;
- }
- } elsif ($hd eq 'P5') {
- while ($ht>0) {
- die "full row expected1\n" if $wd3!=read FIN, $l1, $wd3;
- $l1.=substr($l1,-3+length($l1)%3) if length($l1)%3!=0;
- if (--$ht==0) { $l2=$l1 }
- else {
- die "full row expected2\n" if $wd3!=read FIN, $l2, $wd3;
- $l2.=substr($l2,-3+length($l2)%3) if length($l2)%3!=0;
- if (--$ht==0) { $l3=$l2 } # Imp: adjust 2/3 weight
- else { $ht--;
- die "full row expected3\n" if $wd3!=read FIN, $l3, $wd3;
- $l3.=substr($l3,-3+length($l3)%3) if length($l3)%3!=0;
- }
- }
- p5_avg_lines($l1, $l2, $l3, $ret);
- if ($FileFormat eq 'PBM') {
- my $I=length($ret);
- while ($I--) { vec($ret,$I,8)=vec($ret,$I,8)<$::opt_threshold } # [\0\1]
- # ^^^ grayscale>=$::opt_threshold will be white
- $ret=pack"B".length($ret),$ret;
- }
- die if !print F $ret;
- }
- } elsif ($hd eq 'P6') {
- while ($ht>0) {
- die "full row expected1\n" if $wd3!=read FIN, $l1, $wd3;
- $l1.=substr($l1,-9+length($l1)%9) if length($l1)%9!=0;
- if (--$ht==0) { $l2=$l1 }
- else {
- die "full row expected2\n" if $wd3!=read FIN, $l2, $wd3;
- $l2.=substr($l2,-9+length($l2)%9) if length($l2)%9!=0;
- if (--$ht==0) { $l3=$l2 } # Imp: adjust 2/3 weight
- else { $ht--;
- die "full row expected3\n" if $wd3!=read FIN, $l3, $wd3;
- $l3.=substr($l3,-9+length($l3)%9) if length($l3)%9!=0;
- }
- }
- p6_avg_lines($l1, $l2, $l3, $ret);
- die if !print F $ret;
- }
- }
- die unless close F;
- temp_unlink $temp_out_fn;
- undef $temp_out_fn;
-}
-if (@pnm2sampled_cmd) { # $scale3_pnm_fn -> $OutputFilename
- do_system @pnm2sampled_cmd; # Dat: uses @extra -- really share that?
- temp_unlink $scale3_pnm_fn;
-} else { # BUGFIX for `a2ping.pl -v --antialias=no negyzet.eps negyzet.png' at Wed Jul 20 21:34:29 CEST 2005
- fix_close_out();
-}
-undef $unlink_OutputFilename;
-if ($OutputFilename eq '-') {
- debug "Done OK, stdout is $FileFormat"
-} elsif (-f $OutputFilename) {
- debug "Done OK, created $FileFormat file $OutputFilename (".(-s _)." bytes)";
-} else {
- error "missing $OutputFilename"
-}
-just::end __END__
-
-Dat: `=item * foo' is wrong, puts big space between `*' and `foo'
-
-=encoding latin1
-
-=begin man
-
-.ds pts-dev \*[.T]
-.do if '\*[.T]'ascii' .ds pts-dev tty
-.do if '\*[.T]'ascii8' .ds pts-dev tty
-.do if '\*[.T]'latin1' .ds pts-dev tty
-.do if '\*[.T]'nippon' .ds pts-dev tty
-.do if '\*[.T]'utf8' .ds pts-dev tty
-.do if '\*[.T]'cp1047' .ds pts-dev tty
-.do if '\*[pts-dev]'tty' \{\
-.ll 79
-.pl 33333v
-.nr IN 2n
-.\}
-.ad n
-
-=end man
-
-=head1 NAME
-
-a2ping.pl -- convert between PS, EPS and PDF and other page description
-formats
-
-=head1 SYNOPSIS
-
-Z<> B<a2ping.pl> [B<-->]B<help>
- B<a2ping.pl> [B<-->]B<doc>
- B<a2ping.pl> [I<options>] <I<inputfile>> [[I<outformat>:] I<outputfile>]
-
-=head1 DESCRIPTION
-
-B<a2ping> is a UNIX command line utility written in Perl that
-converts many raster image and vector graphics formats to EPS or PDF and
-other page description formats. Accepted input file formats are: PS
-(PostScript), EPS, PDF, PNG, JPEG, TIFF, PNM, BMP, GIF, LBM, XPM, PCX,
-TGA. Accepted output formats are: EPS, PCL5, PDF, PDF1, PBM, PGM, PPM,
-PS, markedEPS, markedPS, PNG, XWD, BMP, TIFF, JPEG, GIF, XPM.
-B<a2ping> delegates the low-level work to
-Ghostscript (GS), B<pdftops> and B<sam2p>. B<a2ping> fixes many glitches
-during the EPS to EPS conversion, so its output is often more compatible
-and better embeddable than its input.
-
-Without the C<--below> option, it is guarenteed to start at the 0,0
-coordinate. C<--below>, C<--hires> and C<-v> are recommended options.
-
-The page size is set exactly corresponding to the BoundingBox.
-This means that when Ghostscript renders it, the result needs no
-cropping, and the PDF MediaBox is correct.
-
-If the bounding box is not right, of course, you have problems. If you
-feed crap in, you get crap. But you can supply the
-B<--bboxfrom=compute-gs> option to make GS recompute the bounding box.
-
-The name of the input file doesn't matter -- B<a2ping> detects the file
-format based on the first few bytes of the file. The name of the output
-file matters if I<outformat> is missing from the command line: then the
-extension of the output file determines the FileFormat (I<outformat>).
-
-=head1 EXTERNAL PROGRAMS
-
-The internal file format of B<a2ping.pl> is PS/EPS. Everything read is
-first converted to PS or EPS, then processed by B<a2ping.pl>, then
-converted to the output format.
-
-To analyse the bounding box and other properties of non-EPS PS files
-(and EPS files with option B<--bboxfrom> other than B<=guess>), GS is
-used. Converting PS to EPS involves this analysis.
-
-To write PDF files, GS is used.
-
-To read PDF files, B<pdftops> from the B<xpdf> package is used.
-
-Sampled input formats are PNG, JPEG, TIFF, PNM, BMP, GIF, LBM, XPM, PCX
-and TGA. To read sampled input formats, B<sam2p> is used. B<sam2p> is
-a raster image converter written in C++ by the author of B<a2ping.pl>.
-
-Extra output formats are PNG, XWD, BMP, TIFF, JPEG, GIF and XPM. To
-write extra output formats, B<sam2p> and GS are used.
-
-PNM output formats are PGM, PGM and PPM. To write PNM output formats, GS
-is used.
-
-=head1 OPTIONS
-
-=head2 General Options
-
-=over 2
-
-=item B<-h>, B<--help>
-
-Show a summary of the usage
-
-=item B<--doc>
-
-Show the man page
-
-=item B<-v>, B<--(no)verbose>
-
-Show progress and debug messages (default: no)
-
-=back
-
-=head2 Options for the Bounding box
-
-=over 2
-
-=item B<--(no)hires>
-
-Use HiResBoundingBox in the input file, if present (default: yes)
-
-=item B<--(no)exact>
-
-Use ExactBoundingBox in the input file, if present (default: no)
-
-=item B<--(no)keepoldmediabox>
-
-keep only old, [0 0]-based MediaBox in PDF (default: no)
-
-=item B<--bboxfrom=>I<adsc|compute-gs|guess|pagesize>
-
-Method for determining the BoundingBox (default: guess)
-
-=item B<--(no)below>
-
-Allow page content below and left of the origin (default: no)
-
-=back
-
-=head2 Options for graphics and fonts
-
-=over 2
-
-=item B<--(no)compress>
-
-use compression (default: best)
-
-=item B<--(no)antialias>
-
-render shades at outlines. Possible values: (=I<scale3yes> =I<no> =I<yes>) (default: scale3no)
-
-=item B<--(no)lossy>
-
-allow lossy image filters (EPS->PDF) (default: yes)
-
-=item B<--papersize=>I<unchanged|force-unknown|600bpx5cm>
-
-(default: default) (bp)
-
-=item B<--threshold=>
-
-min color for 1 in 8->1 bit conv (default: 128)
-
-=back
-
-=head2 Options for debugging and changing internals
-
-=over 2
-
-=item B<--(no)tmpunlink>
-
-Unlink temporary files (default: yes). Use B<--notmpunklink> if you
-want to inspect intermediate files.
-
-=item B<--gs-cmd=>I<path>
-
-path to Ghostscript program (default: gs or gswin32c)
-
-=item B<--gs-ccmd=>I<path>
-
-path to Ghostscript for BoundingBox calculation (default: gs or gswin32c)
-
-=item B<--gsextra=>I<GS_ARGS>
-
-Pass extra arguments to gs
-
-=item B<--extra=>
-
-Pass extra arguments to external program (i.e pdftops)
-
-=back
-
-=head1 TIPS AND TRICKS
-
-=over 2
-
-=item *
-
-If your EPS contains a wrong bounding box, you can fix it by running
-C<a2ping.pl -v --bboxfrom=compute-gs thefile.eps -->
-
-=item *
-
-You can specify B<-> as I<inputfile> to get stdin and as I<outputfile>
-to get stdout. This works even for PDF files (which must be seekable),
-because B<a2ping> copies them to a temporary file automatically.
-
-=item *
-
-If I<inputfile> and I<outputfile> are the same, B<a2ping> copies the
-I<inputfile> to a temporary location first. However, this usage is
-recommended only if there is a backup of the file to be restored in case
-B<a2ping> doesn't produce the desired result.
-
-=item *
-
-If you specify B<--> as I<outputfile>, it will be the same as I<inputfile>.
-
-=item *
-
-B<a2ping> respects B<--Duplex> for FileFormat PCL5, even though GS doesn't.
-
-=item *
-
-If you have an incompatible PS that GS can read but your printer cannot print,
-just run C<a2ping.pl foo.ps PDF: - | a2ping.pl - PS: foo.ps>
-
-=item *
-
-If you have a PS coming from Win32 (often with extension C<.prn>), run
-it through B<a2ping>. It will remove the resolution changes and the
-progress text printed to the terminal (which confuses gv(1) and makes
-some filters in the print queue emit incorrect output).
-
-=item *
-
-B<a2ping> does antialiasing (B<--antialias=scale3no>) of glyphs and
-curves when emitting a sampled image (FileFormats such as PGM and PPM).
-This improves readability of the glyphs. B<=yes> instructs GS to do
-internal antialiasing, but it usually doesn't improve much. B<=scale3no>
-turns off GS internal antialiasing, but makes it render everything 3x3
-as big, and then scales it back down. B<=scale3no> turns on both 3x3
-scaling and GS internal antialiasing, which results in thicker lines and
-worse quality in general.
-
-=item *
-
-When creating a PBM file, antialiasing usually doesn't improve the
-quality, so it is switched off by default. But if you set
-B<--antialias=scale3no> or B<--antialias=scale3yes>, GS will render a PGM file,
-and the value of B<--threshold> determines the minimum intensity for white in
-the final PBM.
-
-=item *
-
-If you need a bigger sampled output file, specify a larger
-B<--Resolution>. The default is B<--Resolution=72>. If your sampled output file
-is going to be really big, you should specify B<--AntiAlias=yes> instead of
-the default B<--AntiAlias=scale3no> to speed up conversion.
-
-=item *
-
-To make sure fonts are included in a PDF file generated from eps, use
-B<--gsextra='-dEmbedAllFonts=true -dPDFSETTINGS=/printer'>.
-
-=back
-
-
-=head1 MISC
-
-=over 2
-
-=item *
-
-Doesn't depend on the filename or extension of the input file.
-
-=item *
-
-Conversion from EPS to PDF: fixes glitches etc., calls gs
--sDEVICE=pdfwrite
-
-=item *
-
-Conversion from EPS to EPS: fixes various glitches, moves (llx,lly) to
-(0,0), removes binary junk from the beginning of the EPS etc.
-
-=item *
-
-Conversion from PDF to PDF: keeps the file intact
-
-=item *
-
-Conversion from PDF to EPS: calls pdftops -eps (of the xpdf package)
-
-=item *
-
-Conversion from PS to EPS: keeps 1st page only, removes setpagedevice etc.
-
-=back
-
-=head1 AUTHORS
-
-The author of B<a2ping> is Péter Szabó <F<pts@fazekas.hu>>.
-
-B<a2ping> is inspired by and historically based on the B<epstopdf> Perl
-script modified by Thomas Esser, Sept. 1998, but his modifications have
-been removed from B<a2ping>, and also B<a2ping> and B<epstopdf> do not
-share common code anymore. B<epstopdf> is written by Sebastian Rahtz,
-for Elsevier Science. B<epstopdf> contained extra tricks from Hans Hagen's
-texutil.
-
-B<a2ping> contains contributions from several people, see the file
-F<HISTORY.txt> for details. Thank you all for contributing!
diff --git a/Build/source/texk/texlive/linked_scripts/accfonts/mkt1font b/Build/source/texk/texlive/linked_scripts/accfonts/mkt1font
deleted file mode 100755
index 966ba5932d9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/accfonts/mkt1font
+++ /dev/null
@@ -1,1012 +0,0 @@
-#!/usr/bin/perl
-
-# Mkt1font: a program to generate accented Type 1 PostScript fonts
-# Copyright (C) 1997 John D. Smith
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-$version = 0.25;
-#-----------------------------------------------------------------------------#
-$description =
-"Syntax: mkt1font -n fontname -d definition-file -a afm-file -f font-file
- [-s shrink-factor] [-c candrabindu-adjustment] [-b]
-
-Mkt1font creates new Type 1 PostScript fonts based on existing fonts
-(\"input fonts\"). In order to do this it makes use of I. Lee
-Hetherington's programs t1asm and t1disasm, which must be present on
-the system. A successful run will generate an AFM file and a PFB
-file, as well as a DIS file containing a disassembled version of the
-PFB file (including useful comments). Four options must be specified
-on the command line, as follows:
-
- -n should name the font it is intended to generate. Avoid names
- such as \"myfont\", as both mkt1font and other programs attempt
- to draw conclusions from the name; better would be something
- like \"Utopia_French-BoldItalic\". The generated font files
- will also use this for their basename.
-
- -d should refer to a font definition file. This file (which could
- usefully be named, e.g., \"French.def\") should consist of
- lines of character definitions, in the form
- \"number\" \"character\"
- or
- \"number\" \"character\" \"accent\"
- Here \"number\" represents the character's position in the new
- encoding and may be expressed in decimal, octal or hex;
- \"character\" names the character (e.g. \"comma\", \"eight\",
- \"A\") or consists of the word \".notdef\" (indicating that
- the specified number's \"slot\" in the new encoding is to be
- empty); and \"accent\" optionally names an accent to be placed
- on the character. In addition to the standard accents available
- in PostScript fonts, \"underbar\" and \"underdot\" are also
- available, as are \"under\" versions of all the normal
- superscript accents (\"underdieresis\", \"underring\", etc.).
- The Indian accent \"candrabindu\" may also be specified: it
- is formed by overprinting a breve with a dotaccent. Finally,
- \"overdot\" may be used as a synonym for \"dotaccent\".
-
- If the character named in the \"accent\" position is not in fact
- a valid accent character, the program interprets the definition
- as a request for a digraph formed from the \"character\" and the
- \"accent\". A digraph consisting of, say, \"k\" and \"h\" will be
- indistinguishable from the letters \"k\" and \"h\" printed
- consecutively, but the digraph \"kh\" can itself receive accents
- like any other character: see next paragraph.
-
- A new character (such as \"amacron\" or \"kh\") may be freely
- used in the \"character\" position of a further definition (such
- as \"amacron breve\" or \"kh underbar\"). There is no constraint
- on the ordering of definitions within a definition file. The
- definition of \"a macron\" does not have to precede that of
- \"amacron breve\": requests for \"impossible\" characters are
- deferred until their constituents have had a chance to come into
- being.
-
- \"Slots\" for which no new definition is given retain the
- definition they have in the input font.
-
- The definition file may also contain blank lines and comments
- (introduced by \"\#\").
-
- -a should refer to the AFM (Adobe Font Metrics) file for the input
- font.
-
- -f should refer to the binary font file (PFB) for the input font.
- (In fact the equivalent ASCII file (PFA) is also acceptable for
- input, but the output font is always in PFB format.)
-
- -s may optionally give the factor, expressed as a per-thousand
- value, by which normally superscript accents (such as dieresis,
- ring) should be shrunk when they are used as subscript accents
- (such as underdieresis, underring). Values of around 800 may be
- found useful.
-
- -c may optionally give two comma-separated numerical values to
- adjust the x and y coordinates of the dotaccent placed within a
- breve to form the candrabindu accent.
-
- -b may optionally be specified to block the use of predefined
- accented characters, forcing mkt1font to define its own
- versions. This may be useful to secure a consistent appearance
- in cases where a font designer does not share mkt1font's views
- on where accents should be placed.
-
-The -h option prints this help.
-";
-#-----------------------------------------------------------------------------#
-
-########################
-# Packages and constants
-########################
-#
-use File::Basename;
-use Getopt::Std;
-$cmdline = basename($0) . " " . join " ", @ARGV;
-getopts('n:d:a:f:c:s:bh');
-if ($opt_h or !($opt_n && $opt_d && $opt_a && $opt_f) or ($#ARGV >= 0)) {
- print STDERR $description;
- exit 1;
-}
-($enc = basename($opt_d)) =~ s/\..*$//;
-if ($opt_n =~ /\s/) { die "Font name cannot contain whitespace\n" }
-($famname = $opt_n) =~ s/^(.*)-.*?$/$1/;
-if ($opt_s) { $shrink = $opt_s / 1000 } else { $shrink = 1 }
-@months = ( "January", "February", "March", "April",
- "May", "June", "July", "August",
- "September", "October", "November", "December"
- );
-@lt = localtime;
-$date = "$months[$lt[4]] $lt[3], ${ \($lt[5] + 1900) }";
-if ($opt_c) { ($cbx, $cby) = $opt_c =~ /^(.*),(.*)$/ } # candrabindu
-
-###############
-# Read DEF file
-###############
-#
-open DEF, $opt_d or die "Cannot open $opt_d: $!\n";
-while (<DEF>) {
- next if (/^\s*$/ || /^\#/);
- s/\s*(\#.*)?$//;
- push @deflines, $_;
-}
-close DEF;
-
-###############
-# Read AFM file
-###############
-#
-# File header
-#
-open AFM, $opt_a or die "Cannot open $opt_a: $!\n";
-while (<AFM>) {
- if (/^StartFontMetrics/) {
- $afmhead = $_;
- do {
- $_ = <AFM>;
- $afmhead .= $_;
- }
- until $_ =~ /^StartCharMetrics \d+\r?$/;
- $afmhead =~ s/\r//gm; # Might be DOS file
- $afmhead =~ /^FontName (.*)$/m;
- $ofname = $1;
- $afmbanner = "\nComment Based on $ofname; modified for $enc encoding";
- $afmbanner .= "\nComment by John Smiths's program mkt1font ";
- $afmbanner .= "(v. $version) " if $version;
- $afmbanner .= "on $date";
- $afmbanner .= "\nComment Command line: $cmdline";
- $afmhead =~ s/(\n^FontName )(.*)$/$1$opt_n/m;
- $afmhead =~ s/(\n^FullName )(.*)$/$1$opt_n/m;
- $afmhead =~ s/(\n^FamilyName )(.*)$/$1$famname/m;
- $afmhead =~ s/\n^Comment /$afmbanner$&/m;
- $afmhead =~ s/(\n^EncodingScheme ).*$/$1FontSpecific/m;
- if ($afmhead =~ /\n^ItalicAngle (.*)$/m) { $italangle = $1 }
- if ($afmhead =~ /\n^CapHeight (.*)$/m) { $capheight = $1 }
- if ($afmhead =~ /\n^XHeight (.*)$/m) { $xheight = $1 }
- if ($afmhead =~ /\n^FontBBox -?\d+ (-?\d+) (-?\d+) (-?\d+)$/m) {
- ($maxdp, $maxrs, $maxht) = ($1, $2, $3);
- }
- }
- #
- # Encoded chars
- #
- if (/(^C (\d+) ; WX \d+ ; N ([a-zA-Z_][a-zA-Z0-9_.]*|\.notdef) ; B .* ;( L .* ;)?)\r?$/) {
- $metrics_enc[$2] = "$1\n";
- }
- #
- # Unencoded chars
- #
- elsif (/(^C -1 ; WX \d+ ; N ([a-zA-Z_][a-zA-Z0-9_.]*|\.notdef) ; B .* ;( L .* ;)?)\r?$/) {
- $metrics_unenc .= "$1\n";
- }
- #
- # Kerns etc.
- #
- if (/^EndCharMetrics\r?$/) {
- $afmtail = $_;
- do {
- $_ = <AFM>;
- $afmtail .= $_;
- }
- until eof(AFM);
- $afmtail =~ s/[\r\cZ]//gm; # Might be DOS file
- }
-}
-if ($afmtail =~ /(\A(?:.|\n)*^StartKernPairs )\d+\n((?:.|\n)*)(^EndKernPairs(?:.|\n)*\Z)/m) {
- ($kstart, $kdefs, $kend) = ($1, $2, $3);
-}
-close AFM;
-
-###############################
-# Read and disassemble PFB file
-###############################
-#
-open PFB, $opt_f or die "Cannot open $opt_f: $!\n";
-$_ = <PFB>;
-unless (/%!/) { die "File $opt_f is not a PostScript font\n" }
-close PFB;
-$disfile1 = "mkt1font$$.dis";
-system "t1disasm $opt_f >$disfile1 2>/dev/null";
-open DIS, $disfile1 or die "Cannot open disassembled font file: $!\n";
-while (<DIS>) {
- #
- # Locate crucial definitions
- #
- if (/^\/(.*?) ?{ ?noaccess def ?} ?executeonly def$/) {
- $nd = $1;
- ($rend = $nd) =~ s/\|/\\|/g; # Regexp version
- next;
- }
- if (/^\/(.*?) ?{ ?noaccess put ?} ?executeonly def$/) {
- $np = $1;
- ($renp = $np) =~ s/\|/\\|/g; # Regexp version
- next;
- }
- if (/^\/Subrs (\d+) array/) {
- $subrsnum = $1;
- do {
- #
- # Store subroutine definitions in @subrs
- #
- $l = $_ = <DIS>;
- if (/^dup (\d+) {$/) {
- $subrnum = $1;
- $subrdef = $_;
- do {
- $_ = <DIS>;
- $subrdef .= $_;
- }
- until /^\t} ?$renp$/;
- }
- #
- # "correct" t1disasm output so t1asm will accept it as input
- #
- $subrdef =~ s/^(\t})($rend|$renp)$/$1 $2/m;
- $subrs[$subrnum] = $subrdef;
- }
- until ($l !~ /^dup \d+ {$/);
- next;
- }
- if (/^2 index \/CharStrings (\d+) dict dup begin/) {
- #
- # do *not* use "$" to anchor the end of this line, because
- # it may end with an invisible trailing space!
- #
- $chdefsnum = $1;
- do {
- #
- # Store character definitions in %chstrings
- #
- $l = $_ = <DIS>;
- if (/^\/([a-zA-Z_][a-zA-Z0-9_.]*|\.notdef|\.null) {$/) {
- $chname = $1;
- $chdef = $_;
- do {
- $_ = <DIS>;
- $chdef .= $_;
- }
- until /^\t} ?$rend$/;
- }
- #
- #"correct" t1disasm output so t1asm will accept it as input
- #
- $chdef =~ s/^(\t})($rend|$renp)$/$1 $2/m;
- $chstrings{$chname} = $chdef;
- }
- until ($l !~ /^\/([a-zA-Z_][a-zA-Z0-9_.]*|\.notdef|\.null) {$/);
- #
- # File tail
- #
- if (/^end/) {
- $distail = $_;
- do {
- $_ = <DIS>;
- $distail .= $_;
- }
- until eof(DIS);
- }
- }
-}
-close DIS;
-unless ($nd) { die "Cannot find \"noaccess def\" definition\n" }
-unless ($np) { die "Cannot find \"noaccess put\" definition\n" }
-unless ($subrsnum) { die "Cannot find size of Subrs array\n" }
-unless ($chdefsnum) { die "Cannot find size of CharStrings dict\n" }
-
-##################
-# Set up constants
-##################
-#
-$subacc = "(cedilla|ogonek|commaaccent)";
-$supacc = "(grave|acute|circumflex|tilde|macron|breve|dotaccent|overdot|dieresis|ring|hungarumlaut|caron|candrabindu)";
-$underacc = "(underdot|under$supacc)";
-$accents = "($subacc|$supacc|$underacc|underbar)";
-$underadp = -230; # depth of "under" accs
-$underddp = -213; # depth of underdot
-if ($opt_n =~ /Bold/) { $thk = 72 } else { $thk = 52 } # thickness and
-$underbdp = -(82 + $thk); # depth of underbar
-getcharinfo("macron");
-$accheight = $chht{macron}; # height of macron
-$accdepth = $chdp{macron}; # "depth" of macron
-$v1 = $accheight - $xheight; # vertical offset for double accents
-$v2 = $capheight - $xheight; # vertical offset for accented caps etc
-#
-# Italic adjustment: tan(angle)
-#
-$itadj = sin($italangle * 3.14159 / 180) / cos($italangle * 3.14159 / 180);
-
-###########################
-# Create uni0237 (dotlessj)
-###########################
-#
-$chstrings{uni0237} = $chstrings{j} . "\n";
-$chstrings{uni0237} =~ /\A(.*?)(\t[-0-9 ]+?[rvh]moveto)(\n.+)(\n\t.*?(-?\d+) [rv]moveto)(.*?)(\n\tendchar.*?)\Z/ms;
-($one, $two, $three, $four, $five, $six, $seven) = ($1, $2, $3, $4, $5, $6, $7);
-if ($five > 0) { $chstrings{uni0237} = $one . $two . $three . $seven }
-else {
- findend("j1", ($two . $three));
- $j1end = "\t$hend{j1} $vend{j1} rmoveto";
- $chstrings{uni0237} = $one . $j1end . $four . $six . $seven
-}
-$chstrings{uni0237} =~s/\A\/j /\/uni0237 /m;
-getcharinfo("j");
-getcharinfo("dotlessi");
-$metrics_unenc .= "C -1 ; WX $chwd{j} ; N uni0237 ; B $chls{j} $chdp{j} $chrs{j} $chht{dotlessi} ;\n";
-#
-######################
-# Build the characters
-######################
-#
-# First build a list of definitions supplied by user
-#
-for (@deflines) {
- if (/^\s*(\d+|0[0-7]+|0x[0-9a-fA-F]+)\s+([a-zA-Z_][a-zA-Z0-9_.]*?|\.notdef)(?:\s+([a-zA-Z_][a-zA-Z0-9_.]*))?$/) {
- ($num, $char, $acc) = ($1, $2, $3);
- $num = oct $num if $num =~ /^0/;
- if ($num > 255) { die "Bad definition (number out of range): $_\n" }
- $def = {};
- $def->{qdef} = $_;
- $def->{num} = $num;
- $def->{char} = $char;
- $def->{acc} = $acc;
- $def->{nchar} = $char . $acc;
- push @nchars, $def->{nchar};
- push @defs, $def;
- }
- else { die "Bad definition: $_\n" }
-}
-#
-# Work through the list
-#
-while (@defs) {
- $def = shift @defs;
- $qdef = $def->{qdef};
- $num = $def->{num};
- $char = $def->{char};
- $acc = $def->{acc};
- $nchar = $def->{nchar};
- #
- # If we can't handle $char/$acc yet, but believe we will be able
- # to later, send the definition to the back of the queue. In case
- # it later turns out we were wrong, allow only five loops before
- # giving up.
- #
- if (!grep / ; N $char ; /, @metrics_enc
- and $metrics_unenc !~ / ; N $char ; /m) {
- if (grep /^$char$/, @nchars) {
- unless (++$def->{requeue} > 5) {
- push @defs, $def;
- next;
- }
- }
- else { die "Bad definition (no such character): $qdef\n" }
- }
- if ($acc
- and !grep / ; N $acc ; /, @metrics_enc
- and $metrics_unenc !~ / ; N $acc ; /m
- and $acc !~ /^$accents$/) {
- if (grep /^$acc$/, @nchars) {
- unless (++$def->{requeue} > 5) {
- push @defs, $def;
- next;
- }
- }
- else { die "Bad definition (no such accent): $qdef\n" }
- }
- #
- # First deal with .notdef
- #
- if ($nchar eq ".notdef") {
- ($old = $metrics_enc[$num]) =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- undef $metrics_enc[$num];
- }
- #
- # Now look for new char among existing encoded chars (unless blocked by -b)
- #
- else {
- if (!($acc and $opt_b)
- and @foundit = grep / ; N $nchar ; /, @metrics_enc) {
- ($foundit = shift @foundit) =~ s/^C (\d+)/C $num/;
- $prevnum = $1;
- unless ($prevnum == $num) {
- ($old = $metrics_enc[$num]) =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- $metrics_enc[$num] = $foundit;
- }
- fixkerns($char, $acc);
- }
- #
- # Next look among existing unencoded chars (unless blocked by -b)
- #
- elsif (!($acc and $opt_b)
- and $metrics_unenc =~ s/^C -1 ; WX \d+ ; N $nchar ; B .* ;( L .* ;)?\n//m) {
- ($foundit = $&) =~ s/^C -1/C $num$1/m;
- $old = $metrics_enc[$num];
- if ($old) {
- $old =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- }
- $metrics_enc[$num] = $foundit;
- fixkerns($char, $acc);
- }
- #
- # If it can't be built from sub-elements, issue a warning and move on
- #
- elsif (!$acc) { warn "No such character - ignoring definition: $qdef\n" }
- #
- # Now build the char
- #
- else {
- #
- # First get rid of predefined afm entries and synonyms
- #
- $metrics_unenc =~ s/^C -1 ; WX \d+ ; N $nchar ; B .* ;( L .* ;)?\n//m;
- $kdefs =~ s/\nKPX .*$nchar .*$//gm;
- if ($acc eq "overdot") {
- $nchar2 = $char . "dotaccent";
- $metrics_unenc =~ s/^C -1 ; WX \d+ ; N $nchar2 ; B .* ;( L .* ;)?\n//m;
- $kdefs =~ s/\nKPX .*$nchar2 .*$//gm;
- delete $chstrings{$nchar2};
- }
- #
- # Go!
- #
- if ($acc =~ /^$subacc$/) {
- subacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^$supacc$/) {
- supacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^$underacc$/) {
- underacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^underbar$/) {
- underb($num, $char, $nchar);
- fixkerns($char, $acc);
- }
- else {
- digraph($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- }
- }
-}
-
-################
-# Write AFM file
-################
-#
-open OUTAFM, ">$opt_n.afm";
-foreach (@metrics_enc) { # Avoid duplicate entries
- ($chname) = /( ; N [a-zA-Z_][a-zA-Z0-9_.]* ; )/;
- $metrics_unenc =~ s/^C -1 .*$chname.*\n//gm if $chname;
-}
-$chmetricnum = split(/\n/, $metrics_unenc);
-$chmetricnum += grep /^C /, @metrics_enc;
-$afmhead =~ s/^(FontBBox -?\d+ )-?\d+ -?\d+ -?\d+$/$1$maxdp $maxrs $maxht/m;
-$afmhead =~ s/^(StartCharMetrics )\d+$/$1$chmetricnum/m;
-$encoding = "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n";
-print OUTAFM $afmhead;
-for $i (0 .. 255) {
- $line = $metrics_enc[$i];
- if ($line) {
- print OUTAFM $line;
- if ($line =~ /^C \d+ ; WX \d+ ; N ([a-zA-Z_][a-zA-Z0-9_.]*) ; /) {
- $encoding .= "dup $i /$1 put\n";
- }
- }
-}
-$encoding .= "readonly def\n";
-print OUTAFM $metrics_unenc;
-#
-# Tidy up kerns
-#
-if ($kdefs) {
- $kdefs = join("\n", sort split /\n/, $kdefs); # sort
- $kdefs .= "\n";
- $kdefs =~ s/((^KPX .*?)-?\d+$)\n\2.*$/$1/gm; # remove duplicates
- $kdefs =~ s/^\s*\n//gm; # and blank lines
- $knum = split(/\n/, $kdefs);
- $afmtail = $kstart . $knum . "\n" . $kdefs . $kend;
-}
-#
-# Eliminate composite character definitions
-#
-$afmtail =~ s/\n(Start|End)Composites.*$//gm;
-$afmtail =~ s/\nCC .*;$//gm;
-print OUTAFM $afmtail;
-close OUTAFM;
-
-#########################
-# Write DIS and PFB files
-#########################
-#
-$disfile2 = "$opt_n.dis";
-open OUTDIS, ">$disfile2";
-$disbanner = "% Based on $ofname; modified for $enc encoding\n";
-$disbanner .= "% by John Smiths's program mkt1font ";
-$disbanner .= "(v. $version) " if $version;
-$disbanner .= "on $date\n";
-$disbanner .= "% Command line: $cmdline";
-open DIS, $disfile1;
-while (<DIS>) { # get header
- s/^(%!.*: ).*$/$1$opt_n\n$disbanner/;
- s/(\/FullName \().*(\).*)$/$1$opt_n$2/;
- s/(\/FamilyName \().*(\).*)$/$1$famname$2/;
- s/(\/FontName \/).*?( .*)$/$1$opt_n$2/;
- s/(\/FontBBox {-?\d+ )-?\d+ -?\d+ -?\d+/$1$maxdp $maxrs $maxht/m;
- if (/^\/Encoding /) {
- print OUTDIS $encoding;
- next;
- }
- next if (/\/UniqueID .*$/);
- s /(\/BlueValues \[.*)(\] def)$/$1 $accheight $accheight$2/;
- if (/(\/Subrs )\d+( array)$/) {
- print OUTDIS "$1$subrsnum$2\n";
- last;
- }
- else { print OUTDIS }
-}
-close DIS;
-unlink $disfile1;
-foreach $subrdef (@subrs) { print OUTDIS $subrdef }
-$chdefsnum = scalar(keys(%chstrings));
-print OUTDIS "$nd\n2 index /CharStrings $chdefsnum dict dup begin\n";
-foreach (sort values %chstrings) { print OUTDIS }
-print OUTDIS $distail;
-close OUTDIS;
-system "t1asm -b $disfile2 >$opt_n.pfb 2>/dev/null";
-
-#####################
-# End of main program
-#####################
-
-sub subacc {
- #
- # Subscript accents
- #
- my ($num, $char, $acc, $nchar) = @_;
- my ($old, $astr, $h, $H, $V, $chdef, $acdef, $pstr);
- ($old = $metrics_enc[$num]) =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- getcharinfo($char) unless defined $chwd{$char};
- getcharinfo($acc) unless defined $chwd{$acc};
- $astr = "C $num ; WX $chwd{$char} ; N $nchar ; B $chls{$char} ";
- $astr .= "$chdp{$acc} $chrs{$char} $chht{$char} ;\n";
- $metrics_enc[$num] = $astr;
- $h = round(($chwd{$char} - $chwd{$acc}) / 2 + $chls{$acc});
- unless (defined $hend{$char}) { findend($char, $chstrings{$char}) }
- $H = $h - $hend{$char} - $chls{$char};
- $V = -$vend{$char};
- $chstrings{$char} =~ /^\/$char {\n(\t.+?hsbw\n(.|\n)*?)\tendchar\n\t} $rend\n/m;
- $chdef = $1;
- $chstrings{$acc} =~ /^\/$acc {\n\t.+? .+?hsbw\n((.|\n)+?\t} $rend\n)/m;
- $acdef = $1;
- $acdef = fixhints($nchar, $acc, $acdef, $h, 0);
- $pstr = "/$nchar {\n$chdef % $nchar: start of $acc\n";
- $pstr .= "\t$H $V rmoveto\n$acdef";
- $chstrings{$nchar} = $pstr;
-}
-
-sub supacc {
- #
- # Superscript accents
- #
- my ($num, $char, $acc, $nchar) = @_;
- my ($old, $cb, $astr, $h, $v, $H, $V, $it, $chdef, $acdef, $pstr, $newchar);
- ($old = $metrics_enc[$num]) =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- if ($char eq "i") { $char = "dotlessi" }
- if ($char eq "j") { $char = "uni0237" }
- if ($acc eq "overdot") { $acc = "dotaccent" }
- if ($acc eq "candrabindu") {
- $acc = "breve";
- $chstrings{"dotaccent"} =~ /^\/dotaccent {\n\t.+? .+?hsbw\n((.|\n)+?\t} $rend\n)/m;
- $cb = $1;
- }
- getcharinfo($char) unless defined $chwd{$char};
- getcharinfo($acc) unless defined $chwd{$acc};
- $astr = "C $num ; WX $chwd{$char} ; N $nchar ; B ";
- $astr .= "$chls{$char} $chdp{$char} $chrs{$char} ";
- $v = $chht{$acc};
- if ($chht{$char} >= $accheight + $v2) { # double accs
- $v += ($v1 + $v2); # on caps etc.
- $it = ($v1 + $v2) * $itadj;
- }
- elsif ($chht{$char} > 1.15 * $xheight) {
- if ($char =~ /$supacc$/ and $char !~ /under$supacc$/) {
- $v += $v1; # double accents
- $it = $v1 * $itadj;
- }
- else {
- $v += $v2; # accented caps etc.
- $it = $v2 * $itadj;
- }
- }
- else { $it = 0 }
- if ($v > $maxht) { $maxht = $v }
- $astr .= "$v ;\n";
- $metrics_enc[$num] = $astr;
- $v -= $chht{$acc};
- $h = round(($chwd{$char} - $chwd{$acc}) / 2 + $chls{$acc} - $it);
- unless (defined $hend{$char}) { findend($char, $chstrings{$char}) }
- $H = $h - $hend{$char} - $chls{$char};
- $V = $v - $vend{$char};
- $chstrings{$char} =~ /^\/$char {\n(\t.+?hsbw\n(.|\n)*?)\tendchar\n\t} $rend\n/m;
- $chdef = $1;
- $chstrings{$acc} =~ /^\/$acc {\n\t.+? .+?hsbw\n((.|\n)+?\t} $rend\n)/m;
- $acdef = $1;
- $acdef = fixhints($nchar, $acc, $acdef, $h, $v);
- $pstr = "/$nchar {\n$chdef % $nchar: start of $acc\n";
- $pstr .= "\t$H $V rmoveto\n$acdef";
- if ($cb) { # candrabindu
- getcharinfo("dotaccent") unless defined $chwd{dotaccent};
- $h = round(($chwd{$char} - $chwd{dotaccent}) / 2 + $chls{dotaccent} - $it);
- $h += $cbx;
- $v += $cby;
- $cb = fixhints($nchar, "dotaccent", $cb, $h, $v);
- $newchar = $char . $acc;
- unless (defined $hend{$newchar}) { findend($newchar, $pstr) }
- $H = $h - $hend{$newchar} - $chls{$char};
- $V = $v - $vend{$newchar};
- $pstr =~ s/\tendchar\n\t} $rend\n\Z//m;
- $pstr .= " % $nchar: start of dotaccent\n\t$H $V rmoveto\n$cb";
- }
-$chstrings{$nchar} = $pstr;
-}
-
-sub underacc {
- #
- # Dropped accents
- #
- # The Fontographer hack below is necessary because Fontographer (which
- # I have had to use to build TrueType and Macintosh versions of fonts)
- # seems not to respect the depths for characters specified in afm files
- # it has imported: it sets the depth to the lowest point in the path,
- # whether or not a mark was made there. So it is not possible to
- # implement (e.g.) underring by diving down low and then printing a
- # ring at its normal height.
- #
- my ($num, $char, $acc, $nchar) = @_;
- my ($old, $acname, $astr, $h, $v, $H, $V, $chdef, $acdef, $begin, $line, $end, $pstr);
- ($old = $metrics_enc[$num]) =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- $acc =~ s/^under//;
- $acname = $acc;
- if ($acc eq "dot") { $acc = "period" }
- if ($acc eq "candrabindu") { die "Bad definition (no such accent): $qdef\n" }
- getcharinfo($char) unless defined $chwd{$char};
- getcharinfo($acc) unless defined $chwd{$acc};
- if ($acc =~ /^$supacc$/) {
- $v = round($underadp + ($chdp{$acc} - $accdepth) * $shrink);
- }
- else { $v = $underddp + $chdp{$acc} }
- if ($v < $maxdp) { $maxdp = $v }
- $astr = "C $num ; WX $chwd{$char} ; N $nchar ; B $chls{$char} ";
- $astr .= "$v $chrs{$char} $chht{$char} ;\n";
- $metrics_enc[$num] = $astr;
- if ($acc =~ /^$supacc$/) {
- $h = round(($chwd{$char} - ($chwd{$acc} * $shrink)) / 2
- + $chls{$acc} * $shrink - ($v - $accdepth * $shrink) * $itadj);
- }
- else {
- $h = round(($chwd{$char} - $chwd{$acc}) / 2 + $chls{$acc} - $v * $itadj);
- }
- unless (defined $hend{$char}) { findend($char, $chstrings{$char}) }
- $H = $h - $hend{$char} - $chls{$char};
- if ($acc =~ /^$supacc$/) { $V = $underadp - $vend{$char} }
- else { $V = $v - $chdp{$acc} - $vend{$char} }
- #
- # Adjustment for smaller, therefore lower, shrunken accent defs
- #
- if ($acc =~ /^$supacc$/) {
- $V += round($chdp{$acc} * (1 - $shrink) / $shrink);
- }
- $chstrings{$char} =~ /^\/$char {\n(\t.+?hsbw\n(.|\n)*?)\tendchar\n\t} $rend\n/m;
- $chdef = $1;
- $chstrings{$acc} =~ /^\/$acc {\n\t.+? .+?hsbw\n((.|\n)+?\t} $rend\n)/m;
- $acdef = $1;
- if ($acc =~ /^$supacc$/ and $opt_s) { $acdef = fixshrink($acc, $acdef) }
- if ($acc =~ /^$supacc$/) {
- $acdef = fixhints($nchar, $acc, $acdef, $h, $underadp);
- }
- else { $acdef = fixhints($nchar, $acc, $acdef, $h, $underddp) }
- #
- # Bloody Fontographer! We can't just say
- # if ($acc =~ /^$supacc$/) { $V -= $accdepth }
- # Instead we have to go through the following rigmarole:
- #
- if ($acc =~ /^$supacc$/) {
- if ($acdef =~ /^(.*moveto)$/m) {
- ($begin, $line, $end) = ($`, $1, $');
- if ($line =~ /^\t(-?\d+) (-?\d+)( rmoveto)$/) {
- $acdef = "$begin\t$1 " . ($2 - $accdepth) . $3 . $end;
- }
- elsif ($line =~ /^\t(-?\d+)( vmoveto)$/) {
- $acdef = "$begin\t" . ($1 - $accdepth) . $2 . $end;
- }
- elsif ($line =~ /\t(-?\d+) hmoveto$/) {
- $acdef = "$begin\t$1 " . (-$accdepth) . "rmoveto" . $end;
- }
- }
- else { $acdef =~ s/\A/\t-$accdepth vmoveto\n/m }
- }
- $pstr = "/$nchar {\n$chdef % $nchar: start of $acname\n";
- $pstr .= "\t$H $V rmoveto\n$acdef";
- $chstrings{$nchar} = $pstr;
-}
-
-sub underb {
- #
- # Underbar
- #
- my ($num, $char, $nchar) = @_;
- my ($old, $astr, $l, $h, $v, $H, $V, $bdef, $chdef, $acdef, $pstr);
- ($old = $metrics_enc[$num]) =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- $v = $underbdp + $thk;
- getcharinfo($char) unless defined $chwd{$char};
- $h = round(0.1 * $chwd{$char} - $underbdp * $itadj);
- $l = round(0.8 * $chwd{$char});
- $astr = "C $num ; WX $chwd{$char} ; N $nchar ; B $chls{$char} ";
- $astr .= "$underbdp $chrs{$char} $chht{$char} ;\n";
- $metrics_enc[$num] = $astr;
- unless (defined $hend{$char}) { findend($char, $chstrings{$char}) }
- $H = $h - $hend{$char} - $chls{$char};
- $V = -$vend{$char};
- $bdef = "\t$underbdp $thk hstem\n\t$v vmoveto\n\t-$thk vlineto\n\t";
- $bdef .= "$l hlineto\n\t$thk vlineto\n\tclosepath\n";
- $chstrings{$char} =~ /^\/$char {\n(\t.+?hsbw\n(.|\n)*?)\tendchar\n\t} $rend\n/m;
- $chdef = $1;
- $acdef = fixhints($nchar, "underbar", $bdef, $h, 0);
- $pstr = "/$nchar {\n$chdef % $nchar: start of $acc\n";
- $pstr .= "\t$H $V rmoveto\n$acdef\tendchar\n\t} $nd\n";
- $chstrings{$nchar} = $pstr;
-}
-
-sub digraph {
- #
- # Make a new character consisting of two existing characters
- #
- my ($num, $char, $acc, $nchar) = @_;
- my ($old, $kern, $w, $newrs, $astr, $H, $V, $chdef, $acdef, $pstr);
- ($old = $metrics_enc[$num]) =~ s/^C $num/C -1/;
- $metrics_unenc .= $old unless $metrics_unenc =~ /$old/m;
- getcharinfo($char) unless defined $chwd{$char};
- getcharinfo($acc) unless defined $chwd{$acc};
- if ($kdefs =~ /^KPX $char $acc (-?\d+)$/m) { $kern = $1 };
- $w = $chwd{$char} + $chwd{$acc} + $kern;
- $newrs = $chrs{$char} + $chwd{$acc} + $kern;
- if ($newrs > $maxrs) { $maxrs = $newrs }
- $astr = "C $num ; WX " . $w . " ; N $nchar ; B $chls{$char} ";
- $astr .= (min($chdp{$char}, $chdp{$acc})) . " $newrs ";
- $astr .= (max($chht{$char}, $chht{$acc})) . " ;\n";
- $metrics_enc[$num] = $astr;
- unless (defined $hend{$char}) { findend($char, $chstrings{$char}) }
- $H = $chwd{$char} + $chls{$acc} + $kern - $hend{$char};
- $V = -$vend{$char};
- $chstrings{$char} =~ /^\/$char {\n(\t.+?hsbw\n(.|\n)*?)\tendchar\n\t} $rend\n/m;
- ($chdef = $1) =~ s/-?\d+( hsbw\n)/$w$1/m;
- $chstrings{$acc} =~ /^\/$acc {\n\t.+? .+?hsbw\n((.|\n)+?\t} $rend\n)/m;
- $acdef = $1;
- $acdef = fixhints($nchar, $acc, $acdef, ($chwd{$char} + $kern), 0);
- $pstr = "/$nchar {\n$chdef % $nchar: start of $acc\n";
- $pstr .= "\t$H $V rmoveto\n$acdef";
- $chstrings{$nchar} = $pstr;
-}
-
-sub max {
- #
- # Return greater of two values
- #
- my ($a, $b) = @_;
- return $a > $b ? $a : $b;
-}
-
-sub min {
- #
- # Return lesser of two values
- #
- my ($a, $b) = @_;
- return $a > $b ? $b : $a;
-}
-
-sub round {
- #
- # Return nearest integer value
- #
- my ($num) = shift;
- my $n1, $n2;
- if ($num < 0) { $n1 = (0 - $num) }
- else { $n1 = $num }
- $n2 = int($n1);
- if (($n1 - $n2) >= 0.5) { $n2++ }
- if ($num < 0) { return (0 - $n2) }
- else { return $n2 }
-}
-
-sub getcharinfo {
- #
- # Store character metric information
- #
- my $char = shift;
- my $foundit;
- my $metrics_all = join("", @metrics_enc) . $metrics_unenc;
- if ($metrics_all =~ /^.* ; N $char ; .*$/m) { $foundit = $& }
- else { die "Bad definition (no such character/accent): $char\n" }
- $foundit =~ /^C (-?\d+) ; WX (\d+) ; N $char ; B (.+?) (.+?) (.+?) (.+?) ;/;
- ($chnum{$char}, $chwd{$char}, $chls{$char},
- $chdp{$char}, $chrs{$char}, $chht{$char}) = ($1, $2, $3, $4, $5, $6);
-}
-
-sub fixkerns {
- #
- # Generalise the kerning info contained in the afm file by applying
- # it to new accented chars. Do not kern lower-case chars bearing
- # superscript accents with capitals, quotes or a preceding "f".
- #
- my ($char, $acc) = @_;
- my ($lchar, $rchar);
- if ($acc =~ /^$accents$/) { $lchar = $rchar = $char }
- else {
- $lchar = $char;
- $rchar = $acc;
- }
- if ($char =~ /^[a-z]/ and $acc =~ /^$supacc$/) {
- if ($kdefs =~ /^(KPX $char)(( (?:[a-pr-z][a-zA-Z]*|q(?!uote).*?) )-?\d+)$/m) {
- ($one, $three) = ($1, $3);
- $kdefs =~ s[^(KPX $char)(( (?:[a-pr-z][a-zA-Z]*|q(?!uote).*?) )-?\d+)$]
- [$&\n$1$acc$2]gm
- unless $kdefs =~ /^$one$acc$three/m;
- }
- if ($kdefs =~ /^(KPX (?:[a-eg-pr-z][a-zA-Z]*|q(?!uote).*?) $char)( -?\d+)$/m) {
- $one = $1;
- $kdefs =~ s[^(KPX (?:[a-eg-pr-z][a-zA-Z]*|q(?!uote).*?) $char)( -?\d+)$]
- [$&\n$1$acc$2]gm
- unless $kdefs =~ /^$one$acc /m;
- }
- }
- else {
- if ($kdefs =~ /^(KPX )$rchar(( [a-zA-Z]+ )-?\d+)$/m) {
- ($one, $three) = ($1, $3);
- $kdefs =~ s[^(KPX )$rchar(( [a-zA-Z]+ )-?\d+)$]
- [$&\n$1$char$acc$2]gm
- unless $kdefs =~ /^$one$char$acc$three/m;
- }
- if ($kdefs =~ /^(KPX [a-zA-Z]+ )$char( -?\d+)$/m) {
- $one = $1;
- $kdefs =~ s[^(KPX [a-zA-Z]+ )$char( -?\d+)$]
- [$&\n$1$char$acc$2]gm
- unless $kdefs =~ /^$one$char$acc /m;
- }
- }
-}
-
-sub fixshrink {
- #
- # Multiply all coordinates in a character definition by $shrink,
- # creating new subroutines as necessary.
- #
- my ($ch, $chdef) = @_;
- my (@chdef, $line, $snum, $subrdef);
- @chdef = split(/\n/, $chdef);
- $chdef = "";
- foreach $line (@chdef) {
- if ($line =~ /^\t(\d+) .*call(other)?subr$/) {
- $snum = $1;
- $subrdef = $subrs[$snum];
- $subrdef = fixshrink($ch, $subrdef);
- $subrdef =~ s/^(dup )$snum \{$/$1$subrsnum {\n % $nchar: shrink $ch/m;
- $subrs[$subrsnum] = $subrdef;
- $line =~ s/^\t$snum/\t$subrsnum/;
- $subrsnum++;
- }
- else { $line =~ s/-?\d+/int($& * $shrink)/ge unless $line =~ /^dup / }
- $chdef .= "$line\n";
- }
- return $chdef;
-}
-
-sub fixhints {
- #
- # First adjust any Flex "0 callsubr" lines for horizontal and
- # vertical offset. Then collect the hints from the accent definition,
- # remove them, adjust for horizontal and vertical offset, and
- # place them in a numbered subroutine. Have the definition call
- # the subroutine.
- #
- my ($nchar, $acc, $acdef, $h, $v) = @_;
- my $subrdef;
- $acdef =~ s[^(\t-?\d+ )(-?\d+) (-?\d+)( 0 callsubr)$]
- [$1 . ($2 + $h) . " " . ($3 + $v) . $4]gme;
- if ($subrdef = join("\n", grep /^\t.*[hv]stem$/, split(/\n/, $acdef))) {
- $acdef = join("\n", grep !/^\t.*[hv]stem$/, split(/\n/, $acdef)) . "\n";
- }
- elsif ($acdef =~ s/\A(?:\t(\d+) callsubr\n)((?:.|\n)*)\Z/$2/m) {
- $subrdef = $subrs[$1];
- $subrdef = join("\n", grep /^\t.*[hv]stem$/, split(/\n/, $subrdef))
- }
- $subrdef =~ s/^(\t)(-?\d+)( .*hstem)$/$1 . ($2 + $v) . $3/gme;
- $subrdef =~ s/^(\t)(-?\d+)( .*vstem)$/$1 . ($2 + $h) . $3/gme;
- if ($subrdef) {
- $subrs[$subrsnum] = "dup $subrsnum {\n % $nchar: hints for $acc\n";
- $subrs[$subrsnum] .= "$subrdef\n\treturn\n\t} $np\n";
- $acdef = "\t$subrsnum 1 3 callothersubr\n\tpop\n\tcallsubr\n" . $acdef;
- $subrsnum++;
- }
- return $acdef;
-}
-
-sub findend {
- #
- # Calculate the current point reached at the end of the character
- # definition. Place the horizontal offset in $hend{$char}, the
- # vertical offset in $vend{$char}.
- #
- my ($char, $def) = @_;
- my $line;
- foreach $line (split /\n/, $def) {
- SWITCH: {
- $line =~ /^\t(-?\d+) h(line|move)to$/
- && do {
- $hend{$char} += $1;
- last SWITCH;
- };
- $line =~ /^\t(-?\d+) v(line|move)to$/
- && do {
- $vend{$char} += $1;
- last SWITCH;
- };
- $line =~ /^\t(-?\d+) (-?\d+) r(line|move)to$/
- && do {
- $hend{$char} += $1;
- $vend{$char} += $2;
- last SWITCH;
- };
- $line =~ /^\t(-?\d+) (-?\d+) (-?\d+) (-?\d+) hvcurveto$/
- && do {
- $hend{$char} += ($1 + $2);
- $vend{$char} += ($3 + $4);
- last SWITCH;
- };
- $line =~ /^\t(-?\d+) (-?\d+) (-?\d+) (-?\d+) vhcurveto$/
- && do {
- $hend{$char} += ($2 + $4);
- $vend{$char} += ($1 + $3);
- last SWITCH;
- };
- $line =~ /^\t(-?\d+) (-?\d+) (-?\d+) (-?\d+) (-?\d+) (-?\d+) rrcurveto$/
- && do {
- $hend{$char} += ($1 + $3 + $5);
- $vend{$char} += ($2 + $4 + $6);
- last SWITCH;
- };
- $line =~ /^\t(\d+) callsubr$/
- && do {
- findend($char, $subrs[$1]);
- last SWITCH;
- };
- $line =~ /^\t-?\d+ (-?\d+) (-?\d+) 0 callsubr$/ # Flex
- && do {
- $hend{$char} = $1;
- $vend{$char} = $2;
- last SWITCH;
- };
- }
- }
-}
diff --git a/Build/source/texk/texlive/linked_scripts/accfonts/vpl2ovp b/Build/source/texk/texlive/linked_scripts/accfonts/vpl2ovp
deleted file mode 100755
index eb88bfd3dda..00000000000
--- a/Build/source/texk/texlive/linked_scripts/accfonts/vpl2ovp
+++ /dev/null
@@ -1,1085 +0,0 @@
-#!/usr/bin/perl
-
-# Vpl2ovp: a program to generate accented virtual fonts for Omega
-# Copyright (C) 2008 John D. Smith
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-$version = 0.25;
-#------------------------------------------------------------------------#
-$description =
-"Syntax: vpl2ovp -d definition-file [-s shrink-factor]
- [-c candrabindu-adjustment] [-b] vpl-file
-
-Vpl2ovp creates new Omega virtual fonts based on existing TeX
-fonts or virtual fonts (\"input fonts\"). A successful run will
-read a pl (Property List) or vpl (Virtual Property List) file
-and a definition file, and will generate a new ovp (Omega
-Virtual Property List) file on standard output. The input font
-is assumed to adhere to the standard TeX encoding for text
-fonts unless it was created with either of the programs afm2pl
-or afm2tfm, in which case it is assumed to conform to
-(respectively) the Adobe Standard Encoding or the encoding
-specified in the file dvips.enc. In either case, the name of
-the input font is assumed to be the name of the input file
-without its .vpl or .pl extension: it must conform to normal
-TeX conventions for naming fonts, as vpl2ovp attempts to draw
-conclusions from it about the kind of font it is dealing with.
-
-A typical complete sequence of commands to create a new virtual
-font might therefore be
- tftopl cmr10.tfm cmr10.pl
- vpl2ovp -d Unicode1.def cmr10.pl >cmr10-uni1.ovp
- ovp2ovf cmr10-uni1.ovp cmr10-uni1.ovf cmr10-uni1.ofm
-for a Computer Modern font, or
- afm2pl Times-Roman.afm rptmr.pl
- pltotf rptmr.pl rptmr.tfm
- vpl2ovp -d Unicode1.def rptmr.pl >ptmr-uni1.ovp
- ovp2ovf ptmr-uni1.ovp ptmr-uni1.ovf ptmr-uni1.ofm
-for a PostScript font.
-
-Another approach for a PostScript font is to use afm2tfm:
- afm2tfm Times-Roman.afm -t dvips.enc -v ptmr rptmr
- vpl2ovp -d Unicode1.def ptmr.vpl >ptmr-uni1.ovp
- ovp2ovf ptmr-uni1.ovp ptmr-uni1.ovf ptmr-uni1.ofm
--- but this is now deprecated, as afm2tfm generates incorrect
-values for the heights of some characters, and this can lead to
-bad accent placing.
-
-In order to keep the whole of the character range \"F0-\"FF free for
-the requirements of the encoding specified in the definition file,
-certain modifications are made to input fonts following the dvips.enc
-encoding to bring them into greater conformity with the TeX norm. In
-particular, the characters dotaccent and hungarumlaut are placed in
-the positions assigned by TeX (\"5F, \"7D), not those enforced by
-dvips.enc (\"C7, \"CD). The f-ligatures, double quotes and dashes are
-also moved from the upper half of the original 8-bit character set to
-their normal TeX positions. As a result, the following characters are
-not found in the lower half of the character set: quotesingle,
-quotedbl, backslash, underscore, braceleft, bar, braceright. These
-characters can, however, be assigned positions in the output font if
-they are needed. (Indeed, they could all be explicitly restored to
-their dvips.enc positions if this were desired.)
-
-Options:
-
- -d should refer to a font definition file. This file (which could
- usefully be named, e.g., \"Unicode1.def\") should consist of
- lines of character definitions, in the form
- \"number\" \"character\"
- or
- \"number\" \"character\" \"accent\"
- Here \"number\" represents the character's position in the new
- encoding and may be expressed in decimal, octal or hex;
- \"character\" names the character (e.g. \"comma\", \"eight\",
- \"A\") or consists of the word \".notdef\" (indicating that
- the specified number's \"slot\" in the new encoding is to be
- empty); and \"accent\" optionally names an accent to be placed
- on the character. In addition to the standard accents available
- in PostScript fonts, \"underbar\" and \"underdot\" are also
- available, as are \"under\" versions of all the normal
- superscript accents (\"underdieresis\", \"underring\", etc.).
- The Indian accent \"candrabindu\" may also be specified: it
- is formed by overprinting a breve with a dotaccent. Finally,
- \"overdot\" may be used as a synonym for \"dotaccent\".
-
- Note that all accents used in defining accented characters must
- themselves be defined in the .def file. Those which exist in the
- source font should simply be referenced by name in their
- appropriate Unicode position (e.g. \"0x0304 macron\"); those
- which do not should be defined as the character \"space\"
- followed by the name of the accent (e.g. \"0x0310 space
- candrabindu\").
-
- If the character named in the \"accent\" position is not in fact
- a valid accent character, the program interprets the definition
- as a request for a digraph formed from the \"character\" and the
- \"accent\". A digraph consisting of, say, \"k\" and \"h\" will be
- indistinguishable from the letters \"k\" and \"h\" printed
- consecutively, but the digraph \"kh\" can itself receive accents
- like any other character: see next paragraph.
-
- A new character (such as \"amacron\" or \"kh\") may be freely
- used in the \"character\" position of a further definition (such
- as \"amacron breve\" or \"kh underbar\"). There is no constraint
- on the ordering of definitions within a definition file. The
- definition of \"a macron\" does not have to precede that of
- \"amacron breve\": requests for \"impossible\" characters are
- deferred until their constituents have had a chance to come into
- being.
-
- \"Slots\" for which no new definition is given retain the
- definition they have in the input font.
-
- The definition file may also contain blank lines and comments
- (introduced by \"\#\").
-
- -s may optionally give the factor, expressed as a per-thousand
- value, by which normally superscript accents (such as dieresis,
- ring) should be shrunk when they are used as subscript accents
- (such as underdieresis, underring). Values of around 800 may be
- found useful.
-
- -c may optionally give two comma-separated numerical values to
- adjust the x and y coordinates of the dotaccent placed within a
- breve to form the candrabindu accent. A coordinate scheme using
- \"DESIGNUNITS R 1000\" is assumed.
-
- -b may optionally be specified to block the use of predefined
- accented characters, forcing vpl2ovp to define its own
- versions. This may be useful to secure a consistent appearance
- in cases where a font designer does not share vpl2ovp's views
- on where accents should be placed.
-
- -h prints this help.
-";
-#------------------------------------------------------------------------#
-
-########################
-# Packages and constants
-########################
-#
-use File::Basename;
-use Getopt::Std;
-$cmdline = basename($0) . " " . join " ", @ARGV;
-getopts('d:s:c:bh');
-if ($opt_h or !$opt_d or $#ARGV != 0) {
- print STDERR $description;
- exit 1;
-}
-
-$filename = $ARGV[0];
-$dummycodepoint = 0xF8FF;
-($fontname = $filename) =~ s/\..*$//;
-($encname = basename($opt_d)) =~ s/\..*$//;
-$vtitle = "(VTITLE Font $fontname modified for $encname encoding by vpl2ovp";
-$vtitle .= " v. $version" if $version;
-$vtitle .= ")\n(COMMENT Command line: $cmdline)";
-$vtitle .= "\n(OFMLEVEL H 0)";
-
-#
-# Flags for bold and small caps. These are probably a bit iffy, but
-# there's not much that can be done about it.
-#
-if ($fontname =~ /(^p.*b[oi]?[c]?$|^[^p].*bx[a-z]*[0-9]+$)/) { $bold = 1 }
-if ($fontname =~ /(^p.*c$|^[^p].*csc[a-z]*[0-9]+$)/) { $scaps = 1 }
-if ($opt_s) { $shrink = $opt_s / 1000 } else { $shrink = 1 }
-
-#
-# Array to convert from number to vpl representation
-#
-foreach $i (0 .. 0xFFFF) {
- $nv[$i] = (chr($i) =~ /[0-9A-Za-z]/ ? "C " . chr $i : sprintf("H %04lX", $i));
-}
-
-#
-# Now the encoding vectors.
-#
-@TeXenc = (
- "Gamma", "Delta", "Theta", "Lambda",
- "Xi", "Pi", "Sigma", "Upsilon",
- "Phi", "Psi", "Omega", "ff",
- "fi", "fl", "ffi", "ffl",
- "dotlessi", "dotlessj", "grave", "acute",
- "caron", "breve", "macron", "ring",
- "cedilla", "germandbls", "ae", "oe",
- "oslash", "AE", "OE", "Oslash",
- "space", "exclam", "quotedblright", "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",
- "exclamdown", "equal", "questiondown", "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",
- "quotedblleft", "bracketright", "circumflex", "dotaccent",
- "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", "endash",
- "emdash", "hungarumlaut", "tilde", "dieresis"
-);
-
-@dvipsenc = (
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "quotesingle", "exclamdown", "questiondown",
- "dotlessi", "dotlessj", "grave", "acute",
- "caron", "breve", "macron", "ring",
- "cedilla", "germandbls", "ae", "oe",
- "oslash", "AE", "OE", "Oslash",
- "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", "circumflex", "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", "tilde", "dieresis",
- "asciicircum", "asciitilde", "Ccedilla", "Iacute",
- "Icircumflex", "atilde", "edieresis", "egrave",
- "scaron", "zcaron", "Eth", "ff",
- "ffi", "ffl", ".notdef", ".notdef",
- ".notdef", ".notdef", "Scaron", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- "Ydieresis", ".notdef", "Zcaron", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", "cent", "sterling",
- "fraction", "yen", "florin", "section",
- "currency", "copyright", "quotedblleft", "guillemotleft",
- "guilsinglleft", "guilsinglright", "fi", "fl",
- "degree", "endash", "dagger", "daggerdbl",
- "periodcentered", ".notdef", "paragraph", "bullet",
- "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
- "ellipsis", "perthousand", ".notdef", ".notdef",
- "Agrave", "Aacute", "Acircumflex", "Atilde",
- "Adieresis", "Aring", ".notdef", "dotaccent",
- "Egrave", "Eacute", "Ecircumflex", "Edieresis",
- "Igrave", "hungarumlaut", "ogonek", "Idieresis",
- "emdash", "Ntilde", "Ograve", "Oacute",
- "Ocircumflex", "Otilde", "Odieresis", ".notdef",
- ".notdef", "Ugrave", "Uacute", "Ucircumflex",
- "Udieresis", "Yacute", "Thorn", ".notdef",
- "agrave", "aacute", "acircumflex", "ordfeminine",
- "adieresis", "aring", ".notdef", "ccedilla",
- "Lslash", "eacute", "ecircumflex", "ordmasculine",
- "igrave", "iacute", "icircumflex", "idieresis",
- ".notdef", "ntilde", "ograve", "oacute",
- "ocircumflex", "otilde", "odieresis", ".notdef",
- "lslash", "ugrave", "uacute", "ucircumflex",
- "udieresis", "yacute", "thorn", "ydieresis"
-);
-
-@adobeenc=(
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".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", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "exclamdown", "cent", "sterling",
- "fraction", "yen", "florin", "section",
- "currency", "quotesingle", "quotedblleft", "guillemotleft",
- "guilsinglleft", "guilsinglright", "fi", "fl",
- ".notdef", "endash", "dagger", "daggerdbl",
- "periodcentered", ".notdef", "paragraph", "bullet",
- "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
- "ellipsis", "perthousand", ".notdef", "questiondown",
- ".notdef", "grave", "acute", "circumflex",
- "tilde", "macron", "breve", "dotaccent",
- "dieresis", ".notdef", "ring", "cedilla",
- ".notdef", "hungarumlaut", "ogonek", "caron",
- "emdash", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "AE", ".notdef", "ordfeminine",
- ".notdef", ".notdef", ".notdef", ".notdef",
- "Lslash", "Oslash", "OE", "ordmasculine",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "ae", ".notdef", ".notdef",
- ".notdef", "dotlessi", ".notdef", ".notdef",
- "lslash", "oslash", "oe", "germandbls",
- ".notdef", ".notdef", ".notdef", ".notdef"
-);
-
-###############
-# Read DEF file
-###############
-#
-open DEF, $opt_d or die "Cannot open $opt_d: $!\n";
-while (<DEF>) {
- next if (/^\s*$/ || /^\#/);
- s/\s*(\#.*)?$//;
- push @deflines, $_;
-}
-close DEF;
-
-###############
-# Read VPL file
-###############
-#
-# File header
-#
-$vplhead = <> or exit 1;
-unless ($vplhead =~ /^\((VTITLE|FAMILY) /) {
- die "$filename is not a vpl file: giving up\n"
-}
-do {
- $_ = <>;
- $vplhead .= $_;
-} until ($_ =~ /^\(LIGTABLE$/ or eof);
-if (eof) {
- die "$filename does not seem to be a text font (no LIGTABLE): giving up\n";
-}
-if ($vplhead =~ s/\A\(VTITLE(.*)$/$vtitle\n(COMMENT Old vtitle:$1/m) {
- $vplhead =~ s/\n\(COMMENT Please edit that VTITLE .*\)$//m;
- @enc = @dvipsenc;
- $dvips = 1;
-}
-elsif ($vplhead =~ /\A\(FAMILY.*\)\n\(CODINGSCHEME ADOBESTANDARDENCODING\)$/m) {
- $vplhead =~ s/\A/$vtitle\n/m;
- @enc = @adobeenc;
- $dvips = 0;
-}
-else {
- $vplhead =~ s/\A/$vtitle\n/m;
- @enc = @TeXenc;
- $dvips = 0;
-}
-if ($vplhead =~ /^\(CODINGSCHEME TEX MATH SYMBOLS/m) {
- die "$filename is a TeX math font: giving up\n";
-}
-unless ($vplhead =~ s/^(\(CODINGSCHEME .*\+\s?)(\S+)\)$/$1$encname)/m) {
- $vplhead =~ s/^(\(CODINGSCHEME .*)\)$/$1 + $encname)/m;
-}
-if ($vplhead =~ s/^\(DESIGNUNITS R (.+)\)\n//m) { $scale = $1 }
-else { $scale = 1 }
-$vplhead =~ s/^\(COMMENT.*DESIGNSIZE.*\)\n//gm;
-$vplhead =~ s/^\(BOUNDARYCHAR.*\)\n//gm;
-if ($vplhead =~ /^ \(SLANT R (.+)\)/m) { $slant = $1 }
-if ($vplhead =~ /^ \(XHEIGHT [DR] (.+)\)/m) { $xheight = $1 }
-unless ($vplhead =~ /^\(MAPFONT /m) {
- if ($vplhead =~ /^\(DESIGNSIZE R (.*)\)$/m) { $dsize = $1 *$scale }
- $mapfont = "\n(MAPFONT D 0\n (FONTNAME $fontname)\n (FONTDSIZE R $dsize)\n )";
- $vplhead =~ s/\n\(LIGTABLE\Z/$mapfont$&/m;
-}
-$vplhead =~ s/^(\(FONTDIMEN)/(SEVENBITSAFEFLAG FALSE)\n$1/m;
-if ($opt_s) {
- $vplhead =~ s[^(\(MAPFONT D )0(.*?)( \))]
- [$&\n${1}1$2 (FONTAT R ${ \($shrink * $scale) })\n$3]ms;
-}
-@vplhead = split /^/, $vplhead;
-foreach (@vplhead) {
- s[(?<!(IGNSIZE|MAPFONT)) [RD] (-?)([0-9.]+)\)]
- [" R " . $2 . $3/$scale . ")"]ge
-}
-
-#
-# Ligatures and kerns
-#
-do {
- $_ = <>;
- s/ \(comment .*$//i;
- s/^( \((?:LABEL|KRN) )O ([0-7]+)(.*)$/$1 . sprintf("H %04lX", oct $2) . $3/e;
-if (/ \(LIG /) {
- s/O ([0-7]+)/sprintf("H %04lX", oct $1)/ge;
- }
- $ligs .= $_;
-} until $_ =~ /^ \)/;
-#
-# Now build a hash to convert from vpl representation to char name
-# and use it to make ligtable readable
-#
-foreach $i (0 .. 255) { $vc{$nv[$i]} = $enc[$i] }
-$ligs =~ s/^( \((?:LABEL|KRN) )(\S+ \S+)(.*\))$/$1$vc{$2}$3/gm;
-$ligs =~ s/^( \(LIG )(\S+ \S+) (\S+ \S+)\)$/$1$vc{$2} $vc{$3})/gm;
-#
-# Character definitions: store "encoded" defs in @chars, store *all*
-# defs in %allchars
-#
-$_ = <>;
-do {
- if (/^\(CHARACTER/) {
- $character = $_;
- do {
- $_ = <>;
- $character .= $_;
- } until $_ =~ /^ \)/;
- storeinfo($character);
- $_ = <>;
- }
-} until eof;
-foreach $i (0 .. $#chars) {
- if ($chars[$i] and $enc[$i] ne ".notdef") {
- $allchars{$enc[$i]} = $chars[$i];
- }
-}
-
-##################
-# Set up constants
-##################
-
-$subacc = "(cedilla|ogonek|commaaccent)";
-$supacc = "(grave|acute|circumflex|tilde|macron|breve|dotaccent|overdot|dieresis|ring|hungarumlaut|caron|candrabindu)";
-$underacc = "(underdot|under$supacc)";
-$accents = "($subacc|$supacc|$underacc|underbar)";
-$underadp = 0.230; # depth of "under" accs
-$underddp = 0.213; # depth of underdot
-if ($bold) { $thk = 0.072 } else { $thk = 0.052 } # thickness and
-$underbdp = 0.082 + $thk; # depth of underbar
-$capheight = $allchars{"X"}{ht};
-$accheight = $allchars{"macron"}{ht};
-$accdepth = $accheight - $thk * $scale; # probable approx. "depth" of macron
-$v1 = $accheight - $xheight; # vertical offset for double accents
-$v2 = $capheight - $xheight; # vertical offset for accented caps etc
-if ($scaps) { # accented small caps
- $scoffset = $allchars{"x"}{ht} - $xheight;
- $v1 += $scoffset;
-}
-if ($opt_c) { # candrabindu
- ($cbx, $cby) = $opt_c =~ /^(.*),(.*)$/;
- $cbx += ($allchars{"breve"}{wd} - $allchars{"dotaccent"}{wd}) / 2;
- $cbx /= 1000;
- $cby /= 1000;
-}
-
-######################
-# Build the characters
-######################
-#
-# First normalise dvips.enc encoding quirks
-#
-if ($dvips) {
- chmove("fi", 014);
- chmove("fl", 015);
- chmove("quotedblright", 042);
- chmove("quotedblleft", 0134);
- chmove("dotaccent", 0137);
- chmove("endash", 0173);
- chmove("emdash", 0174);
- chmove("hungarumlaut", 0175);
-}
-#
-# Now build a list of definitions supplied by user
-#
-for (@deflines) {
- if (/^\s*(\d+|0[0-7]+|0x[0-9a-fA-F]+)\s+([a-zA-Z]+?|\.notdef)(?:\s+([a-zA-Z]+))?$/) {
- ($num, $char, $acc) = ($1, $2, $3);
- $num = oct $num if $num =~ /^0/;
- if ($num > 0xFFFF) { die "Bad definition (number out of range): $_\n" }
- $def = {};
- $def->{qdef} = $_;
- $def->{num} = $num;
- $def->{char} = $char;
- $def->{acc} = $acc;
- if ($char eq "space") { $def->{nchar} = $acc }
- else { $def->{nchar} = $char . $acc }
- push @nchars, $def->{nchar};
- push @defs, $def;
- }
- else { die "Bad definition: $_\n" }
-}
-#
-# Work through the list
-#
-while (@defs) {
- $def = shift @defs;
- $qdef = $def->{qdef};
- $num = $def->{num};
- $char = $def->{char};
- $acc = $def->{acc};
- $nchar = $def->{nchar};
- #
- # If we can't handle $char/$acc yet, but believe we will be able
- # to later, send the definition to the back of the queue. In case
- # it later turns out we were wrong, allow only five loops before
- # giving up.
- #
- if (!$allchars{$char} and $char ne ".notdef") {
- if (grep /^$char$/, @nchars) {
- unless (++$def->{requeue} > 5) {
- push @defs, $def;
- next;
- }
- }
- else { die "Bad definition (no such character): $qdef\n" }
- }
- if ($acc and !$allchars{$acc} and $acc !~ /^$accents$/) {
- if (grep /^$acc$/, @nchars) {
- unless (++$def->{requeue} > 5) {
- push @defs, $def;
- next;
- }
- }
- else { die "Bad definition (no such accent): $qdef\n" }
- }
- #
- # Remove any existing claims on $num
- #
- @{ $allchars{$chars[$num]{id}}{num} } = grep !/$num/,
- @{ $allchars{$chars[$num]{id}}{num} };
- #
- # First deal with .notdef
- #
- if ($nchar eq ".notdef") {
- undef $chars[$num];
- }
- #
- # Next look among existing chars (unless blocked by -b)
- #
- elsif (!($acc and $opt_b) and $allchars{$nchar}) {
- push( @{ $allchars{$nchar}{num} }, $num);
- $chars[$num] = $allchars{$nchar};
- }
- #
- # If it can't be built from sub-elements, issue a warning and move on
- #
- elsif (!$acc) {
- warn "No such character - ignoring definition: $qdef\n";
- undef $chars[$num];
- }
- #
- # Now build the char
- #
- else {
- #
- # First get rid of predefined/duplicated ligtable statements
- # and character definitions; also synonyms
- #
- $ligs =~ s/\n \((LABEL|KRN|LIG) ($nchar .*|.*$nchar)\)$//gm;
- $allchars{$nchar} = ();
- if ($acc eq "overdot") {
- $nchar2 = $char . "dotaccent";
- $ligs =~ s/\n \((LABEL|KRN|LIG) ($nchar2 .*|.*$nchar2)\)$//gm;
- delete $allchars{$nchar2};
- }
- #
- # Store the info that will be needed to have the character
- # linked into the LIGTABLE
- #
- push @newligs, "$char: (LIG $acc $nchar)";
- #
- # Go!
- #
- if ($acc =~ /^$subacc$/) {
- subacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^$supacc$/) {
- supacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^$underacc$/) {
- underacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^underbar$/) {
- underb($num, $char, $nchar);
- fixkerns($char, $acc);
- }
- else {
- digraph($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- }
-}
-
-###################
-# Sort out ligtable
-###################
-#
-# Pull in the newly created ligatures
-#
-foreach $newlig (@newligs) {
- $newlig =~ s/^(.+)://;
- $newelm1 = $1;
- unless ($ligs =~ s/(^ \(LABEL $newelm1\)\n)/$1$newlig\n/m) {
- $ligs =~ s[^( \)\n)]
- [ \(LABEL $newelm1\)\n$newlig\n \(STOP\)\n$1]m
- }
-}
-#
-# Convert to vpl representation, eliminating statements invoking
-# "unencoded" characters
-#
-@liglist = split /\n/, $ligs;
-$ligs = "";
-foreach (@liglist) {
- if (/^( \(LIG \S+ )(\S+)\)$/) {
- if ($n = ${ $allchars{$2}{num} }[0]) {
- s/^( \(LIG \S+ )(\S+)\)$/$1$nv[$n])/;
- }
- else { next }
- }
- if (/^( \((?:LABEL|LIG|KRN) )([^ )]+)(.*)$/) {
- ($one, $two, $three) = ($1, $2, $3);
- foreach $n (@{ $allchars{$two}{num} }) {
- $ligs .= "$one$nv[$n]$three\n";
- }
- }
- else { $ligs .= "$_\n" }
-}
-#
-# Eliminate sequences orphaned by elimination of a LABEL
-#
-@liglist = split / \(STOP\)\n/, $ligs;
-$ligs = "";
-foreach (@liglist) {
- if (/^ \(LABEL /m) { $ligs .= "$_ (STOP)\n" }
- elsif (/^ \)$/m) { $ligs .= $_ }
-}
-#
-# Eliminate empty statements
-#
-$ligs =~ s/(^ \(LABEL .*\)\n)+ \(STOP\)\n//gm;
-@ligs = split /^/, $ligs;
-foreach (@ligs) {
- s/ [RD] (-?)([0-9.]+)\)/" R " . $1 . $2\/$scale . ")"/ge
-}
-
-####################
-# Output the results
-####################
-#
-print @vplhead, @ligs;
-foreach $i (0 .. 0xFFFF) { if (defined $chars[$i]{id}) { printchar($i) } }
-
-#####################
-# End of main program
-#####################
-
-sub storeinfo {
- #
- # Extract info from a character definition and store it in @chars
- #
- my $char = shift;
- my $num;
- if ($char =~ /\A\(CHARACTER O ([0-7]+)/m) { $num = oct $1 }
- elsif ($char =~ /\A\(CHARACTER C (.)/m) { $num = ord $1 }
- $chars[$num]{id} = $enc[$num];
- push( @{ $chars[$num]{num} }, $num);
- if ($char =~ /^ \(CHARWD R (.*?)\)$/m) { $chars[$num]{wd} = $1 }
- if ($char =~ /^ \(CHARHT R (.*?)\)$/m) { $chars[$num]{ht} = $1 }
- if ($char =~ /^ \(CHARDP R (.*?)\)$/m) { $chars[$num]{dp} = $1 }
- if ($char =~ /^ \(CHARIC R (.*?)\)$/m) { $chars[$num]{ic} = $1 }
- if ($char =~ /^ \(MAP\n((.|\n)*)^ \)/m) { $chars[$num]{map} = $1 }
- else { $chars[$num]{map} = " (SETCHAR $nv[$num])\n" }
- $chars[$num]{map} =~ s[(\(SETCHAR )O ([0-7]+)\)]
- [$1 . sprintf("H %04lX", oct $2) . ")"]gme
-}
-
-sub printchar {
- #
- # Extract info from @chars and build it into a character definition
- #
- my $num = shift;
- my @ch;
- push @ch, "(CHARACTER ";
- if (chr($num) =~ /[0-9A-Za-z]/) { push @ch, "C " . chr($num) }
- else {
- push @ch, sprintf("H %04lX", $num);
- push @ch, " (COMMENT " . $chars[$num]{id} . ")";
- }
- push @ch, "\n";
- push @ch, " (CHARWD R " . $chars[$num]{wd} . ")\n"
- if defined $chars[$num]{wd};
- push @ch, " (CHARHT R " . $chars[$num]{ht} . ")\n"
- if defined $chars[$num]{ht};
- push @ch, " (CHARDP R " . $chars[$num]{dp} . ")\n" if $chars[$num]{dp};
- push @ch, " (CHARIC R " . $chars[$num]{ic} . ")\n" if $chars[$num]{ic};
- push @ch, " (MAP\n";
- push @ch, $chars[$num]{map};
- push @ch, " )\n";
- push @ch, " )\n";
- foreach (@ch) {
- s/(?<!SELECTFONT) [RD] (-?)([0-9.]+)\)/" R " . $1 . $2\/$scale . ")"/ge
- }
- print @ch
-}
-
-sub chmove {
- #
- # Move a character
- #
- my ($char, $num) = @_;
- my $i;
- foreach $i (@{ $allchars{$char}{num} }) { undef $chars[$i] }
- @{ $allchars{$char}{num} } = ();
- @{ $allchars{$chars[$num]{id}}{num} } = grep !/$num/,
- @{ $allchars{$chars[$num]{id}}{num} };
- push( @{ $allchars{$char}{num} }, $num);
- $chars[$num] = $allchars{$char};
-}
-
-sub max {
- #
- # Return greater of two values
- #
- my ($a, $b) = @_;
- return $a > $b ? $a : $b;
-}
-
-sub subacc {
- #
- # Subscript accents
- #
- my ($num, $char, $acc, $id) = @_;
- my ($h, $s1, $s2, $s3);
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$char}{ht};
- $allchars{$id}{dp} = $allchars{$acc}{dp};
- $allchars{$id}{ic} = $allchars{$char}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- $h = sprintf("%.3f", ($allchars{$char}{wd} - $allchars{$acc}{wd}) / 2);
- if ($h > 0) { $s2 = " (MOVERIGHT R $h) " }
- elsif ($h < 0) {
- $h = -$h;
- $s2 = " (MOVELEFT R $h) ";
- }
- else { $s2 = " " }
- $s3 = $allchars{$acc}{map};
- $s3 =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- $allchars{$id}{map} = " $s1\n$s2$s3\n";
- $chars[$num] = $allchars{$id};
-}
-
-sub supacc {
- #
- # Superscript accents
- #
- my ($num, $char, $acc, $id) = @_;
- my ($cb, $h, $hadj, $tallchar, $ic, $s1, $s2, $s3);
- if ($char eq "i" and $allchars{"dotlessi"}) { $char = "dotlessi" }
- if ($char eq "j" and $allchars{"dotlessj"}) { $char = "dotlessj" }
- if ($acc eq "overdot") { $acc = "dotaccent" }
- if ($acc eq "candrabindu") {
- $acc = "breve";
- ($cb = $allchars{"dotaccent"}{map}) =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- }
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$acc}{ht};
- $allchars{$id}{dp} = $allchars{$char}{dp};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- if ($scaps and $char =~ /^[a-z]/) { # accented small caps
- $tallchar = 1;
- if ($char =~ /$supacc$/
- and $char !~ /under$supacc$/) { # double accs
- $s2 = " (MOVEUP R $v1)";
- $allchars{$id}{ht} += $v1;
- $hadj = sprintf("%.3f", $v1 * $slant);
- $ic = $allchars{$char}{ic};
- }
- else { # single accs
- $s2 = " (MOVEUP R $scoffset)";
- $allchars{$id}{ht} += $scoffset;
- $hadj = sprintf("%.3f", $scoffset * $slant);
- $ic = $allchars{$acc}{ic} + $hadj;
- }
- }
- elsif ($allchars{$char}{ht} >= ($accheight + $v2)) { # double accs
- $tallchar = 1; # on caps etc.
- $s2 = " (MOVEUP R ${ \($v1 + $v2) })";
- $allchars{$id}{ht} += ($v1 + $v2);
- $hadj = sprintf("%.3f", ($v1 + $v2) * $slant);
- $ic = $allchars{$char}{ic};
- }
- elsif ($allchars{$char}{ht} > 1.15 * $xheight) {
- $tallchar = 1;
- if ($char =~ /$supacc$/
- and $char !~ /under$supacc$/) { # double accs
- $s2 = " (MOVEUP R $v1)";
- $allchars{$id}{ht} += $v1;
- $hadj = sprintf("%.3f", $v1 * $slant);
- $ic = $allchars{$char}{ic};
- }
- else { # caps etc.
- $s2 = " (MOVEUP R $v2)";
- $allchars{$id}{ht} += $v2;
- $hadj = sprintf("%.3f", $v2 * $slant);
- $ic = $allchars{$char}{ic};
- }
- }
- else { # single accs
- $s2 = " ";
- $ic = $allchars{$acc}{ic};
- }
- $h = sprintf("%.3f", ($allchars{$char}{wd} - $allchars{$acc}{wd}) / 2);
- unless ($tallchar) { $ic -= $h }
- $allchars{$id}{ic} = $ic unless $ic < 0;
- $h += $hadj;
- if ($h > 0) { $s2 .= " (MOVERIGHT R $h) " }
- elsif ($h < 0) {
- $h = -$h;
- $s2 .= " (MOVELEFT R $h) ";
- }
- else { $s2 .= " " }
- $s3 = $allchars{$acc}{map};
- $s3 =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- if ($cb) { # candrabindu
- $cb = $s2 . $cb;
- if ($cbx) {
- unless (($cb =~ s/(MOVERIGHT R )([0-9.]+)/$1 . ($2 + $cbx * $scale)/e)
- or ($cb =~ s/(MOVELEFT R )([0-9.]+)/$1 . ($2 - $cbx * $scale)/e)) {
- $cb =~ s/^( +)/"$1(MOVERIGHT R " . ($cbx * $scale) . ") "/e;
- }
- }
- if ($cby) {
- unless ($cb =~ s/(MOVEUP R )([0-9.]+)/$1 . ($2 + $cby * $scale)/e) {
- $cb =~ s/^( +)/"$1(MOVEUP R " . ($cby * $scale) . ") "/e;
- }
- }
- $cb .= "\n";
- $s1 = "(PUSH) " . $s1;
- $s3 .= " (POP)";
- }
- $allchars{$id}{map} = " $s1\n$s2$s3\n$cb";
- $chars[$num] = $allchars{$id};
-}
-
-sub underacc {
- #
- # Dropped accents
- #
- my ($num, $char, $acc, $id) = @_;
- my ($h, $v, $s1, $s2, $s3);
- $acc =~ s/^under//;
- if ($acc eq "dot") { $acc = "period" }
- if ($acc eq "candrabindu") { die "Bad definition (no such accent): $qdef\n" }
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$char}{ht};
- $allchars{$id}{ic} = $allchars{$char}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- if ($acc =~ /^$supacc$/) {
- $v = $allchars{$id}{dp} = $underadp * $scale * $shrink;
- $v += ($accdepth * $shrink);
- }
- else {
- $v = $allchars{$id}{dp} = $underddp * $scale + $allchars{$acc}{dp};
- }
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- if ($acc =~ /^$supacc$/) {
- $h = ($allchars{$char}{wd} - ($allchars{$acc}{wd} * $shrink)) / 2 - $v * $slant;
- if ($opt_s) { $s2 = " (SELECTFONT D 1)\n" }
- }
- else {
- $h = ($allchars{$char}{wd} - $allchars{$acc}{wd}) / 2 - $v * $slant;
- }
- $h = sprintf("%.3f", $h);
- if ($h > 0) {
- $s2 .= " (MOVEDOWN R $v) (MOVERIGHT R $h) ";
- }
- elsif ($h < 0) {
- $h = -$h;
- $s2 .= " (MOVEDOWN R $v) (MOVELEFT R $h) ";
- }
- else { $s2 = " (MOVEDOWN R $v) " }
- $s3 = $allchars{$acc}{map};
- $s3 =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- if ($opt_s and $acc =~ /^$supacc$/) { $s3 .= "\n (SELECTFONT D 0)" }
- $allchars{$id}{map} = " $s1\n$s2$s3\n";
- $chars[$num] = $allchars{$id};
-}
-
-sub underb {
- #
- # Underbar
- #
- my ($num, $char, $id) = @_;
- my ($h, $w, $dp, $s1, $s2, $s3);
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$char}{ht};
- $allchars{$id}{dp} = $dp = $underbdp * $scale;
- $allchars{$id}{ic} = $allchars{$char}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- $h = sprintf("%.3f", ($allchars{$id}{wd} / 10 - $dp * $slant));
- $w = sprintf("%.3f", ($allchars{$id}{wd} * 8 / 10));
- if ($h > 0) {
- $s2 = " (MOVEDOWN R $dp) (MOVERIGHT R $h) ";
- }
- elsif ($h < 0) {
- $h = -$h;
- $s2 = " (MOVEDOWN R $dp) (MOVELEFT R $h) ";
- }
- else { $s2 .= " (MOVEDOWN R $dp) " }
- $s3 = "(SETRULE R ${ \($thk) } R $w)";
- $allchars{$id}{map} = " $s1\n$s2$s3\n";
- $chars[$num] = $allchars{$id};
- #
- # If the character to be underscored is a digraph, fix up the LIGTABLE
- #
- if (grep /^$char$/, @digraphs) {
- pop @newligs;
- dummychar(0x035F, "uni035F") unless defined $allchars{uni035F};
- $char =~ /^(.)(.)$/;
- ($one, $two) = ($1, $2);
- $one_ = $one . "_uni035F";
- dummychar($dummycodepoint--, $one_) unless defined $allchars{$one_};
- push @newligs, "$one: (LIG uni035F $one_)"
- unless (grep /^$one: \(LIG uni035F $one_\)$/, @newligs);
- push @newligs, "$one_: (LIG $two $id)";
- }
-}
-
-sub digraph {
- #
- # Make a new character consisting of two existing characters
- #
- my ($num, $char, $acc, $id) = @_;
- my ($one, $two, $kern, $s1, $s2, $charZWJ);
- #
- # Remove the ligature info -- we don't want every occurrence of
- # e.g."kh" to be converted into a digraph.
- #
- pop @newligs;
- #
- # List all digraphs for future reference
- #
- push @digraphs, $id;
- if ($ligs =~ /^ \(LABEL $char\)\n(.*?)\n \(KRN $acc R (-?[0-9.]+)\)\n/ms) {
- ($one, $two) = ($1, $2);
- }
- $kern = $two if $one !~ /^ \(STOP\)$/m;
- $allchars{$id}{wd} = $allchars{$char}{wd} + $allchars{$acc}{wd};
- $allchars{$id}{wd} += $kern;
- $allchars{$id}{ht} = max($allchars{$char}{ht}, $allchars{$acc}{ht});
- $allchars{$id}{dp} = max($allchars{$char}{dp}, $allchars{$acc}{dp});
- $allchars{$id}{ic} = $allchars{$acc}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- chomp ($s2 = $allchars{$acc}{map});
- $s1 =~ s/(\(SETCHAR .*?\))/$1\n$s2/;
- if ($kern) {
- if ($kern < 0) {
- $kern = -$kern;
- $s1 =~ s/(\(SETCHAR .*?\))/$1 (MOVELEFT R $kern)/;
- }
- else { $s1 =~ s/(\(SETCHAR .*?\))/$1 (MOVERIGHT R $kern)/ }
- }
- $allchars{$id}{map} = $s1;
- $chars[$num] = $allchars{$id};
-}
-
-sub dummychar {
- #
- # Make a new dummy character
- #
- my ($num, $id) = @_;
- $allchars{$id}{wd} = 0;
- $allchars{$id}{ht} = 0;
- $allchars{$id}{dp} = 0;
- $allchars{$id}{ic} = 0;
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $allchars{$id}{map} = " (SETCHAR H 0020)\n";
- $chars[$num] = $allchars{$id};
-}
-
-sub fixkerns {
- #
- # Generalise the kerning info contained in the vpl file by applying
- # it to new accented chars. Do not kern lower-case chars bearing
- # superscript accents with capitals, quotes or a preceding "f".
- #
- my ($char, $acc) = @_;
- my ($olabel, $nlabel, @liglist, $lchar, $rchar);
- return if $char eq "space";
- if ($acc =~ /^$accents$/) { $lchar = $rchar = $char }
- else {
- $lchar = $char;
- $rchar = $acc;
- }
- unless ($char =~ /^[a-z]/ and $acc =~ /^$supacc$/) {
- $ligs =~ s[(\n \(LABEL )$rchar\)(?!\n \(LIG.*$)]
- [$&$1$char$acc)]gm
- unless $ligs =~ /\n \(LABEL $char$acc\)$/m;
- $ligs =~ s[(\n \(LABEL )$rchar\)(\n \(LIG.*$)+(?!\n \(STOP\))]
- [$&$1$char$acc)]gm
- unless $ligs =~ /\n \(LABEL $char$acc\)$/m;
- $ligs =~ s[(\n \(KRN )$lchar( .*)$]
- [$&$1$char$acc$2]gm;
- }
- else {
- if ($ligs =~ /\n \(LABEL $char\).*?\(STOP\)/s) {
- $nlabel = $olabel = $&;
- $nlabel =~ s/(\n \(LABEL $char)\)/$1$acc)/
- unless $ligs =~ /\n \(LABEL $char$acc\)/m;
- $nlabel =~ s/\n \(LIG .*\)$//gm;
- $nlabel =~ s/\n \(LABEL (?!$char$acc).*\)$//gm;
- $nlabel =~ s/\n \(KRN ([A-Z]|quote).*\)$//gm;
- $ligs =~ s/(\n \(LABEL )$char\).*?\(STOP\)/$olabel$nlabel/s;
- }
- @liglist = split /\n \(STOP\)/, $ligs;
- foreach (@liglist) {
- unless (/\n \(LABEL ([A-Zf]|quote).*\)$/m) {
- s/(\n \(KRN $char)( .*\))$/$&$1$acc$2/gm;
- }
- }
- $ligs = join("\n (STOP)", @liglist);
- }
-}
diff --git a/Build/source/texk/texlive/linked_scripts/accfonts/vpl2vpl b/Build/source/texk/texlive/linked_scripts/accfonts/vpl2vpl
deleted file mode 100755
index 65ded28ce59..00000000000
--- a/Build/source/texk/texlive/linked_scripts/accfonts/vpl2vpl
+++ /dev/null
@@ -1,994 +0,0 @@
-#!/usr/bin/perl
-
-# Vpl2vpl: a program to generate accented virtual fonts for TeX
-# Copyright (C) 1997 John D. Smith
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-$version = 0.25;
-#------------------------------------------------------------------------#
-$description =
-"Syntax: vpl2vpl -d definition-file [-s shrink-factor]
- [-c candrabindu-adjustment] [-b] vpl-file
-
-Vpl2vpl creates new TeX virtual fonts based on existing fonts or
-virtual fonts (\"input fonts\"). A successful run will read a pl
-(Property List) or vpl (Virtual Property List) file and a definition
-file, and will generate a new vpl (Virtual Property List) file on
-standard output. The input font is assumed to adhere to the standard
-TeX encoding for text fonts unless it was created with either of the
-programs afm2pl or afm2tfm, in which case it is assumed to conform to
-(respectively) the Adobe Standard Encoding or the encoding specified
-in the file dvips.enc. In either case, the name of the input font is
-assumed to be the name of the input file without its .vpl or .pl
-extension: it must conform to normal TeX conventions for naming fonts,
-as vpl2vpl attempts to draw conclusions from it about the kind of font
-it is dealing with.
-
-A typical complete sequence of commands to create a new virtual
-font might therefore be
- tftopl cmr10.tfm cmr10.pl
- vpl2vpl -d ISO-Latin1.def cmr10.pl >cmr10_isol1.vpl
- vptovf cmr10_isol1.vpl cmr10_isol1.vf cmr10_isol1.tfm
-for a Computer Modern font, or
- afm2pl Times-Roman.afm rptmr.pl
- pltotf rptmr.pl rptmr.tfm
- vpl2vpl -d ISO-Latin1.def rptmr.pl >ptmr-isol1.vpl
- vptovf ptmr-isol1.vpl ptmr-isol1.vf ptmr-isol1.tfm
-for a PostScript font.
-
-Another approach for a PostScript font is to use afm2tfm:
- afm2tfm Times-Roman.afm -t dvips.enc -v ptmr rptmr
- vpl2vpl -d ISO-Latin1.def ptmr.vpl >ptmr-isol1.vpl
- vptovf ptmr-isol1.vpl ptmr-isol1.vf ptmr-isol1.tfm
--- but this is now deprecated, as afm2tfm generates incorrect
-values for the heights of some characters, and this can lead to
-bad accent placing.
-
-In order to keep the whole upper half of the character set free for
-the requirements of the encoding specified in the definition file,
-certain modifications are made to input fonts following the
-dvips.enc encoding to bring them into greater conformity with the
-TeX norm. In particular, the characters dotaccent and hungarumlaut
-are placed in the positions assigned by TeX (\"5F, \"7D), not those
-enforced by dvips.enc (\"C7, \"CD). The f-ligatures, double quotes
-and dashes are also moved from the upper half of the character set
-to their normal TeX positions. As a result, the following characters
-are not found in the lower half of the character set: quotesingle,
-quotedbl, backslash, underscore, braceleft, bar, braceright. These
-characters can, however, be assigned positions in the output font if
-they are needed. (Indeed, they could all be explicitly restored to
-their dvips.enc positions if this were desired.)
-
-Options:
-
- -d should refer to a font definition file. This file (which could
- usefully be named, e.g., \"French.def\") should consist of
- lines of character definitions, in the form
- \"number\" \"character\"
- or
- \"number\" \"character\" \"accent\"
- Here \"number\" represents the character's position in the new
- encoding and may be expressed in decimal, octal or hex;
- \"character\" names the character (e.g. \"comma\", \"eight\",
- \"A\") or consists of the word \".notdef\" (indicating that
- the specified number's \"slot\" in the new encoding is to be
- empty); and \"accent\" optionally names an accent to be placed
- on the character. In addition to the standard accents available
- in PostScript fonts, \"underbar\" and \"underdot\" are also
- available, as are \"under\" versions of all the normal
- superscript accents (\"underdieresis\", \"underring\", etc.).
- The Indian accent \"candrabindu\" may also be specified: it
- is formed by overprinting a breve with a dotaccent. Finally,
- \"overdot\" may be used as a synonym for \"dotaccent\".
-
- If the character named in the \"accent\" position is not in fact
- a valid accent character, the program interprets the definition
- as a request for a digraph formed from the \"character\" and the
- \"accent\". A digraph consisting of, say, \"k\" and \"h\" will be
- indistinguishable from the letters \"k\" and \"h\" printed
- consecutively, but the digraph \"kh\" can itself receive accents
- like any other character: see next paragraph.
-
- A new character (such as \"amacron\" or \"kh\") may be freely
- used in the \"character\" position of a further definition (such
- as \"amacron breve\" or \"kh underbar\"). There is no constraint
- on the ordering of definitions within a definition file. The
- definition of \"a macron\" does not have to precede that of
- \"amacron breve\": requests for \"impossible\" characters are
- deferred until their constituents have had a chance to come into
- being.
-
- \"Slots\" for which no new definition is given retain the
- definition they have in the input font.
-
- The definition file may also contain blank lines and comments
- (introduced by \"\#\").
-
- -s may optionally give the factor, expressed as a per-thousand
- value, by which normally superscript accents (such as dieresis,
- ring) should be shrunk when they are used as subscript accents
- (such as underdieresis, underring). Values of around 800 may be
- found useful.
-
- -c may optionally give two comma-separated numerical values to
- adjust the x and y coordinates of the dotaccent placed within a
- breve to form the candrabindu accent. A coordinate scheme using
- \"DESIGNUNITS R 1000\" is assumed.
-
- -b may optionally be specified to block the use of predefined
- accented characters, forcing vpl2vpl to define its own
- versions. This may be useful to secure a consistent appearance
- in cases where a font designer does not share vpl2vpl's views
- on where accents should be placed.
-
- -h prints this help.
-";
-#------------------------------------------------------------------------#
-
-########################
-# Packages and constants
-########################
-#
-use File::Basename;
-use Getopt::Std;
-$cmdline = basename($0) . " " . join " ", @ARGV;
-getopts('d:s:c:bh');
-if ($opt_h or !$opt_d or $#ARGV != 0) {
- print STDERR $description;
- exit 1;
-}
-
-$filename = $ARGV[0];
-($fontname = $filename) =~ s/\..*$//;
-($encname = basename($opt_d)) =~ s/\..*$//;
-$vtitle = "(VTITLE Font $fontname modified for $encname encoding by vpl2vpl";
-$vtitle .= " v. $version" if $version;
-$vtitle .= ")\n(COMMENT Command line: $cmdline)";
-
-#
-# Flags for bold and small caps. These are probably a bit iffy, but
-# there's not much that can be done about it.
-#
-if ($fontname =~ /(^p.*b[oi]?[c]?$|^[^p].*bx[a-z]*[0-9]+$)/) { $bold = 1 }
-if ($fontname =~ /(^p.*c$|^[^p].*csc[a-z]*[0-9]+$)/) { $scaps = 1 }
-if ($opt_s) { $shrink = $opt_s / 1000 } else { $shrink = 1 }
-
-#
-# Array to convert from number to vpl representation
-#
-foreach $i (0 .. 255) {
- $nv[$i] = (chr($i) =~ /[0-9A-Za-z]/ ? "C " . chr $i : sprintf("O %lo", $i));
-}
-
-#
-# Now the encoding vectors.
-#
-@TeXenc = (
- "Gamma", "Delta", "Theta", "Lambda",
- "Xi", "Pi", "Sigma", "Upsilon",
- "Phi", "Psi", "Omega", "ff",
- "fi", "fl", "ffi", "ffl",
- "dotlessi", "dotlessj", "grave", "acute",
- "caron", "breve", "macron", "ring",
- "cedilla", "germandbls", "ae", "oe",
- "oslash", "AE", "OE", "Oslash",
- "space", "exclam", "quotedblright", "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",
- "exclamdown", "equal", "questiondown", "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",
- "quotedblleft", "bracketright", "circumflex", "dotaccent",
- "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", "endash",
- "emdash", "hungarumlaut", "tilde", "dieresis"
-);
-
-@dvipsenc = (
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "quotesingle", "exclamdown", "questiondown",
- "dotlessi", "dotlessj", "grave", "acute",
- "caron", "breve", "macron", "ring",
- "cedilla", "germandbls", "ae", "oe",
- "oslash", "AE", "OE", "Oslash",
- "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", "circumflex", "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", "tilde", "dieresis",
- "asciicircum", "asciitilde", "Ccedilla", "Iacute",
- "Icircumflex", "atilde", "edieresis", "egrave",
- "scaron", "zcaron", "Eth", "ff",
- "ffi", "ffl", ".notdef", ".notdef",
- ".notdef", ".notdef", "Scaron", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- "Ydieresis", ".notdef", "Zcaron", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", "cent", "sterling",
- "fraction", "yen", "florin", "section",
- "currency", "copyright", "quotedblleft", "guillemotleft",
- "guilsinglleft", "guilsinglright", "fi", "fl",
- "degree", "endash", "dagger", "daggerdbl",
- "periodcentered", ".notdef", "paragraph", "bullet",
- "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
- "ellipsis", "perthousand", ".notdef", ".notdef",
- "Agrave", "Aacute", "Acircumflex", "Atilde",
- "Adieresis", "Aring", ".notdef", "dotaccent",
- "Egrave", "Eacute", "Ecircumflex", "Edieresis",
- "Igrave", "hungarumlaut", "ogonek", "Idieresis",
- "emdash", "Ntilde", "Ograve", "Oacute",
- "Ocircumflex", "Otilde", "Odieresis", ".notdef",
- ".notdef", "Ugrave", "Uacute", "Ucircumflex",
- "Udieresis", "Yacute", "Thorn", ".notdef",
- "agrave", "aacute", "acircumflex", "ordfeminine",
- "adieresis", "aring", ".notdef", "ccedilla",
- "Lslash", "eacute", "ecircumflex", "ordmasculine",
- "igrave", "iacute", "icircumflex", "idieresis",
- ".notdef", "ntilde", "ograve", "oacute",
- "ocircumflex", "otilde", "odieresis", ".notdef",
- "lslash", "ugrave", "uacute", "ucircumflex",
- "udieresis", "yacute", "thorn", "ydieresis"
-);
-
-@adobeenc=(
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".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", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "exclamdown", "cent", "sterling",
- "fraction", "yen", "florin", "section",
- "currency", "quotesingle", "quotedblleft", "guillemotleft",
- "guilsinglleft", "guilsinglright", "fi", "fl",
- ".notdef", "endash", "dagger", "daggerdbl",
- "periodcentered", ".notdef", "paragraph", "bullet",
- "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
- "ellipsis", "perthousand", ".notdef", "questiondown",
- ".notdef", "grave", "acute", "circumflex",
- "tilde", "macron", "breve", "dotaccent",
- "dieresis", ".notdef", "ring", "cedilla",
- ".notdef", "hungarumlaut", "ogonek", "caron",
- "emdash", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "AE", ".notdef", "ordfeminine",
- ".notdef", ".notdef", ".notdef", ".notdef",
- "Lslash", "Oslash", "OE", "ordmasculine",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "ae", ".notdef", ".notdef",
- ".notdef", "dotlessi", ".notdef", ".notdef",
- "lslash", "oslash", "oe", "germandbls",
- ".notdef", ".notdef", ".notdef", ".notdef"
-);
-
-###############
-# Read DEF file
-###############
-#
-open DEF, $opt_d or die "Cannot open $opt_d: $!\n";
-while (<DEF>) {
- next if (/^\s*$/ || /^\#/);
- s/\s*(\#.*)?$//;
- push @deflines, $_;
-}
-close DEF;
-
-###############
-# Read VPL file
-###############
-#
-# File header
-#
-$vplhead = <> or exit 1;
-unless ($vplhead =~ /^\((VTITLE|FAMILY) /) {
- die "$filename is not a vpl file: giving up\n"
-}
-do {
- $_ = <>;
- $vplhead .= $_;
-} until ($_ =~ /^\(LIGTABLE$/ or eof);
-if (eof) {
- die "$filename does not seem to be a text font (no LIGTABLE): giving up\n";
-}
-if ($vplhead =~ s/\A\(VTITLE(.*)$/$vtitle\n(COMMENT Old vtitle:$1/m) {
- $vplhead =~ s/\n\(COMMENT Please edit that VTITLE .*\)$//m;
- @enc = @dvipsenc;
- $dvips = 1;
-}
-elsif ($vplhead =~ /\A\(FAMILY.*\)\n\(CODINGSCHEME ADOBESTANDARDENCODING\)$/m) {
- $vplhead =~ s/\A/$vtitle\n/m;
- @enc = @adobeenc;
- $dvips = 0;
-}
-else {
- $vplhead =~ s/\A/$vtitle\n/m;
- @enc = @TeXenc;
- $dvips = 0;
-}
-if ($vplhead =~ /^\(CODINGSCHEME TEX MATH SYMBOLS/m) {
- die "$filename is a TeX math font: giving up\n";
-}
-unless ($vplhead =~ s/^(\(CODINGSCHEME .*\+\s?)(\S+)\)$/$1$encname)/m) {
- $vplhead =~ s/^(\(CODINGSCHEME .*)\)$/$1 + $encname)/m;
-}
-if ($vplhead =~ /^\(DESIGNUNITS R (.+)\)/m) { $scale = $1 }
-else {$scale = 1 }
-if ($vplhead =~ /^ \(SLANT R (.+)\)/m) { $slant = $1 }
-if ($vplhead =~ /^ \(XHEIGHT [DR] (.+)\)/m) { $xheight = $1 }
-unless ($vplhead =~ /^\(MAPFONT /m) {
- if ($vplhead =~ /^\(DESIGNSIZE R (.*)\)$/m) { $dsize = $1 }
- $mapfont = "\n(MAPFONT D 0\n (FONTNAME $fontname)\n (FONTDSIZE R $dsize)\n )";
- $vplhead =~ s/\n\(LIGTABLE\Z/$mapfont$&/m;
-}
-if ($opt_s) {
- $vplhead =~ s[^(\(MAPFONT D )0(.*?)( \))]
- [$&\n${1}1$2 (FONTAT R ${ \($shrink * $scale) })\n$3]ms;
-}
-
-#
-# Ligatures and kerns
-#
-do {
- $_ = <>;
- s/ \(comment .*$//i;
- $ligs .= $_;
-} until $_ =~ /^ \)/;
-#
-# Now build a hash to convert from vpl representation to char name
-# and use it to make ligtable readable
-#
-foreach $i (0 .. 255) { $vc{$nv[$i]} = $enc[$i] }
-$ligs =~ s/^( \((?:LABEL|KRN) )(\S+ \S+)(.*\))$/$1$vc{$2}$3/gm;
-$ligs =~ s/^( \(LIG )(\S+ \S+) (\S+ \S+)\)$/$1$vc{$2} $vc{$3})/gm;
-
-#
-# Character definitions: store "encoded" defs in @chars, store *all*
-# defs in %allchars
-#
-$_ = <>;
-do {
- if (/^\(CHARACTER/) {
- $character = $_;
- do {
- $_ = <>;
- $character .= $_;
- } until $_ =~ /^ \)/;
- storeinfo($character);
- $_ = <>;
- }
-} until eof;
-foreach $i (0 .. $#chars) {
- if ($chars[$i] and $enc[$i] ne ".notdef") {
- $allchars{$enc[$i]} = $chars[$i];
- }
-}
-
-##################
-# Set up constants
-##################
-
-$subacc = "(cedilla|ogonek|commaaccent)";
-$supacc = "(grave|acute|circumflex|tilde|macron|breve|dotaccent|overdot|dieresis|ring|hungarumlaut|caron|candrabindu)";
-$underacc = "(underdot|under$supacc)";
-$accents = "($subacc|$supacc|$underacc|underbar)";
-$underadp = 0.230; # depth of "under" accs
-$underddp = 0.213; # depth of underdot
-if ($bold) { $thk = 0.072 } else { $thk = 0.052 } # thickness and
-$underbdp = 0.082 + $thk; # depth of underbar
-$capheight = $allchars{"X"}{ht};
-$accheight = $allchars{"macron"}{ht};
-$accdepth = $accheight - $thk * $scale; # probable approx. "depth" of macron
-$v1 = $accheight - $xheight; # vertical offset for double accents
-$v2 = $capheight - $xheight; # vertical offset for accented caps etc
-if ($scaps) { # accented small caps
- $scoffset = $allchars{"x"}{ht} - $xheight;
- $v1 += $scoffset;
-}
-if ($opt_c) { # candrabindu
- ($cbx, $cby) = $opt_c =~ /^(.*),(.*)$/;
- $cbx += ($allchars{"breve"}{wd} - $allchars{"dotaccent"}{wd}) / 2;
- $cbx /= 1000;
- $cby /= 1000;
-}
-
-######################
-# Build the characters
-######################
-#
-# First normalise dvips.enc encoding quirks
-#
-if ($dvips) {
- chmove("fi", 014);
- chmove("fl", 015);
- chmove("quotedblright", 042);
- chmove("quotedblleft", 0134);
- chmove("dotaccent", 0137);
- chmove("endash", 0173);
- chmove("emdash", 0174);
- chmove("hungarumlaut", 0175);
-}
-#
-# Now build a list of definitions supplied by user
-#
-for (@deflines) {
- if (/^\s*(\d+|0[0-7]+|0x[0-9a-fA-F]+)\s+([a-zA-Z]+?|\.notdef)(?:\s+([a-zA-Z]+))?$/) {
- ($num, $char, $acc) = ($1, $2, $3);
- $num = oct $num if $num =~ /^0/;
- if ($num > 255) { die "Bad definition (number out of range): $_\n" }
- $def = {};
- $def->{qdef} = $_;
- $def->{num} = $num;
- $def->{char} = $char;
- $def->{acc} = $acc;
- $def->{nchar} = $char . $acc;
- push @nchars, $def->{nchar};
- push @defs, $def;
- }
- else { die "Bad definition: $_\n" }
-}
-#
-# Work through the list
-#
-while (@defs) {
- $def = shift @defs;
- $qdef = $def->{qdef};
- $num = $def->{num};
- $char = $def->{char};
- $acc = $def->{acc};
- $nchar = $def->{nchar};
- #
- # If we can't handle $char/$acc yet, but believe we will be able
- # to later, send the definition to the back of the queue. In case
- # it later turns out we were wrong, allow only five loops before
- # giving up.
- #
- if (!$allchars{$char} and $char ne ".notdef") {
- if (grep /^$char$/, @nchars) {
- unless (++$def->{requeue} > 5) {
- push @defs, $def;
- next;
- }
- }
- else { die "Bad definition (no such character): $qdef\n" }
- }
- if ($acc and !$allchars{$acc} and $acc !~ /^$accents$/) {
- if (grep /^$acc$/, @nchars) {
- unless (++$def->{requeue} > 5) {
- push @defs, $def;
- next;
- }
- }
- else { die "Bad definition (no such accent): $qdef\n" }
- }
- #
- # Remove any existing claims on $num
- #
- @{ $allchars{$chars[$num]{id}}{num} } = grep !/$num/,
- @{ $allchars{$chars[$num]{id}}{num} };
- #
- # First deal with .notdef
- #
- if ($nchar eq ".notdef") {
- undef $chars[$num];
- }
- #
- # Next look among existing chars (unless blocked by -b)
- #
- elsif (!($acc and $opt_b) and $allchars{$nchar}) {
- push( @{ $allchars{$nchar}{num} }, $num);
- $chars[$num] = $allchars{$nchar};
- }
- #
- # If it can't be built from sub-elements, issue a warning and move on
- #
- elsif (!$acc) {
- warn "No such character - ignoring definition: $qdef\n";
- undef $chars[$num];
- }
- #
- # Now build the char
- #
- else {
- #
- # First get rid of predefined/duplicated ligtable statements
- # and character definitions; also synonyms
- #
- $ligs =~ s/\n \((LABEL|KRN|LIG) ($nchar .*|.*$nchar)\)$//gm;
- $allchars{$nchar} = ();
- if ($acc eq "overdot") {
- $nchar2 = $char . "dotaccent";
- $ligs =~ s/\n \((LABEL|KRN|LIG) ($nchar2 .*|.*$nchar2)\)$//gm;
- delete $allchars{$nchar2};
- }
- #
- # Go!
- #
- if ($acc =~ /^$subacc$/) {
- subacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^$supacc$/) {
- supacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^$underacc$/) {
- underacc($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- elsif ($acc =~ /^underbar$/) {
- underb($num, $char, $nchar);
- fixkerns($char, $acc);
- }
- else {
- digraph($num, $char, $acc, $nchar);
- fixkerns($char, $acc);
- }
- }
-}
-
-###################
-# Sort out ligtable
-###################
-#
-# Convert to vpl representation, eliminating statements invoking
-# "unencoded" characters
-#
-@liglist = split /\n/, $ligs;
-$ligs = "";
-foreach (@liglist) {
- if (/^( \(LIG \S+ )(\S+)\)$/) {
- if ($n = ${ $allchars{$2}{num} }[0]) {
- s/^( \(LIG \S+ )(\S+)\)$/$1$nv[$n])/;
- }
- else { next }
- }
- if (/^( \((?:LABEL|LIG|KRN) )([^ )]+)(.*)$/) {
- ($one, $two, $three) = ($1, $2, $3);
- foreach $n (@{ $allchars{$two}{num} }) {
- $ligs .= "$one$nv[$n]$three\n";
- }
- }
- else { $ligs .= "$_\n" }
-}
-#
-# Eliminate sequences orphaned by elimination of a LABEL
-#
-@liglist = split / \(STOP\)\n/, $ligs;
-$ligs = "";
-foreach (@liglist) {
- if (/^ \(LABEL /m) { $ligs .= "$_ (STOP)\n" }
- elsif (/^ \)$/m) { $ligs .= $_ }
-}
-#
-# Eliminate empty statements
-#
-$ligs =~ s/(^ \(LABEL .*\)\n)+ \(STOP\)\n//gm;
-
-####################
-# Output the results
-####################
-#
-print $vplhead, $ligs;
-foreach $i (0 .. 255) { if (defined $chars[$i]{id}) { printchar($i) } }
-
-#####################
-# End of main program
-#####################
-
-sub storeinfo {
- #
- # Extract info from a character definition and store it in @chars
- #
- my $char = shift;
- my $num;
- if ($char =~ /\A\(CHARACTER O ([0-7]+)/m) { $num = oct $1 }
- elsif ($char =~ /\A\(CHARACTER C (.)/m) { $num = ord $1 }
- $chars[$num]{id} = $enc[$num];
- push( @{ $chars[$num]{num} }, $num);
- if ($char =~ /^ \(CHARWD R (.*?)\)$/m) { $chars[$num]{wd} = $1 }
- if ($char =~ /^ \(CHARHT R (.*?)\)$/m) { $chars[$num]{ht} = $1 }
- if ($char =~ /^ \(CHARDP R (.*?)\)$/m) { $chars[$num]{dp} = $1 }
- if ($char =~ /^ \(CHARIC R (.*?)\)$/m) { $chars[$num]{ic} = $1 }
- if ($char =~ /^ \(MAP\n((.|\n)*)^ \)/m) { $chars[$num]{map} = $1 }
- else { $chars[$num]{map} = " (SETCHAR $nv[$num])\n" }
-}
-
-sub printchar {
- #
- # Extract info from @chars and build it into a character definition
- #
- my $num = shift;
- print "(CHARACTER ";
- if (chr($num) =~ /[0-9A-Za-z]/) { print "C " . chr($num) }
- else {
- printf "O %lo", $num;
- print " (COMMENT " . $chars[$num]{id} . ")";
- }
- print "\n";
- print " (CHARWD R " . $chars[$num]{wd} . ")\n" if $chars[$num]{wd};
- print " (CHARHT R " . $chars[$num]{ht} . ")\n" if $chars[$num]{ht};
- print " (CHARDP R " . $chars[$num]{dp} . ")\n" if $chars[$num]{dp};
- print " (CHARIC R " . $chars[$num]{ic} . ")\n" if $chars[$num]{ic};
- print " (MAP\n";
- print $chars[$num]{map};
- print " )\n";
- print " )\n";
-}
-
-sub chmove {
- #
- # Move a character
- #
- my ($char, $num) = @_;
- my $i;
- foreach $i (@{ $allchars{$char}{num} }) { undef $chars[$i] }
- @{ $allchars{$char}{num} } = ();
- @{ $allchars{$chars[$num]{id}}{num} } = grep !/$num/,
- @{ $allchars{$chars[$num]{id}}{num} };
- push( @{ $allchars{$char}{num} }, $num);
- $chars[$num] = $allchars{$char};
-}
-
-sub max {
- #
- # Return greater of two values
- #
- my ($a, $b) = @_;
- return $a > $b ? $a : $b;
-}
-
-sub subacc {
- #
- # Subscript accents
- #
- my ($num, $char, $acc, $id) = @_;
- my ($h, $s1, $s2, $s3);
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$char}{ht};
- $allchars{$id}{dp} = $allchars{$acc}{dp};
- $allchars{$id}{ic} = $allchars{$char}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- $h = sprintf("%.3f", ($allchars{$char}{wd} - $allchars{$acc}{wd}) / 2);
- if ($h > 0) { $s2 = " (MOVERIGHT R $h) " }
- elsif ($h < 0) {
- $h = -$h;
- $s2 = " (MOVELEFT R $h) ";
- }
- else { $s2 = " " }
- $s3 = $allchars{$acc}{map};
- $s3 =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- $allchars{$id}{map} = " $s1\n$s2$s3\n";
- $chars[$num] = $allchars{$id};
-}
-
-sub supacc {
- #
- # Superscript accents
- #
- my ($num, $char, $acc, $id) = @_;
- my ($cb, $h, $hadj, $tallchar, $ic, $s1, $s2, $s3);
- if ($char eq "i" and $allchars{"dotlessi"}) { $char = "dotlessi" }
- if ($char eq "j" and $allchars{"dotlessj"}) { $char = "dotlessj" }
- if ($acc eq "overdot") { $acc = "dotaccent" }
- if ($acc eq "candrabindu") {
- $acc = "breve";
- ($cb = $allchars{"dotaccent"}{map}) =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- }
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$acc}{ht};
- $allchars{$id}{dp} = $allchars{$char}{dp};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- if ($scaps and $char =~ /^[a-z]/) { # accented small caps
- $tallchar = 1;
- if ($char =~ /$supacc$/
- and $char !~ /under$supacc$/) { # double accs
- $s2 = " (MOVEUP R $v1)";
- $allchars{$id}{ht} += $v1;
- $hadj = sprintf("%.3f", $v1 * $slant);
- $ic = $allchars{$char}{ic};
- }
- else { # single accs
- $s2 = " (MOVEUP R $scoffset)";
- $allchars{$id}{ht} += $scoffset;
- $hadj = sprintf("%.3f", $scoffset * $slant);
- $ic = $allchars{$acc}{ic} + $hadj;
- }
- }
- elsif ($allchars{$char}{ht} >= ($accheight + $v2)) { # double accs
- $tallchar = 1; # on caps etc.
- $s2 = " (MOVEUP R ${ \($v1 + $v2) })";
- $allchars{$id}{ht} += ($v1 + $v2);
- $hadj = sprintf("%.3f", ($v1 + $v2) * $slant);
- $ic = $allchars{$char}{ic};
- }
- elsif ($allchars{$char}{ht} > 1.15 * $xheight) {
- $tallchar = 1;
- if ($char =~ /$supacc$/
- and $char !~ /under$supacc$/) { # double accs
- $s2 = " (MOVEUP R $v1)";
- $allchars{$id}{ht} += $v1;
- $hadj = sprintf("%.3f", $v1 * $slant);
- $ic = $allchars{$char}{ic};
- }
- else { # caps etc.
- $s2 = " (MOVEUP R $v2)";
- $allchars{$id}{ht} += $v2;
- $hadj = sprintf("%.3f", $v2 * $slant);
- $ic = $allchars{$char}{ic};
- }
- }
- else { # single accs
- $s2 = " ";
- $ic = $allchars{$acc}{ic};
- }
- $h = sprintf("%.3f", ($allchars{$char}{wd} - $allchars{$acc}{wd}) / 2);
- unless ($tallchar) { $ic -= $h }
- $allchars{$id}{ic} = $ic unless $ic < 0;
- $h += $hadj;
- if ($h > 0) { $s2 .= " (MOVERIGHT R $h) " }
- elsif ($h < 0) {
- $h = -$h;
- $s2 .= " (MOVELEFT R $h) ";
- }
- else { $s2 .= " " }
- $s3 = $allchars{$acc}{map};
- $s3 =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- if ($cb) { # candrabindu
- $cb = $s2 . $cb;
- if ($cbx) {
- unless (($cb =~ s/(MOVERIGHT R )([0-9.]+)/$1 . ($2 + $cbx * $scale)/e)
- or ($cb =~ s/(MOVELEFT R )([0-9.]+)/$1 . ($2 - $cbx * $scale)/e)) {
- $cb =~ s/^( +)/"$1(MOVERIGHT R " . ($cbx * $scale) . ") "/e;
- }
- }
- if ($cby) {
- unless ($cb =~ s/(MOVEUP R )([0-9.]+)/$1 . ($2 + $cby * $scale)/e) {
- $cb =~ s/^( +)/"$1(MOVEUP R " . ($cby * $scale) . ") "/e;
- }
- }
- $cb .= "\n";
- $s1 = "(PUSH) " . $s1;
- $s3 .= " (POP)";
- }
- $allchars{$id}{map} = " $s1\n$s2$s3\n$cb";
- $chars[$num] = $allchars{$id};
-}
-
-sub underacc {
- #
- # Dropped accents
- #
- my ($num, $char, $acc, $id) = @_;
- my ($h, $v, $s1, $s2, $s3);
- $acc =~ s/^under//;
- if ($acc eq "dot") { $acc = "period" }
- if ($acc eq "candrabindu") { die "Bad definition (no such accent): $qdef\n" }
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$char}{ht};
- $allchars{$id}{ic} = $allchars{$char}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- if ($acc =~ /^$supacc$/) {
- $v = $allchars{$id}{dp} = $underadp * $scale * $shrink;
- $v += ($accdepth * $shrink);
- }
- else {
- $v = $allchars{$id}{dp} = $underddp * $scale + $allchars{$acc}{dp};
- }
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- if ($acc =~ /^$supacc$/) {
- $h = ($allchars{$char}{wd} - ($allchars{$acc}{wd} * $shrink)) / 2 - $v * $slant;
- if ($opt_s) { $s2 = " (SELECTFONT D 1)\n" }
- }
- else {
- $h = ($allchars{$char}{wd} - $allchars{$acc}{wd}) / 2 - $v * $slant;
- }
- $h = sprintf("%.3f", $h);
- if ($h > 0) {
- $s2 .= " (MOVEDOWN R $v) (MOVERIGHT R $h) ";
- }
- elsif ($h < 0) {
- $h = -$h;
- $s2 .= " (MOVEDOWN R $v) (MOVELEFT R $h) ";
- }
- else { $s2 = " (MOVEDOWN R $v) " }
- $s3 = $allchars{$acc}{map};
- $s3 =~ s/\A.*(\(SETCHAR . .+?\)).*\Z/$1/s;
- if ($opt_s and $acc =~ /^$supacc$/) { $s3 .= "\n (SELECTFONT D 0)" }
- $allchars{$id}{map} = " $s1\n$s2$s3\n";
- $chars[$num] = $allchars{$id};
-}
-
-sub underb {
- #
- # Underbar
- #
- my ($num, $char, $id) = @_;
- my ($h, $w, $dp, $s1, $s2, $s3);
- $allchars{$id}{wd} = $allchars{$char}{wd};
- $allchars{$id}{ht} = $allchars{$char}{ht};
- $allchars{$id}{dp} = $dp = $underbdp * $scale;
- $allchars{$id}{ic} = $allchars{$char}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- $s1 =~ s/\A (.*)\n\Z/(PUSH) $1 (POP)/s;
- $h = sprintf("%.3f", ($allchars{$id}{wd} / 10 - $dp * $slant));
- $w = sprintf("%.3f", ($allchars{$id}{wd} * 8 / 10));
- if ($h > 0) {
- $s2 = " (MOVEDOWN R $dp) (MOVERIGHT R $h) ";
- }
- elsif ($h < 0) {
- $h = -$h;
- $s2 = " (MOVEDOWN R $dp) (MOVELEFT R $h) ";
- }
- else { $s2 .= " (MOVEDOWN R $dp) " }
- $s3 = "(SETRULE R ${ \($thk * $scale) } R $w)";
- $allchars{$id}{map} = " $s1\n$s2$s3\n";
- $chars[$num] = $allchars{$id};
-}
-
-sub digraph {
- #
- # Make a new character consisting of two existing characters
- #
- my ($num, $char, $acc, $id) = @_;
- my ($one, $two, $kern, $s1, $s2);
- if ($ligs =~ /^ \(LABEL $char\)\n(.*?)\n \(KRN $acc R (-?[0-9.]+)\)\n/ms) {
- ($one, $two) = ($1, $2);
- }
- $kern = $two if $one !~ /^ \(STOP\)$/m;
- $allchars{$id}{wd} = $allchars{$char}{wd} + $allchars{$acc}{wd};
- $allchars{$id}{wd} += $kern;
- $allchars{$id}{ht} = max($allchars{$char}{ht}, $allchars{$acc}{ht});
- $allchars{$id}{dp} = max($allchars{$char}{dp}, $allchars{$acc}{dp});
- $allchars{$id}{ic} = $allchars{$acc}{ic};
- $allchars{$id}{id} = $id;
- push( @{ $allchars{$id}{num} }, $num);
- $s1 = $allchars{$char}{map};
- chomp ($s2 = $allchars{$acc}{map});
- $s1 =~ s/(\(SETCHAR .*?\))/$1\n$s2/;
- if ($kern) {
- if ($kern < 0) {
- $kern = -$kern;
- $s1 =~ s/(\(SETCHAR .*?\))/$1 (MOVELEFT R $kern)/;
- }
- else { $s1 =~ s/(\(SETCHAR .*?\))/$1 (MOVERIGHT R $kern)/ }
- }
- $allchars{$id}{map} = $s1;
- $chars[$num] = $allchars{$id};
-}
-
-sub fixkerns {
- #
- # Generalise the kerning info contained in the vpl file by applying
- # it to new accented chars. Do not kern lower-case chars bearing
- # superscript accents with capitals, quotes or a preceding "f".
- #
- my ($char, $acc) = @_;
- my ($olabel, $nlabel, @liglist, $lchar, $rchar);
- if ($acc =~ /^$accents$/) { $lchar = $rchar = $char }
- else {
- $lchar = $char;
- $rchar = $acc;
- }
- unless ($char =~ /^[a-z]/ and $acc =~ /^$supacc$/) {
- $ligs =~ s[(\n \(LABEL )$rchar\)(?!\n \(LIG.*$)]
- [$&$1$char$acc)]gm
- unless $ligs =~ /\n \(LABEL $char$acc\)$/m;
- $ligs =~ s[(\n \(LABEL )$rchar\)(\n \(LIG.*$)+(?!\n \(STOP\))]
- [$&$1$char$acc)]gm
- unless $ligs =~ /\n \(LABEL $char$acc\)$/m;
- $ligs =~ s[(\n \(KRN )$lchar( .*)$]
- [$&$1$char$acc$2]gm;
- }
- else {
- if ($ligs =~ /\n \(LABEL $char\).*?\(STOP\)/s) {
- $nlabel = $olabel = $&;
- $nlabel =~ s/(\n \(LABEL $char)\)/$1$acc)/
- unless $ligs =~ /\n \(LABEL $char$acc\)/m;
- $nlabel =~ s/\n \(LIG .*\)$//gm;
- $nlabel =~ s/\n \(LABEL (?!$char$acc).*\)$//gm;
- $nlabel =~ s/\n \(KRN ([A-Z]|quote).*\)$//gm;
- $ligs =~ s/(\n \(LABEL )$char\).*?\(STOP\)/$olabel$nlabel/s;
- }
- @liglist = split /\n \(STOP\)/, $ligs;
- foreach (@liglist) {
- unless (/\n \(LABEL ([A-Zf]|quote).*\)$/m) {
- s/(\n \(KRN $char)( .*\))$/$&$1$acc$2/gm;
- }
- }
- $ligs = join("\n (STOP)", @liglist);
- }
-}
diff --git a/Build/source/texk/texlive/linked_scripts/adhocfilelist/adhocfilelist.sh b/Build/source/texk/texlive/linked_scripts/adhocfilelist/adhocfilelist.sh
deleted file mode 100755
index 07d0388fa5c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/adhocfilelist/adhocfilelist.sh
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/bin/sh
-##
-## \ProvidesFile{adhocfilelist.sh}
-## [2012/11/19 v0.71 command line -> \string\listfiles
-## \space(UL)]
-##
-## (C) 2012 Uwe LĂĽck LaTeX Project Public License
-##
-## essential part of the `myfilist' script:
-#adhoc_head='mylshead'
-## original idea: read standard file; now contained here instead:
-adhoc_head='\\RequirePackage{myfilist}[2012/10/11]\\EmptyFileList';
-## standard settings for `find':
-adhoc_find_std='-name \*.tex'
-add_type () {
- adhoc_find_std="$adhoc_find_std -o -name \*.$1"
-}
-add_type sty; add_type cfg; add_type cls;
-add_type dtx; add_type def; add_type fd;
-adhoc_find_std="-L -maxdepth 1 ( $adhoc_find_std )" ## -L 2012-11-19
-#echo adhoc_find_std = $adhoc_find_std
-## standard action (v0.7):
-adhoc_fmt_std=',%f'
-adhoc_fmt=$adhoc_fmt_std
-##
-## reduce code for help screen:
-opt_help () {
- echo \ \ \ \ \ \ \ \ \ \ "$@"
-};
-## reporting detected options:
-opt_log () {
- echo + adhocfilelist + "$@" +
-}
-## looking for options:
-#while getopts "fF:hl:n:s:t:" optname
-## one-letter options only, for distinguishing from `find' criteria
-## (learnt from "Optionen ermitteln" by JĂĽrgen Plate on
-## http://www.netzmafia.de/skripten/unix/unix8.html)
-optname='hh'; ## somewhat misused for controlling
-while [ $optname ] ; ## the loop that processes options
- do
- #case $optname in## original code for getopts
- case $1 in
- -h) ## help screen
- optname='h' ## flag for avoiding main function
- echo; echo; echo; echo;
- echo =\
-===============================================================================;
- echo
- #echo "\`adhocfilelist.sh' varies LaTeX's \\listfiles to produce"\
- # a stand-alone
- #echo list of \\Provides... contents on screen\
- # 'and optionally in a text file,'
- echo "\`adhocfilelist.sh' varies LaTeX's \\listfiles to produce"\
- a stand-alone list of
- echo \\Provides... contents \for \files typed explicitly\
- or found by the \`\find\' utility.
- echo USAGE: \ \ \ [PATH]adhocfilelist.sh [-OPTIONS] [FILES]
- echo options: ' -0 files modified today,'\
- 'in addition to -g'; ## v0.5
- opt_help -a '$ files modified $ days ago (or like -mtime $,'\
- 'cf. -0)' ## v0.5
- opt_help -c ' compare info with modification dates (filedate.sty)'
- ## v0.7
- opt_help -f ' read FILES as `find'"' options and tests "\
- ' ('"'"'\\*.tex'"')"
- #' \(\\\\\\*.tex\)'
- opt_help -F '$ read (first) `find'"' options/tests from file $"\
- ' (\\*.tex)'
- opt_help -g ' add FILES to standard `find'"' restrictions (cf. -f)"
- opt_help -h ' help display (what you are seeing)'
- opt_help -i '$ input TeX file $ (maybe for more'\
- "\`nicefilelist' settings," ## was -m before v0.5
- opt_help ' '\
- ' cf.' \`myfilist\' 'v0.5 documentation)'
- opt_help -l '$ maximum (base) filename length for'\
- "\`longnamefilelist.sty'"
- opt_help -n '$ longest (base) filename for `nicefilelist.sty'\'\
- '(or ".")'
- opt_help -o '$ write list to plain text file $'
- opt_help -x ' use `xelatex'\'
- echo Without '`find'\'', FILES is a comma-separated'\
- list of \file names.
- echo Without -l or -n, \`myfilist.sty\' is used. For background\
- '(e.g., mentioned'
- echo '*.sty files), see latexfileinfo_pkgs.htm'\
- 'from package latexfileinfo-pkgs,'
- echo
- opt_help http://ctan.org/pkg/latexfileinfo-pkgs
- echo
- echo =\
-===============================================================================;
- echo;
- break;
- ;;
- ## options for real output:
- -0) ## was -2 in v0.5
- adhoc_day='0'
- adhoc_find='\UseFindUtility'
- opt_log looking \for files modified today, using standard settings
- ## <- plural missing 2012-10-17
- shift;;
- -a) ## was -d in v0.4
- adhoc_day="$2"
- adhoc_find='\UseFindUtility'
- opt_log looking \for files modified $2 days ago,\
- using standard settings
- shift 2;;
- -c) ## v0.7
- adhoc_find='\UseFindUtility'
- adhoc_fmt='\\ReadCheckDateOf{%f}{%TY/%Tm/%Td}'
- shift;;
- -f)
- adhoc_find='\UseFindUtility'
- adhoc_find_std=''
- opt_log expecting \find utility, adding nothing
- shift;;
- -F)
- adhoc_find='\UseFindUtility'
- adhoc_find_file="$2"
- opt_log reading \find criteria from $adhoc_find_file
- shift 2;;
- -g) ##v0.5
- adhoc_find='\UseFindUtility'
- opt_log expecting \find utility, using standard settings
- shift;;
- -i) ## was -m) before v0.5
- adhoc_head="\\input{$2}" ## \input allows -l/-n
- opt_log formatting by $adhoc_head
- shift 2;;
- -l)
- adhoc_head="\\RequirePackage{longnamefilelist}
- \listfiles[$2]
- $adhoc_head" ## default or -i
- ## v0.6 not using \MaxLengthEmptyList thinking of -i ...
- opt_log formatting with \`longnamefilelist\',\
- max. name length $2
- shift 2;;
- -n)
- if [ $2 = . ]; then
- set z abcdefgh;
- fi ## v0.5
- adhoc_head="\\RequirePackage{nicefilelist}
- \\MFfieldtemplate{f-base}{$2}
- $adhoc_head"
- ## v0.6 not using \MaxBaseEmptyList thinking of -i ...
- opt_log formatting with \`nicefilelist\',\
- template \`$2\'
- shift 2;;
- -o)
- adhoc_target="[$2]"
- adhoc_head="${adhoc_head}
- \\def\\ListGenerator{^^J by adhocfilelist.sh^^J}"
- opt_log writing list to $2 ## still was $OPTARG before v0.7
- shift 2;;
- -x) ## v0.7
- adhoc_xe='xe'
- opt_log using xelatex
- shift;;
- *) optname='' ## terminate loop
- esac
- done
-## options parsed, now proceed accordingly:
-if [ "$optname" != "h" ]; ## on -h, nothing more to do
- then
- ## processing remaining arguments:
- if [ $adhoc_find ];
- then ## as `find' input
- if [ $adhoc_find_file ]; then
- ## bashref command substitution:
- #adhoc_file_find=$(< $adhoc_find_file) ## bad
- #adhoc_file_find=$(cat $adhoc_find_file) ## good
- adhoc_file_find=`cat $adhoc_find_file` ## good
- ## <- JĂĽrgen Plate 8.3.1:
- ## http://www.netzmafia.de/skripten/unix/unix8.html
- #echo In file: $adhoc_file_find
- else
- adhoc_file_find="$adhoc_find_std"
- fi
- #echo adhoc_file_find = $adhoc_file_find; ## rm. 2012/10/15
- if [ $adhoc_day ]; then
- #adhoc_file_find="$adhoc_file_find ## bad before $@
- # -daystart
- # -mtime $adhoc_day"
- adhoc_day="-daystart -mtime $adhoc_day"
- fi
- echo \find criteria: $adhoc_file_find $@ $adhoc_day; ## in 2012/10/15
- adhoc_files="$(find $adhoc_file_find $@ $adhoc_day\
- -printf "$adhoc_fmt" )"
- else ## as list of file names
- #adhoc_files="$@" ## works too
- adhoc_files="$*"
- fi
- echo Files: $adhoc_files
- ## run latex with generated list of files, unless empty:
- #if [ $adhoc_files ]; then ## bad with $@/$*
- if [ ! -z "$adhoc_files" ]; then
- if [ "$adhoc_fmt" = "$adhoc_fmt_std" ]; then
- adhoc_list="\\ReadListFileInfos$adhoc_target{$adhoc_files}"
- else
- adhoc_list="\\RequirePackage{filedate}\\EmptyFileList\\ModDates
- $adhoc_files \\ListInfos$adhoc_target\\\\relax"
- fi
- #echo TeX Code:
- #echo $adhoc_head $adhoc_find \\NoBottomLines $adhoc_list
- #echo $adhoc_head $adhoc_find \\NoBottomLines $adhoc_list > adhoclsi.tex
- #latex adhoclsi.tex
- ${adhoc_xe}latex $adhoc_head $adhoc_find \\NoBottomLines $adhoc_list
- else
- echo No files. Type adhocfilelist.sh -h \for usage.
- fi ## <- v0.5
-fi
diff --git a/Build/source/texk/texlive/linked_scripts/albatross/albatross.sh b/Build/source/texk/texlive/linked_scripts/albatross/albatross.sh
deleted file mode 100755
index 4c636c6a03e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/albatross/albatross.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-# Public domain. Originally written by Norbert Preining and Karl Berry, 2018.
-# Note from Paulo: this script provides better Cygwin support than our original
-# approach, so the team decided to use it as a proper wrapper for albatross as well.
-
-scriptname=`basename "$0"`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-exec java -jar "$jarpath" "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/arara/arara.sh b/Build/source/texk/texlive/linked_scripts/arara/arara.sh
deleted file mode 100755
index 12efa361a6b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/arara/arara.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-# Public domain. Originally written by Norbert Preining and Karl Berry, 2018.
-# Note from Paulo: this script provides better Cygwin support than our original
-# approach, so the team decided to use it as a proper wrapper for arara as well.
-
-scriptname=`basename "$0" .sh`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-exec java -jar "$jarpath" "$@" \ No newline at end of file
diff --git a/Build/source/texk/texlive/linked_scripts/attachfile2/pdfatfi.pl b/Build/source/texk/texlive/linked_scripts/attachfile2/pdfatfi.pl
deleted file mode 100755
index 3264d6cf500..00000000000
--- a/Build/source/texk/texlive/linked_scripts/attachfile2/pdfatfi.pl
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-$^W=1; # turn warning on
-#
-# pdfatfi.pl
-#
-# Copyright (C) 2005-2010, 2012 Heiko Oberdiek.
-#
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either
-# version 1.3c of this license or (at your option) any later
-# version. This version of this license is in
-# https://www.latex-project.org/lppl/lppl-1-3c.txt
-# and the latest version of this license is in
-# https://www.latex-project.org/lppl.txt
-# and version 1.3 or later is part of all distributions of
-# LaTeX version 2005/12/01 or later.
-#
-# This work has the LPPL maintenance status "maintained".
-#
-# The Current Maintainers of this work are
-# Heiko Oberdiek and the Oberdiek Package Support Group
-# https://github.com/ho-tex/attachfile2/issues
-#
-# See file "attachfile2.pdf" for a list of files that belong to
-# this project.
-#
-# This file "pdfatfi.pl" may be renamed to "pdfatfi"
-# for installation purposes.
-#
-my $prj = 'pdfatfi';
-my $file = "$prj.pl";
-my $program = uc($&) if $file =~ /^\w+/;
-my $version = "2.9";
-my $date = "2019/11/26";
-my $author = "Heiko Oberdiek";
-my $copyright = "Copyright (c) 2005-2010, 2012 by $author.";
-#
-# History:
-# 2005/05/21 v1.0: First release.
-# 2006/08/16 v2.2: Included in DTX file of attachfile2.dtx.
-# 2010/09/27 v2.6: Keys ModDateTZ and CreationDateTZ added.
-# 2016/05/16 v2.8: Option --version added.
-# 2019/11/24 v2.10: adapted version to attachfile2 version.
-#
-
-use POSIX qw(strftime); # %z is used (GNU)
-use Digest::MD5;
-
-### program identification
-my $title = "$program $version, $date - $copyright\n";
-
-### error strings
-my $Error = "!!! Error:"; # error prefix
-
-### variables
-my $atfifile;
-
-### option variables
-my @bool = ("false", "true");
-$::opt_help = 0;
-$::opt_quiet = 0;
-$::opt_debug = 0;
-$::opt_verbose = 0;
-$::opt_version = 0;
-
-my $usage = <<"END_OF_USAGE";
-${title}Syntax: \L$program\E [options] <file[.atfi]>
-Function: Help program for LaTeX package "attachfile2".
-Options: (defaults:)
- --help print usage
- --version print version number
- --(no)quiet suppress messages ($bool[$::opt_quiet])
- --(no)verbose verbose printing ($bool[$::opt_verbose])
- --(no)debug debug informations ($bool[$::opt_debug])
-END_OF_USAGE
-
-### process options
-my @OrgArgv = @ARGV;
-use Getopt::Long;
-GetOptions(
- "help!",
- "version!",
- "quiet!",
- "debug!",
- "verbose!",
-) or die $usage;
-!$::opt_help or die $usage;
-if ($::opt_version) {
- print "$prj $date v$version\n";
- exit(0);
-}
-@ARGV == 1 or die "$usage$Error Missing jobname!\n";
-
-$::opt_quiet = 0 if $::opt_verbose;
-
-print $title unless $::opt_quiet;
-
-### get jobname
-$atfifile = $ARGV[0];
-if (!-f $atfifile && -f "$atfifile.atfi") {
- $atfifile .= ".atfi";
-}
--f $atfifile or die "$Error File `$atfifile' not found!\n";
-
-print "* job file = $atfifile\n" if $::opt_verbose;
-
-if ($::opt_debug) {
- print <<"END_DEB";
-* OSNAME: $^O
-* PERL_VERSION: $]
-* ARGV: @OrgArgv
-END_DEB
-}
-
-my $tmpfile = $atfifile . ".tmp";
-
-my $timezone = strftime "%z", localtime;
-
-sub gettz ($) {
- my $time = shift;
- my $tz = strftime "%z", localtime($time);
- return '' unless $tz;
- return 'Z' if $tz eq '+0000';
- $tz =~ s/^([+\-]\d\d)(\d\d)$/$1'$2'/;
- return $tz;
-}
-
-open(IN, $atfifile) or die "$Error Cannot open `$atfifile'!\n";
-open(OUT, ">$tmpfile") or die "$Error Cannot write `$tmpfile'!\n";
-
-while(<IN>) {
- # timezone
- if (s/^(\\attachfile\@timezone\{).*(\})$/$1$timezone$2/) {
- print "* timezone = $timezone\n" if $::opt_verbose;
- }
-
- # file entry
- if (/^\\attachfile\@file\[[^\]]*\]\{(.*)\}$/) {
- my $hexfile = $1;
- my $file = pack('H*', $hexfile);
- my @s = stat($file);
- if (@s == 0) {
- print "!!! Warning: File `$file' not found!\n";
- }
- else {
- my $size = $s[7];
- my $mtime = $s[9];
- my $ctime = $s[10]; # inode change time
-
- my ($sec, $min, $hour, $mday, $mon, $year) =
- localtime($mtime);
- my $moddate = sprintf("%04d%02d%02d%02d%02d%02d",
- $year + 1900, $mon + 1, $mday,
- $hour, $min, $sec);
- my $moddatetz = 'D:' . $moddate . gettz($mtime);
-
- # Manual page "perlport" says that "ctime" is creation
- # time instead of inode change time for "Win32" and
- # "Mac OS", but it is unsupported for "Mac OS X".
- my $creationdate = "";
- my $creationdatetz = "";
- if ($^O eq 'MSWin32') { # cygwin?
- ($sec, $min, $hour, $mday, $mon, $year) =
- localtime($ctime);
- $creationdate = sprintf("%04d%02d%02d%02d%02d%02d",
- $year + 1900, $mon + 1, $mday,
- $hour, $min, $sec);
- $creationdatetz =
- 'D:' . $creationdate . gettz($ctime);
- }
-
- # md5 checksum
- my $checksum = "";
- my $ctx = Digest::MD5->new;
- if (open(FILE, $file)) {
- $ctx->addfile(*FILE);
- $checksum = $ctx->hexdigest;
- close(FILE);
- }
- else {
- print "!!! Warning: File `$file' cannot be read,"
- . " dropping checksum!\n";
- }
-
- $_ = "\\attachfile\@file["
- . "ModDateTZ=$moddatetz"
- . ",Size=$size"
- . ($checksum ? ",CheckSum=$checksum" : "")
- . ($creationdatetz ?
- ",CreationDateTZ=$creationdatetz" :
- ($creationdate ?
- ",CreationDate=$creationdate" : ""))
- . "]{$hexfile}\n";
- if ($::opt_verbose) {
- print "* file entry = $file\n";
- print " size = $size\n";
- print " moddate = $moddate\n";
- print " creationdate = $creationdate\n"
- if $creationdate;
- print " checksum = $checksum\n" if $checksum;
- }
- }
- }
-
- print OUT $_;
-}
-
-close(IN);
-close(OUT);
-
-unlink($atfifile) or die "$Error Cannot delete old `$atfifile'!\n";
-rename $tmpfile, $atfifile
- or die "$Error Cannot move `$tmpfile' to `$atfifile'!\n";
-
-print "*** ready. ***\n" unless $::opt_quiet;
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/authorindex/authorindex b/Build/source/texk/texlive/linked_scripts/authorindex/authorindex
deleted file mode 100644
index 6c154a080e9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/authorindex/authorindex
+++ /dev/null
@@ -1,586 +0,0 @@
-#!/usr/bin/env perl
-# This file is part of the authorindex package for LaTeX + BibTeX.
-# Version: 10. August 2008
-
-use warnings 'all';
-use strict;
-
-# configuration: apart from the command to invoke perl above you might want to
-# change:
-
-my $bstenv="BSTINPUTS"; # Environment Variable holding .bst search path
-my $bibenv="BIBINPUTS"; # Env Variable holding search path for BibTeX databases
-my $tmp="_autidx_"; # Name base for temporary files
-my $cwdpath="."; # Directory where files are generated
-my $pathsep=($^O eq "MSWin32") ? ';' : ":"; # Seperator between paths in a list
-
-# This script takes LaTeX .aux files as input. It extracts all citations made
-# with page number information. These, together with the bibliography data base
-# extracted from the input and a .bst file are processed by bibtex to get a
-# file that associates each citation label with corresponding authors. Together
-# with the knowledge of which work is cited on which page, this is used to
-# compute which author is cited on which page. This information is written to
-# the output in form suitable to be included in a LaTeX document.
-# Alternatively, the script can also extract the label that appears in the
-# references for each work instead of the pages. Also, output for further
-# processing by makeindex can be generated instead of a 'ready' LaTeX file.
-
-# examine command line for options
-
-my %opt; # hash to contain options found
-use Getopt::Std;
-getopts('dhikpr',\%opt);
-
-# handle -h option: a short description of the script.
-
-exists $opt{'h'} && die <<END;
-Usage: $0 [-d] [-h] [-i] [-k] [-p] [-r] [filename ...]
-
--d generate additional statistical information as comments
--i generate file (with extension .ain) suitable as input for makeindex
--k keep auxiliary bibliography style file $tmp.bst after script finishes
--h print this help and exit
--r suppresses automatic inclusion of .aux generated by \\include-ed files
--p send result to standard output
-
-Any number of file names can be given. If none is given, input is read from
-standard input. Otherwise, all files specified are read, after the extension
-.aux has been appended to their name where necessary.
-END
-
-# Make sure that all input files get .aux extension.
-
-grep(s/$/\.aux/,grep(!/\.aux$/,@ARGV));
-my @SAVEARGV=@ARGV;
-
-my $usenum=0; # default: put page numbers into index
-my $PageTypeOrder="rRnAa"; # default order of number types
-my $altedit="'skip\$"; # no editors if no authors present
-my $addedit="'skip\$"; # no editors if authors present
-
-my $citationcount=0; # used for statistics
-my $workscount=0;
-my $explicits=0;
-my $authorcount=0;
-
-my $miniindex=0; # flag: is 1 if mini-index is requested
-my $nocompress=0; # flag: is 1 if page range compression is prohibited
-
-my @bib; # collect .bib-file names
-my %biboccured; # collect .bib-file names
-my %pnlist; # collect occuring pages/bib.numbers as keys of hash
-
-my $editors=0; # number: 0 no editors; 1 editors if no authors
- # 2: editors whenever present
-my $nameformat=""; # string to format/sort names
-my $maxnames=999; # max. number of author names per entry
-my $truncnames=999; # how many authors to take if max number is exceeded
-my $labeltype="labels"; # wether bibliography labels or pages are indexed
-
-my %Lab2Pag; # for each label gives array of pages where work cited
-my %Lab2Num; # for each label give its bibliography number
-my %Lab2Bib; # ditto, but for occurrence in bibliography
-my %Aut2Pag; # for each author gives array of pages cited/in bilio.
-my %Aut2Bib; # ditto, but only occurrence in bibliography
-my %Aut2Lab; # list of BibTeX entry labels an author occurs in
-my %Aut2First; # list of all 1st authors to which author was coauthor
-my %LeadAutPag; # author -> hash marking pages with work author is 1st
-
-my %printname; # sort-key -> printed representation of author
-my %plainname; # sort-key -> author name
-
-my %PageTypeOrder; # Page type code -> number giving relative order
-my %PageOrder; # page string -> array used to sort pages
-
-my $see=""; # string to separate other and first author, or undef.
-my $bst=""; # name of BibTeX program to extract author names
-my $output=""; # name of file to which author index is written
-my $twoabbrev=""; # string to append to page for 2 subsequent pages
-my $also=""; # string to cross-refer to first authors
-my $alsosep=""; # seperator for referenced first authors
-
-my $useaibibcite; # flag: watch for \aibibcite, but not for \bibcite.
-
-# scan input files and
-# - build the file later to be processed by BibTeX,
-# - generate a temporary bibtex database of the explicit author names given,
-# - assemble for each citation the page where it was referenced and
-# - look for data base specification, output file name, and so on.
-
-open(AUXFILE,">$tmp.aux") || die "Can't open temporary file $tmp.aux\n";
-open(BIBFILE,">$tmp.bib") || die "Can't open temporary file $tmp.bib\n";
-
-while(<>){
- if(/^\\citationpage\{\s*([^{ ]+)\s*\}\{(.+)\}$/){
- $citationcount++; # used for statistics only.
- $workscount++ unless ($1 eq '*') or (exists $Lab2Pag{$1})
- or (exists $Lab2Bib{$1}) or (exists $Lab2Num{$1});
- $pnlist{$2}="";
- push @{$Lab2Pag{$1}},$2;
- print AUXFILE "\\citation{$1}\n";
- }elsif(/^\\aibibcite\{([^{]+)\}\{(.+)\}$/){
- $workscount++ unless ($1 eq '*') or (exists $Lab2Pag{$1})
- or (exists $Lab2Bib{$1}) or (exists $Lab2Num{$1});
- $pnlist{$2}="";
- push @{$Lab2Num{$1}},$2;
- print AUXFILE "\\citation{$1}\n" if $usenum;
- # using \aibibcite implies we want to ignore \bibcite. For this to
- # work, in the .aux files, the first \aibibcite must appear before any
- # \bibcite.
- $useaibibcite="yes";
- }elsif(/^\\bibcite\{([^{]+)\}\{(.+)\}$/){
- unless($useaibibcite){
- $workscount++ unless ($1 eq '*') or (exists $Lab2Pag{$1})
- or (exists $Lab2Bib{$1}) or (exists $Lab2Num{$1});
- $pnlist{$2}="";
- push @{$Lab2Num{$1}},$2;
- print AUXFILE "\\citation{$1}\n" if $usenum;
- }
- }elsif(/^\\bibpage\{([^{]+)\}\{(.+)\}$/){
- $workscount++ unless (exists $Lab2Pag{$1})
- or (exists $Lab2Bib{$1}) or (exists $Lab2Num{$1});
- $pnlist{$2}="";
- push @{$Lab2Bib{$1}},$2;
- print AUXFILE "\\citation{$1}\n";
- }elsif(/^\\aiexplicit\{(.+)\}\{(.+)\}$/ and !$usenum){
- # above: page number might not contain '}{'
- print BIBFILE "\@MISC{$tmp$explicits,author=\"$1\"}\n";
- $pnlist{$2}="";
- push @{$Lab2Pag{"$tmp$explicits"}},$2;
- print AUXFILE "\\citation{$tmp$explicits}\n";
- $explicits++;
- }elsif(/^\\bibdata\{(.+)\}$/){
- # keep the order of data base files, but remove duplicates;
- # BibTeX complains about them.
- my $bibdb;
- for $bibdb (split(",",$1)){
- push @bib, $bibdb unless $biboccured{$bibdb};
- $biboccured{$bibdb}=1;
- }
- }elsif(/^\\aistyle\{(.+)\}$/){
- warn "Multiple \\authorindexstyle\n" if $bst && ($bst ne $1);
- $bst=$1;
- }elsif(/^\\aioptions\{(.*)\}$/){
- ($editors,$nameformat,$maxnames,$truncnames,$labeltype)=split /\|/,$1;
- $usenum|=($labeltype eq "labels");
- if($editors>0){
- $altedit="{ peditor format }";
- $addedit=$altedit if $editors==2;
- }
- }elsif(/^\\aifilename\{(.+)\}$/){
- warn "Warning: Multiple authorindices\n" if $output;
- $output=$1;
- }elsif(/^\\\@input\{(.+)\}$/){
- push(@ARGV,$1) unless exists $opt{'r'};
- }elsif(/^\\pagetypeorder\{([rRaAn]+)\}$/){
- $PageTypeOrder=$1;
- }elsif(/^\\aiseestring\{(.+)\}$/){
- $see=$1;
- }elsif(/^\\aialsostrings\{(.+)\}\{(.+)\}$/){
- $also=$1;
- $alsosep=$2;
- }elsif(/^\\aitwostring\{(.+)\}$/){
- $twoabbrev=$1;
- }elsif(/^\\aiinbibflag$/){
- $miniindex=1;
- }elsif(/^\\ainocompressflag$/){
- $nocompress=1;
- }
-}
-
-close BIBFILE;
-
-# output can go to stdout or a filename found in the input files.
-
-$output || die "You have to include .aux file produced by .tex file containing \\begin{document}\nin the argument list and you have to \\usepackage{authorindex}!\n";
-$output="-" if exists $opt{'p'};
-
-# We need at least one BibTeX database
-
-push @bib, $tmp if($explicits);
-
-my $bibfiles=join(",",@bib)
- || die "You must specify at least one BibTeX database\n";
-print AUXFILE "\\bibdata{$bibfiles}\n";
-
-$see && $also && die "\\aisee and \\aialso are mutually exlusive!\n";
-
-# if the user hasn't explicitly given a .bst style for formatting author names,
-# we generate our own based on the style options found in the input files.
-
-unless($bst){
- my @nameformat=split /;/,$nameformat;
- my ($printkey,$namefmtcmd)=("cite\$ write\$ termline\n","");
- for (@nameformat){
- my ($namerep,$sortrep)=split /:/;
- $sortrep=$namerep unless $sortrep;
- $namefmtcmd.=
- "duplicate\$ names swap\$ \"$namerep\" format.name\$ " .
- "write\$ termline\n" .
- "duplicate\$ names swap\$ \"$sortrep\" format.name\$ " .
- "purify\$ \"u\" change.case\$ write\$ termline\n$printkey";
- $printkey="termline\n";
- }
-
- $ENV{$bstenv}="$cwdpath$pathsep" . (exists $ENV{$bstenv} ? $ENV{$bstenv} : "");
- $bst=$tmp;
- open(BSTFILE,">$bst.bst") || die "Can't open $bst.bst\n";
- print BSTFILE <<END; # Now comes the BibTeX programm inlined...
-% Temporary file generated by $0
-entry{author editor authauthor autheditor}{}{}
-strings{names} integers{numnames}
-function{prefersecond} % return second argument if non-empty
-{ duplicate\$ empty\$ % return first argument otherwise
- 'skip\$ %'
- { swap\$ }
- if\$
- pop\$
-}
-function{pauthor}{ author authauthor prefersecond }
-function{peditor}{ editor autheditor prefersecond }
-function{termline}{ newline\$ "%" write\$ newline\$ }
-function{format}
-{ duplicate\$ empty\$ % field present?
- { pop\$ } % no: do nothing but cleanup
- { duplicate\$ 'names := %'memorise namelist in variable "names"
- num.names\$ duplicate\$
- #$maxnames > % too many names in list?
- { pop\$ #$truncnames } % yes, truncate.
- 'skip\$ %' no, keep them all
- if\$
- 'numnames := %'save number of names
- #0 % start index
- { duplicate\$ numnames < } % test for "while\$"
- { #1 + % next name
- duplicate\$ names swap\$ % get name list and index
- "{ll}" format.name\$ % format curr. name
- "others" = % et al part?
- 'skip\$ %' yes, do not output
- { $namefmtcmd } % no: format all
- if\$
- } while\$ pop\$ % loop until index is 0
- }
- if\$
-}
-function{default.type}{pauthor format pauthor empty\$ $altedit $addedit if\$ }
-function{article}{default.type} function{book}{default.type}
-function{booklet}{default.type} function{inbook}{default.type}
-function{incollection}{default.type} function{inproceedings}{default.type}
-function{conference}{default.type} function{manual}{default.type}
-function{mastersthesis}{default.type} function{misc}{default.type}
-function{phdthesis}{default.type} function{proceedings}{default.type}
-function{techreport}{default.type} function{unpublished}{default.type}
-read iterate{call.type\$}
-END
- # ... and here comes perl again.
- close BSTFILE;
-}
-
-# Now we have decided on our .bst file and can finish the temporary .aux file
-# we prepared for BibTeX.
-
-print AUXFILE "\\bibstyle{$bst}\n";
-close AUXFILE;
-
-# if we have written to the temporary database, make sure BibTeX can find it.
-
-$ENV{$bibenv}="$cwdpath$pathsep" . (exists $ENV{$bibenv} ? $ENV{$bibenv} : "") if $explicits;
-
-# We now give BibTeX all the citation labels. In return we get a file whose
-# lines in turn contain an author name and a label of a work of that author.
-# The format the author names are given are determined by the BibTeX style file
-# $bst.bst.
-
-print STDERR `bibtex $tmp`;
-die "BibTeX error. Aborting leaving all temporary files $tmp.*\n" if $?;
-
-# if things went well, we can delete all these temporary files made for BibTeX.
-# The generated .bst file is kept if the user wishes so (-k option).
-
-unlink "$bst.bst" if ($bst eq $tmp && !(exists $opt{'k'}));
-unlink "$tmp.aux","$tmp.bib";
-
-# Decide wether pages or citation labels go to the index
-
-my %Lab2Ent=%Lab2Pag;
-if($usenum){
- %Lab2Ent=%Lab2Num;
- %Lab2Bib=();
-}else{
- %Lab2Num=();
-}
-
-# We have now labels associated with page numbers and labels associated with
-# author names (in the file generated by the BibTeX run). Now we can bring
-# together the previous two main steps and compute for each author the pages
-# where she is cited. In draft mode, we also remember for each author the
-# labels of her works and the pages where these works are cited.
-
-my ($firstauthor,$firstsortname,$Lab,$PrevLab)=("","","","");
-open(BIBFILE,"$tmp.bbl") || die "Can't open $tmp.bbl\n";
-my $author;
-while($author=&readtosep()){
- map s/[\[\]]//g, $author;
- my $sortname=&readtosep();
- my $LabOrEmpty=&readtosep();
- if($LabOrEmpty){
- $PrevLab=$Lab;
- $Lab=$LabOrEmpty;
- }
- my $printname=$author;
- if($Lab ne $PrevLab){
- @{$LeadAutPag{$author}}{@{$Lab2Ent{$Lab}}}="" if exists $Lab2Ent{$Lab};
- @{$LeadAutPag{$author}}{@{$Lab2Ent{'*'}}}="" if exists $Lab2Ent{'*'};
- @{$LeadAutPag{$author}}{@{$Lab2Bib{$Lab}}}="" if exists $Lab2Bib{$Lab};
- $firstauthor=$author;
- $firstsortname=$sortname;
- }else{
- ${$Aut2First{$sortname}}{$firstsortname}="";
- if($see){
- $printname="{$author}$see\\aifirst{$firstauthor}";
- $sortname="$sortname$see$firstsortname";
- }
- }
- @{$Aut2Pag{$printname}}{@{$Lab2Ent{$Lab}}}="" if exists $Lab2Ent{$Lab};
- @{$Aut2Pag{$printname}}{@{$Lab2Ent{'*'}}}="" if exists $Lab2Ent{'*'};
- @{$Aut2Pag{$printname}}{@{$Lab2Bib{$Lab}}}="" if exists $Lab2Bib{$Lab};
- @{$Aut2Bib{$printname}}{@{$Lab2Bib{$Lab}}}="" if exists $Lab2Bib{$Lab};
- push @{$Aut2Lab{$printname}},$Lab if (exists $opt{'d'}) and $LabOrEmpty;
- $printname{$sortname}=$printname;
- $plainname{$sortname}=$author;
-}
-close BIBFILE;
-unlink "$tmp.blg","$tmp.bbl";
-
-# Last not least, output the results, properly sorted if needed.
-
-open(AIFILE,">$output") || die "Can't create author index file $output\n";
-
-# convert page type order into numerical values
-my ($i,$page);
-$PageTypeOrder{$i}=length($PageTypeOrder) while($i=chop $PageTypeOrder);
-# create table that relates page to page order info
-for $page (keys %pnlist){
- $PageOrder{$page}=&parse_pagenumber($page);
-}
-
-if($also){
- my $coauthorname;
- for $coauthorname (keys %Aut2First){
- my @namelist;
- my $sortname;
- for $sortname (sort keys %{$Aut2First{$coauthorname}}){
- push @namelist, $printname{$sortname};
- }
- # we rely on the fact that " " is alphabetically first, so that
- # $justbehind will end up directly after $coauthorname
- my $justbehind=$coauthorname." ";
- my $pseudoname=$also.join($alsosep, @namelist);
- $printname{$justbehind}=$pseudoname;
- $plainname{$justbehind}=$pseudoname;
- }
-}
-
-if(exists $opt{'i'}){
- # generate file for makeindex: leave the work for makeindex.
- my $name;
- for $name (keys %printname){
- my $author=$printname{$name};
- my $page;
- for $page (keys %{$Aut2Pag{$author}}){
- print AIFILE "\\indexentry{$name\@$author}{$page}\n";
- }
- }
-}else{
- # sort result, throw away duplicate page numbers and generate LaTeX file.
- print AIFILE "\\begin{theauthorindex}\n";
- my ($prevfirstchar,$prevplain,$name)=("","","");
- for $name (sort keys %printname){
- my $thisfirstchar=substr($name,0,1);
- if($thisfirstchar ne $prevfirstchar){
- print AIFILE "\\indexspace\n" if $prevfirstchar;
- $prevfirstchar=$thisfirstchar;
- }
- my $author=$printname{$name};
- my $plain=$plainname{$name};
- my $rep=$author;
- if($Aut2Lab{$author}){
- print AIFILE "% @{$Aut2Lab{$author}}\n" if(exists $opt{'d'});
- $rep=($plain eq $prevplain) ? "\\airep$author" : "\\aitop$author"
- if $plain ne $author;
- $prevplain=$plain;
- $authorcount++;
- }
- print AIFILE "\\item[$rep]";
- $Aut2Bib{$author}={} unless exists $Aut2Bib{$author};
- $LeadAutPag{$author}={} unless exists $LeadAutPag{$author};
- my %b2p=%{$Aut2Bib{$author}};
- my %lp=%{$LeadAutPag{$author}};
- my %pagerep;
- my $page;
- for $page (keys %{$Aut2Pag{$author}}){
- my $prep=$page;
- $prep="\\aifirstpage{$prep}" if exists $lp{$page};
- $prep="\\aibibpage{$prep}" if exists $b2p{$page};
- $pagerep{$page}=$prep;
- }
- my $res=&compressed_pages($Aut2Pag{$author},\%pagerep);
- print AIFILE " \\aipages{$res}\n";
- }
- print AIFILE "\\end{theauthorindex}\n";
- if(exists $opt{'d'}){ # in draft mode, include some statistics
- print AIFILE "%\n% $citationcount citations ";
- print AIFILE "of $workscount distinct works\n";
- print AIFILE "% $explicits times \\aimention\n" if $explicits;
- print AIFILE "% $authorcount different authors\n";
- }
-}
-close AIFILE;
-
-# merge mini indices into the .bbl-Files if it was requested.
-
-if($miniindex){
- map s/aux$/bbl/,@SAVEARGV;
- my $file;
- for $file (@SAVEARGV){
- open(BBLINPUT,$file) || next;
- open(BBLHELP,">$tmp.bbl") || die "Can't create temp file $tmp.bbl\n";
- my $currlabel="";
- while(<BBLINPUT>){
- if(/\\bibitem(\[.*\])*\{(.*)\}|\\end\{thebibliography\}/){
- if($currlabel){
- my $pagelist=&pages_for_label($currlabel);
- print BBLHELP "\\bibindex{$pagelist}\n";
- }
- $currlabel=$2;
- print BBLHELP "$_";
- }elsif(/\\bibindex\{(.*)\}/){
- if($currlabel){
- my $pagelist=&pages_for_label($currlabel);
- print BBLHELP "$`\\bibindex{$pagelist}$'";
- }
- $currlabel="";
- }else{
- print BBLHELP "$_" if "$_" ne "\n";
- }
- }
- close BBLHELP;
- close BBLINPUT;
- rename "$tmp.bbl","$file" || die "Can't replace old $file\n";
- }
-}
-
-# auxiliary functions
-
-# convert roman numeral string to integer
-
-sub romanvalue
-{
- local($_)=shift; tr/IVXLCDM/ivxlcdm/;
- my %romandigits = ("i", 1, "v", 5, "x", 10, "l", 50,
- "c", 100, "d", 500, "m", 1000);
- my ($i,$sum,$prev)=("",0,1);
- while($i=chop){
- my $this=$romandigits{$i};
- $sum=$sum+(($this<$prev) ? -$this : $this);
- $prev=$this;
- }
- return $sum;
-}
-
-# convert letter to numeric value
-
-sub alphavalue
-{
- local($_)=@_; tr/A-Z/a-z/;
- return ord($_)-ord("a");
-}
-
-# split page number in components and replace each component by a number for
-# the page type and the page number as an integer.
-
-sub parse_pagenumber
-{
- local($_)=@_;
- my $res="";
- while($_){
- s/^[^\\A-Za-z0-9]*//;
- if(exists $PageTypeOrder{'n'} && s/(^\d+)//){
- $res.="$PageTypeOrder{'n'}".sprintf "%0.6d",$1;
- }elsif(exists $PageTypeOrder{'R'} &&
- s/^\\uppercase\s*\{([ivxlcdm]+)\}//){
- $res.="$PageTypeOrder{'R'}".sprintf "%0.4d",&romanvalue($1);
- }elsif(exists $PageTypeOrder{'R'} && s/(^[IVXLCDM]+)//){
- $res.="$PageTypeOrder{'R'}".sprintf "%0.4d",&romanvalue($1);
- }elsif(exists $PageTypeOrder{'A'} && s/(^[A-Z])//){
- $res.="$PageTypeOrder{'A'}".sprintf "%0.2d",&alphavalue($1);
- }elsif(exists $PageTypeOrder{'r'} && s/(^[ivxlcdm]+)//){
- $res.="$PageTypeOrder{'r'}".sprintf "%0.4d",&romanvalue($1);
- }elsif(exists $PageTypeOrder{'a'} && s/(^[a-z])//){
- $res.="$PageTypeOrder{'a'}".sprintf "%0.2d",&alphavalue($1);
- }else{
- s/^.//;
- }
- }
- return $res;
-}
-
-# test wether 2 pages are subsequent
-
-sub a_follows_b
-{
- my ($i,$j)=@PageOrder{@_};
- $i++;
- return($i eq $j);
-}
-
-# make a sorted, maybe compressed, list of pages
-
-sub compressed_pages
-{
- my ($A,$B)=@_;
- my %pages=%{$A};
- my %pagerep=%{$B};
- my ($prevpage,$pendrep,$res,$pagepending,$page)=("","","","","");
- for $page (sort { $PageOrder{$a} cmp $PageOrder{$b} } keys %pages){
- # handle compression of page ranges. At the moment, we
- # also compress ranges that might be displayed in different faces
- my $pagerep=(exists $pagerep{$page}) ? $pagerep{$page} : $page;
- if($prevpage){
- if(!$nocompress and &a_follows_b($prevpage,$page)){
- $pendrep=$pagepending ? "--$pagerep"
- : ($twoabbrev ? "$twoabbrev" : ", $pagerep");
- $pagepending=1;
- }else{
- $res.=($pagepending ? "$pendrep" : "").", $pagerep";
- $pagepending=0;
- }
- }else{
- $res.="$pagerep";
- }
- $prevpage=$page;
- }
- $res.="$pendrep" if $pagepending;
- return $res;
-}
-
-sub pages_for_label
-{
- my ($label)=@_;
- if(exists $Lab2Pag{$label}){
- my (%pages,%empty);
- @pages{@{$Lab2Pag{$label}}}="";
- return &compressed_pages(\%pages,\%empty);
- }
- return "";
-}
-
-sub readtosep
-{
- my $sum="";
- while(<BIBFILE>){
- return $sum if(/^%$/);
- chop; s/%$//;
- $sum.=$_;
- }
-}
diff --git a/Build/source/texk/texlive/linked_scripts/bib2gls/bib2gls.sh b/Build/source/texk/texlive/linked_scripts/bib2gls/bib2gls.sh
deleted file mode 100755
index 2e720ffb545..00000000000
--- a/Build/source/texk/texlive/linked_scripts/bib2gls/bib2gls.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-# Adapted from tlcockpit.sh to ensure the script works with cygwin
-
-scriptname=`basename "$0" .sh`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-# User may have globally set their locale provider preference in
-# $JAVA_TOOL_OPTIONS so don't override it.
-
-if [ -z "$JAVA_TOOL_OPTIONS" ]; then
- exec java -Djava.locale.providers=CLDR,JRE,SPI -jar "$jarpath" "$@"
-else
- exec java -jar "$jarpath" "$@"
-fi
diff --git a/Build/source/texk/texlive/linked_scripts/bib2gls/convertgls2bib.sh b/Build/source/texk/texlive/linked_scripts/bib2gls/convertgls2bib.sh
deleted file mode 100755
index f237f505d5c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/bib2gls/convertgls2bib.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-# Adapted from tlcockpit.sh to ensure the script works with cygwin
-
-scriptname=`basename "$0" .sh`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-exec java -jar "$jarpath" "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/bibexport/bibexport.sh b/Build/source/texk/texlive/linked_scripts/bibexport/bibexport.sh
deleted file mode 100755
index 9358b423ea8..00000000000
--- a/Build/source/texk/texlive/linked_scripts/bibexport/bibexport.sh
+++ /dev/null
@@ -1,350 +0,0 @@
-#!/bin/bash
-##
-## This is file `bibexport.sh',
-## generated with the docstrip utility.
-##
-## The original source files were:
-##
-## bibexport.dtx (with options: `script')
-##
-## (c) 2019/03/30 Nicolas Markey <bibexport at markey dot fr>
-##
-## This work may be distributed and/or modified under the conditions of
-## the LaTeX Project Public License, either version 1.3 of this license
-## or (at your option) any later version. The latest version of this
-## license is in
-##
-## http://www.latex-project.org/lppl.txt
-##
-## and version 1.3 or later is part of all distributions of LaTeX version
-## 2005/12/01 or later.
-##
-## This work has the LPPL maintenance status `maintained'.
-## The Current Maintainer of this work is Nicolas Markey.
-##
-## \CharacterTable
-## {Upper-case \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
-## Lower-case \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
-## Digits \0\1\2\3\4\5\6\7\8\9
-## Exclamation \! Double quote \" Hash (number) \#
-## Dollar \$ Percent \% Ampersand \&
-## Acute accent \' Left paren \( Right paren \)
-## Asterisk \* Plus \+ Comma \,
-## Minus \- Point \. Solidus \/
-## Colon \: Semicolon \; Less than \<
-## Equals \= Greater than \> Question mark \?
-## Commercial at \@ Left bracket \[ Backslash \\
-## Right bracket \] Circumflex \^ Underscore \_
-## Grave accent \` Left brace \{ Vertical bar \|
-## Right brace \} Tilde \~}
-##
-function checkversion()
-{
- kpsewhich expcites.bst > /dev/null ||
- echo "-----------
---Warning-- file expcites.bst not found.
------------"
- grep -q $VDATE `kpsewhich expkeys.bst` ||
- echo "-----------
---Warning-- the version of the .bst files does not match with that of this script.
------------"
-}
-function usage()
-{
-echo "bibexport: a tool to extract BibTeX entries out of .bib files.
-usage: `basename $0` [-h|v|n|c|a|d|s|t] [-b|e|es|ec|o|r file] file...
-
-Basic options:
---------------
- -a, --all export the entire .bib files
- -o bib, --output-file bib write output to file [default: bibexport.bib]
- -ns, --nosave overwrite output file without keeping a copy
- -p, --preamble write a preamble at beginning of output
- -t, --terse operate silently
- -h, --help print this message and exit
- -v, --version print version number and exit
-
-Advanced options:
------------------
- -b bst, --bst bst specifies the .bst style file [default: export.bst]
- -c, --crossref preserve crossref field [default: no]
- -n, --no-crossref remove crossref'd entries [default: no]
- -e bib, --extra bib extra .bib file to be used (crossrefs and strings)
- -es bib, --extras bib extra .bib file to be used (for strings)
- -ec bib, --extrac bib extra .bib file to be used (for crossrefs)
- -r bib, --replace bib replace .bib file(s) in the .aux file
- -d, --debug create intermediate files but don't run BibTeX";
-exit 0;
-}
-function opttoolate()
-{
-if [ ! -z "${TOOLATE}" ]; then
- echo "No options are allowed after the input files";
- exit 0;
-fi
-}
-## Version number
-VERSION="3.03";
-## Release date
-VDATE="2019/03/30";
-
-# ALL is a flag set to 1 when '-a' is given
-ALL="";
-# FILE will be the main input file(s) (.aux or .bib, depending on '-a')
-FILE="";
-# EXT is the extension of the input file(s) (.aux, or .bib if '-a')
-EXT=".aux";
-# EXTRA and EXTRABIB are two copies of the extra files ('-e'), used to
-# include crossref'd entries and @string's
-EXTRA="";
-EXTRABIB="";
-# REPLACEBIB ('-r') is set to 1 when the \bibdata of the .aux input file
-# must be ignores (then '-e' must be used)
-REPLACEBIB="";
-# NEWBIB will contain the argument given to -r
-NEWBIB="";
-# BST is the .bst file to be used (default to export.bst)
-BST="export";
-# TERSE will be set to '-terse' if '-t' is given
-TERSE="";
-# NOSAVE if no need to save file before overwriting it
-NOSAVE=""
-# BANNER is used to turn on or off the preamble informations in the output
-BANNER="";
-# CREF is the number of citations of crossrefs from which the crossref'd entry
-# must be included.
-CREF="0";
-
-# SPACE will be either ' ' or ','
-SPACE="";
-# TOOLATE is used to prevent extra options after the main file
-TOOLATE="";
-# DEBUG is used to create files but not run BibTeX.
-DEBUG="";
-
-ARGS=$@;
-if [ $# -eq 0 ]; then
- usage;
-fi
-checkversion;
-while [ $# != 0 ]; do
- case $1 in
- -a|--all)
- ## - export all entries in the input file(s)
- ## - the input files are BibTeX files
- opttoolate;
- EXT=""; SPACE=""; ALL="a";
- shift ;;
- -b|--bst)
- ## - specifies the .bst file to use (default to 'export.bst')
- opttoolate;
- if [ "`dirname $2`" = "." ]; then
- DOLLARTWO="`basename $2 .bst`";
- else
- DOLLARTWO="`dirname $2`/`basename $2 .bst`";
- fi
- BST="${DOLLARTWO}";
- shift 2;;
- -d|--debug)
- ## - debug mode: we create files but do not run bibtex
- ## - instead, we print what we would have done...
- opttoolate;
- DEBUG="a";
- shift ;;
- -e|--extra)
- ## - extra input files (containing crossrefs or strings)
- ## - they will be included twice: once before the main file(s)
- ## (for @string's), once after (for crossrefs). We fool BibTeX
- ## by naming the first one 'file.bib' and the second one
- ## 'file.bib.bib', to avoid complaints.
- opttoolate;
- if [ "`dirname $2`" = "." ]; then
- DOLLARTWO="`basename $2 .bib`";
- else
- DOLLARTWO="`dirname $2`/`basename $2 .bib`";
- fi
- EXTRA="${EXTRA}${DOLLARTWO},";
- EXTRABIB="${EXTRABIB},${DOLLARTWO}.bib";
- shift 2;;
- -es|--extras)
- ## - extra input files (containing strings)
- ## - will be included *before* the main files (hence not suitable
- ## for crossrefs)
- opttoolate;
- if [ "`dirname $2`" = "." ]; then
- DOLLARTWO="`basename $2 .bib`";
- else
- DOLLARTWO="`dirname $2`/`basename $2 .bib`";
- fi
- EXTRA="${EXTRA}${DOLLARTWO},";
- shift 2;;
- -ec|--extrac)
- ## - extra input files (containing crossrefs)
- ## - will be included only *after* the main files (hence not
- ## suitable for @string's)
- opttoolate;
- if [ "`dirname $2`" = "." ]; then
- DOLLARTWO="`basename $2 .bib`";
- else
- DOLLARTWO="`dirname $2`/`basename $2 .bib`";
- fi
- EXTRABIB="${EXTRABIB},${DOLLARTWO}.bib";
- shift 2;;
- -o|--output-file)
- ## - name of the output file
- ## - we force it to end with '.bib'
- opttoolate;
- if [ "`dirname $2`" = "." ]; then
- DOLLARTWO="`basename $2 .bib`";
- else
- DOLLARTWO="`dirname $2`/`basename $2 .bib`";
- fi
- OUTPUT="${DOLLARTWO}.bib";
- shift 2 ;;
- -c|--crossref|--crossrefs|--with-crossref|--with-crossrefs)
- ## - whether or not to preserve 'crossref' keys.
- ## - by default, they are removed, but crossref'd entries are
- ## included.
- ## - crossrefs are *always* expanded anyway.
- opttoolate;
- CREF="1" ;
- shift ;;
- -n|--no-crossref|--without-crossref|--no-crossrefs|--without-crossrefs)
- ## - to remove crossref'd entries (hence remove 'crossref' keys).
- opttoolate;
- CREF="20000" ;
- shift ;;
- -r|--replace)
- ## - to replace the file(s) given in \bibdata in the .aux file with
- ## (a) new one(s).
- opttoolate;
- REPLACEBIB="a";
- if [ "`dirname $2`" = "." ]; then
- DOLLARTWO="`basename $2 .bib`";
- else
- DOLLARTWO="`dirname $2`/`basename $2 .bib`";
- fi
- NEWBIB="${NEWBIB}${DOLLARTWO}.bib,";
- shift 2;;
- -v|--version)
- echo "This is bibexport v${VERSION} (released ${VDATE})"; exit 0;;
- -ns|--nosave|--no-save)
- NOSAVE="a";
- shift ;;
- -p|--preamble|--with-preamble)
- BANNER="a";
- shift ;;
- -t|--terse|--silent)
- TERSE=" -terse ";
- shift ;;
- -*)
- usage;;
- *)
- ## - list of input files
- ## - we ensure that no extra option is given later...
- TOOLATE="a";
- if [ "`dirname $1`" = "." ]; then
- DOLLARONE="`basename $1 ${EXT}`";
- else
- DOLLARONE="`dirname $1`/`basename $1 ${EXT}`";
- fi
- FILE="${FILE}${SPACE}${DOLLARONE}${EXT}";
- if [ -z "${ALL}" ]; then
- SPACE=" ";
- else
- SPACE=",";
- fi;
- shift;;
- esac
-done
-FINALFILE=${OUTPUT};
-if [ ! "${FINALFILE}" ]; then
- FINALFILE="bibexport.bib";
-fi
-TMPFILE="bibexp.`date +%s`";
-if [ -z "${EXT}" ]; then ## we export all entries
- if [ -z "${EXTRA}" ]; then ## we have no extra files
- cat > ${TMPFILE}.aux <<EOF
-\citation{*}
-\bibdata{${FILE}}
-\bibstyle{${BST}}
-EOF
- else ## we have extra files (e.g. for crossrefs) but want all entries from ${FILE}
- ## we first extract the keys to be used:
- cat > ${TMPFILE}.aux <<EOF
-\citation{*}
-\bibdata{${FILE}}
-\bibstyle{expkeys}
-EOF
- ## This run may generate errors. We redirect the output:
- bibtex -min-crossrefs=${CREF} -terse ${TMPFILE} >/dev/null 2>&1;
- mv -f ${TMPFILE}.bbl ${TMPFILE}.aux;
- ## and then prepare the .aux file for exporting:
- cat >> ${TMPFILE}.aux <<EOF
-\bibdata{${EXTRA}${FILE}${EXTRABIB}}
-\bibstyle{${BST}}
-EOF
- fi
-else ## we only export entries listed in the given .aux file:
- if [ -z "${REPLACEBIB}" ]; then
- cat ${FILE} | sed -e "s/bibstyle{.*}/bibstyle{${BST}}/" > ${TMPFILE}.aux;
- else
- cat ${FILE} | sed -e "s/bibstyle{.*}/bibstyle{${BST}}/" \
- -e "s|bibdata{.*}|bibdata{${EXTRA}${NEWBIB%,}${EXTRABIB}}|" > ${TMPFILE}.aux;
- fi
-fi
-if [ -z "$DEBUG" ]; then
- bibtex -min-crossrefs=${CREF} ${TERSE} ${TMPFILE};
- if [ -e ${FINALFILE} ] && [ -z "${NOSAVE}" ]; then
- mv ${FINALFILE} ${FINALFILE}-save-`date "+%Y.%m.%d:%H.%M.%S"`
- fi
- echo "" > ${FINALFILE}
-else
- echo "bibtex -min-crossrefs=${CREF} ${TERSE} ${TMPFILE};"
- if [ -e ${FINALFILE} ] && [ -z "${NOSAVE}" ]; then
- echo "mv ${FINALFILE} ${FINALFILE}-save-`date \"+%Y.%m.%d:%H.%M.%S\"`"
- fi
- echo "echo \"\" > ${FINALFILE}"
-fi
-if [ ! -z "${BANNER}" ]; then
- ## list of cited entries
- if [ -z "$DEBUG" ]; then
- sed -i -e "s/\\\bibstyle{.*}/\\\bibstyle{expcites}/" ${TMPFILE}.aux
- mv ${TMPFILE}.aux ${TMPFILE}-cites.aux
- bibtex -terse -min-crossrefs=${CREF} ${TMPFILE}-cites
- echo -ne "@comment{generated using bibexport:\n" >> ${FINALFILE};
- echo -ne " creation date:\t`date +\"%c\"`\n" >> ${FINALFILE};
- echo -ne " command:\t\t`basename $0` ${ARGS}\n" >> ${FINALFILE};
- if [ -z "${EXT}" ]; then
- echo -ne " source files:\t\t${FILETAB}\t\t\t${EXTRABIBTAB}\n" >> ${FINALFILE}; \
- fi
- cat ${TMPFILE}-cites.bbl >> ${FINALFILE};
- #echo -ne " bibexport-version:\tv${VERSION} (${VDATE})\n" >> ${FINALFILE};
- #echo -ne " bibexport-maintainer:\tNicolas Markey <bibexport(at)markey.fr>\n" >> ${FINALFILE};
- sed -i -e "s/}/)/g" ${FINALFILE};
- echo -n -e "}\n\n\n" >> ${FINALFILE};
- rm -f ${TMPFILE}-cites.bbl ${TMPFILE}-cites.aux ${TMPFILE}-cites.blg
- fi
-fi
-if [ ${CREF} -ne 1 ]; then
- if [ -z "$DEBUG" ]; then
- egrep -iv '^ *crossref *= *[^,]+,?$' \
- ${TMPFILE}.bbl >> ${FINALFILE};
- else
- echo "egrep -iv '^ *crossref *= *[^,]+,?$' ${TMPFILE}.bbl >> ${FINALFILE};"
- fi
-else
- if [ -z "$DEBUG" ]; then
- cat ${TMPFILE}.bbl >> ${FINALFILE};
- else
- echo "cat ${TMPFILE}.bbl >> ${FINALFILE};"
- fi
-fi
-if [ -z "$DEBUG" ]; then
- rm -f ${TMPFILE}.bbl ${TMPFILE}.aux ${TMPFILE}.blg;
-else
- echo "rm -f ${TMPFILE}.bbl ${TMPFILE}.aux ${TMPFILE}.blg";
-fi
-##
-##
-## End of file `bibexport.sh'.
diff --git a/Build/source/texk/texlive/linked_scripts/bundledoc/arlatex b/Build/source/texk/texlive/linked_scripts/bundledoc/arlatex
deleted file mode 100755
index 9a50f030486..00000000000
--- a/Build/source/texk/texlive/linked_scripts/bundledoc/arlatex
+++ /dev/null
@@ -1,288 +0,0 @@
-#! /usr/bin/env perl
-
-###################################################
-# Combine a bunch of ancillary files into a LaTeX #
-# document using the filecontents* environment. #
-# #
-# By Scott Pakin <scott+bdoc@pakin.org> #
-###################################################
-
-########################################################################
-# arlatex #
-# Copyright (C) 2018 Scott Pakin #
-# #
-# This program may be distributed and/or modified under the conditions #
-# of the LaTeX Project Public License, either version 1.3c of this #
-# license or (at your option) any later version. #
-# #
-# The latest version of this license is in: #
-# #
-# http://www.latex-project.org/lppl.txt #
-# #
-# and version 1.3c or later is part of all distributions of LaTeX #
-# version 2008/05/04 or later. #
-# #
-# This program consists of the file bundledoc and all the files listed #
-# in the Files section of the associated README file. #
-########################################################################
-
-use 5.006; # Fail gracefully if we're not using Perl v5.6.0.
-our $VERSION = "1.03"; # Specify the version of arlatex.
-use Getopt::Long;
-use Pod::Usage;
-use File::Basename;
-use File::Find;
-require File::Spec;
-use strict;
-
-my $progname = basename($0); # Name of this program
-my $latexfile; # Main LaTeX document
-my $outfile = "-"; # Output file (default is standard output)
-my $baseoutfile = "-"; # Base name of output file
-
-######################################################################
-
-# Include a file using the filecontents* environment.
-sub includefile ($)
-{
- my $filename = $_[0];
- my $basefilename = basename $filename;
- next if $basefilename eq $baseoutfile; # Don't let a file overwrite itself.
- $basefilename = "\"$basefilename\"" if $basefilename =~ /\s/ && substr($basefilename, 0, 1) ne '"';
- open (SOMEFILE, "<$filename") || die "${progname}: $! ($filename)\n";
- print OUTFILE "\\begin{filecontents*}{$basefilename}\n";
- print OUTFILE <SOMEFILE>;
- print OUTFILE "\\end{filecontents*}\n";
- close SOMEFILE;
-}
-
-######################################################################
-
-# Parse the command line.
-GetOptions ('version' => sub { print "arlatex $VERSION\n"; exit -1 },
- 'help'=> sub {pod2usage (-exitval => 0, -verbose => 1)},
- 'document=s' => \$latexfile,
- 'outfile=s' => \$outfile) ||
- pod2usage (-exitval => -1, -verbose => 0);
-pod2usage (-exitval => -1, -verbose => 0) if !defined $latexfile;
-if (!-e $latexfile) {
- my $newlatexfile = "$latexfile.tex";
- if (!-e $newlatexfile) {
- die "${progname}: File $latexfile does not exist\n";
- }
- else {
- $latexfile = $newlatexfile;
- }
-}
-$baseoutfile = basename $outfile if $outfile ne "-";
-
-# Read the entire input file.
-open (LATEXFILE, "<$latexfile") || die "${progname}: $! ($latexfile)\n";
-my @entirefile = <LATEXFILE>;
-close LATEXFILE;
-
-# Open the output file, write any initial comments, and then include
-# all of the files specified on the command line using the filecontents*
-# environment. Finally, include the rest of the input file.
-open (OUTFILE, ">$outfile") || die "${progname}: $! ($outfile)\n";
-while ($entirefile[0] =~ /^\s*(\%.*)?$/) {
- print OUTFILE (shift @entirefile);
-}
-print OUTFILE "\\IfFileExists{filecontents.sty}{\\RequirePackage{filecontents}}{}\n";
-my @expandedARGV;
-foreach my $filename (@ARGV) {
- if (-f $filename) {
- push @expandedARGV, $filename;
- }
- else {
- find ({wanted => sub {push @expandedARGV, File::Spec->rel2abs($_) if -f $_},
- follow => 1},
- $filename);
- }
-}
-foreach my $filename (@expandedARGV) {
- includefile ($filename);
- print OUTFILE "\n";
-}
-print OUTFILE @entirefile;
-close OUTFILE;
-exit 0;
-
-######################################################################
-
-=head1 NAME
-
-arlatex - archive a number of ancillary LaTeX files into a master
-F<.tex> file
-
-
-=head1 SYNOPSIS
-
-arlatex
-[B<--outfile>=I<filename>F<.tex>]
-B<--document>=I<filename>F<.tex>
-I<filename>
-...
-
-arlatex
-B<--version>
-
-arlatex
-B<--help>
-
-
-=head1 DESCRIPTION
-
-B<arlatex> is an archiving program like B<shar>, B<tar>, B<zip>, etc.
-Unlike those other archivers, however, B<arlatex> is designed
-specifically for use with LaTeX. B<arlatex> takes the name of a
-master F<.tex> file and a number of ancillary files used by that
-master file (e.g., F<.tex>, F<.sty>, F<.cls>, and F<.eps> files).
-From these, B<arlatex> outputs a single file that, when it's run
-through B<latex>, both regenerates the ancillary files and compiles
-the document into a F<.dvi> file.
-
-B<arlatex> has a few advantages over other archiving programs:
-
-=over 4
-
-=item *
-
-The F<.tex> files produced by B<arlatex> are in a plain-text format.
-They are therefore perfectly portable and trivial to e-mail to
-colleagues.
-
-=item *
-
-B<arlatex> needs only LaTeX to run. There is no dependence on any
-external tools.
-
-=item *
-
-There is no explicit extraction step. As the generated document is
-run through B<latex>, it extracts the ancillary files and builds the
-document in the same step. The user running B<latex> may not even
-notice that additional files are being produced.
-
-=back
-
-B<arlatex> works by writing a number of S<C<\begin{filecontents*}> ...>
-C<\end{filecontents*}> blocks to the output file, followed by the
-contents of the master file. (In fact, any LaTeX comments at the
-beginning of the master file are hoisted to the top of the generated
-file. This enables the author to draw attention, if so desired, to
-the fact that ancillary files will be generated.) The
-C<filecontents*> environment, part of standard LaTeX2e, writes its
-contents verbatim to a specified file.
-
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<--version>
-
-Output the B<arlatex> script's version number.
-
-=item B<--help>
-
-Output brief B<arlatex> usage information.
-
-=item B<--document>=I<.tex file>
-
-Specify the master document. The output from B<arlatex> is this file
-with all of the other files named on the command line prepended to it.
-Note that C<--document> is a I<mandatory> parameter; B<arlatex> will
-abort with an error message if C<--document> is not specified.
-
-=item B<--outfile>=I<.tex file>
-
-Specify the output file. The output file looks just like the master
-document, but with a number of C<filecontents*> environments preceding
-the C<\documentclass> line. If C<--outfile> is not specified, output
-will be written to the standard output device.
-
-=back
-
-
-=head1 EXAMPLES
-
-Suppose you have a paper called F<paper.tex> that loads a custom
-package with C<\usepackage{mypackage}>. You want to submit the paper
-to a conference, but you want to be absolutely certain that
-F<mypackage.sty> doesn't get lost as your paper is shuttled from
-person to person. Here's how B<arlatex> can be of use:
-
- arlatex --document=paper.tex mypackage.sty --outfile=paper-submit.tex
-
-When F<paper-submit.tex> is processed with B<latex>, it builds just
-like the original F<paper.tex>, except that it additionally creates a
-F<mypackage.sty> in the current directory:
-
- This is TeX, Version 3.14159 (Web2C 7.3.1)
- (paper-submit.tex
- LaTeX2e <1999/12/01> patch level 1
- Babel <v3.6Z> and hyphenation patterns for american, french, german,
- ngerman, italian, nohyphenation, loaded.
-
- LaTeX Warning: Writing file `./mypackage.sty'.
-
- (/usr/share/texmf/tex/latex/base/article.cls
- Document Class: article 1999/09/10 v1.4a Standard LaTeX document class
- (/usr/share/texmf/tex/latex/base/size12.clo)) (mypackage.sty)
- .
- .
- .
-
-As another example, here's how you could bundle together all of the
-files needed to build a large document for longevity:
-
- arlatex --document=thesis.tex abstract.tex introduction.tex
- background.tex approach.tex experiments.tex relatedwork.tex
- conclusions.tex before.eps after.eps fast.eps slow.eps
- podunkUthesis.cls --outfile=thesis-all.tex
-
-As the number of files to archive together increases it becomes more
-cumbersome to run B<arlatex> manually. Fortunately, using B<arlatex>
-with B<bundledoc> is straightforward. B<bundledoc> finds all of the
-files needed to build the document, and B<arlatex> combines them into
-a single file. The following are examples of the C<bundle:> line you
-might use in a B<bundledoc> configuration file:
-
-=over 1
-
-=item Unix:
-
- bundle: (arlatex --document=$BDBASE.tex $BDINPUTS \
- --outfile=$BDBASE-all.tex)
-
-=item Windows:
-
- bundle: arlatex --document=%BDBASE%.tex %BDINPUTS% \
- --outfile=%BDBASE%-all.tex
-
-=back
-
-See the B<bundledoc> documentation for more information.
-
-
-=head1 CAVEATS
-
-B<arlatex> makes use of LaTeX2e's C<filecontents*> environment.
-C<filecontents*> refuses to overwrite an existing file. However, it
-also refuses to create a file that exists I<anywhere> that LaTeX can
-find it. That is, if the user running B<latex> on an
-B<arlatex>-generated F<.tex> file already has a
-F</usr/share/texmf/tex/latex/whatever/whatever.sty> file then
-C<filecontents*> will refuse to create a F<whatever.sty> file, even in
-a different directory.
-
-
-=head1 SEE ALSO
-
-bundledoc(1), latex(1), shar(1), tar(1), zip(1)
-
-
-=head1 AUTHOR
-
-Scott Pakin, I<scott+bdoc@pakin.org>
diff --git a/Build/source/texk/texlive/linked_scripts/bundledoc/bundledoc b/Build/source/texk/texlive/linked_scripts/bundledoc/bundledoc
deleted file mode 100755
index 02c7d8e5d93..00000000000
--- a/Build/source/texk/texlive/linked_scripts/bundledoc/bundledoc
+++ /dev/null
@@ -1,905 +0,0 @@
-#! /usr/bin/env perl
-
-##########################################################
-# Bundle all the files needed to build a LaTeX document. #
-# By Scott Pakin <scott+bdoc@pakin.org> #
-##########################################################
-
-########################################################################
-# bundledoc #
-# Copyright (C) 2018-2019 Scott Pakin #
-# #
-# This program may be distributed and/or modified under the conditions #
-# of the LaTeX Project Public License, either version 1.3c of this #
-# license or (at your option) any later version. #
-# #
-# The latest version of this license is in: #
-# #
-# http://www.latex-project.org/lppl.txt #
-# #
-# and version 1.3c or later is part of all distributions of LaTeX #
-# version 2008/05/04 or later. #
-# #
-# This program consists of the file bundledoc and all the files listed #
-# in the Files section of the associated README file. #
-########################################################################
-
-use 5.006; # Fail gracefully if we're not using Perl v5.6.0+.
-our $VERSION = "3.4"; # Specify the version of bundledoc.
-use File::Basename;
-use File::Copy;
-use File::Spec::Functions qw(abs2rel catfile devnull rel2abs rootdir updir);
-use File::Path;
-use File::Temp qw(tempdir);
-use Getopt::Long;
-use Pod::Usage;
-use warnings;
-use strict;
-
-######################################################################
-
-# Variables the user can override with a configuration file
-# DEFAULTS: Linux + kpathsea
-my %uservariable;
-$uservariable{"bundle"} = '(tar -cvf - $BDINPUTS | gzip --best > $BDBASE.tar.gz)';
-$uservariable{"find"} = 'kpsewhich -progname=latex $BDINPUTS';
-$uservariable{"sink"} = '> ' . devnull() . ' 2>&1';
-
-# OS path separator (Is there a better way to get this?)
-my $pathsep = catfile ("", "");
-
-# File that lists original directory names
-my $manifest = "MANIFEST";
-
-# Cleaned-up name of this Perl script
-my $progname = basename($0);
-
-# Other global variables
-my ($verbose, $keepdirs, $depfile, $localonly); # Taken from the command line
-my (@exclude_files, @include_files, @listdeps); # Taken from the command line
-my ($texfile, $docdirname); # Derived from $depfile
-my %subdirs; # Map from a qualified name to its subdirectory
-
-######################################################################
-
-# Find a file in the LaTeX hierarchy and fully qualify it,
-# or abort if we can't.
-sub qualifyname ($)
-{
- my $filename = $_[0];
- $filename = "\"$filename\"" if $filename =~ /\s/ && substr($filename, 0, 1) ne '"';
- my $command = $uservariable{find};
- $command =~ s/[\$\%]BDINPUTS\%?/$filename/g;
- $command =~ s/[\$\%]BDBASE\%?/$ENV{"BDBASE"}/g;
- my $qualified = `$command` ||
- die "${progname}: \"$uservariable{find}\" (BDINPUTS=\"$_[0]\") failed to find $_[0]\n";
- chomp $qualified;
- $qualified = rel2abs $qualified;
- return $qualified;
-}
-
-# Execute a command, and return an error message if it fails.
-sub executecmd ($)
-{
- my $command = ($verbose ? $_[0] : "$_[0] $uservariable{sink}");
- $command =~ s/[\$\%]BDINPUTS\%?/$ENV{"BDINPUTS"}/g;
- $command =~ s/[\$\%]BDBASE\%?/$ENV{"BDBASE"}/g;
- my $retval;
-
- if ($verbose) {
- print "EXECUTING $command WITH BDINPUTS = $ENV{BDINPUTS}\n";
- }
- if ($pathsep eq "\\") {
- # Dirty trick to work around idiotic "\" --> "/" conversion
- $retval = system qq("$command");
- }
- else {
- $retval = system $command;
- }
- die "${progname}: $!. Failing command was:\n\t$command\n" if $retval;
-}
-
-# Append ".dep" to the dependency file if necessary.
-sub find_dependency_file ($)
-{
- my $depfile = $_[0];
-
- # Return the file as is if it exists.
- return $depfile if -e $depfile || $depfile =~ /\.dep$/;
-
- # Return the file with ".dep" appended if that exists.
- return "${depfile}.dep" if -e "${depfile}.dep";
-
- # Give up and return the file as specified.
- return $depfile;
-}
-
-# Try hard to find a configuration file. Return the name of the actual file we
-# located.
-sub find_config_file ($)
-{
- my $configfile = $_[0];
- no warnings; # Don't complain if kpsewhich isn't found.
-
- # Attempt 1: See if the file exists as named.
- return $configfile if -e $configfile;
-
- # Attempt 2: Append ".cfg" if it's not already there.
- my $config_cfg = $configfile;
- if ($config_cfg !~ /\.cfg$/) {
- $config_cfg = "${configfile}.cfg";
- return $config_cfg if -e $config_cfg;
- }
-
- # Attempt 3: Use kpsewhich to find the file with ".cfg" appended. (We
- # don't search for it without ".cfg" because kpsewhich may find a version
- # with ".tex" appended.)
- my $kpfound = `kpsewhich $config_cfg`;
- if (defined $kpfound) {
- chomp $kpfound;
- return $kpfound if -e $kpfound;
- }
-
- # Give up. Return the file name as specified.
- return $configfile;
-}
-
-# Read a configuration file, and set %uservariable accordingly.
-sub process_config_file ($)
-{
- my $configfile = find_config_file $_[0];
- printf("CONFIGURATION FILE: %s\n", rel2abs($configfile)) if $verbose;
- my $prevline = "";
- open (CONFIGFILE, "<", $configfile) || do {
- my $configlist = $configfile;
- if (! -e $configfile) {
- # Error is "file not found". List the files we considered.
- $configlist .= "; also considered ${configfile}.cfg" if $configfile !~ /\.cfg$/;
- }
- die "${progname}: $! ($configlist)\n";
- };
- while (my $oneline=<CONFIGFILE>) {
- # Read a line and trim it.
- chomp $oneline;
- $oneline =~ s/^\s+//;
- $oneline =~ s/\s+$//;
-
- # Determine if we should process the line now, later, or never.
- next if $oneline =~ /^\#.*$/; # Discard comments.
- if ($oneline =~ m|^(.*)\\$|) { # Handle line continuations.
- $prevline .= $1;
- next;
- }
- $oneline = $prevline . $oneline;
- $prevline = "";
- next if $oneline =~ /^\s*$/; # Discard blank lines.
-
- # Parse the line.
- $oneline =~ /^(\w+)\s*:\s*(.*)$/;
- $uservariable{lc($1)} = $2;
- }
- close CONFIGFILE;
-}
-
-# Find all dependencies listed in the input file.
-sub find_dependencies ()
-{
- open (DEPFILE, "<$depfile") || die "${progname}: $! ($depfile)\n";
- my $braced = "\\{([^\\}]*)\\}"; # Regular expression for a braced name
- my @dependencies; # List of fully-qualified filenames
- @dependencies = qualifyname $texfile;
- while (my $oneline=<DEPFILE>) {
- # Parse an input line into its component fields.
- next if !($oneline =~ /^\s*\*$braced\s*$braced\s*$braced\s*$/);
- my $filetype = $1;
- my $filename = $2;
- my $versioninfo = $3;
-
- # Extract the subdirectory if one exists.
- my $subdir = dirname $filename;
- my $qname = "";
-
- # Determine what to do based on the file type.
- # NOTE: The PROCESSDEP block currently ignores the following
- # file types:
- #
- # * application
- # * tfm
- # * format
- PROCESSDEP:
- {
- $filetype eq "package" && do {
- $qname = qualifyname("$filename.sty");
- last PROCESSDEP;
- };
- $filetype eq "class" && do {
- $qname = qualifyname("$filename.cls");
- last PROCESSDEP;
- };
- $filetype eq "file" && do {
- $qname = qualifyname("$filename");
- last PROCESSDEP;
- };
- }
-
- # If the file is of one of the above types, add the qualified
- # name to the list of dependencies. In addition, if it is in
- # a proper subdirectory, add an entry to the subdirs hash.
- unless ($qname eq "") {
- push @dependencies, $qname;
- $subdirs{$qname} = $subdir unless $subdir eq ".";
- }
- }
- close DEPFILE;
- @dependencies = sort @dependencies;
-
- # If --localonly was specified, discard dependencies that are not
- # in the same directory as the .tex file (or a subdirectory
- # thereof).
- if ($localonly) {
- my @newdeps;
- my $texdir = dirname qualifyname $texfile;
- my $lentexdir = length $texdir;
- my $numdeleted = 0;
- foreach my $dep (@dependencies) {
- if (substr($dep, 0, $lentexdir) ne $texdir) {
- $numdeleted++;
- }
- else {
- push @newdeps, $dep;
- }
- }
- @dependencies = @newdeps;
- print "OMITTING $numdeleted non-local file(s)\n" if $verbose;
- }
-
- # If --exclude was specified, discard all dependencies containing
- # excluded text as a substring.
- my $numexcluded = 0;
- foreach my $excluded (@exclude_files) {
- my @newdeps;
- foreach my $dep (@dependencies) {
- if ($dep =~ /\Q$excluded\E/) {
- $numexcluded++;
- }
- else {
- push @newdeps, $dep;
- }
- }
- @dependencies = @newdeps;
- }
- print "OMITTING $numexcluded excluded file(s)\n" if $verbose && $numexcluded;
-
- # If --include was specified, include the corresponding files.
- my $numextras = 0;
- foreach my $include_glob (@include_files) {
- foreach my $include_file (glob $include_glob) {
- push @dependencies, qualifyname $include_file;
- $numextras++;
- }
- }
- print "INCLUDING $numextras additional file(s)\n" if $verbose && $numextras;
-
- # Remove duplicates.
- my %uniquedeps;
- foreach my $dep (@dependencies) {
- $uniquedeps{$dep} = 1;
- }
- my $numdups = @dependencies - keys %uniquedeps;
- print "REMOVING $numdups duplicate file(s)\n" if $verbose && $numdups;
- @dependencies = sort keys %uniquedeps;
-
- # If --listdeps was specified, output the list of dependencies.
- if (@listdeps) {
- @dependencies = map {abs2rel($_)} @dependencies if grep /^rel$/, @listdeps;
- print join("\n", @dependencies), "\n";
- exit 0 if grep /^only$/, @listdeps;
- }
-
- # Return the list of dependencies.
- return @dependencies;
-}
-
-######################################################################
-
-# Parse and process the command-line options.
-my $showhelp = "";
-$keepdirs = 0;
-$verbose = 0;
-$localonly = 0;
-my $configfile;
-Getopt::Long::Configure("bundling");
-GetOptions ('texfile=s' => \$texfile,
- 'directory=s' => \$docdirname,
- 'manifest:s' => \$manifest,
- 'keepdirs!' => \$keepdirs,
- 'localonly!' => \$localonly,
- 'exclude=s' => \@exclude_files,
- 'include=s' => \@include_files,
- 'config=s' => \$configfile,
- 'v|verbose!' => \$verbose,
- 'listdeps=s' => \@listdeps,
- 'V|version' => sub { print "bundledoc $VERSION\n"; exit -1 },
- 'help' => \$showhelp) || pod2usage (-exitval => 1, -verbose => 0);
-pod2usage (-exitval => 0,
- -verbose => 1) if $showhelp && $verbose;
-pod2usage (-message => "(For more detailed help, enter \"$0 --help --verbose\".)",
- -exitval => 0,
- -verbose => 0) if $showhelp;
-pod2usage (-message => "${progname}: Too few arguments",
- -exitval => 1,
- -verbose => 0) if $#ARGV==-1;
-$depfile = find_dependency_file shift; # Dependencies from snapshot.sty
-process_config_file $configfile if defined $configfile;
-($texfile = $depfile) =~ s/\.[^.]*$/.tex/ if !$texfile; # Main LaTeX source file
-($docdirname = basename($depfile)) =~ s/\.[^.]*$// if !$docdirname; # Name to use for the document directory
-($ENV{"BDBASE"} = rel2abs($depfile)) =~ s/\.[^.]*$//; # May be needed by user-defined variables
-print "BDBASE = '$ENV{BDBASE}'\n" if $verbose;
-$ENV{"BDBASE"} = "\"$ENV{BDBASE}\"";
-
-# Expand and sanity check @listdeps.
-@listdeps = map {s/\s+//g; split /,/} @listdeps;
-foreach my $ldep (@listdeps) {
- if ($ldep !~ /^(rel|only|yes|no)$/) {
- pod2usage (-message => "${progname}: Invalid --listdeps option \"$ldep\"",
- -exitval => 1,
- -verbose => 0);
- }
-}
-@listdeps = () if grep /^no$/, @listdeps;
-
-# Create a bundled file.
-my @dependencies = find_dependencies();
-if ($keepdirs) {
- # Put absolute pathnames in the tar file.
- # QUESTIONS: Does this work with multiple drive letters in Windows?
- # What about UNC names?
- chdir rootdir() || die "${progname}: $! (".rootdir().")\n";
- $ENV{"BDINPUTS"} = join (" ", map {s|^/+||; s/\"//g; "\"$_\""} @dependencies);
- executecmd $uservariable{"bundle"};
-}
-else {
- # Copy each of the dependencies to a temporary directory and tar it up.
- my $tempdir = tempdir("bundledoc-XXXXXX", TMPDIR => 1, CLEANUP => 1);
- my $tempdir2 = catfile $tempdir, $docdirname;
- print "CREATING $tempdir\n" if $verbose; # White lie: already created
- print "CREATING $tempdir2\n" if $verbose;
- mkdir ($tempdir2, 0777) || die "${progname}: $! ($tempdir2)\n";
- foreach my $dep (@dependencies) {
- # If the current dependency is in a subdirectory of the
- # original location, create the same subdirectory in the
- # temporary directory and copy the file there. Otherwise just
- # copy it to the root of the temporary directory.
- my $targetdir = $tempdir2;
- if (my $sd = $subdirs{$dep}) {
- $targetdir = catfile($targetdir, $sd);
- unless (-d $targetdir) {
- print "CREATING $targetdir\n" if $verbose;
- mkpath($targetdir, 0, 0777) || die "${progname}: $! ($targetdir)\n";
- }
- }
- copy ($dep, $targetdir) || die "${progname}: $! ($targetdir)\n";
- }
- if ($manifest ne "") {
- my $manifest = catfile $tempdir2, $manifest;
- my $manifestdir = dirname $manifest;
- unless (-d $manifestdir) {
- print "CREATING $manifestdir\n" if $verbose;
- mkpath($manifestdir, 0, 0777) || die "${progname}: $! ($manifestdir)\n";
- }
- print "WRITING $manifest\n" if $verbose;
- open (MANIFEST, ">$manifest") || die "${progname}: $! ($manifest)\n";
- print MANIFEST join ("\n", @dependencies), "\n";
- close MANIFEST;
- }
- chdir $tempdir || die "${progname}: $! ($tempdir)\n";
- $ENV{"BDINPUTS"} = "\"$docdirname\"";
- executecmd $uservariable{"bundle"};
-
- # Clean up our mess.
- # NOTE: We rmtree $tempdir2 and rmdir $tempdir because rmtree
- # complained on WinNT when trying to remove a top-level
- # directory (e.g., "\s4r.").
- print "REMOVING $tempdir2\n" if $verbose;
- rmtree $tempdir2, 0, 1;
- chdir (updir());
- print "REMOVING $tempdir\n" if $verbose;
- rmdir $tempdir || die "${progname}: $! ($tempdir)\n";
-}
-print "FINISHED.\n" if $verbose;
-exit 0;
-
-__END__
-
-######################################################################
-
-=head1 NAME
-
-bundledoc - bundle all the files needed by a LaTeX document
-
-
-=head1 SYNOPSIS
-
-bundledoc
-[B<--version>]
-[B<--help>]
-[B<-->[B<no>]B<verbose>]
-[B<--texfile>=I<file.tex>]
-[B<--directory>=I<directory>]
-[B<-->[B<no>]B<localonly>]
-[B<--exclude>=I<string>]
-[B<--include>=I<filespec>]
-[B<--manifest>=I<file>]
-[B<-->B<listdeps>=[yes|no|only|rel]...]
-[B<-->[B<no>]B<keepdirs>]
-[B<--config>=I<file.cfg>]
-I<file.dep>
-
-
-=head1 DESCRIPTION
-
-B<bundledoc> is a post-processor for the B<snapshot> package that
-bundles together all the classes, packages, and files needed to build
-a given LaTeX document. It reads the F<.dep> file that B<snapshot>
-produces, finds each of the files mentioned therein, and packages them
-into a single archive file (e.g., a F<.tar.gz> file), suitable for
-moving across systems, transmitting to a colleague, etc.
-
-As the simplest example possible, consider a LaTeX file called, say,
-F<hello.tex>:
-
- \RequirePackage{snapshot} % Needed by bundledoc
- \documentclass[11pt]{article}
-
- \begin{document}
- Hello, world!
- \end{document}
-
-The C<\RequirePackage{snapshot}> causes a F<hello.dep> file to be produced.
-When B<bundledoc> is then given C<hello.dep> as an argument, it locates the
-dependent files -- F<snapshot.sty>, F<article.cls>, and F<size11.clo> --
-and bundles them into a single archive file, along with F<hello.tex> and a
-F<MANIFEST> file (described in L<"OPTIONS">, below).
-
-
-=head1 OPTIONS
-
-In the following descriptions, I<somefile> refers to the name of your
-main LaTeX document (no extension).
-
-B<bundledoc> requires the name of the dependency file produced by
-B<snapshot>, normally I<somefile>F<.dep>). (For convenience, the file
-can be specified without its F<.dep> extension.) The following
-options may also be given:
-
-=over 4
-
-=item B<--version>
-
-Output the B<bundledoc> script's version number. This overrides all
-of the remaining options.
-
-=item B<--help>
-
-Give a brief usage message. This overrides all of the remaining options.
-
-=item B<-->[B<no>]B<verbose> (default: C<noverbose>)
-
-B<bundledoc> normally does not output anything except error messages.
-With C<--verbose>, it outputs copious status messages.
-
-=item B<--texfile>=I<main .tex file> (default: I<somefile>F<.tex>)
-
-B<snapshot>'s dependency file does not list the main LaTeX file (the
-one that gets passed to B<latex>). In order for B<bundledoc> to find
-and bundle that file, B<bundledoc> assumes it has the same name as the
-B<snapshot> dependency file but with a F<.tex> extension. If this is
-not the case, then use C<--texfile> to specify the correct filename.
-
-=item B<--directory>=I<archive directory> (default: I<somefile>)
-
-When B<bundledoc> creates an archive (e.g., a F<.tar> or F<.zip> file)
-containing the document's files, it puts all of them in a directory to
-avoid cluttering the current directory with files. If the given
-dependency file is called I<somefile>F<.dep> then the resulting
-archive will, by default, store all the dependent files in a
-I<somefile> directory. To change the directory name use the
-C<--directory> option.
-
-=item B<-->[B<no>]B<localonly> (default: C<nolocalonly>)
-
-Although B<bundledoc> normally archives all of the files named in the
-F<.dep> file, the C<--localonly> option tells B<bundledoc> to exclude
-all files located in a directory other than the F<.tex> file's
-directory or one of its subdirectories.
-
-=item B<--exclude>=I<string> (default: I<none>)
-
-While C<--localonly> causes files outside of the F<.tex> file's
-directory tree to be omitted from the archive, C<--exclude> provides
-finer-grained control over files to omit from the archive. The
-C<--exclude> option, which can be specified repeatedly on the command
-line, causes all files whose name contains I<string> to be omitted
-from the archive.
-
-=item B<--include>=I<filespec> (default: I<none>)
-
-The C<--include> option, which can be specified repeatedly on the
-command line, instructs B<bundledoc> to include in the archive all of
-the files matching I<filespec>, even if they're not referenced in the
-F<.dep> file.
-
-=item B<--manifest>=I<manifest file> (default: F<MANIFEST>)
-
-In addition to the dependent files, B<bundledoc> includes in the
-archive file one extra file called, by default, ``F<MANIFEST>''.
-F<MANIFEST> is a text file that lists the original filenames of all
-the dependencies. To change the filename from ``F<MANIFEST>'' to
-something else, use the C<--manifest> option. As a special case,
-C<--manifest=""> tells B<bundledoc> not to include a manifest file at
-all.
-
-=item B<--listdeps>=[yes|no|only|rel]...] (default: C<no>)
-
-C<--listdeps> accepts one or more of C<yes>, C<no>, C<only>, or C<rel>
-as a comma-separated list. As long as C<no> does not appear in this
-list, B<bundledoc> outputs all of the main LaTeX file's dependencies.
-If the list contains C<rel>, then B<bundledoc> outputs the list of
-dependencies with relative pathnames. If the list contains C<only>,
-then B<bundledoc> exits after displaying the list, without producing
-an archive.
-
-=item B<-->[B<no>]B<keepdirs> (default: C<nokeepdirs>)
-
-Normally, the archive file that B<bundledoc> produces contains a
-single directory -- and subdirectories, if the document refers
-explicitly to them -- in which all the dependent files lie. If
-C<--keepdirs> is specified, all the dependent files are stored with
-their original pathnames. For example, if F<somefile.tex> depends on
-F<figures/somefigure.eps>, F<article.cls>, and F<snapshot.sty>, then
-the I<somefile> archive will normally contain the following files:
-
-=over 4
-
-=item *
-
-F<somefile/somefile.tex>
-
-=item *
-
-F<somefile/figures/somefigure.eps>
-
-=item *
-
-F<somefile/article.cls>
-
-=item *
-
-F<somefile/snapshot.sty>
-
-=item *
-
-F<somefile/MANIFEST>
-
-=back
-
-However, C<--keepdirs> will cause the I<somefile> archive to contain
-the following sorts of filenames instead:
-
-=over 4
-
-=item *
-
-F<home/me/mydocs/somefile.tex>
-
-=item *
-
-F<home/me/mydocs/figures/somefigure.eps>
-
-=item *
-
-F<usr/share/texmf/tex/latex/base/article.cls>
-
-=item *
-
-F<usr/share/texmf/tex/latex/snapshot/snapshot.sty>
-
-=back
-
-C<--directory> is not used when C<--keepdirs> is in effect. In
-addition, no manifest file is written to the archive file as it
-contains redundant information.
-
-=item B<--config>=I<configuration file> (default: E<lt>noneE<gt>)
-
-The C<--config> option is used to point B<bundledoc> to the
-appropriate configuration (F<.cfg>) file for your TeX distribution and
-operating system. B<bundledoc> comes with a few configuration files
-and it's easy to write more. See L<"CONFIGURATION FILES"> (below) for
-a description of the configuration file format. For convenience, the
-file can be specified without its F<.cfg> extension.
-
-=back
-
-
-=head1 CONFIGURATION FILES
-
-=head2 Format
-
-Configuration files follow a fairly simple format. Lines beginning with
-C<#> are comments. Blank lines are ignored. All other lines are of the
-form:
-
- variable: value
-
-The current version of B<bundledoc> recognizes the following variables:
-
-=over 4
-
-=item B<bundle>
-
-The command to use to bundle a set of files into a single archive file
-
-=item B<sink>
-
-The affix to a command to discard its output
-
-=item B<find>
-
-The command to find a file within the TeX tree(s).
-
-=back
-
-Values that are too long for one line can be split across multiple lines
-by using C<\> as the line-continuation symbol.
-
-There are two environment variables that B<bundledoc> makes available
-for use by configuration-file commands: C<BDBASE>, which is set to
-I<somefile> (as in L<"OPTIONS">), and C<BDINPUTS>, which is set to a
-space-separated list of files that a command is to operate upon. That
-is, when the command associated with C<bundle> is running, C<BDINPUTS>
-contains the list of all the files that are to be archived. In
-contrast, when the command associated with C<find> is running,
-C<BDINPUTS> contains the name of the file to search for.
-
-=head2 Examples
-
-The following configuration file parallels B<bundledoc>'s default
-values of the various configuration-file variables, which represents a
-kpathsea-based TeX distribution running on a generic Unix system,
-which doesn't necessarily have any of the GNU tools, such as B<gzip>
-or GNU B<tar>:
-
- # "Default" configuration file
- # By Scott Pakin <scott+bdoc@pakin.org>
-
- bundle: (tar -cvf - $BDINPUTS | compress > $BDBASE.tar.Z)
- sink: > /dev/null 2>&1
- find: kpsewhich -progname=latex $BDINPUTS
-
-The parentheses in the C<bundle:> line tell the Unix shell to run the
-command in a subshell. This is to make the C<sink:> affix work
-properly (i.e., so there aren't two C<E<gt>>'s in the same command).
-
-Notice how the commands treat C<BDBASE> and C<BDINPUTS> like any other
-environment variables in a Unix shell, using C<$> to take their value.
-Other operating systems use different conventions for referring to
-environment variables. For instance, a configuration file for a
-Windows-based TeX distribution would use C<%BDBASE%> and C<%BDINPUTS%>
-instead.
-
-The value for C<sink:> is specific to an operating system. The value
-for C<find:> is specific to a TeX distribution. C<bundle:> is where
-the most opportunity for customization lies. You can use C<bundle:>
-to specify your favorite archive format. For example, you can produce
-a shar file on Unix with something like:
-
- bundle: (shar --archive-name="$BDBASE" $BDINPUTS > $BDBASE.sh)
-
-or a CAB file on Microsoft Windows with something like:
-
- bundle: cabarc -r -p N %BDBASE%.cab %BDINPUTS%
-
-
-=head1 EXAMPLES
-
-Assume that F<myfile.dep> was produced from F<myfile.tex> by following
-the instructions in L<the Description section|/"DESCRIPTION">. The
-following command produces a F<.zip> file with the MikTeX TeX
-distribution running on Microsoft Windows:
-
- bundledoc --config=miktex.cfg myfile.dep
-
-This can be abbreviated to
-
- bundledoc --config=miktex myfile
-
-The following builds a F<.tar.gz> archive with the TeX Live
-distribution running on a Unix-like operating system. B<bundledoc>
-will produce verbose output describing its operations. All files not
-in the same directory tree as F<myfile.tex> and all files containing
-".fd" or ".sty" in their names are omitted. However, all F<.bib>
-files in the current directory will be included in the archive even
-though none of them are referenced by F<myfile.dep>. Finally, no
-F<MANIFEST> file will be produced.
-
- bundledoc --config=texlive-unix.cfg --verbose --localonly \
- --exclude=.fd --exclude=.cfg --include="*.bib" --manifest="" \
- myfile.dep
-
-
-=head1 FILES
-
-The user must have previously installed F<snapshot.sty> and used it to
-produce a dependency file for his document. Besides that, the set of
-external files needed by B<bundledoc> is system-specific and depends on the
-configuration file used. (See L<"CONFIGURATION FILES">, above.)
-
-B<bundledoc> currently comes with two configuration files:
-
-=over 4
-
-=item F<texlive-unix.cfg>
-
-Configuration file for TeX Live installations on Unix or Linux. TeX
-Live is a kpathsea-based TeX distribution that runs on various flavors
-of Unix and Microsoft Windows. F<texlive-unix.cfg> assumes you have
-B<gzip> and uses it to produce a F<.tar.gz> archive file. The
-configuration file has B<bundledoc> use B<kpsewhich> to find LaTeX
-files.
-
-=item F<miktex.cfg>
-
-Configuration file for MikTeX installations. MikTeX is a popular TeX
-distribution for Microsoft Windows. F<miktex.cfg> assumes you have
-B<zip> and uses it to produce a F<.zip> archive file. The
-configuration file now has B<bundledoc> use B<kpsewhich> to find LaTeX
-files; older version of MikTeX required the rather nonstandard
-B<initexmf> for this purpose.
-
-=item F<texlive-unix-arlatex.cfg>
-
-This is a variant of F<texlive-unix.cfg> that uses B<arlatex> instead
-of B<gzip> to archive files. B<arlatex> is a script included in the
-B<bundledoc> distribution that generates a self-extracting F<.tex>
-file based on LaTeX's C<filecontents> environment.
-
-=back
-
-
-=head1 NOTES
-
-=head2 Including and excluding files
-
-The C<--localonly>, C<--exclude>, and C<--include> options provide
-control over the archive's contents. C<--exclude> and C<--include>
-can be specified repeatedly on the command line. The order in which
-these options are specified is immaterial; B<bundledoc> processes file
-inclusions and exclusions in the following order:
-
-=over 4
-
-=item 1.
-
-All files referenced by the F<.dep> file are added to the list of
-files to archive.
-
-=item 2.
-
-If C<--localonly> is specified, all files not found in the F<.tex>
-file's directory are removed from the list.
-
-=item 3.
-
-For each C<--exclude> string specified, all files containing that
-string are removed from the list.
-
-=item 4.
-
-For each C<--include> file specification, the set of files designated
-by its expansion are added to the list.
-
-=back
-
-
-=head2 Issues When Running Under Microsoft Windows
-
-First, because B<bundledoc> is a Perl script, you should do one of the
-following to run it under Windows:
-
-=over 4
-
-=item *
-
-C<perl bundledoc>
-
-=item *
-
-Rename F<bundledoc> to F<bundledoc.pl> and run C<bundledoc.pl>. (This
-is assuming you have a file association set up for F<.pl>.)
-
-=item *
-
-Run the B<pl2bat> script (if you have it) to convert F<bundledoc> to
-F<bundledoc.bat>, then run C<bundledoc>.
-
-=back
-
-Second, Windows uses a multi-rooted filesystem (i.e., multiple drive
-letters). I wouldn't be surprised if bad things were to happen if the
-files to be bundled are scattered across drives. In addition, Windows
-supports ``UNC'' filenames, which have no drive letter at all, just a
-machine and share name. UNC filenames are also untested waters for
-B<bundledoc>. Be careful!
-
-
-=head2 Testing Status
-
-I have tested B<bundledoc> only with Perl v5.6.0 and later and only on
-the following platforms:
-
-=over 4
-
-=item *
-
-Linux + TeX Live
-
-=item *
-
-Linux + teTeX
-
-=item *
-
-Windows NT + MiKTeX
-
-=item *
-
-Solaris + ??? (something kpathsea-based)
-
-=back
-
-It is my hope that B<bundledoc> works on many more platforms than
-those. I tried to make the program itself fairly independent of the
-operating system; only the configuration files should have to change
-to run B<bundledoc> on a different system.
-
-=head2 Future Work
-
-I'd like B<bundledoc> to work on as wide a variety of TeX
-distributions as possible. If your platform is significantly
-different from the ones listed in L<"Testing Status"> (e.g., if you're
-running S<OS X>) and you need to create a substantially different
-configuration file from F<texlive-unix.cfg> and F<miktex.cfg>, please
-send it to me at the address listed in L<"AUTHOR"> so I can include it
-in a future version of B<bundledoc>. (I make no promises, though).
-
-Once B<bundledoc> works on all the major operating systems and TeX
-distributions it would be really convenient if I could get
-B<bundledoc> to detect the platform it's running on and automatically
-select an appropriate configuration file.
-
-Finally, it would be handy for B<bundledoc> to include fonts in the
-archive file. At a minimum, it should include F<.tfm> files, but it
-would be even better if it included F<.mf>, F<.pfb>, F<.ttf>, and
-other common font formats, as well.
-
-=head2 Acknowledgments
-
-Thanks to Fabien Vignes-Tourneret for suggesting what became the
-C<--localonly> option and for a discussion that led to the
-C<--exclude> and C<--include> options; to Marius Kleiner for updating
-B<bundledoc> to properly handle document subdirectories; and to Frank
-Mittelbach for suggesting using Kpathsea to help find F<.cfg> files
-and to automatically append F<.cfg> and F<.dep> extensions if
-necessary.
-
-
-=head1 SEE ALSO
-
-arlatex(1), gzip(1), kpsewhich(1), latex(1), perl(1), zip(1),
-the B<snapshot> documentation
-
-
-=head1 AUTHOR
-
-Scott Pakin, I<scott+bdoc@pakin.org>
diff --git a/Build/source/texk/texlive/linked_scripts/cachepic/cachepic.tlu b/Build/source/texk/texlive/linked_scripts/cachepic/cachepic.tlu
deleted file mode 100755
index 363d6bb6320..00000000000
--- a/Build/source/texk/texlive/linked_scripts/cachepic/cachepic.tlu
+++ /dev/null
@@ -1,231 +0,0 @@
-#!/usr/bin/env texlua
-
-local options = {
- pdfoutput=true,
- redoall=false,
- multipicfile=false,
- noborder=false,
- dotypesetting=true,
- nopostprocess=false,
-}
-
-local usagetext = 'Usage: cachepic [options] latexfile'
-local tryhelp = "Try `cachepic --help' for more information"
-local helptext = [[
-Options start with '-' or '--' and can be any of:
- -pdf output in (e)pdf format (default)
- -eps output in eps format
- -all regenerate all graphics
- -multi all graphics in one file (implies -pdf)
- -tight no 0.5bp margin around the graphic
- -notex no typesetting, only graphic postprocessing
- -nopic generate no graphics, only .cachepic file
- -usage display usage message
- -help,-h,-? display help message]]
-
-local msg = {
- MultipleInputFiles = "cannot process multiple files:\t%s\t%s",
- NoInputFile = "no input file given\n" .. tryhelp,
- UnknownOption = "unknown option: %s\n" .. tryhelp,
- FileOpenFailed = "could not open file: %s",
- NoGhostScript = "could not locate ghostscript interpreter",
- WrongOutputMode = "expected %s output but got %s",
- NoPreviews = "no cachepic previews found",
- MultiPicOnlyInPDF = "option '-multi' for all graphics in one file supported only in pdf mode"
-}
-
-function die(msgfmt, ...)
- error(string.format(msgfmt, ...))
-end
-
-function warn(msgfmt, ...)
- print('warning: ' .. string.format(msgfmt, ...))
-end
-
-local function qfile(filename)
- filename = string.gsub(filename, '"', '')
- if string.find(filename, "[%s%&%(%)%[%]%{%}%^%=%;%!%'%+%,%`%~]") then
- filename = '"' .. filename .. '"'
- end
- return filename
-end
-
-local function syscall(command)
- print('system: ' .. command)
- local ret = os.execute(command)
- if ret > 0 then os.exit(ret)
- else return ret end
-end
-
-local function copyfile(src, dst)
- print('copy ' .. qfile(src) .. ' ' .. qfile(dst))
- local buffer, bufsize = '', 1024
- local fin = io.open(src, 'rb')
- if not fin then die(msg.FileOpenFailed, src) end
- local fout = io.open(dst, 'wb')
- if not fout then die(msg.FileOpenFailed, dst) end
- while buffer do
- fout:write(buffer)
- buffer = fin:read(bufsize)
- end
- fin:close()
- fout:close()
-end
-
-local isfile = lfs and lfs.isfile or function (fname)
- -- if we are not running under texlua, then do it the hard way
- local fh = io.open(fname)
- return (fh and (fh:close() or true) or false)
-end
-
-local function whichfile(fname, path)
- if isfile(fname) then return fname end
- -- make the best guess if it is Windows or Unix
- local dirsep, pathsep = '/', ':'
- if (os.type == 'windows') or string.find(path, '\\') or string.find(path, ';') then
- dirsep, pathsep = '\\', ';' -- Windows
- end
- -- iterate path
- for dir in string.gmatch(path, '[^' .. pathsep .. ']+') do
- local f = dir .. dirsep .. fname
- -- print(f)
- if isfile(f) then return f end
- end
- return nil
-end
-
-local function findgs()
- local path = os.getenv('PATH')
- for _, fname in ipairs{'gs', 'gswin32c.exe', 'mgs.exe'} do
- if whichfile(fname, path) then return fname end
- end
- die(msg.NoGhostScript)
-end
-
--- Process options --
-if #arg == 0 then
- print(usagetext)
- print(tryhelp)
- os.exit(0)
-end
-local filename = nil
-for _, argn in ipairs(arg) do
- local opt, num = string.gsub(argn, '^%-%-?', '')
- if num == 0 then -- not an option
- if filename then die(msg.MultipleInputFiles, filename, opt)
- else filename = opt end
- elseif opt == 'eps' then options.pdfoutput = false
- elseif opt == 'pdf' then options.pdfoutput = true
- elseif opt == 'all' then options.redoall = true
- elseif opt == 'multi' then options.multipicfile = true
- elseif opt == 'tight' then options.noborder = true
- elseif opt == 'notex' then options.dotypesetting = false
- elseif opt == 'nopic' then options.nopostprocess = true
- elseif (opt == 'usage') or (opt == 'help') or (opt == 'h') or (opt == '?') then
- print(usagetext)
- if opt == 'usage' then os.exit(0) end
- print(helptext)
- os.exit(0)
- else die(msg.UnknownOption, argn) end
-end
-if not filename then
- die(msg.NoInputFile)
-end
-if options.multipicfile and not options.pdfoutput then
- warn(msg.MultiPicOnlyInPDF)
- options.multipicfile = false
-end
-filename = string.gsub(filename, '\\', '/')
-local noextname = string.gsub(filename, '%.[^./]*$', '')
-local jobname = string.match(noextname, '[^/]+$')
-local jobsuffix = (options.dotypesetting and '_cptmp' or '')
-local multipicfilename = noextname .. '-cachepic.pdf'
-
--- Typeset document --
-if options.dotypesetting then
- local engine = (options.pdfoutput and 'pdflatex' or 'latex')
- local psfixbb = (options.pdfoutput and '' or ',psfixbb')
- local noborder = (options.noborder and ' \\PreviewBorder=0pt' or '')
- local redoall = (options.redoall and ' \\makeatletter\\def\\cachepic@tryincludepic#1#2{\\xdef\\cachepic@name{#1}#2}\\makeatother' or '')
- local command = engine .. ' -interaction=nonstopmode -jobname=' .. jobname .. jobsuffix ..
- ' \\def\\jobname{' .. jobname .. '}' ..
- ' \\RequirePackage[active,tightpage,delayed,cachepic' .. psfixbb .. ']{preview}' ..
- noborder .. redoall .. ' \\input{' .. qfile(filename) .. '}'
- syscall(command)
-end
-
--- Process log file --
-local iLines = io.lines(noextname .. jobsuffix .. '.log')
-local pics = {}
-local pdfmode = options.pdfoutput
-local trim = '0 0 0 0'
-for line in iLines do
- local head, c1, c2, c3, c4, c5 = string.match(line,
- '^Preview:%s*([A-Za-z]+)%s*(%-?%d*)%s*(%-?%d*)%s*(%-?%d*)%s*(%-?%d*)%s*(.*)')
- if head == 'PDFoutput' then
- pdfmode = (tonumber(c1) ~= 0)
- elseif (head == 'Tightpage') and c1 and c2 and c3 and c4 then
- trim = string.format('%dsp %dsp %dsp %dsp',
- -tonumber(c1), -tonumber(c2), tonumber(c3), tonumber(c4))
- elseif (head == 'CachePic') and c1 and c2 and c3 and c4 and c5 then
- local picname = c5
- local picpage = tonumber(c1)
- local baseline = tonumber(c4) or 0
- local texmacro = string.format('\\CachePicDefMacro{%s}{%d}{trim=%s}{%dsp}',
- picname, picpage, trim, -baseline)
- pics[#pics+1] = {name=picname, page=picpage, macro=texmacro}
- end
-end
-if #pics == 0 then
- warn(msg.NoPreviews)
- return
-end
-if pdfmode ~= options.pdfoutput then
- local expectedmode = options.pdfoutput and 'pdf' or 'dvi'
- local actualmode = pdfmode and 'pdf' or 'dvi'
- die(msg.WrongOutputMode, expectedmode, actualmode)
-end
-
--- Write out cachepic macros --
-io.output(noextname .. '.cachepic')
-for i = 1, #pics do
- io.write(pics[i].macro, '\n')
-end
-io.close()
-if options.nopostprocess then return end
-
--- Postprocess pics --
-if options.multipicfile then
- if options.pdfoutput then
- -- without option -all the file size will slowly grow
- -- extra run through GhostScript seems to prevent that
- -- but it degrades raster graphics or makes them much larger
- -- no perfect solution it seems
- copyfile(noextname .. jobsuffix .. '.pdf', multipicfilename)
- else die(msg.MultiPicOnlyInPDF) end -- this should never happen
-else
- local ext, cmdtmpl
- if options.pdfoutput then
- ext = '.pdf'
- filename = qfile(noextname .. jobsuffix .. '.pdf')
- cmdtmpl = findgs() ..
- ' -sDEVICE=pdfwrite -dQUIET -dBATCH -dNOPAUSE -dCompatibilityLevel=1.4' ..
- ' -dFirstPage=%s -dLastPage=%s -sOutputFile=%s %s'
- else
- ext = '.eps'
- filename = qfile(noextname .. jobsuffix .. '.dvi')
- cmdtmpl = 'dvips -E -p %s -l %s -o %s %s'
- end
- for i = 1, #pics do
- local outfile = string.gsub(pics[i].name, '"', '') .. ext
- if not isfile(outfile) or options.redoall then
- outfile = qfile(outfile)
- syscall(string.format(cmdtmpl, pics[i].page, pics[i].page, outfile, filename))
- end
- end
-end
---[[-- GS options preventing lossy image recompression
- ' -dMonoImageFilter=/CCITTFaxEncode' ..
- ' -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode' ..
- ' -dAutoFilterGrayImages=false -dGrayImageFilter=/FlateEncode' ..
-]] \ No newline at end of file
diff --git a/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua b/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua
deleted file mode 100755
index 6191ca284ab..00000000000
--- a/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua
+++ /dev/null
@@ -1,869 +0,0 @@
-#!/usr/bin/env texlua
--- -----------------------------------------------------------------
--- checkcites.lua
--- Copyright 2012, 2019, Enrico Gregorio, Paulo Roberto Massa Cereda
---
--- This work may be distributed and/or modified under the conditions
--- of the LaTeX Project Public License, either version 1.3 of this
--- license or (at your option) any later version.
---
--- The latest version of this license is in
---
--- http://www.latex-project.org/lppl.txt
---
--- and version 1.3 or later is part of all distributions of LaTeX
--- version 2005/12/01 or later.
---
--- This work has the LPPL maintenance status `maintained'. the
--- current maintainers of this work are the original authors. This
--- work consists of the file checkcites.lua.
---
--- Project repository: http://github.com/cereda/checkcites
--- -----------------------------------------------------------------
-
--- Checks if the table contains the element.
--- @param a Table.
--- @param hit Element.
--- @return Boolean value if the table contains the element.
-local function exists(a, hit)
- for _, v in ipairs(a) do
- if v == hit then
- return true
- end
- end
- return false
-end
-
--- Parses the list of arguments based on a configuration map.
--- @param map Configuration map.
--- @param args List of command line arguments.
--- @return Table containing the valid keys and entries.
--- @return Table containing the invalid keys.
-local function parse(map, args)
- local keys, key, unknown = {}, 'unpaired', {}
- local a, b
- for _, v in ipairs(args) do
- a, _, b = string.find(v, '^%-(%w)$')
- if a then
- for _, x in ipairs(map) do
- key = 'unpaired'
- if x['short'] == b then
- key = x['long']
- break
- end
- end
- if key == 'unpaired' then
- table.insert(unknown, '-' .. b)
- end
- if not keys[key] then
- keys[key] = {}
- end
- else
- a, _, b = string.find(v, '^%-%-([%w-]+)$')
- if a then
- for _, x in ipairs(map) do
- key = 'unpaired'
- if x['long'] == b then
- key = b
- break
- end
- end
- if key == 'unpaired' then
- if not exists(unknown, '--' .. b) then
- table.insert(unknown, '--' .. b)
- end
- end
- if not keys[key] then
- keys[key] = {}
- end
- else
- if not keys[key] then
- keys[key] = {}
- end
- if key ~= 'unpaired' then
- for _, x in ipairs(map) do
- if x['long'] == key then
- if not (x['argument'] and
- #keys[key] == 0) then
- key = 'unpaired'
- end
- break
- end
- end
- if not keys[key] then
- keys[key] = {}
- end
- table.insert(keys[key], v)
- else
- if not keys[key] then
- keys[key] = {}
- end
- table.insert(keys[key], v)
- end
- end
- end
- end
- return keys, unknown
-end
-
--- Calculates the difference between two tables.
--- @param a First table.
--- @param b Second table.
--- @return Table containing the difference between two tables.
-local function difference(a, b)
- local result = {}
- for _, v in ipairs(a) do
- if not exists(b, v) then
- table.insert(result, v)
- end
- end
- return result
-end
-
--- Splits the string based on a pattern.
--- @param str String.
--- @param pattern Pattern.
-local function split(str, pattern)
- local result = {}
- string.gsub(str, pattern, function(a)
- table.insert(result, a) end)
- return result
-end
-
--- Reads lines from a file.
--- @param file File.
--- @returns Table representing the lines.
-local function read(file)
- local handler = io.open(file, 'r')
- local lines = {}
- if handler then
- for line in handler:lines() do
- table.insert(lines, line)
- end
- handler:close()
- end
- return lines
-end
-
--- Gets a pluralized word based on a counter.
--- @param i Counter.
--- @param a Word in singular.
--- @param b Word in plural.
--- @return Either the first or second word based on the counter.
-local function plural(i, a, b)
- if i == 1 then
- return a
- else
- return b
- end
-end
-
--- Normalizes the string, removing leading and trailing spaces.
--- @param str String.
--- @return Normalized string without leading and trailing spaces.
-local function normalize(str)
- local result, _ = string.gsub(str, '^%s', '')
- result, _ = string.gsub(result, '%s$', '')
- return result
-end
-
--- Checks if the element is in a blacklist.
--- @param a Element.
--- @return Boolean value if the element is blacklisted.
-local function blacklist(a)
- local list = {}
- for _, v in ipairs(list) do
- if v == a then
- return true
- end
- end
- return false
-end
-
--- Checks if the key is allowed.
--- @param v The key itself.
--- @return Boolean value if the key is allowed.
-local function allowed(key)
- local keys = { 'string', 'comment' }
- for _, v in ipairs(keys) do
- if string.lower(key) == v then
- return false
- end
- end
- return true
-end
-
--- Extracts the biblographic key.
--- @param lines Lines of a file.
--- @return Table containing bibliographic keys.
-local function extract(lines)
- local result = {}
- for _, line in ipairs(lines) do
- local key, hit = string.match(line,
- '^%s*%@(%w+%s*){%s*(.+),')
- if key and allowed(key) then
- if not exists(result, hit) then
- hit = normalize(hit)
- table.insert(result, hit)
- end
- end
- end
- return result
-end
-
--- Extracts the cross-references found
--- in lines of the bibligraphy file.
--- @param lines Line of a file.
--- @return Table containing cross-references.
-local function crossref(lines)
- local result, lookup, key, hit = {}, ''
- for _, line in ipairs(lines) do
- key, hit = string.match(line,
- '^%s*%@(%w+%s*){%s*(.+),')
- if key and allowed(key) then
- lookup = normalize(hit)
- else
- key, hit = string.match(line,
- '^%s*(%w+)%s*=%s*(.+)$')
- if key then
- key = string.lower(key)
- if key == 'crossref' then
- if string.sub(hit, -1) == ',' then
- hit = string.sub(hit, 2, -3)
- else
- hit = string.sub(hit, 2, -2)
- end
- result[lookup] = hit
- end
- end
- end
- end
- return result
-end
-
--- Adds the extension if the file does not have it.
--- @param file File.
--- @param extension Extension.
--- @return File with proper extension.
-local function sanitize(file, extension)
- extension = '.' .. extension
- if string.sub(file, -#extension) ~= extension then
- file = file .. extension
- end
- return file
-end
-
--- Checks if a file exists.
--- @param file File.
--- @return Boolean value indicating if the file exists.
-local function valid(file)
- local handler = io.open(file, 'r')
- if handler then
- handler:close()
- return true
- else
- return false
- end
-end
-
--- Wraps a string based on a line width.
--- @param str String.
--- @param size Line width.
--- @return Wrapped string.
-local function wrap(str, size)
- local parts = split(str, '[^%s]+')
- local r, l = '', ''
- for _, v in ipairs(parts) do
- if (#l + #v) > size then
- r = r .. '\n' .. l
- l = v
- else
- l = normalize(l .. ' ' .. v)
- end
- end
- r = normalize(r .. '\n' .. l)
- return r
-end
-
--- Backend namespace
-local backends = {}
-
--- Gets data from auxiliary files (BibTeX).
--- @param lines Lines of a file.
--- @param rec Recursive switch.
--- @return Boolean indicating if an asterisk was found.
--- @return Table containing the citations.
--- @return Table containing the bibliography files.
-backends.bibtex = function(lines, rec)
- local citations, bibliography, invalid = {}, {}, {}
- local asterisk, parts, hit = false
- for _, line in ipairs(lines) do
- hit = string.match(line, '^%s*\\citation{(.+)}$')
- if hit then
- if hit ~= '*' then
- parts = split(hit, '[^,%s]+')
- for _, v in ipairs(parts) do
- v = normalize(v)
- if not exists(citations, v) then
- table.insert(citations, v)
- end
- end
- else
- asterisk = true
- end
- else
- hit = string.match(line, '^%s*\\bibdata{(.+)}$')
- if hit then
- parts = split(hit, '[^,%s]+')
- for _, v in ipairs(parts) do
- v = normalize(v)
- if not exists(bibliography, v) and
- not blacklist(v) then
- table.insert(bibliography, v)
- end
- end
- else
- hit = string.match(line, '^%s*\\@input{(.+)}$')
- if rec and hit then
- hit = sanitize(hit, 'aux')
- if not valid(hit) then
- table.insert(invalid, hit)
- else
- local a, b, c = backends.bibtex(read(hit), false)
- asterisk = asterisk or a
- for _, v in ipairs(b) do
- if not exists(citations, v) then
- table.insert(citations, v)
- end
- end
- for _, v in ipairs(c) do
- if not exists(bibliography, v) then
- table.insert(bibliography, v)
- end
- end
- end
- end
- end
- end
- end
- if #invalid ~= 0 then
- print()
- print(wrap('Warning: there ' .. plural(#invalid,
- 'is an invalid reference ', 'are ' ..
- 'invalid references ') .. 'to the ' ..
- 'following auxiliary ' .. plural(#invalid,
- 'file ', 'files ') .. 'that could not ' ..
- 'be resolved at runtime:', 74))
- for _, v in ipairs(invalid) do
- print('=> ' .. v)
- end
- end
- return asterisk, citations, bibliography
-end
-
--- Gets data from auxiliary files (Biber).
--- @param lines Lines of a file.
--- @param _ To be discarded with biber.
--- @return Boolean indicating if an asterisk was found.
--- @return Table containing the citations.
--- @return Table containing the bibliography files.
-backends.biber = function(lines, _)
- local citations, bibliography = {}, {}
- local asterisk, parts, hit = false
- for _, line in ipairs(lines) do
- hit = string.match(line, '^%s*<bcf:citekey order="%d+">' ..
- '(.+)</bcf:citekey>$')
- if hit then
- if hit ~= '*' then
- parts = split(hit, '[^,%s]+')
- for _, v in ipairs(parts) do
- v = normalize(v)
- if not exists(citations, v) then
- table.insert(citations, v)
- end
- end
- else
- asterisk = true
- end
- else
- hit = string.match(line, '^%s*<bcf:datasource type="file" ' ..
- 'datatype="%w+">(.+)</bcf:datasource>$')
- if hit then
- parts = split(hit, '[^,%s]+')
- for _, v in ipairs(parts) do
- v = normalize(v)
- if not exists(bibliography, v) and
- not blacklist(v) then
- table.insert(bibliography, v)
- end
- end
- end
- end
- end
- return asterisk, citations, bibliography
-end
-
--- Counts the number of elements of a nominal table.
--- @param t Table.
--- @return Table size.
-local function count(t)
- local counter = 0
- for _, _ in pairs(t) do
- counter = counter + 1
- end
- return counter
-end
-
--- Repeats the provided char a certain number of times.
--- @param c Char.
--- @param size Number of times.
--- @return String with a char repeated a certain number of times.
-local function pad(c, size)
- local r = c
- while #r < size do
- r = r .. c
- end
- return r
-end
-
--- Flattens a table of tables into only one table.
--- @param t Table.
--- @return Flattened table.
-local function flatten(t)
- local result = {}
- for _, v in ipairs(t) do
- for _, k in ipairs(v) do
- if not exists(result, k) then
- table.insert(result, k)
- end
- end
- end
- return result
-end
-
--- Organizes a key/value table of tables into only one table.
--- @param t Table.
--- @return Flattened key/value table.
-local function organize(t)
- local result = {}
- for _, v in ipairs(t) do
- for j, k in pairs(v) do
- if not result[j] then
- result[j] = k
- end
- end
- end
- return result
-end
-
--- Applies a function to elements of a table.
--- @param c Table.
--- @param f Function.
--- @return A new table.
-local function apply(c, f)
- local result = {}
- for _, v in ipairs(c) do
- table.insert(result, f(v))
- end
- return result
-end
-
--- Search the TeX tree for the file.
--- @param library The library reference.
--- @param file The filename.
--- @param extension The extension.
--- @return String pointing to the file location.
-local function lookup(library, file, extension)
- return library.find_file(file, extension)
-end
-
--- Prints the script header.
-local function header()
-print(" _ _ _ _")
-print(" ___| |_ ___ ___| |_ ___|_| |_ ___ ___")
-print("| _| | -_| _| '_| _| | _| -_|_ -|")
-print("|___|_|_|___|___|_,_|___|_|_| |___|___|")
-print()
- print(wrap('checkcites.lua -- a reference ' ..
- 'checker script (v2.4)', 74))
- print(wrap('Copyright (c) 2012, 2019, ' ..
- 'Enrico Gregorio, Paulo ' ..
- 'Roberto Massa Cereda', 74))
-end
-
--- Operation namespace
-local operations = {}
-
--- Reports the unused references.
--- @param citations Citations.
--- @param references References.
--- @return Integer representing the status.
-operations.unused = function(citations, references, crossrefs)
- print()
- print(pad('-', 74))
- print(wrap('Report of unused references in your TeX ' ..
- 'document (that is, references present in ' ..
- 'bibliography files, but not cited in ' ..
- 'the TeX source file)', 74))
- print(pad('-', 74))
-
- local z = {}
- for _, citation in ipairs(citations) do
- if crossrefs[citation] then
- table.insert(z, crossrefs[citation])
- end
- end
-
- for _, i in ipairs(z) do
- if not exists(i, citations) then
- table.insert(citations, i)
- end
- end
-
- local r = difference(references, citations)
- print()
- print(wrap('Unused references in your TeX document: ' ..
- tostring(#r), 74))
- if #r == 0 then
- return 0
- else
- for _, v in ipairs(r) do
- print('=> ' .. v)
- end
- return 1
- end
-end
-
--- Reports the undefined references.
--- @param citations Citations.
--- @param references References.
--- @return Integer value indicating the status.
-operations.undefined = function(citations, references, crossrefs)
- print()
- print(pad('-', 74))
- print(wrap('Report of undefined references in your TeX ' ..
- 'document (that is, references cited in the ' ..
- 'TeX source file, but not present in the ' ..
- 'bibliography files)', 74))
- print(pad('-', 74))
-
- local z = {}
- for _, citation in ipairs(citations) do
- if crossrefs[citation] then
- table.insert(z, crossrefs[citation])
- end
- end
-
- for _, i in ipairs(z) do
- if not exists(i, citations) then
- table.insert(citations, i)
- end
- end
-
- local r = difference(citations, references)
- print()
- print(wrap('Undefined references in your TeX document: ' ..
- tostring(#r), 74))
- if #r == 0 then
- return 0
- else
- for _, v in ipairs(r) do
- print('=> ' .. v)
- end
- return 1
- end
-end
-
--- Reports both unused and undefined references.
--- @param citations Citations.
--- @param references References.
--- @return Integer value indicating the status.
-operations.all = function(citations, references, crossrefs)
- local x, y
- x = operations.unused(citations, references, crossrefs)
- y = operations.undefined(citations, references, crossrefs)
- if x + y > 0 then
- return 1
- else
- return 0
- end
-end
-
--- Filters a table of files, keeping the inexistent ones.
--- @param files Table.
--- @param lib Search library.
--- @param enabled Boolean switch to enable lookup.
--- @param extension Extension for lookup.
--- @return Table of inexistent files.
--- @return Table of existent files.
-local function validate(files, lib, enabled, extension)
- local bad, good = {}, {}
- for _, v in ipairs(files) do
- if not valid(v) then
- if enabled and lookup(lib, v, extension) then
- table.insert(good, lookup(lib, v, extension))
- else
- table.insert(bad, v)
- end
- else
- table.insert(good, v)
- end
- end
- return bad, good
-end
-
--- Main function.
--- @param args Command line arguments.
--- @return Integer value indicating the status
-local function checkcites(args)
-
- local kpse = require('kpse')
- kpse.set_program_name('texlua')
-
- header()
-
- local parameters = {
- { short = 'a', long = 'all', argument = false },
- { short = 'u', long = 'unused', argument = false },
- { short = 'U', long = 'undefined', argument = false },
- { short = 'v', long = 'version', argument = false },
- { short = 'h', long = 'help', argument = false },
- { short = 'c', long = 'crossrefs', argument = false },
- { short = 'b', long = 'backend', argument = true }
- }
-
- local keys, err = parse(parameters, args)
- local check, backend = 'all', 'bibtex'
-
- if #err ~= 0 then
- print()
- print(pad('-', 74))
- print(wrap('I am sorry, but I do not recognize ' ..
- 'the following ' .. plural(#err, 'option',
- 'options') .. ':', 74))
- for _, v in ipairs(err) do
- print('=> ' .. v)
- end
-
- print()
- print(wrap('Please make sure to use the correct ' ..
- 'options when running this script. You ' ..
- 'can also refer to the user documentation ' ..
- 'for a list of valid options. The script ' ..
- 'will end now.', 74))
- return 1
- end
-
- if count(keys) == 0 then
- print()
- print(pad('-', 74))
- print(wrap('I am sorry, but you have not provided ' ..
- 'any command line argument, including ' ..
- 'files to check and options. Make ' ..
- 'sure to invoke the script with the actual ' ..
- 'arguments. Refer to the user documentation ' ..
- 'if you are unsure of how this tool ' ..
- 'works. The script will end now.', 74))
- return 1
- end
-
- if keys['version'] or keys['help'] then
- if keys['version'] then
- print()
- print(wrap('checkcites.lua, version 2.4 (dated September ' ..
- '3, 2019)', 74))
-
- print(pad('-', 74))
- print(wrap('You can find more details about this ' ..
- 'script, as well as the user documentation, ' ..
- 'in the official source code repository:', 74))
-
- print()
- print('https://github.com/cereda/checkcites')
-
- print()
- print(wrap('The checkcites.lua script is licensed ' ..
- 'under the LaTeX Project Public License, ' ..
- 'version 1.3. The current maintainers ' ..
- 'are the original authors.', 74))
- else
- print()
- print(wrap('Usage: ' .. args[0] .. ' [ [ --all | --unused | ' ..
- '--undefined ] [ --backend <arg> ] <file> [ ' ..
- '<file 2> ... <file n> ] | --help | --version ' ..
- ']', 74))
-
- print()
- print('-a,--all list all unused and undefined references')
- print('-u,--unused list only unused references in your bibliography files')
- print('-U,--undefined list only undefined references in your TeX source file')
- print('-c,--crossrefs enable cross-reference checks (disabled by default)')
- print('-b,--backend <arg> set the backend-based file lookup policy')
- print('-h,--help print the help message')
- print('-v,--version print the script version')
-
- print()
- print(wrap('Unless specified, the script lists all unused and ' ..
- 'undefined references by default. Also, the default ' ..
- 'backend is set to "bibtex". Please refer to the user ' ..
- 'documentation for more details.', 74))
- end
- return 0
- end
-
- if not keys['unpaired'] then
- print()
- print(pad('-', 74))
- print(wrap('I am sorry, but you have not provided ' ..
- 'files to process. The tool requires ' ..
- 'least one file in order to properly ' ..
- 'work. Make sure to invoke the script ' ..
- 'with an actual file (or files). Refer ' ..
- 'to the user documentation if you are ' ..
- 'unsure of how this tool works. The ' ..
- 'script will end now.', 74))
- return 1
- end
-
- if keys['backend'] then
- if not exists({ 'bibtex', 'biber' }, keys['backend'][1]) then
- print()
- print(pad('-', 74))
- print(wrap('I am sorry, but you provided an ' ..
- 'invalid backend. I know two: ' ..
- '"bibtex" (which is the default ' ..
- 'one) and "biber". Please make ' ..
- 'sure to select one of the two. ' ..
- 'Also refer to the user documentation ' ..
- 'for more information on how these ' ..
- 'backends work. The script will end ' ..
- 'now.', 74))
- return 1
- else
- backend = keys['backend'][1]
- end
- end
-
- if not keys['all'] then
- if keys['unused'] and keys['undefined'] then
- check = 'all'
- elseif keys['unused'] or keys['undefined'] then
- check = (keys['unused'] and 'unused') or
- (keys['undefined'] and 'undefined')
- end
- end
-
- local auxiliary = apply(keys['unpaired'], function(a)
- return sanitize(a, (backend == 'bibtex'
- and 'aux') or 'bcf') end)
-
- local invalid, _ = validate(auxiliary, kpse, false, 'aux')
- if #invalid ~= 0 then
- print()
- print(pad('-', 74))
- print(wrap('I am sorry, but I was unable to ' ..
- 'locate ' .. plural(#invalid, 'this file',
- 'these files') .. ' (the extension ' ..
- 'is automatically set based on the ' ..
- '"' .. backend .. '" backend):', 74))
- for _, v in ipairs(invalid) do
- print('=> ' .. v)
- end
-
- print()
- print(wrap('Selected backend: ' .. backend, 74))
- print(wrap('File lookup policy: add ".' ..
- ((backend == 'bibtex' and 'aux') or 'bcf') ..
- '" to files if not provided.', 74))
-
- print()
- print(wrap('Please make sure the ' .. plural(#invalid,
- 'path is', 'paths are') .. ' ' ..
- 'correct and the ' .. plural(#invalid,
- 'file exists', 'files exist') .. '. ' ..
- 'There is nothing I can do at the moment. ' ..
- 'Refer to the user documentation for ' ..
- 'details on the file lookup. If ' .. plural(#invalid,
- 'this is not the file', 'these are not the ' ..
- 'files') .. ' you were expecting, ' ..
- 'double-check your source file or ' ..
- 'change the backend option when running ' ..
- 'this tool. The script will end now.', 74))
- return 1
- end
-
- local lines = flatten(apply(auxiliary, read))
- local asterisk, citations, bibliography = backends[backend](lines, true)
-
- print()
- print(wrap('Great, I found ' .. tostring(#citations) .. ' ' ..
- plural(#citations, 'citation', 'citations') .. ' in ' ..
- tostring(#auxiliary) .. ' ' .. plural(#auxiliary, 'file',
- 'files') ..'. I also found ' .. tostring(#bibliography) ..
- ' ' .. 'bibliography ' .. plural(#bibliography, 'file',
- 'files') .. '. Let me check ' .. plural(#bibliography,
- 'this file', 'these files') .. ' and extract the ' ..
- 'references. Please wait a moment.', 74))
-
- if asterisk then
- print()
- print(wrap('Also, it is worth noticing that I found a mention to ' ..
- 'a special "*" when retrieving citations. That means ' ..
- 'your TeX document contains "\\nocite{*}" somewhere in ' ..
- 'the source code. I will continue with the check ' ..
- 'nonetheless.', 74))
- end
-
- bibliography = apply(bibliography, function(a)
- return sanitize(a, 'bib') end)
-
- invalid, bibliography = validate(bibliography, kpse, true, 'bib')
- if #invalid ~= 0 then
- print()
- print(pad('-', 74))
- print(wrap('I am sorry, but I was unable to locate ' ..
- plural(#invalid, 'this file', 'these files') .. ' ' ..
- '(the extension is automatically set to ' ..
- '".bib", if not provided):', 74))
- for _, v in ipairs(invalid) do
- print('=> ' .. v)
- end
-
- print()
- print(wrap('Please make sure the ' .. plural(#invalid,
- 'path is', 'paths are') .. ' ' ..
- 'correct and the ' .. plural(#invalid,
- 'file exists', 'files exist') .. '. ' ..
- 'There is nothing I can do at the moment. ' ..
- 'Refer to to the user documentation ' ..
- 'for details on bibliography lookup. If ' ..
- plural(#invalid, 'this is not the file',
- 'these are not the files') .. ' you were ' ..
- 'expecting (wrong bibliography), double-check ' ..
- 'your source file. The script will end ' ..
- 'now.', 74))
- return 1
- end
-
- local references = flatten(apply(bibliography, function(a)
- return extract(read(a)) end))
-
- local crossrefs = (keys['crossrefs'] and organize(apply(bibliography,
- function(a) return crossref(read(a)) end))) or {}
-
- print()
- print(wrap('Fantastic, I found ' .. tostring(#references) ..
- ' ' .. plural(#references, 'reference',
- 'references') .. ' in ' .. tostring(#bibliography) ..
- ' bibliography ' .. plural(#bibliography, 'file',
- 'files') .. '. Please wait a moment while the ' ..
- plural(((check == 'all' and 2) or 1), 'report is',
- 'reports are') .. ' generated.', 74))
-
- return operations[check](citations, references, crossrefs)
-end
-
--- Call and exit
-os.exit(checkcites(arg))
-
--- EOF
diff --git a/Build/source/texk/texlive/linked_scripts/checklistings/checklistings.sh b/Build/source/texk/texlive/linked_scripts/checklistings/checklistings.sh
deleted file mode 100755
index 4131d9acbc4..00000000000
--- a/Build/source/texk/texlive/linked_scripts/checklistings/checklistings.sh
+++ /dev/null
@@ -1,446 +0,0 @@
-#!/bin/sh
-#
-# checklistings #
-# version 1.0 #
-# #
-# Timothy Bourke <tim@tbrk.org> #
-# Inria #
-# École normale supérieure #
-# #
-# Marc Pouzet <pouzet@ens.fr> #
-# Université Pierre et Marie Curie #
-# École normale supérieure #
-# Inria #
-#
-
-##
-# Configuration
-SCRIPT=$(basename "$0")
-SUFFIX=.chkl
-
-RED=""
-BLUE=""
-BLACK=""
-
-ADJUSTLINETEXT=line
-
-##
-# Command-line
-
-usage () {
- printf '%s: check source code exported from LaTeX documents.\n' "$SCRIPT"
- printf 'usage: %s [options] [file ...]\n' "$SCRIPT"
- printf '\n'
- printf ' options:\n'
- printf ' --no-colors log to terminal without control codes\n'
- printf ' --no-line-adjust do not try to adjust error line numbers\n'
- printf '\n'
-}
-
-unset INFILES
-while [ -n "$1" ]; do
- case "$1" in
- --no-colors)
- unset RED BLUE BLACK
- ;;
- --no-line-adjust)
- unset ADJUSTLINETEXT
- ;;
- --h)
- usage
- exit 0
- ;;
- --help)
- usage
- exit 0
- ;;
- -*)
- printf "%s: unrecognized option '%s'\n" "$SCRIPT" "$1"
- usage
- exit 1
- ;;
- *${SUFFIX})
- INFILES="$INFILES $1"
- ;;
- *)
- INFILES="$INFILES $1${SUFFIX}"
- ;;
- esac
- shift
-done
-
-if [ -z "$INFILES" ]; then
- INFILES=$(ls ./*${SUFFIX})
-fi
-
-##
-# Allocate temporary files
-
-cleanup() {
- rm -f "${OUTFILE}" "${ERRFILE}"
-}
-OUTFILE=$(mktemp -t "${SCRIPT}.out.XXXXXX") || exit 1
-ERRFILE=$(mktemp -t "${SCRIPT}.err.XXXXXX") || (cleanup; exit 1)
-trap cleanup 1 2 15
-
-##
-# Code
-
-#
-# Given
-# var a variable to store the result
-# name the filename prefix
-# num an id number
-# generate a filename from name and num and store it in var.
-#
-setfilename() {
- var="$1"
- name="$2"
- num="$3"
- if [ "$num" -lt 10 ]; then
- eval "$var='${name}000${num}'"
- elif [ "$num" -lt 100 ]; then
- eval "$var='${name}00${num}'"
- elif [ "$num" -lt 1000 ]; then
- eval "$var='${name}0${num}'"
- else
- eval "$var='${name}${num}'"
- fi
-}
-
-#
-# If the WITHOPEN option is set, create a modified program text (with a
-# different name) whose first lines import dependencies.
-# Args:
-# filename the id of the program text
-# openfilenums its dependencies (id list)
-#
-addopen() {
- filename="$1"
- openfilenums="$2"
- unset of f
-
- if [ -n "$WITHOPEN" ]; then
- setfilename f "$PREFIX" "$filename"
- if [ -f "$SUBDIR$f$EXT" ]; then
-
- openfiles=""
- for n in $openfilenums; do
- setfilename of "$WITHOPEN" "$n"
- # shellcheck disable=SC2154
- openfiles="$openfiles ${INCLUDECMD} $of"
- done
-
- setfilename of "$WITHOPEN" "$filename"
- if [ -n "$openfiles" ]; then
- addedlines=$((addedlines + 1))
- printf '%s \n' "$openfiles" > "$SUBDIR$of$EXT"
- cat "$SUBDIR$f$EXT" >> "$SUBDIR$of$EXT"
- else
- cat "$SUBDIR$f$EXT" > "$SUBDIR$of$EXT"
- fi
- fi
- fi
-}
-
-# A filename string for sed that ignores the case (BSD sed has no i flag)
-makeicfilename() {
- IFILENAME=""
- for l in $(printf "%s" "$FILENAME" | sed -e 's/\(.\)/\1 /g'); do
- L="$(printf "%s" "$l" | tr "[:lower:]" "[:upper:]")"
- IFILENAME="${IFILENAME}[$L$l]"
- done
-}
-
-#
-# Given
-# $ERRFILE path to the file containing error messages
-# $ADJUSTLINETEXT the text preceding the line number (default: "line")
-# if empty or unset, no adjustments are made.
-# $addedlines the amount by which to decrement line numbers
-#
-adjustlinenumbers() {
- if [ -n "$ADJUSTLINETEXT" ]; then
- printf '' > "$ERRFILE-adjusted"
- while read line
- do
- linen=$(expr "$line" : ".*$ADJUSTLINETEXT *\([0-9][0-9]*\).*")
- if [ -n "$linen" ]; then
- before=$(expr "$line" : "^\(.*$ADJUSTLINETEXT *\)$linen.*$")
- after=$(expr "$line" : "^.*$ADJUSTLINETEXT *$linen\(.*\)$")
- newlinen=$((linen - addedlines))
- printf "%s%s%s\n" "$before" "$newlinen" "$after" \
- >> "$ERRFILE-adjusted"
- else
- printf "%s\n" "$line" >> "$ERRFILE-adjusted"
- fi
- done < "$ERRFILE"
- mv "$ERRFILE-adjusted" "$ERRFILE"
- fi
-}
-
-#
-# Given
-# num a program (id)
-# openfilenums its dependencies (id list)
-# (Try to) Compile the program and create a corresponding .tex file that
-# summarizes the results for reading back into the source document.
-#
-compile() {
- num="$1"
- openfilenums="$2"
- unset ifile ofile outf of FILENAME
-
- # Decide whether to use the original program source or the version
- # augmented to import dependencies.
- if [ -n "$WITHOPEN" ]; then
- FILENAME=${WITHOPEN}
- else
- FILENAME=${PREFIX}
- fi
- makeicfilename
-
- # Generate the program (ifile) and output (ofile) filenames
- setfilename ifile "$FILENAME" "$num"
- # shellcheck disable=SC2154
- ipath="$SUBDIR$ifile$EXT"
- setfilename ofile "$PREFIX" "$num"
- # shellcheck disable=SC2154
- opath="$SUBDIR$ofile.tex"
- opath_msg="$SUBDIR$ofile.msg"
- opath_err="$SUBDIR$ofile.err"
- opath_html="$SUBDIR$ofile.html"
-
- # Check that the input file exists
- if [ -f "$ipath" ]; then
- printf '> %s%s...%s\n' "$BLUE" "$ofile$EXT" "$BLACK"
- else
- printf '%s> %s%s: program source not found.%s\n' \
- "$RED" "$ofile" "$EXT" "$BLACK"
- return 1
- fi
-
- # Generate a list of dependency filenames to pass to the compiler
- openfiles=""
- for n in $openfilenums; do
- setfilename of "$FILENAME" "$n"
- openfiles="$openfiles $SUBDIR$of$EXT"
- done
-
- # Invoke the compiler
- # shellcheck disable=SC2086
- $COMPILER $COMPILERFLAGS $openfiles $LASTFLAGS "$ipath" \
- >"$OUTFILE" 2>"$ERRFILE"
- COMPILERSTATUS=$?
- adjustlinenumbers
-
- # Start the output tex file with the compilation command as a comment
- printf '%% %s\n' "$COMPILER $COMPILERFLAGS $openfiles \
- $LASTFLAGS $ipath ($COMPILERSTATUS)" > "$opath"
-
- # Signal compilation success (\chklistingtrue) or not (\chklistingfalse)
- if [ "$COMPILERSTATUS" -eq 0 ]; then
- printf '\\chklistingtrue\n' >> "$opath"
- if [ "$SHOULDFAIL" -eq 1 ]; then
- printf '%s unexpected success (line %s/ page %s)!%s\n' \
- "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2
- fi
- else
- printf '\\chklistingfalse\n' >> "$opath"
- if [ "$SHOULDFAIL" -eq 0 ]; then
- printf "%s unexpected failure (line %s / page %s)!%s\n" \
- "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2
- while read line
- do
- printf " | %s\n" "$line"
- done < "$ERRFILE" >&2
- fi
- fi
-
- # Include a sanitized compilation command (\setchklistingcmd)
- printf '\setchklistingcmd{%s %s \\chklistingfile}\n' \
- "${COMPILERNAME}" "${LASTFLAGS}" >> "$opath"
-
- # Include the compiler's stdout
- printf "%s\n" '\begin{ChkListingMsg}' >> "$opath"
- if [ "$(wc -l < "$OUTFILE")" -eq 0 ]; then
- printf "Failed.\n" >> "$opath"
- else
- sed -e "s#$SUBDIR$ifile#$PREFIX#g" \
- -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \
- "$OUTFILE" > "$opath_msg"
- cat "$opath_msg" >> "$opath"
- fi
- printf "%s\n" '\end{ChkListingMsg}' >> "$opath"
-
- # Include the compiler's stderr
- printf "%s\n" '\begin{ChkListingErr}' >> "$opath"
- if [ "$(wc -l < "$ERRFILE")" -eq 0 ]; then
- printf "%s\n" "Success." >> "$opath"
- else
- sed -e "s#$SUBDIR$ifile#$PREFIX#g" \
- -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \
- "$ERRFILE" > "$opath_err"
- cat "$opath_err" >> "$opath"
- fi
- printf "%s\n" '\end{ChkListingErr}' >> "$opath"
-
- # Filter to html if necessary
- if [ -n "$HTMLFILTER" ]; then
- # shellcheck disable=SC2086
- if [ "$HTMLFILTER" = "cat" ]; then
- printf '<pre>\n' > "$opath_html"
- $HTMLFILTER "$ipath" >> "$opath_html"
- printf '</pre>\n' >> "$opath_html"
- else
- $HTMLFILTER "$ipath" > "$opath_html"
- fi
- fi
-
- return 0
-}
-
-locked=
-dooption() {
- opt_name="$1"
- opt_value="$2"
-
- case "$opt_name" in
- lock\ *)
- opt_name=${opt_name#lock }
- locked="$locked $opt_name "
- ;;
- *)
- if [ "$(expr "$locked" : ".* $opt_name .*")" -ne 0 ]; then
- printf \
- 'info: %s: ignoring locked option ''%s''\n' \
- "$infile" "$opt_name" >&2
- return
- fi
- ;;
- esac
-
- case "$opt_name" in
- subdir)
- SUBDIR="$opt_value" ;;
- prefix)
- PREFIX="$opt_value" ;;
- ext)
- EXT="$opt_value" ;;
- compiler)
- COMPILER="${opt_value}"
- COMPILERNAME="$(basename "${COMPILER}")"
- ;;
- compilerflags)
- COMPILERFLAGS="${opt_value}" ;;
- lastflags)
- LASTFLAGS="${opt_value}" ;;
- includecmd)
- INCLUDECMD="${opt_value}"
- if [ -z "$INCLUDECMD" ]; then
- WITHOPEN=
- else
- WITHOPEN=Withopen
- fi
- ;;
- htmlfilter)
- HTMLFILTER="${opt_value}" ;;
- esac
-}
-
-subdirs=
-readchkl() {
- infile=$1
- unset l existing openfilenums filenum opennums
-
- # Process each line of the command file
- while read l; do
- addedlines=0
- case $l in
- [[:digit:]]*:*)
- # a snippet to be compiled
- filenum=$(expr "$l" : '\(.*\):.*')
- openfilenums=$(expr "$l" : '.*:\(.*\)')
-
- # build up a list of dependencies in opennums
- opennums=""
- for n in $openfilenums; do
- case $n in
- \[page=*)
- PAGENUM=$(expr "$n" : '\[page=\(.*\)\]')
- if [ "$PAGENUM" = "" ]; then
- PAGENUM="unknown"
- fi
- ;;
- \])
- # ignore invalid patterns when checklistings.sty
- # cannot expand \thepage properly (due to a
- # conflicting package setting) and instead produces
- # '[page=\thepage ]' which is read as two tokens:
- # '[page=\thepage' and ']'.
- ;;
- \[line=*\])
- LINENUM=$(expr "$n" : '\[line=\(.*\)\]')
- ;;
- \[fail\])
- SHOULDFAIL=1
- ;;
- \[skip=*\])
- addedlines=$(expr "$n" : '\[skip=\([0-9][0-9]*\)\]')
- ;;
- *)
- if [ "$n" -eq "$n" ] 2>/dev/null; then
- opennums="$opennums $n"
- else
- printf \
- "%swarning: %s: ignoring unresolved include '%s'%s\n" \
- "$RED" "$filenum" "$n" "$BLACK" >&2
- fi
- ;;
- esac
- done
-
- addopen "$filenum" "$opennums"
- compile "$filenum" "$opennums"
- ;;
-
- *=*)
- n="$(expr "$l" : '\([^=]*\)=.*')"
- v="$(expr "$l" : '.*=\(.*\)')"
- dooption "$n" "$v"
- if [ "$n" = "subdir" ]; then
- existing=$(expr "$subdirs" : ".*::${SUBDIR}:\\([^:]*\\):.*")
- if [ -n "$existing" ]; then
- printf "%swarning: %s: subdir=%s already used by %s!%s\n" \
- "$RED" "$infile" "$SUBDIR" "$existing" "$BLACK" >&2
- fi
- fi
- ;;
-
- *)
- if [ -n "$l" ]; then
- printf "%sbad %s: %s%s\n" "$RED" "$infile" "$l" "$BLACK" >&2
- fi
- ;;
- esac
- unset PAGENUM
- unset LINENUM
- SHOULDFAIL=0
- done < "$1"
- subdirs="$subdirs::$SUBDIR:$infile:"
-}
-
-# Loop through each checklistings command file
-for f in ${INFILES}; do
-
- # Add the suffix if necessary (as latex does)
- case $f in
- *${SUFFIX}) ;;
- *) infile="$f$SUFFIX" ;;
- esac
-
- readchkl "$f"
-done
-
-cleanup
-
diff --git a/Build/source/texk/texlive/linked_scripts/chklref/chklref.pl b/Build/source/texk/texlive/linked_scripts/chklref/chklref.pl
deleted file mode 100755
index 6e8ba38e27f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/chklref/chklref.pl
+++ /dev/null
@@ -1,337 +0,0 @@
-#!/usr/bin/env perl -w
-
-#########################################################################
-# Written and (C) by JĂ©rĂ´me Lelong <jerome.lelong@gmail.com> #
-# #
-# This program is free software; you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation; either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-#########################################################################
-
-use strict;
-use warnings;
-use File::Basename;
-use Cwd;
-use Getopt::Long;
-# recognised math environments
-my @have_star_modes = qw( equation eqnarray align multline table gather);
-my $have_star_mode = join('|', @have_star_modes);
-$have_star_mode = "($have_star_mode)";
-
-
-my $TEX = 'pdflatex';
-my $TEXOPTIONS = ' -interaction nonstopmode ';
-my $USERTEXOPTIONS = '';
-my $RUNQUIET = 0;
-my $RUNDEBUG = 0;
-my $PARSEONLY = 0;
-
-# Create a hash with three keys "str", "line", "file" and returns a
-# reference to it
-#
-# Input: 3 args
-# a string
-# a line number
-# a filename
-sub new_ref {
- my ($str, $line, $file) = @_;
- my $ref = {};
- $ref->{str} = $str;
- $ref->{line} = $line;
- $ref->{file} = $file;
- return $ref;
-}
-
-# Create a hash with six keys "str", "begin", "end", "star",
-# "label_line" and "label" and returns a reference to it.
-#
-# Input : 7 args
-# a string (the env name)
-# line of beginning
-# line of end
-# has the env a star?
-# line on which the label appears
-# value of the label
-# file name
-sub new_math_env {
- my ($str, $begin, $end, $star, $label_line, $label, $file) = @_;
- my $this = {};
- $this->{str} = $str;
- $this->{begin} = $begin;
- $this->{end} = $end;
- $this->{star} = $star;
- $this->{label_line} = $label_line;
- $this->{label} = $label;
- $this->{file} = $file;
- return $this;
-}
-
-
-# Parse .chk file and looks for the environments defined by
-# @have_star_modes. The first and last line of the environment are stored
-# along with the name of the environment. One last variable is
-# used to remember if the star version was used.
-#
-# Input:
-# a chk file content
-# entries
-# refs
-# labels
-# the last 3 args are passed as references and are modified
-sub chk_parse {
- my ($txt, $entries, $refs, $labels, $citations, $bibcites) = @_;
- my ($str, $begin, $end, $star, $labelled_env, $label, $file, $entry, $l);
-
- while (defined($l = shift(@$txt))) {
- if ($l =~ m/^label (.+) line (\d+) file (.+)\n$/o) {
- push(@$labels, new_ref($1, $2, $3));
- }
- elsif ($l =~ m/^ref (.+) line (\d+) file (.+)$/o) {
- push(@$refs, new_ref($1, $2, $3));
- }
- elsif ($l =~ m/^citation (.+) line (\d+) file (.+)$/o) {
- foreach my $c (split(/\s*,\s*/, $1)) {
- ${$citations}{$c} = 1;
- }
- }
- elsif ($l =~ m/^bibcite (.+) line (\d+) file (.+)$/o) {
- push(@$bibcites, $1);
- }
- elsif ($l =~ m/^begin\{$have_star_mode(\**)\} line (\d+) file (.+)$/o) {
- $str = $1;
- $star = 1;
- $star = 0 unless ($2);
- $begin = $3;
- $file = $4;
- $label = "";
- $labelled_env = 0;
- while (defined($l = shift(@$txt))) {
- if ($l =~ m/^label (.+) line (\d+) file (.+)$/o) {
- push(@$labels, new_ref($1, $2, $3));
- $label = $1;
- $labelled_env = $2;
- }
- elsif ($l =~ m/^ref (.+) line (\d+) file (.+)$/o) {
- push(@$refs, new_ref($1, $2, $3));
- }
- elsif ($l =~ m/^end\{$str\*{$star}\} line (\d+) file (.+)$/) {
- $end = $1;
- $entry = new_math_env($str, $begin, $end, $star, $labelled_env,
- $label, $file);
- push(@$entries, $entry);
- last;
- }
- }
- }
- }
- return;
-}
-
-# Find environments with both labels and stars
-# Input : list of entries
-sub star_label {
- my ($entries) = @_;
- print "************************************\n";
- print "** Labels in starred environments **\n";
- print "************************************\n";
- foreach my $e (@$entries) {
- printf("-- %-20s line %4d: remove label %s \n",
- $e->{file}, $e->{label_line}, $e->{label})
- if (($e->{star} == 1) && ($e->{label_line} > 0));
-
- printf("-- %-20s line %4d: consider using a STAR environment\n",
- $e->{file}, $e->{begin})
- if (($e->{star} == 0) && ($e->{label_line} == 0));
- }
- print "\n";
- return;
-}
-
-# Find labels without any corrsponding references.
-# references must be sorted
-sub unused_label {
- my ($labels, $refs) = @_;
- my $found;
-
- print "*******************\n";
- print "** Unused Labels **\n";
- print "*******************\n";
- foreach my $l (@$labels) {
- $found = 0;
- foreach my $r (@$refs) {
- if ($r->{str} eq $l->{str}) {
- $found = 1;
- last;
- }
- elsif ($r->{str} ge $l->{str}) {
- last;
- }
- }
- printf("-- %-20s line %4d: remove label %s\n",
- $l->{file}, $l->{line}, $l->{str})
- if (!$found);
- }
- print "\n";
- return;
-}
-
-# Find bibitems without any corresponding \cite
-sub unused_cites {
- my ($bibcites, $citations) = @_;
- print "**********************************\n";
- print "** Uncited Bibliography entries **\n";
- print "**********************************\n";
- foreach my $c (@$bibcites) {
- print("remove bibitem : $c\n") unless exists ${$citations}{$c};
- }
- return;
-}
-
-# Find and remove duplicates in an
-# array of { str, line } entries.
-# Note that the array must be sorted according to str
-# Input : ref or label list
-# Return the corresponding list
-sub rm_duplicate {
- my ($array) = @_;
- my $prev = '___________not_a_true_label______';
- my @uniq_array =
- grep { $_->{str} ne $prev && (($prev) = $_->{str}) } @$array;
- return \@uniq_array;
-}
-
-# Display all math envs with their characteristics
-# Input args
-# line of beginning
-# line of end
-# starred or not
-# label
-sub disp_msg {
- my ($entries) = @_;
- my @entries = @$entries;
-
- foreach my $e (@entries) {
- print("env $e->{str} \n");
- print("\tbeginning : $e->{begin}\n\tend : $e->{end}\n");
- print("\tstar environment\n") if ($e->{star} == 1);
- print("\tlabelled environement\n") if ($e->{label} > 0);
- print("\n");
- }
- return;
-}
-
-sub parse {
- my ($chkfile) = @_;
- my @entries = ();
- my @refs = ();
- my @labels = ();
- my %citations = ();
- my @bibcites = ();
- my $FIC;
-
- # Read the whole file to an array because label and end commands
- # generally need to be swapped.
- open($FIC, '<', $chkfile) or die("open: $!");
- my @txt = <$FIC>;
- close($FIC);
-
- chk_parse(\@txt, \@entries, \@refs, \@labels, \%citations, \@bibcites);
-
- @labels = sort { $a->{line} cmp $b->{line} } @labels;
- @refs = sort { $a->{str} cmp $b->{str} } @refs;
- my $uniq_refs = rm_duplicate(\@refs);
- star_label(\@entries);
- #disp_msg( \@entries );
- unused_label(\@labels, $uniq_refs);
- unused_cites(\@bibcites, \%citations);
-}
-
-sub usage {
- print << 'EOT';
-Usage: chklref [options] texfile
-
-Check unused labels and bibitems in a LaTeX file
-
-Options:
- --tex <compiler>, -t Specify the TeX compiler to be used. Default is `pdflatex`.
- --tex-options List of options to pass to the TeX compiler. It should be a quoted
- string of white space delimited options. Note that we always add
- `-interaction nonstopmode` on top of these options.
- --debug, -d Run in debug mode. Do not clean the generated `.chk` file.
- --quiet, -q Run in quiet mode. Do not print the output of the TeX compiler.
- --parse-only Do not run the LaTeX compiler but use the already existing `.chk` file.
- When this option is passed, the following other options are meaningless:
- `--tex`, `--tex-options`, `--quiet`, `--debug`.
- --version, -v Print the version of this script.
- --help,h Print this help.
-
-
-Report bugs to https://github.com/jlelong/chklref. `chklref` is known not to work with `cleveref`. If you would like to contribute to `chklref`, feel free to open a PR on https://github.com/jlelong/chklref.
-EOT
- exit(0)
-}
-
-sub version {
- print << 'EOT';
-chklref 3.1.2
-
-Copyright 2005-2019 Jerome Lelong <jerome.lelong@gmail.com>.
-This program comes with ABSOLUTELY NO WARRANTY.
-This is free software, and you are welcome to redistribute it under GPLv3.
-
-Written by Jerome Lelong <jerome.lelong@gmail.com>
-EOT
- exit(0)
-}
-
-sub texcompile {
- my ($texfile, $basetexfile) = @_;
- print "Running $TEX $TEXOPTIONS $USERTEXOPTIONS \"$texfile\" to collect labels references and environment declarations\n\n";
- my $texoutput = `$TEX $TEXOPTIONS $USERTEXOPTIONS "$texfile" 2>&1`;
- print($texoutput) unless $RUNQUIET;
- unlink($basetexfile . '.chk');
- $texoutput = `$TEX $TEXOPTIONS $USERTEXOPTIONS --jobname "$basetexfile" '\\RequirePackage{chklref}\\input' "{$texfile}" 2>&1`;
- print($texoutput) unless $RUNQUIET;
-}
-
-Getopt::Long::Configure ("bundling");
-GetOptions (
- 'version|v!' => \&version,
- 'quiet|q!' => \$RUNQUIET,
- 'debug|d!' => \$RUNDEBUG,
- 'tex|t=s' => \$TEX,
- 'texoptions=s' => \$USERTEXOPTIONS,
- 'parse-only' => \$PARSEONLY,
- 'help|h' => \&usage
-) || usage();
-
-if (@ARGV != 1) {
- usage();
- exit 0;
-}
-
-my $texfile = $ARGV[0];
-my $cwd = getcwd();
-my $dirtexfile = dirname($texfile);
-my $basetexfile = basename($texfile, '.tex');
-my $chkfile = $basetexfile . '.chk';
-chdir($dirtexfile);
-if ($PARSEONLY) {
- parse($chkfile);
-}
-else {
- texcompile($texfile, $basetexfile);
- parse($chkfile);
- if (! $RUNDEBUG) {
- unlink($chkfile);
- }
-} \ No newline at end of file
diff --git a/Build/source/texk/texlive/linked_scripts/cjk-gs-integrate/cjk-gs-integrate.pl b/Build/source/texk/texlive/linked_scripts/cjk-gs-integrate/cjk-gs-integrate.pl
deleted file mode 100755
index 68ea6e6198b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/cjk-gs-integrate/cjk-gs-integrate.pl
+++ /dev/null
@@ -1,2861 +0,0 @@
-#!/usr/bin/env perl
-#
-# cjk-gs-integrate - setup Ghostscript for CID/TTF CJK fonts
-#
-# Copyright 2015-2020 by Norbert Preining
-# Copyright 2016-2020 by Japanese TeX Development Community
-#
-# This work is based on research and work by (in alphabetical order)
-# Masamichi Hosoda
-# Yusuke Kuroki
-# Yusuke Terada
-# Bruno Voisin
-# Munehiro Yamamoto
-# Hironobu Yamashita
-# and the Japanese TeX Q&A wiki page
-#
-# This file is licensed under GPL version 3 or any later version.
-# For copyright statements see end of file.
-#
-# For development see
-# https://github.com/texjporg/cjk-gs-support
-#
-# LIMITATIONS:
-# - Running the script (with default mode = actual setup/removing operations)
-# always overwrites "cidfmap.local" and "cidfmap.aliases" without asking,
-# whose file names might be common enough. If you choose to run the script,
-# leave these files untouched. (Do NOT edit these files by yourself!)
-# (This note also applies to MacTeX pre-shipped configuration files.)
-#
-# TODO:
-# - interoperability with kanji-config-updmap
-#
-# Note that symlink names should be consistent with ptex-fontmaps!
-
-use Getopt::Long qw(:config no_autoabbrev ignore_case_always);
-use File::Basename;
-use File::Path qw(make_path);
-use Cwd 'abs_path';
-use strict;
-use warnings;
-use utf8;
-use feature 'state';
-use Encode;
-use Encode::Alias;
-
-my $debug_msg_before_init;
-init_encode_locale ();
-
-binmode (STDIN, ':encoding(console_in)');
-binmode (STDOUT, ':encoding(console_out)');
-binmode (STDERR, ':encoding(console_out)');
-
-@ARGV = map{ decode('locale', $_) }@ARGV;
-
-(my $prg = basename(decode('locale', $0))) =~ s/\.pl$//;
-my $version = '20201206.0';
-
-if (win32()) {
- # some perl functions (symlink, -l test) does not work
- print_warning("Sorry, we have only partial support for Windows!\n");
-
- require Win32::API;
- Win32::API->import ();
- require File::Compare;
- File::Compare->import ();
-}
-
-# The followings are installed by ptex-fontmaps (texjporg):
-# * 2004-H
-# * 2004-V
-# The followings are created by Adobe but not considered official
-# (see https://forums.adobe.com/thread/537415)
-# * GB-RKSJ-H
-# * GBT-RKSJ-H
-# * KSC-RKSJ-H
-# All others are provided in the latest Adobe CMap Resources:
-# https://github.com/adobe-type-tools/cmap-resources
-my %encode_list = (
- Japan => [ qw/
- 2004-H
- 2004-V
- 78-EUC-H
- 78-EUC-V
- 78-H
- 78-RKSJ-H
- 78-RKSJ-V
- 78-V
- 78ms-RKSJ-H
- 78ms-RKSJ-V
- 83pv-RKSJ-H
- 90ms-RKSJ-H
- 90ms-RKSJ-V
- 90msp-RKSJ-H
- 90msp-RKSJ-V
- 90pv-RKSJ-H
- 90pv-RKSJ-V
- Add-H
- Add-RKSJ-H
- Add-RKSJ-V
- Add-V
- Adobe-Japan1-0
- Adobe-Japan1-1
- Adobe-Japan1-2
- Adobe-Japan1-3
- Adobe-Japan1-4
- Adobe-Japan1-5
- Adobe-Japan1-6
- Adobe-Japan1-7
- EUC-H
- EUC-V
- Ext-H
- Ext-RKSJ-H
- Ext-RKSJ-V
- Ext-V
- H
- Hankaku
- Hiragana
- Identity-H
- Identity-V
- Katakana
- NWP-H
- NWP-V
- RKSJ-H
- RKSJ-V
- Roman
- UniJIS-UCS2-H
- UniJIS-UCS2-HW-H
- UniJIS-UCS2-HW-V
- UniJIS-UCS2-V
- UniJIS-UTF16-H
- UniJIS-UTF16-V
- UniJIS-UTF32-H
- UniJIS-UTF32-V
- UniJIS-UTF8-H
- UniJIS-UTF8-V
- UniJIS2004-UTF16-H
- UniJIS2004-UTF16-V
- UniJIS2004-UTF32-H
- UniJIS2004-UTF32-V
- UniJIS2004-UTF8-H
- UniJIS2004-UTF8-V
- UniJISPro-UCS2-HW-V
- UniJISPro-UCS2-V
- UniJISPro-UTF8-V
- UniJISX0213-UTF32-H
- UniJISX0213-UTF32-V
- UniJISX02132004-UTF32-H
- UniJISX02132004-UTF32-V
- V
- WP-Symbol
- / ],
- GB => [ qw/
- Adobe-GB1-0
- Adobe-GB1-1
- Adobe-GB1-2
- Adobe-GB1-3
- Adobe-GB1-4
- Adobe-GB1-5
- GB-EUC-H
- GB-EUC-V
- GB-H
- GB-RKSJ-H
- GB-V
- GBK-EUC-H
- GBK-EUC-V
- GBK2K-H
- GBK2K-V
- GBKp-EUC-H
- GBKp-EUC-V
- GBT-EUC-H
- GBT-EUC-V
- GBT-H
- GBT-RKSJ-H
- GBT-V
- GBTpc-EUC-H
- GBTpc-EUC-V
- GBpc-EUC-H
- GBpc-EUC-V
- Identity-H
- Identity-V
- UniGB-UCS2-H
- UniGB-UCS2-V
- UniGB-UTF16-H
- UniGB-UTF16-V
- UniGB-UTF32-H
- UniGB-UTF32-V
- UniGB-UTF8-H
- UniGB-UTF8-V
- / ],
- CNS => [ qw/
- Adobe-CNS1-0
- Adobe-CNS1-1
- Adobe-CNS1-2
- Adobe-CNS1-3
- Adobe-CNS1-4
- Adobe-CNS1-5
- Adobe-CNS1-6
- Adobe-CNS1-7
- B5-H
- B5-V
- B5pc-H
- B5pc-V
- CNS-EUC-H
- CNS-EUC-V
- CNS1-H
- CNS1-V
- CNS2-H
- CNS2-V
- ETHK-B5-H
- ETHK-B5-V
- ETen-B5-H
- ETen-B5-V
- ETenms-B5-H
- ETenms-B5-V
- HKdla-B5-H
- HKdla-B5-V
- HKdlb-B5-H
- HKdlb-B5-V
- HKgccs-B5-H
- HKgccs-B5-V
- HKm314-B5-H
- HKm314-B5-V
- HKm471-B5-H
- HKm471-B5-V
- HKscs-B5-H
- HKscs-B5-V
- Identity-H
- Identity-V
- UniCNS-UCS2-H
- UniCNS-UCS2-V
- UniCNS-UTF16-H
- UniCNS-UTF16-V
- UniCNS-UTF32-H
- UniCNS-UTF32-V
- UniCNS-UTF8-H
- UniCNS-UTF8-V
- / ],
- Korea => [ qw/
- Adobe-Korea1-0
- Adobe-Korea1-1
- Adobe-Korea1-2
- Identity-H
- Identity-V
- KSC-EUC-H
- KSC-EUC-V
- KSC-H
- KSC-Johab-H
- KSC-Johab-V
- KSC-RKSJ-H
- KSC-V
- KSCms-UHC-H
- KSCms-UHC-HW-H
- KSCms-UHC-HW-V
- KSCms-UHC-V
- KSCpc-EUC-H
- KSCpc-EUC-V
- UniKS-UCS2-H
- UniKS-UCS2-V
- UniKS-UTF16-H
- UniKS-UTF16-V
- UniKS-UTF32-H
- UniKS-UTF32-V
- UniKS-UTF8-H
- UniKS-UTF8-V
- / ] );
-
-#
-# location where links to fonts in texmf are created, relative to TEXMF
-my $otf_pathpart = "fonts/opentype/cjk-gs-integrate";
-my $ttf_pathpart = "fonts/truetype/cjk-gs-integrate";
-
-# location where cidfmap, cidfmap.local and cidfmap.aliases are placed
-# when found gs is tlgs (win32), then files will be placed in lib/ instead of Resource/Init/
-my $cidfmap_pathpart = "Init/cidfmap";
-my $cidfmap_local_pathpart = "Init/cidfmap.local";
-my $cidfmap_aliases_pathpart = "Init/cidfmap.aliases";
-
-# support for ps2otfps by Akira Kakuto
-my $akotfps_pathpart = "dvips/ps2otfps";
-my $akotfps_datafilename = "psnames-for-otf";
-my $akotfps_datacontent = '';
-
-# dump output for data file (for easy editing for users)
-my $dump_datafile = "$prg-data.dat";
-
-my $opt_output;
-my $opt_fontdef;
-my @opt_fontdef_add;
-my @opt_aliases;
-my $opt_filelist;
-my $opt_texmflink;
-my $opt_akotfps;
-my $opt_force = 0;
-my $opt_remove = 0;
-my $opt_cleanup = 0;
-my $opt_hardlink = 0;
-my $opt_winbatch;
-my $opt_dump_data;
-my $opt_only_aliases = 0;
-my $opt_listaliases = 0;
-my $opt_listallaliases = 0;
-my $opt_listfonts = 0;
-my $opt_info = 0;
-my $opt_machine = 0;
-my $opt_strictpsname = 0;
-my $dry_run = 0;
-my $opt_quiet = 0;
-my $opt_debug = 0;
-my $opt_help = 0;
-my $opt_markdown = 0;
-
-if (! GetOptions(
- "o|output=s" => \$opt_output,
- "f|fontdef=s" => \$opt_fontdef,
- "fontdef-add=s" => \@opt_fontdef_add,
- "a|alias=s" => \@opt_aliases,
- "filelist=s" => \$opt_filelist,
- "link-texmf:s" => \$opt_texmflink,
- "otfps:s" => \$opt_akotfps,
- "force" => \$opt_force,
- "remove" => \$opt_remove,
- "cleanup" => \$opt_cleanup,
- "hardlink" => \$opt_hardlink,
- "winbatch:s" => \$opt_winbatch,
- "dump-data:s" => \$opt_dump_data,
- "only-aliases" => \$opt_only_aliases,
- "list-aliases" => \$opt_listaliases,
- "list-all-aliases" => \$opt_listallaliases,
- "list-fonts" => \$opt_listfonts,
- "info" => \$opt_info,
- "machine-readable" => \$opt_machine,
- "strict-psname" => \$opt_strictpsname, # hidden option for debugging
- "n|dry-run" => \$dry_run,
- "q|quiet" => \$opt_quiet,
- "d|debug+" => \$opt_debug,
- "h|help" => \$opt_help,
- "markdown" => \$opt_markdown,
- "v|version" => sub { print &version(); exit(0); }, ) ) {
- die "Try \"$0 --help\" for more information.\n";
-}
-
-if ($debug_msg_before_init) {
- print_debug ($debug_msg_before_init);
-}
-
-sub win32 { return ($^O=~/^MSWin(32|64)$/i); }
-sub macosx { return ($^O=~/^darwin$/i); }
-my $nul = (win32() ? 'nul' : '/dev/null') ;
-my $sep = (win32() ? ';' : ':');
-my %fontdb;
-my %aliases;
-my %user_aliases;
-
-if ($opt_help || $opt_markdown) {
- Usage();
- exit(0);
-}
-
-# check for the existence of kpsewhich, otherwise we cannot do anything
-if (system("kpsewhich --version >$nul 2>&1 <$nul" ) != 0) {
- print_error("We need `kpsewhich' being installed! Exiting.\n");
- exit(1);
-}
-
-if ($opt_debug >= 2) {
- require Data::Dumper;
- no warnings qw(once);
- $Data::Dumper::Indent = 1;
-}
-
-my $zrlistttc = kpse_miscfont("zrlistttc.lua");
-my $zrlistttc_available;
-my $cmdl = "texlua $zrlistttc 2>$nul";
-$cmdl = encode('locale', $cmdl);
-chomp(my $zrlistttc_help = `$cmdl`);
-if ($?) {
- if ($opt_strictpsname) {
- print_error("The script 'zrlistttc.lua' not found, cannot proceed!\n");
- exit(1);
- }
- # show info only for debugging
- print_debug("The script 'zrlistttc.lua' not found.\n");
- print_debug("Sorry, we can't be safe enough to distinguish\n");
- print_debug("uppercase / lowercase file names.\n");
- $zrlistttc_available = 0;
-} else {
- $zrlistttc_available = 1;
-}
-
-if (macosx()) {
- # due to frequent incompatible changes in font file names by Apple,
- # our built-in database doesn't support OS X 10.11 El Capitan or
- # later versions
- my $macos_ver = `sw_vers -productVersion`;
- my $macos_ver_major = $macos_ver;
- $macos_ver_major =~ s/^(\d+)\.(\d+).*/$1/;
- my $macos_ver_minor = $macos_ver;
- $macos_ver_minor =~ s/^(\d+)\.(\d+).*/$2/;
- if ($macos_ver_major>=11 || ($macos_ver_major==10 && $macos_ver_minor>=8)) {
- if (!$opt_cleanup && !$opt_fontdef && !@opt_fontdef_add) { # if built-in only
- print_warning("Our built-in database does not support recent\n");
- print_warning("versions of Mac OS (10.8 Mountain Lion or later)!\n");
- print_warning("If you want to use Hiragino fonts bundled with\n");
- print_warning("your OS, obtain external database file and\n");
- print_warning("specify it with --fontdef-add option!\n");
- print_warning("I'll continue with my built-in database ...\n");
- }
- }
-}
-
-if (defined($opt_texmflink)) {
- my $foo;
- if ($opt_texmflink eq '') {
- # option was passed but didn't receive a value
- # -> use TEXMFLOCAL
- $foo = `kpsewhich -var-value=TEXMFLOCAL`;
- # We assume that the output of kpsewhich is
- # the same as perl's locale (or active code page).
- decode('locale', $foo);
- chomp($foo);
- } else {
- # option was passed with an argument
- # -> use it
- $foo = $opt_texmflink;
- }
- $opt_texmflink = $foo;
-}
-
-if (defined($opt_akotfps)) {
- my $foo;
- if ($opt_akotfps eq '') {
- if (defined($opt_texmflink)) {
- $foo = $opt_texmflink;
- } else {
- $foo = `kpsewhich -var-value=TEXMFLOCAL`;
- # We assume that the output of kpsewhich is
- # the same as perl's locale (or active code page).
- decode('locale', $foo);
- chomp($foo);
- }
- } else {
- $foo = $opt_akotfps;
- }
- $opt_akotfps = $foo;
-}
-
-if (defined($opt_winbatch)) {
- print_warning("ignoring --winbatch option due to being obsolete\n");
-}
-if ($opt_hardlink) {
- print_warning("ignoring --hardlink option due to being obsolete\n");
-}
-
-if (defined($opt_dump_data)) {
- if ($opt_dump_data ne '') {
- $dump_datafile = $opt_dump_data;
- }
- $opt_dump_data = 1;
- unlink encode('locale_fs', $dump_datafile)
- if (-f encode('locale_fs', $dump_datafile));
-} else {
- $opt_dump_data = 0;
-}
-
-if ($opt_cleanup) {
- $opt_remove = 1;
-}
-
-if ($opt_info) {
- $opt_listfonts = 1;
- $opt_listaliases = 1;
-}
-
-# check exclusive options; unsafe due to make_all_available()
-if ($opt_listallaliases && $opt_listaliases) {
- print_error("Both --list-all-aliases and --list-aliases!? I'm confused!\n");
- exit(1);
-}
-if ($opt_listallaliases && $opt_listfonts) {
- print_error("Options --list-all-aliases and --list-fonts cannot be used at the same time!\n");
- exit(1);
-}
-if ($opt_cleanup && $opt_listfonts) {
- print_error("Options --cleanup and --list-fonts cannot be used at the same time!\n");
- exit(1);
-}
-if ($opt_cleanup && $opt_listaliases) {
- print_error("Options --cleanup and --list-aliases cannot be used at the same time!\n");
- exit(1);
-}
-
-main(@ARGV);
-
-#
-# only sub definitions from here on
-#
-sub main {
- # first, read font database to obtain %fontdb
- print_info("reading font database ...\n");
- read_font_database();
- if ($opt_dump_data) {
- # with --dump-data, dump only effective database and exit
- dump_font_database();
- if (-f encode('locale_fs', $dump_datafile)) {
- print_info("*** Data dumped to $dump_datafile ***\n");
- exit(0);
- } else {
- print_error("Failed to dump data to $dump_datafile!\n");
- exit(1);
- }
- }
- # second, determine non-otf link name
- # this is actually required only by info_found_fonts() and do_nonotf_fonts()
- # operations, but it does no harm for other cases too
- determine_nonotf_link_name(); # see comments there
-
- # set 'available' flags and 'type' by kpsewhich search
- # if $opt_cleanup or $opt_listallaliases is given, treat all files
- # in the database as if they were actually available as OTF
- if (!$opt_cleanup && !$opt_listallaliases) {
- print_info("checking for files ...\n");
- check_for_files();
- } else {
- make_all_available();
- }
- # obtain %aliases and %user_aliases
- compute_aliases();
-
- # informative operations
- if ($opt_listfonts) {
- info_found_fonts();
- }
- if ($opt_listaliases || $opt_listallaliases) {
- info_list_aliases();
- }
- exit(0) if ($opt_listfonts || $opt_listaliases || $opt_listallaliases);
- # if $opt_machine is still alive after the above exit(0), it's useless
- if ($opt_machine) {
- print_error("Option --machine-readable should be used with at least one of the followings:\n");
- print_error(" --list-aliases, --list-all-aliases, --list-fonts, --info\n");
- print_error("terminating.\n");
- exit(1);
- }
-
- # do actual setup/removing operations
- if (!$opt_output) {
- print_info("searching for Ghostscript resource\n");
- my $gsres = find_gs_resource();
- if (!$gsres) {
- print_error("Cannot find Ghostscript, terminating!\n");
- exit(1);
- } else {
- $opt_output = $gsres;
- }
- }
- if (! -d encode('locale_fs', $opt_output)) {
- $dry_run || mkdir(encode('locale_fs', $opt_output)) ||
- die("Cannot create directory $opt_output: $!");
- }
- if ($opt_cleanup) {
- print_info("going to clean up $opt_output\n");
- } else {
- print_info("output is going to $opt_output\n");
- }
- if (!$opt_only_aliases) {
- if ($opt_cleanup) {
- # all font types are handled at the same time
- print_info("cleaning up all links, snippets and cidfmap.local ...\n");
- do_all_fonts();
- } else {
- # OTF and TTF/TTC/OTC must be handled separately, depending on the found files
- print_info(($opt_remove ? "removing" : "generating") . " links and snippets for CID fonts ...\n");
- do_otf_fonts();
- print_info(($opt_remove ? "removing" : "generating") . " links, snippets and cidfmap.local for non-CID fonts ...\n");
- do_nonotf_fonts();
- }
- }
- print_info(($opt_remove ? "removing" : "generating") . " snippets and cidfmap.aliases for font aliases ...\n");
- do_aliases();
- do_cmaps();
- write_akotfps_datafile() if $opt_akotfps;
- if ($opt_texmflink && !$dry_run) {
- print_info("running mktexlsr ...\n");
- system("mktexlsr");
- }
- print_info("finished\n");
-}
-
-sub do_all_fonts {
- # try to clean up all possible links/snippets/cidfmap which could have been
- # generated in the previous runs
- # previous versions of cjk-gs-integrate included following bugs:
- # * the database sometimes identified GB/CNS classes wrongly
- # * symlink names were sometimes invalid (some of which contained
- # white-spaces, due to the absence of proper database entry) or
- # inconsistent with ptex-fontmaps (Name <-> PSName or redundant Filename)
- # * confused symlinks between TTF/TTC/OTC (including ttf <-> ttc links)
- # also, current version generates OTC links into $otf_pathpart instead of
- # $ttf_pathpart, which was not true in the older versions
- # we'd like to clean up all such files
- my $fontdest = "$opt_output/Font";
- my $ciddest = "$opt_output/CIDFont";
- my $cidfsubst = "$opt_output/CIDFSubst";
- for my $k (sort keys %fontdb) {
- #
- # remove snippets: note that $class = $fontdb{$k}{'class'} is not enough
- # due to previous bugs
- for my $class (%encode_list) {
- for my $enc (@{$encode_list{$class}}) {
- unlink encode('locale_fs', "$fontdest/$k-$enc")
- if (-f encode('locale_fs', "$fontdest/$k-$enc"));
- }
- }
- #
- # remove links; borrow link_font operation here for convenience
- # since we don't need target in cleanup mode, initialize with stub "none"
- #
- # for OTF/TTF fonts, first remove both $k[.otf,ttf] and $fontdb{$k}{'origname'}[.otf]
- # the links $k.otf and $fontdb{$k}{'origname'} are coming from previous bugs,
- # and the links $k.ttf are (sometimes) coming from inconsistency
- if ($fontdb{$k}{'origname'}) { # this test skips alias-only fonts (e.g. Ryumin-Light)
- link_font("none", $ciddest, $k);
- link_font("none", $cidfsubst, "$k.ttf");
- link_font("none", "$opt_texmflink/$otf_pathpart", "$k.otf")
- if $opt_texmflink;
- link_font("none", "$opt_texmflink/$ttf_pathpart", "$k.ttf")
- if $opt_texmflink;
- link_font("none", $ciddest, $fontdb{$k}{'origname'});
- link_font("none", "$opt_texmflink/$otf_pathpart", "$fontdb{$k}{'origname'}.otf")
- if $opt_texmflink;
- }
- # for OTF/TTF/TTC/OTC fonts, loop through all file candidates
- for my $f (keys %{$fontdb{$k}{'files'}}) {
- # check for subfont extension
- my $foo = $f;
- $foo =~ s/^(.*)\(\d*\)$/$1/;
- link_font("none", $cidfsubst, "$foo");
- link_font("none", "$opt_texmflink/$otf_pathpart", "$foo") if $opt_texmflink;
- link_font("none", "$opt_texmflink/$ttf_pathpart", "$foo") if $opt_texmflink;
- }
- }
- update_master_cidfmap('cidfmap.local');
- # we are in cleanup mode, also remove cidfmap.local itself
- if (-f encode('locale_fs', "$opt_output/$cidfmap_local_pathpart")) {
- unlink encode('locale_fs', "$opt_output/$cidfmap_local_pathpart");
- }
-}
-
-sub do_otf_fonts {
- my $fontdest = "$opt_output/Font";
- my $ciddest = "$opt_output/CIDFont";
- make_dir($fontdest, "cannot create CID snippets there!");
- make_dir($ciddest, "cannot link CID fonts there!");
- make_dir("$opt_texmflink/$otf_pathpart",
- "cannot link fonts to it!")
- if $opt_texmflink;
- for my $k (sort keys %fontdb) {
- if ($fontdb{$k}{'available'} && $fontdb{$k}{'type'} eq 'OTF') {
- generate_font_snippet($fontdest,
- $k, $fontdb{$k}{'class'}, $fontdb{$k}{'target'});
- link_font($fontdb{$k}{'target'}, $ciddest, $k);
- link_font($fontdb{$k}{'target'}, "$opt_texmflink/$otf_pathpart", "$fontdb{$k}{'origname'}.otf")
- if $opt_texmflink;
- }
- }
-}
-
-sub do_nonotf_fonts {
- my $fontdest = "$opt_output/Font";
- my $cidfsubst = "$opt_output/CIDFSubst";
- my $outp = '';
- make_dir($fontdest, "cannot create CID snippets there!");
- make_dir($cidfsubst, "cannot link TTF fonts there!");
- make_dir("$opt_texmflink/$ttf_pathpart",
- "cannot link fonts to it!")
- if $opt_texmflink;
- for my $k (sort keys %fontdb) {
- if ($fontdb{$k}{'available'} && $fontdb{$k}{'type'} eq 'TTF') {
- $outp .= generate_cidfmap_entry($k, $fontdb{$k}{'class'}, $fontdb{$k}{'ttfname'}, -1);
- link_font($fontdb{$k}{'target'}, $cidfsubst, $fontdb{$k}{'ttfname'});
- link_font($fontdb{$k}{'target'}, "$opt_texmflink/$ttf_pathpart", $fontdb{$k}{'ttfname'})
- if $opt_texmflink;
- } elsif ($fontdb{$k}{'available'} && $fontdb{$k}{'type'} eq 'TTC') {
- $outp .= generate_cidfmap_entry($k, $fontdb{$k}{'class'}, $fontdb{$k}{'ttcname'}, $fontdb{$k}{'subfont'});
- link_font($fontdb{$k}{'target'}, $cidfsubst, $fontdb{$k}{'ttcname'});
- link_font($fontdb{$k}{'target'}, "$opt_texmflink/$ttf_pathpart", $fontdb{$k}{'ttcname'})
- if $opt_texmflink;
- } elsif ($fontdb{$k}{'available'} && $fontdb{$k}{'type'} eq 'OTC') {
- # currently Ghostscript does not have OTC support; we don't know what to do
- print_debug("gs does not support OTC, not creating gs resource for $k\n");
- link_font($fontdb{$k}{'target'}, "$opt_texmflink/$otf_pathpart", $fontdb{$k}{'otcname'})
- if $opt_texmflink;
- }
- }
- return if $dry_run;
- if ($outp) {
- if (! -d encode('locale_fs', "$opt_output/Init")) {
- mkdir(encode('locale_fs', "$opt_output/Init")) ||
- die("Cannot create directory $opt_output/Init: $!");
- }
- # It seems that tlgs can handle UTF-8 TTF filename in cidfmap.local.
- open(FOO, ">:encoding(UTF-8)",
- encode('locale_fs', "$opt_output/$cidfmap_local_pathpart")) ||
- die("Cannot open $opt_output/$cidfmap_local_pathpart: $!");
- print FOO $outp;
- close(FOO);
- }
- update_master_cidfmap('cidfmap.local');
-}
-
-sub do_aliases {
- my $fontdest = "$opt_output/Font";
- my $ciddest = "$opt_output/CIDFont"; # required for Heisei* check only
- my $cidfsubst = "$opt_output/CIDFSubst";
- my $outp = '';
- #
- # alias handling
- # we use two levels of aliases
- # * one is for the default generic names (these are not actual fonts)
- # Ryumin-Light, GothicBBB-Medium, ... etc.
- # * the second level of aliases is for Morisawa OTF font names
- # RyuminPro-Light, GothicBBBPro-Medium, ... etc.
- # the order of fonts selected is
- # defined in the Provides(Priority): Name in the font definiton
- #
- $outp .= "\n\n% Aliases\n";
- #
- my (@jal, @kal, @tal, @sal, @ai0al);
- #
- for my $al (sort keys %aliases) {
- my $target;
- my $class;
- if ($user_aliases{$al}) {
- $target = $user_aliases{$al};
- # determine class
- if ($fontdb{$target}{'available'}) {
- $class = $fontdb{$target}{'class'};
- } else {
- # must be an aliases, we checked this when initializing %user_aliases
- # reset the $al value
- # and since $class is still undefined we will use the next code below
- $al = $target;
- }
- }
- if (!$class) {
- if (!%{$aliases{$al}}) {
- print_warning("Alias candidate for $al is empty, skipping!\n");
- next;
- }
- # search lowest number
- my @ks = keys(%{$aliases{$al}});
- my $first = (sort { $a <=> $b} @ks)[0];
- $target = $aliases{$al}{$first};
- $class = $fontdb{$target}{'class'};
- }
- # we also need to create font snippets in Font (or add configuration)
- # for the aliases!
- generate_font_snippet($fontdest, $al, $class, $target);
- if ($class eq 'Japan') {
- push @jal, "/$al /$target ;";
- } elsif ($class eq 'Korea') {
- push @kal, "/$al /$target ;";
- } elsif ($class eq 'GB') {
- push @sal, "/$al /$target ;";
- } elsif ($class eq 'CNS') {
- push @tal, "/$al /$target ;";
- } elsif ($class eq 'AI0') {
- push @ai0al, "/$al /$target ;";
- } else {
- print STDERR "unknown class $class for $al\n";
- }
- }
- # special case for native CID fonts in ancient days
- # if not readable, add aliases for substitution
- push @jal, "/HeiseiMin-W3 /Ryumin-Light ;"
- if (! -r encode('locale_fs', "$ciddest/HeiseiMin-W3"));
- push @jal, "/HeiseiKakuGo-W5 /GothicBBB-Medium ;"
- if (! -r encode('locale_fs', "$ciddest/HeiseiKakuGo-W5"));
- #
- $outp .= "\n% Japanese fonts\n" . join("\n", @jal) . "\n" if @jal;
- $outp .= "\n% Korean fonts\n" . join("\n", @kal) . "\n" if @kal;
- $outp .= "\n% Traditional Chinese fonts\n" . join("\n", @tal) . "\n" if @tal;
- $outp .= "\n% Simplified Chinese fonts\n" . join("\n", @sal) . "\n" if @sal;
- $outp .= "\n% Adobe-Identity-0 fonts\n" . join("\n", @ai0al) . "\n" if @ai0al;
- #
- return if $dry_run;
- if ($outp && !$opt_remove) {
- if (! -d encode('locale_fs', "$opt_output/Init")) {
- mkdir(encode('locale_fs', "$opt_output/Init")) ||
- die("Cannot create directory $opt_output/Init: $!");
- }
- open(FOO, ">:encoding(UTF-8)",
- encode('locale_fs', "$opt_output/$cidfmap_aliases_pathpart")) ||
- die("Cannot open $opt_output/$cidfmap_aliases_pathpart: $!");
- print FOO $outp;
- close(FOO);
- }
- update_master_cidfmap('cidfmap.aliases');
- # if we are in cleanup mode, also remove cidfmap.aliases itself
- if (-f encode('locale_fs', "$opt_output/$cidfmap_aliases_pathpart")) {
- unlink encode('locale_fs', "$opt_output/$cidfmap_aliases_pathpart")
- if $opt_cleanup;
- }
-}
-
-sub do_cmaps {
- # add symlinking CMaps
- # for which we generate snippets but gs does not provide
- my $cmapdest = "$opt_output/CMap";
- return if $dry_run;
- if ($opt_remove) {
- # we remove only if both of the following conditions are met:
- # (1) it is a link
- # (2) the link target is the same as kpsewhich result
- # otherwise it's unsafe to remove, as it may have been added
- # by others or distributed by gs itself
- for my $class (%encode_list) {
- for my $enc (@{$encode_list{$class}}) {
- if (-l encode('locale_fs', "$cmapdest/$enc")) {
- my $linkt = decode('locale_fs',
- readlink(encode('locale_fs',
- "$cmapdest/$enc")));
- if ($linkt) {
- if ($linkt eq search_cmap($enc)) {
- unlink(encode('locale_fs', "$cmapdest/$enc"));
- }
- }
- }
- }
- }
- return;
- }
- # add mode
- if (! -d encode('locale_fs', "$cmapdest")) {
- print_debug("Creating directory $cmapdest ...\n");
- make_dir("$cmapdest", "cannot create CMap directory");
- }
- for my $class (%encode_list) {
- if ($class =~ m/^AI0-(.*)$/) {
- # skip AI0 font-specific CMap when the real font is unavailable
- next if (!$fontdb{$1}{'available'});
- }
- for my $enc (@{$encode_list{$class}}) {
- if (! -f encode('locale_fs', "$cmapdest/$enc")) {
- print_debug("CMap $enc is not found in gs resource directory\n");
- my $dest = search_cmap($enc);
- if ($dest) {
- print_debug("Symlinking CMap $dest ...\n");
- link_font($dest, "$cmapdest", $enc);
- } else {
- print_debug("CMap $enc is not found by kpsewhich\n");
- }
- }
- }
- }
-}
-
-my %cmap_cache;
-
-sub search_cmap {
- my ($cmap) = @_;
- # search CMap with kpsewhich and cache
- if (! exists $cmap_cache{$cmap}) {
- my $cmdl = "kpsewhich -format=cmap $cmap";
- $cmdl = encode('locale', $cmdl);
- $cmap_cache{$cmap} = `$cmdl`;
- # We assume that the output of kpsewhich is
- # the same as perl's locale (or active code page).
- $cmap_cache{$cmap} = decode('locale', $cmap_cache{$cmap});
- chomp($cmap_cache{$cmap});
- $cmap_cache{$cmap} =~ s/[\r\n]+\z//; # perl's chomp() on git-bash cannot strip CR of CRLF ??
- }
- return $cmap_cache{$cmap};
-}
-
-sub update_master_cidfmap {
- # what we have to do is:
- # in add mode:
- # * add an entry for the given argument
- # * for tlgs.win32 pre-shipped cidfmap, prepend '%' to override
- # the default of "(cidfmap.TeXLive) .runlibfile",
- # in remove mode:
- # * remove an entry for the given argument
- # * for tlgs.win32 pre-shipped cidfmap, remove '%' to restore the default
- my $add = shift;
- my $cidfmap_master = "$opt_output/$cidfmap_pathpart";
- print_info(sprintf("%s $add %s cidfmap file ...\n",
- ($opt_remove ? "removing" : "adding"), ($opt_remove ? "from" : "to")));
- if (-r encode('locale_fs', $cidfmap_master)) {
- open(FOO, "<:encoding(UTF-8)", encode('locale_fs', $cidfmap_master)) ||
- die("Cannot open $cidfmap_master for reading: $!");
- my $found = 0;
- my $found_tl = 0;
- my $newmaster = "";
- # in add mode: just search for the entry and set $found
- # in remove mode: collect all lines that do not match
- # also, we handle "cidfmap.TeXLive" now
- while(<FOO>) {
- if (m/^\s*\(\Q$add\E\)\s\s*\.runlibfile\s*$/) {
- $found = 1;
- } elsif (m/^\s*\(cidfmap\.TeXLive\)\s\s*\.runlibfile\s*$/) {
- # if found, it has to be disabled in add mode in a way in which it can
- # be detected in the (future) remove mode
- next if $found_tl; # skip it as duplicate (though unlikely to happen)
- $found_tl = 1;
- $newmaster .= "\%" if (!$opt_remove); # in add mode, disable it
- $newmaster .= $_; # pass it as-is
- } elsif (m/^\s*\%\%*\s*\(cidfmap\.TeXLive\)\s\s*\.runlibfile\s*$/) {
- # if found, it should be the one disabled by myself in the previous run;
- # restore it in remove mode
- next if $found_tl; # skip it as duplicate (though unlikely to happen)
- $found_tl = 1;
- $_ =~ s/\%//g if $opt_remove; # in remove mode, enable it
- $newmaster .= $_; # pass it
- } else {
- $newmaster .= $_;
- }
- }
- close(FOO);
- # if the original master cidfmap has a new line at end of file,
- # then $newmaster should end with "\n".
- # otherwise we add a new line, since there is a possibility of %EOF comment
- # without trailing new line (e.g. TL before r44039)
- $newmaster =~ s/\n$//;
- $newmaster =~ s/$/\n/;
- if ($opt_remove) {
- if ($found || $found_tl) {
- return if $dry_run;
- open(FOO, ">:encoding(UTF-8)", encode('locale_fs', $cidfmap_master)) ||
- die("Cannot clean up $cidfmap_master: $!");
- print FOO $newmaster;
- close FOO;
- }
- } else {
- if ($found && !$found_tl) {
- print_info("$add already loaded in $cidfmap_master, no changes\n");
- } else {
- return if $dry_run;
- open(FOO, ">:encoding(UTF-8)", encode('locale_fs', $cidfmap_master)) ||
- die("Cannot open $cidfmap_master for appending: $!");
- print FOO $newmaster;
- print FOO "($add) .runlibfile\n";
- close(FOO);
- }
- }
- } else {
- return if $dry_run;
- return if $opt_remove;
- open(FOO, ">:encoding(UTF-8)", encode('locale_fs', $cidfmap_master)) ||
- die("Cannot open $cidfmap_master for writing: $!");
- print FOO "($add) .runlibfile\n";
- close(FOO);
- }
-}
-
-sub generate_cidfmap_entry {
- my ($n, $c, $f, $sf) = @_;
- return "" if $opt_remove;
- # $f is already the link target name 'ttfname' (or 'ttcname' or 'otcname')
- # as determined by minimal priority number
- # extract subfont
- my $s = "/$n << /FileType /TrueType
- /Path pssystemparams /GenericResourceDir get
- (CIDFSubst/$f) concatstrings\n";
- if ($sf >= 0) { # in this script, $sf < 0 represents TTF
- $s .= " /SubfontID $sf\n";
- }
- $s .= " /CSI [($c";
- if ($c eq "Japan") {
- $s .= "1) 6]";
- } elsif ($c eq "GB") {
- $s .= "1) 5]";
- } elsif ($c eq "CNS") {
- $s .= "1) 5]";
- } elsif ($c eq "Korea") {
- $s .= "1) 2]";
- } elsif ($c eq "AI0") {
- print_warning("cannot use class AI0 for non-OTF $n, skipping.\n");
- return '';
- } else {
- print_warning("unknown class $c for $n, skipping.\n");
- return '';
- }
- $s .= " >> ;\n";
- return $s;
-}
-
-sub generate_font_snippet {
- my ($fd, $n, $c, $f) = @_;
- return if $dry_run;
- if ($opt_akotfps) {
- add_akotfps_data($n);
- return;
- }
- if ($c eq "AI0") {
- $c = "AI0-$n";
- }
- for my $enc (@{$encode_list{$c}}) {
- if ($opt_remove) {
- unlink encode('locale_fs', "$fd/$n-$enc")
- if (-f encode('locale_fs', "$fd/$n-$enc"));
- next;
- }
- open(FOO, ">:encoding(UTF-8)", encode('locale_fs', "$fd/$n-$enc")) ||
- die("cannot open $fd/$n-$enc for writing: $!");
- print FOO "%!PS-Adobe-3.0 Resource-Font
-%%DocumentNeededResources: $enc (CMap)
-%%IncludeResource: $enc (CMap)
-%%BeginResource: Font ($n-$enc)
-($n-$enc)
-($enc) /CMap findresource
-[($n) /CIDFont findresource]
-composefont
-pop
-%%EndResource
-%%EOF
-";
- close(FOO);
- }
-}
-
-sub add_akotfps_data {
- my ($fn) = @_;
- return if $dry_run;
- if (!$opt_remove) {
- $akotfps_datacontent .= "$fn\n";
- }
-}
-
-#
-# link_font operation
-# $opt_force is *not* treated first to warn only
-# at really critical cases
-# case 1:
-# exists, is link, link targets agree
-# $opt_force is ignored
-# remove or remove+add according to $opt_remove
-# case 2:
-# exists, is link, dangling symlink
-# $opt_force is ignored
-# remove or remove+add according to $opt_remove
-# case 3:
-# exists, is link, link target different
-# if $opt_force
-# warn, remove or remove+add according to $opt_remove
-# else
-# error message
-# case 4:
-# exists, not a link
-# if $opt_force
-# warn, remove or remove+add according to $opt_remove
-# else
-# error message
-# case 5:
-# not exists
-# $opt_force is ignored
-# do nothing or add according to $opt_remove
-#
-sub link_font {
- my ($f, $cd, $n) = @_;
- return if $dry_run;
- if (!$n) {
- $n = basename($f);
- }
- my $target = "$cd/$n";
- my $do_unlink = 0;
- if (-l encode('locale_fs', $target)) {
- if ($opt_cleanup) {
- $do_unlink = 1;
- } else {
- my $linkt = decode('locale_fs', readlink(encode('locale_fs', $target)));
- if ($linkt) {
- if ($linkt eq $f) {
- # case 1: exists, link, targets agree
- $do_unlink = 1;
- } elsif (-r encode('locale_fs', $linkt)) {
- # case 3: exists, link, targets different
- if ($opt_force) {
- print_info("Removing link $target due to --force!\n");
- $do_unlink = 1;
- } else {
- print_error("Link $target already existing, but target different from $f, exiting!\n");
- exit(1);
- }
- } else {
- # case 2: dangling symlink or link-to-link
- print_warning("Removing dangling symlink $target to $linkt\n");
- $do_unlink = 1;
- }
- } else {
- print_error("This should not happen, we have a link but cannot read the target?\n");
- exit(1);
- }
- }
- } elsif (-r encode('locale_fs', $target)) {
- # case 4: exists, but not link (NTFS hardlink on win32 falls into this)
- if (-s encode('locale_fs', $target)) {
- if ($opt_force) {
- print_info("Removing $target due to --force!\n");
- $do_unlink = 1;
- } elsif (win32()) {
- my $result = compare (encode ('locale_fs', $f),
- encode ('locale_fs', $target));
- if ($result == -1) {
- print_error("file compare failed: ${f}, ${target}\n");
- exit(1);
- } elsif ($result) {
- print_error("$target already existing and different content, exiting!\n");
- exit(1);
- }
- print_debug("$target already existing but same content, skipping!\n");
- return;
- } else {
- print_error("$target already existing, exiting!\n");
- exit(1);
- }
- } else {
- # NTFS symlink on win32 has file size 0, we're safe to remove it
- $do_unlink = 1;
- }
- } # case 5: otherwise it is not existing!
-
- # if we are still here and $do_unlink is set, remove it
- maybe_unlink($target) if $do_unlink;
- # recreate link if we are not in the remove case
- if (!$opt_remove) {
- maybe_symlink($f, $target) || die("Cannot link font $f to $target: $!");
- }
-}
-
-sub make_dir {
- my ($d, $w) = @_;
- if (-r encode('locale_fs', $d)) {
- if (! -d encode('locale_fs', $d)) {
- print_error("$d is not a directory, $w\n");
- exit(1);
- }
- } else {
- $dry_run || make_path(encode('locale', $d));
- }
-}
-
-# perl symlink function does not work on windows, so we use Win32 API.
-sub maybe_symlink {
- my ($realname, $targetname) = @_;
- if (win32()) {
- # Try symbolic link, hard link, copy by Win32 API
-
- # On Windows, the creation of a symbolic link requires a privilege.
- # Therefore, if the creation of the symbolic link fails,
- # create a hard link.
- # However, the creation of the hard link requires the write permission
- # to the original existing file.
- # Thus, if the hard link also fails, copy the file.
-
- if (win32_symlink ($realname, $targetname)) {
- print_debug ("Symbolic link succeeded: ${targetname}\n");
- return 1;
- }
-
- if (win32_hardlink ($realname, $targetname)) {
- print_debug ("Hard link succeeded: ${targetname}\n");
- return 1;
- }
-
- if (win32_copy ($realname, $targetname)) {
- print_debug ("Copy succeeded: ${targetname}\n");
- return 1;
- }
-
- print_warning ("Link/copy failed: ${targetname}\n");
- } else {
- symlink ($realname, $targetname);
- }
-}
-
-sub maybe_unlink {
- my ($targetname) = @_;
- unlink (encode('locale_fs', $targetname));
-}
-
-# For Windows: Create symbolic link
-sub win32_symlink {
- my ($existingfilename, $newfilename) = @_;
-
- # We use CreateSymbolicLinkW API directly for creating symbolic link
- # because perl's symlink function may not work in Windows.
- state $createsymboliclinkw = load_createsymboliclinkw ();
-
- $existingfilename =~ s|/|\\|g;
- $newfilename =~ s|/|\\|g;
-
- my $r = $createsymboliclinkw->Call (
- encode ('UTF-16LE', $newfilename),
- encode ('UTF-16LE', $existingfilename),
- 0
- );
- if (ord($r) != 0) {
- return 1;
- }
- my $msg = decode ('locale',
- Win32::FormatMessage (Win32::GetLastError ()));
- $msg =~ s/[\r\n]+\z//;
- print_debug ("CreateSymbolicLinkW failed: ${msg}\n");
-
- return 0;
-}
-
-# For Windows: Create hard link
-sub win32_hardlink {
- my ($existingfilename, $newfilename) = @_;
-
- # We use CreateHardLinkW API directly for creating hard link
- # because -W API is not affected by the perl's active code page.
- state $createhardlinkw = load_createhardlinkw ();
-
- $existingfilename =~ s|/|\\|g;
- $newfilename =~ s|/|\\|g;
-
- my $r = $createhardlinkw->Call (
- encode ('UTF-16LE', $newfilename),
- encode ('UTF-16LE', $existingfilename),
- 0
- );
- if ($r) {
- return 1;
- }
- my $msg = decode ('locale',
- Win32::FormatMessage (Win32::GetLastError ()));
- $msg =~ s/[\r\n]+\z//;
- print_debug ("CreateHardLinkW failed: ${msg}\n");
-
- return 0;
-}
-
-# For Windows: Copy file
-sub win32_copy {
- my ($existingfilename, $newfilename) = @_;
-
- # We use CopyFileW API directly for copying file
- # because -W API is not affected by the perl's active code page.
- state $copyfilew = load_copyfilew ();
-
- $existingfilename =~ s|/|\\|g;
- $newfilename =~ s|/|\\|g;
-
- my $r = $copyfilew->Call (
- encode ('UTF-16LE', $existingfilename),
- encode ('UTF-16LE', $newfilename),
- 1
- );
- if ($r) {
- return 1;
- }
- my $msg = decode ('locale',
- Win32::FormatMessage (Win32::GetLastError ()));
- $msg =~ s/[\r\n]+\z//;
- print_debug ("CopyFileW failed: ${msg}\n");
-
- return 0;
-}
-
-# For Windows: Load CreateSymbolicLinkW API
-sub load_createsymboliclinkw {
- my $createsymboliclinkw = Win32::API::More->new (
- 'kernel32.dll',
- 'BOOLEAN CreateSymbolicLinkW(
- LPCWSTR lpSymlinkFileName,
- LPCWSTR lpTargetFileName,
- DWORD dwFlags
- )'
- ) or die ('Failed: Win32::API::More->new CreateSymbolicLinkW');
-
- return $createsymboliclinkw;
-}
-# For Windows: Load CreateHardLinkW API
-sub load_createhardlinkw {
- my $createhardlinkw = Win32::API::More->new (
- 'kernel32.dll',
- 'BOOL CreateHardLinkW(
- LPCWSTR lpFileName,
- LPCWSTR lpExistingFileName,
- UINT_PTR lpSecurityAttributes
- )'
- ) or die ('Failed: Win32::API::More->new CreateHardLinkW');
-
- return $createhardlinkw;
-}
-
-# For Windows: Load CopyFileW API
-sub load_copyfilew {
- my $copyfilew = Win32::API::More->new (
- 'kernel32.dll',
- 'BOOL CopyFileW(
- LPCWSTR lpExistingFileName,
- LPCWSTR lpNewFileName,
- BOOL bFailIfExists
- )'
- ) or die ('Failed: Win32::API::More->new CopyFileW');
-
- return $copyfilew;
-}
-
-# write to psnames-for-otfps
-sub write_akotfps_datafile {
- return if $dry_run;
- make_dir("$opt_akotfps/$akotfps_pathpart",
- "cannot create $akotfps_datafilename in it!");
- open(FOO, ">:encoding(UTF-8)",
- encode('locale_fs',
- "$opt_akotfps/$akotfps_pathpart/$akotfps_datafilename")) ||
- die("cannot open $opt_akotfps/$akotfps_pathpart/$akotfps_datafilename for writing: $!");
- print FOO "% psnames-for-otf
-%
-% PostSctipt names for OpenType fonts
-%
-% This file is used by a program ps2otfps
-% in order to add needed information to a ps file
-% created by the dvips
-%
-$akotfps_datacontent";
- close(FOO);
-}
-
-#
-# dump found files
-sub info_found_fonts {
- print "List of found fonts:\n\n";
- for my $k (sort keys %fontdb) {
- my @foundfiles;
- if ($fontdb{$k}{'available'}) {
- print "Font: $k\n";
- print "Type: $fontdb{$k}{'type'}\n";
- print "Class: $fontdb{$k}{'class'}\n";
- my $fn = $fontdb{$k}{'target'};
- if ($fontdb{$k}{'type'} eq 'TTC' || $fontdb{$k}{'type'} eq 'OTC') {
- $fn .= "($fontdb{$k}{'subfont'})";
- }
- print "File: $fn\n";
- if ($fontdb{$k}{'type'} eq 'TTF') {
- print "Link: $fontdb{$k}{'ttfname'}\n";
- } elsif ($fontdb{$k}{'type'} eq 'TTC') {
- print "Link: $fontdb{$k}{'ttcname'}\n";
- } elsif ($fontdb{$k}{'type'} eq 'OTC') {
- print "Link: $fontdb{$k}{'otcname'}\n";
- }
- my @ks = sort { $fontdb{$k}{'files'}{$a}{'priority'}
- <=>
- $fontdb{$k}{'files'}{$b}{'priority'} }
- keys %{$fontdb{$k}{'files'}};
- # remove the top element which is the winner and shown above
- shift @ks;
- if (@ks) {
- print "Other candidates in decreasing order:\n";
- for my $f (@ks) {
- print " ", $fontdb{$k}{'files'}{$f}{'target'}, "\n";
- }
- }
- print "\n";
- }
- }
-}
-
-#
-# dump aliases
-sub info_list_aliases {
- print "List of ", ($opt_listallaliases ? "all" : "available"), " aliases and their options (in decreasing priority):\n" unless $opt_machine;
- my (@jal, @kal, @tal, @sal, @ai0al);
- for my $al (sort keys %aliases) {
- my $cl;
- my @ks = sort { $a <=> $b} keys(%{$aliases{$al}});
- my $foo = '';
- $foo = "$al:\n" unless $opt_machine;
- for my $p (@ks) {
- my $t = $aliases{$al}{$p};
- my $fn = ($opt_listallaliases ? "-" : $fontdb{$t}{'target'} );
- # should always be the same ;-)
- $cl = $fontdb{$t}{'class'};
- if (!$opt_listallaliases && ($fontdb{$t}{'type'} eq 'TTC' || $fontdb{$t}{'type'} eq 'OTC')) {
- $fn .= "($fontdb{$t}{'subfont'})";
- }
- if ($opt_machine) {
- $foo .= "$al:$p:$aliases{$al}{$p}:$fn\n";
- } else {
- $foo .= "\t($p) $aliases{$al}{$p} ($fn)\n";
- }
- }
- if ($cl eq 'Japan') {
- push @jal, $foo;
- } elsif ($cl eq 'Korea') {
- push @kal, $foo;
- } elsif ($cl eq 'GB') {
- push @sal, $foo;
- } elsif ($cl eq 'CNS') {
- push @tal, $foo;
- } elsif ($cl eq 'AI0') {
- push @ai0al, $foo;
- } else {
- print STDERR "unknown class $cl for $al\n";
- }
- }
- if ($opt_machine) {
- print @jal if @jal;
- print @kal if @kal;
- print @sal if @sal;
- print @tal if @tal;
- print @ai0al if @ai0al;
- } else {
- print "Aliases for Japanese fonts:\n", @jal, "\n" if @jal;
- print "Aliases for Korean fonts:\n", @kal, "\n" if @kal;
- print "Aliases for Simplified Chinese fonts:\n", @sal, "\n" if @sal;
- print "Aliases for Traditional Chinese fonts:\n", @tal, "\n" if @tal;
- print "Aliases for Adobe-Identity-0 fonts:\n", @ai0al, "\n" if @ai0al;
- }
-}
-
-#
-# make all fonts available for listing all aliases
-sub make_all_available {
- for my $k (keys %fontdb) {
- $fontdb{$k}{'available'} = 1;
- $fontdb{$k}{'type'} = 'OTF';
- delete $fontdb{$k}{'files'} if (!$opt_cleanup);
- }
-}
-
-#
-# checks all file names listed in %fontdb
-# and sets
-sub check_for_files {
- my @foundfiles;
- if ($opt_filelist) {
- open(FOO, "<", encode('locale_fs', $opt_filelist)) ||
- die("Cannot open $opt_filelist: $!");
- @foundfiles = <FOO>;
- close(FOO) || warn "Cannot close $opt_filelist: $!";
- } else {
- # first collect all files:
- my @fn;
- for my $k (keys %fontdb) {
- for my $f (keys %{$fontdb{$k}{'files'}}) {
- # check for subfont extension
- if ($f =~ m/^(.*)\(\d*\)$/) {
- push @fn, $1;
- } else {
- push @fn, $f;
- }
- }
- }
- #
- # collect extra directories for search
- my @extradirs;
- if (win32()) {
- push @extradirs, "c:/windows/fonts//";
- } else {
- # other dirs to check, for normal unix?
- for my $d (qw!/Library/Fonts /System/Library/Fonts
- /System/Library/Assets /System/Library/AssetsV2
- /Network/Library/Fonts /usr/share/fonts!) {
- push @extradirs, "$d//"
- if (-d encode('locale_fs', $d)); # recursive search
- }
- # the path contains white space, so hack required
- for my $d (qw!/Library/Application__Support/Apple/Fonts!) {
- my $sd = $d;
- $sd =~ s/__/ /;
- push @extradirs, "$sd//"
- if (-d encode('locale_fs', "$sd")); # recursive search
- }
- # office for mac 2016
- for my $d (qw!/Applications/Microsoft__Word.app
- /Applications/Microsoft__Excel.app
- /Applications/Microsoft__PowerPoint.app!) {
- my $sd = $d;
- $sd =~ s/__/ /;
- push @extradirs, "$sd/Contents/Resources/Fonts/"
- if (-d encode('locale_fs', "$sd/Contents/Resources/Fonts"));
- push @extradirs, "$sd/Contents/Resources/DFonts/"
- if (-d encode('locale_fs', "$sd/Contents/Resources/DFonts"));
- }
- my $home = $ENV{'HOME'};
- push @extradirs, "$home/Library/Fonts//"
- if (-d encode('locale_fs', "$home/Library/Fonts"));
- }
- #
- if (@extradirs) {
- # TODO: we want that files in OSFONTDIR are found first, before
- # links that we have created in TEXMFLOCAL
- # Thus, instead of setting OSFONTDIR which is at the *END* of
- # the kpsewhich variables OPENTYPEFONTS and TTFONTS, we'd like to
- # put all these fonts at the front of them
- #
- # There are problems with case-insensitive file systems like HFS
- # on MacOS, as we might catch different names (batang/Batang)
- # and identify them wrongly.
- # https://github.com/texjporg/cjk-gs-support/issues/9
- # For now until we have dealt with that, do not set the
- # two variables (HY 2016/09/27) and think about a different approach.
- push @extradirs, $ENV{'OSFONTDIR'} if $ENV{'OSFONTDIR'};
- if (@extradirs) {
- # comment out -- HY (2016/09/27)
- # my $newotf = join($sep, @extradirs) . $sep;
- # my $newttf = $newotf;
- # $newotf .= $ENV{'OPENTYPEFONTS'} if $ENV{'OPENTYPEFONTS'};
- # $newttf .= $ENV{'TTFONTS'} if $ENV{'TTFONTS'};
- # $ENV{'OPENTYPEFONTS'} = $newotf;
- # $ENV{'TTFONTS'} = $newttf;
- # new code for uppercase/lowercase workaround -- HY (2016/09/27)
- my $extrafontdir = join($sep, @extradirs) . $sep;
- $ENV{'OSFONTDIR'} = $extrafontdir;
- }
- }
- # prepare for kpsewhich call, we need to do quoting
- # we need as much candidate files as possible, so -all is needed
- my $cmdl = 'kpsewhich -all ';
- for my $f (@fn) {
- $cmdl .= " \"$f\" ";
- }
- # shoot up kpsewhich
- print_ddebug("checking for $cmdl\n");
- $cmdl = encode('locale', $cmdl);
- @foundfiles = `$cmdl`;
- # We assume that the output of kpsewhich is
- # the same as perl's locale (or active code page).
- @foundfiles = map { decode('locale', $_) } @foundfiles;
- }
- chomp(@foundfiles);
- print_ddebug("Found files @foundfiles\n");
- # map basenames to filenames
- my %bntofn;
- for my $f (@foundfiles) {
- $f =~ s/[\r\n]+\z//; # perl's chomp() on git-bash cannot strip CR of CRLF ??
- my $realf = decode('locale_fs', abs_path(encode('locale_fs', $f)));
- if (!$realf) {
- print_warning("dead link or strange file found: $f - ignored!\n");
- next;
- }
- if (win32()) {
- # abs_path cannot read NTFS symlink/hardlink, and it serves as
- # identity transformation.
- # this might lead to dangling links for multiple runs of cjk-gs-integrate,
- # when $opt_texmflink (in the previous run) is contained in the (current)
- # kpsewhich search path.
- # to avoid this, ignore targets which contain $otf_pathpart or $ttf_pathpart
- my $temp_realfdir = "$realf";
- $temp_realfdir =~ s!^(.*)/(.*)$!$1!;
- next if ($temp_realfdir =~ $otf_pathpart || $temp_realfdir =~ $ttf_pathpart);
- }
- my $bn = basename($f);
- # kpsewhich -all might return multiple files with the same basename;
- # collect all of them
- $bntofn{$bn}{$realf} = 1;
- }
-
- # show the %fontdb before file check
- if ($opt_debug >= 2) {
- print_ddebug("dumping font database before file check:\n");
- print_ddebug(Data::Dumper::Dumper(\%fontdb));
- }
- if ($opt_debug >= 3) {
- print_dddebug("dumping basename to filename list:\n");
- print_dddebug(Data::Dumper::Dumper(\%bntofn));
- }
-
- # update the %fontdb with the found files
- for my $k (keys %fontdb) {
- $fontdb{$k}{'available'} = 0;
- for my $f (keys %{$fontdb{$k}{'files'}}) {
- # check for subfont extension
- my $realfile = $f;
- $realfile =~ s/^(.*)\(\d*\)$/$1/;
- my $index = 0;
- if ($fontdb{$k}{'files'}{$f}{'type'} eq 'TTC' || $fontdb{$k}{'files'}{$f}{'type'} eq 'OTC') {
- if ($f =~ m/^(.*)\((\d*)\)$/) {
- $index = $2;
- }
- }
- # double check for casefolding or incompatible OTC/TTC index
- # [1] casefolding issue
- # we might catch different names (batang/Batang) and identify them wrongly on
- # * case-insensitive file systems (like HFS on MacOS)
- # * kpathsea 6.3.0 or later, with casefolding fallback search (TL2018)
- # check the actual psname using zrlistttc.lua, only when we "know"
- # both uppercase/lowercase font files are possible and they are different
- # [2] incompatible index
- # the index in msgothic.ttc changed at some time between Win7 and Win10.
- my $actualpsname;
- my $bname;
- for my $b (sort keys %{$bntofn{$realfile}}) {
- if ($opt_strictpsname && !$fontdb{$k}{'doublecheck'}) {
- $fontdb{$k}{'doublecheck'} = "debug"; # stub
- }
- if ($fontdb{$k}{'doublecheck'} && $fontdb{$k}{'doublecheck'} ne "false" && $zrlistttc_available) {
- print_debug("We need to test whether\n");
- print_debug(" $b:$index\n");
- print_debug("is the correct one ($k). Invoking zrlistttc ...\n");
- my $cmdl = "texlua $zrlistttc -i $index \"$b\"";
- $cmdl = encode('locale', $cmdl);
- chomp($actualpsname = `$cmdl`);
- if ($?) {
- # something is wrong with the font file, or zrlistttc does not support it;
- # still there is a chance that Ghostscript supports, so don't discard it
- print_debug("... command exited with $?!\n");
- print_debug("OK, I'll take this, but it may not work properly.\n");
- print_warning("zrlistttc check failed for $b\n") if $opt_strictpsname;
- $bname = $b;
- last;
- }
- # We assume that the output of texlua is
- # the same as perl's locale (or active code page).
- $actualpsname = decode('locale', $actualpsname);
- $actualpsname =~ s/[\r\n]+\z//; # perl's chomp() on git-bash cannot strip CR of CRLF ??
- if ($actualpsname ne $k) {
- print_debug("... PSName returned by zrlistttc ($actualpsname) is\n");
- print_debug("different from our database ($k), discarding!\n");
- if ($opt_strictpsname && $fontdb{$k}{'doublecheck'} eq "debug") {
- # in our database, we've set $fontdb{$k}{'doublecheck'} to "true" intentionally
- # when we *know* doublecheck is actually required;
- # if the stub "debug" detects a difference, our database should contain a bug!
- print_warning("zrlistttc check failed for $b: please report to the author!\n");
- }
- } else {
- print_debug("... test passed.\n");
- $bname = $b;
- last;
- }
- } else {
- $bname = $b;
- last;
- }
- }
- if ($bname) {
- # we found a representative, make it available
- $fontdb{$k}{'files'}{$f}{'target'} = $bname;
- $fontdb{$k}{'available'} = 1;
- } else {
- # delete the entry for convenience
- delete $fontdb{$k}{'files'}{$f};
- }
- }
- }
- # second round to determine the winner in case of more targets
- for my $k (keys %fontdb) {
- if ($fontdb{$k}{'available'}) {
- my $mp = 1000000; my $mf;
- for my $f (keys %{$fontdb{$k}{'files'}}) {
- if ($fontdb{$k}{'files'}{$f}{'priority'} < $mp) {
- $mp = $fontdb{$k}{'files'}{$f}{'priority'};
- $mf = $f;
- }
- }
- # extract subfont if necessary
- my $sf = 0;
- if ($mf =~ m/^(.*)\((\d*)\)$/) { $sf = $2; }
- $fontdb{$k}{'target'} = $fontdb{$k}{'files'}{$mf}{'target'};
- $fontdb{$k}{'type'} = $fontdb{$k}{'files'}{$mf}{'type'};
- $fontdb{$k}{'subfont'} = $sf if ($fontdb{$k}{'type'} eq 'TTC' || $fontdb{$k}{'type'} eq 'OTC');
- }
- # not needed anymore
- # delete $fontdb{$k}{'files'};
- }
- if ($opt_debug >= 2) {
- print_ddebug("dumping font database:\n");
- print_ddebug(Data::Dumper::Dumper(\%fontdb));
- }
-}
-
-sub compute_aliases {
- # go through fontdb to check for provides
- # accumulate all provided fonts in @provides
- for my $k (keys %fontdb) {
- if ($fontdb{$k}{'available'}) {
- for my $p (keys %{$fontdb{$k}{'provides'}}) {
- # do not check alias if the real font is available in OTF/TTF/TTC format
- if ($fontdb{$p}{'available'}) {
- next if ($fontdb{$p}{'type'} ne 'OTC');
- }
- # use the priority as key
- # if priorities are double, this will pick one at chance
- if ($aliases{$p}{$fontdb{$k}{'provides'}{$p}}) {
- print_warning("duplicate provide levels:\n");
- print_warning(" current $p $fontdb{$k}{'provides'}{$p} $aliases{$p}{$fontdb{$k}{'provides'}{$p}}\n");
- print_warning(" ignored $p $fontdb{$k}{'provides'}{$p} $k\n");
- } else {
- # if OTC font is caught, then skip it as Ghostscript doesn't support it (2016/12/12)
- if ($fontdb{$k}{'type'} eq 'OTC') {
- print_debug("Currently Ghostscript does not support OTC font,\n");
- print_debug("not adding $fontdb{$k}{'otcname'} to alias candidates\n");
- } else {
- $aliases{$p}{$fontdb{$k}{'provides'}{$p}} = $k;
- }
- }
- }
- }
- }
- # check for user supplied aliases
- for my $a (@opt_aliases) {
- if ($a =~ m/^(.*)=(.*)$/) {
- my $ll = $1;
- my $rr = $2;
- # check for consistency of user provided aliases:
- # - ll must not be available
- # - rr needs to be available as font or alias
- # check whether $rr is available, either as real font or as alias
- if ($fontdb{$ll}{'available'}) {
- print_error("left side of alias spec is provided by a real font: $a\n");
- print_error("stopping here\n");
- exit(1);
- }
- if (!($fontdb{$rr}{'available'} || $aliases{$rr})) {
- print_error("right side of alias spec is not available as real font or alias: $a\n");
- print_error("stopping here\n");
- exit(1);
- }
- $user_aliases{$ll} = $rr;
- }
- }
- if ($opt_debug >= 2) {
- print_ddebug("dumping aliases:\n");
- print_ddebug(Data::Dumper::Dumper(\%aliases));
- }
-}
-
-# While the OTF link target is determined by the filename itself
-# for TTF we can have ttc with several fonts.
-# The following routine determines the link target by selecting
-# the file name of the ttf candidates with the lowest priority
-# as the link target name for TTF
-sub determine_nonotf_link_name {
- for my $k (keys %fontdb) {
- my $ttfname = "";
- my $ttcname = "";
- my $otcname = "";
- my $mpttf = 10000000;
- my $mpttc = 10000000;
- my $mpotc = 10000000;
- for my $f (keys %{$fontdb{$k}{'files'}}) {
- if ($fontdb{$k}{'files'}{$f}{'type'} eq 'TTF') {
- my $p = $fontdb{$k}{'files'}{$f}{'priority'};
- if ($p < $mpttf) {
- $ttfname = $f;
- $ttfname =~ s/^(.*)\(\d*\)$/$1/;
- $mpttf = $p;
- }
- } elsif ($fontdb{$k}{'files'}{$f}{'type'} eq 'TTC') {
- my $p = $fontdb{$k}{'files'}{$f}{'priority'};
- if ($p < $mpttc) {
- $ttcname = $f;
- $ttcname =~ s/^(.*)\(\d*\)$/$1/;
- $mpttc = $p;
- }
- } elsif ($fontdb{$k}{'files'}{$f}{'type'} eq 'OTC') {
- my $p = $fontdb{$k}{'files'}{$f}{'priority'};
- if ($p < $mpotc) {
- $otcname = $f;
- $otcname =~ s/^(.*)\(\d*\)$/$1/;
- $mpotc = $p;
- }
- }
- }
- if ($ttfname) {
- $fontdb{$k}{'ttfname'} = $ttfname;
- }
- if ($ttcname) {
- $fontdb{$k}{'ttcname'} = $ttcname;
- }
- if ($otcname) {
- $fontdb{$k}{'otcname'} = $otcname;
- }
- }
-}
-
-sub read_font_database {
- my @dbl;
- # if --fontdef=foo is given, disregard built-in database and
- # use "foo" as a substitute; otherwise, use built-in database
- if ($opt_fontdef) {
- my $foo = kpse_miscfont($opt_fontdef);
- open(FDB, "<:encoding(UTF-8)", encode('locale_fs', $foo)) ||
- die("Cannot find $opt_fontdef: $!");
- @dbl = <FDB>;
- close(FDB);
- print_debug("New database file: $opt_fontdef...\n");
- } else {
- @dbl = <DATA>;
- }
- read_each_font_database(@dbl);
- # if --fontdef-add=bar is given, use "bar" as an addition
- # to the current database; if the same Name entry appears,
- # overwrite existing one (that is, the addition wins)
- for (@opt_fontdef_add) {
- my $foo = kpse_miscfont($_);
- open(FDB, "<:encoding(UTF-8)", encode('locale_fs', $foo)) ||
- die("Cannot find $_: $!");
- @dbl = <FDB>;
- close(FDB);
- print_debug("Additional database file: $_...\n");
- read_each_font_database(@dbl);
- }
-}
-
-sub read_each_font_database {
- my (@curdbl) = @_;
- my $fontname = "";
- my $fontclass = "";
- my @fontcmaps = ();
- my %fontprovides = ();
- my $fontdoublecheck = "";
- my %fontfiles;
- my $psname = "";
- my $lineno = 0;
- chomp(@curdbl);
- push @curdbl, ""; # add a "final empty line" to easy parsing
- for my $l (@curdbl) {
- $lineno++;
- next if ($l =~ m/^\s*#/); # skip comment line
- $l =~ s/\s*#.*$//; # skip comment after '#'
- if ($l =~ m/^\s*$/) { # empty line is a separator between entries
- if ($fontname || $fontclass || keys(%fontfiles)) {
- if ($fontname && $fontclass && keys(%fontfiles)) {
- my $realfontname = ($psname ? $psname : $fontname);
- if ($fontdb{$realfontname}{'origname'}) {
- # needed for --fontdef-add, which allows overwriting with external database given by user
- print_debug("$fontdb{$realfontname}{'origname'} is already registered in database,\n");
- print_debug("overwriting with the new one ...\n");
- }
- $fontdb{$realfontname}{'origname'} = $fontname;
- $fontdb{$realfontname}{'class'} = $fontclass;
- $fontdb{$realfontname}{'doublecheck'} = $fontdoublecheck;
- $fontdb{$realfontname}{'files'} = { %fontfiles };
- $fontdb{$realfontname}{'provides'} = { %fontprovides };
- if ($fontclass eq "AI0") {
- $encode_list{"AI0-$realfontname"} = [ @fontcmaps ];
- } elsif (@fontcmaps) {
- print_warning("CMap entry for $realfontname (Class: $fontclass) ignored!\n");
- }
- if ($opt_debug >= 3) {
- print_dddebug("Dumping fontfiles for $realfontname: " . Data::Dumper::Dumper(\%fontfiles));
- }
- # reset to start
- $fontname = $fontclass = $psname = "";
- $fontdoublecheck = "";
- @fontcmaps = ();
- %fontfiles = ();
- %fontprovides = ();
- } else {
- print_warning("incomplete entry above line $lineno for $fontname/$fontclass, skipping!\n");
- # reset to start
- $fontname = $fontclass = $psname = "";
- $fontdoublecheck = "";
- @fontcmaps = ();
- %fontfiles = ();
- %fontprovides = ();
- }
- } else {
- # no term is set, so nothing to warn about
- }
- next;
- }
- if ($l =~ m/^!INCLUDE\s*(.*)$/) { # for remove-only database
- next if (!$opt_cleanup);
- my @dbl;
- my $foo = kpse_miscfont($1);
- if (!open(FDB, "<:encoding(UTF-8)", encode('locale_fs', $foo))) {
- print_warning("Cannot find $1, skipping!\n");
- next;
- }
- @dbl = <FDB>;
- close(FDB);
- print_debug("Reading database file $1...\n");
- read_each_font_database(@dbl);
- next;
- }
- if ($l =~ m/^INCLUDE\s*(.*)$/) {
- my @dbl;
- my $foo = kpse_miscfont($1);
- if (!open(FDB, "<:encoding(UTF-8)", encode('locale_fs', $foo))) {
- print_warning("Cannot find $1, skipping!\n");
- next;
- }
- @dbl = <FDB>;
- close(FDB);
- print_debug("Reading database file $1...\n");
- read_each_font_database(@dbl);
- next;
- }
- if ($l =~ m/^Name:\s*(.*)$/) { $fontname = $1; next; }
- if ($l =~ m/^PSName:\s*(.*)$/) { $psname = $1; next; }
- if ($l =~ m/^Class:\s*(.*)$/) { $fontclass = $1 ; next ; }
- if ($l =~ m/^CMap:\s*(.*)$/) { push(@fontcmaps, $1); next ; }
- if ($l =~ m/^Provides\((\d+)\):\s*(.*)$/) { $fontprovides{$2} = $1; next; }
- if ($l =~ m/^Doublecheck:\s*(.*)$/) { $fontdoublecheck = $1 ; next ; }
- if ($l =~ m/^Casefold:\s*(.*)$/) { $fontdoublecheck = $1 ; next ; } # no longer used
- # new code: distinguish 4 types (otf, otc, ttf, ttc)
- if ($l =~ m/^OTFname(\((\d+)\))?:\s*(.*)$/) {
- my $fn = $3;
- $fontfiles{$fn}{'priority'} = ($2 ? $2 : 10);
- print_dddebug("filename: ${fn}\n");
- print_dddebug("type: otf\n");
- $fontfiles{$fn}{'type'} = 'OTF';
- next;
- }
- if ($l =~ m/^OTCname(\((\d+)\))?:\s*(.*)$/) {
- my $fn = $3;
- $fontfiles{$fn}{'priority'} = ($2 ? $2 : 10);
- print_dddebug("filename: ${fn}\n");
- print_dddebug("type: otc\n");
- $fontfiles{$fn}{'type'} = 'OTC';
- next;
- }
- if ($l =~ m/^TTFname(\((\d+)\))?:\s*(.*)$/) {
- my $fn = $3;
- $fontfiles{$fn}{'priority'} = ($2 ? $2 : 10);
- print_dddebug("filename: ${fn}\n");
- print_dddebug("type: ttf\n");
- $fontfiles{$fn}{'type'} = 'TTF';
- next;
- }
- if ($l =~ m/^TTCname(\((\d+)\))?:\s*(.*)$/) {
- my $fn = $3;
- $fontfiles{$fn}{'priority'} = ($2 ? $2 : 10);
- print_dddebug("filename: ${fn}\n");
- print_dddebug("type: ttc\n");
- $fontfiles{$fn}{'type'} = 'TTC';
- next;
- }
- # only for backward compatibility; guess type from the file extension
- if ($l =~ m/^Filename(\((\d+)\))?:\s*(.*)$/) {
- my $fn = $3;
- $fontfiles{$fn}{'priority'} = ($2 ? $2 : 10);
- print_dddebug("filename: ${fn}\n");
- if ($fn =~ m/\.otf$/i) {
- print_dddebug("type: otf\n");
- $fontfiles{$fn}{'type'} = 'OTF';
- } elsif ($fn =~ m/\.otc(\(\d+\))?$/i) {
- print_dddebug("type: otc\n");
- $fontfiles{$fn}{'type'} = 'OTC';
- } elsif ($fn =~ m/\.ttf$/i) {
- print_dddebug("type: ttf\n");
- $fontfiles{$fn}{'type'} = 'TTF';
- } elsif ($fn =~ m/\.ttc(\(\d+\))?$/i) {
- print_dddebug("type: ttc\n");
- $fontfiles{$fn}{'type'} = 'TTC';
- } else {
- print_warning("cannot determine font type of $fn at line $lineno, skipping!\n");
- delete $fontfiles{$fn};
- }
- next;
- }
- # only for removing
- if ($l =~ m/^RMVname(\((\d+)\))?:\s*(.*)$/) {
- my $fn = $3;
- $fontfiles{$fn}{'priority'} = ($2 ? $2 : 10);
- print_dddebug("filename: ${fn}\n");
- print_dddebug("type: remove\n");
- $fontfiles{$fn}{'type'} = 'RMV';
- next;
- }
- # we are still here??
- print_error("Cannot parse this file at line $lineno, exiting.
- Strange line: >>>$l<<<\n");
- exit(1);
- }
-}
-
-sub dump_font_database {
- open(FOO, ">:encoding(UTF-8)", encode('locale_fs', $dump_datafile)) ||
- die("cannot open $dump_datafile for writing: $!");
- for my $k (sort keys %fontdb) {
- print FOO "Name: $fontdb{$k}{'origname'}\n";
- print FOO "PSName: $k\n" if ($fontdb{$k}{'origname'} ne $k);
- my $class = $fontdb{$k}{'class'};
- print FOO "Class: $class\n";
- if ($class eq "AI0") {
- for my $cmap (@{$encode_list{"AI0-$k"}}) {
- print FOO "CMap: $cmap\n";
- }
- }
- for my $p (sort keys %{$fontdb{$k}{'provides'}}) {
- print FOO "Provides($fontdb{$k}{'provides'}{$p}): $p\n";
- }
- print FOO "Doublecheck: $fontdb{$k}{'doublecheck'}\n" if ($fontdb{$k}{'doublecheck'});
- for my $f (sort { $fontdb{$k}{'files'}{$a}{'priority'}
- <=>
- $fontdb{$k}{'files'}{$b}{'priority'} }
- keys %{$fontdb{$k}{'files'}}) {
- print FOO "$fontdb{$k}{'files'}{$f}{'type'}name($fontdb{$k}{'files'}{$f}{'priority'}): $f\n";
- }
- print FOO "\n"; # empty line is a separator between entries
- }
- close(FOO);
-}
-
-sub find_gs_resource {
- my $foundres = '';
- if (win32()) {
- # determine tlgs or native gs
- my $foo = `kpsewhich -var-value=SELFAUTOPARENT`;
- # We assume that the output of kpsewhich is
- # the same as perl's locale (or active code page).
- decode('locale', $foo);
- chomp($foo);
- if ( -d encode('locale_fs', "$foo/tlpkg/tlgs") ) {
- # should be texlive with tlgs
- print_debug("Assuming tlgs win32 ...\n");
- $foundres = "$foo/tlpkg/tlgs/Resource";
- # for TL2016, tlgs binary has built-in Resource,
- # so we cannot set up CJK fonts correctly.
- # the following test forces to exit in such case
- if ( ! -d encode('locale_fs', $foundres) ) {
- print_error("No Resource directory available for tlgs,\n");
- print_error("we cannot support such gs, sorry.\n");
- $foundres = '';
- }
- # change output location
- $cidfmap_pathpart = "../lib/cidfmap";
- $cidfmap_local_pathpart = "../lib/cidfmap.local";
- $cidfmap_aliases_pathpart = "../lib/cidfmap.aliases";
- } else {
- # we assume gswin32c is in the path
- # TODO: what should we do for gswin64c?
- $foundres = `where gswin32c 2>$nul`; # assume 'where' is available
- if ($?) {
- print_error("Cannot run where gswin32c ...\n");
- } else {
- # We assume that the output of 'where' is
- # the same as perl's locale (or active code page).
- chomp($foundres = decode('locale', $foundres));
- # trial 1: assume the relative path
- # when C:\path\to\bin\gswin32c.exe is found, then there should be
- # C:\path\to\Resource (note that 'where' returns backslash-ed path)
- print_debug("Finding gs resource by assuming relative path ...\n");
- $foundres =~ s!\\!/!g;
- $foundres =~ s!/bin/gswin32c\.exe$!/Resource!;
- if ( ! -d encode('locale_fs', $foundres) ) {
- $foundres = '';
- }
- if (!$foundres) {
- print_debug("Found gs but no resource, try another routine ...\n");
- }
- }
- if (!$foundres) {
- chomp(my $gsver = `gswin32c --version 2>$nul`);
- if ($?) {
- print_error("Cannot run gswin32c --version ...\n");
- } else {
- # trial 2: assume the fixed path, c:/gs/gs$gsver/Resource
- print_debug("Finding gs resource by assuming fixed path ...\n");
- $foundres = "c:/gs/gs$gsver/Resource";
- if ( ! -d encode('locale_fs', $foundres) ) {
- $foundres = '';
- }
- if (!$foundres) {
- print_error("Found gs but no resource???\n");
- }
- }
- }
- }
- } else {
- # we assume that gs is in the path
- chomp(my $gsver = `gs --version 2>$nul`);
- if ($?) {
- print_error("Cannot run gs --version ...\n");
- } else {
- # trial 1: assume the relative path
- # when /path/to/bin/gs is found, then there should be
- # /path/to/share/ghostscript/$(gs --version)/Resource
- print_debug("Finding gs resource by assuming relative path ...\n");
- $foundres = `which gs`;
- # We assume that the output of 'which' is
- # the same as perl's locale (or active code page).
- $foundres = decode('locale', $foundres);
- chomp($foundres);
- $foundres =~ s!/bin/gs$!/share/ghostscript/$gsver/Resource!;
- if ( ! -d encode('locale_fs', $foundres) ) {
- $foundres = '';
- }
- if (!$foundres) {
- print_debug("Found gs but no resource, try another routine ...\n");
- }
- }
- if (!$foundres) {
- my @ret = `gs --help 2>$nul`;
- if ($?) {
- print_error("Cannot run gs --help ...\n");
- } else {
- # We assume that the output of gs is
- # the same as perl's locale (or active code page).
- @ret = map { decode('locale', $_) } @ret;
- chomp(@ret);
- # trial 2: parse gs help message
- print_debug("Finding gs resource by parsing help message ...\n");
- $foundres = '';
- # try to find resource line
- for (@ret) {
- if (m!Resource/Font!) {
- $foundres = $_;
- # extract the first substring of non-space chars
- # up to Resource/Font and drop the /Font part
- $foundres =~ s!^.*\s(\S*Resource)/Font.*$!$1!;
- last;
- }
- }
- if (!$foundres) {
- print_error("Found gs but no resource???\n");
- }
- }
- }
- }
- return $foundres;
-}
-
-sub kpse_miscfont {
- my ($file) = @_;
- my $foo = '';
- # first, prioritize GitHub repository diretory structure
- $foo = "database/$file" if (-f encode('locale_fs', "database/$file"));
- if ($foo eq "") {
- my $cmdl = "kpsewhich -format=miscfont $file";
- $cmdl = encode('locale', $cmdl);
- $foo = `$cmdl`;
- # We assume that the output of kpsewhich is
- # the same as perl's locale (or active code page).
- $foo = decode('locale', $foo);
- chomp($foo);
- }
- return $foo;
-}
-
-sub init_encode_locale {
- eval {
- require Encode::Locale;
- Encode::Locale->import();
-
- $debug_msg_before_init .= "Encode::Locale is loaded.\n";
- };
- if ($@) {
- if (win32) {
- die ("For Windows, Encode::Locale is required.\n");
- }
-
- $debug_msg_before_init .=
- "Encode::Locale is not found. Assuming all encodings are UTF-8.\n";
- Encode::Alias::define_alias('locale' => 'UTF-8');
- Encode::Alias::define_alias('locale_fs' => 'UTF-8');
- Encode::Alias::define_alias('console_in' => 'UTF-8');
- Encode::Alias::define_alias('console_out' => 'UTF-8');
- }
-}
-
-sub version {
- my $ret = sprintf "%s version %s\n", $prg, $version;
- return $ret;
-}
-
-sub Usage {
- my $headline = "Configuring Ghostscript for CJK CID/TTF fonts";
- my $usage = "[perl] $prg\[.pl\] [OPTIONS]";
- my $options = "
--o, --output DIR specifies the base output dir, if not provided,
- the Resource directory of an installed Ghostscript
- is searched and used.
--f, --fontdef FILE specify alternate set of font definitions, if not
- given, the built-in set is used
---fontdef-add FILE specify additional set of font definitions, to
- overwrite subset of built-in definitions;
- can be given multiple times
--a, --alias LL=RR defines an alias, or overrides a given alias;
- illegal if LL is provided by a real font, or
- RR is neither available as real font or alias;
- can be given multiple times
---filelist FILE read list of available font files from FILE
- instead of searching with kpathsea
---link-texmf [DIR] link fonts into
- DIR/$otf_pathpart
- and
- DIR/$ttf_pathpart
- where DIR defaults to TEXMFLOCAL
---otfps [DIR] generate configuration file (psnames-for-otf) into
- DIR/$akotfps_pathpart
- which is used by ps2otfps (developed by Akira Kakuto),
- instead of generating snippets
---force do not bail out if linked fonts already exist
---remove try to remove instead of create
---cleanup try to clean up all possible links/snippets and
- cidfmap.local/cidfmap.aliases, which could have been
- generated in the previous runs
--n, --dry-run do not actually output anything
--q, --quiet be less verbose
--d, --debug output debug information, can be given multiple times
--v, --version outputs only the version information
--h, --help this help
-";
-
- my $commandoptions = "
---dump-data [FILE] dump the set of font definitions which is currently
- effective, where FILE (the dump output) defaults to
- $dump_datafile; you can easily modify it,
- and tell me with -f (or --fontdef) option
---only-aliases regenerate only cidfmap.aliases file, instead of all
---list-aliases lists the available aliases and their options, with the
- selected option on top
---list-all-aliases list all possible aliases without searching for
- actually present files
---list-fonts lists the fonts found on the system
---info combines the information of --list-aliases and
- --list-fonts
---machine-readable output of --list-aliases is machine readable
-";
-
- my $shortdesc = "
-This script searches a list of directories for CJK fonts, and makes
-them available to an installed Ghostscript. In the simplest case with
-sufficient privileges, a run without arguments should effect in a
-complete setup of Ghostscript.
-Search is done using the kpathsea library, in particular `kpsewhich`
-program. To run this script, you will need some TeX distribution in
-your system.
-";
-
-my $operation = "
-For each found TrueType (TTF) font it creates a cidfmap entry in
-
- <Resource>/Init/cidfmap.local
- -- if you are using tlgs win32, tlpkg/tlgs/lib/cidfmap.local instead
-
-and links the font to
-
- <Resource>/CIDFSubst/
-
-For each CID font it creates a snippet in
-
- <Resource>/Font/
-
-and links the font to
-
- <Resource>/CIDFont/
-
-The `<Resource>` dir is either given by `-o`/`--output`, or otherwise searched
-from an installed Ghostscript (binary name is assumed to be 'gs' on unix,
-'gswin32c' on win32).
-
-Aliases are added to
-
- <Resource>/Init/cidfmap.aliases
- -- if you are using tlgs win32, tlpkg/tlgs/lib/cidfmap.aliases instead
-
-Finally, it tries to add runlib calls to
-
- <Resource>/Init/cidfmap
- -- if you are using tlgs win32, tlpkg/tlgs/lib/cidfmap
-
-to load the cidfmap.local and cidfmap.aliases.
-";
-
- my $dirsearch = '
-Search is done using the kpathsea library, in particular using kpsewhich
-program. By default the following directories are searched:
- - all TEXMF trees
- - `/Library/Fonts`, `/Library/Fonts/Microsoft`, `/System/Library/Fonts`,
- `/System/Library/Assets`, `/Network/Library/Fonts`,
- `~/Library/Fonts` and `/usr/share/fonts` (all if available)
- - `/Applications/Microsoft Word.app/Contents/Resources/{Fonts,DFonts}`,
- `/Applications/Microsoft Excel.app/Contents/Resources/{Fonts,DFonts}`,
- `/Applications/Microsoft PowerPoint.app/Contents/Resources/{Fonts,DFonts}`
- (all if available, meant for Office for Mac 2016)
- - `c:/windows/fonts` (on Windows)
- - the directories in `OSFONTDIR` environment variable
-
-In case you want to add some directories to the search path, adapt the
-`OSFONTDIR` environment variable accordingly: Example:
-
-`````
- OSFONTDIR="/usr/local/share/fonts/truetype//:/usr/local/share/fonts/opentype//" $prg
-`````
-
-will result in fonts found in the above two given directories to be
-searched in addition.
-';
-
- my $outputfile = "
-If no output option is given, the program searches for a Ghostscript
-interpreter 'gs' and determines its Resource directory. This might
-fail, in which case one need to pass the output directory manually.
-
-Since the program adds files and link to this directory, sufficient
-permissions are necessary.
-";
-
- my $aliases = "
-Aliases are managed via the Provides values in the font database.
-At the moment entries for the basic font names for CJK fonts
-are added:
-
-Japanese:
-
- Ryumin-Light GothicBBB-Medium FutoMinA101-Bold FutoGoB101-Bold
- MidashiMin-MA31 MidashiGo-MB31 Jun101-Light
-
-Korean:
-
- HYSMyeongJo-Medium HYGoThic-Medium HYRGoThic-Medium
-
-Simplified Chinese:
-
- STSong-Light STSong-Regular STHeiti-Regular STHeiti-Light
- STKaiti-Regular STFangsong-Light STFangsong-Regular
-
-Traditional Chinese:
-
- MSung-Light MSung-Medium MHei-Medium MKai-Medium
-
-In addition, we also include provide entries for the OTF Morisawa names:
-
- RyuminPro-Light GothicBBBPro-Medium
- FutoMinA101Pro-Bold FutoGoB101Pro-Bold
- MidashiMinPro-MA31 MidashiGoPro-MB31 Jun101Pro-Light
-
-The order is determined by the `Provides` setting in the font database.
-That is, the first font found in this order will be used to provide the
-alias if necessary.
-
-For the Japanese fonts:
- Morisawa Pr6N, Morisawa, Hiragino ProN, Hiragino,
- Kozuka Pr6N, Kozuka ProVI, Kozuka Pro, Kozuka Std,
- HaranoAji,
- Yu OS X, Yu Win, MS,
- Moga-Mobo-ex, Moga-Mobo, IPAex, IPA, Ume
-
-For the Korean fonts:
- (Hanyang,) Adobe, Solaris, MS, Unfonts, Baekmuk
-
-For the Simplified Chinese:
- Adobe, Fandol, Hiragino, Founder, MS, CJKUnifonts, Arphic, CJKUnifonts-ttf
-
-For the Traditional Chinese:
- Adobe, MS, CJKUnifonts, Arphic, CJKUnifonts-ttf
-
-#### Overriding aliases ####
-
-Using the command line option `--alias LL=RR` one can add arbitrary aliases,
-or override ones selected by the program. For this to work the following
-requirements of `LL` and `RR` must be fulfilled:
- * `LL` is not provided by a real font
- * `RR` is available either as real font, or as alias (indirect alias)
-";
-
- my $authors = "
-The script and its documentation was written by Norbert Preining, based
-on research and work by Masamichi Hosoda, Yusuke Kuroki, Yusuke Terada,
-Bruno Voisin, Hironobu Yamashita, Munehiro Yamamoto and the TeX Q&A wiki
-page.
-
-Maintained by Japanese TeX Development Community. For development, see
- https://github.com/texjporg/cjk-gs-support
-
-The script is licensed under GNU General Public License Version 3 or later.
-The contained font data is not copyrightable.
-";
-
-
- if ($opt_markdown) {
- print "$headline\n";
- print ("=" x length($headline));
- print "\n$shortdesc\nUsage\n-----\n\n`````\n$usage\n`````\n\n";
- print "#### Options ####\n\n`````";
- print_for_out($options, " ");
- print "`````\n\n#### Command like options ####\n\n`````";
- print_for_out($commandoptions, " ");
- print "`````\n\nOperation\n---------\n$operation\n";
- print "How and which directories are searched\n";
- print "--------------------------------------\n$dirsearch\n";
- print "Output files\n";
- print "------------\n$outputfile\n";
- print "Aliases\n";
- print "-------\n$aliases\n";
- print "Authors, Contributors, and Copyright\n";
- print "------------------------------------\n$authors\n";
- } else {
- print "\nUsage: $usage\n\n$headline\n$shortdesc";
- print "\nOptions:\n";
- print_for_out($options, " ");
- print "\nCommand like options:\n";
- print_for_out($commandoptions, " ");
- print "\nOperation:\n";
- print_for_out($operation, " ");
- print "\nHow and which directories are searched:\n";
- print_for_out($dirsearch, " ");
- print "\nOutput files:\n";
- print_for_out($outputfile, " ");
- print "\nAliases:\n";
- print_for_out($aliases, " ");
- print "\nAuthors, Contributors, and Copyright:\n";
- print_for_out($authors, " ");
- print "\n";
- }
- exit(0);
-}
-
-sub print_for_out {
- my ($what, $indent) = @_;
- for (split /\n/, $what) {
- next if m/`````/;
- s/\s*####\s*//g;
- if ($_ eq '') {
- print "\n";
- } else {
- print "$indent$_\n";
- }
- }
-}
-
-# info/warning can be suppressed
-# verbose/error cannot be suppressed
-sub print_info {
- print STDOUT "$prg: ", @_ if (!$opt_quiet);
-}
-sub print_verbose {
- print STDOUT "$prg: ", @_;
-}
-sub print_warning {
- print STDERR "$prg [WARNING]: ", @_ if (!$opt_quiet)
-}
-sub print_error {
- print STDERR "$prg [ERROR]: ", @_;
-}
-sub print_debug {
- print STDERR "$prg [DEBUG]: ", @_ if ($opt_debug >= 1);
-}
-sub print_ddebug {
- print STDERR "$prg [DEBUG]: ", @_ if ($opt_debug >= 2);
-}
-sub print_dddebug {
- print STDERR "$prg [DEBUG]: ", @_ if ($opt_debug >= 3);
-}
-
-
-__DATA__
-#
-# CJK FONT DEFINITIONS
-#
-
-# Noto
-INCLUDE cjkgs-notoserif.dat
-INCLUDE cjkgs-notosans.dat
-
-# SourceHan
-INCLUDE cjkgs-sourcehanserif.dat
-INCLUDE cjkgs-sourcehansans.dat
-
-#
-# JAPANESE FONTS
-#
-
-# Morisawa -- Provides J10(Pr6N), J15(Pr6), J18(Pr5), J20(Pro)
-INCLUDE cjkgs-morisawa.dat
-#INCLUDE cjkgs-morisawa-extra.dat
-
-# Hiragino -- Provides J30(ProN), J40(Pro)
-INCLUDE cjkgs-hiragino.dat
-
-# Kozuka -- Provides J50(Pr6N), J55(ProVI), J60(Pro), J65(Std)
-INCLUDE cjkgs-kozuka.dat
-INCLUDE cjkgs-ryokana.dat
-
-# Yu-fonts MacOS version -- Provides J80
-INCLUDE cjkgs-yu-osx.dat
-
-# Yu-fonts Windows/MSOffice version -- Provides J90
-INCLUDE cjkgs-yu-win.dat
-
-# MS -- Provides J95
-INCLUDE cjkgs-microsoft.dat
-
-# BIZ UD
-INCLUDE cjkgs-bizud.dat
-
-# TypeBank
-INCLUDE cjkgs-typebank.dat
-
-# Fontworks
-INCLUDE cjkgs-fontworks.dat
-
-# Toppan
-INCLUDE cjkgs-toppan.dat
-
-# Heisei
-INCLUDE cjkgs-heisei.dat
-
-# Moga-Mobo from Y.Oz Vox (free) -- Provides J100(Ex), J110(none)
-INCLUDE cjkgs-mogamobo.dat
-
-# IPA (free) -- Provides J120(Ex), J130(none)
-INCLUDE cjkgs-ipa.dat
-
-# Ume-font (free) -- Provides J140
-INCLUDE cjkgs-ume.dat
-
-# Sazanami (free)
-INCLUDE cjkgs-sazanami.dat
-
-# Harano Aji Fonts (free) -- Provides J70, J71
-INCLUDE cjkgs-haranoaji.dat
-
-# Osaka (Apple)
-
-Name: Osaka
-Class: Japan
-TTFname: Osaka.ttf
-
-Name: Osaka-Mono
-Class: Japan
-TTFname: OsakaMono.ttf
-
-#
-# CHINESE FONTS
-#
-
-# Adobe -- Provides S30, T30
-INCLUDE cjkgs-adobe.dat
-
-# Hiragino -- Provides S50
-# (already included in JAPANESE section)
-
-# Beijing Founder Electronics -- Provides S55
-INCLUDE cjkgs-founder.dat
-
-# Changzhou SinoType -- Provides S??
-INCLUDE cjkgs-sinotype.dat
-
-# DynaComware -- Provides T??
-INCLUDE cjkgs-dynacomware.dat
-
-# Monotype
-INCLUDE cjkgs-monotype.dat
-
-# Apple
-INCLUDE cjkgs-apple.dat
-
-# Shanghai Ikarus Ltd./URW Software & Type GmbH
-
-Name: SIL-Hei-Med-Jian
-Class: GB
-TTFname: Hei.ttf
-
-Name: SIL-Kai-Reg-Jian
-Class: GB
-TTFname: Kai.ttf
-
-# Fandol (free) -- Provides S40
-INCLUDE cjkgs-fandol.dat
-
-# Arphic (free) -- Provides S80, T80
-INCLUDE cjkgs-arphic.dat
-
-# CJK-Unifonts new ttc edition (free) -- Provides T70, S70
-# CJK-Unifonts old ttf edition (free) -- Provides T90, S90
-INCLUDE cjkgs-cjkuni.dat
-
-# WenQuanYi (free)
-INCLUDE cjkgs-wenquanyi.dat
-
-# cwTeX (free)
-
-Name: cwTeXMing
-Class: CNS
-TTFname: cwming.ttf
-
-Name: cwTeXHeiBold
-Class: CNS
-TTFname: cwheib.ttf
-
-Name: cwTeXKai
-Class: CNS
-TTFname: cwkai.ttf
-
-Name: cwTeXYen
-Class: CNS
-TTFname: cwyen.ttf
-
-Name: cwTeXFangSong
-Class: CNS
-TTFname: cwfs.ttf
-
-#
-# KOREAN FONTS
-#
-
-# Adobe -- Provides K30/80
-# (already included in CHINESE section)
-
-# Solaris -- Provides K40
-INCLUDE cjkgs-solaris.dat
-
-# Baekmuk (free)
-# This is a special case, because "batang.ttf" in baekmuk and
-# "Batang.ttf" in Microsoft Mac Office font share the same filename;
-# symlink name should be "Baekmuk-Batang.ttf"
-# similar for "Gulim.ttf" -- HY (2016/09/29)
-
-Name: Baekmuk-Batang
-Class: Korea
-Provides(70): HYSMyeongJo-Medium
-Doublecheck: true
-TTFname(20): batang.ttf
-TTFname(10): Baekmuk-Batang.ttf
-
-Name: Baekmuk-Dotum
-Class: Korea
-Provides(70): HYGoThic-Medium
-TTFname(20): dotum.ttf
-TTFname(10): Baekmuk-Dotum.ttf
-
-Name: Baekmuk-Gulim
-Class: Korea
-Provides(70): HYRGoThic-Medium
-Doublecheck: true
-TTFname(20): gulim.ttf
-TTFname(10): Baekmuk-Gulim.ttf
-
-Name: Baekmuk-Headline
-Class: Korea
-TTFname(20): hline.ttf
-TTFname(10): Baekmuk-Headline.ttf
-
-# Unfonts (free) -- Provides K60
-INCLUDE cjkgs-unfonts.dat
-
-# Nanum (free)
-INCLUDE cjkgs-nanum.dat
-
-# Design font by Ho-Seok Ee, aka. "ALee's font" (free)
-
-Name: Bandal
-Class: Korea
-TTFname: Bandal.ttf
-
-Name: Bangwool
-Class: Korea
-TTFname: Bangwool.ttf
-
-Name: Eunjin
-Class: Korea
-TTFname: Eunjin.ttf
-
-Name: EunjinNakseo
-Class: Korea
-TTFname: EunjinNakseo.ttf
-
-Name: Guseul
-Class: Korea
-TTFname: Guseul.ttf
-
-# Woowa Brothers (free)
-
-Name: BMHANNA
-Class: Korea
-TTFname: BM-HANNA.ttf
-
-# Hancom HCR (free)
-INCLUDE cjkgs-hancom.dat
-
-
-#
-# Microsoft Windows, Windows/Mac Office fonts
-#
-
-# korea
-
-Name: Batang
-Class: Korea
-Doublecheck: true
-TTFname(50): Batang.ttf
-TTCname(20): batang.ttc(0)
-
-Name: BatangChe
-Class: Korea
-Provides(50): HYSMyeongJo-Medium
-TTCname(20): batang.ttc(1)
-
-Name: Dotum
-Class: Korea
-TTCname(20): gulim.ttc(2)
-
-Name: DotumChe
-Class: Korea
-Provides(50): HYGoThic-Medium
-TTCname(20): gulim.ttc(3)
-
-Name: Gulim
-Class: Korea
-Doublecheck: true
-TTFname(50): Gulim.ttf
-TTCname(20): gulim.ttc(0)
-
-Name: GulimChe
-Class: Korea
-Provides(50): HYRGoThic-Medium
-Provides(90): HYGoThic-Medium
-TTCname(20): gulim.ttc(1)
-
-Name: Gungsuh
-Class: Korea
-TTCname(20): batang.ttc(2)
-
-Name: GungsuhChe
-Class: Korea
-TTCname(20): batang.ttc(3)
-
-# for Windows 10
-# and Office for Mac 2016 (at least Ver.16.11.0, 2018-03)
-Name: MalgunGothic
-Class: Korea
-Doublecheck: true
-TTFname: malgun.ttf
-
-# for Windows 7
-# and Office for Mac 2016 (Ver.15.32.0, 2017-03)
-Name: MalgunGothicRegular
-Class: Korea
-Doublecheck: true
-TTFname: malgun.ttf
-
-Name: MalgunGothicBold
-Class: Korea
-TTFname: malgunbd.ttf
-
-Name: MalgunGothic-Semilight
-Class: Korea
-TTFname: malgunsl.ttf
-
-# simplified chinese
-
-Name: SimHei
-Class: GB
-Provides(60): STHeiti-Regular
-Provides(60): STHeiti-Light
-TTFname(50): SimHei.ttf
-TTFname(20): simhei.ttf
-
-Name: SimSun
-Class: GB
-Provides(60): STSong-Light
-Provides(60): STSong-Regular
-TTFname(50): SimSun.ttf
-TTFname(21): simsun.ttf
-TTCname(20): simsun.ttc(0)
-
-Name: NSimSun
-Class: GB
-TTCname(20): simsun.ttc(1)
-
-Name: KaiTi
-Class: GB
-Provides(60): STKaiti-Regular
-TTFname(40): Kaiti.ttf
-TTFname(20): simkai.ttf
-
-Name: FangSong
-Class: GB
-Provides(60): STFangsong-Light
-Provides(60): STFangsong-Regular
-TTFname(40): Fangsong.ttf
-TTFname(20): simfang.ttf
-
-Name: LiSu
-Class: GB
-TTCname(20): SIMLI.TTF
-TTCname(19): simli.ttf
-
-Name: YouYuan
-Class: GB
-TTCname(20): SIMYOU.TTF
-TTCname(19): simyou.ttf
-
-Name: MicrosoftYaHei
-Class: GB
-TTFname(20): msyh.ttf
-TTCname(30): msyh.ttc(0)
-
-Name: MicrosoftYaHei-Bold
-Class: GB
-TTFname(20): msyhbd.ttf
-TTCname(30): msyhbd.ttc(0)
-
-Name: MicrosoftYaHeiLight
-Class: GB
-TTFname(20): msyhl.ttf
-TTCname(30): msyhl.ttc(0)
-
-Name: DengXian-Regular
-Class: GB
-TTFname: Deng.ttf
-
-Name: DengXian-Bold
-Class: GB
-TTFname: Dengb.ttf
-
-Name: DengXian-Light
-Class: GB
-TTFname: Dengl.ttf
-
-# traditional chinese
-
-Name: MingLiU
-Class: CNS
-Provides(60): MSung-Medium
-Provides(60): MSung-Light
-TTFname(50): MingLiU.ttf
-TTCname(20): mingliu.ttc(0)
-
-Name: PMingLiU
-Class: CNS
-TTFname(50): PMingLiU.ttf
-TTCname(20): mingliu.ttc(1)
-
-Name: DFKaiShu-SB-Estd-BF
-Class: CNS
-Provides(60): MKai-Medium
-TTFname(50): BiauKai.ttf
-TTFname(20): kaiu.ttf
-
-Name: MicrosoftJhengHeiRegular
-Class: CNS
-Provides(60): MHei-Medium
-TTFname(40): MSJH.ttf
-TTFname(20): msjh.ttf
-TTCname(30): msjh.ttc(0)
-
-Name: MicrosoftJhengHeiBold
-Class: CNS
-TTFname(40): MSJHBD.ttf
-TTFname(20): msjhbd.ttf
-TTCname(30): msjhbd.ttc(0)
-
-Name: MicrosoftJhengHeiLight
-Class: CNS
-TTCname(30): msjhl.ttc(0)
-
-Name: MicrosoftMHei
-Class: CNS
-Provides(65): MHei-Medium
-TTFname(10): MSMHei.ttf
-
-Name: MicrosoftMHei-Bold
-Class: CNS
-TTFname(10): MSMHei-Bold.ttf
-
-# Remove-only database (should begin with !INCLUDE)
-# that is, entries which contain at least one 'RMVname' line
-# note that this line should come at the _end_ of all INCLUDE files
-!INCLUDE cjkgs-removeonly.dat
-!INCLUDE cjkgs-macos-removeonly.dat
-
-
-### Local Variables:
-### perl-indent-level: 2
-### tab-width: 2
-### indent-tabs-mode: nil
-### End:
-# vim: set tabstop=2 expandtab autoindent:
diff --git a/Build/source/texk/texlive/linked_scripts/clojure-pamphlet/pamphletangler b/Build/source/texk/texlive/linked_scripts/clojure-pamphlet/pamphletangler
deleted file mode 100755
index 50c384cc98e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/clojure-pamphlet/pamphletangler
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/perl -w
-
-=head1 NAME
-
-pamphletangler - Extract code bits from LaTeX pamphlet files.
-
-=cut
-
-=head1 SYNOPSIS
-
-B<pamphletangler> [OPTION...] I<FILE> I<CHUNKNAME>
-
-=cut
-
-=head1 DESCRIPTION
-
-The clojure pamphlet system is a system based on the clojure literate
-system. In the clojure's pamphlet system you have your main LaTeX file, which
-can be compiled regularly. This file contains documentation and source code
-(just like in other forms of literate programming). This code snippets are
-wrapped in the 'chunk' environment, hence they can be recognized by the tangler
-in order to extract them. Chunks can be included inside each other by the
-'getchunk' command (which will be typesetted acordingly). Finally, you run your
-LaTeX file through the tangler and get your desired chunk of code.
-
-=cut
-
-=head1 OPTIONS
-
-=over 29
-
-=item -L, --line=linetext
-
-If set, this text will be inserted after jumps of lines, changing the string
-inside "changetext" for the line number. This is used so that error report
-refers to pamphlet line number instead of output line number
-
-=item -C, --change=changetext
-
-Defaults to "{}" this is the text that will be replaced with the line number if
-the linetext option is specified
-
-=item -?, --help
-
-Give this help list
-
-=item --usage
-
-Give a short usage message
-
-=item --man
-
-Print manual page
-
-=item -V, --version
-
-Print program version
-
-=back
-
-=head1 LICENSE
-
-Copyright (C) 2019 Ernesto Lanchares Sanchez.
-
- The clojure-pamphlet tagler is free software; you can redistribute
- it and/or modify it under the terms of the GNU Lesser General
- Public License as published by the Free Software Foundation;
- either version 3 of the License, or (at your option) any later
- version.
-
- The clojure-pamphlet tangler is distributed in the hope that it
- will be useful, but WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, see
- L<http://www.gnu.org/licenses/>.
-
-
-=head1 AUTHOR
-
-Ernesto Lanchares <e.lancha98@gmail.com>
-
-=head1 BUGS
-
-Report bugs to e.lancha98@gmail.com
-
-=cut
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Pod::Usage qw(pod2usage);
-use vars qw/$VERSION/;
-
-BEGIN { $VERSION = '1.3' }
-
-my $linetext = "";
-my $changetext = "{}";
-my $filename;
-my $chunkname;
-
-OPTS: {
- GetOptions(
- 'usage' => sub { pod2usage( -verbose => 99, -sections => [ qw(SYNOPSIS) ]); },
- 'help|?' => sub { pod2usage( -verbose => 99, -sections => [ qw(SYNOPSIS DESCRIPTION OPTIONS BUGS) ]); },
- 'man' => sub { pod2usage( -verbose => 2) },
- 'version|V' => sub { print "$VERSION\n"; exit; },
- 'line|L=s' => \$linetext,
- 'change|C=s' => \$changetext
- );
-
- pod2usage( -message => "[ERROR]: Invalid number of arguments." )
- if scalar(@ARGV) != 2;
- $filename = shift;
- $chunkname = shift;
-}
-
-open(my $file, "<", $filename) or die "Can't open $filename: $!";
-
-my $file_contents = do { local $/; <$file> };
-my %codeblocks;
-
-while ($file_contents =~ /\\begin\{chunk\}\{([\w.]+)\}[\s\h\t]*\n?(.*?)\n?[\s\t\h]*\\end\{chunk\}/sg) {
- $codeblocks{$1} = { source => $2, printing => undef };
-}
-
-open($file, "<", $filename) or die "Can't open $filename: $!";
-my $index = 1;
-while (my $line = <$file>) {
- while ($line =~ /\\begin\{chunk\}\{([\w.]+)\}/g) {
- $codeblocks{$1}{line} = $index+1;
- }
- $index++;
-}
-
-sub printchunk {
- my ($chunk, $indent) = @_;
-
- die "Chunk $chunk not found." if (!exists($codeblocks{$chunk}));
-
- die "Cyclic reference found: $chunk" if $codeblocks{$chunk}{printing};
- $codeblocks{$chunk}{printing} = 1;
-
- my $localines = 1;
- print $linetext =~ s/$changetext/$codeblocks{$chunk}{line}/gr, "\n";
- foreach my $line (split(/\n/, $codeblocks{$chunk}{source})) {
- if ($line =~ /([\s\t\h]*)\\getchunk\{([\w.]+)\}/) {
- eval {
- printchunk($2, $1); #$1 contains indent and $2 contains chunkname
- print $linetext =~ s/$changetext/@{[$codeblocks{$chunk}{line} + $localines]}/gr, "\n";
- 1;
- } or do {
- if (rindex($@, "Cyclic reference found:", 0) == 0) {
- $@ =~ /(.+?)( at .*)/s;
- die "$1 <- $chunk";
- }
- die $@;
- }
- } else {
- print $indent, $line, "\n";
- }
- $localines++;
- }
-
- $codeblocks{$chunk}{printing} = undef;
- return 0;
-}
-printchunk($chunkname, "");
diff --git a/Build/source/texk/texlive/linked_scripts/cluttex/cluttex.lua b/Build/source/texk/texlive/linked_scripts/cluttex/cluttex.lua
deleted file mode 100755
index d3859a69fa5..00000000000
--- a/Build/source/texk/texlive/linked_scripts/cluttex/cluttex.lua
+++ /dev/null
@@ -1,3541 +0,0 @@
-#!/usr/bin/env texlua
-local io, os, string, table, package, require, assert, error, ipairs, type, select, arg = io, os, string, table, package, require, assert, error, ipairs, type, select, arg
-local CLUTTEX_VERBOSITY, CLUTTEX_VERSION
-os.type = os.type or "unix"
-if lfs and not package.loaded['lfs'] then package.loaded['lfs'] = lfs end
-if os.type == "windows" then
-package.preload["texrunner.pathutil"] = function(...)
---[[
- Copyright 2016 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
--- pathutil module
-
-local assert = assert
-local select = select
-local string = string
-local string_find = string.find
-local string_sub = string.sub
-local string_match = string.match
-local string_gsub = string.gsub
-local filesys = require "lfs"
-
-local function basename(path)
- local i = 0
- while true do
- local j = string_find(path, "[\\/]", i + 1)
- if j == nil then
- return string_sub(path, i + 1)
- elseif j == #path then
- return string_sub(path, i + 1, -2)
- end
- i = j
- end
-end
-
-
-local function dirname(path)
- local i = 0
- while true do
- local j = string_find(path, "[\\/]", i + 1)
- if j == nil then
- if i == 0 then
- -- No directory portion
- return "."
- elseif i == 1 then
- -- Root
- return string_sub(path, 1, 1)
- else
- -- Directory portion without trailing slash
- return string_sub(path, 1, i - 1)
- end
- end
- i = j
- end
-end
-
-
-local function parentdir(path)
- local i = 0
- while true do
- local j = string_find(path, "[\\/]", i + 1)
- if j == nil then
- if i == 0 then
- -- No directory portion
- return "."
- elseif i == 1 then
- -- Root
- return string_sub(path, 1, 1)
- else
- -- Directory portion without trailing slash
- return string_sub(path, 1, i - 1)
- end
- elseif j == #path then
- -- Directory portion without trailing slash
- return string_sub(path, 1, i - 1)
- end
- i = j
- end
-end
-
-
-local function trimext(path)
- return (string_gsub(path, "%.[^\\/%.]*$", ""))
-end
-
-
-local function ext(path)
- return string_match(path, "%.([^\\/%.]*)$") or ""
-end
-
-
-local function replaceext(path, newext)
- local newpath, n = string_gsub(path, "%.([^\\/%.]*)$", function() return "." .. newext end)
- if n == 0 then
- return newpath .. "." .. newext
- else
- return newpath
- end
-end
-
-
-local function joinpath2(x, y)
- local xd = x
- local last = string_sub(x, -1)
- if last ~= "/" and last ~= "\\" then
- xd = x .. "\\"
- end
- if y == "." then
- return xd
- elseif y == ".." then
- return dirname(x)
- else
- if string_match(y, "^%.[\\/]") then
- return xd .. string_sub(y, 3)
- else
- return xd .. y
- end
- end
-end
-
-local function joinpath(...)
- local n = select("#", ...)
- if n == 2 then
- return joinpath2(...)
- elseif n == 0 then
- return "."
- elseif n == 1 then
- return ...
- else
- return joinpath(joinpath2(...), select(3, ...))
- end
-end
-
-
--- https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
-local function isabspath(path)
- local init = string_sub(path, 1, 1)
- return init == "\\" or init == "/" or string_match(path, "^%a:[/\\]")
-end
-
-local function abspath(path, cwd)
- if isabspath(path) then
- -- absolute path
- return path
- else
- -- TODO: relative path with a drive letter is not supported
- cwd = cwd or filesys.currentdir()
- return joinpath2(cwd, path)
- end
-end
-
-return {
- basename = basename,
- dirname = dirname,
- parentdir = parentdir,
- trimext = trimext,
- ext = ext,
- replaceext = replaceext,
- join = joinpath,
- abspath = abspath,
-}
-end
-else
-package.preload["texrunner.pathutil"] = function(...)
---[[
- Copyright 2016 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
--- pathutil module for *nix
-
-local assert = assert
-local select = select
-local string = string
-local string_find = string.find
-local string_sub = string.sub
-local string_match = string.match
-local string_gsub = string.gsub
-local filesys = require "lfs"
-
-local function basename(path)
- local i = 0
- while true do
- local j = string_find(path, "/", i + 1, true)
- if j == nil then
- return string_sub(path, i + 1)
- elseif j == #path then
- return string_sub(path, i + 1, -2)
- end
- i = j
- end
-end
-
-
-local function dirname(path)
- local i = 0
- while true do
- local j = string_find(path, "/", i + 1, true)
- if j == nil then
- if i == 0 then
- -- No directory portion
- return "."
- elseif i == 1 then
- -- Root
- return "/"
- else
- -- Directory portion without trailing slash
- return string_sub(path, 1, i - 1)
- end
- end
- i = j
- end
-end
-
-
-local function parentdir(path)
- local i = 0
- while true do
- local j = string_find(path, "/", i + 1, true)
- if j == nil then
- if i == 0 then
- -- No directory portion
- return "."
- elseif i == 1 then
- -- Root
- return "/"
- else
- -- Directory portion without trailing slash
- return string_sub(path, 1, i - 1)
- end
- elseif j == #path then
- -- Directory portion without trailing slash
- return string_sub(path, 1, i - 1)
- end
- i = j
- end
-end
-
-
-local function trimext(path)
- return (string_gsub(path, "%.[^/%.]*$", ""))
-end
-
-
-local function ext(path)
- return string_match(path, "%.([^/%.]*)$") or ""
-end
-
-
-local function replaceext(path, newext)
- local newpath, n = string_gsub(path, "%.([^/%.]*)$", function() return "." .. newext end)
- if n == 0 then
- return newpath .. "." .. newext
- else
- return newpath
- end
-end
-
-
-local function joinpath2(x, y)
- local xd = x
- if string_sub(x, -1) ~= "/" then
- xd = x .. "/"
- end
- if y == "." then
- return xd
- elseif y == ".." then
- return dirname(x)
- else
- if string_sub(y, 1, 2) == "./" then
- return xd .. string_sub(y, 3)
- else
- return xd .. y
- end
- end
-end
-
-local function joinpath(...)
- local n = select("#", ...)
- if n == 2 then
- return joinpath2(...)
- elseif n == 0 then
- return "."
- elseif n == 1 then
- return ...
- else
- return joinpath(joinpath2(...), select(3, ...))
- end
-end
-
-
-local function abspath(path, cwd)
- if string_sub(path, 1, 1) == "/" then
- -- absolute path
- return path
- else
- cwd = cwd or filesys.currentdir()
- return joinpath2(cwd, path)
- end
-end
-
-
-return {
- basename = basename,
- dirname = dirname,
- parentdir = parentdir,
- trimext = trimext,
- ext = ext,
- replaceext = replaceext,
- join = joinpath,
- abspath = abspath,
-}
-end
-end
-if os.type == "windows" then
-package.preload["texrunner.shellutil"] = function(...)
---[[
- Copyright 2016,2019 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local string_gsub = string.gsub
-local os_execute = os.execute
-
--- s: string
-local function escape(s)
- return '"' .. string_gsub(string_gsub(s, '(\\*)"', '%1%1\\"'), '(\\+)$', '%1%1') .. '"'
-end
-
-
-local function has_command(name)
- local result = os_execute("where " .. escape(name) .. " > NUL 2>&1")
- -- Note that os.execute returns a number on Lua 5.1 or LuaTeX
- return result == 0 or result == true
-end
-
-return {
- escape = escape,
- has_command = has_command,
-}
-end
-else
-package.preload["texrunner.shellutil"] = function(...)
---[[
- Copyright 2016,2019 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local assert = assert
-local string_match = string.match
-local table = table
-local table_insert = table.insert
-local table_concat = table.concat
-local os_execute = os.execute
-
--- s: string
-local function escape(s)
- local len = #s
- local result = {}
- local t,i = string_match(s, "^([^']*)()")
- assert(t)
- if t ~= "" then
- table_insert(result, "'")
- table_insert(result, t)
- table_insert(result, "'")
- end
- while i < len do
- t,i = string_match(s, "^('+)()", i)
- assert(t)
- table_insert(result, '"')
- table_insert(result, t)
- table_insert(result, '"')
- t,i = string_match(s, "^([^']*)()", i)
- assert(t)
- if t ~= "" then
- table_insert(result, "'")
- table_insert(result, t)
- table_insert(result, "'")
- end
- end
- return table_concat(result, "")
-end
-
-
-local function has_command(name)
- local result = os_execute("which " .. escape(name) .. " > /dev/null")
- -- Note that os.execute returns a number on Lua 5.1 or LuaTeX
- return result == 0 or result == true
-end
-
-return {
- escape = escape,
- has_command = has_command,
-}
-end
-end
-package.preload["texrunner.fsutil"] = function(...)
---[[
- Copyright 2016 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local assert = assert
-local os = os
-local os_execute = os.execute
-local os_remove = os.remove
-local filesys = require "lfs"
-local pathutil = require "texrunner.pathutil"
-local shellutil = require "texrunner.shellutil"
-local escape = shellutil.escape
-
-local copy_command
-if os.type == "windows" then
- function copy_command(from, to)
- -- TODO: What if `from` begins with a slash?
- return "copy " .. escape(from) .. " " .. escape(to) .. " > NUL"
- end
-else
- function copy_command(from, to)
- -- TODO: What if `from` begins with a hypen?
- return "cp " .. escape(from) .. " " .. escape(to)
- end
-end
-
-local isfile = filesys.isfile or function(path)
- return filesys.attributes(path, "mode") == "file"
-end
-
-local isdir = filesys.isdir or function(path)
- return filesys.attributes(path, "mode") == "directory"
-end
-
-local function mkdir_rec(path)
- local succ, err = filesys.mkdir(path)
- if not succ then
- succ, err = mkdir_rec(pathutil.parentdir(path))
- if succ then
- return filesys.mkdir(path)
- end
- end
- return succ, err
-end
-
-local function remove_rec(path)
- if isdir(path) then
- for file in filesys.dir(path) do
- if file ~= "." and file ~= ".." then
- local succ, err = remove_rec(pathutil.join(path, file))
- if not succ then
- return succ, err
- end
- end
- end
- return filesys.rmdir(path)
- else
- return os_remove(path)
- end
-end
-
-return {
- copy_command = copy_command,
- isfile = isfile,
- isdir = isdir,
- mkdir_rec = mkdir_rec,
- remove_rec = remove_rec,
-}
-end
-package.preload["texrunner.option"] = function(...)
---[[
- Copyright 2016 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
--- options_and_params, i = parseoption(arg, options)
--- options[i] = {short = "o", long = "option" [, param = true] [, boolean = true] [, allow_single_hyphen = false]}
--- options_and_params[j] = {"option", "value"}
--- arg[i], arg[i + 1], ..., arg[#arg] are non-options
-local function parseoption(arg, options)
- local i = 1
- local option_and_params = {}
- while i <= #arg do
- if arg[i] == "--" then
- -- Stop handling options
- i = i + 1
- break
- elseif arg[i]:sub(1,2) == "--" then
- -- Long option
- local name,param = arg[i]:match("^([^=]+)=(.*)$", 3)
- name = name or arg[i]:sub(3)
- local opt = nil
- for _,o in ipairs(options) do
- if o.long then
- if o.long == name then
- if o.param then
- if param then
- -- --option=param
- else
- if o.default ~= nil then
- param = o.default
- else
- -- --option param
- assert(i + 1 <= #arg, "argument missing after " .. arg[i] .. " option")
- param = arg[i + 1]
- i = i + 1
- end
- end
- else
- -- --option
- param = true
- end
- opt = o
- break
- elseif o.boolean and name == "no-" .. o.long then
- -- --no-option
- opt = o
- param = false
- break
- end
- end
- end
- if opt then
- table.insert(option_and_params, {opt.long, param})
- else
- -- Unknown long option
- error("unknown long option: " .. arg[i])
- end
- elseif arg[i]:sub(1,1) == "-" then
- local name,param = arg[i]:match("^([^=]+)=(.*)$", 2)
- name = name or arg[i]:sub(2)
- local opt = nil
- for _,o in ipairs(options) do
- if o.long and o.allow_single_hyphen then
- if o.long == name then
- if o.param then
- if param then
- -- -option=param
- else
- if o.default ~= nil then
- param = o.default
- else
- -- -option param
- assert(i + 1 <= #arg, "argument missing after " .. arg[i] .. " option")
- param = arg[i + 1]
- i = i + 1
- end
- end
- else
- -- -option
- param = true
- end
- opt = o
- break
- elseif o.boolean and name == "no-" .. o.long then
- -- -no-option
- opt = o
- param = false
- break
- end
- elseif o.long and #name >= 2 and (o.long == name or (o.boolean and name == "no-" .. o.long)) then
- error("You must supply two hyphens (i.e. --" .. name .. ") for long option")
- end
- end
- if opt == nil then
- -- Short option
- name = arg[i]:sub(2,2)
- for _,o in ipairs(options) do
- if o.short then
- if o.short == name then
- if o.param then
- if #arg[i] > 2 then
- -- -oparam
- param = arg[i]:sub(3)
- else
- -- -o param
- assert(i + 1 <= #arg, "argument missing after " .. arg[i] .. " option")
- param = arg[i + 1]
- i = i + 1
- end
- else
- -- -o
- assert(#arg[i] == 2, "combining multiple short options like -abc is not supported")
- param = true
- end
- opt = o
- break
- end
- end
- end
- end
- if opt then
- table.insert(option_and_params, {opt.long or opt.short, param})
- else
- error("unknown short option: " .. arg[i])
- end
- else
- -- arg[i] is not an option
- break
- end
- i = i + 1
- end
- return option_and_params, i
-end
-
-return {
- parseoption = parseoption;
-}
-end
-package.preload["texrunner.tex_engine"] = function(...)
---[[
- Copyright 2016,2019 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local table = table
-local setmetatable = setmetatable
-local ipairs = ipairs
-
-local shellutil = require "texrunner.shellutil"
-
---[[
-engine.name: string
-engine.type = "onePass" or "twoPass"
-engine:build_command(inputline, options)
- options:
- halt_on_error: boolean
- interaction: string
- file_line_error: boolean
- synctex: string
- shell_escape: boolean
- shell_restricted: boolean
- jobname: string
- output_directory: string
- extraoptions: a list of strings
- output_format: "pdf" or "dvi"
- draftmode: boolean (pdfTeX / XeTeX / LuaTeX)
- fmt: string
- lua_initialization_script: string (LuaTeX only)
-engine.executable: string
-engine.supports_pdf_generation: boolean
-engine.dvi_extension: string
-engine.supports_draftmode: boolean
-engine.is_luatex: true or nil
-]]
-
-local engine_meta = {}
-engine_meta.__index = engine_meta
-engine_meta.dvi_extension = "dvi"
-function engine_meta:build_command(inputline, options)
- local executable = options.engine_executable or self.executable
- local command = {executable, "-recorder"}
- if options.fmt then
- table.insert(command, "-fmt=" .. options.fmt)
- end
- if options.halt_on_error then
- table.insert(command, "-halt-on-error")
- end
- if options.interaction then
- table.insert(command, "-interaction=" .. options.interaction)
- end
- if options.file_line_error then
- table.insert(command, "-file-line-error")
- end
- if options.synctex then
- table.insert(command, "-synctex=" .. shellutil.escape(options.synctex))
- end
- if options.shell_escape == false then
- table.insert(command, "-no-shell-escape")
- elseif options.shell_restricted == true then
- table.insert(command, "-shell-restricted")
- elseif options.shell_escape == true then
- table.insert(command, "-shell-escape")
- end
- if options.jobname then
- table.insert(command, "-jobname=" .. shellutil.escape(options.jobname))
- end
- if options.output_directory then
- table.insert(command, "-output-directory=" .. shellutil.escape(options.output_directory))
- end
- if self.handle_additional_options then
- self:handle_additional_options(command, options)
- end
- if options.extraoptions then
- for _,v in ipairs(options.extraoptions) do
- table.insert(command, v)
- end
- end
- table.insert(command, shellutil.escape(inputline))
- return table.concat(command, " ")
-end
-
-local function engine(name, supports_pdf_generation, handle_additional_options)
- return setmetatable({
- name = name,
- executable = name,
- supports_pdf_generation = supports_pdf_generation,
- handle_additional_options = handle_additional_options,
- supports_draftmode = supports_pdf_generation,
- }, engine_meta)
-end
-
-local function handle_pdftex_options(self, args, options)
- if options.draftmode then
- table.insert(args, "-draftmode")
- elseif options.output_format == "dvi" then
- table.insert(args, "-output-format=dvi")
- end
-end
-
-local function handle_xetex_options(self, args, options)
- if options.output_format == "dvi" or options.draftmode then
- table.insert(args, "-no-pdf")
- end
-end
-
-local function handle_luatex_options(self, args, options)
- if options.lua_initialization_script then
- table.insert(args, "--lua="..shellutil.escape(options.lua_initialization_script))
- end
- handle_pdftex_options(self, args, options)
-end
-
-local function is_luatex(e)
- e.is_luatex = true
- return e
-end
-
-local KnownEngines = {
- ["pdftex"] = engine("pdftex", true, handle_pdftex_options),
- ["pdflatex"] = engine("pdflatex", true, handle_pdftex_options),
- ["luatex"] = is_luatex(engine("luatex", true, handle_luatex_options)),
- ["lualatex"] = is_luatex(engine("lualatex", true, handle_luatex_options)),
- ["luajittex"] = is_luatex(engine("luajittex", true, handle_luatex_options)),
- ["xetex"] = engine("xetex", true, handle_xetex_options),
- ["xelatex"] = engine("xelatex", true, handle_xetex_options),
- ["tex"] = engine("tex", false),
- ["etex"] = engine("etex", false),
- ["latex"] = engine("latex", false),
- ["ptex"] = engine("ptex", false),
- ["eptex"] = engine("eptex", false),
- ["platex"] = engine("platex", false),
- ["uptex"] = engine("uptex", false),
- ["euptex"] = engine("euptex", false),
- ["uplatex"] = engine("uplatex", false),
-}
-
-KnownEngines["xetex"].dvi_extension = "xdv"
-KnownEngines["xelatex"].dvi_extension = "xdv"
-
-return KnownEngines
-end
-package.preload["texrunner.reruncheck"] = function(...)
---[[
- Copyright 2016,2018 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local io = io
-local assert = assert
-local filesys = require "lfs"
-local md5 = require "md5"
-local fsutil = require "texrunner.fsutil"
-local pathutil = require "texrunner.pathutil"
-local message = require "texrunner.message"
-
-local function md5sum_file(path)
- local f = assert(io.open(path, "rb"))
- local contents = f:read("*a")
- f:close()
- return md5.sum(contents)
-end
-
--- filelist, filemap = parse_recorder_file("jobname.fls", options [, filelist, filemap])
--- filelist[i] = {path = "...", abspath = "...", kind = "input" or "output" or "auxiliary"}
-local function parse_recorder_file(file, options, filelist, filemap)
- filelist = filelist or {}
- filemap = filemap or {}
- for l in io.lines(file) do
- local t,path = l:match("^(%w+) (.*)$")
- if t == "PWD" then
- -- Ignore
-
- elseif t == "INPUT" then
- local abspath = pathutil.abspath(path)
- local fileinfo = filemap[abspath]
- if not fileinfo then
- if fsutil.isfile(path) then
- local kind = "input"
- local ext = pathutil.ext(path)
- if ext == "bbl" then
- kind = "auxiliary"
- end
- fileinfo = {path = path, abspath = abspath, kind = kind}
- table.insert(filelist, fileinfo)
- filemap[abspath] = fileinfo
- else
- -- Maybe a command execution
- end
- else
- if #path < #fileinfo.path then
- fileinfo.path = path
- end
- if fileinfo.kind == "output" then
- -- The files listed in both INPUT and OUTPUT are considered to be auxiliary files.
- fileinfo.kind = "auxiliary"
- end
- end
-
- elseif t == "OUTPUT" then
- local abspath = pathutil.abspath(path)
- local fileinfo = filemap[abspath]
- if not fileinfo then
- local kind = "output"
- local ext = pathutil.ext(path)
- if ext == "out" then
- -- hyperref bookmarks file
- kind = "auxiliary"
- elseif options.makeindex and ext == "idx" then
- -- Treat .idx files (to be processed by MakeIndex) as auxiliary
- kind = "auxiliary"
- -- ...and .ind files
- elseif ext == "bcf" then -- biber
- kind = "auxiliary"
- elseif ext == "glo" then -- makeglossaries
- kind = "auxiliary"
- end
- fileinfo = {path = path, abspath = abspath, kind = kind}
- table.insert(filelist, fileinfo)
- filemap[abspath] = fileinfo
- else
- if #path < #fileinfo.path then
- fileinfo.path = path
- end
- if fileinfo.kind == "input" then
- -- The files listed in both INPUT and OUTPUT are considered to be auxiliary files.
- fileinfo.kind = "auxiliary"
- end
- end
-
- else
- message.warning("Unrecognized line in recorder file '", file, "': ", l)
- end
- end
- return filelist, filemap
-end
-
--- auxstatus = collectfileinfo(filelist [, auxstatus])
-local function collectfileinfo(filelist, auxstatus)
- auxstatus = auxstatus or {}
- for i,fileinfo in ipairs(filelist) do
- local path = fileinfo.abspath
- if fsutil.isfile(path) then
- local status = auxstatus[path] or {}
- auxstatus[path] = status
- if fileinfo.kind == "input" then
- status.mtime = status.mtime or filesys.attributes(path, "modification")
- elseif fileinfo.kind == "auxiliary" then
- status.mtime = status.mtime or filesys.attributes(path, "modification")
- status.size = status.size or filesys.attributes(path, "size")
- status.md5sum = status.md5sum or md5sum_file(path)
- end
- end
- end
- return auxstatus
-end
-
-local function binarytohex(s)
- return (s:gsub(".", function(c) return string.format("%02x", string.byte(c)) end))
-end
-
--- should_rerun, newauxstatus = comparefileinfo(auxfiles, auxstatus)
-local function comparefileinfo(filelist, auxstatus)
- local should_rerun = false
- local newauxstatus = {}
- for i,fileinfo in ipairs(filelist) do
- local path = fileinfo.abspath
- if fsutil.isfile(path) then
- if fileinfo.kind == "input" then
- -- Input file: User might have modified while running TeX.
- local mtime = filesys.attributes(path, "modification")
- if auxstatus[path] and auxstatus[path].mtime then
- if auxstatus[path].mtime < mtime then
- -- Input file was updated during execution
- message.info("Input file '", fileinfo.path, "' was modified (by user, or some external commands).")
- newauxstatus[path] = {mtime = mtime}
- return true, newauxstatus
- end
- else
- -- New input file
- end
-
- elseif fileinfo.kind == "auxiliary" then
- -- Auxiliary file: Compare file contents.
- if auxstatus[path] then
- -- File was touched during execution
- local really_modified = false
- local modified_because = nil
- local size = filesys.attributes(path, "size")
- if auxstatus[path].size ~= size then
- really_modified = true
- if auxstatus[path].size then
- modified_because = string.format("size: %d -> %d", auxstatus[path].size, size)
- else
- modified_because = string.format("size: (N/A) -> %d", size)
- end
- newauxstatus[path] = {size = size}
- else
- local md5sum = md5sum_file(path)
- if auxstatus[path].md5sum ~= md5sum then
- really_modified = true
- if auxstatus[path].md5sum then
- modified_because = string.format("md5: %s -> %s", binarytohex(auxstatus[path].md5sum), binarytohex(md5sum))
- else
- modified_because = string.format("md5: (N/A) -> %s", binarytohex(md5sum))
- end
- end
- newauxstatus[path] = {size = size, md5sum = md5sum}
- end
- if really_modified then
- message.info("File '", fileinfo.path, "' was modified (", modified_because, ").")
- should_rerun = true
- else
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("File '", fileinfo.path, "' unmodified (size and md5sum).")
- end
- end
- else
- -- New file
- if path:sub(-4) == ".aux" then
- local size = filesys.attributes(path, "size")
- if size == 8 then
- local auxfile = io.open(path, "rb")
- local contents = auxfile:read("*a")
- auxfile:close()
- if contents == "\\relax \n" then
- -- The .aux file is new, but it is almost empty
- else
- should_rerun = true
- end
- newauxstatus[path] = {size = size, md5sum = md5.sum(contents)}
- else
- should_rerun = true
- newauxstatus[path] = {size = size}
- end
- else
- should_rerun = true
- end
- if should_rerun then
- message.info("New auxiliary file '", fileinfo.path, "'.")
- else
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("Ignoring almost-empty auxiliary file '", fileinfo.path, "'.")
- end
- end
- end
- if should_rerun then
- break
- end
- end
- else
- -- Auxiliary file is not really a file???
- end
- end
- return should_rerun, newauxstatus
-end
-
--- true if src is newer than dst
-local function comparefiletime(srcpath, dstpath, auxstatus)
- if not filesys.isfile(dstpath) then
- return true
- end
- local src_info = auxstatus[srcpath]
- if src_info then
- local src_mtime = src_info.mtime
- if src_mtime then
- local dst_mtime = filesys.attributes(dstpath, "modification")
- return src_mtime > dst_mtime
- end
- end
- return false
-end
-
-return {
- parse_recorder_file = parse_recorder_file;
- collectfileinfo = collectfileinfo;
- comparefileinfo = comparefileinfo;
- comparefiletime = comparefiletime;
-}
-end
-package.preload["texrunner.auxfile"] = function(...)
---[[
- Copyright 2016 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local string_match = string.match
-local pathutil = require "texrunner.pathutil"
-local filesys = require "lfs"
-local fsutil = require "texrunner.fsutil"
-local message = require "texrunner.message"
-
--- for LaTeX
-local function parse_aux_file(auxfile, outdir, report, seen)
- report = report or {}
- seen = seen or {}
- seen[auxfile] = true
- for l in io.lines(auxfile) do
- local subauxfile = string_match(l, "\\@input{(.+)}")
- if subauxfile then
- local subauxfile_abs = pathutil.abspath(subauxfile, outdir)
- if fsutil.isfile(subauxfile_abs) then
- parse_aux_file(subauxfile_abs, outdir, report, seen)
- else
- local dir = pathutil.join(outdir, pathutil.dirname(subauxfile))
- if not fsutil.isdir(dir) then
- assert(fsutil.mkdir_rec(dir))
- report.made_new_directory = true
- end
- end
- end
- end
- return report
-end
-
--- \citation, \bibdata, \bibstyle and \@input
-local function extract_bibtex_from_aux_file(auxfile, outdir, biblines)
- biblines = biblines or {}
- for l in io.lines(auxfile) do
- local name = string_match(l, "\\([%a@]+)")
- if name == "citation" or name == "bibdata" or name == "bibstyle" then
- table.insert(biblines, l)
- if CLUTTEX_VERBOSITY >= 2 then
- message.info("BibTeX line: ", l)
- end
- elseif name == "@input" then
- local subauxfile = string_match(l, "\\@input{(.+)}")
- if subauxfile then
- local subauxfile_abs = pathutil.abspath(subauxfile, outdir)
- if fsutil.isfile(subauxfile_abs) then
- extract_bibtex_from_aux_file(subauxfile_abs, outdir, biblines)
- end
- end
- end
- end
- return biblines
-end
-
-return {
- parse_aux_file = parse_aux_file,
- extract_bibtex_from_aux_file = extract_bibtex_from_aux_file,
-}
-end
-package.preload["texrunner.luatexinit"] = function(...)
-local function create_initialization_script(filename, options)
- local initscript = assert(io.open(filename,"w"))
- if type(options.file_line_error) == "boolean" then
- initscript:write(string.format("texconfig.file_line_error = %s\n", options.file_line_error))
- end
- if type(options.halt_on_error) == "boolean" then
- initscript:write(string.format("texconfig.halt_on_error = %s\n", options.halt_on_error))
- end
- initscript:write([==[
-local print = print
-local io_open = io.open
-local io_write = io.write
-local os_execute = os.execute
-local texio_write = texio.write
-local texio_write_nl = texio.write_nl
-]==])
-
- -- Packages coded in Lua doesn't follow -output-directory option and doesn't write command to the log file
- initscript:write(string.format("local output_directory = %q\n", options.output_directory))
- -- tex.jobname may not be available when io.open is called for the first time
- initscript:write(string.format("local jobname = %q\n", options.jobname))
- initscript:write([==[
-local luawritelog
-local function openluawritelog()
- if not luawritelog then
- luawritelog = assert(io_open(output_directory .. "/" .. jobname .. ".cluttex-fls", "w"))
- end
- return luawritelog
-end
-io.open = function(fname, mode)
- -- luatexja-ruby
- if mode == "w" and fname == jobname .. ".ltjruby" then
- fname = output_directory .. "/" .. fname
- end
- if type(mode) == "string" and string.find(mode, "w") ~= nil then
- -- write mode
- openluawritelog():write("OUTPUT " .. fname .. "\n")
- end
- return io_open(fname, mode)
-end
-os.execute = function(...)
- texio_write_nl("log", string.format("CLUTTEX_EXEC %s", ...), "")
- return os_execute(...)
-end
-]==])
-
- -- Silence some of the TeX output to the terminal.
- initscript:write([==[
-local function start_file_cb(category, filename)
- if category == 1 then -- a normal data file, like a TeX source
- texio_write_nl("log", "("..filename)
- elseif category == 2 then -- a font map coupling font names to resources
- texio_write("log", "{"..filename)
- elseif category == 3 then -- an image file (png, pdf, etc)
- texio_write("<"..filename)
- elseif category == 4 then -- an embedded font subset
- texio_write("<"..filename)
- elseif category == 5 then -- a fully embedded font
- texio_write("<<"..filename)
- else
- print("start_file: unknown category", category, filename)
- end
-end
-callback.register("start_file", start_file_cb)
-local function stop_file_cb(category)
- if category == 1 then
- texio_write("log", ")")
- elseif category == 2 then
- texio_write("log", "}")
- elseif category == 3 then
- texio_write(">")
- elseif category == 4 then
- texio_write(">")
- elseif category == 5 then
- texio_write(">>")
- else
- print("stop_file: unknown category", category)
- end
-end
-callback.register("stop_file", stop_file_cb)
-texio.write = function(...)
- if select("#",...) == 1 then
- -- Suppress luaotfload's message (See src/fontloader/runtime/fontload-reference.lua)
- local s = ...
- if string.match(s, "^%(using cache: ")
- or string.match(s, "^%(using write cache: ")
- or string.match(s, "^%(using read cache: ")
- or string.match(s, "^%(load luc: ")
- or string.match(s, "^%(load cache: ") then
- return texio_write("log", ...)
- end
- end
- return texio_write(...)
-end
-]==])
- initscript:close()
-end
-
-return {
- create_initialization_script = create_initialization_script
-}
-end
-package.preload["texrunner.recovery"] = function(...)
---[[
- Copyright 2018 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local io = io
-local string = string
-local parse_aux_file = require "texrunner.auxfile".parse_aux_file
-local pathutil = require "texrunner.pathutil"
-local fsutil = require "texrunner.fsutil"
-local shellutil = require "texrunner.shellutil"
-local message = require "texrunner.message"
-
-local function create_missing_directories(args)
- if string.find(args.execlog, "I can't write on file", 1, true) then
- -- There is a possibility that there are some subfiles under subdirectories.
- -- Directories for sub-auxfiles are not created automatically, so we need to provide them.
- local report = parse_aux_file(args.auxfile, args.options.output_directory)
- if report.made_new_directory then
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("Created missing directories.")
- end
- return true
- end
- end
- return false
-end
-
-local function run_epstopdf(args)
- local run = false
- if args.options.shell_escape ~= false then -- (possibly restricted) \write18 enabled
- for outfile, infile in string.gmatch(args.execlog, "%(epstopdf%)%s*Command: <r?epstopdf %-%-outfile=([%w%-/]+%.pdf) ([%w%-/]+%.eps)>") do
- local infile_abs = pathutil.abspath(infile, args.original_wd)
- if fsutil.isfile(infile_abs) then -- input file exists
- local outfile_abs = pathutil.abspath(outfile, args.options.output_directory)
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("Running epstopdf on ", infile, ".")
- end
- local outdir = pathutil.dirname(outfile_abs)
- if not fsutil.isdir(outdir) then
- assert(fsutil.mkdir_rec(outdir))
- end
- local command = string.format("epstopdf --outfile=%s %s", shellutil.escape(outfile_abs), shellutil.escape(infile_abs))
- message.exec(command)
- local success = os.execute(command)
- if type(success) == "number" then -- Lua 5.1 or LuaTeX
- success = success == 0
- end
- run = run or success
- end
- end
- end
- return run
-end
-
-local function check_minted(args)
- return string.find(args.execlog, "Package minted Error: Missing Pygments output; \\inputminted was") ~= nil
-end
-
-local function try_recovery(args)
- local recovered = false
- recovered = create_missing_directories(args)
- recovered = run_epstopdf(args) or recovered
- recovered = check_minted(args) or recovered
- return recovered
-end
-
-return {
- create_missing_directories = create_missing_directories,
- run_epstopdf = run_epstopdf,
- try_recovery = try_recovery,
-}
-end
-package.preload["texrunner.handleoption"] = function(...)
-local COPYRIGHT_NOTICE = [[
-Copyright (C) 2016-2020 ARATA Mizuki
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local pathutil = require "texrunner.pathutil"
-local shellutil = require "texrunner.shellutil"
-local parseoption = require "texrunner.option".parseoption
-local KnownEngines = require "texrunner.tex_engine"
-local message = require "texrunner.message"
-
-local function usage(arg)
- io.write(string.format([[
-ClutTeX: Process TeX files without cluttering your working directory
-
-Usage:
- %s [options] [--] FILE.tex
-
-Options:
- -e, --engine=ENGINE Specify which TeX engine to use.
- ENGINE is one of the following:
- pdflatex, pdftex,
- lualatex, luatex, luajittex,
- xelatex, xetex, latex, etex, tex,
- platex, eptex, ptex,
- uplatex, euptex, uptex,
- --engine-executable=COMMAND+OPTIONs
- The actual TeX command to use.
- [default: ENGINE]
- -o, --output=FILE The name of output file.
- [default: JOBNAME.pdf or JOBNAME.dvi]
- --fresh Clean intermediate files before running TeX.
- Cannot be used with --output-directory.
- --max-iterations=N Maximum number of running TeX to resolve
- cross-references. [default: 3]
- --start-with-draft Start with draft mode.
- --[no-]change-directory Change directory before running TeX.
- --watch Watch input files for change. Requires fswatch
- program to be installed.
- --tex-option=OPTION Pass OPTION to TeX as a single option.
- --tex-options=OPTIONs Pass OPTIONs to TeX as multiple options.
- --dvipdfmx-option[s]=OPTION[s] Same for dvipdfmx.
- --makeindex=COMMAND+OPTIONs Command to generate index, such as
- `makeindex' or `mendex'.
- --bibtex=COMMAND+OPTIONs Command for BibTeX, such as
- `bibtex' or `pbibtex'.
- --biber[=COMMAND+OPTIONs] Command for Biber.
- --makeglossaries[=COMMAND+OPTIONs] Command for makeglossaries.
- -h, --help Print this message and exit.
- -v, --version Print version information and exit.
- -V, --verbose Be more verbose.
- --color[=WHEN] Make ClutTeX's message colorful. WHEN is one of
- `always', `auto', or `never'.
- [default: `auto' if --color is omitted,
- `always' if WHEN is omitted]
- --includeonly=NAMEs Insert '\includeonly{NAMEs}'.
- --make-depends=FILE Write dependencies as a Makefile rule.
- --print-output-directory Print the output directory and exit.
- --package-support=PKG1[,PKG2,...]
- Enable special support for some shell-escaping
- packages.
- Currently supported: minted, epstopdf
- --check-driver=DRIVER Check that the correct driver file is loaded.
- DRIVER is one of `dvipdfmx', `dvips', `dvisvgm'.
-
- --[no-]shell-escape
- --shell-restricted
- --synctex=NUMBER
- --fmt=FMTNAME
- --[no-]file-line-error [default: yes]
- --[no-]halt-on-error [default: yes]
- --interaction=STRING [default: nonstopmode]
- --jobname=STRING
- --output-directory=DIR [default: somewhere in the temporary directory]
- --output-format=FORMAT FORMAT is `pdf' or `dvi'. [default: pdf]
-
-%s
-]], arg[0] or 'texlua cluttex.lua', COPYRIGHT_NOTICE))
-end
-
-local option_spec = {
- -- Options for ClutTeX
- {
- short = "e",
- long = "engine",
- param = true,
- },
- {
- long = "engine-executable",
- param = true,
- },
- {
- short = "o",
- long = "output",
- param = true,
- },
- {
- long = "fresh",
- },
- {
- long = "max-iterations",
- param = true,
- },
- {
- long = "start-with-draft",
- },
- {
- long = "change-directory",
- boolean = true,
- },
- {
- long = "watch",
- },
- {
- short = "h",
- long = "help",
- allow_single_hyphen = true,
- },
- {
- short = "v",
- long = "version",
- },
- {
- short = "V",
- long = "verbose",
- },
- {
- long = "color",
- param = true,
- default = "always",
- },
- {
- long = "includeonly",
- param = true,
- },
- {
- long = "make-depends",
- param = true
- },
- {
- long = "print-output-directory",
- },
- {
- long = "package-support",
- param = true
- },
- {
- long = "check-driver",
- param = true
- },
- -- Options for TeX
- {
- long = "synctex",
- param = true,
- allow_single_hyphen = true,
- },
- {
- long = "file-line-error",
- boolean = true,
- allow_single_hyphen = true,
- },
- {
- long = "interaction",
- param = true,
- allow_single_hyphen = true,
- },
- {
- long = "halt-on-error",
- boolean = true,
- allow_single_hyphen = true,
- },
- {
- long = "shell-escape",
- boolean = true,
- allow_single_hyphen = true,
- },
- {
- long = "shell-restricted",
- allow_single_hyphen = true,
- },
- {
- long = "jobname",
- param = true,
- allow_single_hyphen = true,
- },
- {
- long = "fmt",
- param = true,
- allow_single_hyphen = true,
- },
- {
- long = "output-directory",
- param = true,
- allow_single_hyphen = true,
- },
- {
- long = "output-format",
- param = true,
- allow_single_hyphen = true,
- },
- {
- long = "tex-option",
- param = true,
- },
- {
- long = "tex-options",
- param = true,
- },
- {
- long = "dvipdfmx-option",
- param = true,
- },
- {
- long = "dvipdfmx-options",
- param = true,
- },
- {
- long = "makeindex",
- param = true,
- },
- {
- long = "bibtex",
- param = true,
- },
- {
- long = "biber",
- param = true,
- default = "biber",
- },
- {
- long = "makeglossaries",
- param = true,
- default = "makeglossaries",
- },
-}
-
--- Default values for options
-local function set_default_values(options)
- if options.max_iterations == nil then
- options.max_iterations = 3
- end
-
- if options.interaction == nil then
- options.interaction = "nonstopmode"
- end
-
- if options.file_line_error == nil then
- options.file_line_error = true
- end
-
- if options.halt_on_error == nil then
- options.halt_on_error = true
- end
-
- if options.output_format == nil then
- options.output_format = "pdf"
- end
-end
-
--- inputfile, engine, options = handle_cluttex_options(arg)
-local function handle_cluttex_options(arg)
- -- Parse options
- local option_and_params, non_option_index = parseoption(arg, option_spec)
-
- -- Handle options
- local options = {
- tex_extraoptions = {},
- dvipdfmx_extraoptions = {},
- package_support = {},
- }
- CLUTTEX_VERBOSITY = 0
- for _,option in ipairs(option_and_params) do
- local name = option[1]
- local param = option[2]
-
- if name == "engine" then
- assert(options.engine == nil, "multiple --engine options")
- options.engine = param
-
- elseif name == "engine-executable" then
- assert(options.engine_executable == nil, "multiple --engine-executable options")
- options.engine_executable = param
-
- elseif name == "output" then
- assert(options.output == nil, "multiple --output options")
- options.output = param
-
- elseif name == "fresh" then
- assert(options.fresh == nil, "multiple --fresh options")
- options.fresh = true
-
- elseif name == "max-iterations" then
- assert(options.max_iterations == nil, "multiple --max-iterations options")
- options.max_iterations = assert(tonumber(param), "invalid value for --max-iterations option")
- assert(options.max_iterations >= 1, "invalid value for --max-iterations option")
-
- elseif name == "start-with-draft" then
- assert(options.start_with_draft == nil, "multiple --start-with-draft options")
- options.start_with_draft = true
-
- elseif name == "watch" then
- assert(options.watch == nil, "multiple --watch options")
- options.watch = true
-
- elseif name == "help" then
- usage(arg)
- os.exit(0)
-
- elseif name == "version" then
- io.stderr:write("cluttex ",CLUTTEX_VERSION,"\n")
- os.exit(0)
-
- elseif name == "verbose" then
- CLUTTEX_VERBOSITY = CLUTTEX_VERBOSITY + 1
-
- elseif name == "color" then
- assert(options.color == nil, "multiple --collor options")
- options.color = param
- message.set_colors(options.color)
-
- elseif name == "change-directory" then
- assert(options.change_directory == nil, "multiple --change-directory options")
- options.change_directory = param
-
- elseif name == "includeonly" then
- assert(options.includeonly == nil, "multiple --includeonly options")
- options.includeonly = param
-
- elseif name == "make-depends" then
- assert(options.make_depends == nil, "multiple --make-depends options")
- options.make_depends = param
-
- elseif name == "print-output-directory" then
- assert(options.print_output_directory == nil, "multiple --print-output-directory options")
- options.print_output_directory = true
-
- elseif name == "package-support" then
- local known_packages = {["minted"] = true, ["epstopdf"] = true}
- for pkg in string.gmatch(param, "[^,%s]+") do
- options.package_support[pkg] = true
- if not known_packages[pkg] and CLUTTEX_VERBOSITY >= 1 then
- message.warn("ClutTeX provides no special support for '"..pkg.."'.")
- end
- end
-
- elseif name == "check-driver" then
- assert(options.check_driver == nil, "multiple --check-driver options")
- assert(param == "dvipdfmx" or param == "dvips" or param == "dvisvgm", "wrong value for --check-driver option")
- options.check_driver = param
-
- -- Options for TeX
- elseif name == "synctex" then
- assert(options.synctex == nil, "multiple --synctex options")
- options.synctex = param
-
- elseif name == "file-line-error" then
- options.file_line_error = param
-
- elseif name == "interaction" then
- assert(options.interaction == nil, "multiple --interaction options")
- assert(param == "batchmode" or param == "nonstopmode" or param == "scrollmode" or param == "errorstopmode", "invalid argument for --interaction")
- options.interaction = param
-
- elseif name == "halt-on-error" then
- options.halt_on_error = param
-
- elseif name == "shell-escape" then
- assert(options.shell_escape == nil and options.shell_restricted == nil, "multiple --(no-)shell-escape or --shell-restricted options")
- options.shell_escape = param
-
- elseif name == "shell-restricted" then
- assert(options.shell_escape == nil and options.shell_restricted == nil, "multiple --(no-)shell-escape or --shell-restricted options")
- options.shell_restricted = true
-
- elseif name == "jobname" then
- assert(options.jobname == nil, "multiple --jobname options")
- options.jobname = param
-
- elseif name == "fmt" then
- assert(options.fmt == nil, "multiple --fmt options")
- options.fmt = param
-
- elseif name == "output-directory" then
- assert(options.output_directory == nil, "multiple --output-directory options")
- options.output_directory = param
-
- elseif name == "output-format" then
- assert(options.output_format == nil, "multiple --output-format options")
- assert(param == "pdf" or param == "dvi", "invalid argument for --output-format")
- options.output_format = param
-
- elseif name == "tex-option" then
- table.insert(options.tex_extraoptions, shellutil.escape(param))
-
- elseif name == "tex-options" then
- table.insert(options.tex_extraoptions, param)
-
- elseif name == "dvipdfmx-option" then
- table.insert(options.dvipdfmx_extraoptions, shellutil.escape(param))
-
- elseif name == "dvipdfmx-options" then
- table.insert(options.dvipdfmx_extraoptions, param)
-
- elseif name == "makeindex" then
- assert(options.makeindex == nil, "multiple --makeindex options")
- options.makeindex = param
-
- elseif name == "bibtex" then
- assert(options.bibtex == nil, "multiple --bibtex options")
- assert(options.biber == nil, "multiple --bibtex/--biber options")
- options.bibtex = param
-
- elseif name == "biber" then
- assert(options.biber == nil, "multiple --biber options")
- assert(options.bibtex == nil, "multiple --bibtex/--biber options")
- options.biber = param
-
- elseif name == "makeglossaries" then
- assert(options.makeglossaries == nil, "multiple --makeglossaries options")
- options.makeglossaries = param
-
- end
- end
-
- if options.color == nil then
- message.set_colors("auto")
- end
-
- -- Handle non-options (i.e. input file)
- if non_option_index > #arg then
- -- No input file given
- usage(arg)
- os.exit(1)
- elseif non_option_index < #arg then
- message.error("Multiple input files are not supported.")
- os.exit(1)
- end
- local inputfile = arg[non_option_index]
-
- -- If run as 'cllualatex', then the default engine is lualatex
- if options.engine == nil and type(arg[0]) == "string" then
- local basename = pathutil.trimext(pathutil.basename(arg[0]))
- local engine_part = string.match(basename, "^cl(%w+)$")
- if engine_part and KnownEngines[engine_part] then
- options.engine = engine_part
- end
- end
-
- if options.engine == nil then
- message.error("Engine not specified.")
- os.exit(1)
- end
- local engine = KnownEngines[options.engine]
- if not engine then
- message.error("Unknown engine name '", options.engine, "'.")
- os.exit(1)
- end
-
- set_default_values(options)
-
- if options.output_format == "pdf" then
- if options.check_driver ~= nil then
- error("--check-driver can only be used when the output format is DVI.")
- end
- if engine.supports_pdf_generation then
- if engine.is_luatex then
- options.check_driver = "luatex"
- elseif engine.name == "xetex" or engine.name == "xelatex" then
- options.check_driver = "xetex"
- elseif engine.name == "pdftex" or engine.name == "pdflatex" then
- options.check_driver = "pdftex"
- else
- message.warning("Unknown engine: "..engine.name)
- message.warning("Driver check will not work.")
- end
- else
- -- ClutTeX uses dvipdfmx to generate PDF from DVI output.
- options.check_driver = "dvipdfmx"
- end
- end
-
- return inputfile, engine, options
-end
-
-return {
- usage = usage,
- handle_cluttex_options = handle_cluttex_options,
-}
-end
-package.preload["texrunner.isatty"] = function(...)
---[[
- Copyright 2018 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-if os.type == "unix" then
- -- Try LuaJIT-like FFI
- local succ, M = pcall(function()
- local ffi = require "ffi"
- ffi.cdef[[
-int isatty(int fd);
-int fileno(void *stream);
-]]
- local isatty = assert(ffi.C.isatty, "isatty not found")
- local fileno = assert(ffi.C.fileno, "fileno not found")
- return {
- isatty = function(file)
- -- LuaJIT converts Lua's file handles into FILE* (void*)
- return isatty(fileno(file)) ~= 0
- end
- }
- end)
- if succ then
- if CLUTTEX_VERBOSITY >= 3 then
- io.stderr:write("ClutTeX: isatty found via FFI (Unix)\n")
- end
- return M
- else
- if CLUTTEX_VERBOSITY >= 3 then
- io.stderr:write("ClutTeX: FFI (Unix) not found: ", M, "\n")
- end
- end
-
- -- Try luaposix
- local succ, M = pcall(function()
- local isatty = require "posix.unistd".isatty
- local fileno = require "posix.stdio".fileno
- return {
- isatty = function(file)
- return isatty(fileno(file)) == 1
- end,
- }
- end)
- if succ then
- if CLUTTEX_VERBOSITY >= 3 then
- io.stderr:write("ClutTeX: isatty found via luaposix\n")
- end
- return M
- else
- if CLUTTEX_VERBOSITY >= 3 then
- io.stderr:write("ClutTeX: luaposix not found: ", M, "\n")
- end
- end
-
-else
- -- Try LuaJIT
- -- TODO: Try to detect MinTTY using GetFileInformationByHandleEx
- local succ, M = pcall(function()
- local ffi = require "ffi"
- local bitlib = assert(bit32 or bit, "Neither bit32 (Lua 5.2) nor bit (LuaJIT) found") -- Lua 5.2 or LuaJIT
- ffi.cdef[[
-int _isatty(int fd);
-int _fileno(void *stream);
-void *_get_osfhandle(int fd); // should return intptr_t
-typedef int BOOL;
-typedef uint32_t DWORD;
-typedef int FILE_INFO_BY_HANDLE_CLASS; // ???
-typedef struct _FILE_NAME_INFO {
-DWORD FileNameLength;
-uint16_t FileName[?];
-} FILE_NAME_INFO;
-DWORD GetFileType(void *hFile);
-BOOL GetFileInformationByHandleEx(void *hFile, FILE_INFO_BY_HANDLE_CLASS fic, void *fileinfo, DWORD dwBufferSize);
-BOOL GetConsoleMode(void *hConsoleHandle, DWORD* lpMode);
-BOOL SetConsoleMode(void *hConsoleHandle, DWORD dwMode);
-DWORD GetLastError();
-]]
- local isatty = assert(ffi.C._isatty, "_isatty not found")
- local fileno = assert(ffi.C._fileno, "_fileno not found")
- local get_osfhandle = assert(ffi.C._get_osfhandle, "_get_osfhandle not found")
- local GetFileType = assert(ffi.C.GetFileType, "GetFileType not found")
- local GetFileInformationByHandleEx = assert(ffi.C.GetFileInformationByHandleEx, "GetFileInformationByHandleEx not found")
- local GetConsoleMode = assert(ffi.C.GetConsoleMode, "GetConsoleMode not found")
- local SetConsoleMode = assert(ffi.C.SetConsoleMode, "SetConsoleMode not found")
- local GetLastError = assert(ffi.C.GetLastError, "GetLastError not found")
- local function wide_to_narrow(array, length)
- local t = {}
- for i = 0, length - 1 do
- table.insert(t, string.char(math.min(array[i], 0xff)))
- end
- return table.concat(t, "")
- end
- local function is_mintty(fd)
- local handle = get_osfhandle(fd)
- local filetype = GetFileType(handle)
- if filetype ~= 0x0003 then -- not FILE_TYPE_PIPE (0x0003)
- -- mintty must be a pipe
- if CLUTTEX_VERBOSITY >= 4 then
- io.stderr:write("ClutTeX: is_mintty: not a pipe\n")
- end
- return false
- end
- local nameinfo = ffi.new("FILE_NAME_INFO", 32768)
- local FileNameInfo = 2 -- : FILE_INFO_BY_HANDLE_CLASS
- if GetFileInformationByHandleEx(handle, FileNameInfo, nameinfo, ffi.sizeof("FILE_NAME_INFO", 32768)) ~= 0 then
- local filename = wide_to_narrow(nameinfo.FileName, math.floor(nameinfo.FileNameLength / 2))
- -- \(cygwin|msys)-<hex digits>-pty<N>-(from|to)-master
- if CLUTTEX_VERBOSITY >= 4 then
- io.stderr:write("ClutTeX: is_mintty: GetFileInformationByHandleEx returned ", filename, "\n")
- end
- local a, b = string.match(filename, "^\\(%w+)%-%x+%-pty%d+%-(%w+)%-master$")
- return (a == "cygwin" or a == "msys") and (b == "from" or b == "to")
- else
- if CLUTTEX_VERBOSITY >= 4 then
- io.stderr:write("ClutTeX: is_mintty: GetFileInformationByHandleEx failed\n")
- end
- return false
- end
- end
- return {
- isatty = function(file)
- -- LuaJIT converts Lua's file handles into FILE* (void*)
- local fd = fileno(file)
- return isatty(fd) ~= 0 or is_mintty(fd)
- end,
- enable_virtual_terminal = function(file)
- local fd = fileno(file)
- if is_mintty(fd) then
- -- MinTTY
- if CLUTTEX_VERBOSITY >= 4 then
- io.stderr:write("ClutTeX: Detected MinTTY\n")
- end
- return true
- elseif isatty(fd) ~= 0 then
- -- Check for ConEmu or ansicon
- if os.getenv("ConEmuANSI") == "ON" or os.getenv("ANSICON") then
- if CLUTTEX_VERBOSITY >= 4 then
- io.stderr:write("ClutTeX: Detected ConEmu or ansicon\n")
- end
- return true
- else
- -- Try native VT support on recent Windows
- local handle = get_osfhandle(fd)
- local modePtr = ffi.new("DWORD[1]")
- local result = GetConsoleMode(handle, modePtr)
- if result == 0 then
- if CLUTTEX_VERBOSITY >= 3 then
- local err = GetLastError()
- io.stderr:write(string.format("ClutTeX: GetConsoleMode failed (0x%08X)\n", err))
- end
- return false
- end
- local ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
- result = SetConsoleMode(handle, bitlib.bor(modePtr[0], ENABLE_VIRTUAL_TERMINAL_PROCESSING))
- if result == 0 then
- -- SetConsoleMode failed: Command Prompt on older Windows
- if CLUTTEX_VERBOSITY >= 3 then
- local err = GetLastError()
- -- Typical error code: ERROR_INVALID_PARAMETER (0x57)
- io.stderr:write(string.format("ClutTeX: SetConsoleMode failed (0x%08X)\n", err))
- end
- return false
- end
- if CLUTTEX_VERBOSITY >= 4 then
- io.stderr:write("ClutTeX: Detected recent Command Prompt\n")
- end
- return true
- end
- else
- -- Not a TTY
- return false
- end
- end,
- }
- end)
- if succ then
- if CLUTTEX_VERBOSITY >= 3 then
- io.stderr:write("ClutTeX: isatty found via FFI (Windows)\n")
- end
- return M
- else
- if CLUTTEX_VERBOSITY >= 3 then
- io.stderr:write("ClutTeX: FFI (Windows) not found: ", M, "\n")
- end
- end
-end
-
-return {
- isatty = function(file)
- return false
- end,
-}
-end
-package.preload["texrunner.message"] = function(...)
---[[
- Copyright 2018 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local use_colors = false
-
-local function set_colors(mode)
- local M
- if mode == "always" then
- M = require "texrunner.isatty"
- use_colors = true
- if use_colors and M.enable_virtual_terminal then
- local succ = M.enable_virtual_terminal(io.stderr)
- if not succ and CLUTTEX_VERBOSITY >= 2 then
- io.stderr:write("ClutTeX: Failed to enable virtual terminal\n")
- end
- end
- elseif mode == "auto" then
- M = require "texrunner.isatty"
- use_colors = M.isatty(io.stderr)
- if use_colors and M.enable_virtual_terminal then
- use_colors = M.enable_virtual_terminal(io.stderr)
- if not use_colors and CLUTTEX_VERBOSITY >= 2 then
- io.stderr:write("ClutTeX: Failed to enable virtual terminal\n")
- end
- end
- elseif mode == "never" then
- use_colors = false
- else
- error "The value of --color option must be one of 'auto', 'always', or 'never'."
- end
-end
-
--- ESCAPE: hex 1B = dec 27 = oct 33
-
-local CMD = {
- reset = "\027[0m",
- underline = "\027[4m",
- fg_black = "\027[30m",
- fg_red = "\027[31m",
- fg_green = "\027[32m",
- fg_yellow = "\027[33m",
- fg_blue = "\027[34m",
- fg_magenta = "\027[35m",
- fg_cyan = "\027[36m",
- fg_white = "\027[37m",
- fg_reset = "\027[39m",
- bg_black = "\027[40m",
- bg_red = "\027[41m",
- bg_green = "\027[42m",
- bg_yellow = "\027[43m",
- bg_blue = "\027[44m",
- bg_magenta = "\027[45m",
- bg_cyan = "\027[46m",
- bg_white = "\027[47m",
- bg_reset = "\027[49m",
- fg_x_black = "\027[90m",
- fg_x_red = "\027[91m",
- fg_x_green = "\027[92m",
- fg_x_yellow = "\027[93m",
- fg_x_blue = "\027[94m",
- fg_x_magenta = "\027[95m",
- fg_x_cyan = "\027[96m",
- fg_x_white = "\027[97m",
- bg_x_black = "\027[100m",
- bg_x_red = "\027[101m",
- bg_x_green = "\027[102m",
- bg_x_yellow = "\027[103m",
- bg_x_blue = "\027[104m",
- bg_x_magenta = "\027[105m",
- bg_x_cyan = "\027[106m",
- bg_x_white = "\027[107m",
-}
-
-local function exec_msg(commandline)
- if use_colors then
- io.stderr:write(CMD.fg_x_white, CMD.bg_red, "[EXEC]", CMD.reset, " ", CMD.fg_cyan, commandline, CMD.reset, "\n")
- else
- io.stderr:write("[EXEC] ", commandline, "\n")
- end
-end
-
-local function error_msg(...)
- local message = table.concat({...}, "")
- if use_colors then
- io.stderr:write(CMD.fg_x_white, CMD.bg_red, "[ERROR]", CMD.reset, " ", CMD.fg_red, message, CMD.reset, "\n")
- else
- io.stderr:write("[ERROR] ", message, "\n")
- end
-end
-
-local function warn_msg(...)
- local message = table.concat({...}, "")
- if use_colors then
- io.stderr:write(CMD.fg_x_white, CMD.bg_red, "[WARN]", CMD.reset, " ", CMD.fg_blue, message, CMD.reset, "\n")
- else
- io.stderr:write("[WARN] ", message, "\n")
- end
-end
-
-local function diag_msg(...)
- local message = table.concat({...}, "")
- if use_colors then
- io.stderr:write(CMD.fg_x_white, CMD.bg_red, "[DIAG]", CMD.reset, " ", CMD.fg_blue, message, CMD.reset, "\n")
- else
- io.stderr:write("[DIAG] ", message, "\n")
- end
-end
-
-local function info_msg(...)
- local message = table.concat({...}, "")
- if use_colors then
- io.stderr:write(CMD.fg_x_white, CMD.bg_red, "[INFO]", CMD.reset, " ", CMD.fg_magenta, message, CMD.reset, "\n")
- else
- io.stderr:write("[INFO] ", message, "\n")
- end
-end
-
-return {
- set_colors = set_colors,
- exec = exec_msg,
- error = error_msg,
- warn = warn_msg,
- diag = diag_msg,
- info = info_msg,
-}
-end
-package.preload["texrunner.fswatcher_windows"] = function(...)
---[[
- Copyright 2019 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local ffi = require "ffi"
-local bitlib = assert(bit32 or bit, "Neither bit32 (Lua 5.2) nor bit (LuaJIT) found") -- Lua 5.2 or LuaJIT
-
-ffi.cdef[[
-typedef int BOOL;
-typedef unsigned int UINT;
-typedef uint32_t DWORD;
-typedef void *HANDLE;
-typedef uintptr_t ULONG_PTR;
-typedef uint16_t WCHAR;
-typedef struct _OVERLAPPED {
- ULONG_PTR Internal;
- ULONG_PTR InternalHigh;
- union {
- struct {
- DWORD Offset;
- DWORD OffsetHigh;
- };
- void *Pointer;
- };
- HANDLE hEvent;
-} OVERLAPPED;
-typedef struct _FILE_NOTIFY_INFORMATION {
- DWORD NextEntryOffset;
- DWORD Action;
- DWORD FileNameLength;
- WCHAR FileName[?];
-} FILE_NOTIFY_INFORMATION;
-typedef void (__stdcall *LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, OVERLAPPED *lpOverlapped);
-DWORD GetLastError();
-BOOL CloseHandle(HANDLE hObject);
-HANDLE CreateFileA(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, void *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
-HANDLE CreateIoCompletionPort(HANDLE fileHandle, HANDLE existingCompletionPort, ULONG_PTR completionKey, DWORD numberOfConcurrentThreads);
-BOOL ReadDirectoryChangesW(HANDLE hDirectory, void *lpBuffer, DWORD nBufferLength, BOOL bWatchSubtree, DWORD dwNotifyFilter, DWORD *lpBytesReturned, OVERLAPPED *lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpOverlappedCompletionRoutine);
-BOOL GetQueuedCompletionStatus(HANDLE CompletionPort, DWORD *lpNumberOfBytes, ULONG_PTR *lpCompletionKey, OVERLAPPED **lpOverlapped, DWORD dwMilliseconds);
-int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const char *lpMultiByteStr, int cbMultiByte, WCHAR *lpWideCharStr, int cchWideChar);
-int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const WCHAR *lpWideCharStr, int cchWideChar, char *lpMultiByteStr, int cbMultiByte, const char *lpDefaultChar, BOOL *lpUsedDefaultChar);
-DWORD GetFullPathNameA(const char *lpFileName, DWORD nBufferLength, char *lpBuffer, char **lpFilePart);
-uint64_t GetTickCount64();
-]]
-
--- LuaTeX's FFI does not equate a null pointer with nil.
--- On LuaJIT, ffi.NULL is just nil.
-local NULL = ffi.NULL
-
--- GetLastError
-local ERROR_FILE_NOT_FOUND = 0x0002
-local ERROR_PATH_NOT_FOUND = 0x0003
-local ERROR_ACCESS_DENIED = 0x0005
-local ERROR_INVALID_PARAMETER = 0x0057
-local ERROR_INSUFFICIENT_BUFFER = 0x007A
-local WAIT_TIMEOUT = 0x0102
-local ERROR_ABANDONED_WAIT_0 = 0x02DF
-local ERROR_NOACCESS = 0x03E6
-local ERROR_INVALID_FLAGS = 0x03EC
-local ERROR_NOTIFY_ENUM_DIR = 0x03FE
-local ERROR_NO_UNICODE_TRANSLATION = 0x0459
-local KnownErrors = {
- [ERROR_FILE_NOT_FOUND] = "ERROR_FILE_NOT_FOUND",
- [ERROR_PATH_NOT_FOUND] = "ERROR_PATH_NOT_FOUND",
- [ERROR_ACCESS_DENIED] = "ERROR_ACCESS_DENIED",
- [ERROR_INVALID_PARAMETER] = "ERROR_INVALID_PARAMETER",
- [ERROR_INSUFFICIENT_BUFFER] = "ERROR_INSUFFICIENT_BUFFER",
- [ERROR_ABANDONED_WAIT_0] = "ERROR_ABANDONED_WAIT_0",
- [ERROR_NOACCESS] = "ERROR_NOACCESS",
- [ERROR_INVALID_FLAGS] = "ERROR_INVALID_FLAGS",
- [ERROR_NOTIFY_ENUM_DIR] = "ERROR_NOTIFY_ENUM_DIR",
- [ERROR_NO_UNICODE_TRANSLATION] = "ERROR_NO_UNICODE_TRANSLATION",
-}
-
--- CreateFile
-local FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
-local FILE_FLAG_OVERLAPPED = 0x40000000
-local OPEN_EXISTING = 3
-local FILE_SHARE_READ = 0x00000001
-local FILE_SHARE_WRITE = 0x00000002
-local FILE_SHARE_DELETE = 0x00000004
-local FILE_LIST_DIRECTORY = 0x1
-local INVALID_HANDLE_VALUE = ffi.cast("void *", -1)
-
--- ReadDirectoryChangesW / FILE_NOTIFY_INFORMATION
-local FILE_NOTIFY_CHANGE_FILE_NAME = 0x00000001
-local FILE_NOTIFY_CHANGE_DIR_NAME = 0x00000002
-local FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x00000004
-local FILE_NOTIFY_CHANGE_SIZE = 0x00000008
-local FILE_NOTIFY_CHANGE_LAST_WRITE = 0x00000010
-local FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x00000020
-local FILE_NOTIFY_CHANGE_CREATION = 0x00000040
-local FILE_NOTIFY_CHANGE_SECURITY = 0x00000100
-local FILE_ACTION_ADDED = 0x00000001
-local FILE_ACTION_REMOVED = 0x00000002
-local FILE_ACTION_MODIFIED = 0x00000003
-local FILE_ACTION_RENAMED_OLD_NAME = 0x00000004
-local FILE_ACTION_RENAMED_NEW_NAME = 0x00000005
-
--- WideCharToMultiByte / MultiByteToWideChar
-local CP_ACP = 0
-local CP_UTF8 = 65001
-
-local C = ffi.C
-
-local function format_error(name, lasterror, extra)
- local errorname = KnownErrors[lasterror] or string.format("error code %d", lasterror)
- if extra then
- return string.format("%s failed with %s (0x%04x) [%s]", name, errorname, lasterror, extra)
- else
- return string.format("%s failed with %s (0x%04x)", name, errorname, lasterror)
- end
-end
-local function wcs_to_mbs(wstr, wstrlen, codepage)
- -- wstr: FFI uint16_t[?]
- -- wstrlen: length of wstr, or -1 if NUL-terminated
- if wstrlen == 0 then
- return ""
- end
- codepage = codepage or CP_ACP
- local dwFlags = 0
- local result = C.WideCharToMultiByte(codepage, dwFlags, wstr, wstrlen, nil, 0, nil, nil)
- if result <= 0 then
- -- Failed
- local lasterror = C.GetLastError()
- -- Candidates: ERROR_INSUFFICIENT_BUFFER, ERROR_INVALID_FLAGS, ERROR_INVALID_PARAMETER, ERROR_NO_UNICODE_TRANSLATION
- return nil, format_error("WideCharToMultiByte", lasterror)
- end
- local mbsbuf = ffi.new("char[?]", result)
- result = C.WideCharToMultiByte(codepage, dwFlags, wstr, wstrlen, mbsbuf, result, nil, nil)
- if result <= 0 then
- -- Failed
- local lasterror = C.GetLastError()
- -- Candidates: ERROR_INSUFFICIENT_BUFFER, ERROR_INVALID_FLAGS, ERROR_INVALID_PARAMETER, ERROR_NO_UNICODE_TRANSLATION
- return nil, format_error("WideCharToMultiByte", lasterror)
- end
- return ffi.string(mbsbuf, result)
-end
-local function mbs_to_wcs(str, codepage)
- -- str: Lua string
- if str == "" then
- return ffi.new("WCHAR[0]")
- end
- codepage = codepage or CP_ACP
- local dwFlags = 0
- local result = C.MultiByteToWideChar(codepage, dwFlags, str, #str, nil, 0)
- if result <= 0 then
- local lasterror = C.GetLastError()
- -- ERROR_INSUFFICIENT_BUFFER, ERROR_INVALID_FLAGS, ERROR_INVALID_PARAMETER, ERROR_NO_UNICODE_TRANSLATION
- return nil, format_error("MultiByteToWideChar", lasterror)
- end
- local wcsbuf = ffi.new("WCHAR[?]", result)
- result = C.MultiByteToWideChar(codepage, dwFlags, str, #str, wcsbuf, result)
- if result <= 0 then
- local lasterror = C.GetLastError()
- return nil, format_error("MultiByteToWideChar", lasterror)
- end
- return wcsbuf, result
-end
-
-
-local function get_full_path_name(filename)
- local bufsize = 1024
- local buffer
- local filePartPtr = ffi.new("char*[1]")
- local result
- repeat
- buffer = ffi.new("char[?]", bufsize)
- result = C.GetFullPathNameA(filename, bufsize, buffer, filePartPtr)
- if result == 0 then
- local lasterror = C.GetLastError()
- return nil, format_error("GetFullPathNameA", lasterror, filename)
- elseif bufsize < result then
- -- result: buffer size required to hold the path + terminating NUL
- bufsize = result
- end
- until result < bufsize
- local fullpath = ffi.string(buffer, result)
- local filePart = ffi.string(filePartPtr[0])
- local dirPart = ffi.string(buffer, ffi.cast("intptr_t", filePartPtr[0]) - ffi.cast("intptr_t", buffer)) -- LuaTeX's FFI doesn't support pointer subtraction
- return fullpath, filePart, dirPart
-end
-
---[[
- dirwatche.dirname : string
- dirwatcher._rawhandle : cdata HANDLE
- dirwatcher._overlapped : cdata OVERLAPPED
- dirwatcher._buffer : cdata char[?]
-]]
-local dirwatcher_meta = {}
-dirwatcher_meta.__index = dirwatcher_meta
-function dirwatcher_meta:close()
- if self._rawhandle ~= nil then
- C.CloseHandle(ffi.gc(self._rawhandle, nil))
- self._rawhandle = nil
- end
-end
-local function open_directory(dirname)
- local dwShareMode = bitlib.bor(FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE)
- local dwFlagsAndAttributes = bitlib.bor(FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OVERLAPPED)
- local handle = C.CreateFileA(dirname, FILE_LIST_DIRECTORY, dwShareMode, nil, OPEN_EXISTING, dwFlagsAndAttributes, nil)
- if handle == INVALID_HANDLE_VALUE then
- local lasterror = C.GetLastError()
- print("Failed to open "..dirname)
- return nil, format_error("CreateFileA", lasterror, dirname)
- end
- return setmetatable({
- dirname = dirname,
- _rawhandle = ffi.gc(handle, C.CloseHandle),
- _overlapped = ffi.new("OVERLAPPED"),
- _buffer = ffi.new("char[?]", 1024),
- }, dirwatcher_meta)
-end
-function dirwatcher_meta:start_watch(watchSubtree)
- local dwNotifyFilter = bitlib.bor(FILE_NOTIFY_CHANGE_FILE_NAME, FILE_NOTIFY_CHANGE_DIR_NAME, FILE_NOTIFY_CHANGE_ATTRIBUTES, FILE_NOTIFY_CHANGE_SIZE, FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_NOTIFY_CHANGE_LAST_ACCESS, FILE_NOTIFY_CHANGE_CREATION, FILE_NOTIFY_CHANGE_SECURITY)
- local buffer = self._buffer
- local bufferSize = ffi.sizeof(buffer)
- local result = C.ReadDirectoryChangesW(self._rawhandle, buffer, bufferSize, watchSubtree, dwNotifyFilter, nil, self._overlapped, nil)
- if result == 0 then
- local lasterror = C.GetLastError()
- return nil, format_error("ReadDirectoryChangesW", lasterror, self.dirname)
- end
- return true
-end
-local ActionTable = {
- [FILE_ACTION_ADDED] = "added",
- [FILE_ACTION_REMOVED] = "removed",
- [FILE_ACTION_MODIFIED] = "modified",
- [FILE_ACTION_RENAMED_OLD_NAME] = "rename_from",
- [FILE_ACTION_RENAMED_NEW_NAME] = "rename_to",
-}
-function dirwatcher_meta:process(numberOfBytes)
- -- self._buffer received `numberOfBytes` bytes
- local buffer = self._buffer
- numberOfBytes = math.min(numberOfBytes, ffi.sizeof(buffer))
- local ptr = ffi.cast("char *", buffer)
- local structSize = ffi.sizeof("FILE_NOTIFY_INFORMATION", 1)
- local t = {}
- while numberOfBytes >= structSize do
- local notifyInfo = ffi.cast("FILE_NOTIFY_INFORMATION*", ptr)
- local nextEntryOffset = notifyInfo.NextEntryOffset
- local action = notifyInfo.Action
- local fileNameLength = notifyInfo.FileNameLength
- local fileName = notifyInfo.FileName
- local u = { action = ActionTable[action], filename = wcs_to_mbs(fileName, fileNameLength / 2) }
- table.insert(t, u)
- if nextEntryOffset == 0 or numberOfBytes <= nextEntryOffset then
- break
- end
- numberOfBytes = numberOfBytes - nextEntryOffset
- ptr = ptr + nextEntryOffset
- end
- return t
-end
-
---[[
- watcher._rawport : cdata HANDLE
- watcher._pending : array of {
- action = ..., filename = ...
- }
- watcher._directories[dirname] = {
- dir = directory watcher,
- dirname = dirname,
- files = { [filename] = user-supplied path } -- files to watch
- }
- watcher[i] = i-th directory (_directories[dirname] for some dirname)
-]]
-
-local fswatcher_meta = {}
-fswatcher_meta.__index = fswatcher_meta
-local function new_watcher()
- local port = C.CreateIoCompletionPort(INVALID_HANDLE_VALUE, nil, 0, 0)
- if port == NULL then
- local lasterror = C.GetLastError()
- return nil, format_error("CreateIoCompletionPort", lasterror)
- end
- return setmetatable({
- _rawport = ffi.gc(port, C.CloseHandle), -- ?
- _pending = {},
- _directories = {},
- }, fswatcher_meta)
-end
-local function add_directory(self, dirname)
- local t = self._directories[dirname]
- if not t then
- local dirwatcher, err = open_directory(dirname)
- if not dirwatcher then
- return dirwatcher, err
- end
- t = { dirwatcher = dirwatcher, dirname = dirname, files = {} }
- table.insert(self, t)
- local i = #self
- local result = C.CreateIoCompletionPort(dirwatcher._rawhandle, self._rawport, i, 0)
- if result == NULL then
- local lasterror = C.GetLastError()
- return nil, format_error("CreateIoCompletionPort", lasterror, dirname)
- end
- self._directories[dirname] = t
- local result, err = dirwatcher:start_watch(false)
- if not result then
- return result, err
- end
- end
- return t
-end
-function fswatcher_meta:add_file(path, ...)
- local fullpath, filename, dirname = get_full_path_name(path)
- local t, err = add_directory(self, dirname)
- if not t then
- return t, err
- end
- t.files[filename] = path
- return true
-end
-local INFINITE = 0xFFFFFFFF
-local function get_queued(self, timeout)
- local startTime = C.GetTickCount64()
- local timeout_ms
- if timeout == nil then
- timeout_ms = INFINITE
- else
- timeout_ms = timeout * 1000
- end
- local numberOfBytesPtr = ffi.new("DWORD[1]")
- local completionKeyPtr = ffi.new("ULONG_PTR[1]")
- local lpOverlapped = ffi.new("OVERLAPPED*[1]")
- repeat
- local result = C.GetQueuedCompletionStatus(self._rawport, numberOfBytesPtr, completionKeyPtr, lpOverlapped, timeout_ms)
- if result == 0 then
- local lasterror = C.GetLastError()
- if lasterror == WAIT_TIMEOUT then
- return nil, "timeout"
- else
- return nil, format_error("GetQueuedCompletionStatus", lasterror)
- end
- end
- local numberOfBytes = numberOfBytesPtr[0]
- local completionKey = tonumber(completionKeyPtr[0])
- local dir_t = assert(self[completionKey], "invalid completion key: " .. tostring(completionKey))
- local t = dir_t.dirwatcher:process(numberOfBytes)
- dir_t.dirwatcher:start_watch(false)
- local found = false
- for i,v in ipairs(t) do
- local path = dir_t.files[v.filename]
- if path then
- found = true
- table.insert(self._pending, {path = path, action = v.action})
- end
- end
- if found then
- return true
- end
- if timeout_ms ~= INFINITE then
- local tt = C.GetTickCount64()
- timeout_ms = timeout_ms - (tt - startTime)
- startTime = tt
- end
- until timeout_ms < 0
- return nil, "timeout"
-end
-function fswatcher_meta:next(timeout)
- if #self._pending > 0 then
- local result = table.remove(self._pending, 1)
- get_queued(self, 0) -- ignore error
- return result
- else
- local result, err = get_queued(self, timeout)
- if result == nil then
- return nil, err
- end
- return table.remove(self._pending, 1)
- end
-end
-function fswatcher_meta:close()
- if self._rawport ~= nil then
- for i,v in ipairs(self) do
- v.dirwatcher:close()
- end
- C.CloseHandle(ffi.gc(self._rawport, nil))
- self._rawport = nil
- end
-end
---[[
-local watcher = require("fswatcher_windows").new()
-assert(watcher:add_file("rdc-sync.c"))
-assert(watcher:add_file("sub2/hoge"))
-for i = 1, 10 do
- local result, err = watcher:next(2)
- if err == "timeout" then
- print(os.date(), "timeout")
- else
- assert(result, err)
- print(os.date(), result.path, result.action)
- end
-end
-watcher:close()
-]]
-return {
- new = new_watcher,
-}
-end
-package.preload["texrunner.safename"] = function(...)
---[[
- Copyright 2019 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-local string = string
-local table = table
-
-local function dounsafechar(c)
- if c == " " then
- return "_"
- else
- return string.format("_%02x", c:byte(1))
- end
-end
-
-local function escapejobname(name)
- return (string.gsub(name, "[%s\"$%%&'();<>\\^`|]", dounsafechar))
-end
-
-local function handlespecialchar(s)
- return (string.gsub(s, "[%\\%%^%{%}%~%#]", "~\\%1"))
-end
-
-local function handlespaces(s)
- return (string.gsub(s, " +", function(s) return string.rep(" ", #s, "~") end))
-end
-
-local function handlenonascii(s)
- return (string.gsub(s, "[\x80-\xFF]+", "\\detokenize{%1}"))
-end
-
-local function safeinput(name, engine)
- local escaped = handlespaces(handlespecialchar(name))
- if engine.name == "pdftex" or engine.name == "pdflatex" then
- escaped = handlenonascii(escaped)
- end
- if name == escaped then
- return string.format("\\input\"%s\"", name)
- else
- return string.format("\\begingroup\\escapechar-1\\let~\\string\\edef\\x{\"%s\" }\\expandafter\\endgroup\\expandafter\\input\\x", escaped)
- end
-end
-
-return {
- escapejobname = escapejobname,
- safeinput = safeinput,
-}
-end
-package.preload["texrunner.checkdriver"] = function(...)
---[[
- Copyright 2020 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-local assert = assert
-local ipairs = ipairs
-local error = error
-local string = string
-local pathutil = require "texrunner.pathutil"
-local message = require "texrunner.message"
-
-local right_values = {
- dvips = {
- graphics = "dvips",
- expl3 = "dvips",
- hyperref = "dvips",
- xypic = "dvips",
- },
- dvipdfmx = {
- graphics = "dvipdfmx",
- expl3 = "dvipdfmx",
- hyperref = "dvipdfmx",
- xypic = "pdf",
- },
- dvisvgm = {
- graphics = "dvisvgm",
- expl3 = "dvisvgm",
- },
- xetex = {
- graphics = "xetex",
- expl3 = "xdvipdfmx",
- hyperref = "xetex",
- xypic = "pdf",
- },
- pdftex = {
- graphics = "pdftex",
- expl3 = "pdfmode",
- hyperref = "pdftex",
- xypic = "pdf",
- },
- luatex = {
- graphics = "luatex",
- expl3 = "pdfmode",
- hyperref = "luatex",
- xypic = "pdf",
- },
-}
-
--- expected_driver: one of "dvips", "dvipdfmx", "dvisvgm", "pdftex", "xetex", "luatex"
-local function checkdriver(expected_driver, filelist)
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("checkdriver: expects ", expected_driver)
- end
-
- local loaded = {}
- for i,t in ipairs(filelist) do
- if t.kind == "input" then
- local basename = pathutil.basename(t.path)
- loaded[basename] = true
- end
- end
-
- local graphics_driver = nil -- "dvipdfmx" | "dvips" | "dvisvgm" | "pdftex" | "luatex" | "xetex" | "unknown"
- if loaded["graphics.sty"] or loaded["color.sty"] then
- if loaded["dvipdfmx.def"] then
- graphics_driver = "dvipdfmx"
- elseif loaded["dvips.def"] then
- graphics_driver = "dvips"
- elseif loaded["dvisvgm.def"] then
- graphics_driver = "dvisvgm"
- elseif loaded["pdftex.def"] then
- graphics_driver = "pdftex"
- elseif loaded["luatex.def"] then
- graphics_driver = "luatex"
- elseif loaded["xetex.def"] then
- graphics_driver = "xetex"
- else
- -- Not supported: dvipdf, dvipsone, emtex, textures, pctexps, pctexwin, pctexhp, pctex32, truetex, tcidvi, vtex
- graphics_driver = "unknown"
- end
- end
- local expl3_driver = nil -- "pdfmode" | "dvisvgm" | "xdvipdfmx" | "dvipdfmx" | "dvips" | "unknown"
- if loaded["expl3-code.tex"] or loaded["expl3.sty"] or loaded["l3backend-dvips.def"] or loaded["l3backend-dvipdfmx.def"] or loaded["l3backend-xdvipdfmx.def"] or loaded["l3backend-pdfmode.def"] then
- if loaded["l3backend-pdfmode.def"] then
- expl3_driver = "pdfmode" -- pdftex, luatex
- elseif loaded["l3backend-dvisvgm.def"] then
- expl3_driver = "dvisvgm"
- elseif loaded["l3backend-xdvipdfmx.def"] then
- expl3_driver = "xdvipdfmx"
- elseif loaded["l3backend-dvipdfmx.def"] then
- expl3_driver = "dvipdfmx"
- elseif loaded["l3backend-dvips.def"] then
- expl3_driver = "dvips"
- else
- -- TODO: driver=latex2e?
- expl3_driver = "unknown"
- end
- end
- local hyperref_driver = nil -- "luatex" | "pdftex" | "xetex" | "dvipdfmx" | "dvips" | "unknown"
- if loaded["hyperref.sty"] then
- if loaded["hluatex.def"] then
- hyperref_driver = "luatex"
- elseif loaded["hpdftex.def"] then
- hyperref_driver = "pdftex"
- elseif loaded["hxetex.def"] then
- hyperref_driver = "xetex"
- elseif loaded["hdvipdfm.def"] then
- hyperref_driver = "dvipdfmx"
- elseif loaded["hdvips.def"] then
- hyperref_driver = "dvips"
- else
- -- Not supported: dvipson, dviwind, tex4ht, texture, vtex, vtexhtm, xtexmrk, hypertex
- hyperref_driver = "unknown"
- end
- -- TODO: dvisvgm?
- end
- local xypic_driver = nil -- "pdf" | "dvips" | "unknown"
- if loaded["xy.tex"] then
- if loaded["xypdf.tex"] then
- xypic_driver = "pdf" -- pdftex, luatex, xetex, dvipdfmx
- elseif loaded["xydvips.tex"] then
- xypic_driver = "dvips"
- else
- -- Not supported: dvidrv, dvitops, oztex, 17oztex, textures, 16textures, xdvi
- xypic_driver = "unknown"
- end
- -- TODO: dvisvgm?
- end
-
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("checkdriver: graphics=", tostring(graphics_driver))
- message.info("checkdriver: expl3=", tostring(expl3_driver))
- message.info("checkdriver: hyperref=", tostring(hyperref_driver))
- message.info("checkdriver: xypic=", tostring(xypic_driver))
- end
-
- local expected = assert(right_values[expected_driver], "invalid value for expected_driver")
- if graphics_driver ~= nil and expected.graphics ~= nil and graphics_driver ~= expected.graphics then
- message.diag("The driver option for graphics(x)/color is missing or wrong.")
- message.diag("Consider setting '", expected.graphics, "' option.")
- end
- if expl3_driver ~= nil and expected.expl3 ~= nil and expl3_driver ~= expected.expl3 then
- message.diag("The driver option for expl3 is missing or wrong.")
- message.diag("Consider setting 'driver=", expected.expl3, "' option when loading expl3.")
- end
- if hyperref_driver ~= nil and expected.hyperref ~= nil and hyperref_driver ~= expected.hyperref then
- message.diag("The driver option for hyperref is missing or wrong.")
- message.diag("Consider setting '", expected.hyperref, "' option.")
- end
- if xypic_driver ~= nil and expected.xypic ~= nil and xypic_driver ~= expected.xypic then
- message.diag("The driver option for Xy-pic is missing or wrong.")
- if expected_driver == "dvipdfmx" then
- message.diag("Consider setting 'dvipdfmx' option or running \\xyoption{pdf}.")
- elseif expected_driver == "pdftex" then
- message.diag("Consider setting 'pdftex' option or running \\xyoption{pdf}.")
- elseif expected.xypic == "pdf" then
- message.diag("Consider setting 'pdf' package option or running \\xyoption{pdf}.")
- elseif expected.xypic == "dvips" then
- message.diag("Consider setting 'dvips' option.")
- end
- end
-end
-
---[[
-filelist[i] = {path = ""}
-]]
-
-return {
- checkdriver = checkdriver,
-}
-end
---[[
- Copyright 2016-2020 ARATA Mizuki
-
- This file is part of ClutTeX.
-
- ClutTeX is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- ClutTeX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ClutTeX. If not, see <http://www.gnu.org/licenses/>.
-]]
-
-CLUTTEX_VERSION = "v0.5"
-
--- Standard libraries
-local coroutine = coroutine
-local tostring = tostring
-
--- External libraries (included in texlua)
-local filesys = require "lfs"
-local md5 = require "md5"
--- local kpse = require "kpse"
-
--- My own modules
-local pathutil = require "texrunner.pathutil"
-local fsutil = require "texrunner.fsutil"
-local shellutil = require "texrunner.shellutil"
-local reruncheck = require "texrunner.reruncheck"
-local luatexinit = require "texrunner.luatexinit"
-local recoverylib = require "texrunner.recovery"
-local message = require "texrunner.message"
-local safename = require "texrunner.safename"
-local extract_bibtex_from_aux_file = require "texrunner.auxfile".extract_bibtex_from_aux_file
-local handle_cluttex_options = require "texrunner.handleoption".handle_cluttex_options
-local checkdriver = require "texrunner.checkdriver".checkdriver
-
-os.setlocale("", "ctype") -- Workaround for recent Universal CRT
-
--- arguments: input file name, jobname, etc...
-local function genOutputDirectory(...)
- -- The name of the temporary directory is based on the path of input file.
- local message = table.concat({...}, "\0")
- local hash = md5.sumhexa(message)
- local tmpdir = os.getenv("TMPDIR") or os.getenv("TMP") or os.getenv("TEMP")
- if tmpdir == nil then
- local home = os.getenv("HOME") or os.getenv("USERPROFILE") or error("environment variable 'TMPDIR' not set!")
- tmpdir = pathutil.join(home, ".latex-build-temp")
- end
- return pathutil.join(tmpdir, 'latex-build-' .. hash)
-end
-
-local inputfile, engine, options = handle_cluttex_options(arg)
-
-local jobname_for_output
-if options.jobname == nil then
- local basename = pathutil.basename(pathutil.trimext(inputfile))
- options.jobname = safename.escapejobname(basename)
- jobname_for_output = basename
-else
- jobname_for_output = options.jobname
-end
-local jobname = options.jobname
-assert(jobname ~= "", "jobname cannot be empty")
-
-local output_extension
-if options.output_format == "dvi" then
- output_extension = engine.dvi_extension or "dvi"
-else
- output_extension = "pdf"
-end
-
-if options.output == nil then
- options.output = jobname_for_output .. "." .. output_extension
-end
-
--- Prepare output directory
-if options.output_directory == nil then
- local inputfile_abs = pathutil.abspath(inputfile)
- options.output_directory = genOutputDirectory(inputfile_abs, jobname, options.engine_executable or options.engine)
-
- if not fsutil.isdir(options.output_directory) then
- assert(fsutil.mkdir_rec(options.output_directory))
-
- elseif options.fresh then
- -- The output directory exists and --fresh is given:
- -- Remove all files in the output directory
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("Cleaning '", options.output_directory, "'...")
- end
- assert(fsutil.remove_rec(options.output_directory))
- assert(filesys.mkdir(options.output_directory))
- end
-
-elseif options.fresh then
- message.error("--fresh and --output-directory cannot be used together.")
- os.exit(1)
-end
-
--- --print-output-directory
-if options.print_output_directory then
- io.write(options.output_directory, "\n")
- os.exit(0)
-end
-
-local pathsep = ":"
-if os.type == "windows" then
- pathsep = ";"
-end
-
-local original_wd = filesys.currentdir()
-if options.change_directory then
- local TEXINPUTS = os.getenv("TEXINPUTS") or ""
- filesys.chdir(options.output_directory)
- options.output = pathutil.abspath(options.output, original_wd)
- os.setenv("TEXINPUTS", original_wd .. pathsep .. TEXINPUTS)
-end
-if options.bibtex or options.biber then
- local BIBINPUTS = os.getenv("BIBINPUTS") or ""
- options.output = pathutil.abspath(options.output, original_wd)
- os.setenv("BIBINPUTS", original_wd .. pathsep .. BIBINPUTS)
-end
-
--- Set `max_print_line' environment variable if not already set.
-if os.getenv("max_print_line") == nil then
- os.setenv("max_print_line", "65536")
-end
--- TODO: error_line, half_error_line
---[[
- According to texmf.cnf:
- 45 < error_line < 255,
- 30 < half_error_line < error_line - 15,
- 60 <= max_print_line.
-]]
-
-local function path_in_output_directory(ext)
- return pathutil.join(options.output_directory, jobname .. "." .. ext)
-end
-
-local recorderfile = path_in_output_directory("fls")
-local recorderfile2 = path_in_output_directory("cluttex-fls")
-
-local tex_options = {
- engine_executable = options.engine_executable,
- interaction = options.interaction,
- file_line_error = options.file_line_error,
- halt_on_error = options.halt_on_error,
- synctex = options.synctex,
- output_directory = options.output_directory,
- shell_escape = options.shell_escape,
- shell_restricted = options.shell_restricted,
- jobname = options.jobname,
- fmt = options.fmt,
- extraoptions = options.tex_extraoptions,
-}
-if options.output_format ~= "pdf" and engine.supports_pdf_generation then
- tex_options.output_format = options.output_format
-end
-
--- Setup LuaTeX initialization script
-if engine.is_luatex then
- local initscriptfile = path_in_output_directory("cluttexinit.lua")
- luatexinit.create_initialization_script(initscriptfile, tex_options)
- tex_options.lua_initialization_script = initscriptfile
-end
-
--- Run TeX command (*tex, *latex)
--- should_rerun, newauxstatus = single_run([auxstatus])
--- This function should be run in a coroutine.
-local function single_run(auxstatus, iteration)
- local minted, epstopdf = false, false
- local bibtex_aux_hash = nil
- local mainauxfile = path_in_output_directory("aux")
- if fsutil.isfile(recorderfile) then
- -- Recorder file already exists
- local filelist, filemap = reruncheck.parse_recorder_file(recorderfile, options)
- if engine.is_luatex and fsutil.isfile(recorderfile2) then
- filelist, filemap = reruncheck.parse_recorder_file(recorderfile2, options, filelist, filemap)
- end
- auxstatus = reruncheck.collectfileinfo(filelist, auxstatus)
- for _,fileinfo in ipairs(filelist) do
- if string.match(fileinfo.path, "minted/minted%.sty$") then
- minted = true
- end
- if string.match(fileinfo.path, "epstopdf%.sty$") then
- epstopdf = true
- end
- end
- if options.bibtex then
- local biblines = extract_bibtex_from_aux_file(mainauxfile, options.output_directory)
- if #biblines > 0 then
- bibtex_aux_hash = md5.sum(table.concat(biblines, "\n"))
- end
- end
- else
- -- This is the first execution
- if auxstatus ~= nil then
- message.error("Recorder file was not generated during the execution!")
- os.exit(1)
- end
- auxstatus = {}
- end
- --local timestamp = os.time()
-
- local tex_injection = ""
-
- if options.includeonly then
- tex_injection = string.format("%s\\includeonly{%s}", tex_options.tex_injection or "", options.includeonly)
- end
-
- if minted or options.package_support["minted"] then
- local outdir = options.output_directory
- if os.type == "windows" then
- outdir = string.gsub(outdir, "\\", "/") -- Use forward slashes
- end
- tex_injection = string.format("%s\\PassOptionsToPackage{outputdir=%s}{minted}", tex_injection or "", outdir)
- if not options.package_support["minted"] then
- message.diag("You may want to use --package-support=minted option.")
- end
- end
- if epstopdf or options.package_support["epstopdf"] then
- local outdir = options.output_directory
- if os.type == "windows" then
- outdir = string.gsub(outdir, "\\", "/") -- Use forward slashes
- end
- if string.sub(outdir, -1, -1) ~= "/" then
- outdir = outdir.."/" -- Must end with a directory separator
- end
- tex_injection = string.format("%s\\PassOptionsToPackage{outdir=%s}{epstopdf}", tex_injection or "", outdir)
- if not options.package_support["epstopdf"] then
- message.diag("You may want to use --package-support=epstopdf option.")
- end
- end
-
- local inputline = tex_injection .. safename.safeinput(inputfile, engine)
-
- local current_tex_options, lightweight_mode = tex_options, false
- if iteration == 1 and options.start_with_draft then
- current_tex_options = {}
- for k,v in pairs(tex_options) do
- current_tex_options[k] = v
- end
- if engine.supports_draftmode then
- current_tex_options.draftmode = true
- options.start_with_draft = false
- end
- current_tex_options.interaction = "batchmode"
- lightweight_mode = true
- else
- current_tex_options.draftmode = false
- end
-
- local command = engine:build_command(inputline, current_tex_options)
-
- local execlog -- the contents of .log file
-
- local recovered = false
- local function recover()
- -- Check log file
- if not execlog then
- local logfile = assert(io.open(path_in_output_directory("log")))
- execlog = logfile:read("*a")
- logfile:close()
- end
- recovered = recoverylib.try_recovery{
- execlog = execlog,
- auxfile = path_in_output_directory("aux"),
- options = options,
- original_wd = original_wd,
- }
- return recovered
- end
- coroutine.yield(command, recover) -- Execute the command
- if recovered then
- return true, {}
- end
-
- local filelist, filemap = reruncheck.parse_recorder_file(recorderfile, options)
- if engine.is_luatex and fsutil.isfile(recorderfile2) then
- filelist, filemap = reruncheck.parse_recorder_file(recorderfile2, options, filelist, filemap)
- end
-
- if not execlog then
- local logfile = assert(io.open(path_in_output_directory("log")))
- execlog = logfile:read("*a")
- logfile:close()
- end
-
- if options.check_driver ~= nil then
- checkdriver(options.check_driver, filelist)
- end
-
- if options.makeindex then
- -- Look for .idx files and run MakeIndex
- for _,file in ipairs(filelist) do
- if pathutil.ext(file.path) == "idx" then
- -- Run makeindex if the .idx file is new or updated
- local idxfileinfo = {path = file.path, abspath = file.abspath, kind = "auxiliary"}
- local output_ind = pathutil.replaceext(file.abspath, "ind")
- if reruncheck.comparefileinfo({idxfileinfo}, auxstatus) or reruncheck.comparefiletime(file.abspath, output_ind, auxstatus) then
- local idx_dir = pathutil.dirname(file.abspath)
- local makeindex_command = {
- "cd", shellutil.escape(idx_dir), "&&",
- options.makeindex, -- Do not escape options.makeindex to allow additional options
- "-o", pathutil.basename(output_ind),
- pathutil.basename(file.abspath)
- }
- coroutine.yield(table.concat(makeindex_command, " "))
- table.insert(filelist, {path = output_ind, abspath = output_ind, kind = "auxiliary"})
- else
- local succ, err = filesys.touch(output_ind)
- if not succ then
- message.warn("Failed to touch " .. output_ind .. " (" .. err .. ")")
- end
- end
- end
- end
- else
- -- Check log file
- if string.find(execlog, "No file [^\n]+%.ind%.") then
- message.diag("You may want to use --makeindex option.")
- end
- end
-
- if options.makeglossaries then
- -- Look for .glo files and run makeglossaries
- for _,file in ipairs(filelist) do
- if pathutil.ext(file.path) == "glo" then
- -- Run makeglossaries if the .glo file is new or updated
- local glofileinfo = {path = file.path, abspath = file.abspath, kind = "auxiliary"}
- local output_gls = pathutil.replaceext(file.abspath, "gls")
- if reruncheck.comparefileinfo({glofileinfo}, auxstatus) or reruncheck.comparefiletime(file.abspath, output_gls, auxstatus) then
- local makeglossaries_command = {
- options.makeglossaries,
- "-d", shellutil.escape(options.output_directory),
- pathutil.trimext(pathutil.basename(file.path))
- }
- coroutine.yield(table.concat(makeglossaries_command, " "))
- table.insert(filelist, {path = output_gls, abspath = output_gls, kind = "auxiliary"})
- else
- local succ, err = filesys.touch(output_gls)
- if not succ then
- message.warn("Failed to touch " .. output_ind .. " (" .. err .. ")")
- end
- end
- end
- end
- else
- -- Check log file
- if string.find(execlog, "No file [^\n]+%.gls%.") then
- message.diag("You may want to use --makeglossaries option.")
- end
- end
-
- if options.bibtex then
- local biblines2 = extract_bibtex_from_aux_file(mainauxfile, options.output_directory)
- local bibtex_aux_hash2
- if #biblines2 > 0 then
- bibtex_aux_hash2 = md5.sum(table.concat(biblines2, "\n"))
- end
- local output_bbl = path_in_output_directory("bbl")
- if bibtex_aux_hash ~= bibtex_aux_hash2 or reruncheck.comparefiletime(mainauxfile, output_bbl, auxstatus) then
- -- The input for BibTeX command has changed...
- local bibtex_command = {
- "cd", shellutil.escape(options.output_directory), "&&",
- options.bibtex,
- pathutil.basename(mainauxfile)
- }
- coroutine.yield(table.concat(bibtex_command, " "))
- else
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("No need to run BibTeX.")
- end
- local succ, err = filesys.touch(output_bbl)
- if not succ then
- message.warn("Failed to touch " .. output_bbl .. " (" .. err .. ")")
- end
- end
- elseif options.biber then
- for _,file in ipairs(filelist) do
- if pathutil.ext(file.path) == "bcf" then
- -- Run biber if the .bcf file is new or updated
- local bcffileinfo = {path = file.path, abspath = file.abspath, kind = "auxiliary"}
- local output_bbl = pathutil.replaceext(file.abspath, "bbl")
- if reruncheck.comparefileinfo({bcffileinfo}, auxstatus) or reruncheck.comparefiletime(file.abspath, output_bbl, auxstatus) then
- local bbl_dir = pathutil.dirname(file.abspath)
- local biber_command = {
- options.biber, -- Do not escape options.biber to allow additional options
- "--output-directory", shellutil.escape(options.output_directory),
- pathutil.basename(file.abspath)
- }
- coroutine.yield(table.concat(biber_command, " "))
- table.insert(filelist, {path = output_bbl, abspath = output_bbl, kind = "auxiliary"})
- else
- local succ, err = filesys.touch(output_bbl)
- if not succ then
- message.warn("Failed to touch " .. output_bbl .. " (" .. err .. ")")
- end
- end
- end
- end
- else
- -- Check log file
- if string.find(execlog, "No file [^\n]+%.bbl%.") then
- message.diag("You may want to use --bibtex or --biber option.")
- end
- end
-
- if string.find(execlog, "No pages of output.") then
- return "No pages of output."
- end
-
- local should_rerun, auxstatus = reruncheck.comparefileinfo(filelist, auxstatus)
- return should_rerun or lightweight_mode, auxstatus
-end
-
--- Run (La)TeX (possibly multiple times) and produce a PDF file.
--- This function should be run in a coroutine.
-local function do_typeset_c()
- local iteration = 0
- local should_rerun, auxstatus
- repeat
- iteration = iteration + 1
- should_rerun, auxstatus = single_run(auxstatus, iteration)
- if should_rerun == "No pages of output." then
- message.warn("No pages of output.")
- return
- end
- until not should_rerun or iteration >= options.max_iterations
-
- if should_rerun then
- message.warn("LaTeX should be run once more.")
- end
-
- -- Successful
- if options.output_format == "dvi" or engine.supports_pdf_generation then
- -- Output file (DVI/PDF) is generated in the output directory
- local outfile = path_in_output_directory(output_extension)
- local oncopyerror
- if os.type == "windows" then
- oncopyerror = function()
- message.error("Failed to copy file. Some applications may be locking the ", string.upper(options.output_format), " file.")
- return false
- end
- end
- coroutine.yield(fsutil.copy_command(outfile, options.output), oncopyerror)
- if #options.dvipdfmx_extraoptions > 0 then
- message.warn("--dvipdfmx-option[s] are ignored.")
- end
-
- else
- -- DVI file is generated, but PDF file is wanted
- local dvifile = path_in_output_directory("dvi")
- local dvipdfmx_command = {"dvipdfmx", "-o", shellutil.escape(options.output)}
- for _,v in ipairs(options.dvipdfmx_extraoptions) do
- table.insert(dvipdfmx_command, v)
- end
- table.insert(dvipdfmx_command, shellutil.escape(dvifile))
- coroutine.yield(table.concat(dvipdfmx_command, " "))
- end
-
- -- Copy SyncTeX file if necessary
- if options.output_format == "pdf" then
- local synctex = tonumber(options.synctex or "0")
- local synctex_ext = nil
- if synctex > 0 then
- -- Compressed SyncTeX file (.synctex.gz)
- synctex_ext = "synctex.gz"
- elseif synctex < 0 then
- -- Uncompressed SyncTeX file (.synctex)
- synctex_ext = "synctex"
- end
- if synctex_ext then
- coroutine.yield(fsutil.copy_command(path_in_output_directory(synctex_ext), pathutil.replaceext(options.output, synctex_ext)))
- end
- end
-
- -- Write dependencies file
- if options.make_depends then
- local filelist, filemap = reruncheck.parse_recorder_file(recorderfile, options)
- if engine.is_luatex and fsutil.isfile(recorderfile2) then
- filelist, filemap = reruncheck.parse_recorder_file(recorderfile2, options, filelist, filemap)
- end
- local f = assert(io.open(options.make_depends, "w"))
- f:write(options.output, ":")
- for _,fileinfo in ipairs(filelist) do
- if fileinfo.kind == "input" then
- f:write(" ", fileinfo.path)
- end
- end
- f:write("\n")
- f:close()
- end
-end
-
-local function do_typeset()
- -- Execute the command string yielded by do_typeset_c
- for command, recover in coroutine.wrap(do_typeset_c) do
- message.exec(command)
- local success, termination, status_or_signal = os.execute(command)
- if type(success) == "number" then -- Lua 5.1 or LuaTeX
- local code = success
- success = code == 0
- termination = nil
- status_or_signal = code
- end
- if not success and not (recover and recover()) then
- if termination == "exit" then
- message.error("Command exited abnormally: exit status ", tostring(status_or_signal))
- elseif termination == "signal" then
- message.error("Command exited abnormally: signal ", tostring(status_or_signal))
- else
- message.error("Command exited abnormally: ", tostring(status_or_signal))
- end
- return false, termination, status_or_signal
- end
- end
- -- Successful
- if CLUTTEX_VERBOSITY >= 1 then
- message.info("Command exited successfully")
- end
- return true
-end
-
-if options.watch then
- -- Watch mode
-
- local fswatcherlib
- if os.type == "windows" then
- -- Windows: Try built-in filesystem watcher
- local succ, result = pcall(require, "texrunner.fswatcher_windows")
- if not succ and CLUTTEX_VERBOSITY >= 1 then
- message.warn("Failed to load texrunner.fswatcher_windows: " .. result)
- end
- fswatcherlib = result
- end
-
- local do_watch
- if fswatcherlib then
- if CLUTTEX_VERBOSITY >= 2 then
- message.info("Using built-in filesystem watcher for Windows")
- end
- do_watch = function(files)
- local watcher = assert(fswatcherlib.new())
- for _,path in ipairs(files) do
- assert(watcher:add_file(path))
- end
- local result = assert(watcher:next())
- if CLUTTEX_VERBOSITY >= 2 then
- message.info(string.format("%s %s", result.action, result.path))
- end
- watcher:close()
- return true
- end
- elseif shellutil.has_command("fswatch") then
- if CLUTTEX_VERBOSITY >= 2 then
- message.info("Using `fswatch' command")
- end
- do_watch = function(files)
- local fswatch_command = {"fswatch", "--one-event", "--event=Updated", "--"}
- for _,path in ipairs(files) do
- table.insert(fswatch_command, shellutil.escape(path))
- end
- local fswatch_command_str = table.concat(fswatch_command, " ")
- if CLUTTEX_VERBOSITY >= 1 then
- message.exec(fswatch_command_str)
- end
- local fswatch = assert(io.popen(fswatch_command_str, "r"))
- for l in fswatch:lines() do
- for _,path in ipairs(files) do
- if l == path then
- fswatch:close()
- return true
- end
- end
- end
- return false
- end
- elseif shellutil.has_command("inotifywait") then
- if CLUTTEX_VERBOSITY >= 2 then
- message.info("Using `inotifywait' command")
- end
- do_watch = function(files)
- local inotifywait_command = {"inotifywait", "--event=modify", "--event=attrib", "--format=%w", "--quiet"}
- for _,path in ipairs(files) do
- table.insert(inotifywait_command, shellutil.escape(path))
- end
- local inotifywait_command_str = table.concat(inotifywait_command, " ")
- if CLUTTEX_VERBOSITY >= 1 then
- message.exec(inotifywait_command_str)
- end
- local inotifywait = assert(io.popen(inotifywait_command_str, "r"))
- for l in inotifywait:lines() do
- for _,path in ipairs(files) do
- if l == path then
- inotifywait:close()
- return true
- end
- end
- end
- return false
- end
- else
- message.error("Could not watch files because neither `fswatch' nor `inotifywait' was installed.")
- message.info("See ClutTeX's manual for details.")
- os.exit(1)
- end
-
- local success, status = do_typeset()
- -- TODO: filenames here can be UTF-8 if command_line_encoding=utf-8
- local filelist, filemap = reruncheck.parse_recorder_file(recorderfile, options)
- if engine.is_luatex and fsutil.isfile(recorderfile2) then
- filelist, filemap = reruncheck.parse_recorder_file(recorderfile2, options, filelist, filemap)
- end
- local input_files_to_watch = {}
- for _,fileinfo in ipairs(filelist) do
- if fileinfo.kind == "input" then
- table.insert(input_files_to_watch, fileinfo.abspath)
- end
- end
-
- while do_watch(input_files_to_watch) do
- local success, status = do_typeset()
- if not success then
- -- error
- else
- local filelist, filemap = reruncheck.parse_recorder_file(recorderfile, options)
- if engine.is_luatex and fsutil.isfile(recorderfile2) then
- filelist, filemap = reruncheck.parse_recorder_file(recorderfile2, options, filelist, filemap)
- end
- input_files_to_watch = {}
- for _,fileinfo in ipairs(filelist) do
- if fileinfo.kind == "input" then
- table.insert(input_files_to_watch, fileinfo.abspath)
- end
- end
- end
- end
-
-else
- -- Not in watch mode
- local success, status = do_typeset()
- if not success then
- os.exit(1)
- end
-end
diff --git a/Build/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl b/Build/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl
deleted file mode 100755
index 5fe53c98f4c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl
+++ /dev/null
@@ -1,166 +0,0 @@
-eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
- if 0;
-
-# MikTeX users can set environment variable TEXSYSTEM to "miktex".
-
-# There have been suggestions to patch this script for dealing with different
-# output templates (a relative new metapost feature) but these have given
-# unwanted side effects. One can always wrap this script in another script
-# to deal with whatever patterns needed. We won't touch what has worked for
-# ages. (December 2019)
-
-#D \module
-#D [ file=mptopdf.pl,
-#D version=2010.05.28, % 2000.05.29
-#D title=converting MP to PDF,
-#D subtitle=\MPTOPDF,
-#D author=Hans Hagen,
-#D date=\currentdate,
-#D url=www.pragma-ade.nl,
-#D copyright={PRAGMA ADE / Hans Hagen \& Ton Otten}]
-#C
-#C This module is part of the \CONTEXT\ macro||package and is
-#C therefore copyrighted by \PRAGMA. See licen-en.pdf for
-#C details.
-
-# use File::Copy ; # not in every perl
-
-use Config ;
-use Getopt::Long ;
-use strict ;
-use File::Basename ;
-
-$Getopt::Long::passthrough = 1 ; # no error message
-$Getopt::Long::autoabbrev = 1 ; # partial switch accepted
-
-my $Help = 0 ;
-my $Latex = 0 ;
-my $TeXexec = 0 ;
-my $RawMP = 1 ;
-my $MetaFun = 0 ;
-my $PassOn = '' ;
-
-&GetOptions
- ( "help" => \$Help ,
- "rawmp" => \$RawMP, # option is now default, but keep for compat
- "metafun" => \$MetaFun,
- "passon" => \$PassOn, # option is ignored, but keep for compat
- "latex" => \$Latex,
- "texexec" => \$TeXexec) ;
-
-my $program = "MPtoPDF 1.4.1" ;
-my $pattern = "@ARGV" ; # was $ARGV[0]
-my $miktex = 0 ;
-my $done = 0 ;
-my $report = '' ;
-my $mplatexswitch = " --tex=latex " ;
-my $texexecswitch = " --tex=\"texexec --batch --once --nomp --mptex\" " ; # untested
-
-my $dosish = ($Config{'osname'} =~ /^(ms)?dos|^os\/2|^mswin/i) ;
-my $escapeshell = (($ENV{'SHELL'}) && ($ENV{'SHELL'} =~ m/sh/i ));
-
-if ($ENV{"TEXSYSTEM"}) {
- $miktex = ($ENV{"TEXSYSTEM"} =~ /miktex/io) ;
-}
-
-my @files ;
-my $command = my $mpbin = '' ;
-
-# agressive copy, works for open files like in gs
-
-sub CopyFile {
- my ($From,$To) = @_ ;
- return unless open(INP,"<$From") ;
- return unless open(OUT,">$To") ;
- binmode INP ;
- binmode OUT ;
- while (<INP>) {
- print OUT $_ ;
- }
- close (INP) ;
- close (OUT) ;
-}
-
-if (($pattern eq '')||($Help)) {
- print "\n$program : provide MP output file (or pattern)\n" ;
- exit ;
-} elsif ($pattern =~ /\.mp$/io) {
- shift @ARGV ; my $rest = join(" ", @ARGV) ;
- if (open(INP,$pattern)) {
- while (<INP>) {
- if (/(documentstyle|documentclass|begin\{document\})/io) {
- $Latex = 1 ; last ;
- }
- }
- close (INP) ;
- }
- if ($Latex) {
- $rest .= " $mplatexswitch" ;
- }
- if ($TeXexec) {
- $rest .= " $texexecswitch" ;
- }
- if ($MetaFun) {
- $mpbin = "mpost --progname=mpost --mem=metafun" ;
- } else {
- $mpbin = "mpost --mem=mpost" ;
- }
- my $runner = "$mpbin $rest $pattern" ;
- print "\n$program : running '$runner'\n" ;
- my $error = system ($runner) ;
- if ($error) {
- print "\n$program : error while processing mp file\n" ;
- exit 1 ;
- } else {
- $pattern =~ s/\.mp$//io ;
- @files = glob "$pattern.*" ;
- }
-} elsif (-e $pattern) {
- @files = ($pattern) ;
-} elsif ($pattern =~ /.\../o) {
- @files = glob "$pattern" ;
-} else {
- $pattern .= '.*' ;
- @files = glob "$pattern" ;
-}
-
-foreach my $file (@files) {
- $_ = $file ;
- if (s/\.(\d+|mps)$// && -e $file) {
- if ($miktex) {
- $command = "pdftex -undump=mptopdf" ;
- } else {
- $command = "pdftex -fmt=mptopdf -progname=context" ;
- }
- if ($dosish) {
- $command = "$command \\relax $file" ;
- } else {
- $command = "$command \\\\relax $file" ;
- }
- my $error = system($command) ;
- if ($error) {
- print "\n$program : error while processing tex file\n" ;
- exit 1 ;
- }
- my $pdfsrc = basename($_).".pdf";
- rename ($pdfsrc, "$_-$1.pdf") ;
- if (-e $pdfsrc) {
- CopyFile ($pdfsrc, "$_-$1.pdf") ;
- }
- if ($done) {
- $report .= " +" ;
- }
- $report .= " $_-$1.pdf" ;
- ++$done ;
- }
-}
-
-if ($report eq '') {
- $report = '*' ;
-}
-
-if ($done) {
- print "\n$program : $pattern is converted to$report\n" ;
-} else {
- print "\n$program : no filename matches $pattern\n" ;
-}
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/context b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/context
deleted file mode 100755
index fa62ba8d109..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/context
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-mtxrun --script context "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/contextjit b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/contextjit
deleted file mode 100755
index 5ac1947c78e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/contextjit
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-luajittex --luaonly $(dirname $0)/mtxrun --script context "$@"
-
-# luajittex --luaonly ${0%contextjit}mtxrun --script context "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/ctxtools b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/ctxtools
deleted file mode 100755
index 2e6bd4afaa0..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/ctxtools
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-mtxrun --script ctxtools "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/luatools b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/luatools
deleted file mode 100755
index c17b483be53..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/luatools
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-mtxrun --script base "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun
deleted file mode 100755
index 6eaf5ff449f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun
+++ /dev/null
@@ -1,27647 +0,0 @@
-#!/usr/bin/env texlua
-
-if not modules then modules = { } end modules ['mtxrun'] = {
- version = 1.001,
- comment = "runner, lua replacement for texmfstart.rb",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- one can make a stub:
-
--- mtxrun :
---
--- #!/bin/sh
--- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@"
-
--- mtxrun.cmd :
---
--- @luatex --luaonly %~d0%~p0mtxrun.lua %*
-
--- filename : mtxrun.lua
--- comment : companion to context.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
--- This script is based on texmfstart.rb but does not use kpsewhich to locate files.
--- Although kpse is a library it never came to opening up its interface to other
--- programs (esp scripting languages) and so we do it ourselves. The lua variant
--- evolved out of an experimental ruby one. Interesting is that using a scripting
--- language instead of c does not have a speed penalty. Actually the lua variant is
--- more efficient, especially when multiple calls to kpsewhich are involved. The lua
--- library also gives way more control.
-
--- When libraries used here are updates you can run
---
--- mtxrun --selfmerge
---
--- to update the embedded code. After that you might need to run
---
--- mtxrun --selfupdate
---
--- to copy the new script (from scripts/context/lua) to location where
--- binaries are expected. If you want to remove the embedded code you can run
---
--- mtxxun --selfclean
-
--- to be done / considered
---
--- support for --exec or make it default
--- support for jar files (or maybe not, never used, too messy)
--- support for $RUBYINPUTS cum suis (if still needed)
--- remember for subruns: _CTX_K_V_#{original}_
--- remember for subruns: _CTX_K_S_#{original}_
--- remember for subruns: TEXMFSTART.#{original} [tex.rb texmfstart.rb]
-
--- begin library merge
-
-
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-bit32"] = package.loaded["l-bit32"] or true
-
--- original size: 3607, stripped down to: 3009
-
-if not modules then modules={} end modules ['l-bit32']={
- version=1.001,
- license="the same as regular Lua",
- source="bitwise.lua, v 1.24 2014/12/26 17:20:53 roberto",
- comment="drop-in for bit32, adapted a bit by Hans Hagen",
-}
-if bit32 then
-elseif utf8 then
- load ([[
-local select = select -- instead of: arg = { ... }
-bit32 = {
- bnot = function (a)
- return ~a & 0xFFFFFFFF
- end,
- band = function (x, y, z, ...)
- if not z then
- return ((x or -1) & (y or -1)) & 0xFFFFFFFF
- else
- local res = x & y & z
- for i=1,select("#",...) do
- res = res & select(i,...)
- end
- return res & 0xFFFFFFFF
- end
- end,
- bor = function (x, y, z, ...)
- if not z then
- return ((x or 0) | (y or 0)) & 0xFFFFFFFF
- else
- local res = x | y | z
- for i=1,select("#",...) do
- res = res | select(i,...)
- end
- return res & 0xFFFFFFFF
- end
- end,
- bxor = function (x, y, z, ...)
- if not z then
- return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
- else
- local res = x ~ y ~ z
- for i=1,select("#",...) do
- res = res ~ select(i,...)
- end
- return res & 0xFFFFFFFF
- end
- end,
- btest = function (x, y, z, ...)
- if not z then
- return (((x or -1) & (y or -1)) & 0xFFFFFFFF) ~= 0
- else
- local res = x & y & z
- for i=1,select("#",...) do
- res = res & select(i,...)
- end
- return (res & 0xFFFFFFFF) ~= 0
- end
- end,
- lshift = function (a, b)
- return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
- end,
- rshift = function (a, b)
- return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
- end,
- arshift = function (a, b)
- a = a & 0xFFFFFFFF
- if b <= 0 or (a & 0x80000000) == 0 then
- return (a >> b) & 0xFFFFFFFF
- else
- return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
- end
- end,
- lrotate = function (a ,b)
- b = b & 31
- a = a & 0xFFFFFFFF
- a = (a << b) | (a >> (32 - b))
- return a & 0xFFFFFFFF
- end,
- rrotate = function (a, b)
- b = -b & 31
- a = a & 0xFFFFFFFF
- a = (a << b) | (a >> (32 - b))
- return a & 0xFFFFFFFF
- end,
- extract = function (a, f, w)
- return (a >> f) & ~(-1 << (w or 1))
- end,
- replace = function (a, v, f, w)
- local mask = ~(-1 << (w or 1))
- return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
- end,
-}
- ]] ) ()
-elseif bit then
- load ([[
-local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
-bit32 = {
- arshift = bit.arshift,
- band = band,
- bnot = bnot,
- bor = bit.bor,
- bxor = bit.bxor,
- btest = function(...)
- return band(...) ~= 0
- end,
- extract = function(a,f,w)
- return band(rshift(a,f),2^(w or 1)-1)
- end,
- lrotate = bit.rol,
- lshift = lshift,
- replace = function(a,v,f,w)
- local mask = 2^(w or 1)-1
- return band(a,bnot(lshift(mask,f)))+lshift(band(v,mask),f)
- end,
- rrotate = bit.ror,
- rshift = rshift,
-}
- ]] ) ()
-else
- xpcall(function() local _,t=require("bit32") if t then bit32=t end return end,function() end)
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-lua"] = package.loaded["l-lua"] or true
-
--- original size: 6529, stripped down to: 2933
-
-if not modules then modules={} end modules ['l-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local next,type,tonumber=next,type,tonumber
-LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
-LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
-LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
-LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
-if LUAVERSION<5.2 and jit then
- MINORVERSION=2
- LUAVERSION=5.2
-end
-if not lpeg then
- lpeg=require("lpeg")
-end
-if loadstring then
- local loadnormal=load
- function load(first,...)
- if type(first)=="string" then
- return loadstring(first,...)
- else
- return loadnormal(first,...)
- end
- end
-else
- loadstring=load
-end
-if not ipairs then
- local function iterate(a,i)
- i=i+1
- local v=a[i]
- if v~=nil then
- return i,v
- end
- end
- function ipairs(a)
- return iterate,a,0
- end
-end
-if not pairs then
- function pairs(t)
- return next,t
- end
-end
-if not table.unpack then
- table.unpack=_G.unpack
-elseif not unpack then
- _G.unpack=table.unpack
-end
-if not package.loaders then
- package.loaders=package.searchers
-end
-local print,select,tostring=print,select,tostring
-local inspectors={}
-function setinspector(kind,inspector)
- inspectors[kind]=inspector
-end
-function inspect(...)
- for s=1,select("#",...) do
- local value=select(s,...)
- if value==nil then
- print("nil")
- else
- local done=false
- local kind=type(value)
- local inspector=inspectors[kind]
- if inspector then
- done=inspector(value)
- if done then
- break
- end
- end
- for kind,inspector in next,inspectors do
- done=inspector(value)
- if done then
- break
- end
- end
- if not done then
- print(tostring(value))
- end
- end
- end
-end
-local dummy=function() end
-function optionalrequire(...)
- local ok,result=xpcall(require,dummy,...)
- if ok then
- return result
- end
-end
-if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
-end
-local flush=io.flush
-if flush then
- local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
- local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
- local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
- local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
-end
-FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
-if not FFISUPPORTED then
- local okay;okay,ffi=pcall(require,"ffi")
- FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
-end
-if not FFISUPPORTED then
- ffi=nil
-elseif not ffi.number then
- ffi.number=tonumber
-end
-if LUAVERSION>5.3 then
-end
-if status and os.setenv then
- os.setenv("engine",string.lower(status.luatex_engine or "unknown"))
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-macro"] = package.loaded["l-macro"] or true
-
--- original size: 10130, stripped down to: 5990
-
-if not modules then modules={} end modules ['l-macros']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local S,P,R,V,C,Cs,Cc,Ct,Carg=lpeg.S,lpeg.P,lpeg.R,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg
-local lpegmatch=lpeg.match
-local concat=table.concat
-local format,sub,match=string.format,string.sub,string.match
-local next,load,type=next,load,type
-local newline=S("\n\r")^1
-local continue=P("\\")*newline
-local whitespace=S(" \t\n\r")
-local spaces=S(" \t")+continue
-local nametoken=R("az","AZ","__","09")
-local name=nametoken^1
-local body=((continue/""+1)-newline)^1
-local lparent=P("(")
-local rparent=P(")")
-local noparent=1-(lparent+rparent)
-local nested=P { lparent*(noparent+V(1))^0*rparent }
-local escaped=P("\\")*P(1)
-local squote=P("'")
-local dquote=P('"')
-local quoted=dquote*(escaped+(1-dquote))^0*dquote+squote*(escaped+(1-squote))^0*squote
-local arguments=lparent*Ct((Cs((nested+(quoted+1-S("),")))^1)+S(", "))^0)*rparent
-local macros=lua.macros or {}
-lua.macros=macros
-local patterns={}
-local definitions={}
-local resolve
-local subparser
-local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
-end
-local safeguard=P("local")*whitespace^1*name*(whitespace+P("="))
-resolve=safeguard+C(C(name)*(arguments^-1))/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return s.."("..concat(a,",")..")"
- else
- return raw
- end
-end
-subparser=Cs((resolve+P(1))^1)
-local enddefine=P("#enddefine")/""
-local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
-end
-local register=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
-end
-local unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
- end
- return ""
-end
-local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
-local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
-function macros.reset()
- definitions={}
- patterns={}
-end
-function macros.showdefinitions()
- for name,list in table.sortedhash(definitions) do
- local arguments=list.a
- if arguments then
- arguments="("..concat(arguments,",")..")"
- else
- arguments=""
- end
- print("macro: "..name..arguments)
- for i=0,#list do
- local l=list[i]
- if l then
- print(" "..l)
- end
- end
- end
-end
-function macros.resolvestring(str)
- return lpegmatch(parser,str) or str
-end
-function macros.resolving()
- return next(patterns)
-end
-local function reload(path,name,data)
- local only=match(name,".-([^/]+)%.lua")
- if only and only~="" then
- local name=path.."/"..only
- local f=io.open(name,"wb")
- f:write(data)
- f:close()
- local f=loadfile(name)
- os.remove(name)
- return f
- end
-end
-local function reload(path,name,data)
- if path and path~="" then
- local only=string.match(name,".-([^/]+)%.lua")
- if only and only~="" then
- local name=path.."/"..only.."-macro.lua"
- local f=io.open(name,"wb")
- if f then
- f:write(data)
- f:close()
- local l=loadfile(name)
- os.remove(name)
- return l
- end
- end
- end
- return load(data,name)
-end
-local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
- f:close()
- local n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
- end
- return reload(lfs and lfs.currentdir(),name,n)
-end
-macros.loaded=loaded
-function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.findfile(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
-end
-macros.required=required
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
-
--- original size: 9604, stripped down to: 6394
-
-if not modules then modules={} end modules ['l-sandbox']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local global=_G
-local next=next
-local unpack=unpack or table.unpack
-local type=type
-local tprint=texio and texio.write_nl or print
-local tostring=tostring
-local format=string.format
-local concat=table.concat
-local sort=table.sort
-local gmatch=string.gmatch
-local gsub=string.gsub
-local requiem=require
-sandbox={}
-local sandboxed=false
-local overloads={}
-local skiploads={}
-local initializers={}
-local finalizers={}
-local originals={}
-local comments={}
-local trace=false
-local logger=false
-local blocked={}
-local function report(...)
- tprint("sandbox ! "..format(...))
-end
-sandbox.report=report
-function sandbox.setreporter(r)
- report=r
- sandbox.report=r
-end
-function sandbox.settrace(v)
- trace=v
-end
-function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
-end
-local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
- end
- overloads[f]=overload or false
- originals[f]=func
- return f
- end
-end
-local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
- end
-end
-sandbox.register=register
-sandbox.redefine=redefine
-function sandbox.original(func)
- return originals and originals[func] or func
-end
-function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
- end
- return func
-end
-local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
-end
-function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
-end
-function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
-end
-function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
- end
-end
-function blockrequire(name,lib)
- if trace then
- report("preventing reload of: %s",name)
- end
- blocked[name]=lib or _G[name] or false
-end
-function sandbox.enable()
- if not sandboxed then
- debug={
- traceback=debug.traceback,
- }
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
- end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
- end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
- end
-end
-blockrequire("lfs",lfs)
-blockrequire("io",io)
-blockrequire("os",os)
-blockrequire("ffi",ffi)
-local function supported(library)
- local l=_G[library]
- return l
-end
-loadfile=register(loadfile,"loadfile")
-if supported("lua") then
- lua.openfile=register(lua.openfile,"lua.openfile")
-end
-if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
-end
-if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
-end
-if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-package"] = package.loaded["l-package"] or true
-
--- original size: 11605, stripped down to: 8299
-
-if not modules then modules={} end modules ['l-package']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type=type
-local gsub,format,find=string.gsub,string.format,string.find
-local insert,remove=table.insert,table.remove
-local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
-local package=package
-local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
-local function cleanpath(path)
- return path
-end
-local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
-local function lualibfile(name)
- return lpegmatch(pattern,name) or name
-end
-local offset=luarocks and 1 or 0
-local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
-}
-package.helpers=helpers
-local methods=helpers.methods
-local builtin=helpers.builtin
-local extraluapaths={}
-local extralibpaths={}
-local luapaths=nil
-local libpaths=nil
-local oldluapath=nil
-local oldlibpath=nil
-local nofextralua=-1
-local nofextralib=-1
-local nofpathlua=-1
-local nofpathlib=-1
-local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
- end
- return nofpaths
-end
-local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
-end
-local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
-end
-local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
-end
-local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
-end
-package.luapaths=getluapaths
-package.libpaths=getlibpaths
-package.extraluapaths=getextraluapaths
-package.extralibpaths=getextralibpaths
-local hashes={
- lua={},
- lib={},
-}
-local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
- end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
- end
-end
-local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
-end
-local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
- end
-end
-helpers.registerpath=registerpath
-function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
-end
-function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
-end
-function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
-end
-function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
-end
-function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
-end
-function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
-end
-local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
-end
-helpers.loadedaslib=loadedaslib
-local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
- end
-end
-helpers.loadedbypath=loadedbypath
-local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
- end
-end
-helpers.loadedbyname=loadedbyname
-methods["already loaded"]=function(name)
- return package.loaded[name]
-end
-methods["preload table"]=function(name)
- return builtin["preload table"](name)
-end
-methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
-end
-methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
-end
-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)
-end
-methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
-end
-methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
-end
-methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
-end
-local level=0
-local used={}
-helpers.traceused=false
-function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
- end
- level=level-1
- return nil
-end
-function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
-end
-function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
- end
- package.loaded[name]=nil
-end
-table.insert(searchers,1,helpers.loaded)
-if context then
- package.path=""
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
-
--- original size: 38440, stripped down to: 19316
-
-if not modules then modules={} end modules ['l-lpeg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-lpeg=require("lpeg")
-local lpeg=lpeg
-if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
-local type,next,tostring=type,next,tostring
-local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format
-local floor=math.floor
-local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
-local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
-if setinspector then
- setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
-end
-lpeg.patterns=lpeg.patterns or {}
-local patterns=lpeg.patterns
-local anything=P(1)
-local endofstring=P(-1)
-local alwaysmatched=P(true)
-patterns.anything=anything
-patterns.endofstring=endofstring
-patterns.beginofstring=alwaysmatched
-patterns.alwaysmatched=alwaysmatched
-local sign=S('+-')
-local zero=P('0')
-local digit=R('09')
-local digits=digit^1
-local octdigit=R("07")
-local octdigits=octdigit^1
-local lowercase=R("az")
-local uppercase=R("AZ")
-local underscore=P("_")
-local hexdigit=digit+lowercase+uppercase
-local hexdigits=hexdigit^1
-local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n")
-local escaped=P("\\")*anything
-local squote=P("'")
-local dquote=P('"')
-local space=P(" ")
-local period=P(".")
-local comma=P(",")
-local utfbom_32_be=P('\000\000\254\255')
-local utfbom_32_le=P('\255\254\000\000')
-local utfbom_16_be=P('\254\255')
-local utfbom_16_le=P('\255\254')
-local utfbom_8=P('\239\187\191')
-local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
-local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
-local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
-local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0)
-local utf8next=R("\128\191")
-patterns.utfbom_32_be=utfbom_32_be
-patterns.utfbom_32_le=utfbom_32_le
-patterns.utfbom_16_be=utfbom_16_be
-patterns.utfbom_16_le=utfbom_16_le
-patterns.utfbom_8=utfbom_8
-patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n")
-patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000")
-patterns.utf_32_be_nl=P("\000\000\000\r\000\000\000\n")+P("\000\000\000\r")+P("\000\000\000\n")
-patterns.utf_32_le_nl=P("\r\000\000\000\n\000\000\000")+P("\r\000\000\000")+P("\n\000\000\000")
-patterns.utf8one=R("\000\127")
-patterns.utf8two=R("\194\223")*utf8next
-patterns.utf8three=R("\224\239")*utf8next*utf8next
-patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next
-patterns.utfbom=utfbom
-patterns.utftype=utftype
-patterns.utfstricttype=utfstricttype
-patterns.utfoffset=utfoffset
-local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four
-local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false)
-local utf8character=P(1)*R("\128\191")^0
-patterns.utf8=utf8char
-patterns.utf8char=utf8char
-patterns.utf8character=utf8character
-patterns.validutf8=validutf8char
-patterns.validutf8char=validutf8char
-local eol=S("\n\r")
-local spacer=S(" \t\f\v")
-local whitespace=eol+spacer
-local nonspacer=1-spacer
-local nonwhitespace=1-whitespace
-patterns.eol=eol
-patterns.spacer=spacer
-patterns.whitespace=whitespace
-patterns.nonspacer=nonspacer
-patterns.nonwhitespace=nonwhitespace
-local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
-local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
-local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
-local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
-local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0)
-local e_collapser=Cs((whitespace^1*endofstring/""+nonwhitespace^1+whitespace^1/" ")^0)
-local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0)
-local b_stripper=Cs(spacer^0/""*(nonspacer^1+spacer^1/" ")^0)
-local e_stripper=Cs((spacer^1*endofstring/""+nonspacer^1+spacer^1/" ")^0)
-local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0)
-patterns.stripper=stripper
-patterns.fullstripper=fullstripper
-patterns.collapser=collapser
-patterns.nospacer=nospacer
-patterns.b_collapser=b_collapser
-patterns.m_collapser=m_collapser
-patterns.e_collapser=e_collapser
-patterns.b_stripper=b_stripper
-patterns.m_stripper=m_stripper
-patterns.e_stripper=e_stripper
-patterns.lowercase=lowercase
-patterns.uppercase=uppercase
-patterns.letter=patterns.lowercase+patterns.uppercase
-patterns.space=space
-patterns.tab=P("\t")
-patterns.spaceortab=patterns.space+patterns.tab
-patterns.newline=newline
-patterns.emptyline=newline^1
-patterns.equal=P("=")
-patterns.comma=comma
-patterns.commaspacer=comma*spacer^0
-patterns.period=period
-patterns.colon=P(":")
-patterns.semicolon=P(";")
-patterns.underscore=underscore
-patterns.escaped=escaped
-patterns.squote=squote
-patterns.dquote=dquote
-patterns.nosquote=(escaped+(1-squote))^0
-patterns.nodquote=(escaped+(1-dquote))^0
-patterns.unsingle=(squote/"")*patterns.nosquote*(squote/"")
-patterns.undouble=(dquote/"")*patterns.nodquote*(dquote/"")
-patterns.unquoted=patterns.undouble+patterns.unsingle
-patterns.unspacer=((patterns.spacer^1)/"")^0
-patterns.singlequoted=squote*patterns.nosquote*squote
-patterns.doublequoted=dquote*patterns.nodquote*dquote
-patterns.quoted=patterns.doublequoted+patterns.singlequoted
-patterns.digit=digit
-patterns.digits=digits
-patterns.octdigit=octdigit
-patterns.octdigits=octdigits
-patterns.hexdigit=hexdigit
-patterns.hexdigits=hexdigits
-patterns.sign=sign
-patterns.cardinal=digits
-patterns.integer=sign^-1*digits
-patterns.unsigned=digit^0*period*digits
-patterns.float=sign^-1*patterns.unsigned
-patterns.cunsigned=digit^0*comma*digits
-patterns.cpunsigned=digit^0*(period+comma)*digits
-patterns.cfloat=sign^-1*patterns.cunsigned
-patterns.cpfloat=sign^-1*patterns.cpunsigned
-patterns.number=patterns.float+patterns.integer
-patterns.cnumber=patterns.cfloat+patterns.integer
-patterns.cpnumber=patterns.cpfloat+patterns.integer
-patterns.oct=zero*octdigits
-patterns.octal=patterns.oct
-patterns.HEX=zero*P("X")*(digit+uppercase)^1
-patterns.hex=zero*P("x")*(digit+lowercase)^1
-patterns.hexadecimal=zero*S("xX")*hexdigits
-patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigits+hexdigits*period*hexdigit^0+hexdigits)*(S("pP")*sign^-1*hexdigits)^-1
-patterns.decafloat=sign^-1*(digit^0*period*digits+digits*period*digit^0+digits)*S("eE")*sign^-1*digits
-patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring
-patterns.somecontent=(anything-newline-space)^1
-patterns.beginline=#(1-newline)
-patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
-local function anywhere(pattern)
- return (1-P(pattern))^0*P(pattern)
-end
-lpeg.anywhere=anywhere
-function lpeg.instringchecker(p)
- p=anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
-end
-function lpeg.splitter(pattern,action)
- if action then
- return (((1-P(pattern))^1)/action+1)^0
- else
- return (Cs((1-P(pattern))^1)+1)^0
- end
-end
-function lpeg.tsplitter(pattern,action)
- if action then
- return Ct((((1-P(pattern))^1)/action+1)^0)
- else
- return Ct((Cs((1-P(pattern))^1)+1)^0)
- end
-end
-local splitters_s,splitters_m,splitters_t={},{},{}
-local function splitat(separator,single)
- local splitter=(single and splitters_s[separator]) or splitters_m[separator]
- if not splitter then
- separator=P(separator)
- local other=C((1-separator)^0)
- if single then
- local any=anything
- splitter=other*(separator*C(any^0)+"")
- splitters_s[separator]=splitter
- else
- splitter=other*(separator*other)^0
- splitters_m[separator]=splitter
- end
- end
- return splitter
-end
-local function tsplitat(separator)
- local splitter=splitters_t[separator]
- if not splitter then
- splitter=Ct(splitat(separator))
- splitters_t[separator]=splitter
- end
- return splitter
-end
-lpeg.splitat=splitat
-lpeg.tsplitat=tsplitat
-function string.splitup(str,separator)
- if not separator then
- separator=","
- end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
-end
-local cache={}
-function lpeg.split(separator,str)
- local c=cache[separator]
- if not c then
- c=tsplitat(separator)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-function string.split(str,separator)
- if separator then
- local c=cache[separator]
- if not c then
- c=tsplitat(separator)
- cache[separator]=c
- end
- return lpegmatch(c,str)
- else
- return { str }
- end
-end
-local spacing=patterns.spacer^0*newline
-local empty=spacing*Cc("")
-local nonempty=Cs((1-spacing)^1)*spacing^-1
-local content=(empty+nonempty)^1
-patterns.textline=content
-local linesplitter=tsplitat(newline)
-patterns.linesplitter=linesplitter
-function string.splitlines(str)
- return lpegmatch(linesplitter,str)
-end
-local cache={}
-function lpeg.checkedsplit(separator,str)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-function string.checkedsplit(str,separator)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
-local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
-local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
-patterns.utf8byte=utf8byte
-local cache={}
-function lpeg.stripper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs(((S(str)^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs(((str^1)/""+1)^0)
- end
-end
-local cache={}
-function lpeg.keeper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs((((1-S(str))^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs((((1-str)^1)/""+1)^0)
- end
-end
-function lpeg.frontstripper(str)
- return (P(str)+P(true))*Cs(anything^0)
-end
-function lpeg.endstripper(str)
- return Cs((1-P(str)*endofstring)^0)
-end
-function lpeg.replacer(one,two,makefunction,isutf)
- local pattern
- local u=isutf and utf8char or 1
- if type(one)=="table" then
- local no=#one
- local p=P(false)
- if no==0 then
- for k,v in next,one do
- p=p+P(k)/v
- end
- pattern=Cs((p+u)^0)
- elseif no==1 then
- local o=one[1]
- one,two=P(o[1]),o[2]
- pattern=Cs((one/two+u)^0)
- else
- for i=1,no do
- local o=one[i]
- p=p+P(o[1])/o[2]
- end
- pattern=Cs((p+u)^0)
- end
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
- end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
- end
-end
-function lpeg.finder(lst,makefunction,isutf)
- local pattern
- if type(lst)=="table" then
- pattern=P(false)
- if #lst==0 then
- for k,v in next,lst do
- pattern=pattern+P(k)
- end
- else
- for i=1,#lst do
- pattern=pattern+P(lst[i])
- end
- end
- else
- pattern=P(lst)
- end
- if isutf then
- pattern=((utf8char or 1)-pattern)^0*pattern
- else
- pattern=(1-pattern)^0*pattern
- end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
- end
-end
-local splitters_f,splitters_s={},{}
-function lpeg.firstofsplit(separator)
- local splitter=splitters_f[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)
- splitters_f[separator]=splitter
- end
- return splitter
-end
-function lpeg.secondofsplit(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=(1-pattern)^0*pattern*C(anything^0)
- splitters_s[separator]=splitter
- end
- return splitter
-end
-local splitters_s,splitters_p={},{}
-function lpeg.beforesuffix(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)*pattern*endofstring
- splitters_s[separator]=splitter
- end
- return splitter
-end
-function lpeg.afterprefix(separator)
- local splitter=splitters_p[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=pattern*C(anything^0)
- splitters_p[separator]=splitter
- end
- return splitter
-end
-function lpeg.balancer(left,right)
- left,right=P(left),P(right)
- return P { left*((1-left-right)+V(1))^0*right }
-end
-function lpeg.counter(pattern,action)
- local n=0
- local pattern=(P(pattern)/function() n=n+1 end+anything)^0
- if action then
- return function(str) n=0;lpegmatch(pattern,str);action(n) end
- else
- return function(str) n=0;lpegmatch(pattern,str);return n end
- end
-end
-function lpeg.is_lpeg(p)
- return p and lpegtype(p)=="pattern"
-end
-function lpeg.oneof(list,...)
- if type(list)~="table" then
- list={ list,... }
- end
- local p=P(list[1])
- for l=2,#list do
- p=p+P(list[l])
- end
- return p
-end
-local sort=table.sort
-local function copyindexed(old)
- local new={}
- for i=1,#old do
- new[i]=old
- end
- return new
-end
-local function sortedkeys(tab)
- local keys,s={},0
- for key,_ in next,tab do
- s=s+1
- keys[s]=key
- end
- sort(keys)
- return keys
-end
-function lpeg.append(list,pp,delayed,checked)
- local p=pp
- if #list>0 then
- local keys=copyindexed(list)
- sort(keys)
- for i=#keys,1,-1 do
- local k=keys[i]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- elseif delayed then
- local keys=sortedkeys(list)
- if p then
- for i=1,#keys,1 do
- local k=keys[i]
- local v=list[k]
- p=P(k)/list+p
- end
- else
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- if p then
- p=p/list
- end
- end
- elseif checked then
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- if k==v then
- p=P(k)+p
- else
- p=P(k)/v+p
- end
- else
- if k==v then
- p=P(k)
- else
- p=P(k)/v
- end
- end
- end
- else
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)/v+p
- else
- p=P(k)/v
- end
- end
- end
- return p
-end
-local p_false=P(false)
-local p_true=P(true)
-local lower=utf and utf.lower or string.lower
-local upper=utf and utf.upper or string.upper
-function lpeg.setutfcasers(l,u)
- lower=l or lower
- upper=u or upper
-end
-local function make1(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+P(k)*p_true
- elseif v==false then
- else
- p=p+P(k)*make1(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
- end
- return p
-end
-local function make2(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+(P(lower(k))+P(upper(k)))*p_true
- elseif v==false then
- else
- p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
- end
- return p
-end
-local function utfchartabletopattern(list,insensitive)
- local tree={}
- local n=#list
- if n==0 then
- for s in next,list do
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
- end
- else
- for i=1,n do
- local s=list[i]
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
- end
- end
- return (insensitive and make2 or make1)(tree)
-end
-lpeg.utfchartabletopattern=utfchartabletopattern
-function lpeg.utfreplacer(list,insensitive)
- local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
- return function(str)
- return lpegmatch(pattern,str) or str
- end
-end
-patterns.containseol=lpeg.finder(eol)
-local function nextstep(n,step,result)
- local m=n%step
- local d=floor(n/step)
- if d>0 then
- local v=V(tostring(step))
- local s=result.start
- for i=1,d do
- if s then
- s=v*s
- else
- s=v
- end
- end
- result.start=s
- end
- if step>1 and result.start then
- local v=V(tostring(step/2))
- result[tostring(step)]=v*v
- end
- if step>0 then
- return nextstep(m,step/2,result)
- else
- return result
- end
-end
-function lpeg.times(pattern,n)
- return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
-end
-do
- local trailingzeros=zero^0*-digit
- local stripper=Cs((
- digits*(
- period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
- )+1
- )^0)
- lpeg.patterns.stripzeros=stripper
- local nonzero=digit-zero
- local trailingzeros=zero^1*endofstring
- local stripper=Cs((1-period)^0*(
- period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
- ))
- lpeg.patterns.stripzero=stripper
-end
-local byte_to_HEX={}
-local byte_to_hex={}
-local byte_to_dec={}
-local hex_to_byte={}
-for i=0,255 do
- local H=format("%02X",i)
- local h=format("%02x",i)
- local d=format("%03i",i)
- local c=char(i)
- byte_to_HEX[c]=H
- byte_to_hex[c]=h
- byte_to_dec[c]=d
- hex_to_byte[h]=c
- hex_to_byte[H]=c
-end
-local hextobyte=P(2)/hex_to_byte
-local bytetoHEX=P(1)/byte_to_HEX
-local bytetohex=P(1)/byte_to_hex
-local bytetodec=P(1)/byte_to_dec
-local hextobytes=Cs(hextobyte^0)
-local bytestoHEX=Cs(bytetoHEX^0)
-local bytestohex=Cs(bytetohex^0)
-local bytestodec=Cs(bytetodec^0)
-patterns.hextobyte=hextobyte
-patterns.bytetoHEX=bytetoHEX
-patterns.bytetohex=bytetohex
-patterns.bytetodec=bytetodec
-patterns.hextobytes=hextobytes
-patterns.bytestoHEX=bytestoHEX
-patterns.bytestohex=bytestohex
-patterns.bytestodec=bytestodec
-function string.toHEX(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestoHEX,s)
- end
-end
-function string.tohex(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestohex,s)
- end
-end
-function string.todec(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestodec,s)
- end
-end
-function string.tobytes(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(hextobytes,s)
- end
-end
-local patterns={}
-local function containsws(what)
- local p=patterns[what]
- if not p then
- local p1=P(what)*(whitespace+endofstring)*Cc(true)
- local p2=whitespace*P(p1)
- p=P(p1)+P(1-p2)^0*p2+Cc(false)
- patterns[what]=p
- end
- return p
-end
-lpeg.containsws=containsws
-function string.containsws(str,what)
- return lpegmatch(patterns[what] or containsws(what),str)
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-function"] = package.loaded["l-function"] or true
-
--- original size: 361, stripped down to: 317
-
-if not modules then modules={} end modules ['l-functions']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-functions=functions or {}
-function functions.dummy() end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-string"] = package.loaded["l-string"] or true
-
--- original size: 6644, stripped down to: 3410
-
-if not modules then modules={} end modules ['l-string']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local string=string
-local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
-local lpegmatch,patterns=lpeg.match,lpeg.patterns
-local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
-local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
-function string.unquoted(str)
- return lpegmatch(unquoted,str) or str
-end
-function string.quoted(str)
- return format("%q",str)
-end
-function string.count(str,pattern)
- local n=0
- for _ in gmatch(str,pattern) do
- n=n+1
- end
- return n
-end
-function string.limit(str,n,sentinel)
- if #str>n then
- sentinel=sentinel or "..."
- return sub(str,1,(n-#sentinel))..sentinel
- else
- return str
- end
-end
-local stripper=patterns.stripper
-local fullstripper=patterns.fullstripper
-local collapser=patterns.collapser
-local nospacer=patterns.nospacer
-local longtostring=patterns.longtostring
-function string.strip(str)
- return str and lpegmatch(stripper,str) or ""
-end
-function string.fullstrip(str)
- return str and lpegmatch(fullstripper,str) or ""
-end
-function string.collapsespaces(str)
- return str and lpegmatch(collapser,str) or ""
-end
-function string.nospaces(str)
- return str and lpegmatch(nospacer,str) or ""
-end
-function string.longtostring(str)
- return str and lpegmatch(longtostring,str) or ""
-end
-local pattern=P(" ")^0*P(-1)
-function string.is_empty(str)
- if not str or str=="" then
- return true
- else
- return lpegmatch(pattern,str) and true or false
- end
-end
-local anything=patterns.anything
-local moreescapes=Cc("%")*S(".-+%?()[]*$^{}")
-local allescapes=Cc("%")*S(".-+%?()[]*")
-local someescapes=Cc("%")*S(".-+%()[]")
-local matchescapes=Cc(".")*S("*?")
-local pattern_m=Cs ((moreescapes+anything )^0 )
-local pattern_a=Cs ((allescapes+anything )^0 )
-local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
-local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
-function string.escapedpattern(str,simple)
- return lpegmatch(simple and pattern_b or pattern_a,str)
-end
-function string.topattern(str,lowercase,strict)
- if str=="" or type(str)~="string" then
- return ".*"
- elseif strict=="all" then
- str=lpegmatch(pattern_m,str)
- elseif strict then
- str=lpegmatch(pattern_c,str)
- else
- str=lpegmatch(pattern_b,str)
- end
- if lowercase then
- return lower(str)
- else
- return str
- end
-end
-function string.valid(str,default)
- return (type(str)=="string" and str~="" and str) or default or nil
-end
-string.itself=function(s) return s end
-local pattern_c=Ct(C(1)^0)
-local pattern_b=Ct((C(1)/byte)^0)
-function string.totable(str,bytes)
- return lpegmatch(bytes and pattern_b or pattern_c,str)
-end
-local replacer=lpeg.replacer("@","%%")
-function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
-end
-string.quote=string.quoted
-string.unquote=string.unquoted
-if not string.bytetable then
- local limit=5000
- function string.bytetable(str)
- local n=#str
- if n>limit then
- local t={ byte(str,1,limit) }
- for i=limit+1,n do
- t[i]=byte(str,i)
- end
- return t
- else
- return { byte(str,1,n) }
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-table"] = package.loaded["l-table"] or true
-
--- original size: 41758, stripped down to: 22643
-
-if not modules then modules={} end modules ['l-table']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,next,tostring,tonumber,select,rawget=type,next,tostring,tonumber,select,rawget
-local table,string=table,string
-local concat,sort=table.concat,table.sort
-local format,lower,dump=string.format,string.lower,string.dump
-local getmetatable,setmetatable=getmetatable,setmetatable
-local lpegmatch,patterns=lpeg.match,lpeg.patterns
-local floor=math.floor
-local stripper=patterns.stripper
-function table.getn(t)
- return t and #t
-end
-function table.strip(tab)
- local lst={}
- local l=0
- for i=1,#tab do
- local s=lpegmatch(stripper,tab[i]) or ""
- if s=="" then
- else
- l=l+1
- lst[l]=s
- end
- end
- return lst
-end
-function table.keys(t)
- if t then
- local keys={}
- local k=0
- for key in next,t do
- k=k+1
- keys[k]=key
- end
- return keys
- else
- return {}
- end
-end
-local function compare(a,b)
- local ta=type(a)
- if ta=="number" then
- local tb=type(b)
- if ta==tb then
- return a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
- end
- return tostring(a)<tostring(b)
-end
-local function sortedkeys(tab)
- if tab then
- local srt={}
- local category=0
- local s=0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category~=3 then
- local tkey=type(key)
- if category==1 then
- if tkey~="string" then
- category=3
- end
- elseif category==2 then
- if tkey~="number" then
- category=3
- end
- else
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
- else
- sort(srt)
- end
- return srt
- else
- return {}
- end
-end
-local function sortedhashonly(tab)
- if tab then
- local srt={}
- local s=0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
- end
-end
-local function sortedindexonly(tab)
- if tab then
- local srt={}
- local s=0
- for key in next,tab do
- if type(key)=="number" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
- end
-end
-local function sortedhashkeys(tab,cmp)
- if tab then
- local srt={}
- local s=0
- for key in next,tab do
- if key then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt,cmp)
- end
- return srt
- else
- return {}
- end
-end
-function table.allkeys(t)
- local keys={}
- for k,v in next,t do
- for k in next,v do
- keys[k]=true
- end
- end
- return sortedkeys(keys)
-end
-table.sortedkeys=sortedkeys
-table.sortedhashonly=sortedhashonly
-table.sortedindexonly=sortedindexonly
-table.sortedhashkeys=sortedhashkeys
-local function nothing() end
-local function sortedhash(t,cmp)
- if t then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local m=#s
- if m==1 then
- return next,t
- elseif m>0 then
- local n=0
- return function()
- if n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
- end
- end
- return nothing
-end
-table.sortedhash=sortedhash
-table.sortedpairs=sortedhash
-function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
-end
-function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
-end
-function table.merge(t,...)
- if not t then
- t={}
- end
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
- end
- return t
-end
-function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
- end
- return t
-end
-function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
- end
- return t
-end
-function table.imerged(...)
- local tmp={}
- local ntmp=0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
- end
- return tmp
-end
-local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
- end
-end
-local function copy(t,tables)
- if not tables then
- tables={}
- end
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
- end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
- end
- return tcopy
-end
-table.fastcopy=fastcopy
-table.copy=copy
-function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
-end
-function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
- end
- return h
-end
-function table.fromhash(t)
- local hsh={}
- local h=0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
- end
- return hsh
-end
-local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
-local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto','const',
-}
-local function is_simple_table(t,hexify,accurate)
- local nt=#t
- if nt>0 then
- local n=0
- for _,v in next,t do
- n=n+1
- if type(v)=="table" then
- return nil
- end
- end
- local haszero=rawget(t,0)
- if n==nt then
- local tt={}
- for i=1,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i]=format("0x%X",v)
- elseif accurate then
- tt[i]=format("%q",v)
- else
- tt[i]=v
- end
- elseif tv=="string" then
- tt[i]=format("%q",v)
- elseif tv=="boolean" then
- tt[i]=v and "true" or "false"
- else
- return nil
- end
- end
- return tt
- elseif haszero and (n==nt+1) then
- local tt={}
- for i=0,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i+1]=format("0x%X",v)
- elseif accurate then
- tt[i+1]=format("%q",v)
- else
- tt[i+1]=v
- end
- elseif tv=="string" then
- tt[i+1]=format("%q",v)
- elseif tv=="boolean" then
- tt[i+1]=v and "true" or "false"
- else
- return nil
- end
- end
- tt[1]="[0] = "..tt[1]
- return tt
- end
- end
- return nil
-end
-table.is_simple_table=is_simple_table
-local propername=patterns.propername
-local function dummy() end
-local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- depth=depth.." "
- if indexed then
- handle(format("%s{",depth))
- else
- local tn=type(name)
- if tn=="number" then
- if hexify then
- handle(format("%s[0x%X]={",depth,name))
- else
- handle(format("%s[%s]={",depth,name))
- end
- elseif tn=="string" then
- if noquotes and not reserved[name] and lpegmatch(propername,name) then
- handle(format("%s%s={",depth,name))
- else
- handle(format("%s[%q]={",depth,name))
- end
- elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,name and "true" or "false"))
- else
- handle(format("%s{",depth))
- end
- end
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- if compact then
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
- end
- if last>0 then
- first=1
- end
- end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if compact and first and tk=="number" and k>=first and k<=last then
- if tv=="number" then
- if hexify then
- handle(format("%s 0x%X,",depth,v))
- elseif accurate then
- handle(format("%s %q,",depth,v))
- else
- handle(format("%s %s,",depth,v))
- end
- elseif tv=="string" then
- handle(format("%s %q,",depth,v))
- elseif tv=="table" then
- if next(v)==nil then
- handle(format("%s {},",depth))
- elseif inline then
- local st=is_simple_table(v,hexify,accurate)
- if st then
- handle(format("%s { %s },",depth,concat(st,", ")))
- else
- do_serialize(v,k,depth,level+1,true)
- end
- else
- do_serialize(v,k,depth,level+1,true)
- end
- elseif tv=="boolean" then
- handle(format("%s %s,",depth,v and "true" or "false"))
- elseif tv=="function" then
- if functions then
- handle(format('%s load(%q),',depth,dump(v)))
- else
- handle(format('%s "function",',depth))
- end
- else
- handle(format("%s %q,",depth,tostring(v)))
- end
- elseif k=="__p__" then
- if false then
- handle(format("%s __p__=nil,",depth))
- end
- elseif tv=="number" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=0x%X,",depth,k,v))
- elseif accurate then
- handle(format("%s [%s]=%q,",depth,k,v))
- else
- handle(format("%s [%s]=%s,",depth,k,v))
- end
- elseif tk=="boolean" then
- if hexify then
- handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
- elseif accurate then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
- else
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
- end
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- if hexify then
- handle(format("%s %s=0x%X,",depth,k,v))
- elseif accurate then
- handle(format("%s %s=%q,",depth,k,v))
- else
- handle(format("%s %s=%s,",depth,k,v))
- end
- else
- if hexify then
- handle(format("%s [%q]=0x%X,",depth,k,v))
- elseif accurate then
- handle(format("%s [%q]=%q,",depth,k,v))
- else
- handle(format("%s [%q]=%s,",depth,k,v))
- end
- end
- elseif tv=="string" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,v))
- elseif accurate then
- handle(format("%s [%q]=%q,",depth,k,v))
- else
- handle(format("%s [%s]=%q,",depth,k,v))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,v))
- else
- handle(format("%s [%q]=%q,",depth,k,v))
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={},",depth,k))
- elseif accurate then
- handle(format("%s [%q]={},",depth,k))
- else
- handle(format("%s [%s]={},",depth,k))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,k and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={},",depth,k))
- else
- handle(format("%s [%q]={},",depth,k))
- end
- elseif inline then
- local st=is_simple_table(v,hexify,accurate)
- if st then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
- elseif accurate then
- handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- elseif tv=="boolean" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
- elseif accurate then
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tv=="function" then
- if functions then
- local getinfo=debug and debug.getinfo
- if getinfo then
- local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=load(%q),",depth,k,f))
- elseif accurate then
- handle(format("%s [%q]=load(%q),",depth,k,f))
- else
- handle(format("%s [%s]=load(%q),",depth,k,f))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=load(%q),",depth,k,f))
- else
- handle(format("%s [%q]=load(%q),",depth,k,f))
- end
- end
- end
- else
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
- elseif accurate then
- handle(format("%s [%q]=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%s]=%q,",depth,k,tostring(v)))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%q]=%q,",depth,k,tostring(v)))
- end
- end
- end
- end
- if level>0 then
- handle(format("%s},",depth))
- end
-end
-local function serialize(_handle,root,name,specification)
- local tname=type(name)
- if type(specification)=="table" then
- noquotes=specification.noquotes
- hexify=specification.hexify
- accurate=specification.accurate
- handle=_handle or specification.handle or print
- functions=specification.functions
- compact=specification.compact
- inline=specification.inline and compact
- metacheck=specification.metacheck
- if functions==nil then
- functions=true
- end
- if compact==nil then
- compact=true
- end
- if inline==nil then
- inline=compact
- end
- if metacheck==nil then
- metacheck=true
- end
- else
- noquotes=false
- hexify=false
- handle=_handle or print
- compact=true
- inline=true
- functions=true
- metacheck=true
- end
- if tname=="string" then
- if name=="return" then
- handle("return {")
- else
- handle(name.."={")
- end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
- else
- handle("["..name.."]={")
- end
- elseif tname=="boolean" then
- if name then
- handle("return {")
- else
- handle("{")
- end
- else
- handle("t={")
- end
- if root then
- if metacheck and getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
- end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
- end
- end
- handle("}")
-end
-function table.serialize(root,name,specification)
- local t={}
- local n=0
- local function flush(s)
- n=n+1
- t[n]=s
- end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
-end
-table.tohandle=serialize
-local maxtab=2*1024
-function table.tofile(filename,root,name,specification)
- local f=io.open(filename,'w')
- if f then
- if maxtab>1 then
- local t={}
- local n=0
- local function flush(s)
- n=n+1
- t[n]=s
- if n>maxtab then
- f:write(concat(t,"\n"),"\n")
- t={}
- n=0
- end
- end
- serialize(flush,root,name,specification)
- f:write(concat(t,"\n"),"\n")
- else
- local function flush(s)
- f:write(s,"\n")
- end
- serialize(flush,root,name,specification)
- end
- f:close()
- io.flush()
- end
-end
-local function flattened(t,f,depth)
- if f==nil then
- f={}
- depth=0xFFFF
- elseif tonumber(f) then
- depth=f
- f={}
- elseif not depth then
- depth=0xFFFF
- end
- for k,v in next,t do
- if type(k)~="number" then
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
- end
- end
- for k=1,#t do
- local v=t[k]
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
- end
- return f
-end
-table.flattened=flattened
-local function collapsed(t,f,h)
- if f==nil then
- f={}
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsed(v,f,h)
- elseif not h[v] then
- f[#f+1]=v
- h[v]=true
- end
- end
- return f
-end
-local function collapsedhash(t,h)
- if h==nil then
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsedhash(v,h)
- else
- h[v]=true
- end
- end
- return h
-end
-table.collapsed=collapsed
-table.collapsedhash=collapsedhash
-local function unnest(t,f)
- if not f then
- f={}
- end
- for i=1,#t do
- local v=t[i]
- if type(v)=="table" then
- if type(v[1])=="table" then
- unnest(v,f)
- else
- f[#f+1]=v
- end
- else
- f[#f+1]=v
- end
- end
- return f
-end
-function table.unnest(t)
- return unnest(t)
-end
-local function are_equal(a,b,n,m)
- if a==b then
- return true
- elseif a and b and #a==#b then
- if not n then
- n=1
- end
- if not m then
- m=#a
- end
- for i=n,m do
- local ai,bi=a[i],b[i]
- if ai==bi then
- elseif type(ai)=="table" and type(bi)=="table" then
- if not are_equal(ai,bi) then
- return false
- end
- else
- return false
- end
- end
- return true
- else
- return false
- end
-end
-local function identical(a,b)
- if a~=b then
- for ka,va in next,a do
- local vb=b[ka]
- if va==vb then
- elseif type(va)=="table" and type(vb)=="table" then
- if not identical(va,vb) then
- return false
- end
- else
- return false
- end
- end
- end
- return true
-end
-table.identical=identical
-table.are_equal=are_equal
-local function sparse(old,nest,keeptables)
- local new={}
- for k,v in next,old do
- if not (v=="" or v==false) then
- if nest and type(v)=="table" then
- v=sparse(v,nest)
- if keeptables or next(v)~=nil then
- new[k]=v
- end
- else
- new[k]=v
- end
- end
- end
- return new
-end
-table.sparse=sparse
-function table.compact(t)
- return sparse(t,true,true)
-end
-function table.contains(t,v)
- if t then
- for i=1,#t do
- if t[i]==v then
- return i
- end
- end
- end
- return false
-end
-function table.count(t)
- local n=0
- for k,v in next,t do
- n=n+1
- end
- return n
-end
-function table.swapped(t,s)
- local n={}
- if s then
- for k,v in next,s do
- n[k]=v
- end
- end
- for k,v in next,t do
- n[v]=k
- end
- return n
-end
-function table.hashed(t)
- for i=1,#t do
- t[t[i]]=i
- end
- return t
-end
-function table.mirrored(t)
- local n={}
- for k,v in next,t do
- n[v]=k
- n[k]=v
- end
- return n
-end
-function table.reversed(t)
- if t then
- local tt={}
- local tn=#t
- if tn>0 then
- local ttn=0
- for i=tn,1,-1 do
- ttn=ttn+1
- tt[ttn]=t[i]
- end
- end
- return tt
- end
-end
-function table.reverse(t)
- if t then
- local n=#t
- local m=n+1
- for i=1,floor(n/2) do
- local j=m-i
- t[i],t[j]=t[j],t[i]
- end
- return t
- end
-end
-local function sequenced(t,sep,simple)
- if not t then
- return ""
- elseif type(t)~="table" then
- return t
- end
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- local v=t[i]
- if type(v)=="table" then
- s[i]="{"..sequenced(v,sep,simple).."}"
- else
- s[i]=tostring(t[i])
- end
- end
- else
- n=0
- for k,v in sortedhash(t) do
- if simple then
- if v==true then
- n=n+1
- s[n]=k
- elseif v and v~="" then
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
- else
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
- end
- end
- if sep==true then
- return "{ "..concat(s,", ").." }"
- else
- return concat(s,sep or " | ")
- end
-end
-table.sequenced=sequenced
-function table.print(t,...)
- if type(t)~="table" then
- print(tostring(t))
- else
- serialize(print,t,...)
- end
-end
-if setinspector then
- setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
-end
-function table.sub(t,i,j)
- return { unpack(t,i,j) }
-end
-function table.is_empty(t)
- return not t or next(t)==nil
-end
-function table.has_one_entry(t)
- return t and next(t,next(t))==nil
-end
-function table.loweredkeys(t)
- local l={}
- for k,v in next,t do
- l[lower(k)]=v
- end
- return l
-end
-function table.unique(old)
- local hash={}
- local new={}
- local n=0
- for i=1,#old do
- local oi=old[i]
- if not hash[oi] then
- n=n+1
- new[n]=oi
- hash[oi]=true
- end
- end
- return new
-end
-function table.sorted(t,...)
- sort(t,...)
- return t
-end
-function table.values(t,s)
- if t then
- local values={}
- local keys={}
- local v=0
- for key,value in next,t do
- if not keys[value] then
- v=v+1
- values[v]=value
- keys[k]=key
- end
- end
- if s then
- sort(values)
- end
- return values
- else
- return {}
- end
-end
-function table.filtered(t,pattern,sort,cmp)
- if t and type(pattern)=="string" then
- if sort then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local n=0
- local m=#s
- local function kv(s)
- while n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
- end
- else
- return nothing
- end
-end
-if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-io"] = package.loaded["l-io"] or true
-
--- original size: 11829, stripped down to: 6331
-
-if not modules then modules={} end modules ['l-io']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local io=io
-local open,flush,write,read=io.open,io.flush,io.write,io.read
-local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
-local concat=table.concat
-local type=type
-if string.find(os.getenv("PATH") or "",";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
-else
- io.fileseparator,io.pathseparator="/",":"
-end
-local large=0x01000000
-local medium=0x00100000
-local small=0x00020000
-local function readall(f)
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- return f:read(size)
- else
- return ""
- end
-end
-io.readall=readall
-function io.loaddata(filename,textmode)
- local f=open(filename,(textmode and 'r') or 'rb')
- if f then
- local size=f:seek("end")
- local data=nil
- if size>0 then
- f:seek("set",0)
- data=f:read(size)
- end
- f:close()
- return data
- end
-end
-function io.copydata(source,target,action)
- local f=open(source,"rb")
- if f then
- local g=open(target,"wb")
- if g then
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- local data=f:read(size)
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- end
- g:close()
- end
- f:close()
- flush()
- end
-end
-function io.savedata(filename,data,joiner)
- local f=open(filename,"wb")
- if f then
- if type(data)=="table" then
- f:write(concat(data,joiner or ""))
- elseif type(data)=="function" then
- data(f)
- else
- f:write(data or "")
- end
- f:close()
- flush()
- return true
- else
- return false
- end
-end
-if fio and fio.readline then
- local readline=fio.readline
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=readline(f)
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
- else
- local line=readline(f)
- f:close()
- if line and #line>0 then
- return line
- end
- end
- end
-else
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=f:read("*lines")
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
- else
- local line=f:read("*line") or ""
- f:close()
- if #line>0 then
- return line
- end
- end
- end
-end
-function io.loadchunk(filename,n)
- local f=open(filename,'rb')
- if f then
- local data=f:read(n or 1024)
- f:close()
- if #data>0 then
- return data
- end
- end
-end
-function io.exists(filename)
- local f=open(filename)
- if f==nil then
- return false
- else
- f:close()
- return true
- end
-end
-function io.size(filename)
- local f=open(filename)
- if f==nil then
- return 0
- else
- local s=f:seek("end")
- f:close()
- return s
- end
-end
-local function noflines(f)
- if type(f)=="string" then
- local f=open(filename)
- if f then
- local n=f and noflines(f) or 0
- f:close()
- return n
- else
- return 0
- end
- else
- local n=0
- for _ in f:lines() do
- n=n+1
- end
- f:seek('set',0)
- return n
- end
-end
-io.noflines=noflines
-local nextchar={
- [ 4]=function(f)
- return f:read(1,1,1,1)
- end,
- [ 2]=function(f)
- return f:read(1,1)
- end,
- [ 1]=function(f)
- return f:read(1)
- end,
- [-2]=function(f)
- local a,b=f:read(1,1)
- return b,a
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- return d,c,b,a
- end
-}
-function io.characters(f,n)
- if f then
- return nextchar[n or 1],f
- end
-end
-local nextbyte={
- [4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(a),byte(b),byte(c),byte(d)
- end
- end,
- [3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(a),byte(b),byte(c)
- end
- end,
- [2]=function(f)
- local a,b=f:read(1,1)
- if b then
- return byte(a),byte(b)
- end
- end,
- [1]=function (f)
- local a=f:read(1)
- if a then
- return byte(a)
- end
- end,
- [-2]=function (f)
- local a,b=f:read(1,1)
- if b then
- return byte(b),byte(a)
- end
- end,
- [-3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(c),byte(b),byte(a)
- end
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(d),byte(c),byte(b),byte(a)
- end
- end
-}
-function io.bytes(f,n)
- if f then
- return nextbyte[n or 1],f
- else
- return nil,nil
- end
-end
-function io.ask(question,default,options)
- while true do
- write(question)
- if options then
- write(format(" [%s]",concat(options,"|")))
- end
- if default then
- write(format(" [%s]",default))
- end
- write(format(" "))
- flush()
- local answer=read()
- answer=gsub(answer,"^%s*(.*)%s*$","%1")
- if answer=="" and default then
- return default
- elseif not options then
- return answer
- else
- for k=1,#options do
- if options[k]==answer then
- return answer
- end
- end
- local pattern="^"..answer
- for k=1,#options do
- local v=options[k]
- if find(v,pattern) then
- return v
- end
- end
- end
- end
-end
-local function readnumber(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- if n==1 then
- return byte(f:read(1))
- elseif n==2 then
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==3 then
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==4 then
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==8 then
- local a,b=readnumber(f,4),readnumber(f,4)
- return 0x100*a+b
- elseif n==12 then
- local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
- return 0x10000*a+0x100*b+c
- elseif n==-2 then
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==-3 then
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==-4 then
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==-8 then
- local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
- return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
- else
- return 0
- end
-end
-io.readnumber=readnumber
-function io.readstring(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- local str=gsub(f:read(n),"\000","")
- return str
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-number"] = package.loaded["l-number"] or true
-
--- original size: 5720, stripped down to: 2176
-
-if not modules then modules={} end modules ['l-number']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local tostring,tonumber=tostring,tonumber
-local format,floor,match,rep=string.format,math.floor,string.match,string.rep
-local concat,insert=table.concat,table.insert
-local lpegmatch=lpeg.match
-local floor=math.floor
-number=number or {}
-local number=number
-if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m,w)
- if not w then
- w=32
- end
- local n=w
- for i=0,w-1 do
- local v=bextract(b,i)
- local k=w-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if w then
- return concat(t,"",1,w)
- elseif m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",1,m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
- end
-else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
- end
- end
-end
-function number.valid(str,default)
- return tonumber(str) or default or nil
-end
-function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
-end
-function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
-end
-function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
-end
-function number.idiv(i,d)
- return floor(i/d)
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-set"] = package.loaded["l-set"] or true
-
--- original size: 1923, stripped down to: 1044
-
-if not modules then modules={} end modules ['l-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-set=set or {}
-local nums={}
-local tabs={}
-local concat=table.concat
-local next,type=next,type
-set.create=table.tohash
-function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
- end
-end
-function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
-end
-function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
- end
-end
-function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-os"] = package.loaded["l-os"] or true
-
--- original size: 19120, stripped down to: 10208
-
-if not modules then modules={} end modules ['l-os']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local os=os
-local date,time=os.date,os.time
-local find,format,gsub,upper,gmatch=string.find,string.format,string.gsub,string.upper,string.gmatch
-local concat=table.concat
-local random,ceil,randomseed=math.random,math.ceil,math.randomseed
-local type,setmetatable,tonumber,tostring=type,setmetatable,tonumber,tostring
-do
- local selfdir=os.selfdir
- if selfdir=="" then
- selfdir=nil
- end
- if not selfdir then
- if arg then
- for i=1,#arg do
- local a=arg[i]
- if find(a,"^%-%-[c:]*texmfbinpath=") then
- selfdir=gsub(a,"^.-=","")
- break
- end
- end
- end
- if not selfdir then
- selfdir=os.selfbin or "luatex"
- if find(selfdir,"[/\\]") then
- selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
- elseif os.getenv then
- local path=os.getenv("PATH")
- local name=gsub(selfdir,"^.*[/\\][^/\\]","")
- local patt="[^:]+"
- if os.type=="windows" then
- patt="[^;]+"
- name=name..".exe"
- end
- local isfile
- if lfs then
- local attributes=lfs.attributes
- isfile=function(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
- end
- else
- local open=io.open
- isfile=function(name)
- local f=open(name)
- if f then
- f:close()
- return true
- end
- end
- end
- for p in gmatch(path,patt) do
- if isfile(p.."/"..name) then
- selfdir=p
- break
- end
- end
- end
- end
- os.selfdir=selfdir or "."
- end
-end
-math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-randomseed(math.initialseed)
-if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
- end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
- end
-end
-local execute=os.execute
-local iopopen=io.popen
-local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
-end
-os.resultof=resultof
-function os.pipeto(command)
- return iopopen(command,"w")
-end
-if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
-end
-os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
-if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
-else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
-end
-local launchers={
- windows="start %s",
- macosx="open %s",
- unix="xdg-open %s &> /dev/null &",
-}
-function os.launch(str)
- local command=format(launchers[os.name] or launchers.unix,str)
- execute(command)
-end
-local gettimeofday=os.gettimeofday or os.clock
-os.gettimeofday=gettimeofday
-local startuptime=gettimeofday()
-function os.runtime()
- return gettimeofday()-startuptime
-end
-local resolvers=os.resolvers or {}
-os.resolvers=resolvers
-setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
-end })
-local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
-if platform~="" then
- os.platform=platform
-elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
- local platform=""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
-elseif name=="linux" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=os.getenv("MTX_PLATFORM") or ""
- local musl=find(os.selfdir or "","linuxmusl")
- if platform~="" then
- elseif find(architecture,"x86_64",1,true) then
- platform=musl and "linuxmusl" or "linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform=musl and "linuxmusl" or "linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
-elseif name=="macosx" then
- function resolvers.platform(t,k)
- local architecture=resultof("echo $HOSTTYPE") or ""
- local platform=""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
-elseif name=="sunos" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
-elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
-elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
-else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
-end
-os.newline=name=="windows" and "\013\010" or "\010"
-function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
-end
-local t={ 8,9,"a","b" }
-function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
-end
-local d
-function os.timezone(delta)
- d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
- else
- return 1
- end
-end
-local timeformat=format("%%s%s",os.timezone(true))
-local dateformat="!%Y-%m-%d %H:%M:%S"
-local lasttime=nil
-local lastdate=nil
-function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
-end
-local dateformat="%Y-%m-%d %H:%M:%S"
-local lasttime=nil
-local lastdate=nil
-function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
-end
-function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
-end
-local memory={}
-local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
- end
- memory[filename]=fullname
- end
- return fullname
-end
-os.which=which
-os.where=which
-function os.today()
- return date("!*t")
-end
-function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
-end
-if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
- end
-end
-local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
-end
-os.isleapyear=isleapyear
-local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
-local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
-end
-os.nofdays=nofdays
-function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
-end
-function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
-end
-function os.date(fmt,...)
- if not fmt then
- fmt="%Y-%m-%d %H:%M"
- end
- return date(fmt,...)
-end
-local osexit=os.exit
-local exitcode=nil
-function os.setexitcode(code)
- exitcode=code
-end
-function os.exit(c)
- if exitcode~=nil then
- return osexit(exitcode)
- end
- if c~=nil then
- return osexit(c)
- end
- return osexit()
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-file"] = package.loaded["l-file"] or true
-
--- original size: 22175, stripped down to: 10302
-
-if not modules then modules={} end modules ['l-file']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-file=file or {}
-local file=file
-if not lfs then
- lfs=optionalrequire("lfs")
-end
-local insert,concat=table.insert,table.concat
-local match,find,gmatch=string.match,string.find,string.gmatch
-local lpegmatch=lpeg.match
-local getcurrentdir,attributes=lfs.currentdir,lfs.attributes
-local checkedsplit=string.checkedsplit
-local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
-local attributes=lfs.attributes
-function lfs.isdir(name)
- if name then
- return attributes(name,"mode")=="directory"
- end
-end
-function lfs.isfile(name)
- if name then
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
- end
-end
-function lfs.isfound(name)
- if name then
- local a=attributes(name,"mode")
- return (a=="file" or a=="link") and name or nil
- end
-end
-function lfs.modification(name)
- return name and attributes(name,"modification") or nil
-end
-if sandbox then
- sandbox.redefine(lfs.isfile,"lfs.isfile")
- sandbox.redefine(lfs.isdir,"lfs.isdir")
- sandbox.redefine(lfs.isfound,"lfs.isfound")
-end
-local colon=P(":")
-local period=P(".")
-local periods=P("..")
-local fwslash=P("/")
-local bwslash=P("\\")
-local slashes=S("\\/")
-local noperiod=1-period
-local noslashes=1-slashes
-local name=noperiod^1
-local suffix=period/""*(1-period-slashes)^1*-1
-local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
-local function pathpart(name,default)
- return name and lpegmatch(pattern,name) or default or ""
-end
-local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
-local function basename(name)
- return name and lpegmatch(pattern,name) or name
-end
-local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
-local function nameonly(name)
- return name and lpegmatch(pattern,name) or name
-end
-local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
-local function suffixonly(name)
- return name and lpegmatch(pattern,name) or ""
-end
-local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
-local function suffixesonly(name)
- if name then
- return lpegmatch(pattern,name)
- else
- return ""
- end
-end
-file.pathpart=pathpart
-file.basename=basename
-file.nameonly=nameonly
-file.suffixonly=suffixonly
-file.suffix=suffixonly
-file.suffixesonly=suffixesonly
-file.suffixes=suffixesonly
-file.dirname=pathpart
-file.extname=suffixonly
-local drive=C(R("az","AZ"))*colon
-local path=C((noslashes^0*slashes)^0)
-local suffix=period*C(P(1-period)^0*P(-1))
-local base=C((1-suffix)^0)
-local rest=C(P(1)^0)
-drive=drive+Cc("")
-path=path+Cc("")
-base=base+Cc("")
-suffix=suffix+Cc("")
-local pattern_a=drive*path*base*suffix
-local pattern_b=path*base*suffix
-local pattern_c=C(drive*path)*C(base*suffix)
-local pattern_d=path*rest
-function file.splitname(str,splitdrive)
- if not str then
- elseif splitdrive then
- return lpegmatch(pattern_a,str)
- else
- return lpegmatch(pattern_b,str)
- end
-end
-function file.splitbase(str)
- if str then
- return lpegmatch(pattern_d,str)
- else
- return "",str
- end
-end
-function file.nametotable(str,splitdrive)
- if str then
- local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
- if splitdrive then
- return {
- path=path,
- drive=drive,
- subpath=subpath,
- name=name,
- base=base,
- suffix=suffix,
- }
- else
- return {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
- end
-end
-local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
-function file.removesuffix(name)
- return name and lpegmatch(pattern,name)
-end
-local suffix=period/""*(1-period-slashes)^1*-1
-local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
-function file.addsuffix(filename,suffix,criterium)
- if not filename or not suffix or suffix=="" then
- return filename
- elseif criterium==true then
- return filename.."."..suffix
- elseif not criterium then
- local n,s=lpegmatch(pattern,filename)
- if not s or s=="" then
- return filename.."."..suffix
- else
- return filename
- end
- else
- local n,s=lpegmatch(pattern,filename)
- if s and s~="" then
- local t=type(criterium)
- if t=="table" then
- for i=1,#criterium do
- if s==criterium[i] then
- return filename
- end
- end
- elseif t=="string" then
- if s==criterium then
- return filename
- end
- end
- end
- return (n or filename).."."..suffix
- end
-end
-local suffix=period*(1-period-slashes)^1*-1
-local pattern=Cs((1-suffix)^0)
-function file.replacesuffix(name,suffix)
- if name and suffix and suffix~="" then
- return lpegmatch(pattern,name).."."..suffix
- else
- return name
- end
-end
-local reslasher=lpeg.replacer(P("\\"),"/")
-function file.reslash(str)
- return str and lpegmatch(reslasher,str)
-end
-if lfs.isreadablefile and lfs.iswritablefile then
- file.is_readable=lfs.isreadablefile
- file.is_writable=lfs.iswritablefile
-else
- function file.is_writable(name)
- if not name then
- elseif lfs.isdir(name) then
- name=name.."/m_t_x_t_e_s_t.tmp"
- local f=io.open(name,"wb")
- if f then
- f:close()
- os.remove(name)
- return true
- end
- elseif lfs.isfile(name) then
- local f=io.open(name,"ab")
- if f then
- f:close()
- return true
- end
- else
- local f=io.open(name,"ab")
- if f then
- f:close()
- os.remove(name)
- return true
- end
- end
- return false
- end
- local readable=P("r")*Cc(true)
- function file.is_readable(name)
- if name then
- local a=attributes(name)
- return a and lpegmatch(readable,a.permissions) or false
- else
- return false
- end
- end
-end
-file.isreadable=file.is_readable
-file.iswritable=file.is_writable
-function file.size(name)
- if name then
- local a=attributes(name)
- return a and a.size or 0
- else
- return 0
- end
-end
-function file.splitpath(str,separator)
- return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
-end
-function file.joinpath(tab,separator)
- return tab and concat(tab,separator or io.pathseparator)
-end
-local someslash=S("\\/")
-local stripper=Cs(P(fwslash)^0/""*reslasher)
-local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon
-local isroot=fwslash^1*-1
-local hasroot=fwslash^1
-local reslasher=lpeg.replacer(S("\\/"),"/")
-local deslasher=lpeg.replacer(S("\\/")^1,"/")
-function file.join(one,two,three,...)
- if not two then
- return one=="" and one or lpegmatch(reslasher,one)
- end
- if one=="" then
- return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
- end
- if lpegmatch(isnetwork,one) then
- local one=lpegmatch(reslasher,one)
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return one..two
- else
- return one.."/"..two
- end
- elseif lpegmatch(isroot,one) then
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return two
- else
- return "/"..two
- end
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
-end
-local drivespec=R("az","AZ")^1*colon
-local anchors=fwslash+drivespec
-local untouched=periods+(1-period)^1*P(-1)
-local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0)
-local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
-local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
-local absolute=fwslash
-function file.collapsepath(str,anchor)
- if not str then
- return
- end
- if anchor==true and not lpegmatch(anchors,str) then
- str=getcurrentdir().."/"..str
- end
- if str=="" or str=="." then
- return "."
- elseif lpegmatch(untouched,str) then
- return lpegmatch(reslasher,str)
- end
- local starter,oldelements=lpegmatch(splitstarter,str)
- local newelements={}
- local i=#oldelements
- while i>0 do
- local element=oldelements[i]
- if element=='.' then
- elseif element=='..' then
- local n=i-1
- while n>0 do
- local element=oldelements[n]
- if element~='..' and element~='.' then
- oldelements[n]='.'
- break
- else
- n=n-1
- end
- end
- if n<1 then
- insert(newelements,1,'..')
- end
- elseif element~="" then
- insert(newelements,1,element)
- end
- i=i-1
- end
- if #newelements==0 then
- return starter or "."
- elseif starter then
- return starter..concat(newelements,'/')
- elseif lpegmatch(absolute,str) then
- return "/"..concat(newelements,'/')
- else
- newelements=concat(newelements,'/')
- if anchor=="." and find(str,"^%./") then
- return "./"..newelements
- else
- return newelements
- end
- end
-end
-local validchars=R("az","09","AZ","--","..")
-local pattern_a=lpeg.replacer(1-validchars)
-local pattern_a=Cs((validchars+P(1)/"-")^1)
-local whatever=P("-")^0/""
-local pattern_b=Cs(whatever*(1-whatever*-1)^1)
-function file.robustname(str,strict)
- if str then
- str=lpegmatch(pattern_a,str) or str
- if strict then
- return lpegmatch(pattern_b,str) or str
- else
- return str
- end
- end
-end
-local loaddata=io.loaddata
-local savedata=io.savedata
-file.readdata=loaddata
-file.savedata=savedata
-function file.copy(oldname,newname)
- if oldname and newname then
- local data=loaddata(oldname)
- if data and data~="" then
- savedata(newname,data)
- end
- end
-end
-local letter=R("az","AZ")+S("_-+")
-local separator=P("://")
-local qualified=period^0*fwslash+letter*colon+letter^1*separator+letter^1*fwslash
-local rootbased=fwslash+letter*colon
-lpeg.patterns.qualified=qualified
-lpeg.patterns.rootbased=rootbased
-function file.is_qualified_path(filename)
- return filename and lpegmatch(qualified,filename)~=nil
-end
-function file.is_rootbased_path(filename)
- return filename and lpegmatch(rootbased,filename)~=nil
-end
-function file.strip(name,dir)
- if name then
- local b,a=match(name,"^(.-)"..dir.."(.*)$")
- return a~="" and a or name
- end
-end
-function lfs.mkdirs(path)
- local full=""
- for sub in gmatch(path,"(/*[^\\/]+)") do
- full=full..sub
- lfs.mkdir(full)
- end
-end
-function file.withinbase(path)
- local l=0
- if not find(path,"^/") then
- path="/"..path
- end
- for dir in gmatch(path,"/([^/]+)") do
- if dir==".." then
- l=l-1
- elseif dir~="." then
- l=l+1
- end
- if l<0 then
- return false
- end
- end
- return true
-end
-local symlinkattributes=lfs.symlinkattributes
-function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
-
--- original size: 5115, stripped down to: 1699
-
-if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-gzip=gzip or {}
-if not zlib then
- zlib=xzip
-elseif not xzip then
- xzip=zlib
-end
-if zlib then
- local suffix=file.suffix
- local suffixes=file.suffixes
- local find=string.find
- local openfile=io.open
- local gzipwindow=15+16
- local gziplevel=3
- local identifier="^\x1F\x8B\x08"
- local compress=zlib.compress
- local decompress=zlib.decompress
- function gzip.load(filename)
- local f=openfile(filename,"rb")
- if not f then
- else
- local data=f:read("*all")
- f:close()
- if data and data~="" then
- if suffix(filename)=="gz" then
- data=decompress(data,gzipwindow)
- end
- return data
- end
- end
- end
- function gzip.save(filename,data,level)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=openfile(filename,"wb")
- if f then
- data=compress(data or "",level or gziplevel,nil,gzipwindow)
- f:write(data)
- f:close()
- return #data
- end
- end
- function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
- end
- function gzip.compressed(s)
- return s and find(s,identifier)
- end
- function gzip.compress(s,level)
- if s and not find(s,identifier) then
- if not level then
- level=gziplevel
- elseif level<=0 then
- return s
- elseif level>9 then
- level=9
- end
- return compress(s,level or gziplevel,nil,gzipwindow) or s
- end
- end
- function gzip.decompress(s)
- if s and find(s,identifier) then
- return decompress(s,gzipwindow)
- else
- return s
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-md5"] = package.loaded["l-md5"] or true
-
--- original size: 3414, stripped down to: 2307
-
-if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-if not md5 then
- md5=optionalrequire("md5")
-end
-if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
-end
-local md5,file=md5,file
-local gsub=string.gsub
-local modification,isfile,touch=lfs.modification,lfs.isfile,lfs.touch
-local loaddata,savedata=io.loaddata,io.savedata
-do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
-end
-local md5HEX=md5.HEX
-function file.needsupdating(oldname,newname,threshold)
- local oldtime=modification(oldname)
- if oldtime then
- local newtime=modification(newname)
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
-end
-file.needs_updating=file.needsupdating
-function file.syncmtimes(oldname,newname)
- local oldtime=modification(oldname)
- if oldtime and isfile(newname) then
- touch(newname,oldtime,oldtime)
- end
-end
-local function checksum(name)
- if md5 then
- local data=loaddata(name)
- if data then
- return md5HEX(data)
- end
- end
- return nil
-end
-file.checksum=checksum
-function file.loadchecksum(name)
- if md5 then
- local data=loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
-end
-function file.savechecksum(name,checksum)
- if not checksum then checksum=checksum(name) end
- if checksum then
- savedata(name..".md5",checksum)
- return checksum
- end
- return nil
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-sha"] = package.loaded["l-sha"] or true
-
--- original size: 1085, stripped down to: 969
-
-if not modules then modules={} end modules ['l-sha']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-if sha2 then
- local lpegmatch=lpeg.match
- local lpegpatterns=lpeg.patterns
- local bytestohex=lpegpatterns.bytestohex
- local bytestoHEX=lpegpatterns.bytestoHEX
- local digest256=sha2.digest256
- local digest384=sha2.digest384
- local digest512=sha2.digest512
- sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
- sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
- sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
- sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
- sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
- sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-url"] = package.loaded["l-url"] or true
-
--- original size: 14755, stripped down to: 6981
-
-if not modules then modules={} end modules ['l-url']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local char,format,byte=string.char,string.format,string.byte
-local concat=table.concat
-local tonumber,type,next=tonumber,type,next
-local P,C,R,S,Cs,Cc,Ct,Cf,Cg,V=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Cf,lpeg.Cg,lpeg.V
-local lpegmatch,lpegpatterns,replacer=lpeg.match,lpeg.patterns,lpeg.replacer
-local sortedhash=table.sortedhash
-url=url or {}
-local url=url
-local unescapes={}
-local escapes={}
-setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
-end })
-setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
-end })
-local colon=P(":")
-local qmark=P("?")
-local hash=P("#")
-local slash=P("/")
-local atsign=P("@")
-local percent=P("%")
-local endofstring=P(-1)
-local hexdigit=R("09","AF","af")
-local plus=P("+")
-local nothing=Cc("")
-local okay=R("09","AZ","az")+S("-_.,:=+*~!'()@&$")
-local escapedchar=(percent*C(hexdigit*hexdigit))/unescapes
-local unescapedchar=P(1)/escapes
-local escaped=(plus/" ")+escapedchar
-local noslash=P("/")/""
-local plustospace=P("+")/" "
-local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
-local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
-lpegpatterns.urldecoder=decoder
-lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
-function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
-local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
-local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
-local scheme=schemestr*colon+nothing
-local authority=slash*slash*authoritystr+nothing
-local path=slash*pathstr+nothing
-local query=qmark*querystr+nothing
-local fragment=hash*fragmentstr+nothing
-local validurl=scheme*authority*path*query*fragment
-local parser=Ct(validurl)
-lpegpatterns.url=validurl
-lpegpatterns.urlsplitter=parser
-local escaper=Cs((R("09","AZ","az")^1+P(" ")/"%%20"+S("-./_:")^1+P(1)/escapes)^0)
-local unescaper=Cs((escapedchar+1)^0)
-local getcleaner=Cs((P("+++")/"%%2B"+P("+")/"%%20"+P(1))^1)
-lpegpatterns.urlunescaped=escapedchar
-lpegpatterns.urlescaper=escaper
-lpegpatterns.urlunescaper=unescaper
-lpegpatterns.urlgetcleaner=getcleaner
-function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
-end
-local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
-end
-local isscheme=schemestr*colon*slash*slash
-local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
-end
-local rootletter=R("az","AZ")+S("_-+")
-local separator=P("://")
-local qualified=P(".")^0*P("/")+rootletter*P(":")+rootletter^1*separator+rootletter^1*P("/")
-local rootbased=P("/")+rootletter*P(":")
-local barswapper=replacer("|",":")
-local backslashswapper=replacer("\\","/")
-local equal=P("=")
-local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
-local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
-local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
-},rawset)
-local userpart=(1-atsign-colon)^1
-local serverpart=(1-colon)^1
-local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
-local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
- return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
- }
-end
-url.split=split
-url.hasscheme=hasscheme
-url.hashed=hashed
-function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
-end
-function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
-end
-local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
-function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
-end
-local function escapestring(str)
- return lpegmatch(escaper,str)
-end
-url.escape=escapestring
-function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
-end
-function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
- end
-end
-local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
-function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-dir"] = package.loaded["l-dir"] or true
-
--- original size: 18253, stripped down to: 10816
-
-if not modules then modules={} end modules ['l-dir']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,select=type,select
-local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
-local concat,insert,remove,unpack=table.concat,table.insert,table.remove,table.unpack
-local lpegmatch=lpeg.match
-local P,S,R,C,Cc,Cs,Ct,Cv,V=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Cv,lpeg.V
-dir=dir or {}
-local dir=dir
-local lfs=lfs
-local attributes=lfs.attributes
-local walkdir=lfs.dir
-local isdir=lfs.isdir
-local isfile=lfs.isfile
-local currentdir=lfs.currentdir
-local chdir=lfs.chdir
-local mkdir=lfs.mkdir
-local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
-if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
-else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
-end
-function dir.current()
- return (gsub(currentdir(),"\\","/"))
-end
-local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- local nofdirs=0
- for name,mode,size,time in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- if mode==nil then
- mode=attributes(full,'mode')
- end
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full,size,time)
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
- end
- end
- if dirs then
- for i=1,nofdirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
- end
- end
-end
-local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- local nofdirs=0
- local noffiles=#result
- for name,mode in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- if mode==nil then
- mode=attributes(full,'mode')
- end
- if mode=='file' then
- if not patt or find(full,patt) then
- noffiles=noffiles+1
- result[noffiles]=full
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
- end
- end
- if dirs then
- for i=1,nofdirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
- end
- return result
-end
-local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
- end
- local okay=isdir(path)
- if kind=="function" then
- return okay and glob_pattern_function(path,patt,recurse,method) or {}
- elseif kind=="table" then
- return okay and glob_pattern_table(path,patt,recurse,method) or method
- else
- return okay and glob_pattern_table(path,patt,recurse,{}) or {}
- end
-end
-dir.globpattern=globpattern
-local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
- end
- end
- return result
-end
-dir.collectpattern=collectpattern
-local separator,pattern
-if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
-else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
-end
-local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
-)^0 )
-local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
- else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
- end
-end
-dir.glob=glob
-local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name,mode in walkdir(path) do
- if find(name,"^%.") then
- else
- if mode==nil then
- mode=attributes(name,'mode')
- end
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
- end
- end
- return files
-end
-dir.globfiles=globfiles
-local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name,mode in walkdir(path) do
- if find(name,"^%.") then
- else
- if mode==nil then
- mode=attributes(name,'mode')
- end
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
- end
- end
- return files
-end
-dir.globdirs=globdirs
-function dir.ls(pattern)
- return concat(glob(pattern),"\n")
-end
-local make_indeed=true
-if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
- end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
- else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
- end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
- return pth,(isdir(pth)==true)
- end
-else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
- end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
- else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
- end
- return pth,(isdir(pth)==true)
- end
-end
-dir.makedirs=dir.mkdirs
-do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
- end
- end
-end
-file.expandname=dir.expandname
-local stack={}
-function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" and chdir(newdir) then
- return newdir
- else
- return curdir
- end
-end
-function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
-end
-local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
- end
-end
-dir.found=found
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
-
--- original size: 1850, stripped down to: 1498
-
-if not modules then modules={} end modules ['l-boolean']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,tonumber=type,tonumber
-boolean=boolean or {}
-local boolean=boolean
-function boolean.tonumber(b)
- if b then return 1 else return 0 end
-end
-function toboolean(str,tolerant)
- if str==nil then
- return false
- elseif str==false then
- return false
- elseif str==true then
- return true
- elseif str=="true" then
- return true
- elseif str=="false" then
- return false
- elseif not tolerant then
- return false
- elseif str==0 then
- return false
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
-end
-string.toboolean=toboolean
-function string.booleanstring(str)
- if str=="0" then
- return false
- elseif str=="1" then
- return true
- elseif str=="" then
- return false
- elseif str=="false" then
- return false
- elseif str=="true" then
- return true
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
-end
-function string.is_boolean(str,default,strict)
- if type(str)=="string" then
- if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
- return true
- elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
- return false
- end
- end
- return default
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
-
--- original size: 41281, stripped down to: 17261
-
-if not modules then modules={} end modules ['l-unicode']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-utf=utf or {}
-unicode=nil
-if not string.utfcharacters then
- local gmatch=string.gmatch
- function string.characters(str)
- return gmatch(str,".[\128-\191]*")
- end
-end
-utf.characters=string.utfcharacters
-local type=type
-local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
-local concat=table.concat
-local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp
-local lpegmatch=lpeg.match
-local patterns=lpeg.patterns
-local tabletopattern=lpeg.utfchartabletopattern
-local bytepairs=string.bytepairs
-local finder=lpeg.finder
-local replacer=lpeg.replacer
-local p_utftype=patterns.utftype
-local p_utfstricttype=patterns.utfstricttype
-local p_utfoffset=patterns.utfoffset
-local p_utf8character=patterns.utf8character
-local p_utf8char=patterns.utf8char
-local p_utf8byte=patterns.utf8byte
-local p_utfbom=patterns.utfbom
-local p_newline=patterns.newline
-local p_whitespace=patterns.whitespace
-if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
- else
- local floor=math.floor
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+floor(n/0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+floor(n/0x1000),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+floor(n/0x40000),
- 0x80+(floor(n/0x1000)%0x40),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
- end
- end
-end
-if not utf.byte then
- utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
- if not utf.byte then
- function utf.byte(c)
- return lpegmatch(p_utf8byte,c)
- end
- end
-end
-local utfchar,utfbyte=utf.char,utf.byte
-function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
-end
-local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
-)
-patterns.toentities=toentities
-function utf.toentities(str)
- return lpegmatch(toentities,str)
-end
-local one=P(1)
-local two=C(1)*C(1)
-local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
-local pattern=P("\254\255")*Cs((
- four/function(a,b,c,d)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(a,b)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )+P("\255\254")*Cs((
- four/function(b,a,d,c)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(b,a)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )
-function string.toutf(s)
- return lpegmatch(pattern,s) or s
-end
-local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"ďż˝"
- )^0
-)
-patterns.validatedutf=validatedutf
-function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
-end
-if not utf.len then
- utf.len=string.utflength or (utf8 and utf8.len)
- if not utf.len then
- local n,f=0,1
- local utfcharcounter=patterns.utfbom^-1*Cmt (
- Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
- function(_,t,d)
- n=n+(t-f)/d
- f=t
- return true
- end
- )^0
- function utf.len(str)
- n,f=0,1
- lpegmatch(utfcharcounter,str or "")
- return n
- end
- end
-end
-utf.length=utf.len
-if not utf.sub then
- local utflength=utf.length
- local b,e,n,first,last=0,0,0,0,0
- local function slide_zero(s,p)
- n=n+1
- if n>=last then
- e=p-1
- else
- return p
- end
- end
- local function slide_one(s,p)
- n=n+1
- if n==first then
- b=p
- end
- if n>=last then
- e=p-1
- else
- return p
- end
- end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
- end
- local pattern_zero=Cmt(p_utf8character,slide_zero)^0
- local pattern_one=Cmt(p_utf8character,slide_one )^0
- local pattern_two=Cmt(p_utf8character,slide_two )^0
- local pattern_first=C(p_utf8character)
- function utf.sub(str,start,stop)
- if not start then
- return str
- end
- if start==0 then
- start=1
- end
- if not stop then
- if start<0 then
- local l=utflength(str)
- start=l+start
- else
- start=start-1
- end
- b,n,first=0,0,start
- lpegmatch(pattern_two,str)
- if n>=first then
- return sub(str,b)
- else
- return ""
- end
- end
- if start<0 or stop<0 then
- local l=utf.length(str)
- if start<0 then
- start=l+start
- if start<=0 then
- start=1
- else
- start=start+1
- end
- end
- if stop<0 then
- stop=l+stop
- if stop==0 then
- stop=1
- else
- stop=stop+1
- end
- end
- end
- if start==1 and stop==1 then
- return lpegmatch(pattern_first,str) or ""
- elseif start>stop then
- return ""
- elseif start>1 then
- b,e,n,first,last=0,0,0,start-1,stop
- lpegmatch(pattern_one,str)
- if n>=first and e==0 then
- e=#str
- end
- return sub(str,b,e)
- else
- b,e,n,last=1,0,0,stop
- lpegmatch(pattern_zero,str)
- if e==0 then
- e=#str
- end
- return sub(str,b,e)
- end
- end
-end
-function utf.remapper(mapping,option,action)
- local variant=type(mapping)
- if variant=="table" then
- action=action or mapping
- if option=="dynamic" then
- local pattern=false
- table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
- return function(str)
- if not str or str=="" then
- return ""
- else
- if not pattern then
- pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- end
- return lpegmatch(pattern,str)
- end
- end
- elseif option=="pattern" then
- return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- else
- local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
- end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8character/mapping+p_utf8character)^0)
- else
- local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
- end
- else
- return function(str)
- return str or ""
- end
- end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
- return function(str)
- return lpegmatch(r,str)
- end
-end
-function utf.subtituter(t)
- local f=finder (t)
- local r=replacer(t,false,false,true)
- return function(str)
- local i=lpegmatch(f,str)
- if not i then
- return str
- elseif i>#str then
- return str
- else
- return lpegmatch(r,str)
- end
- end
-end
-local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
-local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
-local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8character))^0)
-local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
-patterns.utflinesplitter=utflinesplitter
-function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
-end
-function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
-end
-function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
-end
-function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
-end
-local utf16_to_utf8_be,utf16_to_utf8_le
-local utf32_to_utf8_be,utf32_to_utf8_le
-local utf_16_be_getbom=patterns.utfbom_16_be^-1
-local utf_16_le_getbom=patterns.utfbom_16_le^-1
-local utf_32_be_getbom=patterns.utfbom_32_be^-1
-local utf_32_le_getbom=patterns.utfbom_32_le^-1
-local utf_16_be_linesplitter=utf_16_be_getbom*lpeg.tsplitat(patterns.utf_16_be_nl)
-local utf_16_le_linesplitter=utf_16_le_getbom*lpeg.tsplitat(patterns.utf_16_le_nl)
-local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_nl)
-local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
-local more=0
-local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
-end
-local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
-end
-local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
-end
-local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
-end
-p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
-p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
-p_utf32_to_utf8_be=P(true)/function() more=0 end*utf_32_be_getbom*Cs(p_utf32_to_utf8_be^0)
-p_utf32_to_utf8_le=P(true)/function() more=0 end*utf_32_le_getbom*Cs(p_utf32_to_utf8_le^0)
-patterns.utf16_to_utf8_be=p_utf16_to_utf8_be
-patterns.utf16_to_utf8_le=p_utf16_to_utf8_le
-patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
-patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
-utf16_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_be,s)
- else
- return s
- end
-end
-local utf16_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_be,s)
- end
- end
- return t
-end
-utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
-end
-local utf16_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_le,s)
- end
- end
- return t
-end
-utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
-end
-local utf32_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_be,s)
- end
- end
- return t
-end
-utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
-end
-local utf32_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_le,s)
- end
- end
- return t
-end
-utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
-utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
-utf.utf32_to_utf8_le_t=utf32_to_utf8_le_t
-utf.utf32_to_utf8_be_t=utf32_to_utf8_be_t
-utf.utf16_to_utf8_le=utf16_to_utf8_le
-utf.utf16_to_utf8_be=utf16_to_utf8_be
-utf.utf32_to_utf8_le=utf32_to_utf8_le
-utf.utf32_to_utf8_be=utf32_to_utf8_be
-function utf.utf8_to_utf8_t(t)
- return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
-end
-function utf.utf16_to_utf8_t(t,endian)
- return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
-end
-function utf.utf32_to_utf8_t(t,endian)
- return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
-end
-if bit32 then
- local rshift=bit32.rshift
- local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
- end
- end
- local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
- end
- end
- local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
- local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
- local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
- end
- end
- local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
- end
- end
- utf.utf8_to_utf16_be=utf8_to_utf16_be
- utf.utf8_to_utf16_le=utf8_to_utf16_le
- function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
- end
- end
-end
-local pattern=Cs (
- (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
-)
-function utf.tocodes(str,separator)
- return lpegmatch(pattern,str,1,separator or " ")
-end
-function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
-end
-function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
-end
-function utf.toeight(str)
- if not str or str=="" then
- return nil
- end
- local utftype=lpegmatch(p_utfstricttype,str)
- if utftype=="utf-8" then
- return sub(str,4)
- elseif utftype=="utf-16-be" then
- return utf16_to_utf8_be(str)
- elseif utftype=="utf-16-le" then
- return utf16_to_utf8_le(str)
- else
- return str
- end
-end
-do
- local p_nany=p_utf8character/""
- local cache={}
- function utf.count(str,what)
- if type(what)=="string" then
- local p=cache[what]
- if not p then
- p=Cs((P(what)/" "+p_nany)^0)
- cache[p]=p
- end
- return #lpegmatch(p,str)
- else
- return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
- end
- end
-end
-if not string.utfvalues then
- local find=string.find
- local dummy=function()
- end
- function string.utfvalues(str)
- local n=#str
- if n==0 then
- return dummy
- elseif n==1 then
- return function() return utfbyte(str) end
- else
- local p=1
- return function()
- local b,e=find(str,".[\128-\191]*",p)
- if b then
- p=e+1
- return utfbyte(sub(str,b,e))
- end
- end
- end
- end
-end
-utf.values=string.utfvalues
-function utf.chrlen(u)
- return
- (u<0x80 and 1) or
- (u<0xE0 and 2) or
- (u<0xF0 and 3) or
- (u<0xF8 and 4) or
- (u<0xFC and 5) or
- (u<0xFE and 6) or 0
-end
-if bit32 then
- local extract=bit32.extract
- local char=string.char
- function utf.toutf32string(n)
- if n<=0xFF then
- return
- char(n).."\000\000\000"
- elseif n<=0xFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
- elseif n<=0xFFFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
- else
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
- end
- end
-end
-local len=utf.len
-local rep=rep
-function string.utfpadd(s,n)
- if n and n~=0 then
- local l=len(s)
- if n>0 then
- local d=n-l
- if d>0 then
- return rep(c or " ",d)..s
- end
- else
- local d=- n-l
- if d>0 then
- return s..rep(c or " ",d)
- end
- end
- end
- return s
-end
-do
- local utfcharacters=utf.characters or string.utfcharacters
- local utfchar=utf.char or string.utfcharacter
- lpeg.UP=P
- if utfcharacters then
- function lpeg.US(str)
- local p=P(false)
- for uc in utfcharacters(str) do
- p=p+P(uc)
- end
- return p
- end
- else
- function lpeg.US(str)
- local p=P(false)
- local f=function(uc)
- p=p+P(uc)
- end
- lpegmatch((p_utf8char/f)^0,str)
- return p
- end
- end
- local range=p_utf8byte*p_utf8byte+Cc(false)
- function lpeg.UR(str,more)
- local first,last
- if type(str)=="number" then
- first=str
- last=more or first
- else
- first,last=lpegmatch(range,str)
- if not last then
- return P(str)
- end
- end
- if first==last then
- return P(str)
- end
- if not utfchar then
- utfchar=utf.char
- end
- if utfchar and (last-first<8) then
- local p=P(false)
- for i=first,last do
- p=p+P(utfchar(i))
- end
- return p
- else
- local f=function(b)
- return b>=first and b<=last
- end
- return p_utf8byte/f
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["l-math"] = package.loaded["l-math"] or true
-
--- original size: 2555, stripped down to: 1831
-
-if not modules then modules={} end modules ['l-math']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-if not math.ceiling then
- math.ceiling=math.ceil
-end
-if not math.round then
- local floor=math.floor
- function math.round(x) return floor(x+0.5) end
-end
-if not math.div then
- local floor=math.floor
- function math.div(n,m) return floor(n/m) end
-end
-if not math.mod then
- function math.mod(n,m) return n%m end
-end
-if not math.sind then
- local sin,cos,tan=math.sin,math.cos,math.tan
- local pipi=2*math.pi/360
- function math.sind(d) return sin(d*pipi) end
- function math.cosd(d) return cos(d*pipi) end
- function math.tand(d) return tan(d*pipi) end
-end
-if not math.odd then
- function math.odd (n) return n%2~=0 end
- function math.even(n) return n%2==0 end
-end
-if not math.cosh then
- local exp=math.exp
- function math.cosh(x)
- local xx=exp(x)
- return (xx+1/xx)/2
- end
- function math.sinh(x)
- local xx=exp(x)
- return (xx-1/xx)/2
- end
- function math.tanh(x)
- local xx=exp(x)
- return (xx-1/xx)/(xx+1/xx)
- end
-end
-if not math.pow then
- function math.pow(x,y)
- return x^y
- end
-end
-if not math.atan2 then
- math.atan2=math.atan
-end
-if not math.ldexp then
- function math.ldexp(x,e)
- return x*2.0^e
- end
-end
-if not math.log10 then
- local log=math.log
- function math.log10(x)
- return log(x,10)
- end
-end
-if not math.type then
- function math.type()
- return "float"
- end
-end
-if not math.tointeger then
- math.mininteger=-0x4FFFFFFFFFFF
- math.maxinteger=0x4FFFFFFFFFFF
- local floor=math.floor
- function math.tointeger(n)
- local f=floor(n)
- return f==n and f or nil
- end
-end
-if not math.ult then
- local floor=math.floor
- function math.tointeger(m,n)
- return floor(m)<floor(n)
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-str"] = package.loaded["util-str"] or true
-
--- original size: 45153, stripped down to: 22734
-
-if not modules then modules={} end modules ['util-str']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-utilities=utilities or {}
-utilities.strings=utilities.strings or {}
-local strings=utilities.strings
-local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
-local load,dump=load,string.dump
-local tonumber,type,tostring,next,setmetatable=tonumber,type,tostring,next,setmetatable
-local unpack,concat=table.unpack,table.concat
-local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
-local patterns,lpegmatch=lpeg.patterns,lpeg.match
-local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
-local loadstripped=function(str,shortcuts)
- if shortcuts then
- return load(dump(load(str),true),nil,nil,shortcuts)
- else
- return load(dump(load(str),true))
- end
-end
-if not number then number={} end
-local stripzero=patterns.stripzero
-local stripzeros=patterns.stripzeros
-local newline=patterns.newline
-local endofstring=patterns.endofstring
-local anything=patterns.anything
-local whitespace=patterns.whitespace
-local space=patterns.space
-local spacer=patterns.spacer
-local spaceortab=patterns.spaceortab
-local digit=patterns.digit
-local sign=patterns.sign
-local period=patterns.period
-local ptf=1/65536
-local bpf=(7200/7227)/65536
-local function points(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*ptf
- if n%1==0 then
- return format("%ipt",n)
- end
- return lpegmatch(stripzeros,format("%.5fpt",n))
-end
-local function basepoints(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*bpf
- if n%1==0 then
- return format("%ibp",n)
- end
- return lpegmatch(stripzeros,format("%.5fbp",n))
-end
-number.points=points
-number.basepoints=basepoints
-local rubish=spaceortab^0*newline
-local anyrubish=spaceortab+newline
-local stripped=(spaceortab^1/"")*newline
-local leading=rubish^0/""
-local trailing=(anyrubish^1*endofstring)/""
-local redundant=rubish^3/"\n"
-local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
-function strings.collapsecrlf(str)
- return lpegmatch(pattern,str)
-end
-local repeaters={}
-function strings.newrepeater(str,offset)
- offset=offset or 0
- local s=repeaters[str]
- if not s then
- s={}
- repeaters[str]=s
- end
- local t=s[offset]
- if t then
- return t
- end
- t={}
- setmetatable(t,{ __index=function(t,k)
- if not k then
- return ""
- end
- local n=k+offset
- local s=n>0 and rep(str,n) or ""
- t[k]=s
- return s
- end })
- s[offset]=t
- return t
-end
-local extra,tab,start=0,0,4,0
-local nspaces=strings.newrepeater(" ")
-string.nspaces=nspaces
-local pattern=Carg(1)/function(t)
- extra,tab,start=0,t or 7,1
- end*Cs((
- Cp()*patterns.tab/function(position)
- local current=(position-start+1)+extra
- local spaces=tab-(current-1)%tab
- if spaces>0 then
- extra=extra+spaces-1
- return nspaces[spaces]
- else
- return ""
- end
- end+newline*Cp()/function(position)
- extra,start=0,position
- end+anything
- )^1)
-function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
-end
-function string.utfpadding(s,n)
- if not n or n==0 then
- return ""
- end
- local l=utflen(s)
- if n>0 then
- return nspaces[n-l]
- else
- return nspaces[-n-l]
- end
-end
-local optionalspace=spacer^0
-local nospace=optionalspace/""
-local endofline=nospace*newline
-local stripend=(whitespace^1*endofstring)/""
-local normalline=(nospace*((1-optionalspace*(newline+endofstring))^1)*nospace)
-local stripempty=endofline^1/""
-local normalempty=endofline^1
-local singleempty=endofline*(endofline^0/"")
-local doubleempty=endofline*endofline^-1*(endofline^0/"")
-local stripstart=stripempty^0
-local intospace=whitespace^1/" "
-local noleading=whitespace^1/""
-local notrailing=noleading*endofstring
-local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
-local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
-local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
-local p_retain_normal=Cs ((normalline+normalempty )^0 )
-local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
-local p_retain_noempty=Cs ((normalline+singleempty )^0 )
-local striplinepatterns={
- ["prune"]=p_prune_normal,
- ["prune and collapse"]=p_prune_collapse,
- ["prune and no empty"]=p_prune_noempty,
- ["prune and to space"]=p_prune_intospace,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
-}
-setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
-strings.striplinepatterns=striplinepatterns
-function strings.striplines(str,how)
- return str and lpegmatch(striplinepatterns[how],str) or str
-end
-function strings.collapse(str)
- return str and lpegmatch(p_prune_intospace,str) or str
-end
-strings.striplong=strings.striplines
-function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return str
-end
-local n=0
-local sequenced=table.sequenced
-function string.autodouble(s,sep)
- if s==nil then
- return '""'
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ('"'..sequenced(s,sep or ",")..'"')
- end
- return ('"'..tostring(s)..'"')
-end
-function string.autosingle(s,sep)
- if s==nil then
- return "''"
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ("'"..sequenced(s,sep or ",").."'")
- end
- return ("'"..tostring(s).."'")
-end
-local tracedchars={ [0]=
- "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
- "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
- "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
- "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
- "[space]",
-}
-string.tracedchars=tracedchars
-strings.tracers=tracedchars
-function string.tracedchar(b)
- if type(b)=="number" then
- return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
- else
- local c=utfbyte(b)
- return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
- end
-end
-function number.signed(i)
- if i>0 then
- return "+",i
- else
- return "-",-i
- end
-end
-local two=digit*digit
-local three=two*digit
-local prefix=(Carg(1)*three)^1
-local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
-)
-local splitter3=Cs (
- three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
-)
-patterns.formattednumber=splitter
-function number.formatted(n,sep1,sep2)
- if sep1==false then
- if type(n)=="number" then
- n=tostring(n)
- end
- return lpegmatch(splitter3,n,1,sep2 or ".")
- else
- if type(n)=="number" then
- n=format("%0.2f",n)
- end
- if sep1==true then
- return lpegmatch(splitter,n,1,".",",")
- elseif sep1=="." then
- return lpegmatch(splitter,n,1,sep1,sep2 or ",")
- elseif sep1=="," then
- return lpegmatch(splitter,n,1,sep1,sep2 or ".")
- else
- return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
- end
- end
-end
-local p=Cs(
- P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
- )
-function number.compactfloat(n,fmt)
- if n==0 then
- return "0"
- elseif n==1 then
- return "1"
- end
- n=lpegmatch(p,format(fmt or "%0.3f",n))
- if n=="." or n=="" or n=="-" then
- return "0"
- end
- return n
-end
-local zero=P("0")^1/""
-local plus=P("+")/""
-local minus=P("-")
-local separator=period
-local trailing=zero^1*#S("eE")
-local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(endofstring*Cc("0")+anything^1))
-local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
-local pattern_b=Cs((exponent+anything)^0)
-function number.sparseexponent(f,n)
- if not n then
- n=f
- f="%e"
- end
- local tn=type(n)
- if tn=="string" then
- local m=tonumber(n)
- if m then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
- end
- elseif tn=="number" then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
- end
- return tostring(n)
-end
-local hf={}
-local hs={}
-setmetatable(hf,{ __index=function(t,k)
- local v="%."..k.."f"
- t[k]=v
- return v
-end } )
-setmetatable(hs,{ __index=function(t,k)
- local v="%"..k.."s"
- t[k]=v
- return v
-end } )
-function number.formattedfloat(n,b,a)
- local s=format(hf[a],n)
- local l=(b or 0)+(a or 0)+1
- if #s<l then
- return format(hs[l],s)
- else
- return s
- end
-end
-local template=[[
-%s
-%s
-return function(%s) return %s end
-]]
-local pattern=Cs(Cc('"')*(
- (1-S('"\\\n\r'))^1+P('"')/'\\"'+P('\\')/'\\\\'+P('\n')/'\\n'+P('\r')/'\\r'
-)^0*Cc('"'))
-patterns.escapedquotes=pattern
-function string.escapedquotes(s)
- return lpegmatch(pattern,s)
-end
-local preamble=""
-local environment={
- global=global or _G,
- lpeg=lpeg,
- type=type,
- tostring=tostring,
- tonumber=tonumber,
- format=string.format,
- concat=table.concat,
- signed=number.signed,
- points=number.points,
- basepoints=number.basepoints,
- utfchar=utf.char,
- utfbyte=utf.byte,
- lpegmatch=lpeg.match,
- nspaces=string.nspaces,
- utfpadding=string.utfpadding,
- tracedchar=string.tracedchar,
- autosingle=string.autosingle,
- autodouble=string.autodouble,
- sequenced=table.sequenced,
- formattednumber=number.formatted,
- sparseexponent=number.sparseexponent,
- formattedfloat=number.formattedfloat,
- stripzero=patterns.stripzero,
- stripzeros=patterns.stripzeros,
- escapedquotes=string.escapedquotes,
- FORMAT=string.f6,
-}
-local arguments={ "a1" }
-setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
-})
-local prefix_any=C((sign+space+period+digit)^0)
-local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
-local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
-local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
-end
-local format_S=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',tostring(a%s))",f,n)
- else
- return format("tostring(a%s)",n)
- end
-end
-local format_right=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- elseif f>0 then
- return format("utfpadding(a%s,%i)..a%s",n,f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,f)
- end
-end
-local format_left=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- end
- if f<0 then
- return format("utfpadding(a%s,%i)..a%s",n,-f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,-f)
- end
-end
-local format_q=JITSUPPORTED and function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
-end or function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
-end
-local format_Q=function()
- n=n+1
- return format("escapedquotes(tostring(a%s))",n)
-end
-local format_i=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%si',a%s)",f,n)
- else
- return format("format('%%i',a%s)",n)
- end
-end
-local format_d=format_i
-local format_I=function(f)
- n=n+1
- return format("format('%%s%%%si',signed(a%s))",f,n)
-end
-local format_f=function(f)
- n=n+1
- return format("format('%%%sf',a%s)",f,n)
-end
-local format_F=function(f)
- n=n+1
- if not f or f=="" then
- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
- else
- return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
- end
-end
-local format_k=function(b,a)
- n=n+1
- return format("formattedfloat(a%s,%s,%s)",n,b or 0,a or 0)
-end
-local format_g=function(f)
- n=n+1
- return format("format('%%%sg',a%s)",f,n)
-end
-local format_G=function(f)
- n=n+1
- return format("format('%%%sG',a%s)",f,n)
-end
-local format_e=function(f)
- n=n+1
- return format("format('%%%se',a%s)",f,n)
-end
-local format_E=function(f)
- n=n+1
- return format("format('%%%sE',a%s)",f,n)
-end
-local format_j=function(f)
- n=n+1
- return format("sparseexponent('%%%se',a%s)",f,n)
-end
-local format_J=function(f)
- n=n+1
- return format("sparseexponent('%%%sE',a%s)",f,n)
-end
-local format_x=function(f)
- n=n+1
- return format("format('%%%sx',a%s)",f,n)
-end
-local format_X=function(f)
- n=n+1
- return format("format('%%%sX',a%s)",f,n)
-end
-local format_o=function(f)
- n=n+1
- return format("format('%%%so',a%s)",f,n)
-end
-local format_c=function()
- n=n+1
- return format("utfchar(a%s)",n)
-end
-local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
-end
-local format_r=function(f)
- n=n+1
- return format("format('%%%s.0f',a%s)",f,n)
-end
-local format_h=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
-end
-local format_H=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
-end
-local format_u=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
-end
-local format_U=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
-end
-local format_p=function()
- n=n+1
- return format("points(a%s)",n)
-end
-local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
-end
-local format_t=function(f)
- n=n+1
- if f and f~="" then
- return format("concat(a%s,%q)",n,f)
- else
- return format("concat(a%s)",n)
- end
-end
-local format_T=function(f)
- n=n+1
- if f and f~="" then
- return format("sequenced(a%s,%q)",n,f)
- else
- return format("sequenced(a%s)",n)
- end
-end
-local format_l=function()
- n=n+1
- return format("(a%s and 'true' or 'false')",n)
-end
-local format_L=function()
- n=n+1
- return format("(a%s and 'TRUE' or 'FALSE')",n)
-end
-local format_n=function()
- n=n+1
- return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
-end
-local format_N if environment.FORMAT then
- format_N=function(f)
- n=n+1
- if not f or f=="" then
- return format("FORMAT(a%s,'%%.9f')",n)
- elseif f==".6" or f=="0.6" then
- return format("FORMAT(a%s)",n)
- else
- return format("FORMAT(a%s,'%%%sf')",n,f)
- end
- end
-else
- format_N=function(f)
- n=n+1
- if not f or f=="" then
- f=".9"
- end
- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
- end
-end
-local format_a=function(f)
- n=n+1
- if f and f~="" then
- return format("autosingle(a%s,%q)",n,f)
- else
- return format("autosingle(a%s)",n)
- end
-end
-local format_A=function(f)
- n=n+1
- if f and f~="" then
- return format("autodouble(a%s,%q)",n,f)
- else
- return format("autodouble(a%s)",n)
- end
-end
-local format_w=function(f)
- n=n+1
- f=tonumber(f)
- if f then
- return format("nspaces[%s+a%s]",f,n)
- else
- return format("nspaces[a%s]",n)
- end
-end
-local format_W=function(f)
- return format("nspaces[%s]",tonumber(f) or 0)
-end
-local format_m=function(f)
- n=n+1
- if not f or f=="" then
- f=","
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,".")]],n,f)
- end
-end
-local format_M=function(f)
- n=n+1
- if not f or f=="" then
- f="."
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,",")]],n,f)
- end
-end
-local format_z=function(f)
- n=n+(tonumber(f) or 1)
- return "''"
-end
-local format_rest=function(s)
- return format("%q",s)
-end
-local format_extension=function(extensions,f,name)
- local extension=extensions[name] or "tostring(%s)"
- local f=tonumber(f) or 1
- local w=find(extension,"%.%.%.")
- if w then
- if f==0 then
- extension=gsub(extension,"%.%.%.","")
- return extension
- elseif f==1 then
- extension=gsub(extension,"%.%.%.","%%s")
- n=n+1
- local a="a"..n
- return format(extension,a,a)
- elseif f<0 then
- local a="a"..(n+f+1)
- return format(extension,a,a)
- else
- extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- local t={}
- for i=1,f do
- n=n+1
- t[i]="a"..n
- end
- return format(extension,unpack(t))
- end
- else
- extension=gsub(extension,"%%s",function()
- n=n+1
- return "a"..n
- end)
- return extension
- end
-end
-local builder=Cs { "start",
- start=(
- (
- P("%")/""*(
- V("!")
-+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
-+V("c")+V("C")+V("S")
-+V("Q")
-+V("n")
-+V("N")
-+V("k")
-+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
-+V("W")
-+V("a")
-+V("A")
-+V("j")+V("J")
-+V("m")+V("M")
-+V("z")
-+V(">")
-+V("<")
- )+V("*")
- )*(endofstring+Carg(1))
- )^0,
- ["s"]=(prefix_any*P("s"))/format_s,
- ["q"]=(prefix_any*P("q"))/format_q,
- ["i"]=(prefix_any*P("i"))/format_i,
- ["d"]=(prefix_any*P("d"))/format_d,
- ["f"]=(prefix_any*P("f"))/format_f,
- ["F"]=(prefix_any*P("F"))/format_F,
- ["g"]=(prefix_any*P("g"))/format_g,
- ["G"]=(prefix_any*P("G"))/format_G,
- ["e"]=(prefix_any*P("e"))/format_e,
- ["E"]=(prefix_any*P("E"))/format_E,
- ["x"]=(prefix_any*P("x"))/format_x,
- ["X"]=(prefix_any*P("X"))/format_X,
- ["o"]=(prefix_any*P("o"))/format_o,
- ["S"]=(prefix_any*P("S"))/format_S,
- ["Q"]=(prefix_any*P("Q"))/format_Q,
- ["n"]=(prefix_any*P("n"))/format_n,
- ["N"]=(prefix_any*P("N"))/format_N,
- ["k"]=(prefix_sub*P("k"))/format_k,
- ["c"]=(prefix_any*P("c"))/format_c,
- ["C"]=(prefix_any*P("C"))/format_C,
- ["r"]=(prefix_any*P("r"))/format_r,
- ["h"]=(prefix_any*P("h"))/format_h,
- ["H"]=(prefix_any*P("H"))/format_H,
- ["u"]=(prefix_any*P("u"))/format_u,
- ["U"]=(prefix_any*P("U"))/format_U,
- ["p"]=(prefix_any*P("p"))/format_p,
- ["b"]=(prefix_any*P("b"))/format_b,
- ["t"]=(prefix_tab*P("t"))/format_t,
- ["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
- ["I"]=(prefix_any*P("I"))/format_I,
- ["w"]=(prefix_any*P("w"))/format_w,
- ["W"]=(prefix_any*P("W"))/format_W,
- ["j"]=(prefix_any*P("j"))/format_j,
- ["J"]=(prefix_any*P("J"))/format_J,
- ["m"]=(prefix_any*P("m"))/format_m,
- ["M"]=(prefix_any*P("M"))/format_M,
- ["z"]=(prefix_any*P("z"))/format_z,
- ["a"]=(prefix_any*P("a"))/format_a,
- ["A"]=(prefix_any*P("A"))/format_A,
- ["<"]=(prefix_any*P("<"))/format_left,
- [">"]=(prefix_any*P(">"))/format_right,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
- ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
- ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
-}
-local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
-local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
-local preset={
- ["%02x"]=function(n) return xx[n] end,
- ["%02X"]=function(n) return XX[n] end,
-}
-local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
-local function make(t,str)
- local f=preset[str]
- if f then
- return f
- end
- local p=lpegmatch(direct,str)
- if p then
- f=loadstripped(p)()
- else
- n=0
- p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
- if n>0 then
- p=format(template,preamble,t._preamble_,arguments[n],p)
- f=loadstripped(p,t._environment_)()
- else
- f=function() return str end
- end
- end
- t[str]=f
- return f
-end
-local function use(t,fmt,...)
- return t[fmt](...)
-end
-strings.formatters={}
-function strings.formatters.new(noconcat)
- local e={}
- for k,v in next,environment do
- e[k]=v
- end
- local t={
- _type_="formatter",
- _connector_=noconcat and "," or "..",
- _extensions_={},
- _preamble_="",
- _environment_=e,
- }
- setmetatable(t,{ __index=make,__call=use })
- return t
-end
-local formatters=strings.formatters.new()
-string.formatters=formatters
-string.formatter=function(str,...) return formatters[str](...) end
-local function add(t,name,template,preamble)
- if type(t)=="table" and t._type_=="formatter" then
- t._extensions_[name]=template or "%s"
- if type(preamble)=="string" then
- t._preamble_=preamble.."\n"..t._preamble_
- elseif type(preamble)=="table" then
- for k,v in next,preamble do
- t._environment_[k]=v
- end
- end
- end
-end
-strings.formatters.add=add
-patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
-patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
-patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
-add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=patterns.xmlescape })
-add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=patterns.texescape })
-add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=patterns.luaescape })
-local dquote=patterns.dquote
-local equote=patterns.escaped+dquote/'\\"'+1
-local cquote=Cc('"')
-local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
-+Cs(cquote*(equote-space)^0*space*equote^0*cquote)
-function string.optionalquoted(str)
- return lpegmatch(pattern,str) or str
-end
-local pattern=Cs((newline/(os.newline or "\r")+1)^0)
-function string.replacenewlines(str)
- return lpegmatch(pattern,str)
-end
-function strings.newcollector()
- local result,r={},0
- return
- function(fmt,str,...)
- r=r+1
- result[r]=str==nil and fmt or formatters[fmt](str,...)
- end,
- function(connector)
- if result then
- local str=concat(result,connector)
- result,r={},0
- return str
- end
- end
-end
-local f_16_16=formatters["%0.5N"]
-function number.to16dot16(n)
- return f_16_16(n/65536.0)
-end
-if not string.explode then
- local tsplitat=lpeg.tsplitat
- local p_utf=patterns.utf8character
- local p_check=C(p_utf)*(P("+")*Cc(true))^0
- local p_split=Ct(C(p_utf)^0)
- local p_space=Ct((C(1-P(" ")^1)+P(" ")^1)^0)
- function string.explode(str,symbol)
- if symbol=="" then
- return lpegmatch(p_split,str)
- elseif symbol then
- local a,b=lpegmatch(p_check,symbol)
- if b then
- return lpegmatch(tsplitat(P(a)^1),str)
- else
- return lpegmatch(tsplitat(a),str)
- end
- else
- return lpegmatch(p_space,str)
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-tab"] = package.loaded["util-tab"] or true
-
--- original size: 32649, stripped down to: 18257
-
-if not modules then modules={} end modules ['util-tab']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-utilities=utilities or {}
-utilities.tables=utilities.tables or {}
-local tables=utilities.tables
-local format,gmatch,gsub,sub=string.format,string.gmatch,string.gsub,string.sub
-local concat,insert,remove,sort=table.concat,table.insert,table.remove,table.sort
-local setmetatable,getmetatable,tonumber,tostring,rawget=setmetatable,getmetatable,tonumber,tostring,rawget
-local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select
-local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc
-local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs
-local formatters=string.formatters
-local utftoeight=utf.toeight
-local splitter=lpeg.tsplitat(".")
-function utilities.tables.definetable(target,nofirst,nolast)
- local composed=nil
- local t={}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
- if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
- else
- return "",target
- end
-end
-function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
-end
-function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
- end
- return t
-end
-function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
- end
- t[names[#names]]=v
-end
-function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
- end
-end
-function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
- end
-end
-function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
- end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
- end
- insert(t,1,extra)
-end
-function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
- end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
- end
- insert(t,#t+1,extra)
-end
-local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
-function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
- end
- return concat(result,"\n")
- else
- return ""
- end
-end
-local nspaces=utilities.strings.newrepeater(" ")
-local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
- end
-end
-function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
-end
-function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
- for key,value in next,core do
- if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
- else
- capsule[key]=value
- end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
-end
-if JITSUPPORTED then
- local f_hashed_string=formatters["[%Q]=%Q,"]
- local f_hashed_number=formatters["[%Q]=%s,"]
- local f_hashed_boolean=formatters["[%Q]=%l,"]
- local f_hashed_table=formatters["[%Q]="]
- local f_indexed_string=formatters["[%s]=%Q,"]
- local f_indexed_number=formatters["[%s]=%s,"]
- local f_indexed_boolean=formatters["[%s]=%l,"]
- local f_indexed_table=formatters["[%s]="]
- local f_ordered_string=formatters["%Q,"]
- local f_ordered_number=formatters["%s,"]
- local f_ordered_boolean=formatters["%l,"]
- function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- local v=t[0]
- if v then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(0,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(0,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(0)
- fastserialize(v)
- m=m+1 r[m]=f_indexed_table(0)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(0,v)
- end
- end
- for i=1,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
- end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
- end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
- end
- return r
- end
- return concat(fastserialize(t,true))
- end
-else
- local f_v=formatters["[%q]=%q,"]
- local f_t=formatters["[%q]="]
- local f_q=formatters["%q,"]
- function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- local v=t[0]
- if v then
- m=m+1
- r[m]="[0]='"
- if type(v)=="table" then
- fastserialize(v)
- else
- r[m]=format("%q,",v)
- end
- end
- for i=1,n do
- local v=t[i]
- m=m+1
- if type(v)=="table" then
- r[m]=format("[%i]=",i)
- fastserialize(v)
- else
- r[m]=format("[%i]=%q,",i,v)
- end
- end
- end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- m=m+1
- if type(v)=="table" then
- r[m]=format("[%i]=",k)
- fastserialize(v)
- else
- r[m]=format("[%i]=%q,",k,v)
- end
- end
- else
- m=m+1
- if type(v)=="table" then
- r[m]=format("[%q]=",k)
- fastserialize(v)
- else
- r[m]=format("[%q]=%q,",k,v)
- end
- end
- end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
- end
- return r
- end
- return concat(fastserialize(t,true))
- end
-end
-function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
-end
-function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
- end
- end
-end
-function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
-end
-local f_key_value=formatters["%s=%q"]
-local f_add_table=formatters[" {%t},\n"]
-local f_return_table=formatters["return {\n%t}"]
-local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
-end
-local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
-end
-function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
-end
-local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
- end
- setmetatable(t,selfmapper)
- return t
-end
-local f_start_key_idx=formatters["%w{"]
-local f_start_key_num=JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
-local f_start_key_str=formatters["%w[%q]={"]
-local f_start_key_boo=formatters["%w[%l]={"]
-local f_start_key_nop=formatters["%w{"]
-local f_stop=formatters["%w},"]
-local f_key_num_value_num=JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
-local f_key_str_value_num=JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
-local f_key_boo_value_num=JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
-local f_key_num_value_str=JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
-local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
-local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo=JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
-local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
-local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
-local f_key_num_value_not=JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
-local f_key_str_value_not=formatters["%w[%Q]={},"]
-local f_key_boo_value_not=formatters["%w[%l]={},"]
-local f_key_num_value_seq=JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
-local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
-local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
-local f_val_num=JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
-local f_val_str=formatters["%w%Q,"]
-local f_val_boo=formatters["%w%l,"]
-local f_val_not=formatters["%w{},"]
-local f_val_seq=formatters["%w{ %, t },"]
-local f_fin_seq=formatters[" %, t }"]
-local f_table_return=formatters["return {"]
-local f_table_name=formatters["%s={"]
-local f_table_direct=formatters["{"]
-local f_table_entry=formatters["[%Q]={"]
-local f_table_finish=formatters["}"]
-local spaces=utilities.strings.newrepeater(" ")
-local original_serialize=table.serialize
-local is_simple_table=table.is_simple_table
-local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
- else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=#root
- if last>0 then
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
- end
- if last>0 then
- first=1
- end
- end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
- end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
- else
- t={ f_table_direct() }
- end
- else
- t={ f_table_name("t") }
- end
- if root then
- if getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
- end
- if next(root)~=nil then
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
- end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
-end
-table.serialize=serialize
-if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
-end
-local mt={
- __newindex=function(t,k,v)
- local n=t.last+1
- t.last=n
- t.list[n]=k
- t.hash[k]=v
- end,
- __index=function(t,k)
- return t.hash[k]
- end,
- __len=function(t)
- return t.last
- end,
-}
-function table.orderedhash()
- return setmetatable({ list={},hash={},last=0 },mt)
-end
-function table.ordered(t)
- local n=t.last
- if n>0 then
- local l=t.list
- local i=1
- local h=t.hash
- local f=function()
- if i<=n then
- local k=i
- local v=h[l[k]]
- i=i+1
- return k,v
- end
- end
- return f,1,h[l[1]]
- else
- return function() end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-fil"] = package.loaded["util-fil"] or true
-
--- original size: 11530, stripped down to: 9007
-
-if not modules then modules={} end modules ['util-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local tonumber=tonumber
-local byte=string.byte
-local char=string.char
-utilities=utilities or {}
-local files={}
-utilities.files=files
-local zerobased={}
-function files.open(filename,zb)
- local f=io.open(filename,"rb")
- if f then
- zerobased[f]=zb or false
- end
- return f
-end
-function files.close(f)
- zerobased[f]=nil
- f:close()
-end
-function files.size(f)
- local current=f:seek()
- local size=f:seek("end")
- f:seek("set",current)
- return size
-end
-files.getsize=files.size
-function files.setposition(f,n)
- if zerobased[f] then
- f:seek("set",n)
- else
- f:seek("set",n-1)
- end
-end
-function files.getposition(f)
- if zerobased[f] then
- return f:seek()
- else
- return f:seek()+1
- end
-end
-function files.look(f,n,chars)
- local p=f:seek()
- local s=f:read(n)
- f:seek("set",p)
- if chars then
- return s
- else
- return byte(s,1,#s)
- end
-end
-function files.skip(f,n)
- if n==1 then
- f:read(n)
- else
- f:seek("set",f:seek()+n)
- end
-end
-function files.readbyte(f)
- return byte(f:read(1))
-end
-function files.readbytes(f,n)
- return byte(f:read(n),1,n)
-end
-function files.readbytetable(f,n)
- local s=f:read(n or 1)
- return { byte(s,1,#s) }
-end
-function files.readchar(f)
- return f:read(1)
-end
-function files.readstring(f,n)
- return f:read(n or 1)
-end
-function files.readinteger1(f)
- local n=byte(f:read(1))
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
-end
-files.readcardinal1=files.readbyte
-files.readcardinal=files.readcardinal1
-files.readinteger=files.readinteger1
-files.readsignedbyte=files.readinteger1
-function files.readcardinal2(f)
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
-end
-function files.readcardinal2le(f)
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
-end
-function files.readinteger2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
-end
-function files.readinteger2le(f)
- local b,a=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
-end
-function files.readcardinal3(f)
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
-end
-function files.readcardinal3le(f)
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
-end
-function files.readinteger3(f)
- local a,b,c=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
-end
-function files.readinteger3le(f)
- local c,b,a=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
-end
-function files.readcardinal4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
-end
-function files.readcardinal4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
-end
-function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
-end
-function files.readinteger4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
-end
-function files.readfixed2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
-end
-function files.readfixed4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
-end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function files.read2dot14(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
- end
-end
-function files.skipshort(f,n)
- f:read(2*(n or 1))
-end
-function files.skiplong(f,n)
- f:read(4*(n or 1))
-end
-if bit32 then
- local rshift=bit32.rshift
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- f:write(b,a)
- end
- function files.writecardinal4(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(d,c,b,a)
- end
- function files.writecardinal2le(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- f:write(a,b)
- end
- function files.writecardinal4le(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(a,b,c,d)
- end
-else
- local floor=math.floor
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- f:write(b,a)
- end
- function files.writecardinal4(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- n=floor(n/256)
- local c=char(n%256)
- n=floor(n/256)
- local d=char(n%256)
- f:write(d,c,b,a)
- end
- function files.writecardinal2le(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- f:write(a,b)
- end
- function files.writecardinal4le(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- n=floor(n/256)
- local c=char(n%256)
- n=floor(n/256)
- local d=char(n%256)
- f:write(a,b,c,d)
- end
-end
-function files.writestring(f,s)
- f:write(char(byte(s,1,#s)))
-end
-function files.writebyte(f,b)
- f:write(char(b))
-end
-if fio and fio.readcardinal1 then
- files.readcardinal1=fio.readcardinal1
- files.readcardinal2=fio.readcardinal2
- files.readcardinal3=fio.readcardinal3
- files.readcardinal4=fio.readcardinal4
- files.readcardinal1le=fio.readcardinal1le or files.readcardinal1le
- files.readcardinal2le=fio.readcardinal2le or files.readcardinal2le
- files.readcardinal3le=fio.readcardinal3le or files.readcardinal3le
- files.readcardinal4le=fio.readcardinal4le or files.readcardinal4le
- files.readinteger1=fio.readinteger1
- files.readinteger2=fio.readinteger2
- files.readinteger3=fio.readinteger3
- files.readinteger4=fio.readinteger4
- files.readinteger1le=fio.readinteger1le or files.readinteger1le
- files.readinteger2le=fio.readinteger2le or files.readinteger2le
- files.readinteger3le=fio.readinteger3le or files.readinteger3le
- files.readinteger4le=fio.readinteger4le or files.readinteger4le
- files.readfixed2=fio.readfixed2
- files.readfixed4=fio.readfixed4
- files.read2dot14=fio.read2dot14
- files.setposition=fio.setposition
- files.getposition=fio.getposition
- files.readbyte=files.readcardinal1
- files.readsignedbyte=files.readinteger1
- files.readcardinal=files.readcardinal1
- files.readinteger=files.readinteger1
- local skipposition=fio.skipposition
- files.skipposition=skipposition
- files.readbytes=fio.readbytes
- files.readbytetable=fio.readbytetable
- function files.skipshort(f,n)
- skipposition(f,2*(n or 1))
- end
- function files.skiplong(f,n)
- skipposition(f,4*(n or 1))
- end
-end
-if fio and fio.writecardinal1 then
- files.writecardinal1=fio.writecardinal1
- files.writecardinal2=fio.writecardinal2
- files.writecardinal3=fio.writecardinal3
- files.writecardinal4=fio.writecardinal4
- files.writecardinal1le=fio.writecardinal1le
- files.writecardinal2le=fio.writecardinal2le
- files.writecardinal3le=fio.writecardinal3le
- files.writecardinal4le=fio.writecardinal4le
- files.writeinteger1=fio.writeinteger1 or fio.writecardinal1
- files.writeinteger2=fio.writeinteger2 or fio.writecardinal2
- files.writeinteger3=fio.writeinteger3 or fio.writecardinal3
- files.writeinteger4=fio.writeinteger4 or fio.writecardinal4
- files.writeinteger1le=files.writeinteger1le or fio.writecardinal1le
- files.writeinteger2le=files.writeinteger2le or fio.writecardinal2le
- files.writeinteger3le=files.writeinteger3le or fio.writecardinal3le
- files.writeinteger4le=files.writeinteger4le or fio.writecardinal4le
-end
-if fio and fio.readcardinaltable then
- files.readcardinaltable=fio.readcardinaltable
- files.readintegertable=fio.readintegertable
-else
- local readcardinal1=files.readcardinal1
- local readcardinal2=files.readcardinal2
- local readcardinal3=files.readcardinal3
- local readcardinal4=files.readcardinal4
- function files.readcardinaltable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
- return t
- end
- local readinteger1=files.readinteger1
- local readinteger2=files.readinteger2
- local readinteger3=files.readinteger3
- local readinteger4=files.readinteger4
- function files.readintegertable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
- return t
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-sac"] = package.loaded["util-sac"] or true
-
--- original size: 12946, stripped down to: 9507
-
-if not modules then modules={} end modules ['util-sac']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local byte,sub=string.byte,string.sub
-local tonumber=tonumber
-utilities=utilities or {}
-local streams={}
-utilities.streams=streams
-function streams.open(filename,zerobased)
- local f=filename and io.loaddata(filename)
- if f then
- return { f,1,#f,zerobased or false }
- end
-end
-function streams.openstring(f,zerobased)
- if f then
- return { f,1,#f,zerobased or false }
- end
-end
-function streams.getstring(f)
- if f then
- return f[1]
- end
-end
-function streams.close()
-end
-function streams.size(f)
- return f and f[3] or 0
-end
-streams.getsize=streams.size
-function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
- else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
- end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
- else
- return f[2]
- end
-end
-function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
-end
-function streams.skip(f,n)
- f[2]=f[2]+n
-end
-function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
-end
-function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
-end
-function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
-end
-function streams.skipbytes(f,n)
- f[2]=f[2]+n
-end
-function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
-end
-function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
-end
-streams.readcardinal1=streams.readbyte
-streams.readcardinal=streams.readcardinal1
-streams.readinteger=streams.readinteger1
-function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
-end
-function streams.readcardinal2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
-end
-function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
-end
-function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
-end
-function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
-end
-function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
-end
-function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
-end
-function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
-end
-function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
-end
-function streams.readcardinal4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
-end
-function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
-end
-function streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
-end
-function streams.readfixed2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return tonumber((a-0x100).."."..b) or 0
- else
- return tonumber((a ).."."..b) or 0
- end
-end
-function streams.readfixed4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return tonumber((0x100*a+b-0x10000).."."..(0x100*c+d)) or 0
- else
- return tonumber((0x100*a+b ).."."..(0x100*c+d)) or 0
- end
-end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
- end
-end
-function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
-end
-function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
-end
-if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.readfixed2(f)
- local i=f[2]
- f[2]=i+2
- return readfixed2(f[1],i)
- end
- function streams.readfixed4(f)
- local i=f[2]
- f[2]=i+4
- return readfixed4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
- end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
- end
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
-end
-if sio and sio.readcardinaltable then
- local readcardinaltable=sio.readcardinaltable
- local readintegertable=sio.readintegertable
- function utilities.streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readcardinaltable(f[1],i,n,b)
- end
- function utilities.streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readintegertable(f[1],i,n,b)
- end
-else
- local readcardinal1=streams.readcardinal1
- local readcardinal2=streams.readcardinal2
- local readcardinal3=streams.readcardinal3
- local readcardinal4=streams.readcardinal4
- function streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
- return t
- end
- local readinteger1=streams.readinteger1
- local readinteger2=streams.readinteger2
- local readinteger3=streams.readinteger3
- local readinteger4=streams.readinteger4
- function streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
- return t
- end
-end
-do
- local files=utilities.files
- if files then
- local openfile=files.open
- local openstream=streams.open
- local openstring=streams.openstring
- local setmetatable=setmetatable
- function io.newreader(str,method)
- local f,m
- if method=="string" then
- f=openstring(str)
- m=streams
- elseif method=="stream" then
- f=openstream(str)
- m=streams
- else
- f=openfile(str,"rb")
- m=files
- end
- if f then
- local t={}
- setmetatable(t,{
- __index=function(t,k)
- local r=m[k]
- if k=="close" then
- if f then
- m.close(f)
- f=nil
- end
- return function() end
- elseif r then
- local v=function(_,a,b) return r(f,a,b) end
- t[k]=v
- return v
- else
- print("unknown key",k)
- end
- end
- } )
- return t
- end
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-sto"] = package.loaded["util-sto"] or true
-
--- original size: 6661, stripped down to: 3074
-
-if not modules then modules={} end modules ['util-sto']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
-utilities=utilities or {}
-utilities.storage=utilities.storage or {}
-local storage=utilities.storage
-function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
-end
-function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
-end
-function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
-end
-function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
-end
-function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
-end
-local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
-end }
-function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
-local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
-}
-function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
-end
-local f_index={
- ["ignore"]=f_ignore,
-}
-function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
-end
-function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
-end
-function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
-end
-function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
-end
-function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
-end
-function table.makeweak(t)
- if not t then
- t={}
- end
- local m=getmetatable(t)
- if m then
- m.__mode="v"
- else
- setmetatable(t,{ __mode="v" })
- end
- return t
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-prs"] = package.loaded["util-prs"] or true
-
--- original size: 24132, stripped down to: 16210
-
-if not modules then modules={} end modules ['util-prs']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local lpeg,table,string=lpeg,table,string
-local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
-local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
-local concat,gmatch,find=table.concat,string.gmatch,string.find
-local tostring,type,next,rawset=tostring,type,next,rawset
-local mod,div=math.mod,math.div
-utilities=utilities or {}
-local parsers=utilities.parsers or {}
-utilities.parsers=parsers
-local patterns=parsers.patterns or {}
-parsers.patterns=patterns
-local setmetatableindex=table.setmetatableindex
-local sortedhash=table.sortedhash
-local sortedkeys=table.sortedkeys
-local tohash=table.tohash
-local hashes={}
-parsers.hashes=hashes
-local digit=R("09")
-local space=P(' ')
-local equal=P("=")
-local colon=P(":")
-local comma=P(",")
-local lbrace=P("{")
-local rbrace=P("}")
-local lparent=P("(")
-local rparent=P(")")
-local lbracket=P("[")
-local rbracket=P("]")
-local period=S(".")
-local punctuation=S(".,:;")
-local spacer=lpegpatterns.spacer
-local whitespace=lpegpatterns.whitespace
-local newline=lpegpatterns.newline
-local anything=lpegpatterns.anything
-local endofstring=lpegpatterns.endofstring
-local nobrace=1-(lbrace+rbrace )
-local noparent=1-(lparent+rparent)
-local nobracket=1-(lbracket+rbracket)
-local escape,left,right=P("\\"),P('{'),P('}')
-lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
-}
-local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
-local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
-local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
-local spaces=space^0
-local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
-local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
-lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
-lpegpatterns.argument=argument
-lpegpatterns.content=content
-local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
-local key=C((1-equal-comma)^1)
-local pattern_a=(space+comma)^0*(key*equal*value+key*C(""))
-local pattern_c=(space+comma)^0*(key*equal*value)
-local pattern_d=(space+comma)^0*(key*(equal+colon)*value+key*C(""))
-local key=C((1-space-equal-comma)^1)
-local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
-local hash={}
-local function set(key,value)
- hash[key]=value
-end
-local pattern_a_s=(pattern_a/set)^1
-local pattern_b_s=(pattern_b/set)^1
-local pattern_c_s=(pattern_c/set)^1
-local pattern_d_s=(pattern_d/set)^1
-patterns.settings_to_hash_a=pattern_a_s
-patterns.settings_to_hash_b=pattern_b_s
-patterns.settings_to_hash_c=pattern_c_s
-patterns.settings_to_hash_d=pattern_d_s
-function parsers.make_settings_to_hash_pattern(set,how)
- if how=="strict" then
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
-end
-function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
- end
-end
-function parsers.settings_to_hash_colon_too(str)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- else
- hash={}
- lpegmatch(pattern_d_s,str)
- return hash
- end
-end
-function parsers.settings_to_hash_tolerant(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
- end
-end
-function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
- end
-end
-local separator=comma*space^0
-local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
-local pattern=spaces*Ct(value*(separator*value)^0)
-patterns.settings_to_array=pattern
-function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
-end
-function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
-end
-local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
-local pattern=spaces*Ct(value*(separator*value)^0)
-function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
-end
-local cache_a={}
-local cache_b={}
-function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
- if withaction then
- local withvalue=Carg(1)*value/function(f,s) return f(s) end
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
-end
-local pattern_a=parsers.groupedsplitat(",",false)
-local pattern_b=parsers.groupedsplitat(",",true)
-function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
-end
-function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
-end
-local function set(t,v)
- t[#t+1]=v
-end
-local value=P(Carg(1)*value)/set
-local pattern=value*(separator*value)^0*Carg(1)
-function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
-end
-function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t={}
- local tn=0
- local s=sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
- end
- return concat(t,separator or ",")
- else
- return ""
- end
-end
-function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
-end
-local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
-function parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
-end
-hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
-end)
-getmetatable(hashes.settings_to_set).__mode="kv"
-function parsers.simple_hash_to_string(h,separator)
- local t={}
- local tn=0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
- end
- return concat(t,separator or ",")
-end
-local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
-local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
-local splitter=setting^1
-function parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
-end
-local splitter=lpeg.tsplitat(" ")
-function parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
-end
-local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
-local pattern_a=spaces*Ct(value*(separator*value)^0)
-local function repeater(n,str)
- if not n then
- return str
- else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t={}
- local tn=0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
- end
- end
-end
-local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
-local pattern_b=spaces*Ct(value*(separator*value)^0)
-function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
-end
-local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
-local pattern=Ct((space+value)^0)
-function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
-end
-function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
- end
- parsers.settings_to_hash(settings,sc)
-end
-function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
-end
-local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
-}
-lpegpatterns.splitthousands=pattern
-function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
-end
-local optionalwhitespace=whitespace^0
-lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
-lpegpatterns.sentences=Ct((optionalwhitespace*Cs((1-period)^0*period))^1)
-lpegpatterns.paragraphs=Ct((optionalwhitespace*Cs((whitespace^1*endofstring/""+1-(spacer^0*newline*newline))^1))^1)
-local dquote=P('"')
-local equal=P('=')
-local escape=P('\\')
-local separator=S(' ,')
-local key=C((1-equal)^1)
-local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
-local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
-function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
-end
-local defaultspecification={ separator=",",quote='"' }
-function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
- end
-end
-function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
-/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
-end
-local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
- end
-end
-local cardinal=lpegpatterns.cardinal/tonumber
-local spacers=lpegpatterns.spacer^0
-local endofstring=lpegpatterns.endofstring
-local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
-local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
-function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
-end
-local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
-local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
-patterns.unittotex=pattern
-function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
-end
-local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
-function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
-end
-local cache={}
-local spaces=lpegpatterns.space^0
-local dummy=function() end
-setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
-end)
-local commalistiterator=cache[","]
-function parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
- end
- end
-end
-local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
- end
-end
-local function fetch(t,name)
- return t[name] or {}
-end
-local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
-end
-local name=C((1-S(", "))^1)
-local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
-local merge=Cf(parser,process)
-function parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
-end
-function parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
-end
-local spacing=whitespace^0
-local apply=P("->")
-local method=C((1-apply)^1)
-local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
-local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
-function parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
-end
-local p_year=lpegpatterns.digit^4/tonumber
-local pattern=Cf(Ct("")*(
- (Cg(Cc("year")*p_year)*S("-/")*Cg(Cc("month")*cardinal)*S("-/")*Cg(Cc("day")*cardinal)
- )+(Cg(Cc("day")*cardinal)*S("-/")*Cg(Cc("month")*cardinal)*S("-/")*Cg(Cc("year")*p_year)
- )
- )*P(" ")*Cg(Cc("hour")*cardinal)*P(":")*Cg(Cc("min")*cardinal)*(P(":")*Cg(Cc("sec")*cardinal))^-1
-,rawset)
-lpegpatterns.splittime=pattern
-function parsers.totime(str)
- return lpegmatch(pattern,str)
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
-
--- original size: 2541, stripped down to: 1624
-
-if not modules then modules={} end modules ['util-fmt']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-utilities=utilities or {}
-utilities.formatters=utilities.formatters or {}
-local formatters=utilities.formatters
-local concat,format=table.concat,string.format
-local tostring,type=tostring,type
-local strip=string.strip
-local lpegmatch=lpeg.match
-local stripper=lpeg.patterns.stripzeros
-function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
-end
-function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
- end
- for i=1,#result do
- local r=result[i]
- for j=1,n do
- local rj=r[j]
- local tj=type(rj)
- if tj=="number" then
- numbers[j]=true
- rj=tostring(rj)
- elseif tj~="string" then
- rj=tostring(rj)
- r[j]=rj
- end
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
- end
- end
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
- end
- end
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
- end
- end
- return result
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true
-
--- original size: 374, stripped down to: 282
-
-local loaded=package.loaded
-loaded["socket"]=nil
-loaded["copas"]=nil
-loaded["ltn12"]=nil
-loaded["mbox"]=nil
-loaded["mime"]=nil
-loaded["socket.url"]=nil
-loaded["socket.headers"]=nil
-loaded["socket.tp"]=nil
-loaded["socket.http"]=nil
-loaded["socket.ftp"]=nil
-loaded["socket.smtp"]=nil
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
-
--- original size: 4905, stripped down to: 3562
-
-
-local type,tostring,setmetatable=type,tostring,setmetatable
-local min=math.min
-local format=string.format
-local socket=socket or package.loaded.socket or require("socket.core")
-local connect=socket.connect
-local tcp4=socket.tcp4
-local tcp6=socket.tcp6
-local getaddrinfo=socket.dns.getaddrinfo
-local defaulthost="0.0.0.0"
-local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("socket")
- report(fmt,first,...)
- elseif fmt then
- fmt="socket: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
- end
-end
-socket.report=report
-function socket.connect4(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet")
-end
-function socket.connect6(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet6")
-end
-function socket.bind(host,port,backlog)
- if host=="*" or host=="" then
- host=defaulthost
- end
- local addrinfo,err=getaddrinfo(host)
- if not addrinfo then
- return nil,err
- end
- for i=1,#addrinfo do
- local alt=addrinfo[i]
- local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
- if not sock then
- return nil,err or "unknown error"
- end
- sock:setoption("reuseaddr",true)
- local res,err=sock:bind(alt.addr,port)
- if res then
- res,err=sock:listen(backlog)
- if res then
- return sock
- else
- sock:close()
- end
- else
- sock:close()
- end
- end
- return nil,"invalid address"
-end
-socket.try=socket.newtry()
-function socket.choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local f=list[name or "nil"]
- if f then
- return f(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
- end
-end
-local sourcet={}
-local sinkt={}
-socket.sourcet=sourcet
-socket.sinkt=sinkt
-socket.BLOCKSIZE=2048
-sinkt["close-when-done"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- sock:close()
- return 1
- end
- end
- }
- )
-end
-sinkt["keep-open"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- return 1
- end
- end
- }
- )
-end
-sinkt["default"]=sinkt["keep-open"]
-socket.sink=socket.choose(sinkt)
-sourcet["by-length"]=function(sock,length)
- local blocksize=socket.BLOCKSIZE
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function()
- if length<=0 then
- return nil
- end
- local chunk,err=sock:receive(min(blocksize,length))
- if err then
- return nil,err
- end
- length=length-#chunk
- return chunk
- end
- }
- )
-end
-sourcet["until-closed"]=function(sock)
- local blocksize=socket.BLOCKSIZE
- local done=false
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- if done then
- return nil
- end
- local chunk,status,partial=sock:receive(blocksize)
- if not status then
- return chunk
- elseif status=="closed" then
- sock:close()
- done=true
- return partial
- else
- return nil,status
- end
- end
- }
- )
-end
-sourcet["default"]=sourcet["until-closed"]
-socket.source=socket.choose(sourcet)
-_G.socket=socket
-package.loaded["socket"]=socket
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
-
--- original size: 26186, stripped down to: 14893
-
-
-local socket=socket or require("socket")
-local ssl=ssl or nil
-local WATCH_DOG_TIMEOUT=120
-local UDP_DATAGRAM_MAX=8192
-local type,next,pcall,getmetatable,tostring=type,next,pcall,getmetatable,tostring
-local min,max,random=math.min,math.max,math.random
-local find=string.find
-local insert,remove=table.insert,table.remove
-local gettime=socket.gettime
-local selectsocket=socket.select
-local createcoroutine=coroutine.create
-local resumecoroutine=coroutine.resume
-local yieldcoroutine=coroutine.yield
-local runningcoroutine=coroutine.running
-local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("copas")
- report(fmt,first,...)
- elseif fmt then
- fmt="copas: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
- end
-end
-local copas={
- _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
- _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
- _VERSION="Copas 2.0.1",
- autoclose=true,
- running=false,
- report=report,
- trace=false,
-}
-local function statushandler(status,...)
- if status then
- return...
- end
- local err=(...)
- if type(err)=="table" then
- err=err[1]
- end
- if copas.trace then
- report("error: %s",tostring(err))
- end
- return nil,err
-end
-function socket.protect(func)
- return function(...)
- return statushandler(pcall(func,...))
- end
-end
-function socket.newtry(finalizer)
- return function (...)
- local status=(...)
- if not status then
- local detail=select(2,...)
- pcall(finalizer,detail)
- if copas.trace then
- report("error: %s",tostring(detail))
- end
- return
- end
- return...
- end
-end
-local function newset()
- local reverse={}
- local set={}
- local queue={}
- setmetatable(set,{
- __index={
- insert=function(set,value)
- if not reverse[value] then
- local n=#set+1
- set[n]=value
- reverse[value]=n
- end
- end,
- remove=function(set,value)
- local index=reverse[value]
- if index then
- reverse[value]=nil
- local n=#set
- local top=set[n]
- set[n]=nil
- if top~=value then
- reverse[top]=index
- set[index]=top
- end
- end
- end,
- push=function (set,key,itm)
- local entry=queue[key]
- if entry==nil then
- queue[key]={ itm }
- else
- entry[#entry+1]=itm
- end
- end,
- pop=function (set,key)
- local top=queue[key]
- if top~=nil then
- local ret=remove(top,1)
- if top[1]==nil then
- queue[key]=nil
- end
- return ret
- end
- end
- }
- } )
- return set
-end
-local _sleeping={
- times={},
- cos={},
- lethargy={},
- insert=function()
- end,
- remove=function()
- end,
- push=function(self,sleeptime,co)
- if not co then
- return
- end
- if sleeptime<0 then
- self.lethargy[co]=true
- return
- else
- sleeptime=gettime()+sleeptime
- end
- local t=self.times
- local c=self.cos
- local i=1
- local n=#t
- while i<=n and t[i]<=sleeptime do
- i=i+1
- end
- insert(t,i,sleeptime)
- insert(c,i,co)
- end,
- getnext=
- function(self)
- local t=self.times
- local delay=t[1] and t[1]-gettime() or nil
- return delay and max(delay,0) or nil
- end,
- pop=
- function(self,time)
- local t=self.times
- local c=self.cos
- if #t==0 or time<t[1] then
- return
- end
- local co=c[1]
- remove(t,1)
- remove(c,1)
- return co
- end,
- wakeup=function(self,co)
- local let=self.lethargy
- if let[co] then
- self:push(0,co)
- let[co]=nil
- else
- local c=self.cos
- local t=self.times
- for i=1,#c do
- if c[i]==co then
- remove(c,i)
- remove(t,i)
- self:push(0,co)
- return
- end
- end
- end
- end
-}
-local _servers=newset()
-local _reading=newset()
-local _writing=newset()
-local _reading_log={}
-local _writing_log={}
-local _is_timeout={
- timeout=true,
- wantread=true,
- wantwrite=true,
-}
-local function isTCP(socket)
- return not find(tostring(socket),"^udp")
-end
-local function copasreceive(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local current_log=_reading_log
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (not _is_timeout[err]) then
- current_log[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- current_log=_writing_log
- current_log[client]=gettime()
- yieldcoroutine(client,_writing)
- else
- current_log=_reading_log
- current_log[client]=gettime()
- yieldcoroutine(client,_reading)
- end
- until false
-end
-local function copasreceivefrom(client,size)
- local s,err,port
- if not size or size==0 then
- size=UDP_DATAGRAM_MAX
- end
- repeat
- s,err,port=client:receivefrom(size)
- if s or err~="timeout" then
- _reading_log[client]=nil
- return s,err,port
- end
- _reading_log[client]=gettime()
- yieldcoroutine(client,_reading)
- until false
-end
-local function copasreceivepartial(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local logger=_reading_log
- local queue=_reading
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
- logger[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- logger=_writing_log
- queue=_writing
- else
- logger=_reading_log
- queue=_reading
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
-end
-local function copassend(client,data,from,to)
- if not from then
- from=1
- end
- local lastIndex=from-1
- local logger=_writing_log
- local queue=_writing
- local s,err
- repeat
- s,err,lastIndex=client:send(data,lastIndex+1,to)
- if random(100)>90 then
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- end
- if s or not _is_timeout[err] then
- logger[client]=nil
- return s,err,lastIndex
- end
- if err=="wantread" then
- logger=_reading_log
- queue=_reading
- else
- logger=_writing_log
- queue=_writing
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
-end
-local function copassendto(client,data,ip,port)
- repeat
- local s,err=client:sendto(data,ip,port)
- if random(100)>90 then
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- end
- if s or err~="timeout" then
- _writing_log[client]=nil
- return s,err
- end
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- until false
-end
-local function copasconnect(skt,host,port)
- skt:settimeout(0)
- local ret,err,tried_more_than_once
- repeat
- ret,err=skt:connect (host,port)
- if ret or (err~="timeout" and err~="Operation already in progress") then
- if not ret and err=="already connected" and tried_more_than_once then
- ret=1
- err=nil
- end
- _writing_log[skt]=nil
- return ret,err
- end
- tried_more_than_once=tried_more_than_once or true
- _writing_log[skt]=gettime()
- yieldcoroutine(skt,_writing)
- until false
-end
-local function copasdohandshake(skt,sslt)
- if not ssl then
- ssl=require("ssl")
- end
- if not ssl then
- report("error: no ssl library")
- return
- end
- local nskt,err=ssl.wrap(skt,sslt)
- if not nskt then
- report("error: %s",tostring(err))
- return
- end
- nskt:settimeout(0)
- local queue
- repeat
- local success,err=nskt:dohandshake()
- if success then
- return nskt
- elseif err=="wantwrite" then
- queue=_writing
- elseif err=="wantread" then
- queue=_reading
- else
- report("error: %s",tostring(err))
- return
- end
- yieldcoroutine(nskt,queue)
- until false
-end
-local function copasflush(client)
-end
-copas.connect=copassconnect
-copas.send=copassend
-copas.sendto=copassendto
-copas.receive=copasreceive
-copas.receivefrom=copasreceivefrom
-copas.copasreceivepartial=copasreceivepartial
-copas.copasreceivePartial=copasreceivepartial
-copas.dohandshake=copasdohandshake
-copas.flush=copasflush
-local function _skt_mt_tostring(self)
- return tostring(self.socket).." (copas wrapped)"
-end
-local _skt_mt_tcp_index={
- send=function(self,data,from,to)
- return copassend (self.socket,data,from,to)
- end,
- receive=function (self,pattern,prefix)
- if self.timeout==0 then
- return copasreceivePartial(self.socket,pattern,prefix)
- else
- return copasreceive(self.socket,pattern,prefix)
- end
- end,
- flush=function (self)
- return copasflush(self.socket)
- end,
- settimeout=function (self,time)
- self.timeout=time
- return true
- end,
- connect=function(self,...)
- local res,err=copasconnect(self.socket,...)
- if res and self.ssl_params then
- res,err=self:dohandshake()
- end
- return res,err
- end,
- close=function(self,...)
- return self.socket:close(...)
- end,
- bind=function(self,...)
- return self.socket:bind(...)
- end,
- getsockname=function(self,...)
- return self.socket:getsockname(...)
- end,
- getstats=function(self,...)
- return self.socket:getstats(...)
- end,
- setstats=function(self,...)
- return self.socket:setstats(...)
- end,
- listen=function(self,...)
- return self.socket:listen(...)
- end,
- accept=function(self,...)
- return self.socket:accept(...)
- end,
- setoption=function(self,...)
- return self.socket:setoption(...)
- end,
- getpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- shutdown=function(self,...)
- return self.socket:shutdown(...)
- end,
- dohandshake=function(self,sslt)
- self.ssl_params=sslt or self.ssl_params
- local nskt,err=copasdohandshake(self.socket,self.ssl_params)
- if not nskt then
- return nskt,err
- end
- self.socket=nskt
- return self
- end,
-}
-local _skt_mt_tcp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_tcp_index,
-}
-local _skt_mt_udp_index={
- sendto=function (self,...)
- return copassendto(self.socket,...)
- end,
- receive=function (self,size)
- return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- receivefrom=function (self,size)
- return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- setpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- setsockname=function(self,...)
- return self.socket:setsockname(...)
- end,
- close=function(self,...)
- return true
- end
-}
-local _skt_mt_udp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_udp_index,
-}
-for k,v in next,_skt_mt_tcp_index do
- if not _skt_mt_udp_index[k] then
- _skt_mt_udp_index[k]=v
- end
-end
-local function wrap(skt,sslt)
- if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
- return skt
- end
- skt:settimeout(0)
- if isTCP(skt) then
- return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
- else
- return setmetatable ({ socket=skt },_skt_mt_udp)
- end
-end
-copas.wrap=wrap
-function copas.handler(handler,sslparams)
- return function (skt,...)
- skt=wrap(skt)
- if sslparams then
- skt:dohandshake(sslparams)
- end
- return handler(skt,...)
- end
-end
-local _errhandlers={}
-function copas.setErrorHandler(err)
- local co=runningcoroutine()
- if co then
- _errhandlers[co]=err
- end
-end
-local function _deferror (msg,co,skt)
- report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
-end
-local function _doTick (co,skt,...)
- if not co then
- return
- end
- local ok,res,new_q=resumecoroutine(co,skt,...)
- if ok and res and new_q then
- new_q:insert(res)
- new_q:push(res,co)
- else
- if not ok then
- pcall(_errhandlers[co] or _deferror,res,co,skt)
- end
- if skt and copas.autoclose and isTCP(skt) then
- skt:close()
- end
- _errhandlers[co]=nil
- end
-end
-local function _accept(input,handler)
- local client=input:accept()
- if client then
- client:settimeout(0)
- local co=createcoroutine(handler)
- _doTick (co,client)
- end
- return client
-end
-local function _tickRead(skt)
- _doTick(_reading:pop(skt),skt)
-end
-local function _tickWrite(skt)
- _doTick(_writing:pop(skt),skt)
-end
-local function addTCPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- _servers[server]=handler
- _reading:insert(server)
-end
-local function addUDPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- local co=createcoroutine(handler)
- _reading:insert(server)
- _doTick(co,server)
-end
-function copas.addserver(server,handler,timeout)
- if isTCP(server) then
- addTCPserver(server,handler,timeout)
- else
- addUDPserver(server,handler,timeout)
- end
-end
-function copas.removeserver(server,keep_open)
- local s=server
- local mt=getmetatable(server)
- if mt==_skt_mt_tcp or mt==_skt_mt_udp then
- s=server.socket
- end
- _servers[s]=nil
- _reading:remove(s)
- if keep_open then
- return true
- end
- return server:close()
-end
-function copas.addthread(handler,...)
- local thread=createcoroutine(function(_,...) return handler(...) end)
- _doTick(thread,nil,...)
- return thread
-end
-local _tasks={}
-local function addtaskRead(task)
- task.def_tick=_tickRead
- _tasks[task]=true
-end
-local function addtaskWrite(task)
- task.def_tick=_tickWrite
- _tasks[task]=true
-end
-local function tasks()
- return next,_tasks
-end
-local _readable_t={
- events=function(self)
- local i=0
- return function ()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,input)
- local handler=_servers[input]
- if handler then
- input=_accept(input,handler)
- else
- _reading:remove(input)
- self.def_tick(input)
- end
- end
-}
-addtaskRead(_readable_t)
-local _writable_t={
- events=function(self)
- local i=0
- return function()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,output)
- _writing:remove(output)
- self.def_tick(output)
- end
-}
-addtaskWrite(_writable_t)
-local _sleeping_t={
- tick=function(self,time,...)
- _doTick(_sleeping:pop(time),...)
- end
-}
-function copas.sleep(sleeptime)
- yieldcoroutine((sleeptime or 0),_sleeping)
-end
-function copas.wakeup(co)
- _sleeping:wakeup(co)
-end
-local last_cleansing=0
-local function _select(timeout)
- local now=gettime()
- local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
- _readable_t._evs=r_evs
- _writable_t._evs=w_evs
- if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
- last_cleansing=now
- for skt,time in next,_reading_log do
- if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#r_evs+1
- _reading_log[skt]=nil
- r_evs[n]=skt
- r_evs[skt]=n
- end
- end
- for skt,time in next,_writing_log do
- if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#w_evs+1
- _writing_log[skt]=nil
- w_evs[n]=skt
- w_evs[skt]=n
- end
- end
- end
- if err=="timeout" and #r_evs+#w_evs>0 then
- return nil
- else
- return err
- end
-end
-local function copasfinished()
- return not (next(_reading) or next(_writing) or _sleeping:getnext())
-end
-local function copasstep(timeout)
- _sleeping_t:tick(gettime())
- local nextwait=_sleeping:getnext()
- if nextwait then
- timeout=timeout and min(nextwait,timeout) or nextwait
- elseif copasfinished() then
- return false
- end
- local err=_select(timeout)
- if err then
- if err=="timeout" then
- return false
- end
- return nil,err
- end
- for task in tasks() do
- for event in task:events() do
- task:tick(event)
- end
- end
- return true
-end
-copas.finished=copasfinished
-copas.step=copasstep
-function copas.loop(timeout)
- copas.running=true
- while not copasfinished() do
- copasstep(timeout)
- end
- copas.running=false
-end
-package.loaded["copas"]=copas
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
-
--- original size: 8709, stripped down to: 5411
-
-
-local select,unpack=select,unpack
-local insert,remove=table.insert,table.remove
-local sub=string.sub
-local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("ltn12")
- report(fmt,first,...)
- elseif fmt then
- fmt="ltn12: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
- end
-end
-local filter={}
-local source={}
-local sink={}
-local pump={}
-local ltn12={
- _VERSION="LTN12 1.0.3",
- BLOCKSIZE=2048,
- filter=filter,
- source=source,
- sink=sink,
- pump=pump,
- report=report,
-}
-function filter.cycle(low,ctx,extra)
- if low then
- return function(chunk)
- return (low(ctx,chunk,extra))
- end
- end
-end
-function filter.chain(...)
- local arg={... }
- local n=select('#',...)
- local top=1
- local index=1
- local retry=""
- return function(chunk)
- retry=chunk and retry
- while true do
- local action=arg[index]
- if index==top then
- chunk=action(chunk)
- if chunk=="" or top==n then
- return chunk
- elseif chunk then
- index=index+1
- else
- top=top+1
- index=top
- end
- else
- chunk=action(chunk or "")
- if chunk=="" then
- index=index-1
- chunk=retry
- elseif chunk then
- if index==n then
- return chunk
- else
- index=index+1
- end
- else
- report("error: filter returned inappropriate 'nil'")
- return
- end
- end
- end
- end
-end
-local function empty()
- return nil
-end
-function source.empty()
- return empty
-end
-local function sourceerror(err)
- return function()
- return nil,err
- end
-end
-source.error=sourceerror
-function source.file(handle,io_err)
- if handle then
- local blocksize=ltn12.BLOCKSIZE
- return function()
- local chunk=handle:read(blocksize)
- if not chunk then
- handle:close()
- end
- return chunk
- end
- else
- return sourceerror(io_err or "unable to open file")
- end
-end
-function source.simplify(src)
- return function()
- local chunk,err_or_new=src()
- if err_or_new then
- src=err_or_new
- end
- if chunk then
- return chunk
- else
- return nil,err_or_new
- end
- end
-end
-function source.string(s)
- if s then
- local blocksize=ltn12.BLOCKSIZE
- local i=1
- return function()
- local nexti=i+blocksize
- local chunk=sub(s,i,nexti-1)
- i=nexti
- if chunk~="" then
- return chunk
- else
- return nil
- end
- end
- else return source.empty() end
-end
-function source.rewind(src)
- local t={}
- return function(chunk)
- if chunk then
- insert(t,chunk)
- else
- chunk=remove(t)
- if chunk then
- return chunk
- else
- return src()
- end
- end
- end
-end
-function source.chain(src,f,...)
- if... then
- f=filter.chain(f,...)
- end
- local last_in=""
- local last_out=""
- local state="feeding"
- local err
- return function()
- if not last_out then
- report("error: source is empty")
- return
- end
- while true do
- if state=="feeding" then
- last_in,err=src()
- if err then
- return nil,err
- end
- last_out=f(last_in)
- if not last_out then
- if last_in then
- report("error: filter returned inappropriate 'nil'")
- end
- return nil
- elseif last_out~="" then
- state="eating"
- if last_in then
- last_in=""
- end
- return last_out
- end
- else
- last_out=f(last_in)
- if last_out=="" then
- if last_in=="" then
- state="feeding"
- else
- report("error: filter returned nothing")
- return
- end
- elseif not last_out then
- if last_in then
- report("filter returned inappropriate 'nil'")
- end
- return nil
- else
- return last_out
- end
- end
- end
- end
-end
-function source.cat(...)
- local arg={... }
- local src=remove(arg,1)
- return function()
- while src do
- local chunk,err=src()
- if chunk then
- return chunk
- end
- if err then
- return nil,err
- end
- src=remove(arg,1)
- end
- end
-end
-function sink.table(t)
- if not t then
- t={}
- end
- local f=function(chunk,err)
- if chunk then
- insert(t,chunk)
- end
- return 1
- end
- return f,t
-end
-function sink.simplify(snk)
- return function(chunk,err)
- local ret,err_or_new=snk(chunk,err)
- if not ret then
- return nil,err_or_new
- end
- if err_or_new then
- snk=err_or_new
- end
- return 1
- end
-end
-local function null()
- return 1
-end
-function sink.null()
- return null
-end
-local function sinkerror(err)
- return function()
- return nil,err
- end
-end
-sink.error=sinkerror
-function sink.file(handle,io_err)
- if handle then
- return function(chunk,err)
- if not chunk then
- handle:close()
- return 1
- else
- return handle:write(chunk)
- end
- end
- else
- return sinkerror(io_err or "unable to open file")
- end
-end
-function sink.chain(f,snk,...)
- if... then
- local args={ f,snk,... }
- snk=remove(args,#args)
- f=filter.chain(unpack(args))
- end
- return function(chunk,err)
- if chunk~="" then
- local filtered=f(chunk)
- local done=chunk and ""
- while true do
- local ret,snkerr=snk(filtered,err)
- if not ret then
- return nil,snkerr
- end
- if filtered==done then
- return 1
- end
- filtered=f(done)
- end
- else
- return 1
- end
- end
-end
-function pump.step(src,snk)
- local chunk,src_err=src()
- local ret,snk_err=snk(chunk,src_err)
- if chunk and ret then
- return 1
- else
- return nil,src_err or snk_err
- end
-end
-function pump.all(src,snk,step)
- if not step then
- step=pump.step
- end
- while true do
- local ret,err=step(src,snk)
- if not ret then
- if err then
- return nil,err
- else
- return 1
- end
- end
- end
-end
-package.loaded["ltn12"]=ltn12
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
-
--- original size: 2373, stripped down to: 1931
-
-
-local type,tostring=type,tostring
-local mime=mime or package.loaded.mime or require("mime.core")
-local ltn12=ltn12 or package.loaded.ltn12 or require("ltn12")
-local filtercycle=ltn12.filter.cycle
-local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("mime")
- report(fmt,first,...)
- elseif fmt then
- fmt="mime: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
- end
-end
-mime.report=report
-local encodet={}
-local decodet={}
-local wrapt={}
-mime.encodet=encodet
-mime.decodet=decodet
-mime.wrapt=wrapt
-local mime_b64=mime.b64
-local mime_qp=mime.qp
-local mime_unb64=mime.unb64
-local mime_unqp=mime.unqp
-local mime_wrp=mime.wrp
-local mime_qpwrp=mime.qpwrp
-local mime_eol=mime_eol
-local mime_dot=mime_dot
-encodet['base64']=function()
- return filtercycle(mime_b64,"")
-end
-encodet['quoted-printable']=function(mode)
- return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
-end
-decodet['base64']=function()
- return filtercycle(mime_unb64,"")
-end
-decodet['quoted-printable']=function()
- return filtercycle(mime_unqp,"")
-end
-local wraptext=function(length)
- if not length then
- length=76
- end
- return filtercycle(mime_wrp,length,length)
-end
-local wrapquoted=function()
- return filtercycle(mime_qpwrp,76,76)
-end
-wrapt['text']=wraptext
-wrapt['base64']=wraptext
-wrapt['default']=wraptext
-wrapt['quoted-printable']=wrapquoted
-function mime.normalize(marker)
- return filtercycle(mime_eol,0,marker)
-end
-function mime.stuff()
- return filtercycle(mime_dot,2)
-end
-local function choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local filter=list[name or "nil"]
- if filter then
- return filter(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
- end
-end
-mime.encode=choose(encodet)
-mime.decode=choose(decodet)
-mime.wrap=choose(wrapt)
-package.loaded["mime"]=mime
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
-
--- original size: 6863, stripped down to: 5269
-
-
-local tonumber,tostring,type=tonumber,tostring,type
-local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,string.find,string.format,string.byte,string.char
-local insert=table.insert
-local socket=socket or require("socket")
-local url={
- _VERSION="URL 1.0.3",
-}
-socket.url=url
-function url.escape(s)
- return (gsub(s,"([^A-Za-z0-9_])",function(c)
- return format("%%%02x",byte(c))
- end))
-end
-local function make_set(t)
- local s={}
- for i=1,#t do
- s[t[i]]=true
- end
- return s
-end
-local segment_set=make_set {
- "-","_",".","!","~","*","'","(",
- ")",":","@","&","=","+","$",",",
-}
-local function protect_segment(s)
- return gsub(s,"([^A-Za-z0-9_])",function(c)
- if segment_set[c] then
- return c
- else
- return format("%%%02X",byte(c))
- end
- end)
-end
-function url.unescape(s)
- return (gsub(s,"%%(%x%x)",function(hex)
- return char(tonumber(hex,16))
- end))
-end
-local function absolute_path(base_path,relative_path)
- if find(relative_path,"^/") then
- return relative_path
- end
- local path=gsub(base_path,"[^/]*$","")
- path=path..relative_path
- path=gsub(path,"([^/]*%./)",function (s)
- if s~="./" then
- return s
- else
- return ""
- end
- end)
- path=gsub(path,"/%.$","/")
- local reduced
- while reduced~=path do
- reduced=path
- path=gsub(reduced,"([^/]*/%.%./)",function (s)
- if s~="../../" then
- return ""
- else
- return s
- end
- end)
- end
- path=gsub(reduced,"([^/]*/%.%.)$",function (s)
- if s~="../.." then
- return ""
- else
- return s
- end
- end)
- return path
-end
-function url.parse(url,default)
- local parsed={}
- for k,v in next,default or parsed do
- parsed[k]=v
- end
- if not url or url=="" then
- return nil,"invalid url"
- end
- url=gsub(url,"#(.*)$",function(f)
- parsed.fragment=f
- return ""
- end)
- url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
- parsed.scheme=s
- return ""
- end)
- url=gsub(url,"^//([^/]*)",function(n)
- parsed.authority=n
- return ""
- end)
- url=gsub(url,"%?(.*)",function(q)
- parsed.query=q
- return ""
- end)
- url=gsub(url,"%;(.*)",function(p)
- parsed.params=p
- return ""
- end)
- if url~="" then
- parsed.path=url
- end
- local authority=parsed.authority
- if not authority then
- return parsed
- end
- authority=gsub(authority,"^([^@]*)@",function(u)
- parsed.userinfo=u
- return ""
- end)
- authority=gsub(authority,":([^:%]]*)$",function(p)
- parsed.port=p
- return ""
- end)
- if authority~="" then
- parsed.host=match(authority,"^%[(.+)%]$") or authority
- end
- local userinfo=parsed.userinfo
- if not userinfo then
- return parsed
- end
- userinfo=gsub(userinfo,":([^:]*)$",function(p)
- parsed.password=p
- return ""
- end)
- parsed.user=userinfo
- return parsed
-end
-function url.build(parsed)
- local url=parsed.path or ""
- if parsed.params then
- url=url..";"..parsed.params
- end
- if parsed.query then
- url=url.."?"..parsed.query
- end
- local authority=parsed.authority
- if parsed.host then
- authority=parsed.host
- if find(authority,":") then
- authority="["..authority.."]"
- end
- if parsed.port then
- authority=authority..":"..tostring(parsed.port)
- end
- local userinfo=parsed.userinfo
- if parsed.user then
- userinfo=parsed.user
- if parsed.password then
- userinfo=userinfo..":"..parsed.password
- end
- end
- if userinfo then authority=userinfo.."@"..authority end
- end
- if authority then
- url="//"..authority..url
- end
- if parsed.scheme then
- url=parsed.scheme..":"..url
- end
- if parsed.fragment then
- url=url.."#"..parsed.fragment
- end
- return url
-end
-function url.absolute(base_url,relative_url)
- local base_parsed
- if type(base_url)=="table" then
- base_parsed=base_url
- base_url=url.build(base_parsed)
- else
- base_parsed=url.parse(base_url)
- end
- local relative_parsed=url.parse(relative_url)
- if not base_parsed then
- return relative_url
- elseif not relative_parsed then
- return base_url
- elseif relative_parsed.scheme then
- return relative_url
- else
- relative_parsed.scheme=base_parsed.scheme
- if not relative_parsed.authority then
- relative_parsed.authority=base_parsed.authority
- if not relative_parsed.path then
- relative_parsed.path=base_parsed.path
- if not relative_parsed.params then
- relative_parsed.params=base_parsed.params
- if not relative_parsed.query then
- relative_parsed.query=base_parsed.query
- end
- end
- else
- relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
- end
- end
- return url.build(relative_parsed)
- end
-end
-function url.parse_path(path)
- local parsed={}
- path=path or ""
- gsub(path,"([^/]+)",function (s)
- insert(parsed,s)
- end)
- for i=1,#parsed do
- parsed[i]=url.unescape(parsed[i])
- end
- if sub(path,1,1)=="/" then
- parsed.is_absolute=1
- end
- if sub(path,-1,-1)=="/" then
- parsed.is_directory=1
- end
- return parsed
-end
-function url.build_path(parsed,unsafe)
- local path=""
- local n=#parsed
- if unsafe then
- for i=1,n-1 do
- path=path..parsed[i].."/"
- end
- if n>0 then
- path=path..parsed[n]
- if parsed.is_directory then
- path=path.."/"
- end
- end
- else
- for i=1,n-1 do
- path=path..protect_segment(parsed[i]).."/"
- end
- if n>0 then
- path=path..protect_segment(parsed[n])
- if parsed.is_directory then
- path=path.."/"
- end
- end
- end
- if parsed.is_absolute then
- path="/"..path
- end
- return path
-end
-package.loaded["socket.url"]=url
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
-
--- original size: 5721, stripped down to: 3754
-
-
-local next=next
-local lower=string.lower
-local concat=table.concat
-local socket=socket or require("socket")
-local headers={}
-socket.headers=headers
-local canonic={
- ["accept"]="Accept",
- ["accept-charset"]="Accept-Charset",
- ["accept-encoding"]="Accept-Encoding",
- ["accept-language"]="Accept-Language",
- ["accept-ranges"]="Accept-Ranges",
- ["action"]="Action",
- ["alternate-recipient"]="Alternate-Recipient",
- ["age"]="Age",
- ["allow"]="Allow",
- ["arrival-date"]="Arrival-Date",
- ["authorization"]="Authorization",
- ["bcc"]="Bcc",
- ["cache-control"]="Cache-Control",
- ["cc"]="Cc",
- ["comments"]="Comments",
- ["connection"]="Connection",
- ["content-description"]="Content-Description",
- ["content-disposition"]="Content-Disposition",
- ["content-encoding"]="Content-Encoding",
- ["content-id"]="Content-ID",
- ["content-language"]="Content-Language",
- ["content-length"]="Content-Length",
- ["content-location"]="Content-Location",
- ["content-md5"]="Content-MD5",
- ["content-range"]="Content-Range",
- ["content-transfer-encoding"]="Content-Transfer-Encoding",
- ["content-type"]="Content-Type",
- ["cookie"]="Cookie",
- ["date"]="Date",
- ["diagnostic-code"]="Diagnostic-Code",
- ["dsn-gateway"]="DSN-Gateway",
- ["etag"]="ETag",
- ["expect"]="Expect",
- ["expires"]="Expires",
- ["final-log-id"]="Final-Log-ID",
- ["final-recipient"]="Final-Recipient",
- ["from"]="From",
- ["host"]="Host",
- ["if-match"]="If-Match",
- ["if-modified-since"]="If-Modified-Since",
- ["if-none-match"]="If-None-Match",
- ["if-range"]="If-Range",
- ["if-unmodified-since"]="If-Unmodified-Since",
- ["in-reply-to"]="In-Reply-To",
- ["keywords"]="Keywords",
- ["last-attempt-date"]="Last-Attempt-Date",
- ["last-modified"]="Last-Modified",
- ["location"]="Location",
- ["max-forwards"]="Max-Forwards",
- ["message-id"]="Message-ID",
- ["mime-version"]="MIME-Version",
- ["original-envelope-id"]="Original-Envelope-ID",
- ["original-recipient"]="Original-Recipient",
- ["pragma"]="Pragma",
- ["proxy-authenticate"]="Proxy-Authenticate",
- ["proxy-authorization"]="Proxy-Authorization",
- ["range"]="Range",
- ["received"]="Received",
- ["received-from-mta"]="Received-From-MTA",
- ["references"]="References",
- ["referer"]="Referer",
- ["remote-mta"]="Remote-MTA",
- ["reply-to"]="Reply-To",
- ["reporting-mta"]="Reporting-MTA",
- ["resent-bcc"]="Resent-Bcc",
- ["resent-cc"]="Resent-Cc",
- ["resent-date"]="Resent-Date",
- ["resent-from"]="Resent-From",
- ["resent-message-id"]="Resent-Message-ID",
- ["resent-reply-to"]="Resent-Reply-To",
- ["resent-sender"]="Resent-Sender",
- ["resent-to"]="Resent-To",
- ["retry-after"]="Retry-After",
- ["return-path"]="Return-Path",
- ["sender"]="Sender",
- ["server"]="Server",
- ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
- ["status"]="Status",
- ["subject"]="Subject",
- ["te"]="TE",
- ["to"]="To",
- ["trailer"]="Trailer",
- ["transfer-encoding"]="Transfer-Encoding",
- ["upgrade"]="Upgrade",
- ["user-agent"]="User-Agent",
- ["vary"]="Vary",
- ["via"]="Via",
- ["warning"]="Warning",
- ["will-retry-until"]="Will-Retry-Until",
- ["www-authenticate"]="WWW-Authenticate",
- ["x-mailer"]="X-Mailer",
-}
-headers.canonic=setmetatable(canonic,{
- __index=function(t,k)
- socket.report("invalid header: %s",k)
- t[k]=k
- return k
- end
-})
-function headers.normalize(headers)
- if not headers then
- return {}
- end
- local normalized={}
- for k,v in next,headers do
- normalized[#normalized+1]=canonic[k]..": "..v
- end
- normalized[#normalized+1]=""
- normalized[#normalized+1]=""
- return concat(normalized,"\r\n")
-end
-function headers.lower(lowered,headers)
- if not lowered then
- return {}
- end
- if not headers then
- lowered,headers={},lowered
- end
- for k,v in next,headers do
- lowered[lower(k)]=v
- end
- return lowered
-end
-socket.headers=headers
-package.loaded["socket.headers"]=headers
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
-
--- original size: 3116, stripped down to: 2533
-
-
-local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber
-local find,upper=string.find,string.upper
-local socket=socket or require("socket")
-local ltn12=ltn12 or require("ltn12")
-local skipsocket=socket.skip
-local sinksocket=socket.sink
-local tcpsocket=socket.tcp
-local ltn12pump=ltn12.pump
-local pumpall=ltn12pump.all
-local pumpstep=ltn12pump.step
-local tp={
- TIMEOUT=60,
-}
-socket.tp=tp
-local function get_reply(c)
- local line,err=c:receive()
- local reply=line
- if err then return
- nil,err
- end
- local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- if not code then
- return nil,"invalid server reply"
- end
- if sep=="-" then
- local current
- repeat
- line,err=c:receive()
- if err then
- return nil,err
- end
- current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- reply=reply.."\n"..line
- until code==current and sep==" "
- end
- return code,reply
-end
-local methods={}
-local mt={ __index=methods }
-function methods.getpeername(self)
- return self.c:getpeername()
-end
-function methods.getsockname(self)
- return self.c:getpeername()
-end
-function methods.check(self,ok)
- local code,reply=get_reply(self.c)
- if not code then
- return nil,reply
- end
- local c=tonumber(code)
- local t=type(ok)
- if t=="function" then
- return ok(c,reply)
- elseif t=="table" then
- for i=1,#ok do
- if find(code,ok[i]) then
- return c,reply
- end
- end
- return nil,reply
- elseif find(code,ok) then
- return c,reply
- else
- return nil,reply
- end
-end
-function methods.command(self,cmd,arg)
- cmd=upper(cmd)
- if arg then
- cmd=cmd.." "..arg.."\r\n"
- else
- cmd=cmd.."\r\n"
- end
- return self.c:send(cmd)
-end
-function methods.sink(self,snk,pat)
- local chunk,err=self.c:receive(pat)
- return snk(chunk,err)
-end
-function methods.send(self,data)
- return self.c:send(data)
-end
-function methods.receive(self,pat)
- return self.c:receive(pat)
-end
-function methods.getfd(self)
- return self.c:getfd()
-end
-function methods.dirty(self)
- return self.c:dirty()
-end
-function methods.getcontrol(self)
- return self.c
-end
-function methods.source(self,source,step)
- local sink=sinksocket("keep-open",self.c)
- local ret,err=pumpall(source,sink,step or pumpstep)
- return ret,err
-end
-function methods.close(self)
- self.c:close()
- return 1
-end
-function tp.connect(host,port,timeout,create)
- local c,e=(create or tcpsocket)()
- if not c then
- return nil,e
- end
- c:settimeout(timeout or tp.TIMEOUT)
- local r,e=c:connect(host,port)
- if not r then
- c:close()
- return nil,e
- end
- return setmetatable({ c=c },mt)
-end
-package.loaded["socket.tp"]=tp
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
-
--- original size: 12577, stripped down to: 9577
-
-
-local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type
-local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match
-local concat=table.concat
-local socket=socket or require("socket")
-local url=socket.url or require("socket.url")
-local ltn12=ltn12 or require("ltn12")
-local mime=mime or require("mime")
-local headers=socket.headers or require("socket.headers")
-local normalizeheaders=headers.normalize
-local parseurl=url.parse
-local buildurl=url.build
-local absoluteurl=url.absolute
-local unescapeurl=url.unescape
-local skipsocket=socket.skip
-local sinksocket=socket.sink
-local sourcesocket=socket.source
-local trysocket=socket.try
-local tcpsocket=socket.tcp
-local newtrysocket=socket.newtry
-local protectsocket=socket.protect
-local emptysource=ltn12.source.empty
-local stringsource=ltn12.source.string
-local rewindsource=ltn12.source.rewind
-local pumpstep=ltn12.pump.step
-local pumpall=ltn12.pump.all
-local sinknull=ltn12.sink.null
-local sinktable=ltn12.sink.table
-local lowerheaders=headers.lower
-local mimeb64=mime.b64
-local http={
- TIMEOUT=60,
- USERAGENT=socket._VERSION,
-}
-socket.http=http
-local PORT=80
-local SCHEMES={
- http=true,
-}
-local function receiveheaders(sock,headers)
- if not headers then
- headers={}
- end
- local line,err=sock:receive()
- if err then
- return nil,err
- end
- while line~="" do
- local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
- if not (name and value) then
- return nil,"malformed reponse headers"
- end
- name=lower(name)
- line,err=sock:receive()
- if err then
- return nil,err
- end
- while find(line,"^%s") do
- value=value..line
- line=sock:receive()
- if err then
- return nil,err
- end
- end
- local found=headers[name]
- if found then
- value=found..", "..value
- end
- headers[name]=value
- end
- return headers
-end
-socket.sourcet["http-chunked"]=function(sock,headers)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- local line,err=sock:receive()
- if err then
- return nil,err
- end
- local size=tonumber(gsub(line,";.*",""),16)
- if not size then
- return nil,"invalid chunk size"
- end
- if size>0 then
- local chunk,err,part=sock:receive(size)
- if chunk then
- sock:receive()
- end
- return chunk,err
- else
- headers,err=receiveheaders(sock,headers)
- if not headers then
- return nil,err
- end
- end
- end
- }
- )
-end
-socket.sinkt["http-chunked"]=function(sock)
- return setmetatable(
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if not chunk then
- chunk=""
- end
- return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
- end
- })
-end
-local methods={}
-local mt={ __index=methods }
-local function openhttp(host,port,create)
- local c=trysocket((create or tcpsocket)())
- local h=setmetatable({ c=c },mt)
- local try=newtrysocket(function() h:close() end)
- h.try=try
- try(c:settimeout(http.TIMEOUT))
- try(c:connect(host,port or PORT))
- return h
-end
-http.open=openhttp
-function methods.sendrequestline(self,method,uri)
- local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
- return self.try(self.c:send(requestline))
-end
-function methods.sendheaders(self,headers)
- self.try(self.c:send(normalizeheaders(headers)))
- return 1
-end
-function methods.sendbody(self,headers,source,step)
- if not source then
- source=emptysource()
- end
- if not step then
- step=pumpstep
- end
- local mode="http-chunked"
- if headers["content-length"] then
- mode="keep-open"
- end
- return self.try(pumpall(source,sinksocket(mode,self.c),step))
-end
-function methods.receivestatusline(self)
- local try=self.try
- local status=try(self.c:receive(5))
- if status~="HTTP/" then
- return nil,status
- end
- status=try(self.c:receive("*l",status))
- local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
- return try(tonumber(code),status)
-end
-function methods.receiveheaders(self)
- return self.try(receiveheaders(self.c))
-end
-function methods.receivebody(self,headers,sink,step)
- if not sink then
- sink=sinknull()
- end
- if not step then
- step=pumpstep
- end
- local length=tonumber(headers["content-length"])
- local encoding=headers["transfer-encoding"]
- local mode="default"
- if encoding and encoding~="identity" then
- mode="http-chunked"
- elseif length then
- mode="by-length"
- end
- return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
-end
-function methods.receive09body(self,status,sink,step)
- local source=rewindsource(sourcesocket("until-closed",self.c))
- source(status)
- return self.try(pumpall(source,sink,step))
-end
-function methods.close(self)
- return self.c:close()
-end
-local function adjusturi(request)
- if not request.proxy and not http.PROXY then
- request={
- path=trysocket(request.path,"invalid path 'nil'"),
- params=request.params,
- query=request.query,
- fragment=request.fragment,
- }
- end
- return buildurl(request)
-end
-local function adjustheaders(request)
- local headers={
- ["user-agent"]=http.USERAGENT,
- ["host"]=gsub(request.authority,"^.-@",""),
- ["connection"]="close, TE",
- ["te"]="trailers"
- }
- local username=request.user
- local password=request.password
- if username and password then
- headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
- end
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- local username=proxy.user
- local password=proxy.password
- if username and password then
- headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
- end
- end
- local requestheaders=request.headers
- if requestheaders then
- headers=lowerheaders(headers,requestheaders)
- end
- return headers
-end
-local default={
- host="",
- port=PORT,
- path="/",
- scheme="http"
-}
-local function adjustrequest(originalrequest)
- local url=originalrequest.url
- local request=url and parseurl(url,default) or {}
- for k,v in next,originalrequest do
- request[k]=v
- end
- local host=request.host
- local port=request.port
- local uri=request.uri
- if not host or host=="" then
- trysocket(nil,"invalid host '"..tostring(host).."'")
- end
- if port=="" then
- request.port=PORT
- end
- if not uri or uri=="" then
- request.uri=adjusturi(request)
- end
- request.headers=adjustheaders(request)
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- request.host=proxy.host
- request.port=proxy.port or 3128
- end
- return request
-end
-local maxredericts=4
-local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true }
-local validmethods={ [false]=true,GET=true,HEAD=true }
-local function shouldredirect(request,code,headers)
- local location=headers.location
- if not location then
- return false
- end
- location=gsub(location,"%s","")
- if location=="" then
- return false
- end
- local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
- if scheme and not SCHEMES[scheme] then
- return false
- end
- local method=request.method
- local redirect=request.redirect
- local redirects=request.nredirects or 0
- return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
-end
-local function shouldreceivebody(request,code)
- if request.method=="HEAD" then
- return nil
- end
- if code==204 or code==304 then
- return nil
- end
- if code>=100 and code<200 then
- return nil
- end
- return 1
-end
-local tredirect,trequest,srequest
-tredirect=function(request,location)
- local result,code,headers,status=trequest {
- url=absoluteurl(request.url,location),
- source=request.source,
- sink=request.sink,
- headers=request.headers,
- proxy=request.proxy,
- nredirects=(request.nredirects or 0)+1,
- create=request.create,
- }
- if not headers then
- headers={}
- end
- if not headers.location then
- headers.location=location
- end
- return result,code,headers,status
-end
-trequest=function(originalrequest)
- local request=adjustrequest(originalrequest)
- local connection=openhttp(request.host,request.port,request.create)
- local headers=request.headers
- connection:sendrequestline(request.method,request.uri)
- connection:sendheaders(headers)
- if request.source then
- connection:sendbody(headers,request.source,request.step)
- end
- local code,status=connection:receivestatusline()
- if not code then
- connection:receive09body(status,request.sink,request.step)
- return 1,200
- end
- while code==100 do
- headers=connection:receiveheaders()
- code,status=connection:receivestatusline()
- end
- headers=connection:receiveheaders()
- if shouldredirect(request,code,headers) and not request.source then
- connection:close()
- return tredirect(originalrequest,headers.location)
- end
- if shouldreceivebody(request,code) then
- connection:receivebody(headers,request.sink,request.step)
- end
- connection:close()
- return 1,code,headers,status
-end
-local function genericform(url,body)
- local buffer={}
- local request={
- url=url,
- sink=sinktable(buffer),
- target=buffer,
- }
- if body then
- request.source=stringsource(body)
- request.method="POST"
- request.headers={
- ["content-length"]=#body,
- ["content-type"]="application/x-www-form-urlencoded"
- }
- end
- return request
-end
-http.genericform=genericform
-srequest=function(url,body)
- local request=genericform(url,body)
- local _,code,headers,status=trequest(request)
- return concat(request.target),code,headers,status
-end
-http.request=protectsocket(function(request,body)
- if type(request)=="string" then
- return srequest(request,body)
- else
- return trequest(request)
- end
-end)
-package.loaded["socket.http"]=http
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
-
--- original size: 10357, stripped down to: 8548
-
-
-local setmetatable,type,next=setmetatable,type,next
-local find,format,gsub,match=string.find,string.format,string.gsub,string.match
-local concat=table.concat
-local mod=math.mod
-local socket=socket or require("socket")
-local url=socket.url or require("socket.url")
-local tp=socket.tp or require("socket.tp")
-local ltn12=ltn12 or require("ltn12")
-local tcpsocket=socket.tcp
-local trysocket=socket.try
-local skipsocket=socket.skip
-local sinksocket=socket.sink
-local selectsocket=socket.select
-local bindsocket=socket.bind
-local newtrysocket=socket.newtry
-local sourcesocket=socket.source
-local protectsocket=socket.protect
-local parseurl=url.parse
-local unescapeurl=url.unescape
-local pumpall=ltn12.pump.all
-local pumpstep=ltn12.pump.step
-local sourcestring=ltn12.source.string
-local sinktable=ltn12.sink.table
-local ftp={
- TIMEOUT=60,
- USER="ftp",
- PASSWORD="anonymous@anonymous.org",
-}
-socket.ftp=ftp
-local PORT=21
-local methods={}
-local mt={ __index=methods }
-function ftp.open(server,port,create)
- local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
- local f=setmetatable({ tp=tp },metat)
- f.try=newtrysocket(function() f:close() end)
- return f
-end
-function methods.portconnect(self)
- local try=self.try
- local server=self.server
- try(server:settimeout(ftp.TIMEOUT))
- self.data=try(server:accept())
- try(self.data:settimeout(ftp.TIMEOUT))
-end
-function methods.pasvconnect(self)
- local try=self.try
- self.data=try(tcpsocket())
- self(self.data:settimeout(ftp.TIMEOUT))
- self(self.data:connect(self.pasvt.address,self.pasvt.port))
-end
-function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("user",user or ftp.USER))
- local code,reply=try(tp:check{"2..",331})
- if code==331 then
- try(tp:command("pass",password or ftp.PASSWORD))
- try(tp:check("2.."))
- end
- return 1
-end
-function methods.pasv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("pasv"))
- local code,reply=try(self.tp:check("2.."))
- local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
- local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
- try(a and b and c and d and p1 and p2,reply)
- local address=format("%d.%d.%d.%d",a,b,c,d)
- local port=p1*256+p2
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if server then
- server:close()
- self.server=nil
- end
- return address,port
-end
-function methods.epsv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("epsv"))
- local code,reply=try(tp:check("229"))
- local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
- local d,prt,address,port=match(reply,pattern)
- try(port,"invalid epsv response")
- local address=tp:getpeername()
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if self.server then
- server:close()
- self.server=nil
- end
- return address,port
-end
-function methods.port(self,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local pl=mod(port,256)
- local ph=(port-pl)/256
- local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
- try(tp:command("port",arg))
- try(tp:check("2.."))
- return 1
-end
-function methods.eprt(self,family,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local arg=format("|%s|%s|%d|",family,address,port)
- try(tp:command("eprt",arg))
- try(tp:check("2.."))
- return 1
-end
-function methods.send(self,sendt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then
- self:pasvconnect()
- end
- local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=sendt.command or "stor"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"2..","1.."})
- if not self.pasvt then
- self:portconnect()
- end
- local step=sendt.step or pumpstep
- local readt={ tp }
- local checkstep=function(src,snk)
- local readyt=selectsocket(readt,nil,0)
- if readyt[tp] then
- code=try(tp:check("2.."))
- end
- return step(src,snk)
- end
- local sink=sinksocket("close-when-done",self.data)
- try(pumpall(sendt.source,sink,checkstep))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- local sent=skipsocket(1,self.data:getstats())
- self.data=nil
- return sent
-end
-function methods.receive(self,recvt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then self:pasvconnect() end
- local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=recvt.command or "retr"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"1..","2.."})
- if code>=200 and code<=299 then
- recvt.sink(reply)
- return 1
- end
- if not self.pasvt then
- self:portconnect()
- end
- local source=sourcesocket("until-closed",self.data)
- local step=recvt.step or pumpstep
- try(pumpall(source,recvt.sink,step))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- self.data=nil
- return 1
-end
-function methods.cwd(self,dir)
- local try=self.try
- local tp=self.tp
- try(tp:command("cwd",dir))
- try(tp:check(250))
- return 1
-end
-function methods.type(self,typ)
- local try=self.try
- local tp=self.tp
- try(tp:command("type",typ))
- try(tp:check(200))
- return 1
-end
-function methods.greet(self)
- local try=self.try
- local tp=self.tp
- local code=try(tp:check{"1..","2.."})
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- return 1
-end
-function methods.quit(self)
- local try=self.try
- try(self.tp:command("quit"))
- try(self.tp:check("2.."))
- return 1
-end
-function methods.close(self)
- local data=self.data
- if data then
- data:close()
- end
- local server=self.server
- if server then
- server:close()
- end
- local tp=self.tp
- if tp then
- tp:close()
- end
-end
-local function override(t)
- if t.url then
- local u=parseurl(t.url)
- for k,v in next,t do
- u[k]=v
- end
- return u
- else
- return t
- end
-end
-local function tput(putt)
- putt=override(putt)
- local host=putt.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,putt.port,putt.create)
- f:greet()
- f:login(putt.user,putt.password)
- local typ=putt.type
- if typ then
- f:type(typ)
- end
- f:epsv()
- local sent=f:send(putt)
- f:quit()
- f:close()
- return sent
-end
-local default={
- path="/",
- scheme="ftp",
-}
-local function genericform(u)
- local t=trysocket(parseurl(u,default))
- trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
- trysocket(t.host,"missing hostname")
- local pat="^type=(.)$"
- if t.params then
- local typ=skipsocket(2,find(t.params,pat))
- t.type=typ
- trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
- end
- return t
-end
-ftp.genericform=genericform
-local function sput(u,body)
- local putt=genericform(u)
- putt.source=sourcestring(body)
- return tput(putt)
-end
-ftp.put=protectsocket(function(putt,body)
- if type(putt)=="string" then
- return sput(putt,body)
- else
- return tput(putt)
- end
-end)
-local function tget(gett)
- gett=override(gett)
- local host=gett.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,gett.port,gett.create)
- f:greet()
- f:login(gett.user,gett.password)
- if gett.type then
- f:type(gett.type)
- end
- f:epsv()
- f:receive(gett)
- f:quit()
- return f:close()
-end
-local function sget(u)
- local gett=genericform(u)
- local t={}
- gett.sink=sinktable(t)
- tget(gett)
- return concat(t)
-end
-ftp.command=protectsocket(function(cmdt)
- cmdt=override(cmdt)
- local command=cmdt.command
- local argument=cmdt.argument
- local check=cmdt.check
- local host=cmdt.host
- trysocket(host,"missing hostname")
- trysocket(command,"missing command")
- local f=ftp.open(host,cmdt.port,cmdt.create)
- local try=f.try
- local tp=f.tp
- f:greet()
- f:login(cmdt.user,cmdt.password)
- if type(command)=="table" then
- local argument=argument or {}
- for i=1,#command do
- local cmd=command[i]
- try(tp:command(cmd,argument[i]))
- if check and check[i] then
- try(tp:check(check[i]))
- end
- end
- else
- try(tp:command(command,argument))
- if check then
- try(tp:check(check))
- end
- end
- f:quit()
- return f:close()
-end)
-ftp.get=protectsocket(function(gett)
- if type(gett)=="string" then
- return sget(gett)
- else
- return tget(gett)
- end
-end)
-package.loaded["socket.ftp"]=ftp
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
-
--- original size: 7018, stripped down to: 5883
-
-
-local type,setmetatable,next=type,setmetatable,next
-local find,lower,format=string.find,string.lower,string.format
-local osdate,osgetenv=os.date,os.getenv
-local random=math.random
-local socket=socket or require("socket")
-local headers=socket.headers or require("socket.headers")
-local ltn12=ltn12 or require("ltn12")
-local tp=socket.tp or require("socket.tp")
-local mime=mime or require("mime")
-local mimeb64=mime.b64
-local mimestuff=mime.stuff
-local skipsocket=socket.skip
-local trysocket=socket.try
-local newtrysocket=socket.newtry
-local protectsocket=socket.protect
-local normalizeheaders=headers.normalize
-local lowerheaders=headers.lower
-local createcoroutine=coroutine.create
-local resumecoroutine=coroutine.resume
-local yieldcoroutine=coroutine.resume
-local smtp={
- TIMEOUT=60,
- SERVER="localhost",
- PORT=25,
- DOMAIN=osgetenv("SERVER_NAME") or "localhost",
- ZONE="-0000",
-}
-socket.smtp=smtp
-local methods={}
-local mt={ __index=methods }
-function methods.greet(self,domain)
- local try=self.try
- local tp=self.tp
- try(tp:check("2.."))
- try(tp:command("EHLO",domain or _M.DOMAIN))
- return skipsocket(1,try(tp:check("2..")))
-end
-function methods.mail(self,from)
- local try=self.try
- local tp=self.tp
- try(tp:command("MAIL","FROM:"..from))
- return try(tp:check("2.."))
-end
-function methods.rcpt(self,to)
- local try=self.try
- local tp=self.tp
- try(tp:command("RCPT","TO:"..to))
- return try(tp:check("2.."))
-end
-function methods.data(self,src,step)
- local try=self.try
- local tp=self.tp
- try(tp:command("DATA"))
- try(tp:check("3.."))
- try(tp:source(src,step))
- try(tp:send("\r\n.\r\n"))
- return try(tp:check("2.."))
-end
-function methods.quit(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("QUIT"))
- return try(tp:check("2.."))
-end
-function methods.close(self)
- return self.tp:close()
-end
-function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("AUTH","LOGIN"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(user).."\r\n"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(password).."\r\n"))
- return try(tp:check("2.."))
-end
-function methods.plain(self,user,password)
- local try=self.try
- local tp=self.tp
- local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
- try(tp:command("AUTH",auth))
- return try(tp:check("2.."))
-end
-function methods.auth(self,user,password,ext)
- if not user or not password then
- return 1
- end
- local try=self.try
- if find(ext,"AUTH[^\n]+LOGIN") then
- return self:login(user,password)
- elseif find(ext,"AUTH[^\n]+PLAIN") then
- return self:plain(user,password)
- else
- try(nil,"authentication not supported")
- end
-end
-function methods.send(self,mail)
- self:mail(mail.from)
- local receipt=mail.rcpt
- if type(receipt)=="table" then
- for i=1,#receipt do
- self:rcpt(receipt[i])
- end
- elseif receipt then
- self:rcpt(receipt)
- end
- self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
-end
-local function opensmtp(self,server,port,create)
- if not server or server=="" then
- server=smtp.SERVER
- end
- if not port or port=="" then
- port=smtp.PORT
- end
- local s={
- tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
- try=newtrysocket(function()
- s:close()
- end),
- }
- setmetatable(s,mt)
- return s
-end
-smtp.open=opensmtp
-local nofboundaries=0
-local function newboundary()
- nofboundaries=nofboundaries+1
- return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
-end
-local send_message
-local function send_headers(headers)
- yieldcoroutine(normalizeheaders(headers))
-end
-local function send_multipart(message)
- local boundary=newboundary()
- local headers=lowerheaders(message.headers)
- local body=message.body
- local preamble=body.preamble
- local epilogue=body.epilogue
- local content=headers['content-type'] or 'multipart/mixed'
- headers['content-type']=content..'; boundary="'..boundary..'"'
- send_headers(headers)
- if preamble then
- yieldcoroutine(preamble)
- yieldcoroutine("\r\n")
- end
- for i=1,#body do
- yieldcoroutine("\r\n--"..boundary.."\r\n")
- send_message(body[i])
- end
- yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
- if epilogue then
- yieldcoroutine(epilogue)
- yieldcoroutine("\r\n")
- end
-end
-local default_content_type='text/plain; charset="UTF-8"'
-local function send_source(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- local getchunk=message.body
- while true do
- local chunk,err=getchunk()
- if err then
- yieldcoroutine(nil,err)
- elseif chunk then
- yieldcoroutine(chunk)
- else
- break
- end
- end
-end
-local function send_string(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- yieldcoroutine(message.body)
-end
-function send_message(message)
- local body=message.body
- if type(body)=="table" then
- send_multipart(message)
- elseif type(body)=="function" then
- send_source(message)
- else
- send_string(message)
- end
-end
-local function adjust_headers(message)
- local headers=lowerheaders(message.headers)
- if not headers["date"] then
- headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
- end
- if not headers["x-mailer"] then
- headers["x-mailer"]=socket._VERSION
- end
- headers["mime-version"]="1.0"
- return headers
-end
-function smtp.message(message)
- message.headers=adjust_headers(message)
- local action=createcoroutine(function()
- send_message(message)
- end)
- return function()
- local ret,a,b=resumecoroutine(action)
- if ret then
- return a,b
- else
- return nil,a
- end
- end
-end
-smtp.send=protectsocket(function(mail)
- local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
- local ext=snd:greet(mail.domain)
- snd:auth(mail.user,mail.password,ext)
- snd:send(mail)
- snd:quit()
- return snd:close()
-end)
-package.loaded["socket.smtp"]=smtp
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["trac-set"] = package.loaded["trac-set"] or true
-
--- original size: 13394, stripped down to: 8882
-
-if not modules then modules={} end modules ['trac-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,next,tostring,tonumber=type,next,tostring,tonumber
-local print=print
-local concat,sortedhash=table.concat,table.sortedhash
-local formatters,find,lower,gsub,topattern=string.formatters,string.find,string.lower,string.gsub,string.topattern
-local is_boolean=string.is_boolean
-local settings_to_hash=utilities.parsers.settings_to_hash
-local allocate=utilities.storage.allocate
-utilities=utilities or {}
-local utilities=utilities
-local setters=utilities.setters or {}
-utilities.setters=setters
-local data={}
-local trace_initialize=false
-local frozen=true
-function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
- end
- return true
- end
- end
-end
-local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
- end
- end
-end
-local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
- end
-end
-local function enable(t,what)
- set(t,what,true)
-end
-local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
-end
-function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
- end
- return false
-end
-function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
-end
-function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
-end
-function setters.reset(t)
- t.done={}
- reset(t)
-end
-function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
- end
- return user,system
-end
-function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
- end
-end
-local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
-function setters.report(setter,fmt,...)
- print(formatters["%-15s : %s\n"](setter.name,formatters[fmt](...)))
-end
-local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
-end
-local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
-end
-function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) return list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
-end
-trackers=setters.new("trackers")
-directives=setters.new("directives")
-experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
-local d_enable,d_disable=directives .enable,directives .disable
-local e_enable,e_disable=experiments.enable,experiments.disable
-local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
-local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
-function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
-end
-function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
-end
-function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
-end
-function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
-end
-directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
-end)
-directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
-end)
-if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
- end
-end
-if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
- end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
-end
-local data=table.setmetatableindex("table")
-updaters={
- register=function(what,f)
- local d=data[what]
- d[#d+1]=f
- end,
- apply=function(what,...)
- local d=data[what]
- for i=1,#d do
- d[i](...)
- end
- end,
-}
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["trac-log"] = package.loaded["trac-log"] or true
-
--- original size: 33003, stripped down to: 21667
-
-if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local next,type,select,print=next,type,select,print
-local format,gmatch,find=string.format,string.gmatch,string.find
-local concat,insert,remove=table.concat,table.insert,table.remove
-local topattern=string.topattern
-local utfchar=utf.char
-local datetime=os.date
-local openfile=io.open
-local runningtex=tex and (tex.jobname or tex.formatname)
-local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
-local setmetatableindex=table.setmetatableindex
-local formatters=string.formatters
-local settings_to_hash=utilities.parsers.settings_to_hash
-local sortedkeys=table.sortedkeys
-local variant="default"
-logs=logs or {}
-local logs=logs
-local moreinfo=[[
-More information about ConTeXt and the tools that come with it can be found at:
-]].."\n"..[[
-maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
-webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
-wiki : http://contextgarden.net
-]]
-formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
-)
-formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
-)
-local function ignore() end
-setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
-local report,subreport,status,settarget,setformats,settranslations
-local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
-local function ansisupported(specification)
- if specification~="ansi" and specification~="ansilog" then
- return false
- elseif os and os.enableansi then
- return os.enableansi()
- else
- return false
- end
-end
-if runningtex and texio then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg and ansisupported then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- if ansisupported("ansi") then
- variant="ansi"
- end
- break
- elseif v=="--ansilog" or v=="--c:ansilog" then
- if ansisupported("ansilog") then
- variant="ansilog"
- end
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- variants.ansilog={
- formats=variants.ansi.formats,
- targets=variants.default.targets,
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
- end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
- end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
- end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
- end
- setformats=function(f)
- formats=f
- end
- settranslations=function(t)
- translations=t
- end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
- end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- if not ansisupported(specification) then
- specification="default"
- end
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" or variant=="ansilog" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
-else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
- end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
- end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
- end
- end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(s)
- writeline(f(s))
- end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- if not ansisupported(specification) then
- specification="default"
- end
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
- end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
- write_nl=function(s)
- writeline(localtime().." | "..s)
- end
- settimedlog=ignore
- end
-end
-logs.report=report
-logs.subreport=subreport
-logs.status=status
-logs.settarget=settarget
-logs.pushtarget=pushtarget
-logs.poptarget=poptarget
-logs.setformats=setformats
-logs.settranslations=settranslations
-logs.setlogfile=setlogfile
-logs.settimedlog=settimedlog
-logs.setprocessor=setprocessor
-logs.setformatters=setformatters
-logs.direct=direct
-logs.subdirect=subdirect
-logs.writer=writer
-logs.newline=newline
-local data={}
-local states=nil
-local force=false
-function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
- end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
- end
- end
- return reporter
-end
-logs.new=logs.reporter
-local ctxreport=logs.writer
-function logs.setmessenger(m)
- ctxreport=m
-end
-function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
- end
-end
-local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
- for k,v in next,data do
- v.state=value
- end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
- end
-end
-function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
-end
-function logs.enable(category)
- setblocked(category,false)
-end
-function logs.categories()
- return sortedkeys(data)
-end
-function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
- end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
-end
-local delayed_reporters={}
-setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
-end)
-function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
-end
-directives.register("logs.blocked",function(v)
- setblocked(v,true)
-end)
-directives.register("logs.target",function(v)
- settarget(v)
-end)
-if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub=0,0,0
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- timing=""
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed=statistics.currenttime(statistics)
- local average,page
- if not lasttime or real<2 then
- average=elapsed
- page=elapsed
- else
- average=elapsed/(real-1)
- page=elapsed-lasttime
- end
- lasttime=elapsed
- timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
- end
- if real<=0 then
- report("flushing page%s",timing)
- elseif user<=0 then
- report("flushing realpage %s%s",real,timing)
- elseif sub<=0 then
- report("flushing realpage %s, userpage %s%s",real,user,timing)
- else
- report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
- end
- logs.flush()
- end
-end
-local nesting=0
-local verbose=false
-local hasscheme=url.hasscheme
-local simple=logs.reporter("comment")
-logs.simple=simple
-logs.simpleline=simple
-logs.setprogram=ignore
-logs.extendbanner=ignore
-logs.reportlines=ignore
-logs.reportbanner=ignore
-logs.reportline=ignore
-logs.simplelines=ignore
-logs.help=ignore
-local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
-local p_newline=lpeg.patterns.newline
-local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
-)^1
-local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
-end
-local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
-end
-local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
-end
-local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
- end
-end
-local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
-end
-local function reportexport(t,method)
- report(t.helpinfo)
-end
-local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
-}
-local exporters={
-}
-logs.reporters=reporters
-logs.exporters=exporters
-function logs.application(t)
- local arguments=environment and environment.arguments
- if arguments then
- local ansi=arguments.ansi or arguments.ansilog
- if ansi then
- logs.setformatters(arguments.ansi and "ansi" or "ansilog")
- end
- end
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
-end
-local f_syslog=formatters["%s %s => %s => %s => %s\r"]
-function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
- end
-end
-local report_system=logs.reporter("system","logs")
-function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
- end
-end
-if utilities then
- utilities.report=report_system
-end
-if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...))
- end
-else
- function logs.texerrormessage(...)
- print(format(...))
- end
-end
-if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
-end
-if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
- newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
- poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
-
--- original size: 10184, stripped down to: 7500
-
-if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,tonumber,select=type,tonumber,select
-local format,lower,find=string.format,string.lower,string.find
-local concat=table.concat
-local clock=os.gettimeofday or os.clock
-local setmetatableindex=table.setmetatableindex
-local serialize=table.serialize
-local formatters=string.formatters
-statistics=statistics or {}
-local statistics=statistics
-statistics.enable=true
-statistics.threshold=0.01
-local statusinfo,n,registered,timers={},0,{},{}
-setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0,offset=0 }
- t[k]=v
- return v
-end)
-local function hastiming(instance)
- return instance and timers[instance]
-end
-local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0,offset=0 }
-end
-local ticks=clock
-local seconds=function(n) return n or 0 end
-if os.type~="windows" then
-elseif lua.getpreciseticks then
- ticks=lua.getpreciseticks
- seconds=lua.getpreciseseconds
-elseif FFISUPPORTED then
- local okay,kernel=pcall(ffi.load,"kernel32")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
- int QueryPerformanceFrequency(int64_t *lpFrequency);
- int QueryPerformanceCounter(int64_t *lpPerformanceCount);
- ]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
- end
-else
-end
-local function starttiming(instance,reset)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if reset then
- it=0
- timer.loadtime=0
- end
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
-end
-local function stoptiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- timer.timing=it-1
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
- end
- return 0
-end
-local function benchmarktimer(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- timer.timing=it-1
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- timer.offset=ticks()-starttime
- else
- timer.offset=0
- end
- end
-end
-local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime-2*(timer.offset or 0)) or 0
- end
-end
-local function currenttime(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- return seconds(timer.loadtime+ticks()-starttime-2*(timer.offset or 0))
- end
- end
- return 0
- end
-end
-local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
-end
-local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
-end
-local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
-end
-statistics.hastiming=hastiming
-statistics.resettiming=resettiming
-statistics.starttiming=starttiming
-statistics.stoptiming=stoptiming
-statistics.currenttime=currenttime
-statistics.elapsed=elapsed
-statistics.elapsedtime=elapsedtime
-statistics.elapsedindeed=elapsedindeed
-statistics.elapsedseconds=elapsedseconds
-statistics.benchmarktimer=benchmarktimer
-function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
-end
-local report=logs.reporter("mkiv lua stats")
-function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- if LUATEXENGINE=="luametatex" then
- register("used engine",function()
- return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
- end)
- else
- register("used engine",function()
- return format("%s version: %s, functionality level: %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- end
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
- end
- statistics.enable=false
- end
-end
-function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB",
- round(collectgarbage("count")/1000),
- round(status.luastate_bytes/1000000),
- status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
- )
-end
-starttiming(statistics)
-function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
-end
-function statistics.runtime()
- stoptiming(statistics)
- local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
- return statistics.formatruntime(runtime)
-end
-local report=logs.reporter("system")
-function statistics.timed(action,all)
- starttiming("run")
- action()
- stoptiming("run")
- local runtime=tonumber(elapsedtime("run"))
- if all then
- local alltime=tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics))
- if alltime and alltime>0 then
- report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
- return
- end
- end
- report("total runtime: %0.3f seconds",runtime)
-end
-function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
-
--- original size: 5841, stripped down to: 3352
-
-if not modules then modules={} end modules ['trac-pro']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
-local report_system=logs.reporter("system","protection")
-namespaces=namespaces or {}
-local namespaces=namespaces
-local registered={}
-local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
-end
-local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
-end
-local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
- end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
- end
- m.__protection__depth=0
-end
-local function private(name)
- local data=registered[name]
- if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
- end
- return data
-end
-local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
-end
-local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
-end
-local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
- end
-end
-local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
- end
-end
-namespaces.register=register
-namespaces.private=private
-namespaces.protect=protect
-namespaces.unprotect=unprotect
-namespaces.protectall=protectall
-namespaces.unprotectall=unprotectall
-namespaces.private("namespaces") registered={} register("global")
-directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
-end)
-directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
-end)
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-lua"] = package.loaded["util-lua"] or true
-
--- original size: 7149, stripped down to: 4997
-
-if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
-local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
-utilities=utilities or {}
-utilities.lua=utilities.lua or {}
-local luautilities=utilities.lua
-local report_lua=logs.reporter("system","lua")
-local report_mem=logs.reporter("system","lua memory")
-local tracestripping=false
-local tracememory=false
-luautilities.stripcode=true
-luautilities.alwaysstripcode=false
-luautilities.nofstrippedchunks=0
-luautilities.nofstrippedbytes=0
-local strippedchunks={}
-luautilities.strippedchunks=strippedchunks
-if not LUATEXENGINE then
- LUATEXENGINE=status.luatex_engine and string.lower(status.luatex_engine)
- JITSUPPORTED=LUATEXENGINE=="luajittex" or jit
- CONTEXTLMTXMODE=CONTEXTLMTXMODE or (LUATEXENGINE=="luametatex" and 1) or 0
-end
-luautilities.suffixes={
- tma="tma",
- tmc=(CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 and "tmd") or (jit and "tmb") or "tmc",
- lua="lua",
- luc=(CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 and "lud") or (jit and "lub") or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc=(CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 and "tud") or (jit and "tub") or "tuc",
-}
-local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
-end
-local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
- if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- code,message=loadfile(fullname)
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
-end
-function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
-end
-function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
-end
-function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
-end
-function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
-end
-local finalizers={}
-setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
- end
-} )
-function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
-end
-function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- collectgarbage("collect")
- local afterwards=collectgarbage("count")
- if trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
- previous/1024,current/1024,delta/1024,threshold,afterwards)
- end
- return afterwards
- elseif trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
- previous/1024,current/1024,delta/1024,threshold)
- end
- end
- return current
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-deb"] = package.loaded["util-deb"] or true
-
--- original size: 10136, stripped down to: 6832
-
-if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,next,tostring,tonumber=type,next,tostring,tonumber
-local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
-local insert,remove,sort=table.insert,table.remove,table.sort
-local setmetatableindex=table.setmetatableindex
-utilities=utilities or {}
-local debugger=utilities.debugger or {}
-utilities.debugger=debugger
-local report=logs.reporter("debugger")
-local ticks=os.gettimeofday or os.clock
-local seconds=function(n) return n or 0 end
-local overhead=0
-local dummycalls=10*1000
-local nesting=0
-local names={}
-local initialize=false
-if lua.getpreciseticks then
- initialize=function()
- ticks=lua.getpreciseticks
- seconds=lua.getpreciseseconds
- initialize=false
- end
-elseif not (FFISUPPORTED and ffi) then
-elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
- int QueryPerformanceFrequency(int64_t *lpFrequency);
- int QueryPerformanceCounter(int64_t *lpPerformanceCount);
- ]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
- end
- initialize=false
- end
-elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
- /* what a mess */
- typedef int clk_id_t;
- typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
- typedef struct timespec { long sec; long nsec; } ctx_timespec;
- int clock_gettime(clk_id_t timerid, struct timespec *t);
- ]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
- end
-end
-setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0,nesting=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
- end)
- t[name]=v
- return v
-end)
-local getinfo=nil
-local sethook=nil
-local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- local nesting=data.nesting
- if nesting==0 then
- data.count=data.count+1
- insert(data,ticks())
- data.nesting=1
- else
- data.nesting=nesting+1
- end
- elseif where=="return" then
- local nesting=data.nesting
- if nesting==1 then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
- data.nesting=0
- else
- data.nesting=nesting-1
- end
- end
- end
-end
-function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
- end
- end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
- else
- return b[2]<a[2]
- end
- else
- return b[1]<a[1]
- end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
-end
-local function getdebug()
- if sethook and getinfo then
- return
- end
- if not debug then
- local okay
- okay,debug=pcall(require,"debug")
- end
- if type(debug)~="table" then
- return
- end
- getinfo=debug.getinfo
- sethook=debug.sethook
- if type(getinfo)~="function" then
- getinfo=nil
- end
- if type(sethook)~="function" then
- sethook=nil
- end
-end
-function debugger.savestats(filename,threshold)
- local f=io.open(filename,'w')
- if f then
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
-end
-function debugger.enable()
- getdebug()
- if sethook and getinfo and nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
-end
-function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if sethook and getinfo and nesting==0 then
- sethook()
- end
-end
-local function showtraceback(rep)
- getdebug()
- if getinfo then
- local level=2
- local reporter=rep or report
- while true do
- local info=getinfo(level,"Sl")
- if not info then
- break
- elseif info.what=="C" then
- reporter("%2i : %s",level-1,"C function")
- else
- reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
- end
- level=level+1
- end
- end
-end
-debugger.showtraceback=showtraceback
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
-
--- original size: 7722, stripped down to: 4212
-
-if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-utilities.templates=utilities.templates or {}
-local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
-local report_template=logs.reporter("template")
-local tostring,next=tostring,next
-local format,sub,byte=string.format,string.sub,string.byte
-local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
-local formatters=string.formatters
-local replacer
-local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
- else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
- end
-end
-local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
-}
-local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
-lpegpatterns.sqlescape=sqlescape
-lpegpatterns.sqlquoted=sqlquoted
-local luaescape=lpegpatterns.luaescape
-local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
-}
-local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
-}
-local luaescaper=escapers.lua
-local quotedluaescaper=quotedescapers.lua
-local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
-end
-local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
-end
-local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
-end
-local function replaceformatted(l,m,r,t,how,recurse)
- local v=t[r]
- return v and formatters[l](v)
-end
-local single=P("%")
-local double=P("%%")
-local lquoted=P("%[")
-local rquoted=P("]%")
-local lquotedq=P("%(")
-local rquotedq=P(")%")
-local escape=double/'%%'
-local nosingle=single/''
-local nodouble=double/''
-local nolquoted=lquoted/''
-local norquoted=rquoted/''
-local nolquotedq=lquotedq/''
-local norquotedq=rquotedq/''
-local nolformatted=P(":")/"%%"
-local norformatted=P(":")/""
-local noloptional=P("%?")/''
-local noroptional=P("?%")/''
-local nomoptional=P(":")/''
-local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle)^1)*args)/replacekey)*nosingle
-local quoted=nolquotedq*((C((1-norquotedq)^1)*args)/replacekeyquoted)*norquotedq
-local unquoted=nolquoted*((C((1-norquoted)^1)*args)/replacekeyunquoted)*norquoted
-local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
-local formatted=nosingle*((Cs(nolformatted*(1-norformatted )^1)*norformatted*C((1-nosingle)^1)*args)/replaceformatted)*nosingle
-local any=P(1)
- replacer=Cs((unquoted+quoted+formatted+escape+optional+key+any)^0)
-local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
-end
-templates.replace=replace
-function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
-end
-function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
-end
-function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
-
--- original size: 21084, stripped down to: 13214
-
-if not modules then modules={} end modules ['util-sbx']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-if not sandbox then require("l-sandbox") end
-local next,type=next,type
-local replace=utilities.templates.replace
-local collapsepath=file.collapsepath
-local expandname=dir.expandname
-local sortedhash=table.sortedhash
-local lpegmatch=lpeg.match
-local platform=os.type
-local P,S,C=lpeg.P,lpeg.S,lpeg.C
-local gsub=string.gsub
-local lower=string.lower
-local find=string.find
-local concat=string.concat
-local unquoted=string.unquoted
-local optionalquoted=string.optionalquoted
-local basename=file.basename
-local nameonly=file.nameonly
-local sandbox=sandbox
-local validroots={}
-local validrunners={}
-local validbinaries=true
-local validlibraries=true
-local validators={}
-local finalized=nil
-local trace=false
-local p_validroot=nil
-local p_split=lpeg.firstofsplit(" ")
-local report=logs.reporter("sandbox")
-trackers.register("sandbox",function(v) trace=v end)
-sandbox.setreporter(report)
-sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
-}
-local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
- end
-end
-sandbox.finalizer {
- category="files",
- action=function()
- if p_validroot then
- report("roots are already initialized")
- else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
- end
- end
-}
-local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
- end
-end
-local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
- end
-end
-local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
-local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
-end
-function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
-end
-local filenamelogger=false
-function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
-end
-local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
- end
- else
- return name
- end
-end
-local function readable(name,finalized)
- return validfilename(name,"r")
-end
-local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
-end
-local function writeable(name,finalized)
- return validfilename(name,"w")
-end
-local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
-end
-validators.readable=readable
-validators.writeable=normalizedwriteable
-validators.normalizedreadable=normalizedreadable
-validators.normalizedwriteable=writeable
-validators.filename=readable
-table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
-end)
-function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
-end
-function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
-end
-function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
-end
-local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
-end
-local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
- else
- end
-end
-local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
- end
-end
-local osexecute=sandbox.original(os.execute)
-local iopopen=sandbox.original(io.popen)
-local reported={}
-local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- local binpath=nil
- if variables then
- for variable,value in next,variables do
- local chktype=checkers[variable]
- if chktype=="verbose" then
- else
- local checker=validators[chktype]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local chktype=checkers[variable]
- if chktype=="verbose" then
- else
- local checker=validators[chktype]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- binpath=variables.binarypath
- end
- if type(binpath)=="string" and binpath~="" then
- program=binpath.."/"..program
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- local okay=osexecute(command)
- return okay
- end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
- end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
- end
- end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined",name)
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
- end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
- end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
- end
-end
-function sandbox.getrunner(name)
- return name and validrunners[name]
-end
-local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
-end
-local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
-end
-local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
-end
-sandbox.filehandlerone=filehandlerone
-sandbox.filehandlertwo=filehandlertwo
-sandbox.iohandler=iohandler
-function sandbox.disablerunners()
- validbinaries=false
-end
-function sandbox.disablelibraries()
- validlibraries=false
-end
-if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
- end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
- end
-end
-local overload=sandbox.overload
-local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
-if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
-end
-if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
-end
-if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
-end
-if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
-end
-sandbox.registerroot=registerroot
-sandbox.registerbinary=registerbinary
-sandbox.registerlibrary=registerlibrary
-sandbox.validfilename=validfilename
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
-
--- original size: 7819, stripped down to: 5881
-
-if not modules then modules={} end modules ['util-mrg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local gsub,format=string.gsub,string.format
-local concat=table.concat
-local type,next=type,next
-local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt,Cb,Cg=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt,lpeg.Cb,lpeg.Cg
-local lpegmatch,patterns=lpeg.match,lpeg.patterns
-utilities=utilities or {}
-local merger=utilities.merger or {}
-utilities.merger=merger
-merger.strip_comment=true
-local report=logs.reporter("system","merge")
-utilities.report=report
-local m_begin_merge="begin library merge"
-local m_end_merge="end library merge"
-local m_begin_closure="do -- create closure to overcome 200 locals limit"
-local m_end_closure="end -- of closure"
-local m_pattern="%c+".."%-%-%s+"..m_begin_merge.."%c+(.-)%c+".."%-%-%s+"..m_end_merge.."%c+"
-local m_format="\n\n-- "..m_begin_merge.."\n%s\n".."-- "..m_end_merge.."\n\n"
-local m_faked="-- ".."created merged file".."\n\n".."-- "..m_begin_merge.."\n\n".."-- "..m_end_merge.."\n\n"
-local m_report=[[
--- used libraries : %s
--- skipped libraries : %s
--- original bytes : %s
--- stripped bytes : %s
-]]
-local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
-local function self_fake()
- return m_faked
-end
-local function self_nothing()
- return ""
-end
-local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
-end
-local space=patterns.space
-local eol=patterns.newline
-local equals=P("=")^0
-local open=P("[")*Cg(equals,"init")*P("[")*P("\n")^-1
-local close=P("]")*C(equals)*P("]")
-local closeeq=Cmt(close*Cb("init"),function(s,i,a,b) return a==b end)
-local longstring=open*(1-closeeq)^0*close
-local quoted=patterns.quoted
-local digit=patterns.digit
-local emptyline=space^0*eol
-local operator1=P("<=")+P(">=")+P("~=")+P("..")+S("/^<>=*+%%")
-local operator2=S("*+/")
-local operator3=S("-")
-local operator4=P("..")
-local separator=S(",;")
-local ignore=(P("]")*space^1*P("=")*space^1*P("]"))/"]=["+(P("=")*space^1*P("{"))/"={"+(P("(")*space^1)/"("+(P("{")*(space+eol)^1*P("}"))/"{}"
-local strings=quoted
-local longcmt=(emptyline^0*P("--")*longstring*emptyline^0)/""
-local longstr=longstring
-local comment=emptyline^0*P("--")*P("-")^0*(1-eol)^0*emptyline^1/"\n"
-local optionalspaces=space^0/""
-local mandatespaces=space^1/""
-local optionalspacing=(eol+space)^0/""
-local mandatespacing=(eol+space)^1/""
-local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
-local lines=emptyline^2/"\n"
-local spaces=(space*space)/" "
-local spaces=(space*space*space*space)/" "
-local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
-)^1 )
-local strip=Cs((emptyline^2/"\n"+1)^0)
-local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
-function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
-end
-local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
-end
-local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
-end
-local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
-end
-local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
- for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
- end
- return concat(result,"\n\n")
-end
-function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
-end
-function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
-end
-function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-env"] = package.loaded["util-env"] or true
-
--- original size: 9738, stripped down to: 5531
-
-if not modules then modules={} end modules ['util-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local allocate,mark=utilities.storage.allocate,utilities.storage.mark
-local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
-local unquoted,quoted,optionalquoted=string.unquoted,string.quoted,string.optionalquoted
-local concat,insert,remove=table.concat,table.insert,table.remove
-environment=environment or {}
-local environment=environment
-local setlocale=os.setlocale
-setlocale(nil,nil)
-local report=logs.reporter("system")
-function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
-end
-local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
-}
-local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
-}
-local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
-}
-environment.validengines=validengines
-environment.basicengines=basicengines
-if not arg then
- environment.used_as_library=true
-elseif luaengines[file.removesuffix(arg[-1])] then
-elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
- arg[0]=specialmapping[originalzero] or originalzero
- insert(arg,0,"--script")
- insert(arg,0,"mtxrun")
- end
-end
-environment.arguments=allocate()
-environment.files=allocate()
-environment.sortedflags=nil
-function environment.initializearguments(arg)
- local arguments={}
- local files={}
- environment.arguments=arguments
- environment.files=files
- environment.sortedflags=nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
- end
- end
- if not environment.ownname then
- if os.selfpath and os.selfname then
- environment.ownname=file.addsuffix(file.join(os.selfpath,os.selfname),"lua")
- end
- end
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
-end
-function environment.setargument(name,value)
- environment.arguments[name]=value
-end
-function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
- end
- return nil
-end
-environment.argument=environment.getargument
-function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
- end
- return before,after
-end
-function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
- end
-end
-function environment.relativepath(path,root)
- if not path then
- path=""
- end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
- end
- return file.collapsepath(path,true)
-end
-if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- if find(argument,"\"$") then
- newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
- instring=false
- else
- newarg[#newarg+1]=gsub(argument,"^\"","")
- instring=true
- end
- elseif find(argument,"\"$") then
- if instring then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- else
- newarg[#newarg+1]=argument
- end
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
- end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["luat-env"] = package.loaded["luat-env"] or true
-
--- original size: 6551, stripped down to: 4315
-
- if not modules then modules={} end modules ['luat-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local rawset,loadfile=rawset,loadfile
-local gsub=string.gsub
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local report_lua=logs.reporter("resolvers","lua")
-local luautilities=utilities.lua
-local luasuffixes=luautilities.suffixes
-local texgettoks=tex and tex.gettoks
-environment=environment or {}
-local environment=environment
-local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
- end
-}
-setmetatable(environment,mt)
-function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
-end
-function environment.luafile(filename)
- if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 and file.suffix(filename)=="lua" then
- local resolved=resolvers.findfile(file.replacesuffix(filename,"lmt")) or ""
- if resolved~="" then
- return resolved
- end
- end
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
-local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
-end
-function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
- end
-end
-function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=filename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- end
- if chunk then
- chunk()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
- end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- chunk()
- return true
- end
- end
- return false
-end
-environment.filenames=setmetatable({},{
- __index=function(t,k)
- local v=environment.files[k]
- if v then
- return (gsub(v,"%.+$",""))
- end
- end,
- __newindex=function(t,k)
- end,
- __len=function(t)
- return #environment.files
- end,
-} )
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-zip"] = package.loaded["util-zip"] or true
-
--- original size: 19496, stripped down to: 10858
-
-if not modules then modules={} end modules ['util-zip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,tostring,tonumber=type,tostring,tonumber
-local sort=table.sort
-local find,format,sub,gsub=string.find,string.format,string.sub,string.gsub
-local osdate,ostime,osclock=os.date,os.time,os.clock
-local ioopen=io.open
-local loaddata,savedata=io.loaddata,io.savedata
-local filejoin,isdir,dirname,mkdirs=file.join,lfs.isdir,file.dirname,dir.mkdirs
-local files=utilities.files
-local openfile=files.open
-local closefile=files.close
-local readstring=files.readstring
-local readcardinal2=files.readcardinal2le
-local readcardinal4=files.readcardinal4le
-local setposition=files.setposition
-local getposition=files.getposition
-local band=bit32.band
-local rshift=bit32.rshift
-local lshift=bit32.lshift
-local decompress,expandsize,calculatecrc
- local zlibdecompress=zlib.decompress
- local zlibexpandsize=zlib.expandsize
- local zlibchecksum=zlib.crc32
- decompress=function(source)
- return zlibdecompress(source,-15)
- end
- expandsize=zlibexpandsize and function(source,targetsize)
- return zlibexpandsize(source,targetsize,-15)
- end or decompress
- calculatecrc=function(buffer,initial)
- return zlibchecksum(initial or 0,buffer)
- end
-local zipfiles={}
-utilities.zipfiles=zipfiles
-local openzipfile,closezipfile,unzipfile,foundzipfile,getziphash,getziplist do
- function openzipfile(name)
- return {
- name=name,
- handle=openfile(name,0),
- }
- end
- local function collect(z)
- if not z.list then
- local list={}
- local hash={}
- local position=0
- local index=0
- local handle=z.handle
- while true do
- setposition(handle,position)
- local signature=readstring(handle,4)
- if signature=="PK\3\4" then
- local version=readcardinal2(handle)
- local flag=readcardinal2(handle)
- local method=readcardinal2(handle)
- local filetime=readcardinal2(handle)
- local filedate=readcardinal2(handle)
- local crc32=readcardinal4(handle)
- local compressed=readcardinal4(handle)
- local uncompressed=readcardinal4(handle)
- local namelength=readcardinal2(handle)
- local extralength=readcardinal2(handle)
- local filename=readstring(handle,namelength)
- local descriptor=band(flag,8)~=0
- local encrypted=band(flag,1)~=0
- local acceptable=method==0 or method==8
- local skipped=0
- local size=0
- if encrypted then
- size=readcardinal2(handle)
- skipbytes(size)
- skipped=skipped+size+2
- skipbytes(8)
- skipped=skipped+8
- size=readcardinal2(handle)
- skipbytes(size)
- skipped=skipped+size+2
- size=readcardinal4(handle)
- skipbytes(size)
- skipped=skipped+size+4
- size=readcardinal2(handle)
- skipbytes(size)
- skipped=skipped+size+2
- end
- position=position+30+namelength+extralength+skipped
- if descriptor then
- setposition(handle,position+compressed)
- crc32=readcardinal4(handle)
- compressed=readcardinal4(handle)
- uncompressed=readcardinal4(handle)
- end
- if acceptable then
- index=index+1
- local data={
- filename=filename,
- index=index,
- position=position,
- method=method,
- compressed=compressed,
- uncompressed=uncompressed,
- crc32=crc32,
- encrypted=encrypted,
- }
- hash[filename]=data
- list[index]=data
- else
- end
- position=position+compressed
- else
- break
- end
- z.list=list
- z.hash=hash
- end
- end
- end
- function getziplist(z)
- local list=z.list
- if not list then
- collect(z)
- end
- return z.list
- end
- function getziphash(z)
- local hash=z.hash
- if not hash then
- collect(z)
- end
- return z.hash
- end
- function foundzipfile(z,name)
- return getziphash(z)[name]
- end
- function closezipfile(z)
- local f=z.handle
- if f then
- closefile(f)
- z.handle=nil
- end
- end
- function unzipfile(z,filename,check)
- local hash=z.hash
- if not hash then
- hash=zipfiles.hash(z)
- end
- local data=hash[filename]
- if not data then
- end
- if data then
- local handle=z.handle
- local position=data.position
- local compressed=data.compressed
- if compressed>0 then
- setposition(handle,position)
- local result=readstring(handle,compressed)
- if data.method==8 then
- if expandsize then
- result=expandsize(result,data.uncompressed)
- else
- result=decompress(result)
- end
- end
- if check and data.crc32~=calculatecrc(result) then
- print("checksum mismatch")
- return ""
- end
- return result
- else
- return ""
- end
- end
- end
- zipfiles.open=openzipfile
- zipfiles.close=closezipfile
- zipfiles.unzip=unzipfile
- zipfiles.hash=getziphash
- zipfiles.list=getziplist
- zipfiles.found=foundzipfile
-end
-if xzip then
- local writecardinal1=files.writebyte
- local writecardinal2=files.writecardinal2le
- local writecardinal4=files.writecardinal4le
- local logwriter=logs.writer
- local globpattern=dir.globpattern
- local compress=xzip.compress
- local checksum=xzip.crc32
- local function fromdostime(dostime,dosdate)
- return ostime {
- year=rshift(dosdate,9)+1980,
- month=band(rshift(dosdate,5),0x0F),
- day=band((dosdate ),0x1F),
- hour=band(rshift(dostime,11) ),
- min=band(rshift(dostime,5),0x3F),
- sec=band((dostime ),0x1F),
- }
- end
- local function todostime(time)
- local t=osdate("*t",time)
- return
- lshift(t.year-1980,9)+lshift(t.month,5)+t.day,
- lshift(t.hour,11)+lshift(t.min,5)+rshift(t.sec,1)
- end
- local function openzip(filename,level,comment,verbose)
- local f=ioopen(filename,"wb")
- if f then
- return {
- filename=filename,
- handle=f,
- list={},
- level=tonumber(level) or 3,
- comment=tostring(comment),
- verbose=verbose,
- uncompressed=0,
- compressed=0,
- }
- end
- end
- local function writezip(z,name,data,level,time)
- local f=z.handle
- local list=z.list
- local level=tonumber(level) or z.level or 3
- local method=8
- local zipped=compress(data,level)
- local checksum=checksum(data)
- local verbose=z.verbose
- if not zipped then
- method=0
- zipped=data
- end
- local start=f:seek()
- local compressed=#zipped
- local uncompressed=#data
- z.compressed=z.compressed+compressed
- z.uncompressed=z.uncompressed+uncompressed
- if verbose then
- local pct=100*compressed/uncompressed
- if pct>=100 then
- logwriter(format("%10i %s",uncompressed,name))
- else
- logwriter(format("%10i %02.1f %s",uncompressed,pct,name))
- end
- end
- f:write("\x50\x4b\x03\x04")
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal2(f,method)
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal4(f,checksum)
- writecardinal4(f,compressed)
- writecardinal4(f,uncompressed)
- writecardinal2(f,#name)
- writecardinal2(f,0)
- f:write(name)
- f:write(zipped)
- list[#list+1]={ #zipped,#data,name,checksum,start,time or 0 }
- end
- local function closezip(z)
- local f=z.handle
- local list=z.list
- local comment=z.comment
- local verbose=z.verbose
- local count=#list
- local start=f:seek()
- for i=1,count do
- local l=list[i]
- local compressed=l[1]
- local uncompressed=l[2]
- local name=l[3]
- local checksum=l[4]
- local start=l[5]
- local time=l[6]
- local date,time=todostime(time)
- f:write('\x50\x4b\x01\x02')
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal2(f,8)
- writecardinal2(f,time)
- writecardinal2(f,date)
- writecardinal4(f,checksum)
- writecardinal4(f,compressed)
- writecardinal4(f,uncompressed)
- writecardinal2(f,#name)
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal4(f,0)
- writecardinal4(f,start)
- f:write(name)
- end
- local stop=f:seek()
- local size=stop-start
- f:write('\x50\x4b\x05\x06')
- writecardinal2(f,0)
- writecardinal2(f,0)
- writecardinal2(f,count)
- writecardinal2(f,count)
- writecardinal4(f,size)
- writecardinal4(f,start)
- if type(comment)=="string" and comment~="" then
- writecardinal2(f,#comment)
- f:write(comment)
- else
- writecardinal2(f,0)
- end
- if verbose then
- local compressed=z.compressed
- local uncompressed=z.uncompressed
- local filename=z.filename
- local pct=100*compressed/uncompressed
- logwriter("")
- if pct>=100 then
- logwriter(format("%10i %s",uncompressed,filename))
- else
- logwriter(format("%10i %02.1f %s",uncompressed,pct,filename))
- end
- end
- f:close()
- end
- local function zipdir(zipname,path,level,verbose)
- if type(zipname)=="table" then
- verbose=zipname.verbose
- level=zipname.level
- path=zipname.path
- zipname=zipname.zipname
- end
- if not zipname or zipname=="" then
- return
- end
- if not path or path=="" then
- path="."
- end
- if not isdir(path) then
- return
- end
- path=gsub(path,"\\+","/")
- path=gsub(path,"/+","/")
- local list={}
- local count=0
- globpattern(path,"",true,function(name,size,time)
- count=count+1
- list[count]={ name,time }
- end)
- sort(list,function(a,b)
- return a[1]<b[1]
- end)
- local zipf=openzip(zipname,level,comment,verbose)
- if zipf then
- local p=#path+2
- for i=1,count do
- local li=list[i]
- local name=li[1]
- local time=li[2]
- local data=loaddata(name)
- local name=sub(name,p,#name)
- writezip(zipf,name,data,level,time,verbose)
- end
- closezip(zipf)
- end
- end
- local function unzipdir(zipname,path,verbose)
- if type(zipname)=="table" then
- verbose=zipname.verbose
- path=zipname.path
- zipname=zipname.zipname
- end
- if not zipname or zipname=="" then
- return
- end
- if not path or path=="" then
- path="."
- end
- local z=openzipfile(zipname)
- if z then
- local list=getziplist(z)
- if list then
- local total=0
- local count=#list
- local step=number.idiv(count,10)
- local done=0
- local steps=verbose=="steps"
- local time=steps and osclock()
- for i=1,count do
- local l=list[i]
- local n=l.filename
- local d=unzipfile(z,n)
- if d then
- local p=filejoin(path,n)
- if mkdirs(dirname(p)) then
- if steps then
- total=total+#d
- done=done+1
- if done>=step then
- done=0
- logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",i,count,total,osclock()-time))
- end
- elseif verbose then
- logwriter(n)
- end
- savedata(p,d)
- end
- else
- logwriter(format("problem with file %s",n))
- end
- end
- if steps then
- logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",count,count,total,osclock()-time))
- end
- closezipfile(z)
- return true
- else
- closezipfile(z)
- end
- end
- end
- zipfiles.zipdir=zipdir
- zipfiles.unzipdir=unzipdir
-end
-zipfiles.gunzipfile=gzip.load
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
-
--- original size: 61191, stripped down to: 35864
-
-if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
-local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
-if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
-xml=xml or {}
-local xml=xml
-local concat,remove,insert=table.concat,table.remove,table.insert
-local type,next,setmetatable,getmetatable,tonumber,rawset,select=type,next,setmetatable,getmetatable,tonumber,rawset,select
-local lower,find,match,gsub=string.lower,string.find,string.match,string.gsub
-local sort=table.sort
-local utfchar=utf.char
-local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
-local P,S,R,C,V,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.C,lpeg.Cs
-local formatters=string.formatters
-do
-xml.xmlns=xml.xmlns or {}
-local check=P(false)
-local parse=check
-function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
-end
-function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
-end
-function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
-end
-end
-local nsremap,resolvens=xml.xmlns,xml.resolvens
-local stack,level,top,at,xmlnms,errorstr
-local entities,parameters
-local strip,utfize,resolve,cleanup,resolve_predefined,unify_predefined
-local dcache,hcache,acache
-local mt,dt,nt
-local currentfilename,currentline,linenumbers
-local grammar_parsed_text_one
-local grammar_parsed_text_two
-local grammar_unparsed_text
-local handle_hex_entity
-local handle_dec_entity
-local handle_any_entity_dtd
-local handle_any_entity_text
-local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
-end
-local function initialize_mt(root)
- mt={ __index=root }
-end
-function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
-end
-function xml.checkerror(top,toclose)
- return ""
-end
-local checkns=xml.checkns
-local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
-end
-local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
-end
-local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
-end
-local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
-end
-local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
- else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
- end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
- else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
- end
-end
-local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
-end
-local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
-end
-local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
-end
-do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
- end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
- end
- return d
- end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
- else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
- end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
- else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
- end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["h:%s"](s),true
- end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
- end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["h:%s"](s),true
- end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
- end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
-end
-local escaped=xml.escaped
-local unescaped=xml.unescaped
-local placeholders=xml.placeholders
-local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
-end
-local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
-end
-local function handlenewline()
- currentline=currentline+1
-end
-local spacetab=S(' \t')
-local space=S(' \r\n\t')
-local newline=lpegpatterns.newline/handlenewline
-local anything=P(1)
-local open=P('<')
-local close=P('>')
-local squote=S("'")
-local dquote=S('"')
-local equal=P('=')
-local slash=P('/')
-local colon=P(':')
-local semicolon=P(';')
-local ampersand=P('&')
-local valid_0=R("\128\255")
-local valid_1=R('az','AZ')+S('_')+valid_0
-local valid_2=valid_1+R('09')+S('-.')
-local valid=valid_1*valid_2^0
-local name_yes=C(valid^1)*colon*C(valid^1)
-local name_nop=C(P(true))*C(valid^1)
-local name=name_yes+name_nop
-local utfbom=lpegpatterns.utfbom
-local spacing=C(space^0)
-local space_nl=spacetab+newline
-local spacing_nl=Cs((space_nl)^0)
-local anything_nl=newline+P(1)
-local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
-end
-local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
-end
-local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
-end
-local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
-end
-local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- local loadbinfile=resolvers and resolvers.loadbinfile
- if loadbinfile then
- okay,data=loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
- end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
-end
-local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
-publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
-end
-local
- grammar_parsed_text_one_nop,
- grammar_parsed_text_two_nop,
- grammar_unparsed_text_nop=install(space,spacing,anything)
-local
- grammar_parsed_text_one_yes,
- grammar_parsed_text_two_yes,
- grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
-local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
- end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
- else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
- else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
- end
- end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
- }
- preparexmlstate()
- return result
-end
-local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
-end
-xml.convert=xmlconvert
-function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
-end
-function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
-end
-function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
-end
-function xml.is_valid(root)
- return root and not root.error
-end
-xml.errorhandler=report_xml
-function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
-end
-local no_root={ no_root=true }
-function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
-end
-local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
- end
-end
-xml.copy=copy
-function xml.checkbom(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
- end
-end
-local f_attribute=formatters['%s=%q']
-local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
- end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
- else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
- end
- else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
- else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
- end
- end
-end
-local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
-end
-local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
-end
-local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
-end
-local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
-end
-local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
-end
-local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
-end
-local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
- end
-end
-local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
- end
-end
-local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- end
-end
-local handlers={}
-local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
- end
- utilities.storage.mark(t)
- return t
-end
-local nofunction=function() end
-function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
-end
-function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
-end
-function xml.gethandlers(name)
- return handlers[name]
-end
-newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
-}
-local result
-local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
-}
-function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
-end
-local result,r,threshold={},0,512
-local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
-}
-local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
-end
-local function __tostring(root)
- return (root and xmltostring(root)) or ""
-end
-initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
-end
-xml.defaulthandlers=handlers
-xml.newhandlers=newhandlers
-xml.serialize=serialize
-xml.tostring=xmltostring
-local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
- end
-end
-xml.string=xmlstring
-function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
- end
- return nil
-end
-function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
- end
- return r
-end
-function xml.parent(root)
- return root.__p__
-end
-function xml.body(root)
- return root.ri and root.dt[root.ri] or root
-end
-function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
-end
-function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
-end
-function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
-end
-function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
-end
-function xml.makestandalone(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" then
- local txt=v.dt[1]
- if find(txt,"xml.*version=") then
- v.dt[1]=txt.." standalone='yes'"
- break
- end
- end
- end
- end
- return root
-end
-function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
- end
- return "empty"
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
-
--- original size: 54626, stripped down to: 31255
-
-if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local concat,remove,insert=table.concat,table.remove,table.insert
-local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
-local format,upper,lower,gmatch,gsub,find,rep=string.format,string.upper,string.lower,string.gmatch,string.gsub,string.find,string.rep
-local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
-local setmetatableindex=table.setmetatableindex
-local formatters=string.formatters
-local trace_lpath=false
-local trace_lparse=false
-local trace_lprofile=false
-local report_lpath=logs.reporter("xml","lpath")
-if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
-end
-local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
-xml.functions=xml.functions or {}
-local functions=xml.functions
-xml.expressions=xml.expressions or {}
-local expressions=xml.expressions
-xml.finalizers=xml.finalizers or {}
-local finalizers=xml.finalizers
-xml.specialhandler=xml.specialhandler or {}
-local specialhandler=xml.specialhandler
-lpegpatterns.xml=lpegpatterns.xml or {}
-local xmlpatterns=lpegpatterns.xml
-finalizers.xml=finalizers.xml or {}
-finalizers.tex=finalizers.tex or {}
-local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
-end
-setmetatableindex(finalizers.xml,fallback)
-setmetatableindex(finalizers.tex,fallback)
-xml.defaultprotocol="xml"
-local apply_axis={}
-apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
- end
- return collected
-end
-apply_axis['self']=function(list)
- return list
-end
-apply_axis['child']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local n=#dt
- if n==0 then
- ll.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- ll.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- end
- end
- ll.en=en
- end
- end
- end
- return collected
-end
-local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- else
- list.en=0
- end
- else
- local en=0
- for k=1,n do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
- end
- end
- return c
-end
-apply_axis['descendant']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
-end
-local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
- end
- end
- return c
-end
-apply_axis['descendant-or-self']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
- end
- return collected
-end
-apply_axis['ancestor']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
- end
- return collected
-end
-apply_axis['ancestor-or-self']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local ll=list[l]
- c=c+1
- collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
- end
- return collected
-end
-apply_axis['parent']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
- end
- return collected
-end
-apply_axis['attribute']=function(list)
- return {}
-end
-apply_axis['namespace']=function(list)
- return {}
-end
-apply_axis['following']=function(list)
- return {}
-end
-apply_axis['preceding']=function(list)
- return {}
-end
-apply_axis['following-sibling']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni+1,#d do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
- end
- return collected
-end
-apply_axis['preceding-sibling']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
- end
- return collected
-end
-apply_axis['reverse-sibling']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
- end
- return collected
-end
-apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
-apply_axis['auto-descendant']=apply_axis['descendant']
-apply_axis['auto-child']=apply_axis['child']
-apply_axis['auto-self']=apply_axis['self']
-apply_axis['initial-child']=apply_axis['child']
-local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns=nodes[2]
- local ntg=nodes[3]
- if not nns and not ntg then
- if directive then
- return list
- else
- return {}
- end
- else
- local collected={}
- local c=0
- local m=0
- local p=nil
- if not nns then
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- if directive then
- if ntg==ltg then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- local ll=list[l]
- local lns=ll.rn or ll.ns
- if lns then
- if directive then
- if lns==nns then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=ltg==ntg and lns==nns
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- end
- end
- end
- return collected
- end
- else
- local collected={}
- local c=0
- local m=0
- local p=nil
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns=nodes[n+1]
- local ntg=nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
- c=c+1
- collected[c]=ll
- ll.mi=m
- end
- end
- end
- return collected
- end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected={}
- local c=0
- quit_expression=false
- for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
- c=c+1
- collected[c]=ll
- end
- if quit_expression then
- break
- end
- end
- return collected
-end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
- end
-end
-local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
-local spaces=S(" \n\r\t\f")^0
-local lp_space=S(" \n\r\t\f")
-local lp_any=P(1)
-local lp_noequal=P("!=")/"~="+P("<=")+P(">=")+P("==")
-local lp_doequal=P("=")/"=="
-local lp_or=P("|")/" or "
-local lp_and=P("&")/" and "
-local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- list="list",
- self="ll",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
-}
-local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
-local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
-local lp_fastpos_p=P("+")^0*R("09")^1*P(-1)/"l==%0"
-local lp_fastpos_n=P("-")*R("09")^1*P(-1)/"(%0<0 and (#list+%0==l))"
-local lp_fastpos=lp_fastpos_n+lp_fastpos_p
-local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
-local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
-local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
-end
-local lparent=P("(")
-local rparent=P(")")
-local noparent=1-(lparent+rparent)
-local nested=P{lparent*(noparent+V(1))^0*rparent}
-local value=P(lparent*C((noparent+nested)^0)*rparent)
-local lp_child=Cc("expr.child(ll,'")*R("az","AZ")*R("az","AZ","--","__")^0*Cc("')")
-local lp_number=S("+-")*R("09")^1
-local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
-local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
-local cleaner
-local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
- else
- return "expr.error("..t..")"
- end
-end
-local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
-local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
-)
-cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
-local template_e=[[
- local expr = xml.expressions
- return function(list,ll,l,order)
- return %s
- end
-]]
-local template_f_y=[[
- local finalizer = xml.finalizers['%s']['%s']
- return function(collection)
- return finalizer(collection,%s)
- end
-]]
-local template_f_n=[[
- return xml.finalizers['%s']['%s']
-]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
-local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
-local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
-local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
-local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
-local register_all_nodes={ kind="nodes",nodetest=true,nodes={ true,false,false } }
-local skip={}
-local function errorrunner_e(str,cnv)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
-end
-local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
-end
-local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
-end
-local function register_selector(specification)
- return { kind="selector",specification=specification }
-end
-local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local wrapped=format(template_e,converted)
- local runner=load(wrapped)
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
-end
-local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
-end
-local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
-}
-local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
-}
-local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
-end
-local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
-local special_2=P("/")*Cc(register_auto_self)
-local special_3=P("")*Cc(register_auto_self)
-local no_nextcolon=P(-1)+#(1-P(":"))
-local no_nextlparent=P(-1)+#(1-P("("))
-local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
-}
-xmlpatterns.pathparser=pathparser
-local cache={}
-local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
-end
-local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns=li.ns
- local tg=li.tg
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- end
- return concat(t," ")
- end
-end
-xml.nodesettostring=nodesettostring
-local lpath
-local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
-end
-xml.lshow=lshow
-local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
-end
-lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
- else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
- else
- parsed={ pattern=pattern }
- end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
- end
- end
- return parsed
- end
-end
-xml.lpath=lpath
-do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
- return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
- end
- return collected
- end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
- end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
- return collected
- end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
- end
-end
-local applylpath=xml.applylpath
-function xml.filter(root,pattern)
- return applylpath(root,pattern)
-end
-expressions.child=function(e,pattern)
- return applylpath(e,pattern)
-end
-expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
-end
-expressions.attribute=function(e,name,value)
- if type(e)=="table" and name then
- local a=e.at
- if a then
- local v=a[name]
- if value then
- return v==value
- else
- return v
- end
- end
- end
- return nil
-end
-expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
- end
- return false
-end
-expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
-end
-expressions.undefined=function(s)
- return s==nil
-end
-expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
-end
-expressions.print=function(...)
- print(...)
- return true
-end
-expressions.find=find
-expressions.upper=upper
-expressions.lower=lower
-expressions.number=tonumber
-expressions.boolean=toboolean
-function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
- end
- return false
-end
-function expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
-end
-local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
- end
-end
-local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
- end
-end
-xml.traverse=traverse
-xml.selection=selection
-local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
- end
-end
-finalizers.xml["function"]=dofunction
-finalizers.tex["function"]=dofunction
-expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
-end
-expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d=e.__p__.dt
- local k=e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d=e.__p__.dt
- local k=e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
- end
- if found then
- local ns=found.rn or found.ns or ""
- local tg=found.tg
- if ns~="" then
- return ns..":"..tg
- else
- return tg
- end
- else
- return ""
- end
-end
-expressions.tag=function(e,n)
- if not e then
- return ""
- else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d=e.__p__.dt
- local k=e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d=e.__p__.dt
- local k=e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
- end
- return (found and found.tg) or ""
- end
-end
-local dummy=function() end
-function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
- end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- end
-end
-function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
- end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
- end
-end
-function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
-end
-local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
- end
- return e
-end
-function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
-
--- original size: 3574, stripped down to: 1808
-
-if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local xml,lpeg,string=xml,lpeg,string
-local type=type
-local concat=table.concat
-local format,gsub,match=string.format,string.gsub,string.match
-local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
-local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
-lpegpatterns.xml=lpegpatterns.xml or {}
-local xmlpatterns=lpegpatterns.xml
-local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
- end
-end
-function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
- end
-end
-local normal=(1-S("<&>"))^0
-local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
-local escaped=Cs(normal*(special*normal)^0)
-local normal=(1-S"&")^0
-local special=P("&lt;")/"<"+P("&gt;")/">"+P("&amp;")/"&"
-local unescaped=Cs(normal*(special*normal)^0)
-local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
-xmlpatterns.escaped=escaped
-xmlpatterns.unescaped=unescaped
-xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
-function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
-function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
-
--- original size: 30771, stripped down to: 19680
-
-if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
-local report_xml=logs.reporter("xml")
-local xml=xml
-local xmlcopy,xmlname=xml.copy,xml.name
-local xmlinheritedconvert=xml.inheritedconvert
-local xmlapplylpath=xml.applylpath
-local type,next,setmetatable,getmetatable=type,next,setmetatable,getmetatable
-local insert,remove,fastcopy,concat=table.insert,table.remove,table.fastcopy,table.concat
-local gmatch,gsub,format,find,strip=string.gmatch,string.gsub,string.format,string.find,string.strip
-local utfbyte=utf.byte
-local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
-local striplinepatterns=utilities.strings.striplinepatterns
-local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
-end
-local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
- end
- end
-end
-xml.withelements=withelements
-function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
- end
- end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
- else
- for c=1,#collected do
- handle(collected[c])
- end
- end
- end
- return collected
- end
-end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
- for c=1,#collected do
- handle(collected[c].at)
- end
- end
- return collected
-end
-function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
-end
-function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
- end
- return collected or {}
-end
-function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t={}
- local n=0
- for c=1,#collected do
- local e=collected[c]
- local ns=e.ns
- local tg=e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
- end
-end
-local no_root={ no_root=true }
-local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
- end
-end
-xml.reindex=redo_ni
-local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
-end
-xml.toelement=xmltoelement
-local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
- end
-end
-function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
- if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
- end
- end
- end
-end
-function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
- end
- end
-end
-local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
-end
-function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
- end
- else
- wrap(root,xmltoelement(pattern))
- end
-end
-local function inject_element(root,pattern,whatever,prepend)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function inject_e(e)
- local r=e.__p__
- local d=r.dt
- local k=e.ni
- local rri=r.ri
- local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
- end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
- end
-end
-local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d=r.dt
- local k=e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
- end
-end
-xml.insert_element=insert_element
-xml.insertafter=insert_element
-xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
-xml.injectafter=inject_element
-xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
-local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
-local settings=xmldata.settings
-local savedresource=settings.currentresource
-settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
-child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
- end
- end
- end
- end
-end
-xml.include=include
-function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
- end
- return default
-end
-local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
- end
-end
-function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
-end
-function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
-end
-local b_collapser=lpegpatterns.b_collapser
-local m_collapser=lpegpatterns.m_collapser
-local e_collapser=lpegpatterns.e_collapser
-local b_stripper=lpegpatterns.b_stripper
-local m_stripper=lpegpatterns.m_stripper
-local e_stripper=lpegpatterns.e_stripper
-local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
- else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
- end
- end
- end
- return e
-end
-xml.stripelement=stripelement
-function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
- end
-end
-local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
- end
- end
-end
-xml.renamespace=renamespace
-function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
- end
-end
-function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
- end
-end
-function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
- end
-end
-function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
- end
-end
-function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
- end
-end
-function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
-end
-function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
-end
-xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
-local entities=characters and characters.entities or nil
-local builtinentities=xml.builtinentities
-function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
- end
-end
-xml.all=xml.each
-xml.insert=xml.insertafter
-xml.inject=xml.injectafter
-xml.after=xml.insertafter
-xml.before=xml.insertbefore
-xml.process=xml.each
-xml.obsolete=xml.obsolete or {}
-local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
-function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
- return ""
-end
-function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
- end
- return ""
-end
-function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
-end
-function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
-end
-function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
-end
-function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
-end
-function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t={ "\n" }
- local n=1
- local i=1
- local nd=#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
- end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
- end
- end
- return x
-end
-local helpers=xml.helpers or {}
-xml.helpers=helpers
-local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
- end
-end
-local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
- end
-end
-function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
- end
-end
-local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
-}
-local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
- end
- end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
- end
- end
- if next(node) then
- return node
- end
-end
-function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
- end
-end
-function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
-
--- original size: 11096, stripped down to: 7702
-
-if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local tonumber,next=tonumber,next
-local concat=table.concat
-local find,lower,upper=string.find,string.lower,string.upper
-local xml=xml
-local finalizers=xml.finalizers.xml
-local xmlfilter=xml.filter
-local xmltostring=xml.tostring
-local xmlserialize=xml.serialize
-local xmlcollected=xml.collected
-local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
-local unescapedentity=xml.unescapedentitylpeg
-local parsedentity=reparsedentity
-local function first(collected)
- return collected and collected[1]
-end
-local function last(collected)
- return collected and collected[#collected]
-end
-local function all(collected)
- return collected
-end
-local reverse=table.reversed
-local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
-end
-local function att(id,name)
- local at=id.at
- return at and at[name]
-end
-local function count(collected)
- return collected and #collected or 0
-end
-local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
-end
-local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
-end
-local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
-end
-local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
- end
-end
-local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
- end
- end
- return ""
-end
-local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
-end
-local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
-}
-local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
-end
-function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
-end
-local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
-end
-local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
-end
-local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
-end
-local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
-end
-local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
-end
-local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
- end
- end
- return true
-end
-finalizers.first=first
-finalizers.last=last
-finalizers.all=all
-finalizers.reverse=reverse
-finalizers.elements=all
-finalizers.default=all
-finalizers.attribute=attribute
-finalizers.att=att
-finalizers.count=count
-finalizers.position=position
-finalizers.match=match
-finalizers.index=index
-finalizers.attributes=attributes
-finalizers.chainattribute=chainattribute
-finalizers.text=text
-finalizers.texts=texts
-finalizers.tag=tag
-finalizers.name=name
-finalizers.tags=tags
-finalizers.empty=empty
-function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
-end
-function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
-end
-function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
-end
-function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
-end
-function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
-end
-function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
-end
-function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
- else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
- end
-end
-xml.content=text
-function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
-end
-function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
-end
-function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
-end
-xml.all=xml.filter
-xml.index=xml.position
-xml.found=xml.filter
-local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
-end
-xml.table=totable
-finalizers.table=totable
-local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
- end
- end
- return t
-end
-function xml.textonly(e)
- return concat(textonly(e,{}))
-end
-function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
- end
- end
-end
-function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
-
--- original size: 6407, stripped down to: 4640
-
-if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local formatters=string.formatters
-local reporters=logs.reporters
-local xmlserialize=xml.serialize
-local xmlcollected=xml.collected
-local xmltext=xml.text
-local xmlfirst=xml.first
-local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
- report()
- report(comment)
- report()
- end
-end
-local reporthelp=reporters.help
-local exporthelp=reporters.export
-local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
- end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
- end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
- end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
-end
-function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
-end
-function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
- else
- t.report("unknown exporter %a",method)
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-ini"] = package.loaded["data-ini"] or true
-
--- original size: 10847, stripped down to: 7086
-
-if not modules then modules={} end modules ['data-ini']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
-}
-local next,type,getmetatable,rawset=next,type,getmetatable,rawset
-local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
-local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
-local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
-local sortedpairs=table.sortedpairs
-local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local report_initialization=logs.reporter("resolvers","initialization")
-resolvers=resolvers or {}
-local resolvers=resolvers
-texconfig.kpse_init=false
-texconfig.shell_escape='t'
-if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
-end
-kpse={ original=kpse }
-setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
-} )
-do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
-end
-do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
-end
-do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
- end
- end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
- end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
-end
-resolvers.ownpath=environment.ownpath
-function resolvers.getownpath()
- return environment.ownpath
-end
-do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
-local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
-if not texos or texos=="" then
- texos=file.basename(texmfos)
-end
-ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
-environment.texos=texos
-environment.texmfos=texmfos
-local texroot=environment.texroot or osgetenv("TEXROOT")
-if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
-end
-environment.texroot=file.collapsepath(texroot)
-local prefixes=utilities.storage.allocate()
-resolvers.prefixes=prefixes
-local resolved={}
-local abstract={}
-local dynamic={}
-function resolvers.resetresolve(str)
- resolved,abstract={},{}
-end
-function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
- end
- return all
-end
-local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
-end
-function resolvers.unresolve(str)
- return abstract[str] or str
-end
-function resolvers.setdynamic(str)
- dynamic[str]=true
-end
-local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
-local prefix=C(R("az")^2)*P(":")
-local target=C((1-S(" \"\';,"))^1)
-local notarget=(#S(";,")+P(-1))*Cc("")
-local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
-local p_simple=prefix*P(-1)
-local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
- end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
- end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
- return res
-end
-resolvers.resolve=resolve
-if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
- end
-end
-if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
- end
-else
- function resolvers.repath(str)
- return str
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-exp"] = package.loaded["data-exp"] or true
-
--- original size: 18179, stripped down to: 10432
-
-if not modules then modules={} end modules ['data-exp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
-}
-local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
-local concat,sort=table.concat,table.sort
-local sortedkeys=table.sortedkeys
-local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
-local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
-local type,next=type,next
-local isdir=lfs.isdir
-local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
-local report_expansions=logs.reporter("resolvers","expansions")
-local report_globbing=logs.reporter("resolvers","globbing")
-local resolvers=resolvers
-local resolveprefix=resolvers.resolve
-local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
- end
- return concat(t,",")
-end
-local comma=P(",")
-local nocomma=(1-comma)^1
-local docomma=comma^1/","
-local before=Cs((nocomma*Carg(1)+docomma)^0)
-local after=Cs((Carg(1)*nocomma+docomma)^0)
-local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
-local function f_first (a,b) return lpegmatch(after,b,1,a) end
-local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
-local left=P("{")
-local right=P("}")
-local var=P((1-S("{}" ))^0)
-local set=P((1-S("{},"))^0)
-local other=P(1)
-local l_first=Cs((Cc("{")*(C(set)*left*C(var)*right/f_first)*Cc("}")+other )^0 )
-local l_second=Cs((Cc("{")*(left*C(var)*right*C(set)/f_second)*Cc("}")+other )^0 )
-local l_both=Cs((Cc("{")*(left*C(var)*right*left*C(var)*right/f_both)*Cc("}")+other )^0 )
-local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
-local stripper_1=lpeg.stripper ("{}@")
-local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
-local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
- repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
- end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
- end
- return t
-end
-local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
-end
-resolvers.validatedpath=validate
-function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
-end
-local usedhomedir=nil
-local donegation=(P("!")/"" )^0
-local doslashes=(P("\\")/"/"+1)^0
-local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
- end
- return usedhomedir
-end
-local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
-local cleanup=Cs(donegation*dohome*doslashes)
-resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
-end
-local expandhome=P("~")/"$HOME"
-local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
-local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
-local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
-)
-function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
-end
-local cache={}
-local splitter=lpeg.tsplitat(";")
-local backslashswapper=lpeg.replacer("\\","/")
-local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
- end
- return found
- end
-end
-resolvers.splitconfigurationpath=splitconfigurationpath
-function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
-end
-function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
-end
-local attributes,directory=lfs.attributes,lfs.dir
-local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
-local lessweird=P(".")^1+lpeg.anywhere(S("~`#$%^&*:;\"\'||<>,?\n\r\t"))
-local timer={}
-local scanned={}
-local nofscans=0
-local scancache={}
-local fullcache={}
-local nofsharedscans=0
-local addcasecraptoo=true
-local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name,mode in directory(full) do
- if not lpegmatch(pattern,name) then
- if not mode then
- mode=attributes(full..name,"mode")
- end
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
- end
- end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
- end
- end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
- end
- end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
-end
-local function scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
- if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
- end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
- end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
-end
-resolvers.scanfiles=scanfiles
-function resolvers.simplescanfiles(path,branch,usecache)
- return scanfiles(path,branch,usecache,true,true)
-end
-function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
-end
-function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
-end
-local nothing=function() end
-function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
- end
- end
- return nothing
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-env"] = package.loaded["data-env"] or true
-
--- original size: 9400, stripped down to: 6347
-
-if not modules then modules={} end modules ['data-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
-}
-local lower,gsub=string.lower,string.gsub
-local next,rawget=next,rawget
-local resolvers=resolvers
-local allocate=utilities.storage.allocate
-local setmetatableindex=table.setmetatableindex
-local suffixonly=file.suffixonly
-local formats=allocate()
-local suffixes=allocate()
-local dangerous=allocate()
-local suffixmap=allocate()
-local usertypes=allocate()
-resolvers.formats=formats
-resolvers.suffixes=suffixes
-resolvers.dangerous=dangerous
-resolvers.suffixmap=suffixmap
-resolvers.usertypes=usertypes
-local luasuffixes=utilities.lua.suffixes
-local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpxl','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkiv","mkvi","mkxl","mklx","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
- },
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
- },
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
- },
-}
-resolvers.relations=relations
-function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
- end
- end
- end
-end
-resolvers.updaterelations()
-local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
-end
-setmetatableindex(formats,simplified)
-setmetatableindex(suffixes,simplified)
-setmetatableindex(suffixmap,simplified)
-function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
-end
-function resolvers.suffixofformat(str)
- return suffixes[str] or {}
-end
-for name,format in next,formats do
- dangerous[name]=true
-end
-dangerous.tex=nil
-function resolvers.formatofvariable(str)
- return formats[str] or ''
-end
-function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
-end
-function resolvers.variableofformat(str)
- return formats[str] or ''
-end
-function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
-
--- original size: 16099, stripped down to: 11379
-
-if not modules then modules={} end modules ['data-tmp']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local next,type=next,type
-local pcall,loadfile,collectgarbage=pcall,loadfile,collectgarbage
-local format,lower,gsub=string.format,string.lower,string.gsub
-local concat,serialize,fastserialize,serializetofile=table.concat,table.serialize,table.fastserialize,table.tofile
-local mkdirs,expanddirname,isdir,isfile=dir.mkdirs,dir.expandname,lfs.isdir,lfs.isfile
-local is_writable,is_readable=file.is_writable,file.is_readable
-local collapsepath,joinfile,addsuffix,dirname=file.collapsepath,file.join,file.addsuffix,file.dirname
-local savedata=file.savedata
-local formatters=string.formatters
-local osexit,osdate,osuuid=os.exit,os.date,os.uuid
-local removefile=os.remove
-local md5hex=md5.hex
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local report_caches=logs.reporter("resolvers","caches")
-local report_resolvers=logs.reporter("resolvers","caching")
-local resolvers=resolvers
-local cleanpath=resolvers.cleanpath
-local resolvepath=resolvers.resolve
-local luautilities=utilities.lua
-do
- local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
- local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
- local compilelua=luautilities.compile
- function luautilities.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compilelua(luafile,lucfile,cleanup,strip)
- end
-end
-caches=caches or {}
-local caches=caches
-local writable=nil
-local readables={}
-local usedreadables={}
-local compilelua=luautilities.compile
-local luasuffixes=luautilities.suffixes
-caches.base=caches.base or "luatex-cache"
-caches.more=caches.more or "context"
-caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
-local direct_cache=false
-local fast_cache=false
-local cache_tree=false
-directives.register("system.caches.direct",function(v) direct_cache=true end)
-directives.register("system.caches.fast",function(v) fast_cache=true end)
-local function configfiles()
- return concat(resolvers.configurationfiles(),";")
-end
-local function hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
-end
-local function treehash()
- local tree=configfiles()
- if not tree or tree=="" then
- return false
- else
- return hashed(tree)
- end
-end
-caches.hashed=hashed
-caches.treehash=treehash
-caches.configfiles=configfiles
-local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvepath(cachepath)
- cachepath=cleanpath(cachepath)
- cachepath=collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable then
- local cacheparent=dirname(cachepath)
- if is_writable(cacheparent) then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvepath(cachepath)
- cachepath=cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
- end
- end
- end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- osexit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- osexit()
- end
- writable=expanddirname(cleanpath(writable))
- local base=caches.base
- local more=caches.more
- local tree=cache_tree or treehash()
- if tree then
- cache_tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=joinfile(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=joinfile(readables[i],base,more)
- end
- end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
- end
- identify=function()
- return writable,readables
- end
- return writable,readables
-end
-function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
- end
-end
-local r_cache={}
-local w_cache={}
-local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=joinfile(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
- end
- return done
-end
-local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
- end
- return done
-end
-local function setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=joinfile(wr,filename)
- return fullname,wr
-end
-local function setluanames(path,name)
- return
- format("%s/%s.%s",path,name,luasuffixes.tma),
- format("%s/%s.%s",path,name,luasuffixes.tmc)
-end
-local function getfirstreadablefile(filename,...)
- local fullname,path=setfirstwritablefile(filename,...)
- if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=joinfile(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
- end
- return fullname,path
-end
-caches.getreadablepaths=getreadablepaths
-caches.getwritablepath=getwritablepath
-caches.setfirstwritablefile=setfirstwritablefile
-caches.getfirstreadablefile=getfirstreadablefile
-caches.setluanames=setluanames
-function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
- end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local state=false
- local tmaname,tmcname=setluanames(path,name)
- if isfile(tmcname) then
- state,loader=pcall(loadfile,tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=setluanames(writable,name)
- if isfile(tmcname) then
- state,loader=pcall(loadfile,tmcname)
- end
- compilelua(tmaname,tmcname)
- if isfile(tmcname) then
- state,loader=pcall(loadfile,tmcname)
- end
- if not loader then
- state,loader=pcall(loadfile,tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
- end
- return false
-end
-function caches.is_writable(filepath,filename)
- local tmaname,tmcname=setluanames(filepath,filename)
- return is_writable(tmaname)
-end
-local saveoptions={ compact=true,accurate=not JITSUPPORTED }
-function caches.savedata(filepath,filename,data,fast)
- local tmaname,tmcname=setluanames(filepath,filename)
- data.cache_uuid=osuuid()
- if fast or fast_cache then
- savedata(tmaname,fastserialize(data,true))
- elseif direct_cache then
- savedata(tmaname,serialize(data,true,saveoptions))
- else
- serializetofile(tmaname,data,true,saveoptions)
- end
- compilelua(tmaname,tmcname)
-end
-local content_state={}
-function caches.contentstate()
- return content_state or {}
-end
-function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=hashed(cachename)
- local full,path=getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=joinfile(path,name)
- end
- local state,blob=pcall(loadfile,addsuffix(filename,luasuffixes.luc))
- if not blob then
- state,blob=pcall(loadfile,addsuffix(filename,luasuffixes.lua))
- end
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
- end
-end
-function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
- end
-end
-function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=hashed(cachename)
- local full,path=setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=joinfile(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
- if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=osdate("%Y-%m-%d"),
- time=osdate("%H:%M:%S"),
- content=content,
- uuid=osuuid(),
- }
- local ok=savedata(luaname,serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if compilelua(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- removefile(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-met"] = package.loaded["data-met"] or true
-
--- original size: 5518, stripped down to: 3854
-
-if not modules then modules={} end modules ['data-met']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type=type
-local find=string.find
-local addurlscheme,urlhashed=url.addscheme,url.hashed
-local collapsepath,joinfile=file.collapsepath,file.join
-local report_methods=logs.reporter("resolvers","methods")
-local trace_locating=false
-local trace_methods=false
-trackers.register("resolvers.locating",function(v) trace_methods=v end)
-trackers.register("resolvers.methods",function(v) trace_methods=v end)
-local allocate=utilities.storage.allocate
-local resolvers=resolvers
-local registered={}
-local function splitmethod(filename)
- if not filename then
- return {
- scheme="unknown",
- original=filename,
- }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return {
- scheme="file",
- path=filename,
- original=filename,
- filename=filename,
- }
- end
- local specification=urlhashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return {
- scheme="file",
- path=filename,
- original=filename,
- filename=filename,
- }
- else
- return specification
- end
-end
-resolvers.splitmethod=splitmethod
-local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how=method.how
- local namespace=method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
- end
- else
- report_methods("resolving, invalid method %a")
- end
-end
-resolvers.methodhandler=methodhandler
-function resolvers.registermethod(name,namespace,how)
- registered[name]={
- how=how or "tag",
- namespace=namespace
- }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
- end
-end
-local concatinators=allocate { notfound=joinfile }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
-resolvers.concatinators=concatinators
-resolvers.locators=locators
-resolvers.hashers=hashers
-resolvers.generators=generators
-local registermethod=resolvers.registermethod
-registermethod("concatinators",concatinators,"tag")
-registermethod("locators",locators,"uri")
-registermethod("hashers",hashers,"uri")
-registermethod("generators",generators,"uri")
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-res"] = package.loaded["data-res"] or true
-
--- original size: 69576, stripped down to: 44470
-
-if not modules then modules={} end modules ['data-res']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
-}
-local gsub,find,lower,upper,match,gmatch=string.gsub,string.find,string.lower,string.upper,string.match,string.gmatch
-local concat,insert,remove=table.concat,table.insert,table.remove
-local next,type,rawget,loadfile=next,type,rawget,loadfile
-local mergedtable=table.merged
-local os=os
-local P,S,R,C,Cc,Cs,Ct,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Carg
-local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
-local formatters=string.formatters
-local filedirname=file.dirname
-local filebasename=file.basename
-local suffixonly=file.suffixonly
-local addsuffix=file.addsuffix
-local removesuffix=file.removesuffix
-local filejoin=file.join
-local collapsepath=file.collapsepath
-local joinpath=file.joinpath
-local is_qualified_path=file.is_qualified_path
-local allocate=utilities.storage.allocate
-local settings_to_array=utilities.parsers.settings_to_array
-local urlhasscheme=url.hasscheme
-local getcurrentdir=lfs.currentdir
-local isfile=lfs.isfile
-local isdir=lfs.isdir
-local setmetatableindex=table.setmetatableindex
-local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_details=false trackers .register("resolvers.details",function(v) trace_details=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
-local report_resolving=logs.reporter("resolvers","resolving")
-local resolvers=resolvers
-local expandedpathfromlist=resolvers.expandedpathfromlist
-local checkedvariable=resolvers.checkedvariable
-local splitconfigurationpath=resolvers.splitconfigurationpath
-local methodhandler=resolvers.methodhandler
-local filtered=resolvers.filtered_from_content
-local lookup=resolvers.get_from_content
-local cleanpath=resolvers.cleanpath
-local resolveprefix=resolvers.resolve
-local initializesetter=utilities.setters.initialize
-local ostype,osname,osenv,ossetenv,osgetenv=os.type,os.name,os.env,os.setenv,os.getenv
-resolvers.cacheversion="1.100"
-resolvers.configbanner=""
-resolvers.homedir=environment.homedir
-resolvers.luacnfname="texmfcnf.lua"
-resolvers.luacnffallback="contextcnf.lua"
-resolvers.luacnfstate="unknown"
-local criticalvars={
- "SELFAUTOLOC",
- "SELFAUTODIR",
- "SELFAUTOPARENT",
- "TEXMFCNF",
- "TEXMF",
- "TEXOS",
-}
-if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
-else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
-end
-local unset_variable="unset"
-local formats=resolvers.formats
-local suffixes=resolvers.suffixes
-local usertypes=resolvers.usertypes
-local dangerous=resolvers.dangerous
-local suffixmap=resolvers.suffixmap
-resolvers.defaultsuffixes={ "tex" }
-local instance=nil
-local variable
-local expansion
-local setenv
-local getenv
-local formatofsuffix=resolvers.formatofsuffix
-local splitpath=resolvers.splitpath
-local splitmethod=resolvers.splitmethod
-setenv=function(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
-end
-getenv=function(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
-end
-resolvers.getenv=getenv
-resolvers.setenv=setenv
-local dollarstripper=lpeg.stripper("$")
-local inhibitstripper=P("!")^0*Cs(P(1)^0)
-local expandedvariable,resolvedvariable do
- local function resolveinstancevariable(k)
- return instance.expansions[k]
- end
- local p_variable=P("$")/""
- local p_key=C(R("az","AZ","09","__","--")^1)
- local p_whatever=P(";")*((1-S("!{}/\\"))^1*P(";")/"")+P(";")*(P(";")/"")+P(1)
- local variableexpander=Cs((p_variable*(p_key/resolveinstancevariable)+p_whatever)^1 )
- local p_cleaner=P("\\")/"/"+P(";")*S("!{}/\\")^0*P(";")^1/";"
- local variablecleaner=Cs((p_cleaner+P(1))^0)
- local p_variable=R("az","AZ","09","__","--")^1/resolveinstancevariable
- local p_variable=(P("$")/"")*(p_variable+(P("{")/"")*p_variable*(P("}")/""))
- local variableresolver=Cs((p_variable+P(1))^0)
- expandedvariable=function(var)
- return lpegmatch(variableexpander,var) or var
- end
- function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
- t[k]=v
- return v
- end)
- local repath=resolvers.repath
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
- t[k]=v
- return v
- end)
- end
-end
-function resolvers.initialized()
- return instance~=nil
-end
-local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
-end
-local function reset_caches()
- instance.lists={}
- instance.pathlists=false
-end
-local makepathexpression do
- local slash=P("/")
- local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
-+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
- )
- local cache={}
- makepathexpression=function(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
- end
- end
-end
-local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#criticalvars do
- local k=criticalvars[i]
- local v=getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
- end
- reportcriticalvariables=function() end
-end
-local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
- if trace_locating then
- report_resolving()
- end
- elseif trace_locating then
- report_resolving("configuration files already identified")
- end
-end
-local function load_configuration_files()
- local specification=instance.specification
- local setups=instance.setups
- local order=instance.order
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=mergedtable(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
- end
- order[#order+1]=setups[pathname]
- if instance.loaderror then
- break
- end
- end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
- end
-end
-local expandedpathlist
-local unexpandedpathlist
-function resolvers.configurationfiles()
- return instance.specification or {}
-end
-local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
- end
-end
-local function locate_file_databases()
- local texmfpaths=expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
- end
- if trace_locating then
- report_resolving()
- end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
- end
- if trace_locating then
- report_resolving()
- end
-end
-local function save_file_databases()
- local hashes=instance.hashes
- local files=instance.files
- for i=1,#hashes do
- local hash=hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
- end
-end
-function resolvers.renew(hashname)
- local files=instance.files
- if hashname and hashname~="" then
- local expanded=expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
- end
-end
-local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
- end
-end
-function resolvers.appendhash(type,name,cache)
- local hashed=instance.hashed
- local hashes=instance.hashes
- if hashed[name] then
- else
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(hashes,{ type=type,name=name,cache=cache } )
- hashed[name]=cache
- end
-end
-function resolvers.prependhash(type,name,cache)
- local hashed=instance.hashed
- local hashes=instance.hashes
- if hashed[name] then
- else
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(hashes,1,{ type=type,name=name,cache=cache } )
- hashed[name]=cache
- end
-end
-function resolvers.extendtexmfvariable(specification)
- local environment=instance.environment
- local variables=instance.variables
- local texmftrees=splitpath(getenv("TEXMF"))
- insert(texmftrees,1,specification)
- texmftrees=concat(texmftrees,",")
- if environment["TEXMF"] then
- environment["TEXMF"]=texmftrees
- elseif variables["TEXMF"] then
- variables["TEXMF"]=texmftrees
- else
- end
- reset_hashes()
-end
-function resolvers.splitexpansions()
- local expansions=instance.expansions
- for k,v in next,expansions do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if tn>1 then
- expansions[k]=t
- else
- expansions[k]=t[1]
- end
- end
-end
-function resolvers.datastate()
- return caches.contentstate()
-end
-variable=function(name)
- local variables=instance.variables
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and variables[name]
- return result~=nil and result or ""
-end
-expansion=function(name)
- local expansions=instance.expansions
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and expansions[name]
- return result~=nil and result or ""
-end
-resolvers.variable=variable
-resolvers.expansion=expansion
-unexpandedpathlist=function(str)
- local pth=variable(str)
- local lst=splitpath(pth)
- return expandedpathfromlist(lst)
-end
-function resolvers.unexpandedpath(str)
- return joinpath(unexpandedpathlist(str))
-end
-function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
-end
-function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
-end
-function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
-end
-local done={}
-function resolvers.resetextrapaths()
- local extra_paths=instance.extra_paths
- if not extra_paths then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
-end
-function resolvers.getextrapaths()
- return instance.extra_paths or {}
-end
-function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local extra_paths=instance.extra_paths or {}
- local oldn=#extra_paths
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- extra_paths[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- extra_paths[newn]=cleanpath(p)
- done[p]=true
- end
- end
- end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=extra_paths[i].."/"..s
- if not done[ps] then
- newn=newn+1
- extra_paths[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- end
- if newn>0 then
- instance.extra_paths=extra_paths
- end
- if newn~=oldn then
- reset_caches()
- end
-end
-function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- local extra_stack=instance.extra_stack
- if extra_stack then
- insert(extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
-end
-function resolvers.popextrapath()
- local extra_stack=instance.extra_stack
- if extra_stack then
- reset_caches()
- return remove(extra_stack,1)
- end
-end
-local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
- end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
- end
- if extra_too then
- local extra_stack=instance.extra_stack
- local extra_paths=instance.extra_paths
- if extra_stack and #extra_stack>0 then
- for k=1,#extra_stack do
- add(extra_stack[k])
- end
- end
- if extra_paths and #extra_paths>0 then
- add(extra_paths)
- end
- end
- add(list)
- return new
-end
-expandedpathlist=function(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,splitpath(expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=splitpath(expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
- end
-end
-resolvers.expandedpathlist=expandedpathlist
-resolvers.unexpandedpathlist=unexpandedpathlist
-function resolvers.cleanpathlist(str)
- local t=expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
- end
- return t
-end
-function resolvers.expandpath(str)
- return joinpath(expandedpathlist(str))
-end
-local function expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return expandedpathlist(tmp~="" and tmp or str)
-end
-function resolvers.expandpathfromvariable(str)
- return joinpath(expandedpathlistfromvariable(str))
-end
-resolvers.expandedpathlistfromvariable=expandedpathlistfromvariable
-function resolvers.cleanedpathlist(v)
- local t=expandedpathlist(v)
- for i=1,#t do
- t[i]=resolveprefix(cleanpath(t[i]))
- end
- return t
-end
-function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(splitpath(str))
- return joinpath(pth)
-end
-function resolvers.registerfilehash(name,content,someerror)
- local files=instance.files
- if content then
- files[name]=content
- else
- files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
- end
-end
-function resolvers.getfilehashes()
- return instance and instance.files or {}
-end
-function resolvers.gethashes()
- return instance and instance.hashes or {}
-end
-function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
-end
-local function isreadable(name)
- local readable=isfile(name)
- if trace_details then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
- end
- return readable
-end
-local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_details then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
- end
- for k=1,#names do
- local filename=names[k]
- if trace_details then
- report_resolving("checking name %a",filename)
- end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- local files=instance.files
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and files[hashname]
- if content then
- if trace_details then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
- end
- end
- end
- return noffiles>0 and filelist or nil
-end
-local fit={}
-function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
-end
-function resolvers.foundintrees()
- return instance.foundintrees or {}
-end
-function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
-end
-local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
- end
- return fakepaths[name]==1
-end
-local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
-local collect_instance_files
-local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
- end
- else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
- end
- end
- return filetype,wantedfiles
-end
-local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_details then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
- end
-end
-local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
- if trace_locating then
- report_resolving("checking qualified name %a",filename)
- end
- if isreadable(filename) then
- if trace_details then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
- end
- if trace_details then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local suffix=format_suffixes[i]
- forcedname=filename.."."..suffix
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",suffix)
- end
- return "qualified",{ forcedname }
- end
- end
- end
- end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=formatofsuffix(suffix)
- end
- if not format then
- askedformat="othertextfiles"
- end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
- end
- end
-end
-local function check_subpath(fname)
- if isreadable(fname) then
- if trace_details then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
- end
-end
-local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=urlhasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
-end
-local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
- end
- end
- if trace_details then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
- if trace_details then
- report_resolving("using pattern %a for path %a",expression,pathname)
- end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_details then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_details then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_details then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
- end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_details then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_details then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
- end
- else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- if #result>0 then
- return method,result
- end
- end
-end
-local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_details then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
- end
-end
-local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
-end
-collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result={}
- local status={}
- local done={}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_details then
- report_resolving("lookup status: %s",table.serialize(status,filename))
- end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
- end
- method,result=find_direct(filename)
- if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
- end
- instance.found[stamp]=result
- end
- return result
- end
-end
-local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- if allresults==nil then
- allresults=true
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
- end
- return result or {},status
-end
-local function findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
-end
-resolvers.findfiles=findfiles
-resolvers.findfile=findfile
-resolvers.find_file=findfile
-resolvers.find_files=findfiles
-function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
-end
-local function findgivenfiles(filename,allresults)
- local hashes=instance.hashes
- local files=instance.files
- local base=filebasename(filename)
- local result={}
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
- end
- end
- return result
-end
-function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
-end
-function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
-end
-local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
-)
-function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
-end
-local function findwildcardfiles(filename,allresults,result)
- local files=instance.files
- local hashes=instance.hashes
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- if find(name,"*",1,true) then
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
- end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
- end
- end
- return result
-end
-function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
-end
-function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
-end
-do
- local starttiming=statistics.starttiming
- local stoptiming=statistics.stoptiming
- local elapsedtime=statistics.elapsedtime
- function resolvers.starttiming()
- starttiming(instance)
- end
- function resolvers.stoptiming()
- stoptiming(instance)
- end
- function resolvers.loadtime()
- return elapsedtime(instance)
- end
-end
-function resolvers.automount()
-end
-function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
-end
-local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
-end
-function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
- end
- end
-end
-function resolvers.showpath(str)
- return joinpath(expandedpathlist(resolvers.formatofvariable(str)))
-end
-function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
- else
- files[name]=path
- end
-end
-function resolvers.dowithpath(name,func)
- local pathlist=expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
-end
-function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
-end
-function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(file.basename(name))
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return fmtname,luiname
- elseif isfile(lucname) then
- return fmtname,lucname
- elseif isfile(luaname) then
- return fmtname,luaname
- end
- end
- return nil,nil
-end
-function resolvers.booleanvariable(str,default)
- local b=expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
-end
-function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- local files=instance.files
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,checked,done)
- end
- end
- end
-end
-function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
- end
- return result
- else
- return {}
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-pre"] = package.loaded["data-pre"] or true
-
--- original size: 5088, stripped down to: 3144
-
-if not modules then modules={} end modules ['data-pre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local insert,remove=table.insert,table.remove
-local resolvers=resolvers
-local prefixes=resolvers.prefixes
-local cleanpath=resolvers.cleanpath
-local findgivenfile=resolvers.findgivenfile
-local expansion=resolvers.expansion
-local getenv=resolvers.getenv
-local basename=file.basename
-local dirname=file.dirname
-local joinpath=file.join
-local isfile=lfs.isfile
-prefixes.environment=function(str)
- return cleanpath(expansion(str))
-end
-local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
- if isfile(pstr) then
- str=pstr
- else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
- end
- end
- return cleanpath(str)
-end
-local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
-end
-prefixes.relative=relative
-prefixes.locate=locate
-prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
-end
-prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
-end
-prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
-end
-prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
-end
-prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
-end
-prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
-end
-prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
-end
-prefixes.env=prefixes.environment
-prefixes.rel=prefixes.relative
-prefixes.loc=prefixes.locate
-prefixes.kpse=prefixes.locate
-prefixes.full=prefixes.locate
-prefixes.file=prefixes.filename
-prefixes.path=prefixes.pathname
-local inputstack={}
-local stackpath=resolvers.stackpath
-local function toppath()
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
-end
-local function jobpath()
- local path=stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
-end
-local function pushinputname(name)
- insert(inputstack,name)
-end
-local function popinputname(name)
- return remove(inputstack)
-end
-resolvers.toppath=toppath
-resolvers.jobpath=jobpath
-resolvers.pushinputname=pushinputname
-resolvers.popinputname=popinputname
-prefixes.toppath=function(str) return cleanpath(joinpath(toppath(),str)) end
-prefixes.jobpath=function(str) return cleanpath(joinpath(jobpath(),str)) end
-resolvers.setdynamic("toppath")
-resolvers.setdynamic("jobpath")
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-inp"] = package.loaded["data-inp"] or true
-
--- original size: 910, stripped down to: 818
-
-if not modules then modules={} end modules ['data-inp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local allocate=utilities.storage.allocate
-local resolvers=resolvers
-local methodhandler=resolvers.methodhandler
-local registermethod=resolvers.registermethod
-local finders=allocate { helpers={},notfound=function() end }
-local openers=allocate { helpers={},notfound=function() end }
-local loaders=allocate { helpers={},notfound=function() return false,nil,0 end }
-registermethod("finders",finders,"uri")
-registermethod("openers",openers,"uri")
-registermethod("loaders",loaders,"uri")
-resolvers.finders=finders
-resolvers.openers=openers
-resolvers.loaders=loaders
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-out"] = package.loaded["data-out"] or true
-
--- original size: 551, stripped down to: 470
-
-if not modules then modules={} end modules ['data-out']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local allocate=utilities.storage.allocate
-local resolvers=resolvers
-local registermethod=resolvers.registermethod
-local savers=allocate { helpers={} }
-resolvers.savers=savers
-registermethod("savers",savers,"uri")
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-fil"] = package.loaded["data-fil"] or true
-
--- original size: 4365, stripped down to: 3588
-
-if not modules then modules={} end modules ['data-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local ioopen=io.open
-local isdir=lfs.isdir
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local report_files=logs.reporter("resolvers","files")
-local resolvers=resolvers
-local resolveprefix=resolvers.resolve
-local findfile=resolvers.findfile
-local scanfiles=resolvers.scanfiles
-local registerfilehash=resolvers.registerfilehash
-local appendhash=resolvers.appendhash
-local loadcachecontent=caches.loadcontent
-local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
-function resolvers.locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
- end
-end
-function resolvers.hashers.file(specification)
- local pathname=specification.filename
- local content=loadcachecontent(pathname,'files')
- registerfilehash(pathname,content,content==nil)
-end
-function resolvers.generators.file(specification)
- local pathname=specification.filename
- local content=scanfiles(pathname,false,true)
- registerfilehash(pathname,content,true)
-end
-resolvers.concatinators.file=file.join
-local finders=resolvers.finders
-local notfound=finders.notfound
-function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return notfound()
- end
-end
-local openers=resolvers.openers
-local notfound=openers.notfound
-local overloaded=false
-local function textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() return f:close() end,
- }
-end
-function openers.helpers.textopener(...)
- return textopener(...)
-end
-function openers.helpers.settextopener(opener)
- if overloaded then
- report_files("file opener: %s overloaded","already")
- else
- if trace_locating then
- report_files("file opener: %s overloaded","once")
- end
- overloaded=true
- textopener=opener
- end
-end
-function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=ioopen(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
- end
- return notfound()
-end
-local loaders=resolvers.loaders
-local notfound=loaders.notfound
-function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=ioopen(filename,"rb")
- if f then
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
- end
- return notfound()
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-con"] = package.loaded["data-con"] or true
-
--- original size: 5388, stripped down to: 3685
-
-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 -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-use"] = package.loaded["data-use"] or true
-
--- original size: 5790, stripped down to: 2910
-
-if not modules then modules={} end modules ['data-use']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local format=string.format
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local report_mounts=logs.reporter("resolvers","mounts")
-local resolvers=resolvers
-local findfile=resolvers.findfile
-statistics.register("used config file",function() return caches.configfiles() end)
-statistics.register("used cache path",function() return caches.usedpaths() end)
-function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- formatid=LUATEXFORMATID,
- functionality=LUATEXFUNCTIONALITY,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- if jit then
- logs.report("format banner","%s lua: %s jit",banner,LUAVERSION)
- else
- logs.report("format banner","%s lua: %s",banner,LUAVERSION)
- end
- logs.newline()
- end)
- end
-end
-function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- local engluaversion=LUAVERSION or 0
- if luvluaversion~=engluaversion then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,engluaversion)
- end
- local luvfunctionality=luv.functionality or 0
- local engfunctionality=status.development_id or 0
- if luvfunctionality~=engfunctionality then
- return format("functionality mismatch (luv: %s <> bin: %s)",luvfunctionality,engfunctionality)
- end
- local luvformatid=luv.formatid or 0
- local engformatid=status.format_id or 0
- if luvformatid~=engformatid then
- return format("formatid mismatch (luv: %s <> bin: %s)",luvformatid,engformatid)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
- end
- return true
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-zip"] = package.loaded["data-zip"] or true
-
--- original size: 10725, stripped down to: 7949
-
-if not modules then modules={} end modules ['data-zip']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local report_zip=logs.reporter("resolvers","zip")
-local resolvers=resolvers
-local findfile=resolvers.findfile
-local registerfile=resolvers.registerfile
-local splitmethod=resolvers.splitmethod
-local prependhash=resolvers.prependhash
-local starttiming=resolvers.starttiming
-local extendtexmf=resolvers.extendtexmfvariable
-local stoptiming=resolvers.stoptiming
-local urlquery=url.query
-zip=zip or {}
-local zip=zip
-local archives=zip.archives or {}
-zip.archives=archives
-local registeredfiles=zip.registeredfiles or {}
-zip.registeredfiles=registeredfiles
-local zipfiles=utilities.zipfiles
-local openzip,closezip,validfile,wholefile,filehandle,traversezip
-if zipfiles then
- local ipairs=ipairs
- openzip=zipfiles.open
- closezip=zipfiles.close
- validfile=zipfiles.found
- wholefile=zipfiles.unzip
- local listzip=zipfiles.list
- traversezip=function(zfile)
- return ipairs(listzip(zfile))
- end
- local streams=utilities.streams
- local openstream=streams.open
- local readstring=streams.readstring
- local streamsize=streams.size
- local metatable={
- close=streams.close,
- read=function(stream,n)
- readstring(stream,n=="*a" and streamsize(stream) or n)
- end
- }
- filehandle=function(zfile,queryname)
- local data=wholefile(zfile,queryname)
- if data then
- local stream=openstream(data)
- if stream then
- return setmetatableindex(stream,metatable)
- end
- end
- end
-else
- openzip=zip.open
- closezip=zip.close
- validfile=function(zfile,queryname)
- local dfile=zfile:open(queryname)
- if dfile then
- dfile:close()
- return true
- end
- return false
- end
- traversezip=function(zfile)
- return z:files()
- end
- wholefile=function(zfile,queryname)
- local dfile=zfile:open(queryname)
- if dfile then
- local s=dfile:read("*all")
- dfile:close()
- return s
- end
- end
- filehandle=function(zfile,queryname)
- local dfile=zfile:open(queryname)
- if dfile then
- return dfile
- end
- end
-end
-local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
-end
-local function openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=findfile(name) or ""
- arch=full~="" and openzip(full) or false
- archives[name]=arch
- end
- return arch
- end
-end
-local function closearchive(name)
- if not name or (name=="" and archives[name]) then
- closezip(archives[name])
- archives[name]=nil
- end
-end
-zip.openarchive=openarchive
-zip.closearchive=closearchive
-function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
- end
-end
-function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
-end
-local finders=resolvers.finders
-local notfound=finders.notfound
-function finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=urlquery(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- if validfile(zfile,queryname) then
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
- end
- end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return notfound()
-end
-local openers=resolvers.openers
-local notfound=openers.notfound
-local textopener=openers.helpers.textopener
-function openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=urlquery(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local handle=filehandle(zfile,queryname)
- if handle then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return textopener('zip',original,handle)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
- end
- end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return notfound()
-end
-local loaders=resolvers.loaders
-local notfound=loaders.notfound
-function loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=urlquery(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local data=wholefile(zfile,queryname)
- if data then
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- return true,data,#data
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
- end
- end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return notfound()
-end
-local function registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- starttiming()
- for i in traversezip(z) do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- registerfile(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
- end
- stoptiming()
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
-end
-local function usezipfile(archive)
- local specification=splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=openarchive(archive)
- if z then
- local tree=urlquery(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- prependhash('zip',archive)
- extendtexmf(archive)
- registeredfiles[archive]=z
- registerfilehash(archive,registerzipfile(z,tree))
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
- elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
- end
-end
-resolvers.usezipfile=usezipfile
-resolvers.registerzipfile=registerzipfile
-function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- usezipfile(specification.original)
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-tre"] = package.loaded["data-tre"] or true
-
--- original size: 10802, stripped down to: 6619
-
-if not modules then modules={} end modules ['data-tre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type=type
-local find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file.join
-local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
-local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local report_trees=logs.reporter("resolvers","trees")
-local resolvers=resolvers
-local finders=resolvers.finders
-local openers=resolvers.openers
-local loaders=resolvers.loaders
-local locators=resolvers.locators
-local hashers=resolvers.hashers
-local generators=resolvers.generators
-do
- local collectors={}
- local found={}
- local notfound=finders.notfound
- function finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
- end
- okay=notfound()
- found[spec]=okay
- end
- return okay
- end
-end
-do
- local resolveprefix=resolvers.resolve
- local appendhash=resolvers.appendhash
- local function dolocate(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
- end
- end
- locators.tree=dolocate
- locators.dirlist=dolocate
- locators.dirfile=dolocate
-end
-do
- local filegenerator=generators.file
- generators.dirlist=filegenerator
- generators.dirfile=filegenerator
-end
-do
- local filegenerator=generators.file
- local methodhandler=resolvers.methodhandler
- local function dohash(specification)
- local name=specification.filename
- if trace_locating then
- report_trees("analyzing %a",name)
- end
- methodhandler("hashers",name)
- filegenerator(specification)
- end
- hashers.tree=dohash
- hashers.dirlist=dohash
- hashers.dirfile=dohash
-end
-local resolve do
- local collectors={}
- local splitter=lpeg.splitat("/**/")
- local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
- local loadcontent=caches.loadcontent
- local savecontent=caches.savecontent
- local notfound=finders.notfound
- local scanfiles=resolvers.scanfiles
- local lookup=resolvers.get_from_content
- table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=loadcontent(dataname,"files",dataname)
- if not content then
- content=scanfiles(rootname,nil,nil,false,true)
- savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
- end)
- local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- return notfound()
- end
- resolve=function(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
- end
- end
- local path=dirname(filename)
- local name=basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
- end
- end
- return notfound()
- end
- finders.dirlist=resolve
- function finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
- end
-end
-do
- local fileopener=openers.file
- local fileloader=loaders.file
- openers.dirlist=fileopener
- loaders.dirlist=fileloader
- openers.dirfile=fileopener
- loaders.dirfile=fileloader
-end
-do
- local hashfile="dirhash.lua"
- local kind="HASH256"
- local version=1.0
- local loadtable=table.load
- local savetable=table.save
- local loaddata=io.loaddata
- function resolvers.dirstatus(patterns)
- local t=type(patterns)
- if t=="string" then
- patterns={ patterns }
- elseif t~="table" then
- return false
- end
- local status=loadtable(hashfile)
- if not status or status.version~=version or status.kind~=kind then
- status={
- version=1.0,
- kind=kind,
- hashes={},
- }
- end
- local hashes=status.hashes
- local changed={}
- local action=sha2[kind]
- local update={}
- for i=1,#patterns do
- local pattern=patterns[i]
- local files=globdir(pattern)
- for i=1,#files do
- local name=files[i]
- local hash=action(loaddata(name))
- if hashes[name]~=hash then
- changed[#changed+1]=name
- end
- update[name]=hash
- end
- end
- status.hashes=update
- savetable(hashfile,status)
- return #changed>0 and changed or false
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-sch"] = package.loaded["data-sch"] or true
-
--- original size: 6945, stripped down to: 5408
-
-if not modules then modules={} end modules ['data-sch']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local load,tonumber=load,tonumber
-local gsub,format=string.gsub,string.format
-local sortedhash,concat=table.sortedhash,table.concat
-local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local addsuffix,suffix,splitbase=file.addsuffix,file.suffix,file.splitbase
-local md5hex=md5.hex
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
-local report_schemes=logs.reporter("resolvers","schemes")
-local http=require("socket.http")
-local ltn12=require("ltn12")
-if mbox then mbox=nil end
-local resolvers=resolvers
-local schemes=resolvers.schemes or {}
-resolvers.schemes=schemes
-local cleaners={}
-schemes.cleaners=cleaners
-local threshold=24*60*60
-directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
-function cleaners.none(specification)
- return specification.original
-end
-function cleaners.strip(specification)
- local path,name=splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
-end
-function cleaners.md5(specification)
- return addsuffix(md5hex(specification.original),suffix(specification.path))
-end
-local cleaner=cleaners.strip
-directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
-function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
-end
-local cached={}
-local loaded={}
-local reused={}
-local thresholds={}
-local handlers={}
-local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template='--silent --insecure --create-dirs --output "%cachename%" "%original%"',
- checkers={
- cachename="cache",
- original="url",
- }
-}
-local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
- end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
- if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
- end
- reused[scheme]=reused[scheme]+1
- end
- return cached[original]
-end
-local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
-end
-local opener=openers.file
-local loader=loaders.file
-local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
-end
-schemes.install=install
-local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local handle=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(handle)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
-end
-install('http',http_handler)
-install('https')
-install('ftp')
-statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- if nl==0 then l={ "none" } end
- if nr==0 then r={ "none" } end
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,concat(l," "),concat(l," "))
- else
- return nil
- end
-end)
-local httprequest=http.request
-local toquery=url.toquery
-local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
-end
-schemes.fetchstring=fetchstring
-function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-lua"] = package.loaded["data-lua"] or true
-
--- original size: 4227, stripped down to: 3049
-
-if not modules then modules={} end modules ['data-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local package,lpeg=package,lpeg
-local loadfile=loadfile
-local addsuffix=file.addsuffix
-local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
-local luasuffixes={ 'tex','lua' }
-local libsuffixes={ 'lib' }
-local luaformats={ 'TEXINPUTS','LUAINPUTS' }
-local libformats={ 'CLUAINPUTS' }
-local helpers=package.helpers or {}
-local methods=helpers.methods or {}
-local resolvers=resolvers
-local resolveprefix=resolvers.resolve
-local expandedpaths=resolvers.expandedpathlistfromvariable
-local findfile=resolvers.findfile
-helpers.report=logs.reporter("resolvers","libraries")
-trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
-trackers.register("resolvers.locating",function(v) helpers.trace=v end)
-helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
-}
-local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
-function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
-end
-local loadedaslib=helpers.loadedaslib
-local registerpath=helpers.registerpath
-local lualibfile=helpers.lualibfile
-local luaformatpaths
-local libformatpaths
-local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,expandedpaths(luaformats[i]))
- end
- end
- return luaformatpaths
-end
-local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,expandedpaths(libformats[i]))
- end
- end
- return libformatpaths
-end
-local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
- end
-end
-helpers.loadedbyformat=loadedbyformat
-methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
-end
-methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
-end
-resolvers.loadlualib=require
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-aux"] = package.loaded["data-aux"] or true
-
--- original size: 2610, stripped down to: 2019
-
-if not modules then modules={} end modules ['data-aux']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local find=string.find
-local type,next=type,next
-local addsuffix,removesuffix=file.addsuffix,file.removesuffix
-local loaddata,savedata=io.loaddata,io.savedata
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local resolvers=resolvers
-local cleanpath=resolvers.cleanpath
-local findfiles=resolvers.findfiles
-local report_scripts=logs.reporter("resolvers","scripts")
-function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- local oldscript=cleanpath(oldname)
- local newname=addsuffix(newname,"lua")
- local newscripts=findfiles(newname) or {}
- if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
- end
- if #newscripts==0 then
- if trace_locating then
- report_scripts("unable to locate new script")
- end
- else
- for i=1,#newscripts do
- local newscript=cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content: %s",oldscript)
- end
- savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
-
--- original size: 2601, stripped down to: 1549
-
-if not modules then modules={} end modules ['data-tmf']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local resolvers=resolvers
-local report_tds=logs.reporter("resolvers","tds")
-function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["data-lst"] = package.loaded["data-lst"] or true
-
--- original size: 2038, stripped down to: 1696
-
-if not modules then modules={} end modules ['data-lst']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type=type
-local sortedhash=table.sortedhash
-local isdir=lfs.isdir
-local resolvers=resolvers
-local listers=resolvers.listers or {}
-resolvers.listers=listers
-local resolveprefix=resolvers.resolve
-local configurationfiles=resolvers.configurationfiles
-local expandedpathfromlist=resolvers.expandedpathfromlist
-local splitpath=resolvers.splitpath
-local knownvariables=resolvers.knownvariables
-local report_lists=logs.reporter("resolvers","lists")
-local report_resolved=logs.reporter("system","resolved")
-local function tabstr(str)
- if not str then
- return "unset"
- elseif type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
-end
-function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment))
- report_lists(" var: %s",tabstr(value.variable))
- report_lists(" exp: %s",tabstr(value.expansion))
- report_lists(" res: %s",tabstr(value.resolved))
- end
-end
-function listers.configurations()
- local configurations=configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=expandedpathfromlist(splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["libs-ini"] = package.loaded["libs-ini"] or true
-
--- original size: 5822, stripped down to: 3629
-
-if not modules then modules={} end modules ['libs-ini']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local type,unpack=type,unpack
-local type=type
-local nameonly=file.nameonly
-local joinfile=file.join
-local addsuffix=file.addsuffix
-local qualifiedpath=file.is_qualified_path
-local isfile=lfs.isfile
-local findfile=resolvers.findfile
-local expandpaths=resolvers.expandedpathlistfromvariable
-local report=logs.reporter("resolvers","libraries")
-local trace=false
-trackers.register("resolvers.lib",function(v) trace=v end)
-local function findlib(required)
- local suffix=os.libsuffix or "so"
- if not qualifiedpath(required) then
- local list=directives.value("system.librarynames" )
- local only=nameonly(required)
- if type(list)=="table" then
- list=list[only]
- if type(list)~="table" then
- list={ only }
- end
- else
- list={ only }
- end
- if trace then
- report("using lookup list for library %a: % | t",only,list)
- end
- for i=1,#list do
- local name=list[i]
- local found=findfile(name,"lib")
- if not found then
- found=findfile(addsuffix(name,suffix),"lib")
- end
- if found then
- if trace then
- report("library %a resolved via %a path to %a",name,"tds lib",found)
- end
- return found
- end
- end
- if expandpaths then
- local list=expandpaths("PATH")
- local base=addsuffix(only,suffix)
- for i=1,#list do
- local full=joinfile(list[i],base)
- local found=isfile(full) and full
- if found then
- if trace then
- report("library %a resolved via %a path to %a",name,"system",found)
- end
- return found
- end
- end
- end
- elseif isfile(addsuffix(required,suffix)) then
- if trace then
- report("library with qualified name %a %sfound",required,"")
- end
- return required
- else
- if trace then
- report("library with qualified name %a %sfound",required,"not ")
- end
- end
- return false
-end
-local foundlibraries=table.setmetatableindex(function(t,k)
- local v=findlib(k)
- t[k]=v
- return v
-end)
-function resolvers.findlib(required)
- return foundlibraries[required]
-end
-local libraries={}
-resolvers.libraries=libraries
-local report=logs.reporter("optional")
-if optional then optional.loaded={} end
-function libraries.validoptional(name)
- local thelib=optional and optional[name]
- if not thelib then
- elseif thelib.initialize then
- return thelib
- else
- report("invalid optional library %a",libname)
- end
-end
-function libraries.optionalloaded(name,libnames)
- local thelib=optional and optional[name]
- if not thelib then
- report("no optional %a library found",name)
- else
- local thelib_initialize=thelib.initialize
- if not thelib_initialize then
- report("invalid optional library %a",name)
- else
- if type(libnames)=="string" then
- libnames={ libnames }
- end
- if type(libnames)=="table" then
- for i=1,#libnames do
- local libname=libnames[i]
- local filename=foundlibraries[libname]
- if filename then
- libnames[i]=filename
- else
- report("unable to locate library %a",libname)
- return
- end
- end
- local initialized=thelib_initialize(unpack(libnames))
- if initialized then
- report("using library '% + t'",libnames)
- else
- report("unable to initialize library '% + t'",libnames)
- end
- return initialized
- end
- end
- end
-end
-if FFISUPPORTED and ffi and ffi.load then
- local ffiload=ffi.load
- function ffi.load(name)
- local full=name and foundlibraries[name]
- if full then
- return ffiload(full)
- else
- return ffiload(name)
- end
- end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
-
--- original size: 5703, stripped down to: 2321
-
-if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local gmatch,match=string.gmatch,string.match
-local type=type
-states=states or {}
-local states=states
-states.data=states.data or {}
-local data=states.data
-states.hash=states.hash or {}
-local hash=states.hash
-states.tag=states.tag or ""
-states.filename=states.filename or ""
-function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
-end
-function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
-end
-local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
- end
- end
-end
-local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
- end
- end
-end
-states.set_by_tag=set_by_tag
-states.get_by_tag=get_by_tag
-function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
-end
-function states.get(key,default)
- return get_by_tag(states.tag,key,default)
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
-
--- original size: 13843, stripped down to: 9991
-
-if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local format=string.format
-local concat=table.concat
-local quoted=string.quoted
-local luasuffixes=utilities.lua.suffixes
-local report_format=logs.reporter("resolvers","formats")
-local function primaryflags(arguments)
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- return concat(flags," ")
-end
-local function secondaryflags(arguments)
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- if arguments.ansilog then
- flags[#flags+1]="--c:ansilog"
- end
- if arguments.strip then
- flags[#flags+1]="--c:strip"
- end
- if arguments.lmtx then
- flags[#flags+1]="--c:lmtx"
- end
- return concat(flags," ")
-end
-local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
-local checkers={
- primaryflags="verbose",
- secondaryflags="verbose",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
- binarypath="string",
-}
-local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luametatex=sandbox.registerrunner {
- name="make luametatex format",
- program="luametatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
-}
-local function validbinarypath()
- if not environment.arguments.nobinarypath then
- local path=environment.ownpath or file.dirname(environment.ownname)
- if path and path~="" then
- path=dir.expandname(path)
- if path~="" and lfs.isdir(path) then
- return path
- end
- end
- end
-end
-function environment.make_format(formatname)
- local arguments=environment.arguments
- local engine=environment.ownmain or "luatex"
- local silent=arguments.silent
- local errors=arguments.errors
- local texsourcename=""
- local texsourcepath=""
- local fulltexsourcename=""
- if engine=="luametatex" then
- texsourcename=file.addsuffix(formatname,"mkxl")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(formatname,"mkiv")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(formatname,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",formatname)
- return
- end
- report_format("using tex source file %a",fulltexsourcename)
- fulltexsourcename=dir.expandname(fulltexsourcename)
- texsourcepath=file.dirname(fulltexsourcename)
- if not lfs.isfile(fulltexsourcename) then
- report_format("no accessible tex source file with name %a",fulltexsourcename)
- return
- end
- local specificationname="context.lus"
- local specificationpath=""
- local fullspecificationname=resolvers.findfile(specificationname) or ""
- if fullspecificationname=="" then
- report_format("unable to locate specification file %a",specificationname)
- return
- end
- report_format("using specification file %a",fullspecificationname)
- fullspecificationname=dir.expandname(fullspecificationname)
- specificationpath=file.dirname(fullspecificationname)
- if texsourcepath~=specificationpath then
- report_format("tex source file and specification file are on different paths")
- return
- end
- if not lfs.isfile(fulltexsourcename) then
- report_format("no accessible tex source file with name %a",fulltexsourcename)
- return
- end
- if not lfs.isfile(fullspecificationname) then
- report_format("no accessible specification file with name %a",fulltexsourcename)
- return
- end
- report_format("using tex source path %a",texsourcepath)
- local validformatpath=caches.getwritablepath("formats",engine) or ""
- local startupdir=dir.current()
- if validformatpath=="" then
- report_format("invalid format path, insufficient write access")
- return
- end
- local binarypath=validbinarypath()
- report_format("changing to format path %a",validformatpath)
- lfs.chdir(validformatpath)
- if dir.current()~=validformatpath then
- report_format("unable to change to format path %a",validformatpath)
- return
- end
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(specificationpath,usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(startupdir)
- return
- end
- local runner=runners[engine]
- if not runner then
- report_format("the format %a cannot be generated, no runner available for engine %a",name,engine)
- lfs.chdir(startupdir)
- return
- end
- local primaryflags=primaryflags(arguments)
- local secondaryflags=secondaryflags(arguments)
- local specification={
- binarypath=binarypath,
- primaryflags=primaryflags,
- secondaryflags=secondaryflags,
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- if silent then
- specification.redirect="> temp.log"
- end
- statistics.starttiming("format")
- local result=runner(specification)
- statistics.stoptiming("format")
- if silent then
- os.remove("temp.log")
- end
- report_format()
- if binarypath and binarypath~="" then
- report_format("binary path : %s",binarypath or "?")
- end
- report_format("format path : %s",validformatpath)
- report_format("luatex engine : %s",engine)
- report_format("lua startup file : %s",usedluastub)
- if primaryflags~="" then
- report_format("primary flags : %s",primaryflags)
- end
- if secondaryflags~="" then
- report_format("secondary flags : %s",secondaryflags)
- end
- report_format("context file : %s",fulltexsourcename)
- report_format("run time : %.3f seconds",statistics.elapsed("format"))
- report_format("return value : %s",result==0 and "okay" or "error")
- report_format()
- lfs.chdir(startupdir)
-end
-local template=[[%primaryflags% --fmt=%fmtfile% --lua=%luafile% %texfile% %secondaryflags%]]
-local checkers={
- primaryflags="verbose",
- secondaryflags="verbose",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
-}
-local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luametatex=sandbox.registerrunner {
- name="run luametatex format",
- program="luametatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
-}
-function environment.run_format(formatname,scriptname,filename,primaryflags,secondaryflags,verbose)
- local engine=environment.ownmain or "luatex"
- if not formatname or formatname=="" then
- report_format("missing format name")
- return
- end
- if not scriptname or scriptname=="" then
- report_format("missing script name")
- return
- end
- if not lfs.isfile(formatname) or not lfs.isfile(scriptname) then
- formatname,scriptname=resolvers.locateformat(formatname)
- end
- if not formatname or formatname=="" then
- report_format("invalid format name")
- return
- end
- if not scriptname or scriptname=="" then
- report_format("invalid script name")
- return
- end
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",file.nameonly(name),engine)
- return
- end
- if not filename then
- filename ""
- end
- local binarypath=validbinarypath()
- local specification={
- binarypath=binarypath,
- primaryflags=primaryflags or "",
- secondaryflags=secondaryflags or "",
- fmtfile=quoted(formatname),
- luafile=quoted(scriptname),
- texfile=filename~="" and quoted(filename) or "",
- }
- statistics.starttiming()
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if verbose then
- report_format()
- if binarypath and binarypath~="" then
- report_format("binary path : %s",binarypath)
- end
- report_format("luatex engine : %s",engine)
- report_format("lua startup file : %s",scriptname)
- report_format("tex format file : %s",formatname)
- if filename~="" then
- report_format("tex input file : %s",filename)
- end
- if primaryflags~="" then
- report_format("primary flags : %s",primaryflags)
- end
- if secondaryflags~="" then
- report_format("secondary flags : %s",secondaryflags)
- end
- report_format("run time : %.3f seconds",runtime)
- report_format("return value : %s",result==0 and "okay" or "error")
- report_format()
- end
- return result
-end
-
-
-end -- of closure
-
--- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
--- skipped libraries : -
--- original bytes : 1038373
--- stripped bytes : 409980
-
--- end library merge
-
--- We need this hack till luatex is fixed.
---
--- for k,v in pairs(arg) do print(k,v) end
-
-if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
- arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
-end
-
--- End of hack.
-
-local format, gsub, gmatch, match, find = string.format, string.gsub, string.gmatch, string.match, string.find
-local concat = table.concat
-
-local ownname = environment and environment.ownname or arg[0] or 'mtxrun.lua'
-local ownpath = gsub(match(ownname,"^(.+)[\\/].-$") or ".","\\","/")
-local owntree = environment and environment.ownpath or ownpath
-
-local ownlibs = { -- order can be made better
-
- 'l-bit32.lua',
- 'l-lua.lua',
- 'l-macro.lua',
- 'l-sandbox.lua',
- 'l-package.lua',
- 'l-lpeg.lua',
- 'l-function.lua',
- 'l-string.lua',
- 'l-table.lua',
- 'l-io.lua',
- 'l-number.lua',
- 'l-set.lua',
- 'l-os.lua',
- 'l-file.lua',
- 'l-gzip.lua',
- 'l-md5.lua',
- 'l-sha.lua',
- 'l-url.lua',
- 'l-dir.lua',
- 'l-boolean.lua',
- 'l-unicode.lua',
- 'l-math.lua',
-
- 'util-str.lua', -- code might move to l-string
- 'util-tab.lua',
- 'util-fil.lua',
- 'util-sac.lua',
- 'util-sto.lua',
- 'util-prs.lua',
- 'util-fmt.lua',
-
- 'util-soc-imp-reset.lua',
- 'util-soc-imp-socket.lua',
- 'util-soc-imp-copas.lua',
- 'util-soc-imp-ltn12.lua',
- -- 'util-soc-imp-mbox.lua',
- 'util-soc-imp-mime.lua',
- 'util-soc-imp-url.lua',
- 'util-soc-imp-headers.lua',
- 'util-soc-imp-tp.lua',
- 'util-soc-imp-http.lua',
- 'util-soc-imp-ftp.lua',
- 'util-soc-imp-smtp.lua',
-
- 'trac-set.lua',
- 'trac-log.lua',
- 'trac-inf.lua', -- was before trac-set
- 'trac-pro.lua', -- not really needed
- 'util-lua.lua', -- indeed here?
- 'util-deb.lua',
-
- 'util-tpl.lua',
- 'util-sbx.lua',
- 'util-mrg.lua',
-
- 'util-env.lua',
- 'luat-env.lua', -- can come before inf (as in mkiv)
-
- 'util-zip.lua',
-
- 'lxml-tab.lua',
- 'lxml-lpt.lua',
- -- 'lxml-ent.lua',
- 'lxml-mis.lua',
- 'lxml-aux.lua',
- 'lxml-xml.lua',
-
- 'trac-xml.lua',
-
- 'data-ini.lua',
- 'data-exp.lua',
- 'data-env.lua',
- 'data-tmp.lua',
- 'data-met.lua',
- 'data-res.lua',
- 'data-pre.lua',
- 'data-inp.lua',
- 'data-out.lua',
- 'data-fil.lua',
- 'data-con.lua',
- 'data-use.lua',
--- 'data-tex.lua',
--- 'data-bin.lua',
- 'data-zip.lua',
- 'data-tre.lua',
- 'data-sch.lua',
- 'data-lua.lua',
- 'data-aux.lua', -- updater
- 'data-tmf.lua',
- 'data-lst.lua',
-
- 'libs-ini.lua',
-
- 'luat-sta.lua',
- 'luat-fmt.lua',
-
-}
-
--- c:/data/develop/tex-context/tex/texmf-win64/bin/../../texmf-context/tex/context/base/mkiv/data-tmf.lua
--- c:/data/develop/context/sources/data-tmf.lua
-
-local ownlist = {
- -- '.',
- -- ownpath ,
- owntree .. "/../../../../context/sources", -- HH's development path
- --
- owntree .. "/../../texmf-local/tex/context/base/mkiv",
- owntree .. "/../../texmf-context/tex/context/base/mkiv",
- owntree .. "/../../texmf/tex/context/base/mkiv",
- owntree .. "/../../../texmf-local/tex/context/base/mkiv",
- owntree .. "/../../../texmf-context/tex/context/base/mkiv",
- owntree .. "/../../../texmf/tex/context/base/mkiv",
- --
- owntree .. "/../../texmf-local/tex/context/base",
- owntree .. "/../../texmf-context/tex/context/base",
- owntree .. "/../../texmf/tex/context/base",
- owntree .. "/../../../texmf-local/tex/context/base",
- owntree .. "/../../../texmf-context/tex/context/base",
- owntree .. "/../../../texmf/tex/context/base",
-}
-
-if ownpath == "." then table.remove(ownlist,1) end
-
-own = {
- name = ownname,
- path = ownpath,
- tree = owntree,
- list = ownlist,
- libs = ownlibs,
-}
-
-local function locate_libs()
- for l=1,#ownlibs do
- local lib = ownlibs[l]
- for p =1,#ownlist do
- local pth = ownlist[p]
- local filename = pth .. "/" .. lib
- local found = lfs.isfile(filename)
- if found then
- package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require
- return pth
- end
- end
- end
-end
-
-local function load_libs()
- local found = locate_libs()
- if found then
- for l=1,#ownlibs do
- local filename = found .. "/" .. ownlibs[l]
- local codeblob = loadfile(filename)
- if codeblob then
- codeblob()
- end
- end
- else
- resolvers = nil
- end
-end
-
-if not resolvers then
- load_libs()
-end
-
-if not resolvers then
- print("")
- print("Mtxrun is unable to start up due to lack of libraries. You may")
- print("try to run 'lua mtxrun.lua --selfmerge' in the path where this")
- print("script is located (normally under ..../scripts/context/lua) which")
- print("will make this script library independent.")
- os.exit()
-end
-
--- verbosity
-
------ e_verbose = environment.arguments["verbose"]
-
-local e_verbose = false
-
--- some common flags (also passed through environment)
-
-local e_silent = environment.argument("silent")
-local e_errors = environment.argument("errors")
-local e_noconsole = environment.argument("noconsole")
-
-local e_trackers = environment.argument("trackers")
-local e_directives = environment.argument("directives")
-local e_experiments = environment.argument("experiments")
-
-local t = { }
-
-if type(e_directives) == "string" then
- t[#t+1] = e_directives
-end
-
-if type(e_silent) == "string" then
- t[#t+1] = format("logs.blocked={%s}",e_silent)
-elseif e_silent == true then
- t[#t+1] = "logs.blocked"
-end
-
-if type(e_errors) == "string" then
- t[#t+1] = format("logs.errors={%s}",e_errors)
-elseif e_errors == true then
- t[#t+1] = "logs.errors"
-end
-
-if e_noconsole then
- t[#t+1] = format("logs.target=file")
-end
-
-if #t > 0 then
- e_directives = concat(t,",")
-end
-
-if e_trackers then trackers .enable(e_trackers) end
-if e_directives then directives .enable(e_directives) end
-if e_experiments then experiments.enable(e_experiments) end
-
-if not environment.trackers then environment.trackers = e_trackers end
-if not environment.directives then environment.directives = e_directives end
-if not environment.experiments then environment.experiments = e_experiments end
-
---
-
-resolvers.reset()
-
-local helpinfo = [[
-<?xml version="1.0" ?>
-<application>
- <metadata>
- <entry name="name">mtxrun</entry>
- <entry name="detail">ConTeXt TDS Runner Tool</entry>
- <entry name="version">1.33</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="script"><short>run an mtx script (lua prefered method) (<ref name="noquotes"/>), no script gives list</short></flag>
- <flag name="evaluate"><short>run code passed on the commandline (between quotes) (=loop) (exit|quit aborts)</short></flag>
- <flag name="execute"><short>run a script or program (texmfstart method) (<ref name="noquotes"/>)</short></flag>
- <flag name="resolve"><short>resolve prefixed arguments</short></flag>
- <flag name="ctxlua"><short>run internally (using preloaded libs)</short></flag>
- <flag name="internal"><short>run script using built in libraries (same as <ref name="ctxlua"/>)</short></flag>
- <flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
- </subcategory>
- <subcategory>
- <flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
- <flag name="path" value="runpath"><short>go to given path before execution</short></flag>
- <flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
- <flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
- </subcategory>
- <subcategory>
- <flag name="makestubs"><short>create stubs for (context related) scripts</short></flag>
- <flag name="removestubs"><short>remove stubs (context related) scripts</short></flag>
- <flag name="stubpath" value="binpath"><short>paths where stubs wil be written</short></flag>
- <flag name="windows"><short>create windows (mswin) stubs</short></flag>
- <flag name="unix"><short>create unix (linux) stubs</short></flag>
- <flag name="addbinarypath"><short>prepend the (found) binarypath to runners</short></flag>
- </subcategory>
- <subcategory>
- <flag name="verbose"><short>give a bit more info</short></flag>
- <flag name="trackers" value="list"><short>enable given trackers</short></flag>
- <flag name="progname" value="str"><short>format or backend</short></flag>
- <flag name="systeminfo" value="str"><short>show current operating system, processor, etc</short></flag>
- </subcategory>
- <subcategory>
- <flag name="edit"><short>launch editor with found file</short></flag>
- <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
- </subcategory>
- <subcategory>
- <flag name="timedrun"><short>run a script and time its run</short></flag>
- <flag name="autogenerate"><short>regenerate databases if needed (handy when used to run context in an editor)</short></flag>
- </subcategory>
- <subcategory>
- <flag name="usekpse"><short>use kpse as fallback (when no mkiv and cache installed, often slower)</short></flag>
- <flag name="forcekpse"><short>force using kpse (handy when no mkiv and cache installed but less functionality)</short></flag>
- </subcategory>
- <subcategory>
- <flag name="prefixes"><short>show supported prefixes</short></flag>
- </subcategory>
- <subcategory>
- <flag name="generate"><short>generate file database</short></flag>
- </subcategory>
- <subcategory>
- <flag name="variables"><short>show configuration variables</short></flag>
- <flag name="configurations"><short>show configuration order</short></flag>
- </subcategory>
- <subcategory>
- <flag name="directives"><short>show (known) directives</short></flag>
- <flag name="trackers"><short>show (known) trackers</short></flag>
- <flag name="experiments"><short>show (known) experiments</short></flag>
- </subcategory>
- <subcategory>
- <flag name="expand-braces"><short>expand complex variable</short></flag>
- <flag name="resolve-path"><short>expand variable (completely resolve paths)</short></flag>
- <flag name="expand-path"><short>expand variable (resolve paths)</short></flag>
- <flag name="expand-var"><short>expand variable (resolve references)</short></flag>
- <flag name="show-path"><short>show path expansion of ...</short></flag>
- <flag name="var-value"><short>report value of variable</short></flag>
- <flag name="find-file"><short>report file location</short></flag>
- <flag name="find-path"><short>report path of file</short></flag>
- </subcategory>
- <subcategory>
- <flag name="pattern" value="string"><short>filter variables</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtxrun",
- banner = "ConTeXt TDS Runner Tool 1.32",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-messages = messages or { } -- for the moment
-
-runners = runners or { } -- global (might become local)
-
-runners.applications = {
- ["lua"] = "luatex --luaonly",
- ["luc"] = "luatex --luaonly",
- ["pl"] = "perl",
- ["py"] = "python",
- ["rb"] = "ruby",
-}
-
-runners.suffixes = {
- 'rb', 'lua', 'py', 'pl'
-}
-
-runners.registered = {
- texexec = { 'texexec.rb', false }, -- context mkii runner (only tool not to be luafied)
- texutil = { 'texutil.rb', true }, -- old perl based index sorter for mkii (old versions need it)
- texfont = { 'texfont.pl', true }, -- perl script that makes mkii font metric files
- texfind = { 'texfind.pl', false }, -- perltk based tex searching tool, mostly used at pragma
- texshow = { 'texshow.pl', false }, -- perltk based context help system, will be luafied
- -- texwork = { 'texwork.pl', false }, -- perltk based editing environment, only used at pragma
- makempy = { 'makempy.pl', true },
- mptopdf = { 'mptopdf.pl', true },
- pstopdf = { 'pstopdf.rb', true }, -- converts ps (and some more) images, does some cleaning (replaced)
- -- examplex = { 'examplex.rb', false },
- concheck = { 'concheck.rb', false },
- runtools = { 'runtools.rb', true },
- textools = { 'textools.rb', true },
- tmftools = { 'tmftools.rb', true },
- ctxtools = { 'ctxtools.rb', true },
- rlxtools = { 'rlxtools.rb', true },
- pdftools = { 'pdftools.rb', true },
- mpstools = { 'mpstools.rb', true },
- -- exatools = { 'exatools.rb', true },
- xmltools = { 'xmltools.rb', true },
- -- luatools = { 'luatools.lua', true },
- mtxtools = { 'mtxtools.rb', true },
- pdftrimwhite = { 'pdftrimwhite.pl', false },
-}
-
-runners.launchers = {
- windows = { },
- unix = { },
-}
-
--- like runners.libpath("framework"): looks on script's subpath
-
-function runners.libpath(...)
- package.prepend_libpath(file.dirname(environment.ownscript),...)
- package.prepend_libpath(file.dirname(environment.ownname) ,...)
-end
-
-function runners.prepare()
- local checkname = environment.argument("ifchanged")
- if type(checkname) == "string" and checkname ~= "" then
- local oldchecksum = file.loadchecksum(checkname)
- local newchecksum = file.checksum(checkname)
- if oldchecksum == newchecksum then
- if e_verbose then
- report("file '%s' is unchanged",checkname)
- end
- return "skip"
- elseif e_verbose then
- report("file '%s' is changed, processing started",checkname)
- end
- file.savechecksum(checkname)
- end
- local touchname = environment.argument("iftouched")
- if type(touchname) == "string" and touchname ~= "" then
- local oldname, newname = string.splitup(touchname, ",")
- if oldname and newname and oldname ~= "" and newname ~= "" then
- if not file.needs_updating(oldname,newname) then
- if e_verbose then
- report("file '%s' and '%s' have same age",oldname,newname)
- end
- return "skip"
- elseif e_verbose then
- report("file '%s' is older than '%s'",oldname,newname)
- end
- end
- end
- local runpath = environment.argument("path")
- if type(runpath) == "string" and not lfs.chdir(runpath) then
- report("unable to change to path '%s'",runpath)
- return "error"
- end
- runners.prepare = function() end
- return "run"
-end
-
-function runners.execute_script(fullname,internal,nosplit)
- local noquote = environment.argument("noquotes")
- if fullname and fullname ~= "" then
- local state = runners.prepare()
- if state == 'error' then
- return false
- elseif state == 'skip' then
- return true
- elseif state == "run" then
- local path, name, suffix = file.splitname(fullname)
- local result = ""
- if path ~= "" then
- result = fullname
- elseif name then
- name = gsub(name,"^int[%a]*:",function()
- internal = true
- return ""
- end )
- name = gsub(name,"^script:","")
- if suffix == "" and runners.registered[name] and runners.registered[name][1] then
- name = runners.registered[name][1]
- suffix = file.suffix(name)
- end
- if suffix == "" then
- -- loop over known suffixes
- for _,s in pairs(runners.suffixes) do
- result = resolvers.findfile(name .. "." .. s, 'texmfscripts')
- if result ~= "" then
- break
- end
- end
- elseif runners.applications[suffix] then
- result = resolvers.findfile(name, 'texmfscripts')
- else
- -- maybe look on path
- result = resolvers.findfile(name, 'other text files')
- end
- end
- if result and result ~= "" then
- if not no_split then
- local before, after = environment.splitarguments(fullname) -- already done
- environment.arguments_before, environment.arguments_after = before, after
- end
- if internal then
- arg = { } for _,v in pairs(environment.arguments_after) do arg[#arg+1] = v end
- environment.ownscript = result
- dofile(result)
- else
-local texmfcnf = resolvers.getenv("TEXMFCNF")
-if not texmfcnf or texmfcnf == "" then
- texmfcnf = resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.resolve(resolvers.luacnfspec)))
- resolvers.setenv("TEXMFCNF",table.concat(texmfcnf,";")) -- for running texexec etc (after tl change to texmf-dist)
-end
- local binary = runners.applications[file.suffix(result)]
- result = string.quoted(string.unquoted(result))
- -- if string.match(result,' ') and not string.match(result,"^\".*\"$") then
- -- result = '"' .. result .. '"'
- -- end
- if binary and binary ~= "" then
- result = binary .. " " .. result
- end
- local command = result .. " " .. environment.reconstructcommandline(environment.arguments_after,noquote)
- if e_verbose then
- report()
- report("executing: %s",command)
- report()
- report()
- io.flush()
- end
- local code = os.execute(command)
- if code == 0 then
- return true
- else
- if binary then
- binary = file.addsuffix(binary,os.binsuffix)
- for p in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- if lfs.isfile(file.join(p,binary)) then
- return false
- end
- end
- report()
- report("This script needs '%s' which seems not to be installed.",binary)
- report()
- end
- return false
- end
- end
- end
- end
- end
- return false
-end
-
-function runners.execute_program(fullname)
- local noquote = environment.argument("noquotes")
- if fullname and fullname ~= "" then
- local state = runners.prepare()
- if state == 'error' then
- return false
- elseif state == 'skip' then
- return true
- elseif state == "run" then
- local before, after = environment.splitarguments(fullname)
- for k=1,#after do after[k] = resolvers.resolve(after[k]) end
- environment.initializearguments(after)
- fullname = gsub(fullname,"^bin:","")
- local command = fullname .. " " .. (environment.reconstructcommandline(after or "",noquote) or "")
- report()
- report("executing: %s",command)
- report()
- report()
- io.flush()
- local code = os.execute(command)
- return code == 0
- end
- end
- return false
-end
-
--- the --usekpse flag will fallback (not default) on kpse (hm, we can better update mtx-stubs)
-
-local windows_stub = '@echo off\013\010setlocal\013\010set ownpath=%%~dp0%%\013\010texlua "%%ownpath%%mtxrun.lua" --usekpse --execute %s %%*\013\010endlocal\013\010'
-local unix_stub = '#!/bin/sh\010mtxrun --usekpse --execute %s \"$@\"\010'
-
-function runners.handle_stubs(create)
- local stubpath = environment.argument('stubpath') or '.' -- 'auto' no longer subpathssupported
- local windows = environment.argument('windows') or environment.argument('mswin') or false
- local unix = environment.argument('unix') or environment.argument('linux') or false
- if not windows and not unix then
- if os.platform == "unix" then
- unix = true
- else
- windows = true
- end
- end
- for _,v in pairs(runners.registered) do
- local name, doit = v[1], v[2]
- if doit then
- local base = gsub(file.basename(name), "%.(.-)$", "")
- if create then
- if windows then
- io.savedata(file.join(stubpath,base..".bat"),format(windows_stub,name))
- report("windows stub for '%s' created",base)
- end
- if unix then
- io.savedata(file.join(stubpath,base),format(unix_stub,name))
- report("unix stub for '%s' created",base)
- end
- else
- if windows and (os.remove(file.join(stubpath,base..'.bat')) or os.remove(file.join(stubpath,base..'.cmd'))) then
- report("windows stub for '%s' removed", base)
- end
- if unix and (os.remove(file.join(stubpath,base)) or os.remove(file.join(stubpath,base..'.sh'))) then
- report("unix stub for '%s' removed",base)
- end
- end
- end
- end
-end
-
-function runners.resolve_string(filename)
- if filename and filename ~= "" then
- runners.report_location(resolvers.resolve(filename))
- end
-end
-
--- differs from texmfstart where locate appends .com .exe .bat ... todo
-
-function runners.locate_file(filename) -- was given file but only searches in tree
- if filename and filename ~= "" then
- if environment.argument("first") then
- runners.report_location(resolvers.findfile(filename))
- -- resolvers.dowithfilesandreport(resolvers.findfile,filename)
- elseif environment.argument("all") then
- local result, status = resolvers.findfiles(filename)
- if status and environment.argument("detail") then
- runners.report_location(status)
- else
- runners.report_location(result)
- end
- else
- runners.report_location(resolvers.findgivenfile(filename))
- -- resolvers.dowithfilesandreport(resolvers.findgivenfile,filename)
- end
- end
-end
-
-function runners.locate_platform()
- runners.report_location(os.platform)
-end
-
-function runners.report_location(result)
- if type(result) == "table" then
- for i=1,#result do
- if i > 1 then
- io.write("\n")
- end
- io.write(result[i])
- end
- else
- io.write(result)
- end
-end
-
-function runners.edit_script(filename) -- we assume that gvim is present on most systems (todo: also in cnf file)
- local editor = os.getenv("MTXRUN_EDITOR") or os.getenv("TEXMFSTART_EDITOR") or os.getenv("EDITOR") or 'gvim'
- local rest = resolvers.resolve(filename)
- if rest ~= "" then
- local command = editor .. " " .. rest
- if e_verbose then
- report()
- report("starting editor: %s",command)
- report()
- report()
- end
- os.launch(command)
- end
-end
-
-function runners.save_script_session(filename, list)
- local t = { }
- for i=1,#list do
- local key = list[i]
- t[key] = environment.arguments[key]
- end
- io.savedata(filename,table.serialize(t,true))
-end
-
-function runners.load_script_session(filename)
- if lfs.isfile(filename) then
- local t = io.loaddata(filename)
- if t then
- t = loadstring(t)
- if t then t = t() end
- for key, value in pairs(t) do
- environment.arguments[key] = value
- end
- end
- end
-end
-
-function resolvers.launch(str)
- -- maybe we also need to test on mtxrun.launcher.suffix environment
- -- variable or on windows consult the assoc and ftype vars and such
- local launchers = runners.launchers[os.platform] if launchers then
- local suffix = file.suffix(str) if suffix then
- local runner = launchers[suffix] if runner then
- str = runner .. " " .. str
- end
- end
- end
- os.launch(str)
-end
-
-function runners.launch_file(filename)
- local allresults = environment.arguments["all"]
- local pattern = environment.arguments["pattern"]
- local listonly = environment.arguments["list"]
- if not pattern or pattern == "" then
- pattern = filename
- end
- if not pattern or pattern == "" then
- report("provide name or --pattern=")
- else
- local t = resolvers.findfiles(pattern,nil,allresults)
- if not t or #t == 0 then
- t = resolvers.findfiles("*/" .. pattern,nil,allresults)
- end
- if not t or #t == 0 then
- t = resolvers.findfiles("*/" .. pattern .. "*",nil,allresults)
- end
- if t and #t > 0 then
- for i=1,#t do
- local name = t[i]
- if listonly then
- report("% 3i: %-30s %s",i,file.basename(name),file.dirname(name))
- else
- report("launching: %s",name)
- resolvers.launch(name)
- if not allresults then
- break
- end
- end
- end
- if listonly then
- io.write("\n")
- io.write("\n[select number]\n\n>> ")
- local answer = tonumber(io.read())
- if answer then
- io.write("\n")
- local name = t[answer]
- if name then
- report("launching: %s",name)
- resolvers.launch(name)
- else
- report("invalid number")
- end
- end
- end
- else
- report("no match for %s", pattern)
- end
- end
-end
-
-local mtxprefixes = {
- { "^mtx%-", "mtx-" },
- { "^mtx%-t%-", "mtx-t-" },
-}
-
-function runners.find_mtx_script(filename)
- local function found(name)
- local path = file.dirname(name)
- if path and path ~= "" then
- return false
- else
- local fullname = own and own.path and file.join(own.path,name)
- return io.exists(fullname) and fullname
- end
- end
- filename = file.addsuffix(filename,"lua")
- local basename = file.removesuffix(file.basename(filename))
- local suffix = file.suffix(filename)
- -- qualified path, raw name
- local fullname = file.is_qualified_path(filename) and io.exists(filename) and filename
- if fullname and fullname ~= "" then
- return fullname
- end
- -- current path, raw name
- fullname = "./" .. filename
- fullname = io.exists(fullname) and fullname
- if fullname and fullname ~= "" then
- return fullname
- end
- -- mtx- prefix checking
- for i=1,#mtxprefixes do
- local mtxprefix = mtxprefixes[i]
- mtxprefix = find(filename,mtxprefix[1]) and "" or mtxprefix[2]
- -- context namespace, mtx-<filename>
- fullname = mtxprefix .. filename
- fullname = found(fullname) or resolvers.findfile(fullname)
- if fullname and fullname ~= "" then
- return fullname
- end
- -- context namespace, mtx-<filename>s
- fullname = mtxprefix .. basename .. "s" .. "." .. suffix
- fullname = found(fullname) or resolvers.findfile(fullname)
- if fullname and fullname ~= "" then
- return fullname
- end
- -- context namespace, mtx-<filename minus trailing s>
- fullname = mtxprefix .. gsub(basename,"s$","") .. "." .. suffix
- fullname = found(fullname) or resolvers.findfile(fullname)
- if fullname and fullname ~= "" then
- return fullname
- end
- end
- -- context namespace, just <filename>
- fullname = resolvers.findfile(filename)
- return fullname
-end
-
-function runners.register_arguments(...)
- local arguments = environment.arguments_after
- local passedon = { ... }
- for i=#passedon,1,-1 do
- local pi = passedon[i]
- if pi then
- table.insert(arguments,1,pi)
- end
- end
-end
-
-function runners.execute_ctx_script(filename,...)
- runners.register_arguments(...)
- local arguments = environment.arguments_after
- local fullname = runners.find_mtx_script(filename) or ""
- if file.suffix(fullname) == "cld" then
- -- handy in editors where we force --autopdf
- report("running cld script: %s",filename)
- table.insert(arguments,1,fullname)
- table.insert(arguments,"--autopdf")
- fullname = runners.find_mtx_script("context") or ""
- end
- -- retry after generate but only if --autogenerate
- if fullname == "" and environment.argument("autogenerate") then -- might become the default
- resolvers.renewcache()
- trackers.enable("resolvers.locating")
- resolvers.load()
- --
- fullname = runners.find_mtx_script(filename) or ""
- end
- -- that should do it
- if fullname ~= "" then
- local state = runners.prepare()
- if state == 'error' then
- return false
- elseif state == 'skip' then
- return true
- elseif state == "run" then
- -- load and save ... kind of undocumented
- arg = { } for _,v in pairs(arguments) do arg[#arg+1] = resolvers.resolve(v) end
- environment.initializearguments(arg)
- local loadname = environment.arguments['load']
- if loadname then
- if type(loadname) ~= "string" then loadname = file.basename(fullname) end
- loadname = file.replacesuffix(loadname,"cfg")
- runners.load_script_session(loadname)
- end
- filename = environment.files[1]
- if e_verbose then
- report("using script: %s (if --path is used don't run on path where mtxrun lives)\n",fullname)
- end
- environment.ownscript = fullname
- dofile(fullname)
- local savename = environment.arguments['save']
- if savename then
- if type(savename) ~= "string" then savename = file.basename(fullname) end
- savename = file.replacesuffix(savename,"cfg")
- runners.save_script_session(savename,save_list)
- end
- return true
- end
- else
- if filename == "" or filename == "help" then
- local context = resolvers.findfile("mtx-context.lua")
- trackers.enable("resolvers.locating")
- if context ~= "" then
- local result = dir.glob((gsub(context,"mtx%-context","mtx-*"))) -- () needed
- local valid = { }
- table.sort(result)
- for i=1,#result do
- local scriptname = result[i]
- local scriptbase = match(scriptname,".*mtx%-([^%-]-)%.lua")
- if scriptbase then
- local data = io.loaddata(scriptname)
- local application = match(data,"local application.-=.-(%{.-%})")
- if application then
- application = loadstring("return " .. application)
- if application then
- application = application()
- local banner = application.banner
- if banner then
- local description, version = match(banner,"^(.-) ([%d.]+)$")
- if description then
- valid[#valid+1] = { scriptbase, version, description }
- else
- valid[#valid+1] = { scriptbase, "", banner }
- end
- end
- end
- end
- end
- end
- if #valid > 0 then
- application.identify()
- report("no script name given, known scripts:")
- report()
- for k=1,#valid do
- local v = valid[k]
- report("%-12s %4s %s",v[1],v[2],v[3])
- end
- end
- else
- report("no script name given")
- end
- else
- filename = file.addsuffix(filename,"lua")
- if file.is_qualified_path(filename) then
- report("unknown script '%s'",filename)
- else
- report("unknown script '%s' or 'mtx-%s'",filename,filename)
- end
- end
- return false
- end
-end
-
-function runners.prefixes()
- application.identify()
- report()
- report(concat(resolvers.allprefixes(true)," "))
-end
-
-function runners.timedrun(filename) -- just for me
- if filename and filename ~= "" then
- runners.timed(function() os.execute(filename) end)
- end
-end
-
-function runners.timed(action)
- statistics.timed(action,true)
-end
-
-function runners.associate(filename)
- os.launch(filename)
-end
-
-function runners.evaluate(code,filename) -- for Luigi
- local environment = table.setmetatableindex(_G)
- if code == "loop" then
- while true do
- io.write("lua > ")
- local code = io.read()
- if code == "quit" or code == "exit" then
- break
- elseif code ~= "" then
- local temp = string.match(code,"^= (.*)$")
- if temp then
- code = "inspect("..temp..")"
- end
- local compiled, message = load(code,"console","t",environment)
- if type(compiled) ~= "function" then
- compiled = load("inspect("..code..")","console","t",environment)
- end
- if type(compiled) ~= "function" then
- io.write("! " .. (message or code).."\n")
- else
- io.write(compiled())
- end
- end
- end
- else
- if type(code) ~= "string" or code == "" then
- code = filename
- end
- if code ~= "" then
- local compiled, message = load(code,"console","t",environment)
- if type(compiled) ~= "function" then
- compiled = load("inspect("..code..")","console","t",environment)
- end
- if type(compiled) ~= "function" then
- io.write("invalid lua code: " .. (message or code))
- return
- end
- io.write(compiled())
- end
- end
-end
-
-function runners.gethelp(filename)
- local url = environment.argument("url")
- if url and url ~= "" then
- local command = string.gsub(environment.argument("command") or "unknown","^%s*\\*(.-)%s*$","%1")
- url = utilities.templates.replace(url,{ command = command })
- os.launch(url)
- else
- report("no --url given")
- end
-end
-
-function runners.systeminfo()
- report("architecture : %s",os.platform or "<unset>")
- report("operating system : %s",os.name or "<unset>")
- report("file architecture : %s",os.type or "<unset>")
- report("binary path : %s",os.selfdir or "<unset>")
- report("binary suffix : %s",os.binsuffix or "<unset>")
- report("library suffix : %s",os.libsuffix or "<unset>")
-end
-
--- this is a bit dirty ... first we store the first filename and next we
--- split the arguments so that we only see the ones meant for this script
--- ... later we will use the second half
-
-local filename = environment.files[1] or ""
-local ok = true
-
-local before, after = environment.splitarguments(filename)
-environment.arguments_before, environment.arguments_after = before, after
-environment.initializearguments(before)
-
-e_verbose = environment.arguments["verbose"] -- delayed till here (we need the ones before script)
-
-if e_verbose then
- trackers.enable("resolvers.locating")
-end
-
--- maybe the unset has to go to this level
-
-local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))]
-
-local e_argument = environment.argument
-
-if e_argument("timedlog") then
- logs.settimedlog()
-end
-
-if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then
-
- resolvers.load_tree(e_argument('tree'),true) -- force resolve of TEXMFCNF
-
- os.setenv("engine","")
- os.setenv("progname","")
-
- local remapper = {
- otf = "opentype fonts",
- ttf = "truetype fonts",
- ttc = "truetype fonts",
- pfb = "type1 fonts",
- other = "other text files",
- }
-
- local progname = e_argument("progname") or 'context'
-
- local function kpse_initialized()
- texconfig.kpse_init = true
- local t = os.clock()
- local k = kpse.original.new("luatex",progname)
- local dummy = k:find_file("mtxrun.lua") -- so that we're initialized
- report("kpse fallback with progname '%s' initialized in %s seconds",progname,os.clock()-t)
- kpse_initialized = function() return k end
- return k
- end
-
- local findfile = resolvers.findfile
- local showpath = resolvers.showpath
-
- if e_argument("forcekpse") then
-
- function resolvers.findfile(name,kind)
- return (kpse_initialized():find_file(resolvers.cleanpath(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or ""
- end
- function resolvers.showpath(name)
- return (kpse_initialized():show_path(name)) or ""
- end
-
- elseif e_argument("usekpse") or is_mkii_stub then
-
- resolvers.load()
-
- function resolvers.findfile(name,kind)
- local found = findfile(name,kind) or ""
- if found ~= "" then
- return found
- else
- return (kpse_initialized():find_file(resolvers.cleanpath(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or ""
- end
- end
- function resolvers.showpath(name)
- local found = showpath(name) or ""
- if found ~= "" then
- return found
- else
- return (kpse_initialized():show_path(name)) or ""
- end
- end
-
- end
-
- function runners.loadbase()
- end
-
-else
-
- function runners.loadbase(...)
- if not resolvers.load(...) then
- report("forcing cache reload")
- resolvers.renewcache()
- trackers.enable("resolvers.locating")
- if not resolvers.load(...) then
- report("the resolver databases are not present or outdated")
- end
- end
- end
-
- resolvers.load_tree(e_argument('tree'),e_argument("resolve"))
-
-end
-
--- joke .. reminds me of messing with gigi terminals
-
-do
-
- local a_locale = e_argument("locale")
-
- if a_locale then
-
- -- I really hate this crap but am too tired of discussing it over and over
- -- again so for the sake of usiage outside context we will provide ways to
- -- use locales in an otherwise supposed to be locale agnostic system. And
- -- forget about support in case of interferences.
-
- report()
- report(what == "force" and "forcing locale:" or "original locale:")
- report()
- report(" collate : %s",status.lc_collate or "<unset>")
- report(" ctype : %s",status.lc_ctype or "<unset>")
- report(" monetary : %s",status.lc_monetary or "<unset>")
- report(" numeric : %s",status.lc_numeric or "<unset>")
- report(" time : %s",status.lc_time or "<unset>")
- report()
-
- end
-
- if a_locale == "force" then
- os.setlocale(status.lc_collate ,"collate")
- os.setlocale(status.lc_ctype ,"ctype")
- os.setlocale(status.lc_monetary,"monetary")
- os.setlocale(status.lc_numeric ,"numeric")
- os.setlocale(status.lc_time ,"time")
- else
- function os.setlocale()
- end
- end
-
-end
-
--- if e_argument("ansi") or e_argument("ansilog") then
-
--- logs.setformatters(e_argument("ansi") and "ansi" or "ansilog")
-
--- -- local script = e_argument("script") or e_argument("scripts")
--- --
--- -- if type(script) == "string" then
--- -- logs.writer("]0;"..script.."") -- for Alan to test
--- -- end
-
--- end
-
-if e_argument("script") or e_argument("scripts") then
-
- -- run a script by loading it (using libs), pass args
-
- if e_argument("nofiledatabase") then
- -- handy for mtx-update
- else
- runners.loadbase()
- end
- if is_mkii_stub then
- ok = runners.execute_script(filename,false,true)
- else
- ok = runners.execute_ctx_script(filename)
- end
-
-elseif e_argument("evaluate") then
-
- runners.evaluate(e_argument("evaluate"),filename)
-
-elseif e_argument("selfmerge") then
-
- -- embed used libraries
-
- runners.loadbase()
- local found = locate_libs()
-
- if found then
- local mtxrun = resolvers.findfile("mtxrun.lua") -- includes local name
- if lfs.isfile(mtxrun) then
- utilities.merger.selfmerge(mtxrun,own.libs,{ found })
- application.report("runner updated on resolved path: %s",mtxrun)
- else
- utilities.merger.selfmerge(own.name,own.libs,{ found })
- application.report("runner updated on relative path: %s",own.name)
- end
- end
-
-elseif e_argument("selfclean") then
-
- -- remove embedded libraries
-
- runners.loadbase()
-
- local mtxrun = resolvers.findfile("mtxrun.lua") -- includes local name
- if lfs.isfile(mtxrun) then
- utilities.merger.selfclean(mtxrun)
- application.report("runner cleaned on resolved path: %s",mtxrun)
- else
- utilities.merger.selfclean(own.name)
- application.report("runner cleaned on relative path: %s",own.name)
- end
-
-elseif e_argument("selfupdate") then
-
- runners.loadbase()
- trackers.enable("resolvers.locating")
- resolvers.updatescript(own.name,"mtxrun")
-
-elseif e_argument("ctxlua") or e_argument("internal") then
-
- -- run a script by loading it (using libs)
-
- runners.loadbase()
- ok = runners.execute_script(filename,true)
-
-elseif e_argument("execute") then
-
- -- execute script
-
- runners.loadbase()
- ok = runners.execute_script(filename)
-
-elseif e_argument("direct") then
-
- -- equals bin:
-
- runners.loadbase()
- ok = runners.execute_program(filename)
-
-elseif e_argument("edit") then
-
- -- edit file
-
- runners.loadbase()
- runners.edit_script(filename)
-
-elseif e_argument("launch") then
-
- runners.loadbase()
- runners.launch_file(filename)
-
-elseif e_argument("associate") then
-
- runners.associate(filename)
-
-elseif e_argument("gethelp") then
-
- runners.gethelp()
-
-elseif e_argument("makestubs") then
-
- -- make stubs (depricated)
-
- runners.handle_stubs(true)
-
-elseif e_argument("removestubs") then
-
- -- remove stub (depricated)
-
- runners.loadbase()
- runners.handle_stubs(false)
-
-elseif e_argument("resolve") then
-
- -- resolve string
-
- runners.loadbase()
- runners.resolve_string(filename)
-
-elseif e_argument("locate") then
-
- -- locate file (only database)
-
- runners.loadbase()
- runners.locate_file(filename)
-
-elseif e_argument("platform") or e_argument("show-platform") then
-
- -- locate platform
-
- runners.loadbase()
- runners.locate_platform()
-
-elseif e_argument("prefixes") then
-
- runners.loadbase()
- runners.prefixes()
-
-elseif e_argument("timedrun") then
-
- -- locate platform
-
- runners.loadbase()
- runners.timedrun(filename)
-
-elseif e_argument("variables") or e_argument("show-variables") or e_argument("expansions") or e_argument("show-expansions") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--expansions",filename)
-
- resolvers.load("nofiles")
- resolvers.listers.variables(e_argument("pattern"))
-
-elseif e_argument("configurations") or e_argument("show-configurations") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--configurations",filename)
-
- resolvers.load("nofiles")
- resolvers.listers.configurations()
-
-elseif e_argument("find-file") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--find-file",filename)
-
- resolvers.load()
- local e_all = e_argument("all")
- local e_pattern = e_argument("pattern")
- local e_format = e_argument("format")
- local finder = e_all and resolvers.findfiles or resolvers.findfile
- if not e_pattern then
- runners.register_arguments(filename)
- environment.initializearguments(environment.arguments_after)
- resolvers.dowithfilesandreport(finder,environment.files,e_format)
- elseif type(e_pattern) == "string" then
- resolvers.dowithfilesandreport(finder,{ e_pattern },e_format)
- end
-
-elseif e_argument("find-path") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--find-path",filename)
-
- resolvers.load()
- local path = resolvers.findpath(filename)
- if e_verbose then
- report(path)
- else
- print(path)
- end
-
-elseif e_argument("expand-braces") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename)
-
- resolvers.load("nofiles")
- runners.register_arguments(filename)
- environment.initializearguments(environment.arguments_after)
- resolvers.dowithfilesandreport(resolvers.expandbraces, environment.files)
-
-elseif e_argument("expand-path") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--expand-path",filename)
-
- resolvers.load("nofiles")
- runners.register_arguments(filename)
- environment.initializearguments(environment.arguments_after)
- resolvers.dowithfilesandreport(resolvers.expandpath, environment.files)
-
-elseif e_argument("resolve-path") then
-
- resolvers.load("nofiles")
- runners.register_arguments(filename)
- environment.initializearguments(environment.arguments_after)
- resolvers.dowithfilesandreport(resolvers.cleanedpathlist, environment.files)
-
-elseif e_argument("expand-var") or e_argument("expand-variable") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--expand-var",filename)
-
- resolvers.load("nofiles")
- runners.register_arguments(filename)
- environment.initializearguments(environment.arguments_after)
- resolvers.dowithfilesandreport(resolvers.expansion, environment.files)
-
-elseif e_argument("show-path") or e_argument("path-value") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--show-path",filename)
-
- resolvers.load("nofiles")
- runners.register_arguments(filename)
- environment.initializearguments(environment.arguments_after)
- resolvers.dowithfilesandreport(resolvers.showpath, environment.files)
-
-elseif e_argument("var-value") or e_argument("show-value") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--show-value",filename)
-
- resolvers.load("nofiles")
- runners.register_arguments(filename)
- environment.initializearguments(environment.arguments_after)
- resolvers.dowithfilesandreport(resolvers.variable,environment.files)
-
-elseif e_argument("format-path") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--format-path",filename)
-
- resolvers.load()
- report(caches.getwritablepath("format"))
-
--- elseif e_argument("pattern") then
---
--- -- luatools
---
--- runners.execute_ctx_script("mtx-base","--pattern='" .. e_argument("pattern") .. "'",filename)
-
-elseif e_argument("generate") then
-
- -- luatools
-
- if filename and filename ~= "" then
- resolvers.load("nofiles")
- trackers.enable("resolvers.locating")
- resolvers.renew(filename)
- else
- resolvers.renewcache()
- trackers.enable("resolvers.locating")
- resolvers.load()
- end
-
- e_verbose = true
-
-elseif e_argument("make") or e_argument("ini") or e_argument("compile") then
-
- -- luatools: runners.execute_ctx_script("mtx-base","--make",filename)
-
- resolvers.load()
- trackers.enable("resolvers.locating")
- environment.make_format(filename)
-
-elseif e_argument("run") then
-
- -- luatools
-
- runners.execute_ctx_script("mtx-base","--run",filename)
-
-elseif e_argument("fmt") then
-
- -- luatools
-
- runners.execute_ctx_script("mtx-base","--fmt",filename)
-
-elseif e_argument("help") and filename=='base' then
-
- -- luatools
-
- runners.execute_ctx_script("mtx-base","--help")
-
-elseif e_argument("version") then
-
- application.version()
-
- application.report("source path",environment.ownbin)
-
-elseif e_argument("directives") then
-
- directives.show()
-
-elseif e_argument("trackers") then
-
- trackers.show()
-
-elseif e_argument("experiments") then
-
- experiments.show()
-
-elseif e_argument("exporthelp") then
-
- runners.loadbase()
- application.export(e_argument("exporthelp"),filename)
-
-elseif e_argument("systeminfo") then
-
- runners.systeminfo()
-
-elseif e_argument("locale") then
-
- -- already done
-
-elseif e_argument("help") or filename=='help' or filename == "" then
-
- application.help()
-
-elseif find(filename,"^bin:") then
-
- runners.loadbase()
- ok = runners.execute_program(filename)
-
-elseif is_mkii_stub then
-
- -- execute mkii script
-
- runners.loadbase()
- ok = runners.execute_script(filename,false,true)
-
-elseif false then
-
- runners.loadbase()
- ok = runners.execute_ctx_script(filename)
- if not ok then
- ok = runners.execute_script(filename)
- end
-
-elseif environment.files[1] == 'texmfcnf.lua' then -- so that we don't need to load mtx-base
-
- resolvers.load("nofiles")
- resolvers.listers.configurations()
-
-else
- runners.loadbase()
- runners.execute_ctx_script("mtx-base",filename)
-
-end
-
-if e_verbose then
- report()
- report("elapsed lua time: %0.3f seconds",os.runtime())
-end
-
-if os.type ~= "windows" then
- texio.write("\n") -- is this still valid?
-end
-
-if ok == false then ok = 1 elseif ok == true or ok == nil then ok = 0 end
-
--- os.exit(ok,true) -- true forces a cleanup in 5.2+
-
-os.exit(ok) -- true forces a cleanup in 5.2+ but reports a wrong number then
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrunjit b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrunjit
deleted file mode 100755
index 117105aa5c0..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrunjit
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-luajittex --luaonly $(dirname $0)/mtxrun "$@"
-
-# luajittex --luaonly ${0%jit} "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/pstopdf b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/pstopdf
deleted file mode 100755
index 116f5f4a32e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/pstopdf
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-mtxrun --script pstopdf "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/texexec b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/texexec
deleted file mode 100755
index cd5900ff84c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/texexec
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-mtxrun --usekpse --execute texexec "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/texmfstart b/Build/source/texk/texlive/linked_scripts/context/stubs/unix/texmfstart
deleted file mode 100755
index 1799b357915..00000000000
--- a/Build/source/texk/texlive/linked_scripts/context/stubs/unix/texmfstart
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-mtxrun --usekpse "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/convbkmk/convbkmk.rb b/Build/source/texk/texlive/linked_scripts/convbkmk/convbkmk.rb
deleted file mode 100755
index 29734b2e129..00000000000
--- a/Build/source/texk/texlive/linked_scripts/convbkmk/convbkmk.rb
+++ /dev/null
@@ -1,584 +0,0 @@
-#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
-
-=begin
-
-= convbkmk Ver.0.30
-
- 2018.11.25
- Takuji Tanaka
- ttk (at) t-lab.opal.ne.jp
-((<URL:http://www.t-lab.opal.ne.jp/tex/uptex_en.html>))
-
-
-== Abstract
-
-((*convbkmk*)) is a tiny utility for making correct bookmarks in pdf files
-typesetted by pLaTeX/upLaTeX with the hyperref package.
-pLaTeX/upLaTeX + hyperref outputs data of bookmarks
-in their internal encodings (EUC-JP, Shift_JIS or UTF-8).
-On the other hand, the PostScript/PDF format requests that
-the data is written in a certain syntax with UTF-16 or PDFDocEncoding.
-Thus, data conversion is required to create correct bookmarks.
-
-In addition, pLaTeX outputs dvi files with special commands
-in its internal encoding (EUC-JP or Shift_JIS).
-It is not consistent with recent dviware and file systems
-which assume UTF-8.
-
-((*convbkmk*)) provides a function of
-the encoding conversion and formatting the data.
-
-== Requirement
-
-((*ruby*)) 1.9.x or later is required.
-((*ruby*)) 1.8.x is no longer supported.
-To support conversion of dvi special,
-((*dvispc*)) in dviout-util is required.
-
-== Examples
-
-=== for pdf bookmark
-
-pLaTeX (internal kanji code: euc) + hyperref + dvips :
- $ platex doc00.tex
- $ platex doc00.tex
- $ dvips doc00.dvi
- $ convbkmk.rb -e doc00.ps
- $ ps2pdf doc00-convbkmk.ps
-
-pLaTeX (kanji code: sjis) + hyperref + dvipdfmx :
- $ platex doc01.tex
- $ platex doc01.tex
- $ convbkmk.rb -s -o doc01.out
- $ platex doc01.tex
- $ dvipdfmx doc01.dvi
-
-upLaTeX + hyperref + dvips :
- $ uplatex doc02.tex
- $ uplatex doc02.tex
- $ dvips doc02.dvi
- $ convbkmk.rb doc02.ps
- $ ps2pdf doc02-convbkmk.ps
-
-upLaTeX + hyperref + dvipdfmx :
- $ uplatex doc03.tex
- $ uplatex doc03.tex
- $ convbkmk.rb -o doc03.out
- $ uplatex doc03.tex
- $ dvipdfmx doc03.dvi
-
-=== for dvi special (graphic file names)
-
-pLaTeX (internal kanji code: euc) + dvips :
- $ platex doc04.tex
- $ platex doc04.tex
- $ convbkmk.rb -e -d doc04.dvi
- $ dvips doc04-convbkmk.dvi
- $ ps2pdf doc04-convbkmk.ps
-
-pLaTeX (internal kanji code: sjis) + dvipdfmx :
- $ platex doc05.tex
- $ platex doc05.tex
- $ convbkmk.rb -s -d doc05.dvi
- $ dvipdfmx doc05.dvi
-
-((*convbkmk*)) executes ((*dvispc*)) command
-to extract dvi files.
-((*dvispc*)) command is designated by
-an environmental variable 'DVISPC'.
-By default, 'dvispc' is set.
-
-More examples are provided at the GitHub repository
-and by the upTeX source archive.
-
-== Repository
-
-convbkmk is maintained on GitHub:
-((<URL:https://github.com/t-tk/convbkmk>))
-
-== License
-
-convbkmk
-
-Copyright (c) 2009-2018 Takuji Tanaka
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-== History
-
-: 2009.08.02 0.00
- * Initial version.
-: 2011.05.02 0.01
- * Bug fix: BOM was not correct.
-: 2012.05.08 0.02
- * Bug fix: for a case of dvips with -z option and Ruby1.8.
- * Add conversion of /Creator and /Producer .
-: 2012.05.12 0.03
- * Suppress halfwidth -> fullwidth katakana conversion and MIME decoding in Ruby1.8.
-: 2012.06.01 0.04
- * Support escape sequences: \n, \r, \t, \b, \f, \\, \ddd (octal, PDFDocEncoding) and \0xUUUU (Unicode UTF-16BE).
- * Support sequences of end of line: '\' or other followed by "\n", "\r\n" or "\r" .
- * Set file IO to binary mode.
-: 2012.07.26 0.05
- * Add -o option to support conversion of OUT files generated by dvipdfmx.
-: 2012.08.07 0.06
- * Bug fix: Ver.0.05 does not work with Ruby1.9.
-: 2012.09.17 0.07
- * Bug fix: An infinite loop occurs in Ver.0.05, 0.06 with -g option in some cases.
- * Add reference for PDFDocEncoding.
-: 2013.05.11 0.08
- * Add -O option: overwrite output files onto input files instead of creating foo-convbkmk.ps .
- * Make comments rd/rdtool friendly.
-: 2014.03.02 0.09
- * Bug fix: Conversion was not complete in some cases.
-: 2014.03.08 0.10
- * Bug fix: Output of binary data might be broken in filter mode on Windows.
-: 2014.12.29 0.10a
- * Update the author's mail address and web site.
-: 2018.11.11 0.20
- * Do not support Ruby1.8 anymore.
-: 2018.11.25 0.30
- * Add -d option to support conversion of graphic file names in dvi special by pLaTeX.
-
-=end
-
-Version = "0.30"
-
-require "optparse"
-
-if RUBY_VERSION < "1.9"
- abort("Ruby 1.8 or earlier is no longer supported.")
-end
-
-class String
- def to_utf8(enc)
- self.force_encoding(enc.current).encode('UTF-8')
- end
- def utf16be_to_utf8
- self.force_encoding('UTF-16BE').encode('UTF-8')
- end
- def utf8_to_utf16be
- self.force_encoding('UTF-8').encode('UTF-16BE')
- end
-end
-
-class TeXEncoding
- attr_accessor :current, :option, :status, :is_8bit
- attr_reader :list
-
- def initialize
- @current = false
- @option = false
- @status = false
- @is_8bit = false
- @list = ['Shift_JIS', 'EUC-JP', 'UTF-8']
- end
-
- def set_process_encoding(enc)
- if @status == 'fixed'
- raise 'dupulicate definition'
- end
- if enc == 'guess'
- @option = 'guess'
- @status = 'guess'
- else
- @current = enc
- @option = enc
- @status = 'fixed'
- end
- return enc
- end
-end
-enc = TeXEncoding.new
-
-Opts = {}
-
-OptionParser.new do |opt|
- opt.on('-e', '--euc-jp',
- 'set pTeX internal encoding to EUC-JP') {|v|
- enc.set_process_encoding('EUC-JP')
- }
- opt.on('-s', '--shift_jis',
- 'set pTeX internal encoding to Shift_JIS') {|v|
- enc.set_process_encoding('Shift_JIS')
- }
- opt.on('-u', '--utf-8',
- 'set upTeX internal encoding to UTF-8') {|v|
- enc.set_process_encoding('UTF-8')
- }
- opt.on('-g', '--guess',
- 'guess pTeX/upTeX internal encoding') {|v|
- enc.set_process_encoding('guess')
- }
- enc_alias = Hash.new
- enc.list.each { |e|
- enc_alias[e] = e
- enc_alias[e[0]] = e
- enc_alias[e.downcase] = e
- }
- opt.on('--enc=ENC', enc_alias,
- 'set pTeX/upTeX internal encoding to ENC') {|v|
- enc.set_process_encoding(v)
- }
- opt.on('-o', '--out',
- 'treat OUT files') {|v|
- Opts[:mode] = :out
- Opts[:overwrite] = true
- require "fileutils"
- }
- opt.on('-d', '--dvi-special',
- 'treat specials in DVI files') {|v|
- Opts[:mode] = :spc
- Dvispc = ENV["DVISPC"] ||= 'dvispc'
- require "fileutils"
- }
- opt.on('-O', '--overwrite',
- 'overwrite output files') {|v|
- Opts[:overwrite] = true
- require "fileutils"
- }
- opt.banner += " file0.ps [file1.ps ...]\n" \
- + opt.banner.sub('Usage:',' ') + " < in_file.ps > out_file.ps\n" \
- + opt.banner.sub('Usage:',' ') + " -o file0.out [file1.out ...]\n" \
- + opt.banner.sub('Usage:',' ') + " -d file0.dvi [file1.dvi ...]\n" \
- + opt.banner.sub('Usage:',' ') + " -d file0.dvispc [file1.dvispc ...]"
-
- opt.parse!
-end
-
-# default encoding
-if enc.status == false
- enc.set_process_encoding('UTF-8')
-end
-if Opts[:mode] == :out
- OpenP, CloseP, OpenPEsc, ClosePEsc = '{', '}', '\{', '\}'
- FileSfx = 'out'
-elsif Opts[:mode] == :spc then
- FileSfx = '(dvi|dvispc)'
-else
- OpenP, CloseP, OpenPEsc, ClosePEsc = '(', ')', '\(', '\)'
- FileSfx = 'ps'
-end
-
-def try_guess_encoding(line, enc)
- return 'US-ASCII' if line.ascii_only?
-
- enc.is_8bit = true
- valid_enc = false
- count = 0
- enc.list.each { |e|
- if line.dup.force_encoding(e).valid_encoding?
- count += 1
- valid_enc = e
- end
- }
- if count == 1
- enc.set_process_encoding(valid_enc)
- return valid_enc
- elsif count > 1
- return false # ambiguous
- else
- raise 'Cannot guess encoding!'
- end
-end
-
-def os_legacy_encoding(enc)
- return if enc.status != 'guess'
- enc.is_8bit = true
- if (RUBY_PLATFORM =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/i)
- valid_enc = 'Shift_JIS'
- else
- valid_enc = 'EUC-JP'
- end
- enc.set_process_encoding(valid_enc)
-end
-
-def check_parentheses_balance(line, enc)
- depth = 0
- count = 0
- tmp_prev = ''
- tmp_rest = line
-
- if enc.status == 'guess'
- if tmp_enc = try_guess_encoding(line, enc)
- # succeeded in guess or ascii only
- tmp_rest = line.force_encoding(tmp_enc)
- else
- # ambiguous
- raise 'unexpected internal condition!'
- end
- else
- tmp_enc = enc.current
- tmp_rest = tmp_rest.force_encoding(tmp_enc)
- unless tmp_rest.valid_encoding?
- # illegal input
- $stdout = STDERR
- p 'parameters: '
- p ' status: ' + enc.status
- p ' option: ' + enc.option
- p ' current: ' + enc.current
- p enc.is_8bit
- p ' [' + line + ']'
- raise 'encoding is not consistent'
- end
- end
-
- while tmp_rest.length>0 do
- if (tmp_rest =~ /\A(\\#{OpenPEsc}|\\#{ClosePEsc}|[^#{OpenP}#{CloseP}])*(#{OpenPEsc}|#{ClosePEsc})/o) # parenthis
- if $2 == OpenP
- depth += 1
- count += 1
- else
- depth -= 1
- end
- tmp_prev += $&
- tmp_rest = $'
- else
- tmp_prev += tmp_rest
- tmp_rest = ''
- end
- if depth<1
- break
- end
- end
- return depth, count, tmp_prev, tmp_rest
-end
-
-# PDFDocEncoding -> UTF-16BE
-# Ref. "PDF Reference, Sixth Edition, version 1.7", 2006, Adobe Systems Incorporated
-# http://www.adobe.com/devnet/pdf/pdf_reference_archive.html
-# http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf
-PDF2UNI = Array(0..255)
-PDF2UNI[0o030..0o037] = 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc
-PDF2UNI[0o200..0o207] = 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044
-PDF2UNI[0o210..0o217] = 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018
-PDF2UNI[0o220..0o227] = 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160
-PDF2UNI[0o230..0o237] = 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0xfffd
-PDF2UNI[0o240 ] = 0x20ac
-PDF2UNI[0o255 ] = 0xfffd
-
-def conv_string_to_utf16be(line, enc)
- if line !~ /(#{OpenPEsc})(.*)(#{ClosePEsc})/mo
- raise 'illegal input!'
- end
- pre, tmp, post = $`, $2, $'
-
- if tmp.ascii_only? && tmp !~ /\\0x[0-9A-F]{4}/i
- return line
- end
-
- conv = ''
- conv.force_encoding('UTF-8')
- tmp.force_encoding(enc.current)
-
- while tmp.length>0 do
- case tmp
- when /\A[^\\\n\r]+/
- conv += $&.to_utf8(enc)
- when /\A\\([0-3][0-7][0-7])/ # PDFDocEncoding -> UTF-8
- conv += [PDF2UNI[$1.oct]].pack("U*")
- when /\A\\0x(D[8-B][0-9A-F]{2})\\0x(D[C-F][0-9A-F]{2})/i # surrogate pair
- conv += [$1.hex, $2.hex].pack("n*").utf16be_to_utf8
- when /\A\\0x([0-9A-F]{4})/i
- conv += [$1.hex].pack("U*")
- when /\A\\[nrtbf\\]/
- conv += eval(%!"#{$&}"!)
- when /\A(\r\n|\r|\n)/
- conv += "\n"
- when /\A\\([\r\n]{1,2})|\\/
- # ignore
- else
- raise 'unexpected input!'
- end
- tmp = $'
- end
-
- buf = ''
- conv16be = "\xFE\xFF" # BOM U+FEFF
- conv16be.force_encoding('UTF-16BE')
- conv16be += conv.utf8_to_utf16be # UTF-16BE with BOM
- conv16be.each_byte {|byte|
- buf += (Opts[:mode] == :out ? '\%03o' : '%02X') % byte
- }
- buf = Opts[:mode] == :out ? '{' + buf + '}' : '<' + buf + '>'
- return pre + buf + post
-end
-
-def special_string_to_utf8(line, enc)
- if line.ascii_only? || line !~ /\Axxx[1-4]/mo
- return line, 0
- end
-
- if line !~ /\Axxx(\d) (\d+) '(.*)'([^']*)\Z/mo
- raise 'illegal input!'
- end
- xxx, bytes, str, trail = $1.to_i, $2.to_i, $3, $4
- if str.bytesize != bytes
- raise 'byte size is not consistent!'
- end
- if str !~ /\A((PS|ps)file=|pdf:image |pdf:epdf )/mo
- return line, 0
- end
-
- conv = ''
- conv.force_encoding('UTF-8')
-
- os_legacy_encoding(enc)
- str.force_encoding(enc.current)
- str = str.to_utf8(enc)
- bytes_new = str.bytesize
-
- xxx_new = bytes_new <= 0xff ? 1 : 4
- conv = 'xxx' + xxx_new.to_s + ' ' + bytes_new.to_s + " '" + str + "'" + trail
- return conv, bytes_new - bytes + xxx_new - xxx
-end
-
-def dvi_post_post(line, offset)
- if line !~ /\Apost_post (\d+) ([23])(?: 223){4,7}\Z/mo
- raise 'illegal input!'
- end
- bytes, id = $1.to_i, $2
- padding = line.scan(' 223').count
- bytes += offset
- padding = (padding - offset) % 4 + 4
- line = 'post_post ' + bytes.to_s + ' ' + id + ' 223' * padding + "\n"
- return line
-end
-
-def file_treatment(ifile, ofile, enc)
- ifile.set_encoding('ASCII-8BIT')
- ofile.set_encoding('ASCII-8BIT')
-
- line, offset = '', 0
- while l = ifile.gets do
- line.force_encoding('ASCII-8BIT')
- line += l
- if Opts[:mode] == :out then
- reg = %r!(\{)!
- elsif Opts[:mode] == :spc then
- reg = %r!(\A(xxx|post_post))!
- else
- reg = %r!(/Title|/Author|/Keywords|/Subject|/Creator|/Producer)(\s+\(|$)!
- end
- if (line !~ reg )
- ofile.print line
- line = ''
- next
- end
-
- if Opts[:mode] == :spc
- if (line =~ /\Axxx/)
- line, diff = special_string_to_utf8(line, enc)
- offset += diff
- else
- line = dvi_post_post(line, offset)
- end
- ofile.print line
- line = ''
- next
- end
-
- ofile.print $`
- line = $& + $'
-
- if Opts[:mode] != :out
- while line =~ %r!(/Title|/Author|/Keywords|/Subject|/Creator|/Producer)\Z! do
- line += ifile.gets
- end
- end
-
- if enc.status == 'guess'
- if tmp_enc = try_guess_encoding(line, enc)
- # succeeded in guess or ascii only
- line.force_encoding(tmp_enc)
- else
- # ambiguous
- next
- end
- end
-
- while line.length>0 do
- depth, count, tmp_prev, tmp_rest \
- = check_parentheses_balance(line, enc)
- if depth<0
- p depth, count, tmp_prev, tmp_rest
- raise 'illegal input! (depth<0)'
- elsif depth>0
- break
- elsif count==0
- ofile.print line
- line = ''
- break
- elsif count>0
- ofile.print conv_string_to_utf16be(tmp_prev, enc)
- line = tmp_rest
- else
- p depth, count, tmp_prev, tmp_rest
- raise 'illegal input! (count<0)'
- end
- end
-
- end
-
- if enc.status == 'guess' && enc.is_8bit
- raise 'did not succeed in guess encoding!'
- end
-end
-
-
-### main
-if ARGV.size == 0
- ifile = STDIN.binmode
- ofile = STDOUT.binmode
- file_treatment(ifile, ofile, enc)
-else
- ARGV.each {|fin|
- if (fin !~ /\.#{FileSfx}$/io)
- raise 'input file does not seem ' + FileSfx.upcase + ' file'
- end
- sfx = $&
- if (Opts[:mode] == :spc && fin =~ /\.dvi$/i)
- dvi_conversion = true
- fspc = fin.gsub(/\.dvi$/io, '.dvispc')
- if !(system Dvispc + ' -a ' + fin + ' ' + fspc)
- raise "fail to execute 'dvispc -a' command!"
- end
- fin = fspc
- sfx = '.dvispc'
- end
- fout = fin.gsub(/#{sfx}$/i, "-convbkmk#{sfx}")
- open(fin, 'rb') {|ifile|
- open(fout, 'wb') {|ofile|
- file_treatment(ifile, ofile, enc)
- }
- }
- if (Opts[:overwrite])
- FileUtils.mv(fout, fin)
- fout = fin
- end
- if dvi_conversion
- fdvi = fout.gsub(/\.dvispc$/o, '.dvi')
- if !(system Dvispc + ' -x ' + fout + ' ' + fdvi)
- raise "fail to execute 'dvispc -x' command!"
- end
- end
- }
-end
-
diff --git a/Build/source/texk/texlive/linked_scripts/crossrefware/bbl2bib.pl b/Build/source/texk/texlive/linked_scripts/crossrefware/bbl2bib.pl
deleted file mode 100755
index 397e52a6af8..00000000000
--- a/Build/source/texk/texlive/linked_scripts/crossrefware/bbl2bib.pl
+++ /dev/null
@@ -1,350 +0,0 @@
-#!/usr/bin/env perl
-
-=pod
-
-=head1 NAME
-
-bbl2bib.pl - convert thebibliography environment to a bib file
-
-=head1 SYNOPSIS
-
-bbl2bib.pl [-d] [-u] [B<-o> I<output>] I<file>
-
-=head1 OPTIONS
-
-=over 4
-
-=item [-d]
-
-Send debugging output to stdout
-
-=item B<-o> I<output>
-
-Output file. If this option is not used, the name for the
-output file is formed by changing the extension to C<.bib>
-
-
-=item B<-u>
-
-Do not clean URL fields.
-
-Normally C<bbl2bib> recognizes URL fields of the kind
-C<http://dx.doi.org> and their variants and converts them to DOI
-fields (see also L<biburl2doi(1)> script). The switch B<-u>
-suppresses this cleanup.
-
-=back
-
-=head1 DESCRIPTION
-
-The script tries to reconstruct a C<bib> file from the corresponding
-C<thebibliography> environment. One can argue that this operation is
-akin to reconstructing a cow from the steak. The way the script does
-it is searching for the entry in the MR database, and
-creating the corresponding BibTeX fields.
-
-The script reads a TeX or Bbl file and extracts from it the
-C<thebibliography> environment. For each bibitem it creates a plain
-text bibliography entry, and then tries to match it in
-the database.
-
-=head1 INPUT FILE
-
-We assume some structure of the input file:
-
-=over 4
-
-=item 1.
-
-The bibliography is contained between the lines
-
- \begin{thebibliography}...
-
-and
-
- \end{thebibliography}
-
-=item 2.
-
-Each bibliography item starts from the line
-
- \bibitem[...]{....}
-
-=back
-
-
-
-=head1 EXAMPLES
-
- bbl2bib -o - file.tex > result.bib
- bbl2bib -o result.bib file.bbl
- bbl2bib file.tex
-
-=head1 AUTHOR
-
-Boris Veytsman
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2014-2017 Boris Veytsman
-
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the
-extent permitted by law.
-
-=cut
-
-use strict;
-BEGIN {
- # find files relative to our installed location within TeX Live
- chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
- if (length($TLMaster)) {
- unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
- }
-}
-use IO::File;
-use BibTeX::Parser;
-use FileHandle;
-use LaTeX::ToUnicode qw (convert);
-use Getopt::Std;
-use URI::Escape;
-use LWP::Simple;
-# Sometimes AMS forgets to update certificates
-$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
-
-
-my $USAGE="USAGE: $0 [-d] [-u] [-o output] file\n";
-my $VERSION = <<END;
-bbl2bib v2.3
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the
-extent permitted by law.
-$USAGE
-END
-our %opts;
-getopts('do:huV',\%opts) or die $USAGE;
-
-if ($opts{h} || $opts{V}){
- print $VERSION;
- exit 0;
-}
-
-################################################################
-# Defaults and parameters
-################################################################
-
-my $inputfile = shift;
-
-my $outputfile = $inputfile;
-
-$outputfile =~ s/\.([^\.]*)$/.bib/;
-
-if (exists $opts{o}) {
- $outputfile = $opts{o};
-}
-
-my $debug=0;
-if ($opts{d}) {
- $debug=1;
-}
-
-my $cleanUrls = 1;
-if ($opts{u}) {
- $cleanUrls = 0;
-}
-
-my $input= IO::File->new($inputfile) or
- die "Cannot find Bbl or TeX file $inputfile\n$USAGE\n";
-my $output = IO::File->new("> $outputfile") or
- die "Cannot write to $outputfile\n$USAGE\n";
-
-my $userAgent = LWP::UserAgent->new;
-
-
-# Bibitem is a hash with the entries 'key', 'text', 'mr',
-# 'zbl'
-my $bibitem;
-
-while (<$input>) {
- if (!(/\\begin\{thebibliography\}/../\\end\{thebibliography\}/) ||
- /\\begin\{thebibliography\}/ || /\\end\{thebibliography\}/) {
- next;
- }
- if (/\\bibitem\s*(\[[^\]]*\])?\{([^\}]*)\}/) {
- ProcessBibitem($bibitem);
- $bibitem = undef;
- $bibitem->{key}=$2;
- $bibitem->{text}="";
- }
- if (!/^\s*$/) {
- $bibitem -> {text} .= $_;
- }
-}
-ProcessBibitem($bibitem);
-
-
-exit 0;
-
-sub ProcessBibitem {
- my $bibitem = shift;
- my $key = $bibitem->{key};
- my $text=$bibitem->{text};
-
- if ($debug) {
- print STDOUT "DEBUG: Processing item $key\n";
- }
-
- if (!length($text) || $text =~ /^\s+$/s) {
- if ($debug) {
- print STDOUT "DEBUG: No text found\n";
- }
- return;
- }
-
- my $printtext = $text;
- $printtext =~ s/^(.)/% $1/mg;
- print $output "$printtext";
- $text =~ s/\n/ /mg;
- $text =~ s/\\bibitem(\[[^\]]*\])?\{[^\}]*\}//;
-
- # Arxiv entry?
- if ($text =~ s/\\arxiv\{([^\}]+)\}\.?//) {
- if ($debug) {
- print STDOUT "DEBUG: Found arXiv number $1\n";
- }
- $bibitem->{arxiv}=$1;
- }
-
- # Mr number exists?
- if ($text =~ s/\\mr\{([^\}]+)\}\.?//) {
- if ($debug) {
- print STDOUT "DEBUG: Found mr number $1\n";
- }
- $bibitem->{mr}=$1;
- }
-
- # zbl number exists?
- if ($text =~ s/\\zbl\{([^\}]+)\}\.?//) {
- if ($debug) {
- print STDOUT "DEBUG: Found zbl number $1\n";
- }
- $bibitem->{zbl}=$1;
- }
-
- # doi number exists?
- if ($text =~ s/\\doi\{([^\}]+)\}\.?//) {
- if ($debug) {
- print STDOUT "DEBUG: Found doi $1\n";
- }
- $bibitem->{doi}=$1;
- }
-
- $bibitem->{bib} = SearchMref($bibitem);
-
- if ($cleanUrls) {
- $bibitem->{bib} = CleanUrl ($bibitem->{bib});
- }
-
- PrintBibitem($bibitem);
- return;
-}
-
-
-sub SearchMref {
- my $bibitem = shift;
- my $mirror = "http://www.ams.org/mathscinet-mref";
- my $string=uri_escape_utf8($bibitem->{text});
- if ($debug) {
- print STDOUT "Sending $mirror?ref=$string".'&'."dataType=bibtex\n"
- }
- my $response = $userAgent->get("$mirror?ref=$string&dataType=bibtex") ->
- decoded_content();
- if ($debug) {
- print STDOUT "DEBUG: Response $response\n";
- }
- if ($response =~ /<pre>(.*)<\/pre>/s) {
- my $bib= $1;
- # Looks like Mathscinet sometimes fails to unaccent text.
- # For the time being we just delete the offending characters.
- # Should probably write LaTeX::FromUnicode instead
- $bib =~ s/[^\x00-\x7f]//g;
- if ($debug) {
- print STDOUT "DEBUG: got $bib\n";
- }
- my $fh = new FileHandle;
- open $fh, "<", \$bib;
- my $parser = new BibTeX::Parser($fh);
- my $entry = $parser->next;
- if (ref($entry) && $entry->parse_ok()) {
- $entry->key($bibitem->{key});
- return ($entry);
- } else {
- if ($debug) {
- if (!ref($entry)) {
- print STDERR "DEBUG: not a reference\n";
- } else{
- print STDERR "DEBUG: parsing $entry->parse_ok\n";
- }
- }
- }
- } else {
- if ($debug) {
- print STDOUT "DEBUG: did not get an entry\n";
- }
- }
-}
-
-sub CleanUrl {
- my $entry = shift;
- if (!ref($entry)) {
- return $entry;
- }
-
- if ($entry->has('doi')) {
- return $entry;
- }
- if (!$entry->has('url')) {
- return $entry;
- }
- if ($entry->field('url') =~ m|^http(?:s)?://(?:dx\.)?doi\.org/(.*)$|) {
- $entry->field('doi', $1);
- delete $entry->{'url'};
- }
- return $entry;
-
-}
-
-
-sub PrintBibitem {
- print $output "\n";
- my $bibitem = shift;
- if (!ref($bibitem->{bib})) {
- return;
- }
- my $entry=$bibitem->{bib};
- if ($bibitem->{mr} && ! $entry->field('mrnumber')) {
- $entry->field('mrnumber', $bibitem->{mr});
- }
- if ($entry->field('mrnumber')) {
- my $mr=$entry->field('mrnumber');
- while (length($mr)<7) {
- $mr = "0$mr";
- }
- $mr=$entry->field('mrnumber', $mr);
- }
- if ($bibitem->{zbl} && ! $entry->field('zblnumber')) {
- $entry->field('zblnumber', $bibitem->{zbl});
- }
- if ($bibitem->{doi} && ! $entry->field('doi')) {
- $entry->field('doi', $bibitem->{doi});
- }
- if ($bibitem->{arxiv} && ! $entry->field('arxiv')) {
- $entry->field('arxiv', $bibitem->{arxiv});
- }
-
- print $output $entry->to_string(), "\n\n";
-}
-
-
diff --git a/Build/source/texk/texlive/linked_scripts/crossrefware/bibdoiadd.pl b/Build/source/texk/texlive/linked_scripts/crossrefware/bibdoiadd.pl
deleted file mode 100755
index 219896bf404..00000000000
--- a/Build/source/texk/texlive/linked_scripts/crossrefware/bibdoiadd.pl
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/env perl
-
-=pod
-
-=head1 NAME
-
-bibdoiadd.pl - add DOI numbers to papers in a given bib file
-
-=head1 SYNOPSIS
-
-bibdoiadd [B<-c> I<config_file>] [B<-C> 1|0] [B<-e> 1|0] [B<-f>] [B<-o> I<output>] I<bib_file>
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-c> I<config_file>
-
-Configuration file. If this file is absent, some defaults are used.
-See below for its format.
-
-=item B<-C> 1|0
-
-Whether to canonize names in the output (1) or not (0). By default, 1.
-
-=item B<-e>
-
-If 1 (default), add empty doi if a doi cannot be found. This prevents
-repeated searches for the same entries if you add new entries to the
-file. Calling C<-e 0> suppresses this behavior.
-
-=item B<-f>
-
-Force checking doi number even if one is present
-
-=item B<-o> I<output>
-
-Output file. If this option is not used, the name for the
-output file is formed by adding C<_doi> to the input file
-
-=back
-
-=head1 DESCRIPTION
-
-The script reads a BibTeX file. It checks whether the entries have
-DOIs. If not, it tries to contact http://www.crossref.org to get the
-corresponding DOI. The result is a BibTeX file with the fields
-C<doi=...> added.
-
-The name of the output file is either set by the B<-o> option or
-is derived by adding the suffix C<_doi> to the output file.
-
-There are two options for making queries with Crossref: free account
-and paid membership. In the first case you still must register with
-Crossref and are limited to a small number of queries, see the
-agreement at
-C<http://www.crossref.org/01company/free_services_agreement.html>. In
-the second case you have a username and password, and can use them for
-automatic queries. I am not sure whether the use of this script is
-allowed for the free account holders. Anyway if you try to add DOI
-to a large number of entries, you should register as a paid member.
-
-
-
-=head1 CONFIGURATION FILE
-
-The configuration file is mostly self-explanatory: it has comments
-(starting with C<#>) and assginments in the form
-
- $field = value ;
-
-The important parameters are C<$mode> (C<'free'> or C<'paid'>),
-C<$email> (for free users) and C<$username> & C<$password> for paid
-members.
-
-
-=head1 EXAMPLES
-
- bibdoiadd -c bibdoiadd.cfg -o - citations.bib > result.bib
- bibdoiadd -c bibdoiadd.cfg -o result.bib citations.bib
-
-=head1 AUTHOR
-
-Boris Veytsman
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2014-2017 Boris Veytsman
-
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the
-extent permitted by law.
-
-=cut
-
-use strict;
-BEGIN {
- # find files relative to our installed location within TeX Live
- chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
- if (length($TLMaster)) {
- unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
- }
-}
-use IO::File;
-use BibTeX::Parser;
-use LaTeX::ToUnicode qw (convert);
-use Getopt::Std;
-use URI::Escape;
-use LWP::Simple;
-# Sometimes AMS forgets to update certificates
-$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
-
-my $USAGE="USAGE: $0 [-c config] [-C 1|0] [-e 1|0] [-f] [-o output] file\n";
-my $VERSION = <<END;
-bibdoiadd v2.2
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the
-extent permitted by law.
-$USAGE
-END
-our %opts;
-getopts('fe:c:C:o:hV',\%opts) or die $USAGE;
-
-if ($opts{h} || $opts{V}){
- print $VERSION;
- exit 0;
-}
-
-################################################################
-# Defaults and parameters
-################################################################
-
-my $inputfile = shift;
-
-my $outputfile = $inputfile;
-
-$outputfile =~ s/\.([^\.]*)$/_doi.$1/;
-
-if (exists $opts{o}) {
- $outputfile = $opts{o};
-}
-
-my $forceSearch=$opts{f};
-my $forceEmpty = 1;
-if (exists $opts{e}) {
- $forceEmpty = $opts{e};
-}
-
-my $canonizeNames = 1;
-if (exists $opts{C}) {
- $canonizeNames = $opts{C};
-}
-
-our $mode='free';
-our $email;
-our $username;
-our $password;
-
-if ($opts{c}) {
- if (-r $opts{c}) {
- push @INC, ".";
- require $opts{c};
- } else {
- die "Cannot read options $opts{c}. $USAGE";
- }
-}
-
-
-# Check the consistency
-
-if ($mode eq 'free' && !length($email)) {
- die "Crossref requires a registered e-mail for the free mode queries\n";
-}
-
-if ($mode eq 'paid' && (!length($username) || !length($password))) {
- die
- "Crossref requires a username and password for the paid mode queries\n";
-}
-
-my $input= IO::File->new($inputfile) or
- die "Cannot find BibTeX file $inputfile\n$USAGE\n";
-my $output = IO::File->new("> $outputfile") or
- die "Cannot write to $outputfile\n$USAGE\n";
-
-my $parser=new BibTeX::Parser($input);
-
-my $prefix =
- "http://www.crossref.org/openurl?redirect=false";
-if ($mode eq 'free') {
- $prefix .= '&pid='.uri_escape($email);
-} else {
- $prefix .= '&pid='.uri_escape($username).":".
- uri_escape($password);
-}
-
-# Processing the input
-while (my $entry = $parser->next) {
- if (!$entry->parse_ok()) {
- print STDERR "Cannot understand entry: ";
- $entry->print(*STDERR);
- print STDERR "Skipping this entry\n";
- next;
- }
-
- if (!($entry->type() eq 'ARTICLE') && !($entry->type() eq 'BOOK')
- && !($entry->type() eq 'INCOLLECTION')) {
- print $output $entry->raw_bibtex(), "\n\n";
- next;
- }
- if ($entry->has('doi') && !$forceSearch) {
- print $output $entry->raw_bibtex(), "\n\n";
- next;
- }
-
-
-
- my $doi = GetDoi($prefix, $entry);
- if (length($doi) || $forceEmpty) {
- $entry->field('doi',$doi);
- }
-
- print $output
- $entry->to_string(canonize_names=>$canonizeNames),
- "\n\n";
-
-
-}
-
-$input->close();
-$output->close();
-exit 0;
-
-###############################################################
-# Getting one doi
-###############################################################
-
-sub GetDoi {
- my ($url,$entry) = @_;
- if ($entry->has('issn')) {
- $url .= "&issn=".uri_escape_utf8(SanitizeText($entry->field('issn')));
- }
- if ($entry->has('journal')) {
- $url .= "&title=".uri_escape_utf8(SanitizeText($entry->field('journal')));
- }
- my @names=$entry->author();
- if (scalar(@names)) {
- my $lastname = SanitizeText($names[0]->last());
- $url .= "&aulast=".uri_escape_utf8($lastname);
- }
- if ($entry->has('volume')) {
- $url .= "&volume=".uri_escape_utf8($entry->field('volume'));
- }
- if ($entry->has('number')) {
- $url .= "&issue=".uri_escape_utf8($entry->field('number'));
- }
- if ($entry->has('pages')) {
- my $pages=$entry->field('pages');
- $pages =~ s/-.*$//;
- $url .= "&spage=".uri_escape_utf8($pages);
- }
- if ($entry->has('year')) {
- $url .= "&date=".uri_escape_utf8($entry->field('year'));
- }
-
- my $result=get($url);
-
- if ($result =~ m/<doi [^>]*>(.*)<\/doi>/) {
- return $1;
- } else {
- return "";
- }
-}
-
-###############################################################
-# Sanitization of a text string
-###############################################################
-sub SanitizeText {
- my $string = shift;
- $string = convert($string);
- $string =~ s/\\newblock//g;
- $string =~ s/\\bgroup//g;
- $string =~ s/\\egroup//g;
- $string =~ s/\\scshape//g;
- $string =~ s/\\urlprefix//g;
- $string =~ s/\\emph//g;
- $string =~ s/\\textbf//g;
- $string =~ s/\\enquote//g;
- $string =~ s/\\url/URL: /g;
- $string =~ s/\\doi/DOI: /g;
- $string =~ s/\\\\/ /g;
- $string =~ s/\$//g;
- $string =~ s/\\checkcomma/,/g;
- $string =~ s/~/ /g;
- $string =~ s/[\{\}]//g;
- return $string;
-}
-
diff --git a/Build/source/texk/texlive/linked_scripts/crossrefware/bibmradd.pl b/Build/source/texk/texlive/linked_scripts/crossrefware/bibmradd.pl
deleted file mode 100755
index 10f36113f6a..00000000000
--- a/Build/source/texk/texlive/linked_scripts/crossrefware/bibmradd.pl
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/env perl
-
-=pod
-
-=head1 NAME
-
-bibmradd.pl - add MR numbers to papers in a given bib file
-
-=head1 SYNOPSIS
-
-bibmradd [-d] [B<-f>] [B<-e> 1|0] [B<-o> I<output>] I<bib_file>
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-d>
-
-Debug mode
-
-=item B<-e>
-
-If 1 (default), add an empty mrnumber if a mr cannot be found. This
-prevents repeated searches for the same entries if you add new entries
-to the file. Calling C<-e 0> suppresses this behavior.
-
-
-=item B<-f>
-
-Force searching for MR numbers even if the entry already has one.
-
-=item B<-o> I<output>
-
-Output file. If this option is not used, the name for the
-output file is formed by adding C<_mr> to the input file
-
-=back
-
-=head1 DESCRIPTION
-
-The script reads a BibTeX file. It checks whether the entries have
-mrnumberss. If not, tries to contact internet to get the numbers. The
-result is a BibTeX file with the fields
-C<mrnumber=...> added.
-
-The name of the output file is either set by the B<-o> option or
-is derived by adding the suffix C<_mr> to the output file.
-
-=head1 AUTHOR
-
-Boris Veytsman
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2014-2017 Boris Veytsman
-
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the
-extent permitted by law.
-
-=cut
-
-use strict;
-BEGIN {
- # find files relative to our installed location within TeX Live
- chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
- if (length($TLMaster)) {
- unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
- }
-}
-use IO::File;
-use BibTeX::Parser;
-use Getopt::Std;
-use URI::Escape;
-use LWP::UserAgent;
-$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
-# Sometimes AMS forgets to update certificates
-$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
-
-my $USAGE="USAGE: $0 [-d] [-e 1|0] [-f] [-o output] file\n";
-my $VERSION = <<END;
-bibmradd v2.2
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the
-extent permitted by law.
-$USAGE
-END
-my %opts;
-getopts('de:fo:hV',\%opts) or die $USAGE;
-
-if ($opts{h} || $opts{V}){
- print $VERSION;
- exit 0;
-}
-
-################################################################
-# Defaults and parameters
-################################################################
-
-my $inputfile = shift;
-
-my $outputfile = $inputfile;
-
-$outputfile =~ s/\.([^\.]*)$/_mr.$1/;
-
-if ($opts{o}) {
- $outputfile = $opts{o};
-}
-
-my $forceSearch=$opts{f};
-
-my $forceEmpty = 1;
-if (exists $opts{e}) {
- $forceEmpty = $opts{e};
-}
-
-my $debug = $opts{d};
-
-my $input= IO::File->new($inputfile) or
- die "Cannot find BibTeX file $inputfile\n$USAGE\n";
-my $output = IO::File->new("> $outputfile") or
- die "Cannot write to $outputfile\n$USAGE\n";
-
-my $parser=new BibTeX::Parser($input);
-
-
-
-# Creating the HTTP parameters
-my $mirror =
- "http://www.ams.org/mathscinet-mref";
-my $userAgent = LWP::UserAgent->new;
-
-while (my $entry = $parser->next ) {
- if (!$entry->parse_ok()) {
- print STDERR "Cannot understand entry: ";
- $entry->print(*STDERR);
- print STDERR "Skipping this entry\n";
- next;
- }
- if ($entry->has('mrnumber') && !$forceSearch) {
- print $output $entry->raw_bibtex(), "\n\n";
- if ($debug) {
- print STDERR "DEBUG: entry ", $entry->key(),
- " has mrnumber ", $entry->field('mrnumber'),
- " and no forced search is requested\n";
- }
- next;
- }
-
-
- # Now we have an entry with no MR. Let us get to work.
- if ($debug) {
- print STDERR "DEBUG: Searching for mr number for entry ",
- $entry->key, "\n";
- }
- my $mr = GetMr($entry, $userAgent, $mirror);
- if (length($mr) || $forceEmpty) {
- $entry->field('mrnumber', $mr);
- }
- print $output $entry->to_string(), "\n\n";
-
-}
-
-$input->close();
-$output->close();
-exit 0;
-
-###############################################################
-# Getting one MR
-###############################################################
-
-sub GetMr {
- my $entry=shift;
- my $userAgent=shift;
- my $mirror=shift;
-
- my @query;
-
- my $string=uri_escape_utf8($entry->to_string());
-
- if ($debug) {
- print STDERR "DEBUG: query: $mirror?ref=$string&dataType=bibtex\n" ;
- }
-
-
- my $response = $userAgent->get("$mirror?ref=$string&dataType=bibtex");
- if ($debug) {
- print STDERR "DEBUG: response: ",
- $response->decoded_content, "\n";
- }
-
- if ($response->decoded_content =~ /MRNUMBER\s*=\s*{(.*)}/m) {
- my $mr=$1;
- # Somehow mref deletes leading zeros. They are needed!
- while (length($mr)<7) {
- $mr = "0$mr";
- }
- if ($debug) {
- print STDERR "DEBUG: got MR: $mr\n",
- }
- return $mr;
- } else {
- if ($debug) {
- print STDERR "DEBUG: Did not get MR\n",
- }
- return ("");
- }
-
-}
-
diff --git a/Build/source/texk/texlive/linked_scripts/crossrefware/biburl2doi.pl b/Build/source/texk/texlive/linked_scripts/crossrefware/biburl2doi.pl
deleted file mode 100755
index 76d1842bf92..00000000000
--- a/Build/source/texk/texlive/linked_scripts/crossrefware/biburl2doi.pl
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env perl
-
-=pod
-
-=head1 NAME
-
-biburl2doi.pl - convert URLs pointing to doi.org to DOIs
-
-=head1 SYNOPSIS
-
-biburl2doi [B<-D>] [B<-o> I<output>] I<bib_file>
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-D>
-
-Do not delete URLs converted to DOIs
-
-
-=item B<-o> I<output>
-
-Output file. If this option is not used, the name for the
-output file is formed by adding C<_cleaned> to the input file
-
-=back
-
-=head1 DESCRIPTION
-
-The script recognizes URL fields of the kind
-C<http://dx.doi.org> and their variants and converts them to DOI
-fields.
-
-
-=head1 AUTHOR
-
-Boris Veytsman
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2017 Boris Veytsman
-
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the
-extent permitted by law.
-
-=cut
-
-use strict;
-BEGIN {
- # find files relative to our installed location within TeX Live
- chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
- if (length($TLMaster)) {
- unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
- }
-}
-use IO::File;
-use BibTeX::Parser;
-use LaTeX::ToUnicode qw (convert);
-use Getopt::Std;
-
-my $USAGE="USAGE: $0 [-D] [-o output] file\n";
-my $VERSION = <<END;
-biburl2doi 1.0
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the
-extent permitted by law.
-$USAGE
-END
-our %opts;
-getopts('Do:hV',\%opts) or die $USAGE;
-
-if ($opts{h} || $opts{V}){
- print $VERSION;
- exit 0;
-}
-
-################################################################
-# Defaults and parameters
-################################################################
-
-my $inputfile = shift;
-
-my $outputfile = $inputfile;
-
-$outputfile =~ s/\.([^\.]*)$/_cleaned.$1/;
-
-if (exists $opts{o}) {
- $outputfile = $opts{o};
-}
-
-my $deleteUrl = 1;
-if (exists $opts{D}) {
- $deleteUrl = 0;
-}
-
-
-my $input= IO::File->new($inputfile) or
- die "Cannot find BibTeX file $inputfile\n$USAGE\n";
-my $output = IO::File->new("> $outputfile") or
- die "Cannot write to $outputfile\n$USAGE\n";
-
-my $parser=new BibTeX::Parser($input);
-
-
-
-# Processing the input
-while (my $entry = $parser->next) {
- if (!$entry->parse_ok()) {
- print STDERR "Cannot understand entry: ";
- $entry->print(*STDERR);
- print STDERR "Skipping this entry\n";
- next;
- }
-
- if ($entry->has('doi') || !$entry->has('url')) {
- print $output $entry->raw_bibtex(), "\n\n";
- next;
- }
-
- if ($entry->field('url') =~ m|^http(?:s)?://(?:dx\.)?doi\.org/(.*)$|) {
- $entry->field('doi', $1);
- if ($deleteUrl) {
- delete $entry->{'url'};
- }
- print $output $entry->to_string(), "\n\n";
- } else {
- print $output $entry->raw_bibtex(), "\n\n";
- }
-}
-
-
-
diff --git a/Build/source/texk/texlive/linked_scripts/crossrefware/bibzbladd.pl b/Build/source/texk/texlive/linked_scripts/crossrefware/bibzbladd.pl
deleted file mode 100755
index 7516862bafe..00000000000
--- a/Build/source/texk/texlive/linked_scripts/crossrefware/bibzbladd.pl
+++ /dev/null
@@ -1,205 +0,0 @@
-#!/usr/bin/env perl
-
-=pod
-
-=head1 NAME
-
-bibzbladd.pl - add Zbl numbers to papers in a given bib file
-
-=head1 SYNOPSIS
-
-bibzbladd [-d] [B<-f>] [B<-e> 1|0] [B<-o> I<output>] I<bib_file>
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-d>
-
-Debug mode
-
-=item B<-e>
-
-If 1 (default), add an empty zblnumber if a zbl cannot be found. This
-prevents repeated searches for the same entries if you add new entries
-to the file. Calling C<-e 0> suppresses this behavior.
-
-
-=item B<-f>
-
-Force searching for Zbl numbers even if the entry already has one.
-
-=item B<-o> I<output>
-
-Output file. If this option is not used, the name for the
-output file is formed by adding C<_zbl> to the input file
-
-=back
-
-=head1 DESCRIPTION
-
-The script reads a BibTeX file. It checks whether the entries have
-Zbls. If not, tries to contact internet to get the numbers. The
-result is a BibTeX file with the fields
-C<zblnumber=...> added.
-
-The name of the output file is either set by the B<-o> option or
-is derived by adding the suffix C<_zbl> to the output file.
-
-=head1 AUTHOR
-
-Boris Veytsman
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2014-2017 Boris Veytsman
-
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the
-extent permitted by law.
-
-=cut
-
-use strict;
-BEGIN {
- # find files relative to our installed location within TeX Live
- chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
- if (length($TLMaster)) {
- unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
- }
-}
-use IO::File;
-use BibTeX::Parser;
-use Getopt::Std;
-use URI::Escape;
-use LWP::UserAgent;
-$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
-
-my $USAGE="USAGE: $0 [-d] [-e 1|0] [-f] [-o output] file\n";
-my $VERSION = <<END;
-bibzbladd v2.2
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the
-extent permitted by law.
-$USAGE
-END
-my %opts;
-getopts('de:fo:hV',\%opts) or die $USAGE;
-
-if ($opts{h} || $opts{V}){
- print $VERSION;
- exit 0;
-}
-
-################################################################
-# Defaults and parameters
-################################################################
-
-my $inputfile = shift;
-
-my $outputfile = $inputfile;
-
-$outputfile =~ s/\.([^\.]*)$/_zbl.$1/;
-
-if ($opts{o}) {
- $outputfile = $opts{o};
-}
-
-my $forceSearch=$opts{f};
-
-my $forceEmpty = 1;
-if (exists $opts{e}) {
- $forceEmpty = $opts{e};
-}
-
-my $debug = $opts{d};
-
-my $input= IO::File->new($inputfile) or
- die "Cannot find BibTeX file $inputfile\n$USAGE\n";
-my $output = IO::File->new("> $outputfile") or
- die "Cannot write to $outputfile\n$USAGE\n";
-
-my $parser=new BibTeX::Parser($input);
-
-
-
-# Creating the HTTP parameters
-my $mirror =
- "https://zbmath.org/citationmatching/bibtex/match";
-my $userAgent = LWP::UserAgent->new;
-
-while (my $entry = $parser->next ) {
- if (!$entry->parse_ok()) {
- print STDERR "Cannot understand entry: ";
- $entry->print(*STDERR);
- print STDERR "Skipping this entry\n";
- next;
- }
- if ($entry->has('zblnumber') && !$forceSearch) {
- print $output $entry->raw_bibtex(), "\n\n";
- if ($debug) {
- print STDERR "DEBUG: entry ", $entry->key(),
- " has zblnumber ", $entry->field('zblnumber'),
- " and no forced search is requested\n";
- }
- next;
- }
-
-
- # Now we have an entry with no Zbl. Let us get to work.
- if ($debug) {
- print STDERR "DEBUG: Searching for zbl number for entry ",
- $entry->key, "\n";
- }
- my $zbl = GetZbl($entry, $userAgent, $mirror);
- if (length($zbl) || $forceEmpty) {
- $entry->field('zblnumber',$zbl);
- }
- print $output $entry->to_string(), "\n\n";
-
-}
-
-$input->close();
-$output->close();
-exit 0;
-
-###############################################################
-# Getting one Zbl
-###############################################################
-
-sub GetZbl {
- my $entry=shift;
- my $userAgent=shift;
- my $mirror=shift;
-
- my @query;
-
- my $string=uri_escape_utf8($entry->to_string());
-
- if ($debug) {
- print STDERR "DEBUG: query: $mirror?bibtex=$string\n" ;
- }
-
-
- my $response = $userAgent->get("$mirror?bibtex=$string");
- if ($debug) {
- print STDERR "DEBUG: response: ",
- $response->decoded_content, "\n";
- }
-
- if ($response->decoded_content =~ /^\s*"zbl_id":\s*"(.*)",?\s*$/m) {
- if ($debug) {
- print STDERR "DEBUG: got zbl: $1\n",
- }
- return $1;
- } else {
- if ($debug) {
- print STDERR "DEBUG: Did not get zbl\n",
- }
- return ("");
- }
-
-}
-
diff --git a/Build/source/texk/texlive/linked_scripts/crossrefware/ltx2crossrefxml.pl b/Build/source/texk/texlive/linked_scripts/crossrefware/ltx2crossrefxml.pl
deleted file mode 100755
index 105611a7dc9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/crossrefware/ltx2crossrefxml.pl
+++ /dev/null
@@ -1,461 +0,0 @@
-#!/usr/bin/env perl
-
-=pod
-
-=head1 NAME
-
-ltx2crossrefxml.pl - a tool for creation of XML files for submitting to crossref.
-
-=head1 SYNOPSIS
-
-ltx2crossrefxml [B<-c> I<config_file>] [B<-o> I<output>] I<latex_file> I<latex_file> ...
-
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-c> I<config_file>
-
-Configuration file. If this file is absent, some defaults are used.
-See below for its format.
-
-
-=item B<-o> I<output>
-
-Output file. If this option is not used, the XML is output to stdout.
-
-=back
-
-=head1 DESCRIPTION
-
-The script takes a number of latex files and produces an XML file
-ready for submission to Crossref. Each file must be previously processed
-by LaTeX with the newest C<resphilosophica> package: the package creates
-the file C<.rti> wtih the information about the bibliography.
-
-The processing of reference list is at present rather limited: only so
-called unstructured references are produced.
-
-=head1 CONFIGURATION FILE FORMAT
-
-The configuration file is mostly self-explanatory: it has comments
-(starting with C<#>) and assginments in the form
-
- $field = value ;
-
-=head1 EXAMPLES
-
- ltx2crossrefxml.pl ../paper1/paper1.tex ../paper2/paper2.tex -o result.xml
-
- ltx2crossrefxml.pl -c myconfig.cnf paper.tex -o paper.xml
-
-=head1 AUTHOR
-
-Boris Veytsman
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2012-2016 Boris Veytsman
-
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the
-extent permitted by law.
-
-
-=cut
-
- use strict;
-
- BEGIN {
- # find files relative to our installed location within TeX Live
- chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
- if (length($TLMaster)) {
- unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
- }
- }
- use POSIX qw(strftime);
- use BibTeX::Parser::Author;
- use LaTeX::ToUnicode qw (convert);
- use File::Basename;
- use File::Spec;
- my $USAGE="USAGE: $0 [-c config] [-o output] file1 file2 ...\n";
-my $VERSION = <<END;
-ltx2crossrefxml v2.2
-This is free software. You may redistribute copies of it under the
-terms of the GNU General Public License
-http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the
-extent permitted by law.
-$USAGE
-END
- use Getopt::Std;
- my %opts;
- getopts('c:o:hV',\%opts) or die $USAGE;
- use utf8;
- binmode(STDOUT, ":utf8");
-
-if ($opts{h} || $opts{V}){
- print $VERSION;
- exit 0;
-}
-
- ################################################################
- # Defaults and parameters
- ################################################################
-
- *OUT=*STDOUT;
-
- if (defined($opts{o})) {
- open (OUT, ">$opts{o}") or die "Cannot open file $opts{o} for writing\n";
- binmode(OUT, ":utf8")
- }
-
-
- our $depositorName='DEPOSITOR_NAME';
- our $depositorEmail='DEPOSITOR_EMAIL';
- our $registrant='REGISTRANT';
- our $fullTitle = "FULL TITLE";
- our $abbrevTitle = "ABBR. Title.";
- our $issn = "1234-5678";
- our $coden = "CODEN";
- our $batchId="ltx2crossref$$";
- our $timestamp=strftime("%Y%m%d%H%M%S", gmtime);
-
-
- if ($opts{c}) {
- if (-r $opts{c}) {
- require $opts{c};
- } else {
- die "Cannot read options $opts{c}. $USAGE";
- }
- }
-
-
-
- PrintHead();
-
- #
- # The hash %papers. Keys year->vol->issue->number
- #
- my %papers;
-
- foreach my $file (@ARGV) {
- AddPaper($file);
- }
-
- foreach my $year (keys %papers) {
- foreach my $volume (keys %{$papers{$year}}) {
- foreach my $issue (keys %{$papers{$year}->{$volume}}) {
- PrintIssueHead($year, $volume, $issue);
- my $paperList = $papers{$year}->{$volume}->{$issue};
- foreach my $paper (@{$paperList}) {
- PrintPaper($paper);
- }
- }
- }
-
- }
-
- PrintTail();
-
- exit(0);
-
-
-#####################################################
-# Printing the head and the tail
-#####################################################
-
-sub PrintHead {
-
-
- print OUT <<END;
-<doi_batch xmlns="http://www.crossref.org/schema/4.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="4.3.0" xsi:schemaLocation="http://www.crossref.org/schema/4.3.0 http://www.crossref.org/schema/deposit/crossref4.3.0.xsd">
- <head>
- <doi_batch_id>$batchId</doi_batch_id>
- <timestamp>$timestamp</timestamp>
- <depositor>
- <name>$depositorName</name>
- <email_address>$depositorEmail</email_address>
- </depositor>
- <registrant>$registrant</registrant>
- </head>
- <body>
- <journal>
- <journal_metadata language="en">
- <full_title>$fullTitle</full_title>
- <abbrev_title>$abbrevTitle</abbrev_title>
- <issn>$issn</issn>
- <coden>$coden</coden>
- </journal_metadata>
-END
-
-}
-
-sub PrintTail {
- print OUT <<END;
- </journal>
- </body>
-</doi_batch>
-END
-
-return;
-}
-
-
-#######################################################
-# Adding one paper
-#######################################################
-
-sub AddPaper {
- my $file = shift;
- my ($name,$path,$suffix) = fileparse($file, '\.[^\.]*$');
- my $rpifile = File::Spec->catfile($path, "$name.rpi");
- open (RPI, $rpifile) or die
- "Cannot find $rpifile. Did you process $file?\n";
- my %data;
- while (<RPI>) {
- chomp;
- if (/^%([^=]*)\s*=\s*(.*)\s*$/) {
- $data{$1}=$2;
- }
- }
- close RPI;
- my @bibliography;
- foreach my $bibfile ($file, File::Spec->catfile($path, "$name.bbl")) {
- @bibliography = (@bibliography,
- AddBibliography($bibfile));
- }
- $data{'bibliography'}=\@bibliography;
- push @{$papers{$data{year}}->{$data{volume}}->{$data{issue}}}, \%data;
-}
-
-##############################################################
-# Reading a list of papers and adding it to the
-# bibliography
-##############################################################
-
-sub AddBibliography {
- my $bibfile = shift;
- open (BIB, $bibfile) or return;
- my $insidebibliography = 0;
- my $currpaper="";
- my @result;
- my $key;
- while (<BIB>) {
- chomp;
- if (/^\s*\\bibitem(?:\[.*\])?+\{(.+)\}/) {
- if ($insidebibliography) {
- if ($currpaper) {
- my %paperhash;
- $paperhash{$key}=$currpaper;
- push @result, \%paperhash;
- }
- }
- $key = $1;
- $currpaper="";
- $insidebibliography=1;
- next;
- }
- if (/^\s*\\end\{thebibliography\}/) {
- if ($currpaper) {
- my %paperhash;
- $paperhash{$key}=$currpaper;
- push @result, \%paperhash;
- }
- $currpaper="";
- $insidebibliography=0;
- next;
- }
- if ($insidebibliography) {
- $currpaper .= " $_";
- }
- }
- close BIB;
- return @result;
-}
-
-#################################################################
-# Printing information about one issue
-#################################################################
-
-sub PrintIssueHead {
- my ($year, $volume, $issue) = @_;
- print OUT <<END;
- <journal_issue>
- <publication_date media_type="print">
- <year>$year</year>
- </publication_date>
- <journal_volume>
- <volume>$volume</volume>
- </journal_volume>
- <issue>$issue</issue>
- </journal_issue>
-END
-}
-
-###############################################################
-# Printing information about one paper
-###############################################################
-sub PrintPaper {
- my $paper = shift;
- my $title=convert($paper->{title});
- my $url=GetURL($paper);
- print OUT <<END;
- <journal_article publication_type="full_text">
- <titles>
- <title>
- $title
- </title>
- </titles>
- <contributors>
-END
-my @authors = split /\s*\\and\s*/, $paper->{authors};
- my $seq='first';
- foreach my $author (@authors) {
- print OUT <<END;
- <person_name sequence="$seq" contributor_role="author">
-END
-$seq='additional';
- PrintAuthor($author);
- print OUT <<END;
- </person_name>
-END
-
- }
-
- print OUT <<END;
- </contributors>
- <publication_date media_type="print">
- <year>$paper->{year}</year>
- </publication_date>
- <pages>
- <first_page>$paper->{startpage}</first_page>
- <last_page>$paper->{endpage}</last_page>
- </pages>
- <doi_data>
- <doi>$paper->{doi}</doi>
- <timestamp>$timestamp</timestamp>
- <resource>$url</resource>
- </doi_data>
-END
-
-if (scalar(@{$paper->{bibliography}})) {
- print OUT <<END;
- <citation_list>
-END
- foreach my $citation (@{$paper->{bibliography}}) {
- PrintCitation($citation);
- }
- print OUT <<END;
- </citation_list>
-END
-}
-
- print OUT <<END;
- </journal_article>
-END
-
-
-}
-
-
-###############################################################
-# Sanitization of a text string
-###############################################################
-sub SanitizeText {
- my $string = shift;
- $string = convert($string);
- $string =~ s/\\newblock//g;
- $string =~ s/\\bgroup//g;
- $string =~ s/\\egroup//g;
- $string =~ s/\\scshape//g;
- $string =~ s/\\urlprefix//g;
- $string =~ s/\\emph//g;
- $string =~ s/\\textbf//g;
- $string =~ s/\\enquote//g;
- $string =~ s/\\url/URL: /g;
- $string =~ s/\\doi/DOI: /g;
- $string =~ s/\\\\/ /g;
- $string =~ s/\$//g;
- $string =~ s/\\checkcomma/,/g;
- $string =~ s/~/ /g;
- $string =~ s/[\{\}]//g;
- return $string;
-}
-
-################################################################
-# Printing one author
-################################################################
-sub PrintAuthor {
- my $author=shift;
-
- my $person=new BibTeX::Parser::Author ($author);
-
- if ($person->first) {
- my $line = $person->first;
- $line = SanitizeText($line);
- print OUT <<END;
- <given_name>$line</given_name>
-END
-
- }
-
- if ($person->last) {
- my $line = SanitizeText($person->last);
- if ($person->von) {
- $line = SanitizeText($person->von)." $line";
- }
- print OUT <<END;
- <surname>$line</surname>
-END
-
- }
-
- if ($person->jr) {
- my $line = SanitizeText($person->jr);
- print OUT <<END;
- <suffix>$line</suffix>
-END
-
- }
-
-}
-
-#############################################################
-# Printing citations
-#############################################################
-sub PrintCitation {
- my $paperhash=shift;
- foreach my $key (keys (%{$paperhash})) {
- my $citation=$paperhash->{$key};
- $citation=SanitizeText($citation);
-
- print OUT <<END;
- <citation key="$key">
- <unstructured_citation>
- $citation
- </unstructured_citation>
- </citation>
-END
-}
-
-}
-
-##############################################################
-# Calculating URL
-##############################################################
-
-sub GetURL {
- my $paper = shift;
-
- my $result;
- if ($paper->{paperUrl}) {
- $result= $paper->{paperUrl}
- } else {
- my $doi=$paper->{doi};
- $result= 'http://www.pdcnet.org/oom/service?url_ver=Z39.88-2004&rft_val_fmt=&rft.imuse_synonym=resphilosophica&rft.DOI='.$doi.'&svc_id=info:www.pdcnet.org/collection';
- }
- $result =~ s/&/&#38;/g;
- return $result;
-}
diff --git a/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat b/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat
deleted file mode 100755
index 3041dc07ad3..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat
+++ /dev/null
@@ -1,21 +0,0 @@
-#/bin/sh
-##-----------------------------------------------------------------------------
-## This file is part of ctan-o-mat.
-## This program is distributed under BSD-like license. See file LICENSE
-##
-## (c) 2016-2017 Gerd Neugebauer
-##
-## Net: gene@gerd-neugebauer.de
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of a 3-clause BSD-like license as stated in the
-## file LICENSE contained in this distribution.
-##
-## You should have received a copy of the LICENSE along with this
-## program; if not, see the repository under http://***.
-##
-##-----------------------------------------------------------------------------
-
-exec perl "$0.pl" "$@"
-
-# \ No newline at end of file
diff --git a/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl b/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl
deleted file mode 100755
index c2f882e55f5..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl
+++ /dev/null
@@ -1,801 +0,0 @@
-#!/usr/bin/perl -w
-##-----------------------------------------------------------------------------
-## This file is part of ctan-o-mat.
-## This program is distributed under BSD-like license. See file LICENSE
-##
-## (c) 2016-2017 Gerd Neugebauer
-##
-## Net: gene@gerd-neugebauer.de
-##
-## This program is free software; you can redistribute it and/or modify it
-## under the terms of a 3-clause BSD-like license as stated in the file
-## LICENSE contained in this distribution.
-##
-## You should have received a copy of the LICENSE along with this program; if
-## not, see the repository under https://github.com/ge-ne/ctan-o-mat.
-##
-##-----------------------------------------------------------------------------
-
-=head1 NAME
-
-ctan-o-mat - Validate and upload a package for CTAN
-
-=head1 SYNOPSIS
-
-ctan-o-mat [options] [<package configuration>]
-
-=head1 DESCRIPTION
-
-This program can be used to automate the upload of a package to the
-Comprehensive TeX Archive Network (https://www.ctan.org). The description
-of the package is taken from a configuration file. Thus it can be updated
-easily without the need to fill a Web form with the same old information
-again and again.
-
-The provided information is validated in any case. If the validation
-succeeds and not only the validation is requested then the provided
-archive file is placed in the incoming area of the CTAN for further
-processing by the CTAN team.
-
-In any case any finding during the validation is reported at the end
-of the processing. Note that the validation is the default and a
-official submission has to be requested by the an appropriate command
-line option.
-
-B<ctan-o-mat> requires an Internet connection to the CTAN server. Even the
-validation retrieves the known attributes and the basic constraints
-from the server.
-
-
-=head1 CONFIGURATION
-
-The default configuration is read from a file with the same name as
-the current directory an the extension .pkg. This file name can be
-overwritten on the command line.
-
-The configuration depends on the features currently supported by the
-CTAN server.
-Since these features can change over time the configuration is not
-hard-coded in B<ctan-o-mat>. You can request an empty template of the
-configuration via the command line parameter C<--init>.
-
-
-=head1 OPTIONS
-
-=over 4
-
-=item -h
-
-=item --help
-
-Print this short summary about the usage and exit the program.
-
-=item -i
-
-=item --init
-
-Create an empty template for a configuration.
-
-=item --list licenses
-
-List the known licenses of CTAN to the standard output stream.
-Each license is represented as one line. The line contains the fields
-key, name, free indicator. Those fields are separated by tab characters.
-Afterwards the program terminates without processing any further arguments.
-
-=item --config <package configuration>
-
-=item --pkg <package configuration>
-
-=item --package <package configuration>
-
-Set the package configuration file.
-
-=item -s
-
-=item --submit
-
-Upload the submission, validate it and officially submit it to CTAN it the
-validation succeeds.
-
-=item -v
-
-=item --verbose
-
-Print some more information during the processing (verbose mode).
-
-=item --version
-
-Print the version number of this program and exit.
-
-=item --validate
-
-=item -n
-
-=item --noaction
-
-Do not perform the final upload. The package is validated and the
-resulting messages are printed.
-
-=item <package>
-
-This parameter is the name of a package configuration
-(see section CONFIGURATION) contained in a file.
-If not set otherwise the package configuration defaults to the
-name of the current directory with C<.pkg> appended.
-
-=back
-
-
-=head1 ENVIRONMENT
-
-The following environment variables are recognized by B<ctan-o-mat>.
-
-=over 4
-
-=item CTAN_O_MAT_URL
-
-The value is the URL prefix for the CTAN server to be contacted. The default
-is C<https://ctan.org/submit>. The complete URL is constructed by appending
-C<validate>, C<upload>, or C<fields> to use the respective CTAN REST API.
-
-=back
-
-
-=head1 CONNECTING VIA PROXIES
-
-If you need to connect to the Internet via a proxy then this can be achieved
-by setting some environment variables before running B<ctan-o-mat>.
-To redirect the request via the proxy simply define an environment variable
-C<http_proxy> to point to the proxy host -- including protocol and port as
-required. Note that the name of the environment variable is supposed to be in
-B<lower> case.
-
-
-=head1 AUTHOR
-
-Gerd Neugebauer (gene@gerd-neugebauer.de)
-
-=head1 BUGS
-
-=over 4
-
-=item *
-
-The program can not be used without a working connection to the
-Internet.
-
-=back
-
-=cut
-
-use strict;
-use FileHandle;
-use File::Basename;
-use Cwd;
-
-use constant VERSION => '1.2';
-
-#------------------------------------------------------------------------------
-# Function: usage
-# Arguments: none
-# Returns: nothing
-# Description: Print the POD to stderr and exit
-#
-sub usage {
- use Pod::Text;
- Pod::Text->new()
- ->parse_from_filehandle( new FileHandle( $0, 'r' ), \*STDERR );
- exit(0);
-}
-
-#------------------------------------------------------------------------------
-# Variable: $verbose
-# Description: The verbosity indicator.
-#
-my $verbose = 0;
-
-#------------------------------------------------------------------------------
-# Variable: $debug
-# Description: The debug indicator.
-#
-my $debug = 0;
-
-#------------------------------------------------------------------------------
-# Variable: $submit
-# Description: The validation or submit indicator.
-#
-my $submit = undef;
-
-#------------------------------------------------------------------------------
-# Variable: $cfg
-# Description: The name of the configuration file.
-#
-my $cfg = undef;
-
-#------------------------------------------------------------------------------
-# Variable: $CTAN_URL
-# Description: The base URL for requesting information from the CTAN server.
-#
-my $CTAN_URL = $ENV{'CTAN_O_MAT_URL'} || 'https://ctan.org';
-$CTAN_URL .= '/' if not $CTAN_URL =~ m/\/$/;
-
-use Getopt::Long;
-GetOptions(
- "config=s" => \$cfg,
- "debug" => \$debug,
- "h|help" => \&usage,
- "i|init:s" => sub {
- local $_ = pkg_name_or_fallback( $_[1], '' );
- ( new CTAN::Pkg() )->add( pkg => $_ )
- ->write( new CTAN::Upload::Fields() );
- exit(0);
- },
- "list=s" => sub {
- if ( $_[1] eq 'licenses' ) {
- new CTAN::Licenses()->print();
- }
- else {
- print STDERR "*** Unknown entity $_[1]\n";
- }
- exit(0);
- },
- "n|noaction" => sub { $submit = undef; },
- "pkg=s" => \$cfg,
- "package=s" => \$cfg,
- "submit|upload" => sub { $submit = 1; },
- "validate" => sub { $submit = undef; },
- "v|verbose" => \$verbose,
- "version" => sub {
- print STDOUT VERSION, "\n";
- exit(0);
- },
-);
-
-new CTAN::Pkg()
- ->read( pkg_name_or_fallback( $ARGV[0] || $cfg, '.pkg' ) )
- ->upload($submit);
-
-#------------------------------------------------------------------------------
-# Function: pkg_name_or_fallback
-# Arguments: $value the value
-# $ext the extension to append
-# Description: Construct a fallback from the current directory if $value is
-# not defined.
-#
-sub pkg_name_or_fallback {
- my ( $value, $ext ) = @_;
- if ( not defined $value or $value eq '' ) {
- $value = cwd();
- $value =~ s|.*[/\\]||;
- $value = $value . $ext;
- }
- return $value;
-}
-
-###############################################################################
-
-package JSON::Parser;
-
-#------------------------------------------------------------------------------
-# Constructor: new
-# Description: This is the constructor
-#
-sub new {
- my $proto = shift;
- my $class = ref($proto) || $proto;
- my $this = {};
-
- return bless $this, $class;
-}
-
-#------------------------------------------------------------------------------
-# Method: parse
-# Arguments:
-# $json the JSON list with the messages
-# Description: Parse the input string for a JSON object and retrun the Perl
-# representation of it.
-#
-sub parse {
- my ( $this, $json ) = @_;
-
- my ( $result, $remainder ) = $this->scan($json);
- chomp $remainder;
- if ( $remainder ne '' ) {
- die "*** Unprocessed JSON: $remainder\n";
- }
- return $result;
-}
-
-#------------------------------------------------------------------------------
-# Method: scan
-# Arguments:
-# $json the JSON list with the messages
-# Description: Scan the input string for the next token
-#
-sub scan {
- my ( $this, $json ) = @_;
- local $_ = $json;
-
- s/^\s+//;
- if ( m/^\[\s*/ ) {
- my @a = ();
- $_ = $';
- while ( not m/^\]/ ) {
- my ( $el, $remainder ) = $this->scan($_);
- push @a, $el;
- $_ = $remainder;
- s/^\s*,\s*//;
- }
- $_ = substr( $_, 1 );
- return ( \@a, $_ );
- }
- elsif ( m/^\{\s*/ ) {
- my %a = ();
- $_ = $';
- while ( not m/^\}/ ) {
- my ( $key, $remainder ) = $this->scan($_);
- $_ = $remainder;
- s/^\s*:\s*//;
- my ( $val, $remainder2 ) = $this->scan($_);
- $_ = $remainder2;
- $a{$key} = $val;
- s/^\s*,\s*//;
- }
- $_ = substr( $_, 1 );
- return ( \%a, $_ );
- }
- elsif ( $_ =~ m/^"/ ) {
- $_ = $';
- my $s = '';
- while ( m/(\\.|")/ ) {
- $s .= $`;
- $_ = $';
- if ( $& eq '"' ) {
- return ( $s, $_ );
- }
- if ( $& eq '\\n' ) {
- $s .= "\n";
- }
- elsif ( $& eq '\\"' ) {
- $s .= '"';
- }
- elsif ( $& eq '\\t' ) {
- $s .= "\t";
- }
- elsif ( $& eq '\\\\' ) {
- $s .= "\\";
- }
- elsif ( $& eq '\\r' ) {
- $s .= "\r";
- }
- elsif ( $& eq '\\b' ) {
- $s .= "\b";
- }
- else {
- $s .= "\\";
- }
- }
- die "*** Missing end of string\n";
- }
- elsif ( m/^([0-9]+|[a-z]+)/i ) {
- $_ = $';
- $_ = $&;
- return ( $_, $_ );
- }
-
- die "*** Parse error at: $_\n";
-}
-
-###############################################################################
-package CTAN::Upload::Fields;
-
-use LWP::UserAgent;
-use LWP::Protocol::https;
-use HTTP::Request::Common;
-
-#------------------------------------------------------------------------------
-# Variable: @parameter
-# Description: The list of fields.
-#
-my @parameter = (); # FIXME
-
-#------------------------------------------------------------------------------
-# Constructor: new
-# Description: This is the constructor
-#
-sub new {
- my $proto = shift;
- my $class = ref($proto) || $proto;
- my $this = {};
- bless $this, $class;
- return $this->_load();
-}
-
-#------------------------------------------------------------------------------
-# Method: _load
-# Arguments: none
-# Description: Retrieve a list of currently supported fields from the
-# CTAN server.
-#
-sub _load {
- my $this = shift;
- my $url = $CTAN_URL . 'submit/fields';
-
- print STDERR "--- Retrieving fields from CTAN..." if $::verbose;
- print STDERR $url, "\n" if $debug;
- my $response;
- eval {
- my $ua = LWP::UserAgent->new();
- my $request = GET $url;
- print STDERR "done\n" if $::verbose;
- $response = $ua->request($request);
- };
-
- die CTAN::ErrorHandler::format(
- $response->decoded_content, $response->status_line
- ),
- "\n"
- if not $response->is_success;
-
- local $_ = $response->decoded_content;
- print STDERR $response->decoded_content, "\n\n" if $debug;
- while (m/\"([a-z0-9]+)\":\{([^{}]*)\}/i) {
- my $f = $1;
- my %a = ();
- $_ = $';
- my $attr = $2;
- while ( $attr =~ m/\"([a-z0-9]+)\":([a-z0-9]+|"[^"]*")/i ) {
- $attr = $';
- $a{$1} = $2;
- $a{$1} =~ s/(^"|"$)//g;
- }
- $this->{$f} = \%a;
- push @CTAN::Upload::Fields::parameter, $f;
- }
- return $this;
-}
-
-###############################################################################
-package CTAN::Licenses;
-
-use LWP::UserAgent;
-use LWP::Protocol::https;
-use HTTP::Request::Common;
-
-use Data::Dumper;
-
-#------------------------------------------------------------------------------
-# Constructor: new
-# Description: This is the constructor
-#
-sub new {
- my $proto = shift;
- my $class = ref($proto) || $proto;
- my $this = [];
- bless $this, $class;
- return $this->_load();
-}
-
-#------------------------------------------------------------------------------
-# Method: _load
-# Arguments: none
-# Description: Retrieve a list of currently supported licenses from the
-# CTAN server.
-#
-sub _load {
- my $this = shift;
- my $url = $CTAN_URL . 'json/1.3/licenses';
-
- print STDERR "--- Retrieving licenses from CTAN..." if $verbose;
- print STDERR $url, "\t" if $debug;
- my $response;
- eval {
- my $ua = LWP::UserAgent->new();
- my $request = GET $url;
- print STDERR "done\n" if $verbose;
- $response = $ua->request($request);
- };
-
- die CTAN::ErrorHandler::format(
- $response->decoded_content, $response->status_line
- ),
- "\n"
- if not $@ and not $response->is_success;
-
- print STDERR "done\n" if $verbose;
- local $_ = $response->decoded_content;
-
- eval {
- $this->[0] = new JSON::Parser()->parse($_);
- };
- if ($@) {
- s/^[0-9]+ */*** /;
- die $_;
- }
-
- return $this;
-}
-
-#------------------------------------------------------------------------------
-# Method: print
-# Arguments: none
-# Description: Print the licenses to stdout.
-#
-sub print {
- my $this = shift;
- local $_ = $this->[0];
- my @a = @$_;
-
- foreach (@a) {
- print $_->{key}, "\t", $_->{name}, "\t";
- if ( $_->{free} eq 'true' ) {
- print "free\n";
- }
- else {
- print "non-free\n";
- }
- }
-}
-
-###############################################################################
-package CTAN::ErrorHandler;
-
-#------------------------------------------------------------------------------
-# Method: format
-# Arguments:
-# $json the JSON list with the messages
-# $fallback the fallback message if the first parameter is empty
-# Description: format the JSON error message
-#
-sub format {
- local $_ = shift;
- if ( $_ eq '' ) {
- return shift;
- }
- if (m/^(<!DOCTYPE html>|<html)/i) {
- return "Unexpected HTML response found under $CTAN_URL";
- }
-
- my $json;
- eval {
- $json = new JSON::Parser()->parse($_);
- };
- if ($@) {
- s/^[0-9]+ */*** /;
- die $_;
- }
- return join( "\n", map { join( ': ', @$_ ) } @$json );
-}
-
-###############################################################################
-package CTAN::Pkg;
-
-use LWP::UserAgent;
-use LWP::Protocol::https;
-use HTTP::Request::Common;
-
-#------------------------------------------------------------------------------
-# Constructor: new
-# Description: This is the constructor
-#
-sub new {
- my $proto = shift;
- my $class = ref($proto) || $proto;
- my $this = [];
- return bless $this, $class;
-}
-
-#------------------------------------------------------------------------------
-# Method: add
-# Arguments: arbitrary many key/value pairs
-# Description:
-# This function adds a key/value pair to the object.
-#
-sub add {
- my $this = shift;
- my ( $key, $val );
- $key = shift;
- $val = shift;
- while ( defined $key and defined $val ) {
- if ( $key eq 'file' ) {
- push @$this, $key => [$val];
- }
- else { push @$this, $key => $val; }
- $key = shift;
- $val = shift;
- }
- return $this;
-}
-
-#------------------------------------------------------------------------------
-# Method: read
-# Arguments: $file the file name to be read
-# Description:
-# This function parses a configuration file in (La)TeX form and returns
-# it as hash-like list.
-#
-sub read {
- my ( $this, $file ) = @_;
- die "*** Configuration file missing.\n" if not defined $file;
-
- my $fields = new CTAN::Upload::Fields();
- my $fd = new FileHandle($file)
- || die "*** Configuration file `$file' could not be read.\n";
- local $_;
-
- while (<$fd>) {
- s/^[ \t]*%.*//;
- s/([^\\])%.*/$1/;
- while (m/\\([a-z]+)/i) {
- $_ = $';
- my $keyword = $1;
- if ( $keyword eq 'begin' ) {
- die "$file:$.: missing {environment} instead of $_\n"
- if not m/^[ \t]*\{([a-z]*)\}/i;
- $keyword = $1;
- my $val = '';
- $_ = $';
- while ( not m/\\end\{$keyword\}/ ) {
- $val .= $_;
- $_ = <$fd>;
- die "$file:$.: "
- . "unexpected end of file while searching end of $keyword\n"
- if not defined $_;
- }
- m/\\end\{$keyword\}/;
- $_ = $';
- $val .= $`;
- $val =~ s/^[ \t\n\r]*//m;
- $val =~ s/[ \t\n\r]*$//m;
- $this->add( $keyword => $val );
- }
- elsif ( $keyword eq 'endinput' ) {
- last;
- }
- elsif ( defined $fields->{$keyword} ) {
- die "$file:$.: missing {environment} instead of $_\n"
- if not m/^[ \t]*\{([^{}]*)\}/i;
- $_ = $';
- $this->add( $keyword => $1 );
- }
- else {
- die "$file:$.: undefined keyword $keyword\n";
- }
- s/^[ \t]*%.*//;
- }
- }
- $fd->close();
- return $this;
-}
-
-#------------------------------------------------------------------------------
-# Method: upload
-# Arguments: Upload a file and the parameters
-# Description: Connect to the CTAN server to upload or validate the package.
-#
-sub upload {
- my $this = shift;
- my $submit = shift;
-
- my $service_url;
- if ($submit) {
- print STDERR "--- Sending to CTAN for submission..." if $verbose;
- $service_url = $CTAN_URL . 'submit/upload';
- }
- else {
- print STDERR "--- Uploading to CTAN for validation..." if $verbose;
- $service_url = $CTAN_URL . 'submit/validate';
- }
- my $ua = LWP::UserAgent->new();
- my $request = POST(
- $service_url,
- 'Content_Type' => 'multipart/form-data',
- 'Content' => $this
- );
- my $response = $ua->request($request);
- print STDERR "done\n" if $verbose;
-
- die CTAN::ErrorHandler::format( $response->decoded_content,
- $response->status_line )
- . "\n"
- if not $response->is_success;
-
- if ( not $submit and $response->decoded_content eq '[]' ) {
- print "ok\n";
- print STDERR "--- The validation has succeeded.\n",
- "--- You can now submit your package to CTAN for publication.\n"
- if $verbose;
- }
- else {
- print CTAN::ErrorHandler::format( $response->decoded_content, 'ok' ),
- "\n";
- }
- return $this;
-}
-
-#------------------------------------------------------------------------------
-# Method: write
-# Arguments: none
-# Description: Write a new configuration to stdout.
-#
-sub write {
- my $this = shift;
- my %this = @$this;
- my $fields = shift;
-
- print <<__EOF__;
-% This is a description file for ctan-o-mat.
-% It manages uploads of a package to
-% CTAN -- the Comprehensive TeX Archive Network.
-%
-% The syntax is roughly oriented towards (La)TeX.
-% Two form of the macros are used. The simple macros take one argument
-% in braces. Here the argument may not contain embedded macros.
-%
-% The second form uses an environment enclosed in \\begin{}/\\end{}.
-% In the long text fields logo macros can be used.
-%
-% You should enter your values between the begin and the end of the
-% named type.
-__EOF__
- local $_;
- foreach (@CTAN::Upload::Fields::parameter) {
- print <<__EOF__;
-% -------------------------------------------------------------------------
-% This field contains the $fields->{$_}->{'text'}.
-__EOF__
- if ( defined $fields->{$_}->{'nullable'} ) {
- print "% The value is optional.\n";
- }
- if ( defined $fields->{$_}->{'url'} ) {
- print "% The value is a URL.\n";
- }
- if ( defined $fields->{$_}->{'email'} ) {
- print "% The value is an email address.\n";
- }
- if ( defined $fields->{$_}->{'file'} ) {
- print
- "% The value is the file name of the archive to be uploaded.\n";
- print "% It may have a relative or absolute directory.\n";
- }
- if ( defined $fields->{$_}->{'maxsize'} ) {
- print "% The value is restricted to ", $fields->{$_}->{'maxsize'},
- " characters.\n";
- }
- if ( defined $fields->{$_}->{'list'} ) {
- print "% Multiple values are allowed.\n\\$_\{}\n";
- }
- elsif ( defined $fields->{$_}->{'maxsize'}
- and $fields->{$_}->{'maxsize'} ne 'null'
- and $fields->{$_}->{'maxsize'} < 256 )
- {
- my $v = $this{$_};
- $v = '' if not defined $v;
- print "\\$_\{$v\}\n";
- }
- elsif ( defined $fields->{$_}->{'file'}
- and $fields->{$_}->{'file'} eq 'true' )
- {
- my $v = $this{$_};
- $v = '' if not defined $v;
- print "\\$_\{$v\}\n";
- }
- else {
- my $v = $this{$_};
- if ( defined $v ) {
- $v = "\n " + $v + "\n";
- }
- else {
- $v = '';
- }
-
- print "\\begin{$_}$v\\end{$_}\n";
- }
- }
-}
-
-#------------------------------------------------------------------------------
-# Local Variables:
-# mode: perl
-# End:
diff --git a/Build/source/texk/texlive/linked_scripts/ctanbib/ctanbib b/Build/source/texk/texlive/linked_scripts/ctanbib/ctanbib
deleted file mode 100755
index 21adfd46792..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ctanbib/ctanbib
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/env texlua
-kpse.set_program_name("luatex")
--- ctanbib -- export ctan entries to bib format
--- Copyright: Michal Hoftich <michal.h21@gmail.com> (2014-2018)
---
--- This work may be distributed and/or modified under the
--- conditions of the LaTeX Project Public License, either version 1.3
--- of this license or (at your option) any later version.
--- The latest version of this license is in
--- http://www.latex-project.org/lppl.txt
--- and version 1.3 or later is part of all distributions of LaTeX
--- version 2005/12/01 or later.
---
--- This work has the LPPL maintenance status `maintained'.
---
--- The Current Maintainer of this work is Michal Hoftich
-
-local bibtype = "manual"
-if #arg < 1 or arg[1]=="--help" or arg[1]=="-h" then
- print([[ctanbib - convert ctan package information to bibtex format
-Usage:
-ctanbib [options] <package name>
-Available options:
- -c,--ctan Use @ctan type instead of @manual
- -h,--help Print this message
- -v,--version Print version info
- ]])
- os.exit(1)
-elseif arg[1]=="--version" or arg[1]=="-v" then
- print "ctanbib version 0.1d"
- os.exit(1)
-elseif arg[1]=="--ctan" or arg[1]=="-c" then
- table.remove(arg, 1)
- bibtype = "ctan"
-end
-
-local pkgname = arg[1]
-local url = "https://www.ctan.org/xml/2.0/pkg/" .. pkgname .. "?author-name=true"
-local authors_url = "https://ctan.org/xml/2.0/authors"
-
--- change that for different title scheme
-local titleformat = "The %s package"
-
-local bibtexformat = [[
-@manual{$package,
-title = {$title},
-subtitle = {$subtitle},
-author = {$author},
-url = {$url},
-urldate = {$urldate},
-date = {$date},
-version = {$version}
-}
-]]
-
-local dom = require('luaxml-domobject')
-
-
-local load_xml = function(url)
- -- local command = io.popen("wget -qO- ".. url,"r")
- local command = io.popen("curl -sS ".. url,"r")
-
- local info = command:read("*all")
- command:close()
-
- if string.len(info) == 0 then
- return false
- end
- return dom.parse(info)
-end
-
-local bibtex_escape = function(a)
- local a = a or ""
- return a:gsub("([%$%{%}%\\])", function(x)
- if x == "\\" then return "\\textbackslash " end
- return '\\'..x
- end)
-end
-
--- we need to use this method temporarily because of a bug in
--- CTAN API
-local author_list
-local fetch_author_list = function()
- if author_list then return author_list end
- local authors = load_xml(authors_url)
- author_list = {}
- for _, author in ipairs(authors:query_selector("author")) do
- -- save all authors under they ID
- local id = author:get_attribute("id")
- author_list[id] = author
- end
- return author_list
-end
-
-local process_author = function(author)
- local current = {}
- current[#current+1] = author:get_attribute("familyname")
- current[#current+1] = author:get_attribute("givenname")
- -- the author is an organization
- if #current == 1 then
- return "{" .. current[1] .. "}"
- elseif #current > 1 then
- return table.concat(current, ", ")
- end
- return nil -- no author
-end
-
--- get the author name and surname
-local get_author = function(author)
- local name = process_author(author)
- if name then return name end
- -- if the package XML doesn't contain author name,
- -- we need to fetch the authors list from CTAN and find
- -- it here
- local author_list = fetch_author_list()
- local id = author:get_attribute("id")
- -- try to find the author id in list of authors
- -- if everything fails, just return an empty group
- return process_author(author_list[id]) or "{}"
-end
-
-local get_authors = function(a)
- local retrieved_authors = {}
- for _, author in ipairs(a) do
- table.insert(retrieved_authors, get_author(author))
- end
- return table.concat(retrieved_authors," and ")
-end
-
-local get_title = function(record)
- local title = record:query_selector("name")[1]
- if title then
- title = title:get_text()
- title = title:gsub("^(.)", function(a) return unicode.utf8.upper(a) end)
- else
- title = pkgname
- end
- return string.format(titleformat, bibtex_escape(title))
-end
-
-
-local get_url = function(record)
- local home = record:query_selector("home")[1]
- if home then return home:get_attribute("href") end
- return "http://www.ctan.org/pkg/"..pkgname
-end
-
-local get_caption = function(record)
- local caption = record:query_selector("caption")[1]
- if caption then return bibtex_escape(caption:get_text()) end
- return nil
-end
-
-local get_version = function(record)
- local version = record:query_selector("version")[1]
- if version then
- return version:get_attribute("number"), version:get_attribute("date")
- end
-end
-
-local ctan_url = function(record)
- local ctan = record:query_selector("ctan")[1]
- -- some package don't contain the CTAN path
- if not ctan then return get_url(record) end
- local path = ctan:get_attribute("path")
- return path
-end
-
-
-local compile = function(template, records)
- return template:gsub("$([a-z]+)", function(a)
- return records[a] or ""
- end)
-end
-
-local record = load_xml(url)
-
-if not record then
- print("Cannot find entry for package "..pkgname)
- os.exit(1)
-end
-
--- root element is also saved, so we use this trick
--- local record = entry.entry
-
-local e = {}
-
-e.author = get_authors(record:query_selector("authorref"))
-e.package = pkgname
-e.title = get_title(record)
-e.subtitle = get_caption(record)
-e.url = get_url(record)
--- use the CTAN path as url for the CTAN type
-if bibtype == "ctan" then
- e.url = ctan_url(record)
-end
-e.version, e.date = get_version(record)
-e.urldate = os.date("%Y-%m-%d")
-
-local result = compile(bibtexformat, e)
--- update the bibliography type
-result = result:gsub("^@manual", "@" .. bibtype)
-
-print(result)
diff --git a/Build/source/texk/texlive/linked_scripts/ctanify/ctanify b/Build/source/texk/texlive/linked_scripts/ctanify/ctanify
deleted file mode 100755
index e168ed6ede8..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ctanify/ctanify
+++ /dev/null
@@ -1,716 +0,0 @@
-#! /usr/bin/env perl
-
-################################################
-# Prepare a LaTeX package for upload to CTAN #
-# By Scott Pakin <scott+ctify@pakin.org> #
-################################################
-
-use Cwd;
-use File::Basename;
-use File::Copy::Recursive qw(fcopy);
-use File::Find;
-use File::Path;
-use File::Spec;
-use File::stat;
-use File::Temp qw(tempdir);
-use Getopt::Long;
-use Pod::Usage;
-use warnings;
-use strict;
-
-# Define some global variables.
-our $VERSION = "1.9.1"; # ctanify version number
-my $progname = basename $0; # Name of this program
-my $pkgname; # Base name of the package to create
-my $miscify = 0; # 1=replace singletons with misc; 0=don't
-my $autoinclude = 1; # 1=automatically include files named in .ins
-my $skipdroppings = 1; # 1=skip "dropping" files (e.g., "README~")
-my $unixify = 1; # 1=make text files use Unix line endings
-my $maketds = 1; # 1=embed a .tds.zip file; 0=don't
-my @manifest; # List of files to include
-my %file2tds; # Map from specific filenames to TDS directories
-my @tdsdirlist; # Contents of the TDS tree
-my @pkgdirlist; # Contents of the package tree
-my @tdsonly; # Files to include only in the TDS tree
-my $tdsdir = ""; # Absolute directory of the TDS tree
-my $pkgdir = ""; # Absolute directory of the package directory
-my $zipname; # Name of the TDS zip file
-my $tarname; # Name of the package tar file
-my $tdsoutdir; # Directory name where to output TDS tree
-my $texmacros = "latex"; # TeX macro package
-
-# Associate file extensions with TDS directories. "%s" is replaced
-# with the package name.
-my %ext2tds =
- ("README" => "doc/latex/%s",
- "afm" => "fonts/afm/public/%s",
- "bat" => "scripts/%s",
- "bbx" => "tex/latex/%s",
- "bib" => "bibtex/bib/%s",
- "bst" => "bibtex/bst/%s",
- "cbx" => "tex/latex/%s",
- "cls" => "tex/latex/%s",
- "dbx" => "tex/latex/%s",
- "dtx" => "source/latex/%s",
- "dvi" => "doc/latex/%s",
- "fd" => "tex/latex/%s",
- "ins" => "source/latex/%s",
- "map" => "fonts/map/dvips/%s",
- "md" => "doc/latex/%s",
- "mf" => "fonts/source/public/%s",
- "mp" => "metapost/%s",
- "ofm" => "fonts/ofm/public/%s",
- "ovf" => "fonts/ovf/public/%s",
- "ovp" => "fonts/ovp/public/%s",
- "pdf" => "doc/latex/%s",
- "pfb" => "fonts/type1/public/%s",
- "pfm" => "fonts/type1/public/%s",
- "ps" => "doc/latex/%s",
- "py" => "scripts/%s",
- "sh" => "scripts/%s",
- "sty" => "tex/latex/%s",
- "tfm" => "fonts/tfm/public/%s",
- "txt" => "doc/latex/%s",
- "vf" => "fonts/vf/public/%s");
-
-# Specify a list of filename regexps to ignore.
-my @ignore_re = ('~$', '\bCVS\b', '\b\.svn\b');
-
-# Specify a list of file extensions that are considered "text" files.
-# This script will convert their line endings to Unix style (a single
-# linefeed character).
-my %text_ext =
- map {($_ => 1)} qw(afm bib bst cls dtx fd ins ltx md mf mp sty tex txt);
-
-# Define a subroutine that returns the size in bytes of a file,
-# aborting on error.
-sub filesize ($)
-{
- my $finfo = lstat($_[0]) || die "${progname}: Failed to stat $_ ($!)\n";
- return $finfo->size;
-}
-
-# Define a subroutine that runs a command and aborts on error.
-sub run_command ($;$)
-{
- my $command = $_[0];
- my $ignore_errors = defined $_[1] ? $_[1] : 0;
- my $retval = system $command;
- if (!$ignore_errors && $retval>>8) {
- die "${progname}: Command \"$command\" failed\n";
- }
-}
-
-# Define a subroutine that Unix-ifies the line endings in text files.
-# This subroutine is called from File::Find so it does not accept
-# arguments via the @_ variable.
-my %reported_line_endings; # Files we converted and told the user about
-sub use_unix_line_endings
-{
- # Determine if the file is a text file.
- my $fname = $_;
- return if !-f $fname;
- my $fext = ($fname =~ m|([^./]+)$| && $1);
- return if !defined $text_ext{$fext};
-
- # Make it use Unix line endings. Note that we don't bother
- # checking if we're already on a Unix (or Unix-like) system.
- my $oldsize = filesize $fname;
- open(TEXTFILE, "<$fname") || die "${progname}: Failed to open $File::Find::name ($!)\n";
- my @entirefile = map {s/[\n\r]+$/\n/; $_} <TEXTFILE>;
- close TEXTFILE;
- open(BINARYFILE, ">$fname") || die "${progname}: Failed to open $File::Find::name ($!)\n";
- binmode BINARYFILE;
- print BINARYFILE @entirefile;
- close BINARYFILE;
- my $newsize = filesize $fname;
- if ($newsize != $oldsize && !defined $reported_line_endings{$fname}) {
- # Don't frighten the user when he sees a different file size
- # in the tar file from the original in the filesystem
- my $fullname = $File::Find::name;
- $fullname =~ s,^$tdsdir/,,;
- $fullname =~ s,^$pkgdir/,,;
- warn "${progname}: Modified $fullname to use Unix line endings (use --no-unixify to prevent this)\n";
- $reported_line_endings{$fname} = 1;
- }
-}
-
-###########################################################################
-
-# Parse the command line.
-my $wanthelp = 0;
-my $wantversion = 0;
-GetOptions("p|pkgname=s" => \$pkgname,
- "m|misc!" => \$miscify,
- "k|skip!" => \$skipdroppings,
- "u|unixify!" => \$unixify,
- "t|tdsonly=s" => \@tdsonly,
- "a|auto!" => \$autoinclude,
- "d|tdsdir=s" => \$tdsoutdir,
- "T|tex=s" => \$texmacros,
- "s|tds!" => \$maketds,
- "V|version" => \$wantversion,
- "h|help" => \$wanthelp)
- || pod2usage(-verbose => 0,
- -exitval => 1);
-pod2usage(-verbose => 1,
- -exitval => 0) if $wanthelp;
-if ($wantversion) {
- print "ctanify version $VERSION\n";
- exit 0;
-}
-pod2usage(-verbose => 0,
- -exitval => 1) if !@ARGV;
-foreach my $fname (@ARGV) {
- # Let the user specify "<filename>=<dirname>" to place files
- # explicitly in the TDS tree.
- if ($fname =~ /^(.*)=([^=]+)$/) {
- foreach my $exp_fname (glob $1) {
- $file2tds{$exp_fname} = $2;
- push @manifest, $exp_fname;
- }
- }
- else {
- push @manifest, glob $fname;
- }
-}
-@tdsonly = map {File::Spec->abs2rel($_)} map {glob} @tdsonly;
-
-# Replace "latex" with something else if --tex was specified.
-if ($texmacros ne "latex") {
- foreach my $ext (keys %ext2tds) {
- $ext2tds{$ext} =~ s,\blatex\b,$texmacros,g;
- }
-}
-
-# Determine the package name if not explicitly specified.
-if (!defined $pkgname) {
- my @mainfiles = (grep(/\.ins$/, @manifest), grep(/\.sty$/, @manifest));
- if (!@mainfiles) {
- die "${progname}: Please either list a .ins or .sty file or specify --pkgname\n";
- }
- $pkgname = basename $mainfiles[0];
- $pkgname =~ s/\.[^.]+$//;
-}
-
-# Parse each .ins file to find more files to include.
-if ($autoinclude) {
- foreach my $fname (grep /\.ins$/, @manifest) {
- # Read the entire file.
- local $/ = undef;
- open(INSFILE, "<$fname") || die "${progname}: Failed to open $fname ($!)\n";
- my $insfile = <INSFILE>;
- close INSFILE;
- $insfile =~ s/\%.*?\n//g;
-
- # Add all source files (\from) to the manifest.
- while ($insfile =~ /\\from\{([^\}]+)\}/g) {
- my $fname_exp = $1;
- $fname_exp =~ s/\\jobname\b/$pkgname/g;
- push @manifest, $fname_exp;
- }
-
- # Add all generated files (\file) to the manifest but also to
- # the list of TDS-only inclusions.
- while ($insfile =~ /\\file\{([^\}]+)\}/g) {
- my $fname_exp = $1;
- $fname_exp =~ s/\\jobname\b/$pkgname/g;
- push @manifest, $fname_exp;
- push @tdsonly, $fname_exp;
- }
- }
-}
-
-# Skip "dropping" files and files beginning with ".".
-if ($skipdroppings) {
- my @newmanifest;
- CHECK_DROPPING:
- foreach my $fname (@manifest) {
- if (substr($fname, 0, 1) eq ".") {
- warn "${progname}: Excluding $fname (use --no-skip to force inclusion)\n";
- next CHECK_DROPPING;
- }
- foreach my $dropping_re (@ignore_re) {
- if ($fname =~ $dropping_re) {
- warn "${progname}: Excluding $fname (use --no-skip to force inclusion)\n";
- next CHECK_DROPPING;
- }
- }
- push @newmanifest, $fname;
- }
- @manifest = @newmanifest;
-}
-
-# Map each file to a TDS directory.
-foreach my $fname (@manifest) {
- next if defined $file2tds{$fname};
- my $fext = ($fname =~ m|([^./]+)$| && $1);
- if ($fname =~ /\.tex$/ && $pkgname eq basename $fname, ".tex") {
- # <package>.tex -- treat as documentation.
- $file2tds{$fname} = sprintf $ext2tds{"README"}, $pkgname;
- }
- elsif (defined $ext2tds{$fext}) {
- # Most files -- determine the directory based on the file extension.
- $file2tds{$fname} = sprintf $ext2tds{$fext}, $pkgname;
- }
- elsif ($fext =~ /^(\d+)[a-z]*$/i) {
- # Man page (e.g., "ls.1" or "File::Temp.3pm").
- $file2tds{$fname} = "doc/man/man$1";
- }
- else {
- # Read the file to determine if it's a Unix script (starts with "#!").
- open(SCRIPT, "<", $fname) || die "${progname}: Failed to open $fname ($!)\n";
- my $shebang;
- read(SCRIPT, $shebang, 2);
- close SCRIPT;
- if ($shebang eq "#!") {
- $file2tds{$fname} = "scripts/$pkgname";
- }
- else {
- warn "${progname}: Not including $fname in the TDS tree (unknown extension)\n";
- }
- }
-}
-
-# Create a working directory and populate it with TDS files.
-my $workdir = tempdir("$progname-XXXXXX", TMPDIR => 1, CLEANUP => 1);
-$tdsdir = $tdsoutdir ? $tdsoutdir : "$workdir/texmf";
-mkdir $tdsdir || die "${progname}: Failed to create $tdsdir ($!)\n";
-foreach my $fname (@manifest) {
- # Create a TDS subdirectory.
- my $subdir = $file2tds{$fname};
- next if !defined $subdir;
- mkpath "$tdsdir/$subdir";
-
- # Copy the specified file into the subdirectory.
- fcopy($fname, "$tdsdir/$subdir/" . basename $fname) || die "${progname}: Failed to copy $fname ($!)\n";
-}
-if ($miscify) {
- # Replace package directories containing a single file with "misc".
- my %renamings;
- find(sub {
- return if $File::Find::name =~ m|\btexmf/fonts\b|;
- if (-d) {
- my @children = glob "$_/*";
- if ($#children == 0 && -f $children[0] && $_ eq $pkgname) {
- $renamings{$File::Find::name} = $File::Find::dir . "/misc";
- }
- }
- }, $tdsdir);
- while (my ($oldname, $newname) = each %renamings) {
- rename $oldname, $newname;
- }
-}
-if ($unixify) {
- # Make all text files use Unix line endings.
- find(\&use_unix_line_endings, $tdsdir);
-}
-
-# Complain if the doc directory contains PostScript or DVI files.
-my @bad_docs;
-find(sub {
- return if !-f;
- push @bad_docs, $_ if $File::Find::name =~ m,\bdoc/[^/]+/$pkgname/.*\.(ps|dvi)$,;
-}, $tdsdir);
-if (@bad_docs) {
- my $bad_docs = join ", ", @bad_docs;
- warn "${progname}: CTAN prefers having only PDF documentation (re: $bad_docs)\n";
-}
-
-# We have no more work to do if we're simply creating a TDS directory.
-exit 0 if $tdsoutdir;
-
-# Store a listing of the TDS directory.
-my $prevdir = getcwd();
-chdir $tdsdir || die "${progname}: Failed to switch to $tdsdir ($!)\n";
-find(sub {
- return if !-f;
- my $fsize = filesize $_;
- push @tdsdirlist, [substr($File::Find::name, 2), $fsize];
-}, ".");
-
-# Archive and remove the TDS directory.
-$zipname = "$pkgname.tds.zip";
-my $zip_exclusions = $skipdroppings ? "-x __MACOSX -x .DS_Store" : "";
-run_command "zip -q -r -9 -y -m $workdir/$zipname . $zip_exclusions", 1;
-my $zipsize;
-if (-f "$workdir/$zipname") {
- $zipsize = filesize "$workdir/$zipname";
-}
-else {
- $zipname = "";
-}
-$zipname = "" if !$maketds;
-chdir $prevdir || die "${progname}: Failed to switch to $prevdir ($!)\n";
-rmdir $tdsdir || die "${progname}: Failed to remove $tdsdir ($!)\n";
-
-# Copy all files named in the file manifest to the package directory.
-$pkgdir = "$workdir/$pkgname";
-mkdir $pkgdir || die "${progname}: Failed to create $pkgdir ($!)\n";
-my %tdsonly = map {($_ => 1)} @tdsonly;
-foreach my $fname (@manifest) {
- my $relname = File::Spec->abs2rel($fname);
- next if defined $tdsonly{$relname};
- my ($namepart, $pathpart, $suffixpart) = fileparse($relname);
- mkpath "$pkgdir/$pathpart";
- my $targetfile = "$pkgdir/$pathpart/$namepart$suffixpart";
- fcopy($fname, $targetfile) || die "${progname}: Failed to copy $fname ($!)\n";
-}
-if ($unixify) {
- # Make all text files use Unix line endings.
- find(\&use_unix_line_endings, $pkgdir);
-}
-
-# Store a listing of the package directory.
-$prevdir = getcwd();
-chdir $pkgdir || die "${progname}: Failed to switch to $pkgdir ($!)\n";
-find(sub {
- return if !-f;
- my $fsize = filesize $_;
- push @pkgdirlist, [substr($File::Find::name, 2), $fsize];
-}, ".");
-chdir $prevdir || die "${progname}: Failed to switch to $prevdir ($!)\n";
-
-# Tar up the package directory.
-$tarname = "$pkgname.tar.gz";
-my $tar_exclusions = $skipdroppings ? "--exclude=__MACOSX --exclude=.DS_Store" : "";
-run_command "tar -czf $tarname -C $workdir $tar_exclusions $pkgname $zipname";
-
-# Output a listing of what we tarred up.
-printf "\n%8d %s\n\n", filesize($tarname), $tarname;
-foreach my $fname_size (sort {$a->[0] cmp $b->[0]} @pkgdirlist) {
- my ($fname, $fsize) = @$fname_size;
- printf " %8d %s/%s\n", $fsize, $pkgname, $fname;
-}
-if ($zipname ne "") {
- printf " %8d %s\n\n", $zipsize, $zipname;
- foreach my $fname_size (sort {$a->[0] cmp $b->[0]} @tdsdirlist) {
- my ($fname, $fsize) = @$fname_size;
- printf " %8d %s\n", $fsize, $fname;
- }
-}
-print "\n";
-
-###########################################################################
-
-__END__
-
-=head1 NAME
-
-ctanify - Prepare a package for upload to CTAN
-
-
-=head1 SYNOPSIS
-
-ctanify
-[B<--pkgname>=I<string>]
-[B<-->[B<no>]B<auto>]
-[B<--tdsonly>=I<filespec> ...]
-[B<-->[B<no>]B<unixify>]
-[B<-->[B<no>]B<skip>]
-[B<--tdsdir>=I<dirname> ...]
-[B<--tex>=I<macro_pkg>]
-[B<-->[B<no>]B<miscify>]
-[B<-->[B<no>]B<tds>]
-I<filespec>[=I<dirname>] ...
-
-ctanify
-[B<--help>]
-
-ctanify
-[B<--version>]
-
-
-=head1 DESCRIPTION
-
-B<ctanify> is intended for developers who have a LaTeX package that
-they want to distribute via the Comprehensive TeX Archive Network
-(CTAN). Given a list of filenames, B<ctanify> creates a tarball (a
-F<.tar.gz> file) with the files laid out in CTAN's preferred
-structure. The tarball additionally contains a ZIP (F<.zip>) file
-with copies of all files laid out in the standard TeX Directory
-Structure (TDS), which facilitates inclusion of the package in the TeX
-Live distribution.
-
-
-=head1 OPTIONS
-
-B<ctanify> accepts the following command-line options:
-
-=over 5
-
-=item B<-h>, B<--help>
-
-Output basic usage information and exit.
-
-=item B<-V>, B<--version>
-
-Output B<ctanify>'s version number and exit.
-
-=item B<-p> I<string>, B<--pkgname>=I<string>
-
-Specify explicitly a package name. Normally, B<ctanify> uses the base
-name of the first F<.ins> or F<.sty> file listed as the package name.
-The package name forms the base name of the tarball that B<ctanify>
-produces.
-
-=item B<--noauto>
-
-Do not automatically add files to the tarball. Normally, B<ctanify>
-automatically includes all files mentioned in a F<.ins> file.
-
-=item B<-t> I<filespec>, B<--tdsonly>=I<filespec>
-
-Specify a subset of the files named on the command line to include
-only in the TDS ZIP file, not in the CTAN package directory.
-Wildcards are allowed (quoted if necessary), and B<--tdsonly> can be
-used multiple times on the same command line.
-
-=back
-
-At least one filename must be specified on the command line.
-B<ctanify> automatically places files in the TDS tree based on their
-extension, but this can be overridden by specifying explicitly a
-target TDS directory using the form I<filespec>=I<dirname>. Wildcards
-are allowed for the filespec (quoted if necessary).
-
-
-=head1 ADDITIONAL OPTIONS
-
-The following options are unlikely to be necessary in ordinary usage.
-They are provided for special circumstances that may arise.
-
-=over 5
-
-=item B<-d> I<dirname>, B<--tdsdir>=I<dirname>
-
-Instead of creating a tarball for CTAN, merely create the package TDS
-tree rooted in directory I<dirname>.
-
-=item B<-T> I<macro_pkg>, B<--tex>=I<macro_pkg>
-
-Assert that the files being packaged for CTAN target a TeX macro
-package other than LaTeX. Some common examples of I<macro_pkg> are
-C<generic>, C<plain>, and C<context>.
-
-=item B<-nou>, B<--no-unixify>
-
-Store text files unmodified instead of converting their end-of-line
-character to Unix format (a single linefeed character with no
-carriage-return character), even though CTAN prefers receiving all
-files with Unix-format end-of-line characters.
-
-=item B<-nok>, B<--no-skip>
-
-Force B<ctanify> to include files such as Unix hidden files, Emacs
-backup files, and version-control metadata files, all of which CTAN
-dislikes receiving.
-
-=item B<-m>, B<--miscify>
-
-Rename directories containing a single file to C<misc>. (For example,
-rename C<tex/latex/mypackage/mypackage.sty> to
-C<tex/latex/misc/mypackage.sty>.) This was common practice in the
-past but is now strongly discouraged.
-
-=item B<-nos>, B<--no-tds>
-
-Do not embed a .tds.zip file in the generated tarball.
-
-=back
-
-
-=head1 DIAGNOSTICS
-
-=over 5
-
-=item C<Failed to copy I<filename> (No such file or directory)>
-
-This message is typically caused by a F<.ins> file that generates
-I<filename> but that has not already been run through F<tex> or
-F<latex> to actually produce I<filename>. B<ctanify> does not
-automatically run F<tex> or F<latex>; this needs to be done manually
-by the user. See L</CAVEATS> for more information.
-
-=item C<Modified I<filename> to use Unix line endings (use --no-unixify to prevent this)>
-
-For consistency, CTAN stores all text files with Unix-style line
-endings (a single linefeed character with no carriage-return
-character). To help in this effort, B<ctanify> automatically replaces
-non-Unix-style line endings. The preceding merely message notifies
-the user that he should not be alarmed to see a different size for
-I<filename> in the tarball versus the original I<filename> on disk
-(which B<ctanify> never modifies). If there's a good reason to
-preserve the original line endings (and there rarely is), the
-B<--no-unixify> option can be used to prevent B<ctanify> from altering
-any files when storing them in the tarball.
-
-=item C<Excluding I<filename> (use --no-skip to force inclusion)>
-
-B<ctanify> normally ignores files--even when specified explicitly on
-the command line--that CTAN prefers not receiving. These include
-files whose names start with "F<.>" (Unix hidden files), end in "F<~>"
-(Emacs automatic backups), or that come from a F<CVS> or F<.svn>
-directory (version-control metadata files). If there's a good reason
-to submit such files to CTAN (and there rarely is), the B<--no-skip>
-option can be used to prevent B<ctanify> from ignoring them.
-
-=item C<CTAN prefers having only PDF documentation (re: I<filename>)>
-
-Because of the popularity of the PDF format, CTAN wants to have as
-much documentation as possible distributed in PDF. The preceding
-message asks the user to replace any PostScript or DVI documentation
-with PDF if possible. (B<ctanify> will still include PostScript and
-DVI documentation in the tarball; the preceding message is merely a
-polite request.)
-
-=item C<Not including I<filename> in the TDS tree (unknown extension)>
-
-B<ctanify> places files in the TDS tree based on a table of file
-extensions. For example, all F<.sty> files are placed in
-F<tex/latex/I<package-name>>. If B<ctanify> does not know where to
-put a file it does not put it anywhere. See the last paragraph of
-L</OPTIONS> for an explanation of how to specify explicitly a file's
-target location in the TDS tree. For common file extensions that
-happen to be absent from B<ctanify>'s table, consider also notifying
-B<ctanify>'s author at the address shown below under L</AUTHOR>.
-
-=back
-
-
-=head1 EXAMPLES
-
-=head2 The Common Case
-
-Normally, all that's needed is to tell B<ctanify> the name of the
-F<.ins> file (or F<.sty> if the package does not use DocStrip) and the
-prebuilt documentation, if any:
-
- $ ctanify mypackage.ins mypackage.pdf README
-
- 490347 mypackage.tar.gz
-
- 1771 mypackage/README
- 15453 mypackage/mypackage.dtx
- 1957 mypackage/mypackage.ins
- 277683 mypackage/mypackage.pdf
- 246935 mypackage.tds.zip
-
- 1771 doc/latex/mypackage/README
- 277683 doc/latex/mypackage/mypackage.pdf
- 15453 source/latex/mypackage/mypackage.dtx
- 1957 source/latex/mypackage/mypackage.ins
- 1725 tex/latex/mypackage/mypackage.sty
-
-B<ctanify> outputs the size in bytes of the resulting tarball, each
-file within it, and each file within the contained ZIP file. In the
-preceding example, notice how B<ctanify> automatically performed all
-of the following operations:
-
-=over 5
-
-=item *
-
-including F<mypackage.dtx> (found by parsing F<mypackage.ins>) in both
-the F<mypackage> directory and the ZIP file,
-
-=item *
-
-including F<mypackage.sty> (found by parsing F<mypackage.ins>) in the
-ZIP file but, because it's a generated file, not in the F<mypackage>
-directory, and
-
-=item *
-
-placing all files into appropriate TDS directories (documentation,
-source, main package) within the ZIP file.
-
-=back
-
-Consider what it would take to manually produce an equivalent
-F<mypackage.tar.gz> file. B<ctanify> is definitely a simpler, quicker
-alternative.
-
-
-=head2 Advanced Usage
-
-B<ctanify> assumes that PostScript files are documentation and
-therefore stores them under F<doc/latex/I<package-name>/> in the TDS
-tree within the ZIP File. Suppose, however, that a LaTeX package uses
-a set of PostScript files to control B<dvips>'s output. In this case,
-B<ctanify> must be told to include those PostScript files in the
-package directory, not the documentation directory.
-
- $ ctanify mypackage.ins "mypackage*.ps=tex/latex/mypackage"
-
-
-=head1 FILES
-
-=over 5
-
-=item F<perl>
-
-B<ctanify> is written in Perl and needs a Perl installation to run.
-
-=item F<tar>, F<gzip>
-
-B<ctanify> requires the GNU F<tar> and F<gzip> programs to create a
-compressed tarball (F<.tar.gz>).
-
-=item F<zip>
-
-B<ctanify> uses a F<zip> program to archive the TDS tree within the
-main tarball.
-
-=back
-
-
-=head1 CAVEATS
-
-B<ctanify> does not invoke F<tex> or F<latex> on its own, S<e.g., to>
-process a F<.ins> file. The reason is that B<ctanify> does not know
-in the general case how to produce all of a package's generated files.
-It was deemed better to do nothing than to risk overwriting existing
-F<.sty> (or other) files or to include outdated generated files in the
-tarball. In short, before running B<ctanify> you should manually
-process any F<.ins> files and otherwise generate any files that should
-be sent to CTAN.
-
-B<ctanify> has been tested only on Linux. It may work on S<OS X>.
-I've been told that it works on Windows when run using Cygwin.
-Volunteers willing to help port B<ctanify> to other platforms are
-extremely welcome.
-
-
-=head1 SEE ALSO
-
-tar(1),
-zip(1),
-latex(1),
-Guidelines for uploading TDS-Packaged materials to CTAN
-(L<http://www.ctan.org/TDS-guidelines>),
-A Directory Structure for TeX Files (L<http://tug.org/tds/>),
-
-
-=head1 AUTHOR
-
-Scott Pakin, I<scott+ctify@pakin.org>
-
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2017 Scott Pakin
-
-This work may be distributed and/or modified under the conditions of
-the LaTeX Project Public License, either S<version 1.3c> of this
-license or (at your option) any later version. The latest version of
-this license is in
-
-=over 4
-
-L<http://www.latex-project.org/lppl.txt>
-
-=back
-
-and S<version 1.3c> or later is part of all distributions of LaTeX
-version 2008/05/04 or later.
diff --git a/Build/source/texk/texlive/linked_scripts/ctanupload/ctanupload.pl b/Build/source/texk/texlive/linked_scripts/ctanupload/ctanupload.pl
deleted file mode 100644
index 163b4906513..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ctanupload/ctanupload.pl
+++ /dev/null
@@ -1,554 +0,0 @@
-#!/usr/bin/perl
-################################################################################
-# Copyright (c) 2011-2012 Martin Scharrer <martin@scharrer-online.de>
-# This is open source software under the GPL v3 or later.
-################################################################################
-use strict;
-use warnings;
-
-sub fromenv;
-sub load_data;
-sub save_data;
-
-my $VERSION = 'v1.2c from 2012/05/08';
-my %CTAN_SERVERURLS = (
- dante => 'http://dante.ctan.org/upload.html',
- uktug => 'http://www.tex.ac.uk/upload/',
-);
-my %CTAN_SERVERALIASES = (
- de => 'dante',
- 'uk-tug' => 'uktug',
- uk => 'uktug',
- cambridge => 'uktug',
-);
-
-my $CTAN_URL;
-
-my @FIELDS = qw(contribution version name email summary directory DoNotAnnounce announce notes license freeversion file);
-my @REQUIRED = qw(contribution version name email summary license file);
-my %FIELDS = map { $_ => fromenv($_) } @FIELDS;
-
-
-my %FIELDS_DESC = (
- contribution => 'Name of your contribution',
- version => 'Version number',
- name => 'Your name',
- email => 'Your email',
- summary => 'Summary description',
- directory => 'Suggested CTAN directory',
- DoNotAnnounce => 'No need to announce this update',
- announce => 'Short description for announcement',
- notes => 'Optional notes to the CTAN maintainers (DANTE only)',
- license => 'License type',
- freeversion => 'Which free license',
- file => 'File to upload',
-);
-
-my @LICENSES = qw( free nocommercial nosell nosource shareware artistic other-nonfree);
-
-my %LICENSES = (
- free => 'Free',
- nocommercial => 'Nocommercial',
- nosell => 'Nosell',
- nosource => 'Nosource',
- shareware => 'Shareware',
- artistic => 'Perl Artistic (Clarified or later)',
- 'other-nonfree' => 'Other nonfree License',
-);
-
-my @FREEVERSIONS = qw( apache2 artistic fdl gfl gpl lgpl lppl ofl pd other-free);
-
-my %FREEVERSIONS = (
- apache2 => 'Apache License v2.0',
- artistic => 'Perl Artistic License (version 2)',
- fdl => 'GNU Free Documentation License',
- gfl => 'GUST Font License',
- gpl => 'GNU General Public License',
- lgpl => 'Lesser GPL',
- lppl => 'LaTeX Project',
- ofl => 'Open Font License',
- pd => 'Public Domain',
- 'other-free' => 'Other Free',
-);
-
-my $QUIET = 0;
-my $ASK = 1;
-my $FORCE = 0;
-my $PROMPT = -t STDIN ? 1 : 0;
-my $LOG = 0;
-
-my $LOGFILE = $ENV{CTANUPLOAD_LOGFILE};
-
-sub usage {
- my $warn = shift;
- if ($warn) {
- print STDERR "Unknown option '$warn'\n";
- }
- print STDERR <<"EOT";
-ctanupload script $VERSION
-Uploads a contribution to CTAN.
-
-Usage:
-ctanupload <options> --<name>=<value>
-
-Arguments can also be given using the CTANUPLOAD environment variable which are processed first, so that
-explicit arguments will overwrite them.
-
-Options:
- -p Prompt for missing values. (default if run in terminal)
- -P Do not prompt for missing values. (default if not run in terminal)
- -y Do not ask for confirmation, but submit immediately.
- -u <URL> CTAN URL to upload to (defaults to CTAN_URL environment variable or random if not set)
- -U <name> CTAN server to upload to, either 'dante' or 'uktug'.
- -F <file> Read data from file
- -f Force upload even if input seems incorrect (unknown license etc.).
- -v Verbose mode.
- -q Quiet mode.
- -l Write log file.
- -L Do not write log file. (default)
- -o <file> Define log file. (still requires -l)
- -h Print this help and exit.
- -V Print version number.
-
-The following fields exists and can be given as
---<name>=<value>, --<name> <value>, --<name>-file=<file>, --<name>-file <file>
-or as environment variables: CTAN_<NAME>, CTAN_<name>, <NAME> or <name>.
-
-EOT
-
- foreach my $field (@FIELDS) {
- printf STDERR " %15s %s\n", $field, $FIELDS_DESC{$field};
- }
-
- printf STDERR "\nValid license types:\n";
- for my $license (@LICENSES) {
- printf STDERR " %15s %s\n", $license, $LICENSES{$license};
- }
-
- printf STDERR "\nValid free license:\n";
- for my $license (@FREEVERSIONS) {
- printf STDERR " %15s %s\n", $license, $FREEVERSIONS{$license};
- }
-
- exit ($warn ? 1 : 0);
-}
-
-if (exists $ENV{CTAN_URL}) {
- unshift @ARGV, ('-u', $ENV{'CTAN_URL'});
-}
-elsif (exists $ENV{CTAN_SERVER}) {
- unshift @ARGV, ('-U', $ENV{'CTAN_SERVER'});
-}
-
-if (exists $ENV{'CTANUPLOAD'}) {
- unshift @ARGV, (split /\s+/, $ENV{'CTANUPLOAD'});
-}
-
-
-while (my $arg = shift @ARGV) {
- if ($arg =~ /^--(.*?)(?:=(.*))?$/) {
- my $name = $1;
- my $value = defined $2 ? $2 : shift @ARGV;
- my $file;
- if ($name =~ /(.*)-file$/) {
- $name = $1;
- $file = $value;
- }
- if (exists $FIELDS{$name}) {
- if ($file) {
- if (open (my $valfile, '<', $file)) {
- $value = join '', <$valfile>;
- close ($valfile);
- }
- else {
- warn "Couldn't read file '$file'!\n";
- $value = '';
- }
- }
- $FIELDS{$name} = $value;
- }
- else {
- usage('--' . $name . ($file ? '-file' : ''));
- }
- }
- elsif ($arg =~ /^-([a-z]+)$/i) {
- for my $char (split //, $1) {
- if ($char eq 'h') {
- usage(0);
- }
- elsif ($char eq 'q') {
- $QUIET = 1;
- }
- elsif ($char eq 'v') {
- $QUIET = 0;
- }
- elsif ($char eq 'y') {
- $ASK = 0;
- }
- elsif ($char eq 'F') {
- my $file = shift @ARGV;
- load_data ($file);
- }
- elsif ($char eq 'f') {
- $FORCE = 1;
- }
- elsif ($char eq 'p') {
- $PROMPT = 1;
- }
- elsif ($char eq 'P') {
- $PROMPT = 0;
- }
- elsif ($char eq 'u') {
- $CTAN_URL = shift @ARGV;
- }
- elsif ($char eq 'U') {
- my $server = lc shift @ARGV;
- $server = $CTAN_SERVERALIASES{$server} || $server;
- if (not exists $CTAN_SERVERURLS{ $server }) {
- die "Error: Unknown CTAN server '$server'.\n";
- }
- $CTAN_URL = $CTAN_SERVERURLS{ $server };
- }
- elsif ($char eq 'l') {
- $LOG = 1;
- }
- elsif ($char eq 'L') {
- $LOG = 0;
- }
- elsif ($char eq 'o') {
- $LOGFILE = shift @ARGV;
- }
- elsif ($char eq 'V') {
- print STDERR "ctanupload script $VERSION.\n";
- exit (0);
- }
- else {
- usage('-' . $char);
- }
- }
- }
- else {
- usage($arg);
- }
-}
-
-$CTAN_URL = (values %CTAN_SERVERURLS)[int rand scalar values %CTAN_SERVERURLS]
- if not defined $CTAN_URL;
-
-my $DANTE = $CTAN_URL =~ /dante/;
-
-PROMPT:
-
-if ($PROMPT) {
- foreach my $field (@FIELDS) {
- if (!defined $FIELDS{$field} || !length $FIELDS{$field}) {
- my $input = '';
- if ($field eq 'notes' || $field eq 'announce') {
- next if $field eq 'announce' and $FIELDS{DoNotAnnounce};
- next if $field eq 'notes' and not $DANTE;
- print "\u$FIELDS_DESC{$field}: (press CTRL-Z (Windows) or CTRL-D (Linux) to stop)\n";
- while (<STDIN>) {
- $input .= $_;
- }
- }
- elsif ($field eq 'DoNotAnnounce') {
- print "\uNo need to announce upload? [y/N]: ";
- $input = <STDIN>;
- }
- elsif ($field eq 'license') {
- print "\u$FIELDS_DESC{$field}:\n";
- my $num = 1;
- foreach my $license (@LICENSES) {
- printf " [%d] %s\n", $num++, $LICENSES{$license};
- }
- print "Selection: ";
- $input = lc (<STDIN> || '');
- if ($input =~ /^\s*(\d+)\s*$/) {
- $input = $LICENSES[$1-1];
- }
- }
- elsif ($field eq 'freeversion') {
- next if $FIELDS{license} ne 'free';
- print "\u$FIELDS_DESC{$field}:\n";
- my $num = 1;
- foreach my $license (@FREEVERSIONS) {
- printf " [%d] %s\n", $num++, $FREEVERSIONS{$license};
- }
- print "Selection: ";
- $input = lc (<STDIN> || '');
- if ($input =~ /^\s*(\d+)\s*$/) {
- $input = $FREEVERSIONS[$1-1];
- }
- }
- else {
- print "\u$FIELDS_DESC{$field}: ";
- $input = <STDIN>;
- }
- $input = '' if not defined $input;
- chomp $input;
- $input =~ s/^\s+//;
- $input =~ s/\s+$//;
- $FIELDS{$field} = $input;
- }
- }
-}
-
-my $abort = '';
-foreach my $required (@REQUIRED) {
- if (!length $FIELDS{$required}) {
- $abort .= "Required field '$required' is missing!\n";
- }
-}
-if (not exists $LICENSES{ $FIELDS{license} }) {
- $abort .= "Unknown license type '$FIELDS{license}'!\n"
- if not $FORCE;
-}
-if ($FIELDS{license} ne 'free') {
- $FIELDS{freeversion} = '-not-selected-';
-} elsif (!$FIELDS{freeversion}) {
- $abort .= "Required field 'freeversion' is missing!\n";
-} elsif (not exists $FREEVERSIONS{ $FIELDS{freeversion} }) {
- $abort .= "Unknown free license '$FIELDS{freeversion}'!\n"
- if not $FORCE;
-}
-if ($FIELDS{file} && ! -f $FIELDS{file}) {
- $abort .= "File '$FIELDS{file}' not found!\n";
-}
-
-if ($LOG) {
- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
- my $DATE = sprintf ('%04d-%02d-%02d %02d:%02d:%02d', $year+1900, $mon+1, $mday, $hour, $min, $sec);
- if (!$LOGFILE) {
- $LOGFILE = 'ctanupload-' . $FIELDS{contribution} . " $DATE.log";
- $LOGFILE =~ tr/: /-_/;
- }
- save_data($LOGFILE, 1, "# $DATE");
- if (!open (LOG, '>>', $LOGFILE)) {
- warn "Couldn't open logfile '$LOGFILE'.\n";
- $LOG = 0;
- }
-}
-
-if ($abort) {
- print $abort, "Aborting!\n";
- if ($LOG) {
- $abort =~ s/\n/\n# /gms;
- print LOG "# $abort\n# Aborting!\n";
- }
- exit (2);
-}
-
-my $DoNotAnnounce = ($FIELDS{DoNotAnnounce}) ? '[x]' : '[ ]';
-
-if (!$FIELDS{directory}) {
- $FIELDS{directory} = '/macros/latex/contrib/' . $FIELDS{contribution};
-}
-
-
-print "\nThe following data will be submitted to CTAN ($CTAN_URL):\n";
-
-foreach my $field (@FIELDS) {
- if ($field eq 'DoNotAnnounce') {
- print "$FIELDS_DESC{$field}: $DoNotAnnounce\n";
- }
- elsif ($field eq 'license') {
- print "$FIELDS_DESC{$field}: $LICENSES{$FIELDS{$field}}\n";
- }
- elsif ($field eq 'freeversion') {
- print "$FIELDS_DESC{$field}: $FREEVERSIONS{$FIELDS{$field}}\n";
- }
- else {
- print "$FIELDS_DESC{$field}: ", $FIELDS{$field} || '', "\n";
- }
-}
-
-eval {
- my $file = $FIELDS{file};
- die if not -f $file;
- print "\n$file (", (-s $file), "):\n";
- if ($file =~ /\.tar\.gz$/) {
- system ('tar', 'tzvf', $file);
- }
-};
-
-if ($ASK) {
- print "\nUpload? [(y/N/(e)dit/(s)ave] ";
- my $response = lc <STDIN>;
- chomp ($response);
-
- unless ($response eq 'y' or $response eq 'yes') {
- if ($response eq 'e' or $response eq 'edit') {
- my $file = 'ctanupload.dat';
- save_data($file);
- my $editor = $ENV{'CTANUPLOAD_EDITOR'} || $ENV{'EDITOR'};
- if (not defined $editor) {
- print "No EDITOR environment variable defined.\n";
- print "Data was stored in file '$file'. Please edit manually and load with the -F option.\n";
- exit (1);
- }
- else {
- system($editor, $file);
- load_data($file);
- goto PROMPT;
- }
- }
- elsif ($response eq 's' or $response eq 'save') {
- my $file = 'ctanupload.dat';
- save_data($file);
- print "Data was stored in file '$file'.\n";
- print LOG "\n# Data was stored in file '$file'.\n" if $LOG;
- exit (2);
- }
- else {
- print "\nUpload aborted!\n";
- print LOG "\n# Upload aborted!\n" if $LOG;
- exit (1);
- }
- }
-}
-
-if ($FIELDS{DoNotAnnounce}) {
- if ($DANTE) {
- $FIELDS{DoNotAnnounce} = 'No';
- delete $FIELDS{'to_announce'};
- $FIELDS{notes} = '';
- } else {
- $FIELDS{'to_announce'} = 'Yes';
- delete $FIELDS{DoNotAnnounce};
- delete $FIELDS{notes};
- }
-}
-else {
- if ($DANTE) {
- $FIELDS{DoNotAnnounce} = 'Yes';
- delete $FIELDS{to_announce};
- } else {
- delete $FIELDS{'to_announce'};
- delete $FIELDS{DoNotAnnounce};
- delete $FIELDS{notes};
- }
-}
-# Add Submit button for the sake of completeness:
-$FIELDS{'SUBMIT'} = ($DANTE) ? 'Submit' : 'Submit contribution';
-
-use WWW::Mechanize;
-my $mech = WWW::Mechanize->new(quiet => $QUIET, autocheck => 1);
-
-print "Accessing CTAN upload page ...\n";
-$mech->get( $CTAN_URL );
-print "Uploading ...\n";
-$mech->submit_form(
- form_number => 1,
- fields => \%FIELDS,
-);
-
-if ($mech->success()) {
- print "HTTP response code: ", $mech->response()->message(), "\n";
-}
-
-print "\nResponse:\n";
-print LOG "\n# Response:\n" if $LOG;
-eval {
- if ($mech->response()->header('Content-Type') eq 'text/plain') {
- #open (my $DEBUGFILE, '>', 'ctanupload.dbg');
- #print {$DEBUGFILE} $mech->content();
- #close ($DEBUGFILE);
- print $mech->content();
- print LOG $mech->content() if $LOG;
- }
- else {
- use HTML::TreeBuilder;
- use HTML::FormatText;
- my $tree = HTML::TreeBuilder->new_from_content( $mech->content() );
- my $formatter = HTML::FormatText->new(leftmargin => 0, rightmargin => 80);
- my @response = split /\n/, $formatter->format($tree);
- local $, = "\n";
- print @response[3..$#response-3];
- local $, = "\n# ";
- print LOG '', @response[3..$#response-3] if $LOG;
- }
- 1;
-} or do {
- print "Can't display HTML response, storing reponse if log file 'ctanupload_response.html'\n";
- open (HLOG, '>', 'ctanupload_response.html');
- print HLOG $mech->content();
- close (HLOG);
-};
-
-print "\n";
-close LOG if $LOG;
-exit (0);
-
-
-sub fromenv {
- my $name = shift;
- foreach my $var ('CTAN_' . uc $name, uc $name, 'CTAN_' . $name, $name) {
- return $ENV{$var} if exists $ENV{$var};
- }
- return undef;
-}
-
-sub load_data {
- my $file = shift;
- open (my $load, '<', $file) or die "Couldn't open data file '$file'!\n";
- LOAD_LOOP:
- while (my $line = <$load>) {
- next if ($line =~ /^\s*(#|$)/);
- if ($line =~ /^([a-z]+)\s*=\s*(.*)$/i) {
- my ($name,$value) = ($1,$2);
- if (!exists $FIELDS{$name}) {
- print STDERR "Ignoring unknown variable '$name' from file '$file' (line $.)!\n";
- next;
- }
- $FIELDS{$name} = $value;
- if ($name eq 'announce' || $name eq 'notes') {
- $FIELDS{$name} .= "\n";
- while ($line = <$load>) {
- next if ($line =~ /^\s*#/);
- last if ($line =~ /^[a-z]+\s*=/i);
- $FIELDS{$name} .= $line;
- }
- $FIELDS{$name} =~ s/^[\s\n]+//;
- $FIELDS{$name} =~ s/[\s\n]+$//;
- redo LOAD_LOOP if not eof $load;
- }
- }
- else {
- print STDERR "Ignoring incorrect line '$line' from file '$file' (line $.)!\n";
- }
- }
- close ($load);
-}
-
-sub save_data {
- my $file = shift;
- my $storefileinfo = shift;
- my $header = shift;
- $file = 'ctanupload.dat' if not defined $file;
- open (my $save, '>', $file) or do { warn "Couldn't save data to file '$file'!\n"; return; };
- print {$save} "$header\n" if $header;
- foreach my $field (@FIELDS) {
- if ($field eq 'DoNotAnnounce') {
- print {$save} "$field = ", $FIELDS{DoNotAnnounce} ? '1' : '0', "\n";
- }
- else {
- print {$save} "$field = ", $FIELDS{$field} || '', "\n";
- }
- }
- if ($storefileinfo && -f $FIELDS{file}) {
- my $file = $FIELDS{file};
- print {$save} "\n# $file (", (-s $file), "):\n";
- if ($file =~ /\.tar\.gz$/) {
- open (my $TAR, '-|', "tar tzvf $file");
- print {$save} map { "# $_" } <$TAR>;
- print {$save} "\n";
- close ($TAR);
- }
- }
- close ($save);
- return;
-}
-
-
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/de-macro/de-macro b/Build/source/texk/texlive/linked_scripts/de-macro/de-macro
deleted file mode 100755
index c5795fe891f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/de-macro/de-macro
+++ /dev/null
@@ -1,1097 +0,0 @@
-#!/usr/bin/python -O
-
-r"""
-Copyright 2005-2020 Peter Gacs
-Licensed under the Academic Free Licence version 2.1
-
- DE-MACRO
-
-Version 1.4 - Luca Citi made it python2.7 and python3 compatible.
- Peter Gacs improved the parsing of \input{<filename>},
- and made @ a letter in the style files.
-Version 1.3 - this version is much more conservative about deleting
- comments and inserting or deleting blank space: tries to
- leave in all comments, adds space only when necessary, and
- tries not to delete space in the main text.
- The motivating comments came from Daniel Webb.
-Version 1.2 - a syntactical bug corrected, thanks Brian de Alwis!
-
-
-PURPOSE
-
-This program can eliminate most private macros from a LaTeX file.
-Applications:
- - your publisher has difficulty dealing with many private macros
- - you cooperate with colleagues who do not understand your macros
- - preprocessing before a system like latex2html, which is somewhat
- unpredictable with private macros.
-
-It cannot be used to eliminate more complex macros that rely on
-more programming-like constructs in style files. In particular, it will
-not replace style files that have options.
-
-USAGE
-
-de-macro [--defs <defs-db>] <tex-file-1>[.tex] [<tex-file-2>[.tex] ...]
-
-Simplest example: de-macro testament
-
-(As you see, the <> is used only in the notation of this documentation,
-you should not type it.)
-
-If <tex-file-i> contains a command \usepackage{<defs-file>-private}
-then the file <defs-file>-private.sty will be read, and its macros will be
-replaced in <tex-file-i> with their definitions.
-The result is in <tex-file-i>-clean.tex.
-
-Only newcommand, renewcommand, newenvironment, and renewenvironment are
-understood (it does not matter, whether you write new or renew).
-These can be nested but do not be too clever, since I do not
-guarantee the same expansion order as in TeX.
-
-FILES
-
-<tex-file-1>.db
-<tex-file>-clean.tex
-<defs-file>-private.sty
-
-For speed, a macro database file called <defs-file>.db is created.
-If such a file exists already then it is used.
-If <defs-file>-private.sty is older than <tex-file-1>.db then it will not
-be used.
-
-It is possible to specify another database filename via --defs <defs-db>.
-Then <defs-db>.db will be used.
-
-For each <tex-file-i>, a file <tex-file-i>-clean.tex will be produced.
-If <tex-file-i>-clean.tex is newer than <tex-file-i>.tex then it stays.
-
-INPUT COMMAND
-
-If a tex file contains a command \input{<tex-file-j>} or \input <tex-file-j>
-then <tex-file-j>.tex is processed recursively, and <tex-file-j>-clean.tex
-will be inserted into the final output.
-For speed, if <tex-file-j>-clean.tex is newer than <tex-file-j>.tex
-then <tex-file-j>.tex will not be reprocessed.
-
-The dependency checking is not sophisticated, so if you rewrite some macros
-then remove all *-clean.tex files!
-
-"""
-
-import sys, os, re, shelve
-
-# Utilities
-
-class No_detail:
- strerror = ""
-
-no_detail = No_detail()
-
-
-class Error(Exception):
- """Base class for exceptions in this module."""
- pass
-
-class Empty_text_error(Error):
- """Exception raised for errors in the input.
-
- Attributes:
- data -- data that was found empty
- message
- """
-
- def __init__(self, data, message):
- self.data = data
- self.message = message
-
-def warn(error_message, detail = no_detail):
- sys.stderr.write(error_message + "\n")
- if no_detail != detail:
- sys.stderr.write(detail.strerror + "\n")
-
-def die(error_message, detail = no_detail):
- warn(error_message, detail = no_detail)
- sys.exit(1)
-
-def getopt_map(one_letter_opts, long_optlist):
- "Turns long options into an option map, using getopt."
- import getopt
- optlist, args = getopt.getopt(sys.argv[1:],
- one_letter_opts, long_optlist)
- opt_map = {}
- for pair in optlist: opt_map[pair[0]] = pair[1] or 1
- return opt_map, args
-
-def newer(file1, file2):
-
- if not os.path.isfile(file1):
- return False
-
- try:
- stat_return = os.lstat(file1)
- except OSError as detail:
- die("lstat " + file1 + " failed:", detail)
- time1 = stat_return.st_mtime
-
- try:
- stat_return = os.lstat(file2)
- except OSError as detail:
- die("lstat " + file2 + " failed:", detail)
- time2 = stat_return.st_mtime
-
- return time1 > time2
-
-def cut_extension(filename, ext):
- """
- If filename has extension ext (including the possible dot),
- it will be cut off.
- """
- file = filename
- index = filename.rfind(ext)
- if 0 <= index and len(file)-len(ext) == index:
- file = file[:index]
- return file
-
-
-class Stream:
- data = None
- pos = None
- item = None
-
- def legal(self):
- return 0 <= self.pos and self.pos < len(self.data)
-
- def uplegal(self):
- return self.pos < len(self.data)
-
- def __init__(self, data_v = None):
- self.data = data_v
- if self.data:
- self.pos = 0
- self.item = self.data[self.pos]
-
- def next(self):
- self.pos += 1
- if self.pos < len(self.data):
- self.item = self.data[self.pos]
- return self.item
-
- def reset(self):
- if self.data and 0 < len(self.data):
- self.pos = 0
- self.item = self.data[0]
- return self.item
-
-
-# Basic classes
-
-blank_re = re.compile(r"\s")
-blanked_filename_re = re.compile(r"^\s+(\w*)\s+")
-braced_filename_re = re.compile(r"^\s*{\s*(\w*)\s*}")
-blank_or_rbrace_re = re.compile(r"[\s}]")
-pos_digit_re = re.compile(r"[1-9]")
-
-def isletter(c, isatletter=False):
- if "@" == c:
- return isatletter
- else:
- return c.isalpha()
-
-class Token:
- """Type 0 means ordinary character, types 1,2 mean escape sequence
- (without the \ ), type 3 means comment.
- """
- simple_ty = 0
- esc_symb_ty = 1
- esc_str_ty = 2
- comment_ty = 3
-
- type = simple_ty
- val = " "
-
- def __init__(self, type_v=simple_ty, val_v=" "):
- self.type = type_v
- self.val = val_v
-
- def show(self):
- out = ""
- if simple_ty == self.type or comment_ty == self.type:
- out = self.val
- else:
- out = "\\" + self.val
- return out
-
-
-# Constants
-
-g_token = Token(0," ") # generic token
-simple_ty = g_token.simple_ty
-comment_ty = g_token.comment_ty
-esc_symb_ty = g_token.esc_symb_ty
-esc_str_ty = g_token.esc_str_ty
-
-
-def detokenize(text, isatletter=False):
- """
- Input is a list of tokens.
- Output is a string.
- """
- out = ""
- if 0 == len(text):
- return
- pos = 0
- out += text[pos].show()
- pos += 1
- while pos < len(text):
- previtem = text[pos-1]
- item = text[pos]
- """Insert a separating space after an escape sequence if it is a
- string and is followed by a letter."""
- if (esc_str_ty == previtem.type
- and simple_ty == item.type and isletter(item.val[0], isatletter)):
- out += " "
- out += item.show()
- pos += 1
- return out
-
-
-def strip_comments(text):
- """
- Input is a list of tokens.
- Output is the same list except the comment tokens.
- """
- out = []
- for token in text:
- if not comment_ty == token.type:
- out.append(token)
- return out
-
-class Group:
- """type 0 means a token, type 1 means contents of a group within {}
- """
- token_ty = 0
- group_ty = 1
- type = token_ty
- val = [] # Value is a token list.
-
- def __init__(self, type_v, val_v):
- self.type = type_v
- self.val = val_v
-
- def show(self):
- if token_ty == self.type:
- return self.val.show()
- else:
- return "{%s}" % detokenize(self.val)
-
-# Constants
-
-g_group = Group(0, [])
-token_ty = g_group.token_ty
-group_ty = g_group.group_ty
-
-
-def tokenize(in_str, isatletter=False):
- """Returns a list of tokens.
- """
- text = []
- cs = Char_stream(in_str)
- cs.reset()
- if not cs.legal():
- raise Error("No string to tokenize.")
- while cs.uplegal():
- if "%" == cs.item:
- comment = cs.scan_comment_token()
- text.append(Token(comment_ty, comment))
- elif "\\" != cs.item:
- text.append(Token(simple_ty, cs.item))
- cs.next()
- else:
- cs.next()
- name = cs.scan_escape_token(isatletter)
- if isletter(name[0], isatletter):
- token = Token(esc_str_ty, name)
- else:
- token = Token(esc_symb_ty, name)
- text.append(token)
- if "makeatletter" == name:
- isatletter=True
- elif "makeatother" == name:
- isatletter=False
- return text
-
-
-class Command_def:
- name = "1"
- numargs = 0
- body= ""
-
- def __init__(self, name_v, numargs_v, body_v):
- self.name = name_v
- self.numargs = numargs_v
- self.body = body_v
-
- def show(self):
- out = "\\newcommand{\\%s}" % (self.name)
- if 0 < self.numargs:
- out += "[%d]" % self.numargs
- out += "{%s}" % detokenize(self.body)
- return out
-
-
-class Env_def:
- name = "1"
- numargs = 0
- begin = ""
- end = ""
-
- def __init__(self, name_v, numargs_v, begin_v, end_v):
- self.name = name_v
- self.numargs = numargs_v
- self.begin = begin_v
- self.end = end_v
-
- def show(self):
- out = "\\newenvironment{%s}" % self.name
- if 0 < self.numargs:
- out += "[%d]" % self.numargs
- out += "{%s}" % detokenize(self.begin)
- out += "{%s}" % detokenize(self.end)
- return out
-
-
-class Command_instance:
- name = "1"
- args = []
-
- def __init__(self, name_v, args_v):
- self.name = name_v
- self.args = args_v
-
- def show(self):
- out = "\\"+self.name
- for arg in self.args:
- out += "{%s}" % detokenize(arg)
- return out
-
-
-class Env_instance:
- name = "1"
- args = []
-
- def __init__(self, name_v, args_v, body_v):
- self.name = name_v
- self.args = args_v
- self.body = body_v
-
- def show(self):
- out = "\\begin{%s}" % self.name
- for arg in self.args:
- out += "{%s}" % detokenize(arg)
- out += detokenize(self.body)
- out += "\\end{%s}" % self.name
- return out
-
-class Char_stream(Stream):
-
- def scan_escape_token(self, isatletter=False):
- """
- Starts after the escape sign, assumes that it is scanning a symbol.
- Returns a token-string.
- """
- out = self.item # Continue only if this is a letter.
- item = self.next()
- if isletter(out, isatletter):
- while self.uplegal() and isletter(item, isatletter):
- out += item
- item = self.next()
- return out
-
- def scan_comment_token(self):
- """
- Starts at the comment sign %, assumes that it is scanning a comment.
- Returns the whole comment string,
- including the % and all empty space after it.
- """
- comment = ""
- while self.uplegal() and "\n" != self .item:
- comment += self.item
- self.next()
- while self.uplegal() and blank_re.match(self.item):
- comment += self.item
- self.next()
- return comment
-
- def scan_input_filename(self):
- """We have just read an \input token. The next group or word will be
- interpreted as a filename (possibly without .tex). Filenames should not begin with spaces.
- Return the filename.
- """
- item = self.item
- file = ""
- while self.uplegal() and blank_re.match(self.item):
- item = self.next()
- if "{" == item:
- item = self.next()
- while self.uplegal() and not "}" == item:
- file += item
- item = self.next()
- self.next()
- else:
- while self.uplegal() and not blank_re.match(item):
- file += item
- item = self.next()
- return file
-
- def scan_package_filenames(self):
- r"""We just read a \usepackage token. The next group will be
- interpreted as a list of filenames (without .sty) separated by commas.
- Return the list.
- """
- item = self.item
- while self.uplegal() and blank_re.match(item):
- item = self.next()
- file = ""
- if not "{" == item:
- raise Error("\\usepackage not followed by brace.")
- item = self.next()
- while self.uplegal() and not blank_or_rbrace_re.match(item):
- file += item
- item = self.next()
- self.next()
- return file.split(",")
-
-
-class Tex_stream(Stream):
-
- defs = ({}, {})
- defs_db = "x"
- defs_db_file = "x.db"
- debug = False
-
- def smart_tokenize(self, in_str, handle_inputs=False, isatletter=False):
- """Returns a list of tokens.
- It may interpret and carry out all \input commands.
- """
- self.data = []
- text = self.data
- cs = Char_stream(in_str)
- cs.reset()
- if not cs.legal():
- raise Error("No string to tokenize.")
- while cs.uplegal():
- if "%" == cs.item:
- comment = cs.scan_comment_token()
- text.append(Token(comment_ty, comment))
- elif "\\" != cs.item:
- text.append(Token(simple_ty, cs.item))
- cs.next()
- else:
- cs.next()
- name = cs.scan_escape_token(isatletter)
- if "input" == name and handle_inputs:
- file = cs.scan_input_filename()
- to_add = self.process_if_newer(file)
- text.extend(to_add)
- elif "usepackage" == name:
- while cs.uplegal() and blank_re.match(cs.item):
- cs.next()
- if "[" == cs.item: # Packages with options will not be processed.
- text.extend([Token(esc_str_ty, "usepackage"),
- Token(simple_ty, "[")])
- cs.next()
- continue
- files = cs.scan_package_filenames()
- i = 0
- while i < len(files): # process private packages
- file = files[i]
- p = file.rfind("-private")
- if p < 0 or not len(file) - len("-private") == p:
- i += 1
- continue
- defs_db_file = file+".db"
- self.add_defs(file)
- del files[i:(i+1)]
- if files: # non-private packages left
- group_content = ",".join(files)
- to_add_str = "\\usepackage{%s}" % (group_content)
- to_add = tokenize(to_add_str,isatletter)
- text.extend(to_add)
- else:
- if isletter(name[0], isatletter):
- token = Token(esc_str_ty, name)
- else:
- token = Token(esc_symb_ty, name)
- text.append(token)
- if "makeatletter" == name:
- isatletter=True
- elif "makeatother" == name:
- isatletter=False
- self.reset()
- return self.data
-
- def smart_detokenize(self,isatletter=False):
- """
- Output is a string.
- If the list contains an \input{file} then the content of file
- file-clean.tex replaces it in the output.
- """
- self.reset()
- if not self.legal():
- return ""
- out = ""
- previtem = None
- while self.uplegal():
- item = self.item
- """Insert a separating space after an escape sequence if it is a
- string and is followed by a letter."""
- if (None != previtem and esc_str_ty == previtem.type
- and simple_ty == item.type and isletter(item.val[0], isatletter)):
- out += " "
- previtem = item
- if not (esc_str_ty == item.type and "input" == item.val):
- out += item.show()
- self.next()
- else:
- self.next()
- group = self.scan_group()
- file = detokenize(group.val)
- clean_file = "%s-clean.tex" % (file)
- print("Reading file %s" % (clean_file))
- fp = open(clean_file,"r")
- content = fp.read()
- fp.close()
- out += content
- return out
-
- # Basic tex scanning
-
- def skip_blank_tokens(self): # we also skip comment tokens.
- item = self.item
- while (self.uplegal() and
- (comment_ty == item.type or
- (simple_ty == item.type and blank_re.match(item.val)))):
- item = self.next()
- return item
-
- def scan_group(self):
- """Returns group.
- """
- if not self.legal():
- raise Error("No group to scan.")
- item = self.item
- if not (simple_ty == item.type and "{" == item.val):
- return Group(token_ty, [self.item])
- count = 1
- group = []
- item = self.next()
- while count and self.uplegal():
- if simple_ty == item.type:
- if "{" == item.val:
- count += 1
- elif "}" == item.val:
- count -= 1
- if count != 0:
- group.append(item)
- item = self.next()
- return Group(group_ty, group)
-
- # Command and environment definitions
-
- def scan_command_name(self):
- """Returns name.
- """
- if not self.legal():
- raise Error("No command name to scan.")
- item = self.item
- name = ""
- if item.type in [esc_symb_ty, esc_str_ty]:
- name = item.val
- else:
- if not "{" == item.val:
- raise Error("Command definition misses first {.")
- self.next()
- item = self.skip_blank_tokens()
- if not item.type in [esc_symb_ty, esc_str_ty]:
- raise Error("Command definition does not begin with control sequence.")
- name = item.val
- self.next()
- item = self.skip_blank_tokens()
- if not "}" == item.val:
- raise Error("Definition for commmand %s misses first }., %s" %
- (name, item.val))
- self.next()
- self.skip_blank_tokens()
- return name
-
- def scan_numargs(self, name):
- """
- name is the name of the command or environment definition being
- scanned.
- Starts on a nonblank token.
- Returns numargs
- where numargs is the number of arguments in a command or environment
- definition,
- """
- if not self.legal():
- raise Error("No numargs to scan.")
- item = self.item
- numargs = 0
- if not simple_ty == item.type:
- raise Error("Illegal command or environment definition: "+name)
- if "[" == item.val:
- if not 4 < len(self.data):
- raise Error("Command or environment definition is illegal: "+name)
- item = self.next()
- if not simple_ty == item.type:
- raise Error("Illegal command or environment definition: "+name)
- numargs = item.val
- if not pos_digit_re.match(numargs):
- raise Error("%s must be argument number after %s" % (numargs, name))
- numargs = int(numargs)
- self.next()
- item = self.skip_blank_tokens()
- if not simple_ty == item.type:
- raise Error("Illegal command definition: "+name)
- if "]" != item.val:
- raise Error("Illegal command definition: "+name)
- self.next()
- self.skip_blank_tokens()
- return numargs
-
- def scan_command_def(self):
- """Scan a command definition.
- Return command_def.
- Assumes that the number of arguments is at most 9.
- """
- if not self.legal():
- raise Error("No command definition to scan.")
- item = self.item
- if not 2 < len(self.data):
- raise Error("Command definition is illegal.")
- # newcommand or renewcommand
- if not item.type in [esc_symb_ty, esc_str_ty]:
- raise Error("Command definition should begin with control sequence: "+item.val)
- if item.val not in ["newcommand", "renewcommand"]:
- raise Error("Command definition should begin with control sequence.")
- self.next()
- self.skip_blank_tokens()
-
- cmd_name = self.scan_command_name()
- numargs = self.scan_numargs(cmd_name)
-
- body_group = self.scan_group()
- if group_ty != body_group.type:
- raise Error("Command body missing: "+cmd_name)
- body_val = strip_comments(body_group.val)
- return Command_def(cmd_name, numargs, body_val)
-
- def scan_env_name(self):
- """Starts on a {.
- Returns name.
- """
- if not self.legal():
- raise Error("No environment name to scan.")
- item = self.item
- if not "{" == item.val:
- raise Error("Env. definition begins with %s, not with {" % (item.val))
- self.next()
- item = self.skip_blank_tokens()
- name = ""
- if not simple_ty == item.type:
- raise Error("1. Env. def. begins with cont. seq. %s, not with env.name."
- % (item.val))
- while self.uplegal() and not blank_or_rbrace_re.match(item.val):
- name += item.val
- item = self.next()
- if not simple_ty == item.type:
- raise Error("2. Env. def. begins with cont. seq. %s, not with env.name."
- % (item.val))
- item = self.skip_blank_tokens()
- if not "}" == item.val:
- raise Error("Command definition does not begin with control sequence.")
- self.next()
- self.skip_blank_tokens()
- return name
-
- def scan_env_def(self):
- """Scan an environment definition.
- Return env_def
- Assumes that the number of arguments is at most 9.
- """
- if not self.legal():
- raise Error("No environment definition to scan.")
- item = self.item
- if not 7 < len(self.data):
- raise Error("Environment definition is illegal.")
- pos = 0
-
- if not item.type in [esc_symb_ty, esc_str_ty]:
- raise Error("Env. definition does not begin with control sequence:"+
- item.val)
- if item.val not in ["newenvironment", "renewenvironment"]:
- raise Error("Env. definition does not begin with control sequence.")
- self.next()
- self.skip_blank_tokens()
-
- env_name = self.scan_env_name()
- numargs = self.scan_numargs(env_name)
- self.skip_blank_tokens()
-
- begin_group = self.scan_group()
- if group_ty != begin_group.type:
- raise Error("Begin body missing: "+env_name)
- begin_val = strip_comments(begin_group.val)
-
- self.skip_blank_tokens()
-
- end_group = self.scan_group()
- if group_ty != end_group.type:
- raise Error("End body missing:"+env_name)
- end_val = strip_comments(end_group.val)
-
- return Env_def(env_name, numargs, begin_val, end_val)
-
- def scan_defs(self):
- if not self.legal():
- raise Error("No definitions to scan.")
- self.reset()
- command_defs, env_defs = self.defs
- while self.uplegal():
- if (esc_str_ty == self.item.type
- and self.item.val in ["newcommand", "renewcommand"]):
- command_def = self.scan_command_def()
- command_defs[command_def.name] = command_def
- elif (esc_str_ty == self.item.type and self.item.val
- in ["newenvironment", "renewenvironment"]):
- env_def = self.scan_env_def()
- env_defs[env_def.name] = env_def
- else:
- self.next()
-
- # Instances
-
- def scan_args(self, command_or_env_def):
- """Scan the arguments of a command or environment.
- Return [args].
- """
- if not self.legal():
- raise Error("No arguments to scan.")
- numargs = command_or_env_def.numargs
- name = command_or_env_def.name
-
- args = []
- for i in range(numargs):
- arg = []
- if not (simple_ty == self.item.type and "{" == self.item.val):
- arg = [self.item]
- self.next()
- else:
- group = self.scan_group()
- arg = group.val
- args.append(arg)
- return args
-
- def scan_command(self, command_def):
- """Scan the arguments of a command.
- Return command_instance
- """
- if not self.legal():
- raise Error("No command to scan.")
- if not self.item.type in [esc_symb_ty, esc_str_ty]:
- raise Error("Command does not begin with control sequence.")
- name = self.item.val
- self.next()
- if 0 < command_def.numargs:
- self.skip_blank_tokens()
- args = self.scan_args(command_def)
- else:
- args = []
- return Command_instance(name, args)
-
- def test_env_boundary(self, item):
- """Check whether an environment begin or end follows.
- Return 1 if \begin, -1 if \end, 0 otherwise.
- """
- d = 0
- if esc_str_ty == item.type:
- if "begin"==item.val:
- d = 1
- elif "end"==item.val:
- d = -1
- return d
-
- def scan_env_begin(self):
- """Scan an environment name.
- Return env_name.
- """
- if not self.legal():
- raise Error("No environment begin to scan.")
- item = self.item
- if not (esc_str_ty == item.type and "begin" == item.val):
- raise Error("Environment does not begin with begin.")
- self.next()
- name_group = self.scan_group()
- name = detokenize(name_group.val)
- return name
-
- def scan_env_end(self):
- """Scan an environment end.
- Return env_name.
- """
- if not self.legal():
- raise Error("No environment end to scan.")
- item = self.item
- if not (esc_str_ty == item.type and "end" == item.val):
- raise Error("Environment does not end with end.")
- self.next()
- name_group = self.scan_group()
- name = detokenize(name_group.val)
- return name
-
- def scan_env_rest(self, env_def):
- """Scanning starts after \begin{envname}.
- Returns env_instance.
- """
- if not self.legal():
- raise Error("No environment rest to scan.")
- count = 1 # We are already within a boundary.
- args = self.scan_args(env_def)
- body = []
- while count and self.uplegal():
- old_pos = self.pos
- d = self.test_env_boundary(self.item)
- count += d
- if 1 == d:
- self.scan_env_begin()
- elif -1 == d:
- self.scan_env_end()
- else:
- self.next()
- if 0 < count:
- body.extend(self.data[old_pos : self.pos])
- return Env_instance(env_def.name, args, body)
-
- # Definitions
-
- def restore_defs(self):
- if os.path.isfile(self.defs_db_file):
- print("Using defs db %s" % (self.defs_db_file))
- db_h = shelve.open(self.defs_db)
- self.defs = db_h["defs"]
- db_h.close()
-
- def save_defs(self):
- db_h = shelve.open(self.defs_db)
- if "defs" in db_h:
- del db_h["defs"]
- db_h["defs"] = self.defs
- db_h.close()
-
- def add_defs(self, defs_file):
- defs_file_compl = defs_file + ".sty"
- if not os.path.isfile(defs_file_compl):
- raise Error("%s does not exist" % (defs_file_compl))
-
- defs_db_file = self.defs_db_file
- if newer(defs_db_file, defs_file_compl):
- print("Using defs db %s for %s" % (defs_db_file, defs_file))
- else:
- defs_fp = open(defs_file_compl, "r")
- defs_str = defs_fp.read()
- defs_fp.close()
- ds = Tex_stream()
- ds.defs = self.defs
- defs_text = ds.smart_tokenize(defs_str,isatletter=True)
- # changing ds.defs will change self.defs
- if self.debug:
- defs_seen_file = "%s-seen.sty" % (defs_file)
- defs_seen_fp = open(defs_seen_file, "w")
- out = detokenize(defs_text,isatletter=True)
- defs_seen_fp.write(out)
- defs_seen_fp.close()
- ds.scan_defs()
- if self.debug:
- out = ""
- command_defs, env_defs = self.defs
- for def_name in command_defs.keys():
- out += command_defs[def_name].show() + "\n"
- for def_name in env_defs.keys():
- out += env_defs[def_name].show() +"\n"
- print("Definitions after reading %s:" % (defs_file))
- print(out)
-
- # Applying definitions, recursively
- # (maybe not quite in Knuth order, so avoid tricks!)
-
- def subst_args(self, body, args):
- out = []
- pos = 0
- while pos < len(body):
- item = body[pos]
- if not (simple_ty == item.type and "#" == item.val):
- out.append(item)
- pos += 1
- continue
- pos += 1
- token = body[pos]
- argnum = token.val
- if not pos_digit_re.match(argnum):
- raise Error("# is not followed by number.")
- argnum = int(argnum)
- if argnum > len(args):
- raise Error("Too large argument number.")
- arg = args[argnum-1]
- out += arg
- pos += 1
- return out
-
- def apply_command_recur(self, command_instance):
- command_defs, env_defs = self.defs
- name = command_instance.name
- command_def = command_defs[name]
-
- args = command_instance.args
- body = command_def.body
- result = self.subst_args(body, args)
- try:
- result = self.apply_all_recur(result)
- except Empty_text_error as e:
- raise Error("apply_all_recur fails on command instance %s: %s, %s" % \
- (command_instance.show(), detokenize(e.data), e.message))
- return result
-
- def apply_env_recur(self, env_instance):
- command_defs, env_defs = self.defs
- name = env_instance.name
- env_def = env_defs[name]
-
- begin, end = env_def.begin, env_def.end
- body, args = env_instance.body, env_instance.args
- out = self.subst_args(begin, args) + body + self.subst_args(end, args)
- return self.apply_all_recur(out)
-
-
- def apply_all_recur(self, data, report=False):
- ts = Tex_stream(data)
- ts.defs = self.defs
- command_defs, env_defs = self.defs
- out = []
- progress_step = 10000
- progress = progress_step
- if not ts.legal():
- raise Empty_text_error(data, "No text to process.")
- while ts.uplegal():
- if self.pos > progress:
- if report:
- print(self.pos)
- progress += progress_step
- if not ts.item.type in [esc_symb_ty, esc_str_ty]:
- out.append(ts.item)
- ts.next()
- continue
- if 1 == ts.test_env_boundary(ts.item):
- old_pos = ts.pos
- env_name = ts.scan_env_begin()
- if env_name not in env_defs:
- out.extend(ts.data[old_pos : ts.pos])
- continue
- else:
- env_def = env_defs[env_name]
- env_instance = ts.scan_env_rest(env_def)
- result = ts.apply_env_recur(env_instance)
- out.extend(result)
- elif ts.item.val not in command_defs:
- out.append(ts.item)
- ts.next()
- continue
- else:
- command_def = command_defs[ts.item.val]
- command_inst = ts.scan_command(command_def)
- result = ts.apply_command_recur(command_inst)
- out.extend(result)
- return out
-
-
- # Processing files
-
- def process_file(self, file):
- """Returns the new defs.
- """
- file = cut_extension(file, ".tex")
- source_file = "%s.tex" % (file)
- print("File %s [" % (source_file))
- source_fp = open(source_file, "r")
- text_str = source_fp.read()
- source_fp.close()
-
- self.smart_tokenize(text_str, handle_inputs=True)
- if not self.data:
- raise Error("Empty tokenization result.")
- self.reset()
-
- if self.debug:
- source_seen_fname = "%s-seen.tex" % (file)
- source_seen_fp = open(source_seen_fname, "w")
- source_seen_fp.write(detokenize(self.data))
- source_seen_fp.close()
-
- self.data = self.apply_all_recur(self.data, report=True)
-
- result_fname = "%s-clean.tex" % (file)
- print("Writing %s [" % (result_fname))
- result_fp = open(result_fname, "w")
- result_fp.write(self.smart_detokenize())
- result_fp.close()
- print("] file %s" % (result_fname))
- print("] file %s" % (source_file))
-
- def process_if_newer(self, file):
- """
- \input{file} is added to the token list.
- If the input file is newer it is processed.
- Returns tokenized \input{file}.
- """
- file = cut_extension(file, ".tex")
- tex_file = file+".tex"
- clean_tex_file = file+"-clean.tex"
- if newer(clean_tex_file, tex_file):
- print("Using %s." % (clean_tex_file))
- else:
- ts = Tex_stream()
- ts.data = []
- ts.defs = self.defs
- ts.process_file(file)
- to_add = "\\input{%s}" % (file)
- return tokenize(to_add)
-
-# Main
-
-long_optlist = ["debug","defs="]
-options, restargs = getopt_map("x", long_optlist)
-
-debug = False
-if "--debug" in options:
- debug = True
-
-root = restargs[0]
-root = cut_extension(root, ".tex")
-if "--defs" in options:
- defs_root = options["--defs"]
-else:
- defs_root = "%s" % (root)
-defs_db = defs_root
-defs_db_file = defs_root+".db"
-
-ts = Tex_stream()
-ts.defs_db = defs_db
-ts.defs_db_file = defs_db_file
-ts.debug = debug
-
-ts.restore_defs()
-for root in restargs:
- ts.process_file(root)
-
-print("(Re)creating defs db %s" % (defs_db))
-ts.save_defs()
diff --git a/Build/source/texk/texlive/linked_scripts/diadia/diadia.lua b/Build/source/texk/texlive/linked_scripts/diadia/diadia.lua
deleted file mode 100644
index 81d668499e7..00000000000
--- a/Build/source/texk/texlive/linked_scripts/diadia/diadia.lua
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/usr/bin/env texlua
---
--- diadia [options]
---
--- loads and processes a diadia data file
---
--- License: LPPL
---
-local version = "v1.0 (2015/05/15)"
-
-local infile = ""
-local outfile = ""
-local mode = "*"
-local startdate = ""
-local enddate = ""
-local columns = ""
-local data = {}
-function pversion()
- print("diadia.lua " .. version)
- print("(C) Josef Kleber 2015 License: LPPL")
- os.exit(0)
-end
-function phelp()
- print([[
-diadia.lua [options]
-
- allows you to
-
- - cut a chunk out of the data file
- e.g.: -i in.dat -o out.dat -s YYYY-MM-DD -e YYYY-MM-DD
-
- - compose a new data file based on given columns of an
- existing data file
- e.g.: -i in.dat -o out.dat -c 1,2
-
- - create a new data file with date and value (1st and
- 2nd column of existing file) and added value average
- columns of the last 7, 14, 30, 60 and 90 days
- e.g.: -i in.dat -o out.dat [-s YYYY-MM-DD -e YYYY-MM-DD]
-
- Options:
-
- -m specify the mode (cut|compose|average)
-
- -i specify the input file
-
- -o specify the output file
-
- -c specify the columns for compose mode
-
- -s specify the start date (YYYY-MM-DD) in
- cut and average mode
-
- -e specify the end date
-
- -v prints version information
-
- -h prints help information
-
-]])
- pversion()
-end
-function check_date(date)
- if string.find(date, "(%d%d%d%d)-(%d%d)-(%d%d)") == nil
- then
- io.stderr:write ("Error 21: wrong date format (YYYY-MM-DD)\n")
- os.exit(11)
- end
-end
-function parse_date(date)
- return string.match(date, "(%d%d%d%d)%-(%d%d)%-(%d%d)")
-end
-function parse_dateinline(line)
- return string.match(line, "(%d%d%d%d%-%d%d%-%d%d)")
-end
-function daystring(unixtime)
- return os.date("%Y-%m-%d", unixtime)
-end
-function unixtime(year,month,day)
- return os.time{year=year, month=month, day=day}
-end
-function round(number)
- return math.floor(number+0.5)
-end
-function ptd(value)
- local val = tostring(value)
- local slen = string.len(val)
- if slen == 3
- then
- return val
- else
- return val .. " "
- end
-end
-function calc_avg(data,date,days)
- local sum = 0
- local wdays = 0
- local wday
- local endday = unixtime(parse_date(date))
- local startday = endday - 60*60*24*(days-1)
- while startday <= endday
- do
- wday = daystring(startday)
- if data[wday] ~= nil
- then
- sum = sum + data[wday]
- wdays = wdays + 1
- end
- startday = startday + 60*60*24
- end
- if wdays == 0
- then
- return "nan"
- else
- return tostring(round(sum/wdays))
- end
-end
-function read_data(file)
- local data = {}
- local date
- local startdate
- local enddate
- local dat
- local firstline = true
- for line in io.lines(file)
- do
- if string.match(line, "date")
- then
- else
- date, dat = string.match(line, "(%d%d%d%d%-%d%d%-%d%d)%s+(%S+)")
- if firstline == true
- then
- startdate = date
- firstline = false
- end
- if dat ~= "nan" and dat ~= "{}" and dat ~= ""
- then
- data[date] = dat
- end
- end
- end
- enddate = date
- return data,startdate,enddate
-end
-function write_avg_file(data,file,startdate,enddate)
- local sdate
- local edate
- local wday
- sdate = unixtime(parse_date(startdate))
- edate = unixtime(parse_date(enddate))
- outfile = assert(io.open(file, "w"))
- outfile:write("date value avg07 avg14 avg30 avg60 avg90")
- while sdate <= edate+7200
- do
- wday = daystring(sdate)
- if data[wday] ~= nil
- then
- outfile:write("\n" .. wday .. " "
- .. ptd(data[wday]) .. " "
- .. ptd(calc_avg(data,wday,7)) .. " "
- .. ptd(calc_avg(data,wday,14)) .. " "
- .. ptd(calc_avg(data,wday,30)) .. " "
- .. ptd(calc_avg(data,wday,60)) .. " "
- .. ptd(calc_avg(data,wday,90)))
- end
- sdate = sdate + 60*60*24
- end
- outfile:close()
-end
-do
- local newarg = {}
- local i, limit = 1, #arg
- while (i <= limit) do
- if arg[i] == "-i" then
- infile = arg[i+1]
- i = i + 1
- elseif arg[i] == "-o" then
- outfile = arg[i+1]
- i = i + 1
- elseif arg[i] == "-s" then
- startdate = arg[i+1]
- i = i + 1
- elseif arg[i] == "-e" then
- enddate = arg[i+1]
- i = i + 1
- elseif arg[i] == "-c" then
- columns = arg[i+1]
- i = i + 1
- elseif arg[i] == "-m" then
- mode = arg[i+1]
- i = i + 1
- elseif arg[i] == "-v" then
- pversion()
- elseif arg[i] == "-h" then
- phelp()
- else
- newarg[#newarg+1] = arg[i]
- end
- i = i + 1
- end
- arg = newarg
-end
-if mode == "average"
-then
- local startd
- local endd
-
- print("set mode to " .. mode)
- print("reading data file " .. infile)
- data,startd,endd = read_data(infile)
- if startdate ~= ""
- then
- startd = startdate
- end
- if enddate ~= ""
- then
- endd = enddate
- end
- print("writing data file " .. outfile)
- write_avg_file(data,outfile,startd,endd)
- os.exit(0)
-end
-if mode == "compose"
-then
- local row = 0
- local column = 0
- local ofile
- local cols
-
- print("set mode to " .. mode)
- print("reading data file " .. infile)
- for line in io.lines(infile)
- do
- row = row + 1
- data[row] = {}
- column = 0
- for value in string.gmatch(line, "%S+")
- do
- column = column + 1
- data[row][column] = value
- end
- end
- cols = assert(load("return table.concat({"..columns:gsub("%d+","(...)[%0]").."},' ')"))
- ofile = assert(io.open(outfile, "w"))
- print("writing data file " .. outfile)
- for irow = 1,row
- do
- if irow == row
- then
- ofile:write(cols(data[irow]))
- else
- ofile:write(cols(data[irow]).."\n")
- end
- end
- ofile:close()
- os.exit(0)
-end
-if mode == "cut"
-then
- local ofile
- local date
- local sdate
- local edate
- local cdate
-
- check_date(startdate)
- check_date(enddate)
- sdate = unixtime(parse_date(startdate))
- edate = unixtime(parse_date(enddate))
- print("set mode to " .. mode)
- print("reading data file " .. infile)
- print("writing data file " .. outfile)
- ofile = assert(io.open(outfile, "w"))
- for line in io.lines(infile)
- do
- if string.match(line, "date")
- then
- ofile:write(line)
- else
- date = parse_dateinline(line)
- cdate = unixtime(parse_date(date))
- if cdate >= sdate and cdate <= edate
- then
- ofile:write("\n" .. line)
- end
- end
- end
- ofile:close()
- os.exit(0)
-end
-if mode == "*"
-then
- io.stderr:write ("Error 11: no mode specified!")
- os.exit(11)
-else
- io.stderr:write ("Error 12: invalid mode " .. mode)
- os.exit(12)
-end
diff --git a/Build/source/texk/texlive/linked_scripts/dosepsbin/dosepsbin.pl b/Build/source/texk/texlive/linked_scripts/dosepsbin/dosepsbin.pl
deleted file mode 100755
index 41b72991fc3..00000000000
--- a/Build/source/texk/texlive/linked_scripts/dosepsbin/dosepsbin.pl
+++ /dev/null
@@ -1,457 +0,0 @@
-#!/usr/bin/env perl
-#
-use strict;
-$^W=1;
-
-my $prj = 'dosepsbin';
-my $version = '1.2';
-my $date = '2012/03/22';
-my $author = 'Heiko Oberdiek';
-my $copyright = "Copyright 2011-2012 $author";
-
-my $verbose = 0;
-my $quiet = 0;
-my $inputfile = '';
-my $file_eps = '';
-my $file_wmf= '';
-my $file_tiff = '';
-my $buf_size = 0x1000000;
-
-my $title = "\U$prj\E $date v$version, $copyright\n";
-
-sub die_error ($;$) {
- my $msg = shift;
- $msg = "\n!!! Error: $msg!\n";
- if (@_) {
- my $ref = shift;
- foreach my $key (sort keys %$ref) {
- my $value = $$ref{$key};
- $key =~ s/ /_/g;
- $key =~ s/^\d+_?//;
- $msg .= " [$key: $value]\n";
- }
- }
- die $msg;
-}
-
-sub warning ($) {
- my $msg = shift;
- print "!!! Warning: $msg!\n";
-}
-
-sub verbose (@) {
- return unless $verbose;
- my @msg = @_;
- print "* @msg\n";
-}
-
-sub verbose_kv ($$) {
- return unless $verbose;
- my $key = shift;
- my $value = shift;
- $key =~ s/ /_/g;
- print " [$key: $value]\n";
-}
-
-sub die_usage {
- my $msg = $_[0];
- pod2usage(
- -exitstatus => 2,
- -msg => "\n==> $msg!\n");
-}
-
-use Getopt::Long;
-use Pod::Usage;
-
-GetOptions(
- 'verbose' => sub {
- $verbose = 1;
- $quiet = 0;
- },
- 'quiet' => sub {
- $quiet = 1;
- $verbose = 0;
- },
- 'help|?' => sub {
- print $title;
- pod2usage(1);
- },
- 'man' => sub {
- pod2usage(-exitstatus => 0, -verbose => 2);
- },
- 'version' => sub {
- print "$prj $date v$version\n";
- exit(0);
- },
- 'inputfile=s' => \$inputfile,
- 'eps-file=s' => \$file_eps,
- 'wmf-file=s' => \$file_wmf,
- 'tiff-file=s' => \$file_tiff,
-) or die_usage('Unknown option');
-
-print $title unless $quiet;
-
-verbose_kv 'program name', $0;
-verbose_kv 'osname', $^O;
-verbose_kv 'perl version', $^V ? sprintf('v%vd', $^V) : $];
-
-$inputfile = shift @ARGV if not $inputfile and @ARGV;
-$inputfile or die_error "Missing input file";
-
-# If input file does not exist, try with extension ".eps"
-if (not -f $inputfile) {
- my $file = "$inputfile.eps";
- $inputfile = $file if -f $file;
-}
--f $inputfile or
- die_error "Input file not found", {
- 'input file' => $inputfile
- };
-verbose_kv 'input file', $inputfile;
-
-# Get file size of input file
-my @tmp = stat $inputfile;
-@tmp or die_error "Getting size of Input file `$inputfile' failed";
-my $inputfile_size = $tmp[7];
-$inputfile_size > 30 or
- die_error "Input file size is too small", {
- '1 input file' => $inputfile,
- '2 file size' => $inputfile_size,
- };
-verbose_kv 'input file size', $inputfile_size;
-
-# Open input file
-open(IN, '<', $inputfile) or # die_error "Input file `$inputfile' not found";
- die_error "Cannot open input file", {
- '1 input file' => $inputfile,
- '2 os error' => $!,
- };
-binmode(IN);
-
-# Read header
-my $header;
-read IN, $header, 30 or
- die_error "Reading the header of the input file failed", {
- 'file' => $inputfile,
- 'os error' => $!,
- };
-# Check ASCII PS header
-if ('%!' eq substr $header, 0, 2) {
- $header =~ m/^(%![A-Za-z0-9\.\- \t]+)/;
- my $first_line = $1;
- die_error "Input file seems to be an ASCII PostScript file", {
- '1 input file' => $inputfile,
- '2 file header' => $first_line,
- }
-}
-my ($id,
- $offset_ps, $length_ps,
- $offset_wmf, $length_wmf,
- $offset_tiff, $length_tiff,
- $checksum) = unpack 'NV6n', $header;
-
-my $id_hex = unpack 'H8', pack 'N', $id;
-$id_hex = "0x\U$id_hex\E";
-verbose_kv 'header id', $id_hex;
-$id eq 0xC5D0D3C6 or
- die_error "Input file is not a `DOS EPS binary file'", {
- '1 input file' => $inputfile,
- '2 file header id' => $id_hex,
- };
-
-# Check checksum
-if ($checksum == 0xFFFF) {
- verbose_kv 'checksum', '0xFFFF (ignored)';
-}
-else {
- my $cs = 0;
- map { $cs ^= $_ } unpack 'n14', $header;
- if ($cs != $checksum) {
- my $cs_hex = unpack 'H4', pack 'n', $cs;
- $cs_hex = "0x\U$cs_hex\E";
- my $cs_found = unpack 'H4', pack 'n', $checksum;
- $cs_found = "0x\U$cs_found\E";
- die_error "Checksum mismatch", {
- '1 input file' => $inputfile,
- '2 checksum found' => $cs_found,
- '3 checksum expected' => $cs_hex,
- };
- }
-}
-
-verbose_kv 'offset of PS section', $offset_ps;
-verbose_kv 'length of PS section', $length_ps;
-verbose_kv 'offset of WMF section', $offset_wmf;
-verbose_kv 'length of WMF section', $length_wmf;
-verbose_kv 'offset of TIFF section', $offset_tiff;
-verbose_kv 'length of TIFF section', $length_tiff;
-
-{
- my %check_positions;
- sub check_section ($$$) {
- my $type = shift;
- my $ref_off = shift;
- my $ref_len = shift;
- if ($$ref_off == 0 and $$ref_len == 0) {
- print "--> $type section is not available.\n" unless $quiet;
- return '<not present>';
- }
- $$ref_off >= 30 and $$ref_off < $inputfile_size or
- die_error "Invalid offset of PS section", {
- '1 input file' => $inputfile,
- "2 offset of $type section" => $$ref_off,
- "3 length of $type section" => $$ref_len,
- };
- $$ref_len >= 0 and $$ref_off + $$ref_len <= $inputfile_size or
- die_error "Invalid length of PS section", {
- '1 input file' => $inputfile,
- "2 offset of $type section" => $$ref_off,
- "3 length of $type section" => $$ref_len,
- };
- $check_positions{$$ref_off} = $$ref_off + $$ref_len;
- print "--> $type section with $$ref_len bytes.\n" unless $quiet;
- return sprintf '%d..%d', $$ref_off, $$ref_off + $$ref_len - 1;
- }
- my $sec_ps = check_section 'PS', \$offset_ps, \$length_ps;
- verbose_kv 'position of PS section', $sec_ps;
- my $sec_wmf = check_section 'WMF', \$offset_wmf, \$length_wmf;
- verbose_kv 'position of WMF section', $sec_wmf;
- my $sec_tiff = check_section 'TIFF', \$offset_tiff, \$length_tiff;
- verbose_kv 'position of TIFF section', $sec_tiff;
- my $pos = 30;
- foreach my $beg (sort keys %check_positions) {
- $check_positions{$beg} >= $pos or
- die_error "Section overlap detected", {
- '1 input file' => $inputfile,
- '2 position of header' => "0..29",
- '3 position of PS section' => $sec_ps,
- '4 position of WMF section' => $sec_wmf,
- '5 position of TIFF section' => $sec_tiff,
- };
- }
-}
-
-sub write_file ($$$$) {
- my $type = shift;
- my $file = shift;
- my $off = shift;
- my $len = shift;
- my $org_len = $len;
- return unless $file;
- verbose_kv "$type file", $file;
- if ($off <= 0 or $len <= 0) {
- warning "No $type section found";
- return;
- }
- my $position = $off;
- seek IN, $off, 0 or
- die_error "Moving to $type section offset failed", {
- '1 input file' => $inputfile,
- '2 position' => $off,
- '3 os error' => $!,
- };
- open(OUT, '>', $file) or
- die_error "Opening $type file for writing failed", {
- "1 $type file" => $file,
- '2 os error' => $!,
- };
- binmode(OUT);
- while ($len > 0) {
- my $read_len = ($len > $buf_size) ? $buf_size : $len;
- my $buf;
- my $read_count = read IN, $buf, $read_len;
- $read_count > 0 or
- die_error "Reading file failed", {
- '1 input file' => $inputfile,
- "2 $type file" => $file,
- '3 offset' => $position,
- '4 length' => $read_len,
- '5 os error' => $!,
- };
- $position += $read_count;
- print OUT $buf or
- die_error "Writing $type file failed", {
- "1 $type file" => $file,
- '2 offset' => $org_len - $len,
- '3 length' => $read_count,
- '4 os error' => $!,
- };
- $len -= $read_count;
- }
- close(OUT);
- print "==> $type file written: [$file]\n" unless $quiet;
-}
-
-write_file 'TIFF', $file_tiff, $offset_tiff, $length_tiff;
-write_file 'WMF', $file_wmf, $offset_wmf, $length_wmf;
-write_file 'EPS', $file_eps, $offset_ps, $length_ps;
-
-close(IN);
-
-1;
-
-__DATA__
-
-=head1 NAME
-
-dosepsbin -- Extract PS/WMF/TIFF sections from DOS EPS binary files
-
-=head1 VERSION
-
-2012-03-22 v1.2
-
-=head1 SYNOPSIS
-
-The progam B<dosepsbin> analyses an EPS file that is not
-a plain ASCII PostScript file but given as DOS EPS binary file.
-
- dosepsbin [options] <input file>
-
-First it analyzes the I<input file>, validates its header
-and summarizes the available sections. Depending on the
-given options, the sections are then written to files.
-
-Options:
-
- --eps-file <file> Write PS section to <file>.
- --wmf-file <file> Write WMF section to <file>.
- --tiff-file <file> Write TIFF section to <file>.
- --inputfile <file> The name of the input file.
- --verbose Verbose output.
- --quiet Only errors and warnings are printed.
- --help Brief help message.
- --man Full documentation.
- --version Print version identification.
-
-The files for output must be different from the input file.
-
-=head1 DESCRIPTION
-
-=head2 DOS EPS Binary File Format
-
-A Encapsulated PostScript (EPS) file can also given in a special
-binary format to support the inclusion of a thumbnail. The file
-format starts with a binary header that contains the positions of
-the possible sections:
-
-=over
-
-=item * Postscript (PS)
-
-=item * Windows Metafile Format (WMF)
-
-=item * Tag Image File Format (TIFF)
-
-=back
-
-The PS section must be present and either the WMF file or the TIFF
-file should be given.
-
-=head1 OPTIONS
-
-=over
-
-=item B<->B<-eps-file>=<I<file>>
-
-The PS section is written to <I<file>>. The output file must
-be different from the input file.
-
-=item B<->B<-wmf-file>=<I<file>>
-
-The WMF section is written to <I<file>> if present. The output
-file must be different from the input file.
-
-=item B<->B<-tiff-file>=<I<file>>
-
-The TIFF section is written to <I<file>> if present. The output
-file must be different from the input file.
-
-=item B<->B<-inputfile>=<I<file>>
-
-The input file can also be given directly on the command line.
-If the file does not exist, then the file with extension `.eps'
-is tried.
-
-=item B<->B<-verbose>
-
-Verbose messages.
-
-=item B<->B<-quiet>
-
-No messages are printed except for errors and warnings.
-
-=item B<->B<-help>
-
-Display help screen.
-
-=item B<->B<-man>
-
-Prints manual page.
-
-=item B<->B<-version>
-
-Print version identification and exit.
-
-=back
-
-=head1 EXAMPLES
-
-The following command extracts the PS section from file F<test.eps>
-and stores the result in file F<test-ps.eps>:
-
- dosepsbin --eps-file test-ps.eps test.eps
-
-=head1 AUTHOR
-
-Heiko Oberdiek, email: heiko.oberdiek at googlemail.com
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2011-2012 by Heiko Oberdiek.
-
-This library is free software; you may redistribute it and/or
-modify it under the same terms as Perl itself
-(Perl Artistic License/GNU General Public License, version 2).
-
-=head1 SEE ALSO
-
-The DOS EPS binary file format is described
-in section "5.2 Windows Metafile or TIFF":
-
- Adobe Developer Support,
- Encapsulated PostScript File Format Specification,
- Version 3.0,
- 1992-05-01,
- http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf
-
-=head1 HISTORY
-
-=over 2
-
-=item B<2011/11/10 v1.0>
-
-=over 2
-
-=item * First version.
-
-=back
-
-=item B<2011/12/05 v1.1>
-
-=over 2
-
-=item * Typo fixed in help text (thanks Peter Breitenlohner).
-
-=back
-
-=item B<2012/03/22 v1.2>
-
-=over 2
-
-=item * Fix in validation test for offset of PS section.
-
-=back
-
-=back
-
-=cut
diff --git a/Build/source/texk/texlive/linked_scripts/dtxgen/dtxgen b/Build/source/texk/texlive/linked_scripts/dtxgen/dtxgen
deleted file mode 100755
index 9d9e91103e1..00000000000
--- a/Build/source/texk/texlive/linked_scripts/dtxgen/dtxgen
+++ /dev/null
@@ -1,462 +0,0 @@
-#!/bin/bash
-
-Version=1.08
-Myname="${0##*/}"
-
-:<<'DOC'
-= dtxgen - generate template for LaTeX self-extracting .dtx file
-
-= Synopsis
-dtxgen [options] basename.[sty,cls]
-
-== Options
--h,--help print short help and exit
--H,--Help print full documentation via less and exit
--V,--version print version and exit
--s,--short short, one-liner, package description
--d,--date initial version's date. Default: current date
--m,--mail your email address. Default: |$EMAIL|
--n,--name your name. Default: |$NAME|
--c,--class (class packs only) class to be preloaded. Default: article
--q,--quiet run quietly
-
-= Description
-dtxgen creates a template for a self-extracting .dtx file, based on the model described by
-[Joseph Wright](www.texdev.net/2009/10/06/a-model-dtx-file/). It is useful for
-those who plan to create a new Documented LaTeX Source (.dtx) file.
-
-Usage example:
-
- dtxgen -n 'your name' -m 'your@email.ad' myclass.cls
-
-The script takes some variables such as:
-- name and email address of the author,
-- a short description of the class or package generated from the .dtx file,
-- a date
-from environment variables, or from command line options and generates,
-among more, a template for the .dtx file with some minimal examples. Of
-course, the user will have to replace those examples with the real work,
-but the dates, basename, author's name and email address are already in
-place and, depending on whether you use used a .cls or a .sty extension
-in the argument, it is formatted to be either a class or a package
-source file.
-
-If you have an environment with your name and email address defined in
-NAME and EMAIL, you could simply type:
-
- dtxgen myclass.cls
-
-and you would end up with five files: |myclass.dtx|, |myclass.cls|,
-|myclass.pdf|, |README|, and |Makefile|.
-
-= Options
-dtxgen recognizes the following options:
-
--s,--short=...
- A short, one-liner, description for the class or package.
- By default, the string /A new LaTeX class/ or /A new LaTeX package/
- will be used.
--n,--name=...
- Your name (first name, followed by surname). Alternatively,
- you can set a default value in the environment variable |NAME|;
- if you do so and still use this option, the option's value wills
- have priority.
--m,--mail=...
- Your email address. Alternatively, you can set a default value ins
- the environment variable |EMAIL|; if you do so and still use this
- option, the option's value will have priority.
--c,--class=...
- For class templates only: inserts a |\LoadClass{...}|, so that the
- new class will start with the properties of the |...| class.
- The default is |article|.
--d,--date=...
- Set the initial version's date. By default, the current date will
- be used. The date should be entered in the |yyyymmdd| format,
- although it will be stored the LaTeX way: |yyyy/mm/dd|.
--q,--quiet
- Run quietly
--V,--version
- Prints the script's version and exits.
--h,--help
- Prints help information and exits.
--H,--Help
- print full documentation via less and exit
-
-= Makefile
-The |Makefile| can be used to compile new versions of your work; it contains the following targets:
-
-all (the default) generate the style or class file, the pdf-documentation,
- and a README file.
-distclean remove all files that can be regenerated,
-clean same, except the style or class file, the pdf-documentation,
- and a README file.
-inst install in the user's TeX tree,
-install install in the local TeX tree (uses sudo)
-zip produce a zip file ready for upload to CTAN
-
-= Author
-[Wybo Dekker](wybo@dekkerdocumenten.nl)
-
-= Copyright
-Released under the [GNU General Public License](www.gnu.org/copyleft/gpl.html)
-DOC
-
-# check executables and versions of bash and getopt
-((BASH_VERSINFO>=4)) || die "Need bash version >= 4"
-for i in getopt make; do
- command -v "$i" &> /dev/null || die "$i: command not found"
-done
-i=$(getopt -T)
-{ (($?==4)) && [[ -z $i ]]; } || die "Your getopt is not GNU"
-
-# using the label in arg 2, read template from my self, filter it
-# through the script in arg 1, and write the output to the file in arg 3.
-# The default for arg 3 is arg 2
-function createfile {
- file=$3
- test "$file" = "" && file=$2
- sed -n "/^:<<'$2'/,/^$2/p" "$0" |tail -n +2 |head -n -1 |sed "$1" >"$file"
-}
-
-REd='\e[38;5;9m'
- die() { local i; for i; do echo -e "$Myname: $REd$i"; done 1>&2; exit 1; }
-helpsrt() { sed -n '/^= Synopsis/,/^= /p' "$0"|sed '1d;$d'; exit; }
-instscr() { instscript --zip --pdf "$Myname"; exit; }
-
-# shellcheck disable=SC2154
-helpall() { sed -n "/^:<<'DOC'$/,/^DOC/p" "$0"|sed -n '1d;$d;p'|
- less -Ps"$Myname-${Version/./·} documentation - type h for help, q to quit."
- exit
- }
-
-if ! options=$(getopt \
- -n "$Myname" \
- -o s:n:m:c:d:hHVqI \
- -l short:,name:,mail:,class:,date:,help,Help,version,quiet -- "$@"
-); then exit 1; fi
-eval set -- "$options"
-
-while [ $# -gt 0 ]; do
- case $1 in
- (-h|--help) # print short help and exit
- helpsrt
- ;;
- (-H|--Help) # print full documentation via less and exit
- helpall
- ;;
- (-V|--version) # print version and exit
- echo $Version
- exit
- ;;
- (-s|--short) # short, one-liner, package description
- short=$2
- shift 2
- ;;
- (-d|--date) # initial version's date. Default: current date
- date=$2
- shift 2
- ;;
- (-m|--mail) # your email address. Default: $EMAIL
- mail=$2
- shift 2
- ;;
- (-n|--name) # your name. Default: $NAME
- name=$2
- shift 2
- ;;
- (-c|--class) # (class packs only) class to be preloaded. Default: article
- loadclass=$2
- shift 2
- ;;
- (-q|--quiet) # run quietly
- quiet=--quiet
- shift
- ;;
- (-I) instscr
- ;;
- (--) shift
- break
- ;;
- (*) break
- ;;
- esac
-done
-
-export year typ Typ lcl use # used in templates - shellcheck se them as unused
-
-name=${name:-${NAME:-(not set)}}
-mail=${mail:-${EMAIL:-(not set)}}
-date=${date:-$(date +%Y%m%d)}
-year=${date:0:4}
-loadclass=${loadclass:-article}
-
-# date must be 8 digits; insert the two /'s:
-if [[ ! $date =~ ^[[:digit:]]{8}$ ]]; then die "illegal date"; fi
-date=$(sed 's/\(....\)\(..\)\(..\)/\1\\\/\2\\\/\3/' <<<"$date")
-
-# argument must have .cls or .sty extension:
-base=${1%.*}
-ext=${1#*.}
-
-case "$ext" in
-(cls) typ=class; Typ=Class;
- short=${short:-A new LaTeX class}
- lcl='\\LoadClass[a4paper,fleqn]{'"$loadclass}"
- ;;
-(sty) typ=package; Typ=Package;
- short=${short:-A new LaTeX package}
- use='\\usepackage{\\jobname}'
- ;;
-(*) die "The argument must have .cls or .sty extension
- (try the --help option)"
-esac
-
-# The short description may contain TeX commands, but then we need
-# a version without them at some places; note that this removes only
-# simple contructs:
-shrt=$(sed 's/\\[[:alpha:]]\\+{\\([^}]*\\)}/\\1/g;s/\\//g' <<<"$short")
-
-# Any \'s in the short description need to be duplicated for the script:
-short="${short//\\/\\\\}"
-
-test -z "$mail" && die "author's email not set - use option or environment variable EMAIL"
-test -z "$name" && die "author's name not set - use option or environment variable NAME"
-
-colw=${#base}
-(( colw = colw < 7 ? 7 : colw ))
-kopl="$(eval "printf '%.0s-' {1..$colw}")"
-kopr="$(eval "printf '%.0s-' {1..$((72-colw))}")"
-declare -A rm=(
- [$kopl]=$kopr
- [$base]=$shrt
- [Author]=$name
- [E-mail]=$mail
- [License]='Released under the LaTeX Project Public License v1.3c or later'
- [See]='http://www.latex-project.org/lppl.txt'
-)
-
-for i in $kopl $base Author E-mail License See; do
- readme+="$(printf "%*s:| %s\\\\n" $colw "$i" "${rm[$i]}")"
-done
-
-# make sed script replacing the variables in the templates:
-sedscript=''
-for i in base year ext mail use typ Typ name date short shrt lcl readme; do
- test $quiet || eval "echo -e \"$i \$$i\""|sed 's/\\\\/\\/g'
- eval "sedscript+=\"s=%$i%=\$$i=g;\""
-done
-
-createfile "$sedscript" Makefile
-createfile "$sedscript" DTX "$base.dtx"
-make $quiet
-exit 0
-
-# ---- TEMPLATES: ----
-:<<'Makefile'
-NAME = %base%
-SHELL = bash
-PWD = $(shell pwd)
-VERS = $(shell ltxfileinfo -v $(NAME).dtx|sed -e 's/^v//')
-LOCAL = $(shell kpsewhich --var-value TEXMFLOCAL)
-UTREE = $(shell kpsewhich --var-value TEXMFHOME)
-all: $(NAME).pdf
- test -e README.txt && mv README.txt README || exit 0
-$(NAME).pdf: $(NAME).dtx
- pdflatex -shell-escape -recorder -interaction=batchmode $(NAME).dtx >/dev/null
- if [ -f $(NAME).glo ]; then makeindex -q -s gglo.ist -o $(NAME).gls $(NAME).glo; fi
- if [ -f $(NAME).idx ]; then makeindex -q -s gind.ist -o $(NAME).ind $(NAME).idx; fi
- pdflatex --recorder --interaction=nonstopmode $(NAME).dtx > /dev/null
- pdflatex --recorder --interaction=nonstopmode $(NAME).dtx > /dev/null
-clean:
- rm -f $(NAME).{aux,fls,glo,gls,hd,idx,ilg,ind,ins,log,out}
-distclean: clean
- rm -f $(NAME).{pdf,%ext%} README
-inst: all
- mkdir -p $(UTREE)/{tex,source,doc}/latex/$(NAME)
- cp $(NAME).dtx $(UTREE)/source/latex/$(NAME)
- cp $(NAME).%ext% $(UTREE)/tex/latex/$(NAME)
- cp $(NAME).pdf $(UTREE)/doc/latex/$(NAME)
-install: all
- sudo mkdir -p $(LOCAL)/{tex,source,doc}/latex/$(NAME)
- sudo cp $(NAME).dtx $(LOCAL)/source/latex/$(NAME)
- sudo cp $(NAME).%ext% $(LOCAL)/tex/latex/$(NAME)
- sudo cp $(NAME).pdf $(LOCAL)/doc/latex/$(NAME)
-zip: all
- ln -sf . $(NAME)
- zip -Drq $(PWD)/$(NAME)-$(VERS).zip $(NAME)/{README,$(NAME).{pdf,dtx}}
- rm $(NAME)
-Makefile
-
-:<<'DTX'
-% \iffalse meta-comment
-% vim: textwidth=75
-%<*internal>
-\iffalse
-%</internal>
-%<*readme>
-|
-%readme%
-
-Short description:
-Some text about the %typ%: probably the same as the abstract.
-%</readme>
-%<*internal>
-\fi
-\def\nameofplainTeX{plain}
-\ifx\fmtname\nameofplainTeX\else
- \expandafter\begingroup
-\fi
-%</internal>
-%<*install>
-\input docstrip.tex
-\keepsilent
-\askforoverwritefalse
-\preamble
-%readme%
-\endpreamble
-\postamble
-
-Copyright (C) %year% by %name% <%mail%>
-
-This work may be distributed and/or modified under the
-conditions of the LaTeX Project Public License (LPPL), either
-version 1.3c of this license or (at your option) any later
-version. The latest version of this license is in the file:
-
-http://www.latex-project.org/lppl.txt
-
-This work is "maintained" (as per LPPL maintenance status) by
-%name%.
-
-This work consists of the file %base%.dtx and a Makefile.
-Running "make" generates the derived files README, %base%.pdf and %base%.%ext%.
-Running "make inst" installs the files in the user's TeX tree.
-Running "make install" installs the files in the local TeX tree.
-
-\endpostamble
-
-\usedir{tex/latex/%base%}
-\generate{
- \file{\jobname.%ext%}{\from{\jobname.dtx}{%typ%}}
-}
-%</install>
-%<install>\endbatchfile
-%<*internal>
-\usedir{source/latex/%base%}
-\generate{
- \file{\jobname.ins}{\from{\jobname.dtx}{install}}
-}
-\nopreamble\nopostamble
-\usedir{doc/latex/%base%}
-\generate{
- \file{README.txt}{\from{\jobname.dtx}{readme}}
-}
-\ifx\fmtname\nameofplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
-%</internal>
-% \fi
-%
-% \iffalse
-%<*driver>
-\ProvidesFile{%base%.dtx}
-%</driver>
-%<%typ%>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
-%<%typ%>\Provides%Typ%{%base%}
-%<*%typ%>
- [%date% v1.00 %shrt%]
-%</%typ%>
-%<*driver>
-\documentclass{ltxdoc}
-\usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry}
-\usepackage[numbered]{hypdoc}
-%use%
-\EnableCrossrefs
-\CodelineIndex
-\RecordChanges
-\begin{document}
- \DocInput{\jobname.dtx}
-\end{document}
-%</driver>
-% \fi
-%
-% \GetFileInfo{\jobname.dtx}
-% \DoNotIndex{\newcommand,\newenvironment}
-%
-%\title{\textsf{%base%} --- %short%\thanks{This file
-% describes version \fileversion, last revised \filedate.}
-%}
-%\author{%name%\thanks{E-mail: %mail%}}
-%\date{Released \filedate}
-%
-%\maketitle
-%
-%\changes{v1.00}{%date%}{First public release}
-%
-% \begin{abstract}
-% ==== Put abstract text here. ====
-% \end{abstract}
-%
-% \section{Usage}
-%
-% ==== Put descriptive text here. ====
-%
-% \DescribeMacro{\dummyMacro}
-% This macro does nothing.\index{doing nothing|usage} It is merely an
-% example. If this were a real macro, you would put a paragraph here
-% describing what the macro is supposed to do, what its mandatory and
-% optional arguments are, and so forth.
-%
-% \DescribeEnv{dummyEnv}
-% This environment does nothing. It is merely an example.
-% If this were a real environment, you would put a paragraph here
-% describing what the environment is supposed to do, what its
-% mandatory and optional arguments are, and so forth.
-%
-%\StopEventually{^^A
-% \PrintChanges
-% \PrintIndex
-%}
-%
-% \section{Implementation}
-%
-% \begin{macrocode}
-%<*%typ%>
-%lcl%
-% \end{macrocode}
-% \begin{macro}{\dummyMacro}
-% This is a dummy macro. If it did anything, we'd describe its
-% implementation here.
-% \begin{macrocode}
-\newcommand{\dummyMacro}{}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{environment}{dummyEnv}
-% This is a dummy environment. If it did anything, we'd describe its
-% implementation here.
-% \begin{macrocode}
-\newenvironment{dummyEnv}{%
-}{%
-% \end{macrocode}
-% \changes{v1.00a}{%date%}{Added a spurious change log entry to
-% show what a change \emph{within} an environment definition looks
-% like.}
-% Don't use |%| to introduce a code comment within a |macrocode|
-% environment. Instead, you should typeset all of your comments with
-% LaTeX---doing so gives much prettier results. For comments within a
-% macro/environment body, just do an |\end{macrocode}|, include some
-% commentary, and do another |\begin{macrocode}|. It's that simple.
-% \begin{macrocode}
-}
-% \end{macrocode}
-% \end{environment}
-%
-% \begin{macrocode}
-\endinput
-%</%typ%>
-% \end{macrocode}
-%\Finale
-DTX
diff --git a/Build/source/texk/texlive/linked_scripts/dviasm/dviasm.py b/Build/source/texk/texlive/linked_scripts/dviasm/dviasm.py
deleted file mode 100755
index 2e7fc34d6f9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/dviasm/dviasm.py
+++ /dev/null
@@ -1,1259 +0,0 @@
-#! /usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# This is DVIasm, a DVI utility for editing DVI files directly.
-#
-# Copyright (C) 2007-2008 by Jin-Hwan Cho <chofchof@ktug.or.kr>
-# Copyright (C) 2011-2017 by Khaled Hosny <khaledhosny@eglug.org>
-# Copyright (C) 2019 by Arthur Reutenauer <arthur@reutenauer.eu>
-# Copyright (C) 2019-2020 by Hironobu Yamashita <h.y.acetaminophen@gmail.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import sys, os.path
-from optparse import OptionParser
-
-# Global variables
-is_ptex = False
-is_subfont = False
-cur_font = None
-cur_dsize = 0
-cur_ssize = 0
-subfont_idx = 0
-subfont_list = ['cyberb', 'outbtm', 'outbtb', 'outgtm', 'outgtb']
-
-# DVI opcodes
-SET_CHAR_0 = 0; SET_CHAR_127 = 127;
-SET1 = 128; SET2 = 129; SET3 = 130; SET4 = 131;
-SET_RULE = 132;
-PUT1 = 133; PUT2 = 134; PUT3 = 135; PUT4 = 136;
-PUT_RULE = 137;
-NOP = 138;
-BOP = 139; EOP = 140;
-PUSH = 141; POP = 142;
-RIGHT1 = 143; RIGHT2 = 144; RIGHT3 = 145; RIGHT4 = 146;
-W0 = 147; W1 = 148; W2 = 149; W3 = 150; W4 = 151;
-X0 = 152; X1 = 153; X2 = 154; X3 = 155; X4 = 156;
-DOWN1 = 157; DOWN2 = 158; DOWN3 = 159; DOWN4 = 160;
-Y0 = 161; Y1 = 162; Y2 = 163; Y3 = 164; Y4 = 165;
-Z0 = 166; Z1 = 167; Z2 = 168; Z3 = 169; Z4 = 170;
-FNT_NUM_0 = 171; FNT_NUM_63 = 234;
-FNT1 = 235; FNT2 = 236; FNT3 = 237; FNT4 = 238;
-XXX1 = 239; XXX2 = 240; XXX3 = 241; XXX4 = 242;
-FNT_DEF1 = 243; FNT_DEF2 = 244; FNT_DEF3 = 245; FNT_DEF4 = 246;
-PRE = 247; POST = 248; POST_POST = 249;
-# DVIV opcodes
-DIR = 255;
-# DVI-IVD opcodes
-BEGIN_REFLECT = 250; END_REFLECT = 251;
-# XDV opcodes
-NATIVE_FONT_DEF = 252;
-GLYPHS = 253;
-TEXT_GLYPHS = 254;
-# XDV flags
-XDV_FLAG_VERTICAL = 0x0100;
-XDV_FLAG_COLORED = 0x0200;
-XDV_FLAG_EXTEND = 0x1000;
-XDV_FLAG_SLANT = 0x2000;
-XDV_FLAG_EMBOLDEN = 0x4000;
-# DVI identifications
-DVI_ID = 2; DVIV_ID = 3; XDVI_ID = 6; XDV_ID = 7;
-DVI_IDS = (DVI_ID, DVIV_ID, XDVI_ID, XDV_ID)
-
-def warning(msg):
- sys.stderr.write('%s\n' % msg)
-
-def ValidID(dvi_id):
- if dvi_id not in DVI_IDS:
- return False
- return True
-
-def BadDVI(msg):
- raise AttributeError('Bad DVI file: %s!' % msg)
-
-def GetByte(fp): # { returns the next byte, unsigned }
- try: return ord(fp.read(1))
- except: return -1
-
-def SignedByte(fp): # { returns the next byte, signed }
- try: b = ord(fp.read(1))
- except: return -1
- if b < 128: return b
- else: return b - 256
-
-def Get2Bytes(fp): # { returns the next two bytes, unsigned }
- try: a, b = fp.read(2)
- except: BadDVI('Failed to Get2Bytes()')
- return (a << 8) + b
-
-def SignedPair(fp): # {returns the next two bytes, signed }
- try: a, b = fp.read(2)
- except: BadDVI('Failed to SignedPair()')
- if a < 128: return (a << 8) + b
- else: return ((a - 256) << 8) + b
-
-def Get3Bytes(fp): # { returns the next three bytes, unsigned }
- try: a, b, c = fp.read(3)
- except: BadDVI('Failed to Get3Bytes()')
- return (((a << 8) + b) << 8) + c
-
-def SignedTrio(fp): # { returns the next three bytes, signed }
- try: a, b, c = fp.read(3)
- except: BadDVI('Failed to SignedTrio()')
- if a < 128: return (((a << 8) + b) << 8) + c
- else: return ((((a - 256) << 8) + b) << 8) + c
-
-def Get4Bytes(fp): # { returns the next four bytes, unsigned }
- try: a, b, c, d = fp.read(4)
- except: BadDVI('Failed to Get4Bytes()')
- return (((((a << 8) + b) << 8) + c) << 8) + d
-
-def SignedQuad(fp): # { returns the next four bytes, signed }
- try: a, b, c, d = fp.read(4)
- except: BadDVI('Failed to get SignedQuad()')
- if a < 128: return (((((a << 8) + b) << 8) + c) << 8) + d
- else: return ((((((a - 256) << 8) + b) << 8) + c) << 8) + d
-
-def PutByte(q):
- return bytes.fromhex('%02x' % (q & 0xff))
-
-def Put2Bytes(q):
- return PutByte(q>>8) + PutByte(q)
-
-def Put3Bytes(q):
- return PutByte(q>>16) + PutByte(q>>8) + PutByte(q)
-
-def PutSignedQuad(q):
- if q < 0: q += 0x100000000
- return PutByte(q>>24) + PutByte(q>>16) + PutByte(q>>8) + PutByte(q)
-
-def PutUnsigned(q):
- if q >= 0x1000000: return (3, PutSignedQuad(q))
- if q >= 0x10000: return (2, Put3Bytes(q))
- if q >= 0x100: return (1, Put2Bytes(q))
- return (0, PutByte(q))
-
-def PutSigned(q):
- if q < -0x800000 or q >= 0x800000: return (3, PutSignedQuad(q))
- if q >= 0x8000: return (2, Put3Bytes(q))
- if q < -0x8000: q += 0x1000000; return (2, Put3Bytes(q))
- if q >= 0x80: return (1, Put2Bytes(q))
- if q < -0x80: q += 0x10000; return (1, Put2Bytes(q))
- return (0, PutByte(q))
-
-def PutGlyphs(width, glyphs):
- s = []
- length = len(glyphs)
- s.append(PutSignedQuad(width))
- s.append(Put2Bytes(length))
- for glyph in glyphs:
- s.append(PutSignedQuad(glyph["x"]))
- s.append(PutSignedQuad(glyph["y"]))
- for glyph in glyphs:
- s.append(Put2Bytes(glyph["id"]))
-
- return b''.join(s)
-
-def PutTextGlyphs(text, width, glyphs):
- s = []
- length = len(text)
- s.append(Put2Bytes(length))
- for ch in text:
- s.append(Put2Bytes(ch))
- s.append(PutGlyphs(width, glyphs))
-
- return b''.join(s)
-
-def GetInt(s):
- try: return int(s)
- except: return -1
-
-def GetStrASCII(s): # used in Parse()
- if len(s) > 1 and ((s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"')):
- return [ord(c) for c in s[1:-1].decode('unicode_escape')]
- else: return ''
-
-def UCS2toJIS(c):
- try:
- s = c.encode('iso2022-jp')
- except UnicodeEncodeError:
- s = c.encode('raw_unicode_escape')
- if len(s) == 1: return ord(s)
- else: return (s[3] << 8) + s[4]
-
-def GetStrUTF8(s): # used in Parse()
- if len(s) > 1 and ((s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"')):
- t = s[1:-1].encode('raw_unicode_escape').decode('unicode_escape')
- if is_ptex: return [UCS2toJIS(c) for c in t]
- else: return [ord(c) for c in t]
- else: return ''
-
-def PutStrASCII(t): # used in Dump()
- s = ''
- for o in t:
- if o == 92: s += '\\\\'
- elif 32 <= o < 127: s += chr(o)
- elif o < 256: s += ('\\x%02x' % o)
- elif o < 65536: s += ('\\u%04x' % o)
- else:
- warning('Not support characters > 65535; may skip %d.\n' % o)
- return "'%s'" % s
-
-def PutStrLatin1(t): # used in Dump()
- s = ''
- for o in t:
- if o == 92: s += '\\\\'
- elif 32 <= o < 127 or 161 <= o < 256: s += chr(o)
- elif o < 256: s += ('\\x%02x' % o)
- elif o < 65536: s += ('\\u%04x' % o)
- else:
- warning('Not support characters > 65535; may skip %d.\n' % o)
- return "'%s'" % s
-
-def DecodeISO2022JP(c):
- try:
- s = bytes.fromhex("1b 24 42 %02x %02x" % (c//256, c%256)).decode('iso2022-jp')
- except UnicodeDecodeError:
- s = chr(c)
- return s
-
-def PutStrUTF8(t): # used in Dump()
- s = ''
- if is_subfont:
- for o in t:
- s += chr((subfont_idx << 8) + o)
- else: # not the case of subfont
- for o in t:
- if o == 92: s += '\\\\'
- elif 32 <= o < 127: s += chr(o)
- elif o < 128: s += ('\\x%02x' % o)
- elif is_ptex:
- s += DecodeISO2022JP(o)
- else: s += chr(o)
- return "'%s'" % s
-
-def IsFontChanged(f, z):
- global cur_font, cur_ssize, subfont_idx, is_subfont
- for n in subfont_list:
- if n == f[:-2]:
- is_subfont = True
- subfont_idx = int(f[-2:], 16)
- if cur_font == n and cur_ssize == z:
- return False
- else:
- cur_font = n; cur_ssize = z
- return True
- else:
- is_subfont = False
- cur_font = f; cur_ssize = z
- return True
-
-############################################################
-# DVI class
-############################################################
-class DVI(object):
- def __init__(self, unit='pt'):
- if unit == 'sp': self.byconv = self.by_sp_conv
- elif unit == 'bp': self.byconv = self.by_bp_conv
- elif unit == 'mm': self.byconv = self.by_mm_conv
- elif unit == 'cm': self.byconv = self.by_cm_conv
- elif unit == 'in': self.byconv = self.by_in_conv
- else: self.byconv = self.by_pt_conv
- self.Initialize()
-
- ##########################################################
- # Initialize: Required by __init__(), Load(), and Parse()
- ##########################################################
- def Initialize(self):
- self.id = DVI_ID
- self.numerator = 25400000
- self.denominator = 473628672
- self.mag = 1000
- self.ComputeConversionFactors()
- self.comment = ''
- self.font_def = {}
- self.max_v = self.max_h = self.max_s = self.total_pages = 0
- self.pages = []
-
- ##########################################################
- # Load: DVI -> Internal Format
- ##########################################################
- def Load(self, fn):
- fp = open(fn, 'rb')
- self.LoadFromFile(fp)
- fp.close()
-
- def LoadFromFile(self, fp):
- self.Initialize()
- fp.seek(0, 2)
- if fp.tell() < 53: BadDVI('less than 53 bytes long')
- self.ProcessPreamble(fp)
- self.ProcessPostamble(fp)
- loc = self.first_backpointer
- while loc >= 0:
- fp.seek(loc)
- if GetByte(fp) != BOP: BadDVI('byte %d is not bop' % fp.tell())
- cnt = [SignedQuad(fp) for i in range(10)]
- loc = SignedQuad(fp)
- page = self.ProcessPage(fp)
- self.pages.insert(0, {'count':cnt, 'content':page})
-
- def ProcessPreamble(self, fp):
- fp.seek(0)
- if GetByte(fp) != PRE: BadDVI("First byte isn't start of preamble")
- id = GetByte(fp)
- if not ValidID(id):
- warning("ID byte is %d; use the default %d!" % (id, DVI_ID))
- else:
- self.id = id
- numerator = SignedQuad(fp)
- if numerator <= 0:
- warning('numerator is %d; use the default 25400000!' % numerator)
- else:
- self.numerator = numerator
- denominator = SignedQuad(fp)
- if denominator <= 0:
- warning('denominator is %d; use the default 473628672!' % denominator)
- else:
- self.denominator = denominator
- mag = SignedQuad(fp)
- if mag <= 0:
- warning('magnification is %d; use the default 1000!' % mag)
- else:
- self.mag = mag
- self.comment = fp.read(GetByte(fp)).decode('utf8')
- self.ComputeConversionFactors()
-
- def ProcessPostamble(self, fp):
- fp.seek(-5, 2) # at least four 223's
- while True:
- k = GetByte(fp)
- if k < 0: BadDVI('all 223s; is it a DVI file?') # found EOF
- elif k != 223: break
- fp.seek(-2, 1)
- if not ValidID(k):
- warning('ID byte is %d' % k)
- fp.seek(-5, 1)
- q = SignedQuad(fp)
- m = fp.tell() # id_byte
- if q < 0 or q > m - 33: BadDVI('post pointer %d at byte %d' % (q, m - 4))
- fp.seek(q) # move to post
- k = GetByte(fp)
- if k != POST: BadDVI('byte %d is not post' % k)
- self.post_loc = q
- self.first_backpointer = SignedQuad(fp)
-
- if SignedQuad(fp) != self.numerator:
- warning("numerator doesn't match the preamble!")
- if SignedQuad(fp) != self.denominator:
- warning("denominator doesn't match the preamble!")
- if SignedQuad(fp) != self.mag:
- warning("magnification doesn't match the preamble!")
- self.max_v = SignedQuad(fp)
- self.max_h = SignedQuad(fp)
- self.max_s = Get2Bytes(fp)
- self.total_pages = Get2Bytes(fp)
- while True:
- k = GetByte(fp)
- if k == FNT_DEF1: p = GetByte(fp)
- elif k == FNT_DEF2: p = Get2Bytes(fp)
- elif k == FNT_DEF3: p = Get3Bytes(fp)
- elif k == FNT_DEF4: p = SignedQuad(fp)
- elif k == NATIVE_FONT_DEF: p = SignedQuad(fp)
- elif k != NOP: break
- if k == NATIVE_FONT_DEF: self.DefineNativeFont(p, fp)
- else: self.DefineFont(p, fp)
- if k != POST_POST:
- warning('byte %d is not postpost!' % (fp.tell() - 1))
- if SignedQuad(fp) != self.post_loc:
- warning('bad postamble pointer in byte %d!' % (fp.tell() - 4))
- m = GetByte(fp)
- if not ValidID(m):
- warning('identification in byte %d should be one of: %s!' % (fp.tell() - 1, DVI_IDS))
- if not self.id == m:
- if not (self.id == 2 and m == 3): # pTeX/upTeX with dir allowed
- warning('ID byte mismatch: preamble %d vs postamble %d!' % (self.id, m))
-
- def DefineFont(self, e, fp):
- c = SignedQuad(fp) # font_check_sum
- q = SignedQuad(fp) # font_scaled_size
- d = SignedQuad(fp) # font_design_size
- n = fp.read(GetByte(fp) + GetByte(fp)).decode('utf8')
- try:
- f = self.font_def[e]
- except KeyError:
- self.font_def[e] = {'name':n, 'checksum':c, 'scaled_size':q, 'design_size':d}
- if q <= 0 or q >= 0o1000000000:
- warning("%s---not loaded, bad scale (%d)!" % (n, q))
- elif d <= 0 or d >= 0o1000000000:
- warning("%s---not loaded, bad design size (%d)!" % (n, d))
- else:
- if f['checksum'] != c:
- warning("\t---check sum doesn't match previous definition!")
- if f['scaled_size'] != q:
- warning("\t---scaled size doesn't match previous definition!")
- if f['design_size'] != d:
- warning("\t---design size doesn't match previous definition!")
- if f['name'] != n:
- warning("\t---font name doesn't match previous definition!")
-
- def DefineNativeFont(self, e, fp):
- size = Get4Bytes(fp) # scaled size
- flags = Get2Bytes(fp)
- l = GetByte(fp) # name length
- fnt_name = fp.read(l).decode('utf8')
- index = Get4Bytes(fp) # face index
- ext = []
- embolden = 0
- if flags & XDV_FLAG_VERTICAL: ext.append("vertical")
- if flags & XDV_FLAG_COLORED: ext.append("color=%08X" % Get4Bytes(fp))
- if flags & XDV_FLAG_EXTEND: ext.append("extend=%d" % SignedQuad(fp))
- if flags & XDV_FLAG_SLANT: ext.append("slant=%d" % SignedQuad(fp))
- if flags & XDV_FLAG_EMBOLDEN: ext.append("embolden=%d" % SignedQuad(fp))
- try:
- f = self.font_def[e]
- except KeyError:
- if index > 0:
- fnt_name += "[%d]" % index
- name = '"%s"' % fnt_name
- if ext:
- name = '"%s:%s"' % (fnt_name, ";".join(ext))
-
- self.font_def[e] = {
- 'name': name,
- 'checksum': 0,
- 'scaled_size': size,
- 'design_size': 655360, # hardcoded
- }
-
- def ProcessPage(self, fp):
- s = []
- while True:
- o = GetByte(fp)
- p = self.Get1Arg(o, fp)
- if o < SET_CHAR_0 + 128 or o in (SET1, SET2, SET3, SET4):
- q = [p]
- while True:
- o = GetByte(fp)
- p = self.Get1Arg(o, fp)
- if o < SET_CHAR_0 + 128 or o in (SET1, SET2, SET3, SET4):
- q.append(p)
- else:
- break
- s.append([SET1, q])
- if o == SET_RULE:
- s.append([SET_RULE, [p, SignedQuad(fp)]])
- elif o in (PUT1, PUT2, PUT3, PUT4):
- s.append([PUT1, [p]])
- elif o == PUT_RULE:
- s.append([PUT_RULE, [p, SignedQuad(fp)]])
- elif o == NOP:
- continue
- elif o == BOP:
- warning('bop occurred before eop!')
- break
- elif o == EOP:
- break
- elif o == PUSH:
- s.append([PUSH])
- elif o == POP:
- s.append([POP])
- elif o in (RIGHT1, RIGHT2, RIGHT3, RIGHT4):
- s.append([RIGHT1, p])
- elif o == W0:
- s.append([W0])
- elif o in (W1, W2, W3, W4):
- s.append([W1, p])
- elif o == X0:
- s.append([X0])
- elif o in (X1, X2, X3, X4):
- s.append([X1, p])
- elif o in (DOWN1, DOWN2, DOWN3, DOWN4):
- s.append([DOWN1, p])
- elif o == Y0:
- s.append([Y0])
- elif o in (Y1, Y2, Y3, Y4):
- s.append([Y1, p])
- elif o == Z0:
- s.append([Z0])
- elif o in (Z1, Z2, Z3, Z4):
- s.append([Z1, p])
- elif o < FNT_NUM_0 + 64 or o in (FNT1, FNT2, FNT3, FNT4):
- s.append([FNT1, p])
- elif o in (XXX1, XXX2, XXX3, XXX4):
- q = fp.read(p)
- s.append([XXX1, q])
- elif o in (FNT_DEF1, FNT_DEF2, FNT_DEF3, FNT_DEF4):
- self.DefineFont(p, fp)
- elif o == NATIVE_FONT_DEF:
- self.DefineNativeFont(p, fp)
- elif o == GLYPHS:
- s.append([GLYPHS, self.GetGlyphs(fp)])
- elif o == TEXT_GLYPHS:
- s.append([TEXT_GLYPHS, self.GetTextGlyphs(fp)])
- elif o == DIR:
- s.append([DIR, p])
- elif o == BEGIN_REFLECT:
- s.append([BEGIN_REFLECT])
- elif o == END_REFLECT:
- s.append([END_REFLECT])
- elif o == PRE:
- warning('preamble command within a page!')
- break
- elif o in (POST, POST_POST):
- warning('postamble command %d!' % o)
- break
- else:
- warning('undefined command %d!' % o)
- break
- return s
-
- def Get1Arg(self, o, fp):
- if o < SET_CHAR_0 + 128:
- return o - SET_CHAR_0
- if o in (SET1, PUT1, FNT1, XXX1, FNT_DEF1, DIR):
- return GetByte(fp)
- if o in (SET2, PUT2, FNT2, XXX2, FNT_DEF2):
- return Get2Bytes(fp)
- if o in (SET3, PUT3, FNT3, XXX3, FNT_DEF3):
- return Get3Bytes(fp)
- if o in (RIGHT1, W1, X1, DOWN1, Y1, Z1):
- return SignedByte(fp)
- if o in (RIGHT2, W2, X2, DOWN2, Y2, Z2):
- return SignedPair(fp)
- if o in (RIGHT3, W3, X3, DOWN3, Y3, Z3):
- return SignedTrio(fp)
- if o in (SET4, SET_RULE, PUT4, PUT_RULE, RIGHT4, W4, X4, DOWN4, Y4, Z4, FNT4, XXX4, FNT_DEF4, NATIVE_FONT_DEF):
- return SignedQuad(fp)
- if o in (NOP, BOP, EOP, PUSH, POP, PRE, POST, POST_POST) or o > POST_POST:
- return 0
- if o in (W0, X0, Y0, Z0, BEGIN_REFLECT, END_REFLECT):
- return 0
- if o < FNT_NUM_0 + 64:
- return o - FNT_NUM_0
-
- def GetGlyphs(self, fp):
- width = SignedQuad(fp)
- length = Get2Bytes(fp)
- glyphs = {}
- for i in range(length):
- glyphs[i] = {}
- glyphs[i]["x"] = SignedQuad(fp)
- glyphs[i]["y"] = SignedQuad(fp)
-
- for i in range(length):
- glyphs[i]["id"] = Get2Bytes(fp)
-
- return (width, glyphs)
-
- def GetTextGlyphs(self, fp):
- length = Get2Bytes(fp)
- chars = []
- for i in range(length):
- chars.append(Get2Bytes(fp))
- width, glyphs = self.GetGlyphs(fp)
-
- return (chars, width, glyphs)
-
- def ReadGlyphs(self, val):
- import re
- glyphs = []
- w, g = val.split(" ", 1)
- for m in re.finditer(r"gid(?P<id>\d+?)\((?P<pos>.*?.)\)", g):
- gid = m.group("id")
- pos = m.group("pos")
-
- if "," in pos:
- x, y = pos.split(",")
- else:
- x, y = pos, "0sp"
-
- glyphs.append({"id": int(gid), 'x': self.ConvLen(x), 'y': self.ConvLen(y)})
-
- return (self.ConvLen(w), glyphs)
-
- def ReadTextGlyphs(self, val):
- _, text, glyphs = val.split(val[0])
- text = "'%s'" % text
- glyphs = glyphs.lstrip()
- chars = GetStr(text)
- w, glyphs = self.ReadGlyphs(glyphs)
-
- return (chars, w, glyphs)
-
- ##########################################################
- # Save: Internal Format -> DVI
- ##########################################################
- def Save(self, fn):
- fp = open(fn, 'wb')
- self.SaveToFile(fp)
- fp.close()
-
- def SaveToFile(self, fp):
- # WritePreamble
- fp.write(b''.join([bytes.fromhex('%02x' % PRE), PutByte(self.id), PutSignedQuad(self.numerator), PutSignedQuad(self.denominator), PutSignedQuad(self.mag), PutByte(len(self.comment)), self.comment.encode('utf8')]))
- # WriteFontDefinitions
- self.WriteFontDefinitions(fp)
- # WritePages
- stackdepth = 0; loc = -1
- for page in self.pages:
- w = x = y = z = 0; stack = []
- s = [bytes.fromhex('%02x' % BOP)]
- s.extend([PutSignedQuad(c) for c in page['count']])
- s.append(PutSignedQuad(loc))
- for cmd in page['content']:
- if cmd[0] == SET1:
- for o in cmd[1]:
- if o < 128: s.append(bytes.fromhex('%02x' % (SET_CHAR_0 + o)))
- else: s.append(self.CmdPairU([SET1, o]))
- elif cmd[0] in (SET_RULE, PUT_RULE):
- s.append(bytes.fromhex('%02x' % cmd[0]) + PutSignedQuad(cmd[1][0]) + PutSignedQuad(cmd[1][1]))
- elif cmd[0] == PUT1:
- s.append(self.CmdPairU([PUT1, cmd[1][0]]))
- elif cmd[0] in (RIGHT1, DOWN1):
- s.append(self.CmdPair(cmd))
- elif cmd[0] in (W0, X0, Y0, Z0):
- s.append(bytes.fromhex('%02x' % cmd[0]))
- elif cmd[0] == PUSH:
- s.append(bytes.fromhex('%02x' % PUSH))
- stack.append((w, x, y, z))
- if len(stack) > stackdepth: stackdepth = len(stack)
- elif cmd[0] == POP:
- s.append(bytes.fromhex('%02x' % POP))
- w, x, y, z = stack.pop()
- elif cmd[0] == W1:
- w = cmd[1]; s.append(self.CmdPair(cmd))
- elif cmd[0] == X1:
- x = cmd[1]; s.append(self.CmdPair(cmd))
- elif cmd[0] == Y1:
- y = cmd[1]; s.append(self.CmdPair(cmd))
- elif cmd[0] == Z1:
- z = cmd[1]; s.append(self.CmdPair(cmd))
- elif cmd[0] == FNT1:
- if cmd[1] < 64: s.append(bytes.fromhex('%02x' % (FNT_NUM_0 + cmd[1])))
- else: s.append(self.CmdPairU(cmd))
- elif cmd[0] == XXX1:
- if options.xxx_encoding == "none":
- l = len(cmd[1]) # leave encoding untouched
- else:
- cmd1 = cmd[1].encode(options.xxx_encoding)
- l = len(cmd1)
- if l < 256:
- s.append(bytes.fromhex('%02x' % XXX1) + bytes.fromhex('%02x' % l))
- else:
- s.append(bytes.fromhex('%02x' % XXX4) + PutSignedQuad(l))
- if options.xxx_encoding == "none":
- for o in cmd[1]:
- s.append(bytes.fromhex('%02x' % ord(o)))
- else:
- s.append(cmd1)
- elif cmd[0] == DIR:
- s.append(bytes.fromhex('%02x' % DIR) + bytes.fromhex('%02x' % cmd[1]))
- elif cmd[0] == BEGIN_REFLECT:
- s.append(bytes.fromhex('%02x' % BEGIN_REFLECT))
- elif cmd[0] == END_REFLECT:
- s.append(bytes.fromhex('%02x' % END_REFLECT))
- elif cmd[0] == GLYPHS:
- s.append(PutByte(GLYPHS))
- s.append(PutGlyphs(cmd[1], cmd[2]))
- elif cmd[0] == TEXT_GLYPHS:
- s.append(PutByte(TEXT_GLYPHS))
- s.append(PutTextGlyphs(cmd[1], cmd[2], cmd[3]))
- else:
- warning('invalid command %s!' % cmd[0])
- s.append(bytes.fromhex('%02x' % EOP))
- loc = fp.tell()
- fp.write(b''.join(s))
- # WritePostamble
- post_loc = fp.tell()
- fp.write(b''.join([bytes.fromhex('%02x' % POST), PutSignedQuad(loc), PutSignedQuad(self.numerator), PutSignedQuad(self.denominator), PutSignedQuad(self.mag), PutSignedQuad(self.max_v), PutSignedQuad(self.max_h), Put2Bytes(stackdepth+1), Put2Bytes(len(self.pages))]))
- # WriteFontDefinitions
- self.WriteFontDefinitions(fp)
- # WritePostPostamble
- fp.write(b''.join([bytes.fromhex('%02x' % POST_POST), PutSignedQuad(post_loc), PutByte(self.id_post), b'\xdf\xdf\xdf\xdf']))
- loc = fp.tell()
- while (loc % 4) != 0:
- fp.write(b'\xdf'); loc += 1
-
- def WriteFontDefinitions(self, fp):
- s = []
- for e in sorted(self.font_def.keys()):
- try:
- self.font_def[e]['native']
- flags = self.font_def[e]['flags']
- s.append(PutByte(NATIVE_FONT_DEF))
- s.append(PutSignedQuad(e))
- s.append(PutSignedQuad(self.font_def[e]['scaled_size']))
- s.append(Put2Bytes(flags))
- s.append(PutByte(len(self.font_def[e]['name'])))
- s.append(self.font_def[e]['name'].encode('utf8'))
- s.append(PutSignedQuad(self.font_def[e]['index']))
- if flags & XDV_FLAG_COLORED: s.append(PutSignedQuad(self.font_def[e]['color']))
- if flags & XDV_FLAG_EXTEND: s.append(PutSignedQuad(self.font_def[e]['extend']))
- if flags & XDV_FLAG_SLANT: s.append(PutSignedQuad(self.font_def[e]['slant']))
- if flags & XDV_FLAG_EMBOLDEN: s.append(PutSignedQuad(self.font_def[e]['embolden']))
- except KeyError:
- l, q = PutUnsigned(e)
- s.append(PutByte(FNT_DEF1 + l))
- s.append(q)
- s.append(PutSignedQuad(self.font_def[e]['checksum']))
- s.append(PutSignedQuad(self.font_def[e]['scaled_size']))
- s.append(PutSignedQuad(self.font_def[e]['design_size']))
- s.append(b'\x00')
- s.append(PutByte(len(self.font_def[e]['name'])))
- s.append(self.font_def[e]['name'].encode('utf8'))
- fp.write(b''.join(s))
-
- def CmdPairU(self, cmd):
- l, q = PutUnsigned(cmd[1])
- return bytes.fromhex('%02x' % (cmd[0] + l)) + q
-
- def CmdPair(self, cmd):
- l, q = PutSigned(cmd[1])
- return bytes.fromhex('%02x' % (cmd[0] + l)) + q
-
- ##########################################################
- # Parse: Text -> Internal Format
- ##########################################################
- def Parse(self, fn, encoding=''):
- fp = open(fn, 'r', encoding=encoding)
- s = fp.read()
- fp.close()
- self.ParseFromString(s, encoding=encoding)
-
- def ParseFromString(self, s, encoding=''):
- global GetStr, cur_font, cur_dsize, cur_ssize, subfont_idx
- if encoding == 'ascii': GetStr = GetStrASCII
- else: GetStr = GetStrUTF8
- self.Initialize()
- self.fnt_num = 0
- dir_used = 0
- for l in s.split('\n'):
- l = l.strip()
- if not l or l[0] == '%': continue
- try:
- key, val = l.split(':', 1)
- key = key.strip(); val = val.strip()
- except:
- if l[-1] == ']': v = l[:-1].split(' ')
- else: v = l.split(' ')
- if v[0] == "[page":
- self.cur_page = []
- count = [GetInt(c) for c in v[1:]]
- if len(count) < 10: count += ([0] * (10-len(count)))
- self.pages.append({'count':count, 'content':self.cur_page})
- continue
- # ParsePreamble
- if key == "id":
- self.id = GetInt(val)
- if not ValidID(self.id):
- warning('identification byte %d should be one of: %s!' % (self.id, DVI_IDS))
- elif key == "numerator":
- d = GetInt(val)
- if d <= 0:
- warning('non-positive numerator %d!' % d)
- else:
- self.numerator = d
- self.ComputeConversionFactors()
- elif key == "denominator":
- d = GetInt(val)
- if d <= 0:
- warning('non-positive denominator %d!' % d)
- else:
- self.denominator = d
- self.ComputeConversionFactors()
- elif key == "magnification":
- d = GetInt(val)
- if d <= 0:
- warning('non-positive magnification %d!' % d)
- else:
- self.mag = d
- elif key == "comment":
- self.comment = val[1:-1]
- # Parse Postamble
- elif key == "maxv":
- self.max_v = self.ConvLen(val)
- elif key == "maxh":
- self.max_h = self.ConvLen(val)
- elif key == "maxs":
- self.max_s = GetInt(val)
- elif key == "pages":
- self.total_pages = GetInt(val)
- # Parse Font Definitions
- elif key == "fntdef":
- self.font_def[self.fnt_num] = self.GetFntDef(val)
- self.fnt_num += 1
- # Parse Pages
- elif key == 'xxx':
- self.cur_page.append([XXX1, eval(val)])
- elif key == 'set':
- ol = GetStr(val)
- if is_subfont:
- subfont_idx = (ol[0] >> 8)
- self.AppendFNT1()
- nl = [ol[0] & 0xff]
- for o in ol[1:]:
- idx = (o >> 8)
- if idx != subfont_idx:
- self.cur_page.append([SET1, nl])
- subfont_idx = idx
- self.AppendFNT1()
- nl = [o & 0xff]
- else:
- nl.append(o & 0xff)
- self.cur_page.append([SET1, nl])
- else:
- self.cur_page.append([SET1, ol])
- elif key == 'put':
- ol = GetStr(val)
- if len(ol) != 1:
- warning('only one character is allowed for put!')
- self.cur_page.append([PUT1, ol])
- elif key == 'setrule':
- v = val.split(' ')
- if len(v) != 2:
- warning('two values are required for setrule!')
- continue
- self.cur_page.append([SET_RULE, [self.ConvLen(c) for c in v]])
- elif key == 'putrule':
- v = val.split(' ')
- if len(v) != 2:
- warning('two values are required for putrule!')
- continue
- self.cur_page.append([PUT_RULE, [self.ConvLen(c) for c in v]])
- elif key == 'fnt':
- f = self.GetFntDef(val)
- n = f['name']
- d = f['design_size']
- q = f['scaled_size']
- if n in subfont_list:
- is_subfont = True
- cur_font = n; cur_dsize = d; cur_ssize = q
- else:
- is_subfont = False
- try:
- e = list(self.font_def.keys())[list(self.font_def.values()).index(f)]
- except:
- e = self.fnt_num
- self.font_def[self.fnt_num] = f
- self.fnt_num += 1
- self.cur_page.append([FNT1, e])
- elif key == 'right':
- self.cur_page.append([RIGHT1, self.ConvLen(val)])
- elif key == 'down':
- self.cur_page.append([DOWN1, self.ConvLen(val)])
- elif key == 'w':
- self.cur_page.append([W1, self.ConvLen(val)])
- elif key == 'x':
- self.cur_page.append([X1, self.ConvLen(val)])
- elif key == 'y':
- self.cur_page.append([Y1, self.ConvLen(val)])
- elif key == 'z':
- self.cur_page.append([Z1, self.ConvLen(val)])
- elif key == 'push':
- self.cur_page.append([PUSH])
- elif key == 'pop':
- self.cur_page.append([POP])
- elif key == 'w0':
- self.cur_page.append([W0])
- elif key == 'x0':
- self.cur_page.append([X0])
- elif key == 'y0':
- self.cur_page.append([Y0])
- elif key == 'z0':
- self.cur_page.append([Z0])
- elif key == 'dir':
- self.cur_page.append([DIR, GetInt(val)])
- dir_used = 1
- elif key == 'begin_reflect':
- self.cur_page.append([BEGIN_REFLECT])
- elif key == 'end_reflect':
- self.cur_page.append([END_REFLECT])
- elif key == 'setglyphs':
- w, glyphs = self.ReadGlyphs(val)
- self.cur_page.append([GLYPHS, w, glyphs])
- elif key == 'settextglyphs':
- text, w, glyphs = self.ReadTextGlyphs(val)
- self.cur_page.append([TEXT_GLYPHS, text, w, glyphs])
- else:
- warning('invalid command %s!' % key)
- if self.id == 2 and dir_used == 1: # standard DVI with dir -> force pTeX/upTeX spec
- self.id_post = 3
- else:
- self.id_post = self.id
-
- def AppendFNT1(self):
- f = {'name':cur_font+"%02x"%subfont_idx, 'design_size':cur_dsize, 'scaled_size':cur_ssize, 'checksum':0}
- try:
- e = list(self.font_def.keys())[list(self.font_def.values()).index(f)]
- except:
- e = self.fnt_num
- self.font_def[e] = f
- self.fnt_num += 1
- self.cur_page.append([FNT1, e])
-
- ##########################################################
- # Dump: Internal Format -> Text
- ##########################################################
- def Dump(self, fn, tabsize=2, encoding=''):
- fp = open(fn, 'w', encoding=encoding)
- self.DumpToFile(fp, tabsize=tabsize, encoding=encoding)
- fp.close()
-
- def DumpToFile(self, fp, tabsize=2, encoding=''):
- global PutStr
- if encoding == 'ascii': PutStr = PutStrASCII
- elif encoding == 'latin1': PutStr = PutStrLatin1
- else: PutStr = PutStrUTF8
- # DumpPreamble
- fp.write("[preamble]\n")
- fp.write("id: %d\n" % self.id)
- fp.write("numerator: %d\n" % self.numerator)
- fp.write("denominator: %d\n" % self.denominator)
- fp.write("magnification: %d\n" % self.mag)
- fp.write("comment: %s\n" % repr(self.comment))
- # DumpPostamble
- fp.write("\n[postamble]\n")
- fp.write("maxv: %s\n" % self.byconv(self.max_v))
- fp.write("maxh: %s\n" % self.byconv(self.max_h))
- fp.write("maxs: %d\n" % self.max_s)
- fp.write("pages: %d\n" % self.total_pages)
- # DumpFontDefinitions
- fp.write("\n[font definitions]\n")
- for e in sorted(self.font_def.keys()):
- fp.write("fntdef: %s " % self.font_def[e]['name'])
- if self.font_def[e]['design_size'] != self.font_def[e]['scaled_size']:
- fp.write("(%s) " % self.byconv(self.font_def[e]['design_size']))
- fp.write("at %s\n" % self.byconv(self.font_def[e]['scaled_size']))
- # DumpPages
- for page in self.pages:
- fp.write("\n[page" + (" %d"*10 % tuple(page['count'])) + "]\n")
- indent = 0
- for cmd in page['content']:
- if cmd[0] == POP:
- indent -= tabsize
- fp.write("%spop:\n" % (' ' * indent))
- continue
- fp.write("%s" % (' ' * indent))
- if cmd[0] == PUSH:
- fp.write("push:\n")
- indent += tabsize
- elif cmd[0] == XXX1:
- if options.xxx_encoding == "none":
- fp.write("xxx: %s\n" % PutStrASCII(cmd[1])) # leave encoding untouched
- else:
- fp.write("xxx: '%s'\n" % cmd[1].decode(options.xxx_encoding))
- elif cmd[0] == DIR:
- fp.write("dir: %d\n" % cmd[1])
- elif cmd[0] == BEGIN_REFLECT:
- fp.write("begin_reflect:\n")
- elif cmd[0] == END_REFLECT:
- fp.write("end_reflect:\n")
- elif cmd[0] == SET_RULE:
- fp.write("setrule: %s %s\n" % (self.byconv(cmd[1][0]), self.byconv(cmd[1][1])))
- elif cmd[0] == PUT_RULE:
- fp.write("putrule: %s %s\n" % (self.byconv(cmd[1][0]), self.byconv(cmd[1][1])))
- elif cmd[0] == SET1:
- fp.write("set: %s\n" % PutStr(cmd[1]))
- elif cmd[0] == PUT1:
- fp.write("put: %s\n" % PutStr(cmd[1]))
- elif cmd[0] == FNT1:
- f = self.font_def[cmd[1]]['name']
- z = self.font_def[cmd[1]]['scaled_size']
- if IsFontChanged(f, z):
- fp.write("fnt: %s " % cur_font)
- if self.font_def[cmd[1]]['design_size'] != self.font_def[cmd[1]]['scaled_size']:
- fp.write("(%s) " % self.byconv(self.font_def[cmd[1]]['design_size']))
- fp.write("at %s\n" % self.byconv(cur_ssize))
- elif cmd[0] == GLYPHS:
- fp.write("setglyphs: %s\n" % self.DumpGlyphs(cmd[1][0], cmd[1][1]))
- elif cmd[0] == TEXT_GLYPHS:
- fp.write("settextglyphs: %s\n" % self.DumpTextGlyphs(cmd[1][0], cmd[1][1], cmd[1][2]))
- elif cmd[0] == RIGHT1:
- fp.write("right: %s\n" % self.byconv(cmd[1]))
- elif cmd[0] == DOWN1:
- fp.write("down: %s\n" % self.byconv(cmd[1]))
- elif cmd[0] == W1:
- fp.write("w: %s\n" % self.byconv(cmd[1]))
- elif cmd[0] == X1:
- fp.write("x: %s\n" % self.byconv(cmd[1]))
- elif cmd[0] == Y1:
- fp.write("y: %s\n" % self.byconv(cmd[1]))
- elif cmd[0] == Z1:
- fp.write("z: %s\n" % self.byconv(cmd[1]))
- elif cmd[0] == W0:
- fp.write("w0:\n")
- elif cmd[0] == X0:
- fp.write("x0:\n")
- elif cmd[0] == Y0:
- fp.write("y0:\n")
- elif cmd[0] == Z0:
- fp.write("z0:\n")
-
- def DumpGlyphs(self, w, g):
- yPresent = False
- for i in g:
- if g[i]["y"] != 0:
- yPresent = True
-
- glyphs = []
- for i in g:
- gid = "gid%s" % g[i]["id"]
- x = self.byconv(g[i]["x"])
- y = self.byconv(g[i]["y"])
- if yPresent:
- glyphs.append("%s(%s, %s)" % (gid, x, y))
- else:
- glyphs.append("%s(%s)" % (gid, x))
-
- return "%s %s" % (self.byconv(w), " ".join(glyphs))
-
- def DumpTextGlyphs(self, t, w, g):
- return "%s %s" % (PutStrUTF8(t), self.DumpGlyphs(w, g))
-
- ##########################################################
- # Misc Functions
- ##########################################################
- def ComputeConversionFactors(self):
- self.sp_conv = (self.numerator / 25400000.) * (473628672. / self.denominator)
- self.pt_conv = (self.numerator / 25400000.) * (7227. / self.denominator)
- self.bp_conv = (self.numerator / 254000.) * (72. / self.denominator)
- self.mm_conv = (self.numerator / 10000.) / self.denominator
- self.cm_conv = (self.numerator / 100000.) / self.denominator
- self.in_conv = (self.numerator / 254000.) * (1. / self.denominator)
-
- def ConvLen(self, s):
- try: return int(s)
- except: pass
- try: f = float(s[:-2])
- except: return 0
- m = s[-2:]
- if m == "pt": return int(round(f / self.pt_conv))
- elif m == "in": return int(round(f / self.in_conv))
- elif m == "mm": return int(round(f / self.mm_conv))
- elif m == "cm": return int(round(f / self.cm_conv))
- elif m == "bp": return int(round(f / self.bp_conv))
- elif m == "sp": return int(round(f / self.sp_conv))
- else:
- try: return int(round(f / self.pt_conv))
- except: return 0
-
- def GetFntDef(self, s):
- f = {}
- try:
- n, size = s.split('(', 1)
- d, q = size.split(')', 1)
- except:
- n, q = s.split(' ', 1)
- n = n.strip(); q = q.strip()
- if n.startswith('"') and n.endswith('"'):
- f['native'] = True
- n = n.strip('"')
- flags = 0
- color = 0
- extend = 0
- slant = 0
- embolden = 0
- try:
- name, ext = n.split(':')
- except:
- name, ext = n, ""
-
- try:
- name, index = name.split('[')
- index = index.split(']')[0]
- except:
- index = 0
-
- if ext:
- ext = ext.split(';')
- for opt in ext:
- try:
- key, value = opt.split('=')
- except:
- key, value = opt, ""
- if key == "color":
- flags |= XDV_FLAG_COLORED
- color = int(value, 16)
- if key == "vertical":
- flags |= XDV_FLAG_VERTICAL
- if key == "extend":
- flags |= XDV_FLAG_EXTEND
- extend = int(value)
- if key == "slant":
- flags |= XDV_FLAG_SLANT
- slant = int(value)
- if key == "embolden":
- flags |= XDV_FLAG_EMBOLDEN
- embolden = int(value)
-
- f['name'] = name
- f['index'] = int(index)
- f['flags'] = flags
- f['color'] = color
- f['extend'] = extend
- f['slant'] = slant
- f['embolden'] = embolden
- else:
- f['name'] = n
-
- if q[:2] == "at": q = q[2:]
- q = self.ConvLen(q.strip())
- try: d = self.ConvLen(d.strip())
- except: d = q
-
- f['design_size'] = d
- f['scaled_size'] = q
- f['checksum'] = 0
-
- return f
-
- def by_sp_conv(self, a):
- v = self.sp_conv * a
- return "%dsp" % int(v)
-
- def by_pt_conv(self, a):
- v = self.pt_conv * a
- if v == int(v): return "%dpt" % int(v)
- else: return "%fpt" % v
-
- def by_bp_conv(self, a):
- v = self.bp_conv * a
- if v == int(v): return "%dbp" % int(v)
- else: return "%fbp" % v
-
- def by_mm_conv(self, a):
- v = self.mm_conv * a
- if v == int(v): return "%dmm" % int(v)
- else: return "%fmm" % v
-
- def by_cm_conv(self, a):
- v = self.cm_conv * a
- if v == int(v): return "%dcm" % int(v)
- else: return "%fcm" % v
-
- def by_in_conv(self, a):
- v = self.in_conv * a
- if v == int(v): return "%din" % int(v)
- else: return "%fin" % v
-
-############################################################
-# Misc Functions for Main Routine
-############################################################
-def ProcessOptions():
- usage = """%prog [options] dvi_file|dvi_dump_file
-
-DVIasm is a Python script to support changing or creating DVI files
-via disassembling into text, editing, and then reassembling into
-binary format. It is fully documented at
- http://tug.org/TUGboat/Articles/tb28-2/tb89cho.pdf
- http://ajt.ktug.kr/assets/2008/5/1/0201cho.pdf
-
-Please report bugs to
- https://github.com/aminophen/dviasm"""
-
- version = """This is %prog-20200918
-
-Copyright (C) 2007-2008 by Jin-Hwan Cho <chofchof@ktug.or.kr>
-Copyright (C) 2011-2017 by Khaled Hosny <khaledhosny@eglug.org>
-Copyright (C) 2019 by Arthur Reutenauer <arthur@reutenauer.eu>
-Copyright (C) 2019-2020 by Hironobu Yamashita <h.y.acetaminophen@gmail.com>
-
-This is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version."""
-
- parser = OptionParser(usage=usage, version=version)
- parser.add_option("-u", "--unit",
- action="store", type="string", dest="unit",
- metavar="STR",
- help="unit (sp, pt, bp, mm, cm, in) [default=%default]")
- parser.add_option("-o", "--output",
- action="store", type="string", dest="output",
- metavar="FILE",
- help="filename for output instead of stdout")
- parser.add_option("-e", "--encoding",
- action="store", type="string", dest="encoding",
- metavar="STR",
- help="encoding for input/output [default=%default]")
- parser.add_option("-x", "--xxx-encoding",
- action="store", type="string", dest="xxx_encoding",
- metavar="STR",
- help="encoding for interpreting xxx strings [default=%default]")
- parser.add_option("-t", "--tabsize",
- action="store", type="int", dest="tabsize",
- metavar="INT",
- help="tab size for push/pop [default=%default]")
- parser.add_option("-p", "--ptex",
- action="store_true", dest="ptex", default=False,
- help="ISO-2022-JP-encoded DVI for Japanese pTeX")
- parser.add_option("-s", "--subfont",
- action="append", type="string", dest="subfont",
- metavar="STR",
- help="the list of fonts with UCS2 subfont scheme (comma separated); disable internal subfont list if STR is empty")
- parser.set_defaults(unit='pt', encoding='utf8', xxx_encoding='none', tabsize=2)
- (options, args) = parser.parse_args()
- if not options.unit in ['sp', 'pt', 'bp', 'mm', 'cm', 'in']:
- parser.error("invalid unit name '%s'!" % options.unit)
- if options.tabsize < 0:
- parser.error("negative tabsize!")
- if not options.xxx_encoding in ['none', 'utf8', 'sjis', 'eucjp']:
- parser.error("invalid xxx-encoding '%s'!" % options.xxx_encoding)
- if not options.encoding in ['ascii', 'latin1', 'utf8', 'sjis', 'eucjp']:
- parser.error("invalid encoding '%s'!" % options.encoding)
- if options.ptex:
- global is_ptex
- is_ptex = True
- if not options.encoding in ['utf8', 'sjis', 'eucjp']:
- parser.error("invalid encoding '%s' for Japanese pTeX!" % options.encoding)
- if options.subfont:
- global subfont_list
- if not options.subfont[0]: # disable subfont
- subfont_list = []
- for l in options.subfont:
- subfont_list.extend([f.strip() for f in l.split(',')])
- if len(args) != 1:
- parser.error("try with the option --help!")
- return (options, args)
-
-def IsDVI(fname):
- from os.path import splitext
- if splitext(fname)[1] not in ('.dvi', '.xdv'): return False
- try:
- fp = open(fname, 'rb')
- fp.seek(0)
- if GetByte(fp) != PRE: return False
- fp.seek(-4, 2)
- if GetByte(fp) != 223: return False
- fp.close()
- except:
- sys.stderr.write('Failed to read %s\n' % fname)
- return False
- return True
-
-############################################################
-# Main Routine
-############################################################
-if __name__ == '__main__':
- (options, args) = ProcessOptions()
- aDVI = DVI(unit=options.unit)
- if IsDVI(args[0]): # dvi -> dump
- aDVI.Load(args[0])
- if options.output: aDVI.Dump(options.output, tabsize=options.tabsize, encoding=options.encoding)
- else: aDVI.DumpToFile(sys.stdout, tabsize=options.tabsize, encoding=options.encoding)
- else: # dump -> dvi
- aDVI.Parse(args[0], encoding=options.encoding)
- if options.output: aDVI.Save(options.output)
- else: aDVI.SaveToFile(sys.stdout.buffer)
diff --git a/Build/source/texk/texlive/linked_scripts/dviinfox/dviinfox.pl b/Build/source/texk/texlive/linked_scripts/dviinfox/dviinfox.pl
deleted file mode 100755
index 39330951047..00000000000
--- a/Build/source/texk/texlive/linked_scripts/dviinfox/dviinfox.pl
+++ /dev/null
@@ -1,366 +0,0 @@
-#!/usr/bin/env perl
-
-# dviinfox
-# ========
-#
-# This script is a joint effort of
-# Dag Langmyhr, Department of Informatics, University of Oslo
-# (dag at ifi.uio.no)
-# and
-# Hironobu Yamashita, Japanese TeX Development Community
-# (h.y.acetaminophen at gmail.com)
-#
-# A program to print information about a DVI file.
-#
-# Usage: dviinfox [options] file1 file2 ...
-# where the flags indicate which information is desired.
-# -f Give information about the fonts used.
-# -p Give information about the number of pages.
-# -v List the program version number.
-# -h Show help message.
-# No options will provide all information available.
-#
-# Example:
-# % dviinfox alltt.dvi
-# alltt.dvi: DVI format 2; 3 pages
-# Magnification: 1000/1000
-# Size unit: 1000x25400000/(1000x473628672)dum = 0.054dum = 1.000sp
-# Page size: 407ptx682pt = 14.340cmx23.970cm
-# Stack size: 8
-# Comment: " TeX output 1995.07.07:1513"
-# Font 27: cmr9 at 9.000 (design size 9.000, checksum=1874103239)
-# Font 26: cmsy6 at 6.000 (design size 6.000, checksum=1906386187)
-# Font 21: cmr8 at 8.000 (design size 8.000, checksum=2088458503)
-# Font 20: cmsy10 at 12.000 (design size 10.000, checksum=555887770)
-# Font 16: cmr12 at 12.000 (design size 12.000, checksum=1487622411)
-# Font 15: cmtt12 at 17.280 (design size 12.000, checksum=3750147412)
-# Font 14: cmr17 at 17.280 (design size 17.280, checksum=1154739572)
-# Font 13: cmsy10 at 10.000 (design size 10.000, checksum=555887770)
-# Font 7: cmr10 at 10.000 (design size 10.000, checksum=1274110073)
-# Font 6: cmr7 at 7.000 (design size 7.000, checksum=3650330706)
-
-use strict;
-
-my $Prog = "dviinfox";
-my $Version = "1.04";
-my $Author = "Dag Langmyhr and Hironobu Yamashita";
-
-my $True = 1;
-my $False = 0;
-
-my $List_all = $True;
-my $List_fonts = $False;
-my $List_pages = $False;
-
-# DVI commands:
-my $DVI_Filler = "\337"; # 223 = 0xdf
-my $DVI_Font = "\363"; # 243 = 0xf3
-my $DVI_Post = "\370"; # 248 = 0xf8
-my $DVI_Post_post = "\371"; # 249 = 0xf9
-my $DVI_Pre = "\367"; # 247 = 0xf7
-my $XDV_Font = "\374"; # 252 = 0xfc
-
-my $Unit;
-
-if (!@ARGV) {
- show_usage();
- print "Try \"$Prog -h\" for more information.\n";
-}
-
-Param:
-foreach (@ARGV) {
- /^-f$/ && do {
- $List_fonts = $True; $List_all = $False; next Param; };
- /^-p$/ && do {
- $List_pages = $True; $List_all = $False; next Param; };
- /^-v$/ && do {
- show_version(); next Param; };
- /^-h$/ && do {
- show_help(); next Param; };
- /^-/ && do {
- print STDERR "$Prog: Unknown option '$_' ignored.\n"; next Param; };
-
- &Read_DVI_file($_);
-}
-
-exit 0;
-
-# Only sub definitions from here on
-
-sub show_version {
- print "This is $Prog $Version, by $Author\n";
-}
-
-sub show_usage {
- show_version();
- print "Usage: $Prog [-f][-p][-v] file...\n";
-}
-
-sub show_help {
- show_usage();
- print "A program to print information about a DVI file.\n";
- print "Options:\n";
- print " -f Give information about the fonts used.\n";
- print " -p Give information about the number of pages.\n";
- print " -v List the program version number.\n";
- print " -h Show help message.\n";
- exit 0;
-}
-
-sub Read_DVI_file {
- local($_) = @_;
- my ($c, $cn);
- my $IS_XDV = 0;
-
- print "$_: ";
-
- open(F, $_) || do { print STDERR "Could not open!\n\n"; exit 1; };
-
- # First, read info at start of DVI file:
-
- if (($c = getc(F)) ne $DVI_Pre) {
- printf STDERR ("Not a DVI file (first byte is 0x%02x, not 0x%02x)!\n\n",
- ord($c), ord($DVI_Pre));
- close F; exit 1;
- };
-
- my $Format = ord(getc(F));
- my $Numer = &Read4;
- my $Denom = &Read4;
- my $Magni = &Read4;
- my $Comment = &Read_text;
-
- # Then, read information at the end of the DVI file:
-
- seek(F, -1, 2);
- while (($c = getc(F)) eq $DVI_Filler) { seek(F, -2, 1); };
- my $VersionID = ord($c);
- # Previously we required equality ($VersionID == $Format). However,
- # it seems ok even when format id (pre) and version id (post_post)
- # are different. TeX4ht allows $VersionID <= 10, so we follow it
- if (($VersionID != $Format) && ($VersionID > 10)) {
- print STDERR "DVI format error (format: $Format vs id: $VersionID)!\n\n";
- close F; exit 1;
- };
- $IS_XDV = 1 if ($Format > 2);
-
- seek(F, -6, 1);
- if (($c = getc(F)) ne $DVI_Post_post) {
- $cn = ord($c);
- printf STDERR ("DVI error: Expected POST_POST command, not 0x%02x!\n\n", $cn);
- close F; exit 1;
- };
-
- my $Last_post = &Read4;
- seek(F, $Last_post, 0) || do {
- print STDERR "Could not locate position $Last_post!\n\n";
- close F; exit 1;
- };
- if (($c = getc(F)) ne $DVI_Post) {
- $cn = ord($c);
- printf STDERR ("DVI error: Expected POST command, not 0x%02x!\n\n", $cn);
- close F; exit 1;
- };
-
- my $Final_page = &Read4;
- my $Numer2 = &Read4;
- my $Denom2 = &Read4;
- my $Magni2 = &Read4;
- my $Height = &Read4;
- my $Width = &Read4;
- my $Stack = &Read2_u;
- my $Pages = &Read2_u;
-
- if ($List_all) {
- print "DVI format $Format";
- print "; id $VersionID" if ($VersionID != $Format);
- print " (pTeX DVI)" if (($Format == 2) && ($VersionID == 3));
- print " (XeTeX XDV)" if ($Format > 2);
- print "; ";
- }
- if ($List_all || $List_pages) {
- print "$Pages page";
- print "s" if ($Pages > 1);
- };
-
- $Unit = $Magni*$Numer/(1000*$Denom);
- if ($List_all) {
- print "\n Magnification: $Magni/1000";
- printf("\n Size unit: %dx$Numer/(1000x$Denom)dum = %5.3fdum = %5.3fsp",
- $Magni, $Unit, &Scale_to_sp(1));
- printf("\n Page size: %dptx%dpt = %5.3fcmx%5.3fcm",
- &Scale_to_pt($Width), &Scale_to_pt($Height),
- &Scale_to_cm($Width), &Scale_to_cm($Height));
- print "\n Stack size: $Stack";
- print "\n Comment: \"$Comment\"";
- }
- print "\n";
-
- if ($List_all || $List_fonts) {
- my ($F_count, $F_check, $F_scale, $F_design, $F_name);
- my ($F_flag, $F_index, $F_colored, $F_extend, $F_slant, $F_embolden);
- my $F_tempswa;
- while (($c = getc(F)) eq $DVI_Font || $c eq $XDV_Font) {
- # initialize
- $F_count = 0;
- $F_check = 0;
- $F_scale = 0;
- $F_design = 0;
- $F_name = '';
- $F_flag = 0;
- $F_index = 0;
- $F_colored = 0;
- $F_extend = 0;
- $F_slant = 0;
- $F_embolden = 0;
- if ($c eq $DVI_Font) {
- # standard DVI: TFM font definition command
- $F_count = ord(getc(F));
- $F_check = &Read4_u;
- $F_scale = &Read4;
- $F_design = &Read4;
- $F_name = &Read_text2;
- printf(" Font %3d: %9s at %6.3f",
- $F_count, $F_name, &Scale_to_pt($F_scale));
- printf(" (design size %6.3f, ", &Scale_to_pt($F_design));
- print "checksum=$F_check)\n";
- } else { # $c eq $XDV_Font
- # extended XDV for XeTeX: Native font definition command
- if (!$IS_XDV) {
- printf STDERR ("Erorr: Command %d used in non-XDV file!\n", ord($XDV_Font));
- close F; exit 1;
- }
- $F_count = &Read4_u;
- $F_scale = &Read4;
- $F_flag = &Read2_u;
- $F_name = &Read_text;
- $F_index = &Read4_u;
- $F_colored = &Read4_u if ($F_flag & 512);
- $F_extend = &Read4_u if ($F_flag & 4096);
- $F_slant = &Read4_u if ($F_flag & 8192);
- $F_embolden = &Read4_u if ($F_flag & 16384);
- printf(" Native Font %3d: %s at %6.3f",
- $F_count, $F_name, &Scale_to_pt($F_scale));
- printf(" (flags 0x%04x, face index %d)\n", $F_flag, $F_index);
- if ($F_flag) {
- print(" +features: ");
- $F_tempswa = 0;
- if ($F_colored) {
- printf("Colored=0x%x", $F_colored);
- $F_tempswa = 1;
- }
- if ($F_extend) {
- print(", ") if ($F_tempswa);
- printf("Extend=0x%x", $F_extend);
- $F_tempswa = 1;
- }
- if ($F_slant) {
- print(", ") if ($F_tempswa);
- printf("Slant=0x%x", $F_slant);
- $F_tempswa = 1;
- }
- if ($F_embolden) {
- print(", ") if ($F_tempswa);
- printf("Embolden=0x%x", $F_embolden);
- $F_tempswa = 1;
- }
- print("\n");
- }
- }
- };
-
- if ($c ne $DVI_Post_post) {
- $cn = ord($c);
- printf STDERR ("DVI error: Expected POST_POST command, not 0x%02x!\n", $cn);
- close F; exit 1;
- };
-
- print "\n";
- };
-
- close F;
-}
-
-
-# Scale_to_pt (Size)
-# -----
-# Give the Size (which is in dum, the standard DVI size) in pt.
-sub Scale_to_pt {
- return $Unit*$_[0]*72.27/254000;
-}
-
-
-# Scale_to_cm (Size)
-# -----------
-# Give the Size (which is in dum, the standard DVI size) in cm.
-sub Scale_to_cm {
- return &Scale_to_pt($_[0])*2.54/72.27;
-}
-
-
-# Scale_to_sp (Size)
-# -----------
-# Give the Size (which is in dum, the standard DVI size) in sp.
-sub Scale_to_sp {
- return &Scale_to_pt($_[0])*65536;
-}
-
-
-# Read2_u
-# -------
-# Read an unsigned two-byte value.
-sub Read2_u {
- return ord(getc(F))*256 + ord(getc(F));
-}
-
-
-# Read4
-# -----
-# Read a four-byte value.
-# (I assume the value is positive and less than 2^31, so the sign bit
-# won't matter.)
-sub Read4 {
- return ((ord(getc(F))*256+ord(getc(F)))*256+ord(getc(F)))*256+ord(getc(F));
-}
-
-
-# Read4_u
-# -----
-# Read an unsigned four-byte value.
-# (I don't know why this works for values >=2^31, and Read4 does not,
-# but as long as it works...)
-sub Read4_u {
- my (@bytes, @sum);
-
- $bytes[0] = ord(getc(F)); $bytes[1] = ord(getc(F));
- $bytes[2] = ord(getc(F)); $bytes[3] = ord(getc(F));
-
- $sum[0] = $bytes[0]*256 + $bytes[1];
- $sum[1] = $bytes[2]*256 + $bytes[3];
-
- return $sum[0]*65536 + $sum[1];
-}
-
-
-# Read_text
-# ---------
-# Read a text (a one-byte length and the the text byte).
-sub Read_text {
- local($_);
- my ($Leng, $Res);
-
- $Leng = ord(getc(F)); read(F, $Res, $Leng);
- return $Res;
-}
-
-
-# Read_text2
-# ----------
-# Like 'Read_text', but the length is the sum of two bytes.
-sub Read_text2 {
- local($_);
- my ($Leng, $Res);
-
- $Leng = ord(getc(F)) + ord(getc(F)); read(F, $Res, $Leng);
- return $Res;
-}
diff --git a/Build/source/texk/texlive/linked_scripts/ebong/ebong.py b/Build/source/texk/texlive/linked_scripts/ebong/ebong.py
deleted file mode 100755
index c4162cf0ef6..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ebong/ebong.py
+++ /dev/null
@@ -1,346 +0,0 @@
-#!/usr/bin/env python
-# look in newbong
-import sre
-A='A'
-B='B'
-S='S'
-s='s'
-F='F'
-X='X'
-
-NCLINE = 0
-global NCWORD,CWORD
-
-AKSAR={
- 'k' :[B,'k'],
- 'kh' :[B,'kh'],
- 'g' :[B,'g'],
- 'gh' :[B,'gh'],
- 'ng' :[B,'NG'],
-
- 'ch' :[B,'c'],
- '^ch' :[B,'ch'],
- 'j' :[B,'j'],
- 'jh' :[B,'jh'],
- '^y' :[B,'NJ'],
- '_n' :[B,'NJ'],
-
- 't' :[B,'T'],
- '^th' :[B,'Th'],
- 'd' :[B,'D'],
- 'dh' :[B,'Dh'],
- '^n' :[B,'N'],
-
- '_t' :[B,'t'],
- 'th' :[B,'th'],
- '_d' :[B,'d'],
- '_dh' :[B,'dh'],
- 'n' :[B,'n'],
-
- 'p' :[B,'p'],
- 'ph' :[B,'ph'],
- 'f' :[B,'ph'],
- 'b' :[B,'b'],
- 'bh' :[B,'bh'],
- 'v' :[B,'bh'],
- 'm' :[B,'m'],
- 'M' :[F,'M'],
-
- '^j' :[B,'J'],
- 'J' :[B,'J'],
- 'r' :[B,'r'],
- 'R' :[F,'R'],
- 'l' :[B,'l'],
- 'L' :[F,'L'],
- 'W' :[F,'W'],
- 'V' :[F,'W'],
- 'h' :[B,'H'],
- 'kk' :[B,'kK'],
- 'kkm' :[B,'kK/N'],
-
- 'sh' :[B,'sh'],
- '^s' :[B,'Sh'],
- '^sh' :[B,'Sh'],
- 's' :[B,'s'],
-
- '^r' :[B,'rh'],
- '^rh' :[B,'rhh'],
- 'y' :[B,'y'],
- 'Y' :[F,'Y'],
- 'JY' :[F,'Y'],
- '__t' :[B,'t//'],
- '^ng' :[B,'NNG'],
- ':h' :[B,'h'],
- '^' :[F,'NN'],
- '_' :[F,':/'],
-
- 'A' :[S,'A'],
- 'AA' :[S,'Aa'],
- 'I' :[S,'I'],
- 'II' :[S,'II'],
- 'U' :[S,'U'],
- 'UU' :[S,'UU'],
- 'RI' :[S,'RR'],
- 'E' :[S,'E'],
- 'OI' :[S,'OI'],
- 'O' :[S,'O'],
- 'OU' :[S,'OU'],
-
- 'a' :[X,'o',1],
- 'aa' :[s,'a',1],
- 'i' :[s,'i',-1],
- 'ii' :[s,'ii',1],
- 'u' :[s,'u',1],
- 'uu' :[s,'uu',1],
- 'RII' :[s,'rR',1],
- 'e' :[s,'e',-1],
- 'oi' :[s,'oi',-2],
- 'oo' :[s,'oo',11],
- 'o' :[X,'o',1],
- 'ou' :[s,'ou',12],
-
- '.' :[F,'.'],
- '..' :[F,'..'],
- '...' :[F,'...'],
- '|' :[F,'|'],
-
- '~' :[F,'~'],
- '`' :[F,'`'],
- '!' :[F,'!'],
- '1' :[F,'1'],
- '2' :[F,'2'],
- 'at' :[F,'@'],
- '#' :[F,'#'],
- '3' :[F,'3'],
- '$' :[F,'$'],
- '4' :[F,'4'],
- '%' :[F,'%'],
- '5' :[F,'5'],
- '6' :[F,'6'],
- '&' :[F,'&'],
- '7' :[F,'7'],
- '*' :[F,'*'],
- '8' :[F,'8'],
- '(' :[F,'('],
- '9' :[F,'9'],
- ')' :[F,')'],
- '0' :[F,'0'],
- 'dash' :[F,'-'],
- '+' :[F,'+'],
- '=' :[F,'='],
- '|' :[F,'|'],
- '{' :[F,'{'],
- '[' :[F,'['],
- '}' :[F,'}'],
- ']' :[F,']'],
- ':' :[F,':'],
- ';' :[F,';'],
- '"' :[F,'"'],
- "'" :[F,"'"],
- '<' :[F,'<'],
- ',' :[F,','],
- '>' :[F,'>'],
- '.' :[F,'.'],
- '?' :[F,'?'],
- '/' :[F,'/']}
-
-CATCODES = {'SS' :[S,'','','',1],
- 'SB' :[B,'','','',1],
- 'BS' :[S,'','','',1],
- 'BB' :[B,'','/','',1],
- 'BF' :[F,'','','',1],
- 'Bs1' :[S,'','','',1],
- 'Bs-1':[S,'\*','','*',1],
- 'Bs-2':[S,'\*','','*{oi}',0],
- 'Bs11':[S,'\*','','*ea',0],
- 'Bs12':[S,'\*','','*eou',0],
- 'Fs1' :[S,'','','',1],
- 'Fs-1':[S,'\*','','*',1],
- 'Fs-2':[S,'\*','','*{oi}',0],
- 'Fs11':[S,'\*','','*ea',0],
- 'Fs12':[S,'\*','','*eou',0],
- 'FF' :[F,'','','',1],
- 'AX' :[F,'','','',1]}
-
-def blocked(line):
- #print '@ blocked', line , '->',
- m = sre.findall('@[^@]+@',line)
- outline = line
- if not m :
- #print outline
- return(outline)
- else:
- for i in range(len(m)):
- s=m[i][:-1].replace(' ','%X%')
- outline = outline.replace(m[i],s,1)
- #print outline
- return(outline)
-
-def unblock(line):
- #print '@unblock', line, '->',
- m = sre.findall('@[^\s]+',line)
- outline = line
- if not m :
- #print outline
- return(outline)
- else:
- for i in range(len(m)):
- s=m[i].replace('@','').replace('%X%',' ')
- outline = outline.replace(m[i],s)
- #print outline
- return(outline)
-
-def printamp(line):
- #print '@unblock', line, '->',
- m = sre.findall('#AT',line)
- outline = line
- if not m :
- #print outline
- return(outline)
- else:
- for i in range(len(m)):
- outline = outline.replace('#AT','@')
- #print outline
- return(outline)
-
-def readsyll(syll):
- syllparts=[]
- start = 0; end = len(syll)
- while syll[start : end]:
- slice = syll[start : end]
- #print slice
- if AKSAR.has_key(slice):
- syllparts.append(AKSAR[slice])
- start = start + len(slice)
- end = len(syll)
- else :
- end = end -1
- return(syllparts)
-
-def fuse(list1,list2):
- global CCATCODE
- #print list1,list2
- Type1 = list1[0]
- Type2 = list2[0]
-
- if Type2 == s:
- Type3 = str(list2[2])
- elif Type2 == X:
- Type1=A
- Type3=''
- else:
- Type3 =''
-
- Type = Type1+Type2+Type3
-
- #print 'Type:', Type
-
- try:
- CATCODE = CATCODES[Type]
- TARGET = CATCODE[0]
- PREFIX = CATCODE[1]
- MIDFIX = CATCODE[2]
- POSTFIX = CATCODE[3]
- FLAG = CATCODE[4]
-
- #print 'TGT:', TARGET, PREFIX,MIDFIX,POSTFIX,FLAG
- #print 'RAWC', AKSAR[list1[1]][1],AKSAR[list2[1]][1]
-
- c1=list1[1]
- c2=list2[1]
-
- if FLAG == 1 :
- c = PREFIX + c1 + MIDFIX + POSTFIX + c2
- else :
- c = PREFIX + c1 + MIDFIX + POSTFIX
-
- fused = [TARGET,c]
- #print CATCODE
- return(fused)
- except KeyError:
- print '\n ERROR AT LINE:', NCLINE, 'WORD:',NCWORD, '(',CWORD,')'
- return(['ERROR','UNKNOWN CATCODE'])
-
-def fuseatoms(syll):
- slist=readsyll(syll);
- #print slist
- lslist=len(slist);
- l0=slist[0];
- for i in range(1,lslist):
- nextitem = slist[i]
- l0=fuse(l0,nextitem)
-
- return(l0[1])
-
-def fuseword(wrd):
- if wrd[0] == '@' :
- return(wrd)
- syllables = wrd.split('-')
- w0=''
- for eachsyll in syllables:
- syll=eachsyll
- thesyll = fuseatoms(syll)
- w0 = w0 + thesyll
- #print 'FUSED WORD',w0
- return(w0)
-
-def fuseline(line):
- global NCWORD,CWORD
- NCWORD = 0
- #line = blocked(line)
- words = line.split()
- l0=''
- for eachword in words:
- NCWORD=NCWORD+1
- word = eachword
- CWORD=word
- theword=fuseword(word)
- #print 'XX',theword
- l0=l0+' '+theword
- #print 'FUSED LINE', l0
- return(l0)
-
-# The main program
-import sys
-OK=1
-finnam = sys.argv[1]
-foutnam = finnam.split('.')[0] + '.' + 'tex'
-
-fin = file(finnam,'rt')
-fout = file(foutnam,'wt')
-
-textin = fin.readlines()
-nlines = len(textin)
-
-textout = []
-
-fin.close()
-
-for eachline in textin:
- NCLINE = NCLINE+1
- if eachline[0] == '#' :
- lineout = eachline[1:]
- elif eachline[0] == '\\' :
- lineout = eachline
- elif eachline == '\n':
- lineout = eachline
- else :
- line1 = eachline.strip()
- line2 = blocked(line1)
- lineout = fuseline(line2) + '\n'
- lineout = lineout[1:]
- #print ':::', lineout
- if lineout.find('UNKNOWN CATCODE') == -1 :
- lineout = unblock(lineout)
- #print ':::', lineout
- textout.append(printamp(lineout))
- else :
- OK = 0
- fout.close()
-
-if OK == 1:
- fout.writelines(textout)
- fout.close()
- print 'done'
-else:
- print 'Unknown CATCODE, Fix The errors and try again'
diff --git a/Build/source/texk/texlive/linked_scripts/epspdf/epspdf.tlu b/Build/source/texk/texlive/linked_scripts/epspdf/epspdf.tlu
deleted file mode 100755
index 1dba171bf18..00000000000
--- a/Build/source/texk/texlive/linked_scripts/epspdf/epspdf.tlu
+++ /dev/null
@@ -1,2690 +0,0 @@
-#!/usr/bin/env texlua
-
-kpse.set_program_name('texlua')
-
---[[
-epspdf conversion utility
-
-0.6.0: first texlua version
-0.6.1: allow TeX installation on path with spaces
-0.6.2: compatibility fix for luatex 0.81
-0.6.3: compatibility fixes for luatex 0.9x
-0.6.4: adaptations for newer versions of LuaTeX and ghostscript;
- some refactoring; better handling of some corner cases
-0.6.5: eliminate .setpdfwrite from ghostscript commandlines,
- since this is now considered obsolete
-
-Copyright (C) 2006-2020 Siep Kroonenberg
-
-siepo at bitmuis nl
-
-This program is free software, licensed under the GNU GPL, >=2.0.
-This software comes with absolutely NO WARRANTY. Use at your own risk!
-
-Note.
-TeX code for cropping pdfs adapted from Heiko Oberdiek's pdfcrop utility
-
-Program structure
-
-- early initialization
-- functions for:
- - error handling
- - file- and path utilities
- - other general utilities
- - infrastructure: logging and temporary files
- - reading and writing settings
- - gui function for communicating with frontend
- - boundingboxes
- - manipulating [e]ps- and pdf files
-- the PsPdf object:
- - creator functions
- - boundingbox handling
- - one-step conversion methods
-- any_to_any function.
- this function checks options, the one-step converters check for success.
-- main initialization section:
- - collecting system information
- - infrastructure: setting up logging and temp directory
- - settings:
- - defining settings-, descriptions-, options- and auxiliary tables
- - read settings
- - defining commandline options and help function
- - parsing commandline and performing non-conversion options
-- calling any_to_any
-- finishing up
-
-all calls to external programs work on temporary files with a simple
-generated filename. The current directory is a newly-created
-temporary directory. So no need to quote names of input- and output
-filenames.
-
-POSSIBLE EXTENSIONS
-
-- duplicating epstopdf options
-- custom options for gs and pdftops
-
---]]
-
--- some general utilities and globals ---------------------------
-
--- early initializations
-
-eol = false
-path_sep = false
-if os.type=='unix' then
- eol='\n'
- path_sep = ':'
-else
- eol='\r\n'
- path_sep = ';'
-end
-
-infile = false
-outfile = false
-
-bufsize=16000 -- for reading and writing files
-
--- these `declarations' are not really needed;
--- they are here mainly for my own peace of mind
-
-from_gui = false -- whether epspdf is run from the epspsdtk gui
-
-cwd = ''
-
--- Windows: miktex, TL or neither.
--- Actual values determined during system-dependent initialization
-is_miktex = false
-is_tl_w32 = false
-
--- Luatex 1.09 and later replace epdf with pdfe
-
--- some global file- and directory names
-gs_prog = false
-pdftops = false
-epsdir = false
-rcfile = false
-logfile = false
-tempdir = false
-tempfiles = {}
--- childpath = false
--- os.getenv('path') returns the parents path,
--- so we need to keep track ourselves of the child path
-
-options = false -- actual conversion options
-settings = false -- persistent settings; may be stored in config file
-descriptions = false -- help strings for settings
-gs_options = false
-pdf_options = false
-pdf_tail_options = false
-ps_options = false
-gray_options = false
-
--- logging ------------------------
-
--- we open and close the logfile anew for each write.
--- failure to open does not constitute an error.
-
-function print_log(s)
- local f = io.open(logfile, 'a')
- if f then
- f:write(s,eol)
- f:close()
- end
- if from_gui then
- print(s) -- intercepted by the gui
- end
-end
-
-function write_log(s)
- print_log(string.format('%s %s',
- os.date('%Y/%m/%d %H:%M:%S', os.time()), s))
-end
-
-function log_cmd(cmd)
- write_log('[' .. table.concat(cmd, '] [') .. ']')
-end
-
--- error- and debug -------------------------
-
--- Simple-minded error handling. At most, we call a function which
--- tries to write the error message to log before re-raising the error.
-
--- When run from the Tcl/Tk gui, this gui will capture error messages.
-
-function errror(mess)
- if infile and outfile then
- mess = 'Failure to convert '..infile..' to '..outfile..':\n'..mess
- end
- if logfile then pcall(write_log, mess) end
- -- ignore result of pcall: we can do nothing about failure
- error(mess, 2)
-end
-
-function warn(mess)
- if logfile then write_log(mess) end
- print(mess)
-end
-
--- function dbg(mess)
--- if options.debug then
--- warn(mess)
--- end
--- end
-
--- file- and path utilities ----------------
-
--- function ep_shortname(path)
--- if os.type=='unix' then
--- return path
--- else
--- -- shortname appears not to work under miktex
--- -- so return original path as a fallback
--- local sp = lfs.shortname(path)
--- return sp or path
--- end
--- end
-
--- prepend or append dir to path if necessary
-function maybe_add_path(dir, append)
- local dircmp = path_sep .. dir .. path_sep
- local pathcmp = path_sep .. kpse.var_value('PATH') .. path_sep
- -- case folding
- if os.name=='windows' or os.name=='cygwin' or os.name=='macosx' then
- dircmp = string.lower(dir)
- pathcmp = string.lower(pathcmp)
- end
- -- slash flipping
- if os.type=='windows' then
- pathcmp = (string.gsub(pathcmp, '/', '\\'))
- dircmp = (string.gsub(dircmp, '/', '\\'))
- end
- if not string.find(pathcmp, dircmp, 1, true) then
- if not append then -- prepend
- os.setenv('PATH', dir..path_sep..kpse.var_value('PATH'))
- else -- append
- os.setenv('PATH', kpse.var_value('PATH')..path_sep..dir)
- end
- end
-end
-
-function fw(path)
- if os.type=='windows' then
- return string.gsub(path, '\\', '/')
- else
- return path
- end
-end
-
-function absolute_path(path)
-
- --[[ Return absolute normalized version of path, interpreted
- from the directory from where the program was called.
-
- We use the fact that lfs.currentdir() always returns an absolute and
- normalized path. So we go to the parent directory of path, ask for
- the current directory and then combine the current directory with
- the base filename.
-
- On windows, texlua has no trouble cd-ing into a UNC path.
-
- The function returns nil if there is no valid parent path.
- This might be an issue if path is a directory,
- but we shall apply this function only on files.
- It is ok if path itself does not exist. --]]
-
- path = fw(path)
-
- local present_dir = fw(lfs.currentdir())
-
- lfs.chdir(cwd)
-
- local parentdir
- local filename
-
- if string.match(path, '/') then
- parentdir, filename = string.match(path,'^(.*)/([^/]*)$')
- if parentdir=='' then
- parentdir = '/'
- -- on unix, this is an absolute path. on windows, it is not
- if os.type=='windows' then
- lfs.chdir('/')
- parentdir = fw(lfs.currentdir())
- end
- elseif os.type=='windows' and string.match(parentdir,'^[a-zA-Z]:$') then
- parentdir = string.sub(parentdir,1,2)..'/'
- else
- if not lfs.chdir(parentdir) then
- parentdir = nil
- else
- parentdir = fw(lfs.currentdir())
- end
- end
- elseif os.type=='windows' and string.match(path,'^[a-zA-Z]:') then
- -- windows: d:file
- parentdir = string.sub(path,1,2)
- if not lfs.chdir(parentdir) then
- parentdir = nil
- else
- parentdir = fw(lfs.currentdir())
- filename = string.sub(path,3)
- end
- else
- parentdir = fw(lfs.currentdir())
- filename = path
- end
- lfs.chdir(present_dir)
- if not parentdir then
- return nil
- elseif string.sub(parentdir,-1)=='/' then
- return parentdir..filename, parentdir
- else
- return parentdir..'/'..filename, parentdir
- end
-end -- absolute_path
-
--- check whether prog is on the searchpath.
--- we need it only under unix,
--- so we save ourselves the trouble of accommodating windows.
--- we return the original string, although we only need a yes or no answer
-
-function find_on_path (prog)
- if os.type == 'unix' then
- for d in string.gmatch(os.getenv('PATH'), '[^:]+') do
- if lfs.isfile(d..'/'..prog) then
- return prog
- end
- end
- else
- for d in string.gmatch(os.getenv('PATH'), '[^;]+') do
- if lfs.isfile(d..'\\'..prog) then
- return prog
- end
- end
- end
- return false
-end -- find_on_path
-
-function dir_writable(d)
- -- because directory attributes do not tell the whole story,
- -- we actually try to create a file in the directory.
- if not lfs.isdir(d) then
- return false
- end
- -- try to create a new file, write to it and delete it afterwards
- for i=1,1000 do
- local s = d .. '/' .. tostring(i)
- if not lfs.isfile(s) then
- local fh = io.open(s, "w")
- if fh then
- fh:write('test')
- fh:close()
- if lfs.isfile(s) then
- if lfs.attributes(s, 'size') > 0 then
- os.remove(s)
- return true
- else
- os.remove(s)
- return false -- open and write resulted in empty file
- end -- lfs.attributes
- else
- return false -- open and write did not result in a file
- end -- lfs.isfile
- end -- fh
- return false -- filename available; could not open for write
- end -- not lfs.isfile
- end -- for
- return false
-end
-
-function system_tempdir ()
- local d
- if os.type=='windows' then
- d = os.getenv('TEMP')
- if not d then
- d = os.getenv('TMP')
- end
- else
- d = os.getenv('TMPDIR')
- if not d then
- d = '/tmp'
- end
- end
- -- cygwin: $TEMP=/tmp, root '/' being root of cygwin installation
- if d and not dir_writable(d) then
- d = false
- end
- return d
-end
-
--- other general utilities ---------------------------
-
--- check whether el occurs in array lst
-function in_list (el, lst)
- if not lst then return false end
- for _,p in ipairs(lst) do
- if el == p then
- return true
- end
- end
- return false
-end -- in_list
-
--- remove leading and trailing, but not embedded spaces
-function strip_outer_spaces(s)
- s = string.gsub(s, '%s*$', '')
- s = string.gsub(s, '^%s*', '')
- return s
-end -- strip_outer_spaces
-
-function join(t, sep, lastsep)
- -- there is a table function concat which does this,
- -- but without optional different lastsep
- if t==nil or #t<1 then return '' end -- or should we return nil?
- local s = t[1]
- for i=2,#t do -- ok if #t<2
- if i==#t and lastsep then
- s = s .. lastsep .. t[i]
- else
- s = s .. sep .. t[i]
- end
- end
- return s
-end -- join
-
--- combine several tables into one.
--- the parameter is a table of tables.
-function tab_combine (t)
- local res = {}
- for _,tt in ipairs(t) do
- for __, ttt in ipairs(tt) do
- table.insert(res, ttt)
- end
- end
- return res
-end -- tab_combine
-
--- files ----------------------------------------------------
--- Copy a file in chunks, with optional length and offset.
--- Since files may be very large, we copy them piecemeal.
--- An initial chunk of size bufsize should be plenty to include
--- any interesting header information.
-
-function slice_file(source, dest, len, offset, mode)
- -- The final three parameters can be independently left out by
- -- specifying false as value
- -- Assume caller ensured parameters of correct type.
- -- We do not allow negative offsets.
-
- local copy2self = false
- if source==dest then copy2self = true end
- if os.type=='unix' and
- lfs.attributes(source,'ino')==lfs.attributes(dest,'ino') then
- copy2self = true
- end
- if copy2self and not len and not offset and mode~='ab' then
- return -- nothing to do
- elseif copy2self then
- errror('slice_file invoked with identical source and destination '..
- source..' and non-simple copy')
- end
- -- in practice any_to_any already checks for this.
- -- in addition, the main program makes a backup if infile==outfile
-
- local sz = lfs.attributes(source, 'size')
- if not offset then
- offset = 0
- elseif offset>sz then
- offset = sz
- end
- if not len or len>sz-offset then
- len = sz - offset
- end
- if not mode then mode = 'wb' end
- local buffer=''
- local s=io.open(source, 'rb')
- s:seek('set', offset)
- local copied = 0
- local d=io.open(dest, mode)
- if not d then errror('slice_file: failed to copy to '..dest) end
- local slen = len
- while slen>0 do
- if slen>=bufsize then
- buffer = s:read(bufsize)
- slen = slen - bufsize
- else
- buffer = s:read(slen)
- slen = 0
- end
- if not d:write(buffer) then
- errror('slice_file: failed to copy to '..dest)
- end
- end
- s:close()
- d:close()
-end -- slice_file
-
-function move_or_copy(source, dest)
- if lfs.isfile(dest) and lfs.attributes(dest, 'size')>0 then
- warn('Removing old '..dest)
- os.remove(dest) -- in case of failure, go ahead anyway
- end
- -- Windows: try first renaming in-place before moving to the right directory
- if os.type == 'windows' then
- if os.rename(source, source..'.renamed') then
- source = source..'.renamed'
- end
- end
- if not os.rename(source, dest) then
- slice_file(source, dest) -- bails out on failure
- local ok, err_mess = os.remove(source)
- if not ok then
- warn('Failed to remove old ' .. source .. ': ' .. err_mess)
- end
- end
-end
-
--- temporary files ----------------------------------------
-
--- tempdir = false -- will be created later and chdir-ed into
--- tempfiles initialized early to empty table
-
--- We just name our temporary files nn.<ext> with successive nn.
--- We cannot exclude that another process uses our tempdir
--- so we have to first check for each new file whether it already exists.
--- Epspdf does all the real work from the temp directory.
-
-function mktemp(ext)
- local froot, fname, f, g
- for i=0,99 do
- froot = string.format('%02d.', i)
- fname = froot..ext
- if ext~='tex' then
- if not lfs.isfile(fname) then
- f = io.open(fname, 'wb')
- if not f then
- errror('Cannot create temporary file '..fname)
- end
- f:close()
- table.insert(tempfiles, fname)
- return froot..ext -- no need to record pdf name
- end
- else
- -- tex; we also need a pdf
- if not lfs.isfile(fname) and not lfs.isfile(froot..'pdf') then
- local f = io.open(fname, 'wb')
- if not f then
- errror('Cannot create temporary file '..fname)
- end
- f:close()
- table.insert(tempfiles, fname)
- fname = froot..'pdf'
- g = io.open(fname, 'wb')
- if not g then
- errror('Cannot create temporary file '..fname)
- end
- g:close()
- table.insert(tempfiles, fname)
- table.insert(tempfiles, froot..'log')
- return froot..ext -- no need to record pdf name
- end
- end -- if
- end -- for
- errror('Cannot create temporary file in '..tempdir)
-end
-
-function waitasec()
- -- stupid windows file locking; assume vista or later
- if os.type=='windows' then
- os.execute('timeout /t 1 /nobreak >nul')
- -- else do nothing
- end
- -- error checking pointless
-end
-
-function cleantemp()
- lfs.chdir(tempdir)
- if os.type=='windows' then waitasec() end
- for _,f in ipairs(tempfiles) do
- if lfs.isfile(f) then
- local success, mess = os.remove(f)
- if not success then write_log(mess) end
- end
- end
- local empty = true
- for f in lfs.dir('.') do
- if f ~= '.' and f ~= '..' then
- empty = false
- write_log('Temp dir '..tempdir..' contains '..f..' therefore not removed')
- break
- end
- end
- if os.type=='windows' then waitasec() end
- lfs.chdir('..')
- if empty then
- local res, mess
- res, mess = lfs.rmdir(tempdir)
- if not res then
- write_log('Failed to remove empty '..tempdir..'\n'..mess)
- end
- end
-end
-
--- gs_epsdevice -----------------------
-
-function gs_epsdevice()
- local gh = io.popen(gs_prog..' -help')
- local s = gh:read("*a")
- gh:close()
- if string.find(s,'eps2write') then
- return 'eps2write'
- elseif string.find(s,'epswrite') then
- return 'epswrite'
- else
- return false
- end
-end
-
--- settings -----------------------
-
-function write_settings (file)
- local f
- if file then
- f = io.open(file, 'wb')
- if not f then
- return
- end
- else -- stdout to be captured by epspdftk
- f = io.output()
- end
- for k, v in pairs(settings) do
- if descriptions[k] and file then
- f:write(eol, '# ', descriptions[k], eol)
- end
- f:write(k, ' = ', tostring(v), eol)
- end
- if file then
- f:close()
- end
-end
-
-function read_settings(file)
- -- read and interpret rcfile
- -- we shall ignore illegal entries.
- local contents
- local f
- if file then
- f = io.open(rcfile, 'rb')
- if not f then
- return
- end
- else
- f = io.input()
- end
- contents = f:read(10000)
- if file then
- f:close()
- end
- if not contents or contents=='' then
- return
- end
- -- remove initial \r and \n characters
- contents = string.gsub(contents, '^[\r\n]*', '');
- -- gmatch chops contents into series of non-line-ending characters
- -- possibly followed by line-ending characters i.e. in lines
- local k, v, vl, vnum
- for l in string.gmatch(contents, '[^\r\n]+[\r\n]*') do
- l = string.match(l,'[^\r\n]*')
- if not string.match(l, '^#') then
- k, v = string.match(l, '^%s*([^%s]+)%s*=%s*(.*)$')
- if v then v = string.gsub(v,'%s*$', '') end
- -- now handle k and v
- if k == 'pdf_target' then
- -- ignore unless valid option
- if in_list(v, pdf_targets) then
- settings[k] = v
- end
- elseif k == 'pdf_version' then
- -- ignore unless valid option
- if in_list(v, pdf_versions) then
- settings[k] = v
- end
- elseif k == 'ignore_pdftops' then
- vl = string.lower(string.sub(v,1,1))
- if v == 0 or vl == 'n' or vl == 'f' then
- settings.use_pdftops = true
- elseif v == 1 or vl == 'y' or vl == 't' then
- settings.use_pdftops = false
- end
- elseif k == 'use_pdftops' then
- vl = string.lower(string.sub(v,1,1))
- if v == '0' or vl == 'n' or vl == 'f' then
- settings.use_pdftops = false
- elseif v == '1' or vl == 'y' or vl == 't' then
- settings.use_pdftops = true
- end
- -- final three settings not used by epspdf itself but
- -- passed along to epspdftk
- elseif k == 'ps_viewer' then
- settings.ps_viewer = v
- elseif k == 'pdf_viewer' then
- settings.pdf_viewer = v
- elseif k == 'default_dir' then
- settings.default_dir = v
- end -- test for k
- end -- not matching ^#
- end -- for
-end -- read settings
-
-function version_added()
- for _, v in pairs(pdf_options) do
- if string.find(v, '-dCompatibilityLevel') then
- return true
- end
- end
- return false
-end
-
-function maybe_add_version_parameter()
- if options.type=='pdf' and not options.bbox and settings.pdf_version and
- settings.pdf_version~='default' and not version_added() then
- table.insert(pdf_options, '-dCompatibilityLevel#'..settings.pdf_version)
- end
-end
-
--- gui: reading and writing settings -----------
-
-function gui(action)
- -- use stdin for reading settings from gui, and stdout for writing
- if action=='config_w' then
- -- called at start of epspdftk
- write_settings() -- to pipe epspdf => epspdftk
- os.exit()
- elseif action=='config_r' then
- read_settings() -- from 'pipe' epspdftk => epspdf
- write_settings(rcfile)
- os.exit()
- else
- from_gui = true
- end
-end
-
--- boundingboxes ---------------------------------------------------
-
--- [HR]Bb.coords names same as those of epdf PDFRectangle
--- but the new pdfe simply uses an array
-
-Bb = {}
-Bb.coords = {'x1', 'y1', 'x2', 'y2'}
-
-function Bb:from_rect(r)
- -- also handle the case that r is a 4-element array:
- if not r.x1 then r.x1 = r[1] end
- if not r.y1 then r.y1 = r[2] end
- if not r.x2 then r.x2 = r[3] end
- if not r.y2 then r.y2 = r[4] end
-
- for _,k in ipairs(self.coords) do
- if not r[k] or type(r[k])~='number' then
- errror('from_rect called with illegal parameters')
- end
- -- sanity check on size
- -- FIXME: this limit is far too high
- if r[k]+.5==r[k] or r[k]-.5==r[k] then
- errror('Bb:from_rect: ' .. r[k] ..' greater than maxint')
- end
- local b = {}
- local eps = 0.000001
- b.x1, b.x2 = math.floor(math.min(r.x1, r.x2) + eps),
- math.ceil(math.max(r.x1, r.x2) - eps)
- b.y1, b.y2 = math.floor(math.min(r.y1, r.y2) + eps),
- math.ceil(math.max(r.y1, r.y2) - eps)
- if b.x1==b.x2 or b.y1==b.y2 then
- errror('from_rect: width or height is zero')
- end
- setmetatable(b, {__index=self})
- return b
- end
-end
-
-Bb.bb_pat = '^%s*%%%%BoundingBox:'
-Bb.bb_end = '^%s*%%%%BoundingBox:%s*%(%s*atend%s*%)'
-
-function Bb:from_comment(s)
- local p = self.bb_pat..'%s*([-+%d]+)'..string.rep('%s+([-+%d]+)',3)
- local b = {}
- b.x1, b.y1, b.x2, b.y2 = string.match(s, p)
- if not b.y2 then
- errror('Bb.from_comment: illegal boundingbox string ' .. s)
- end
- for _,k in ipairs(self.coords) do
- b[k] = tonumber(b[k])
- end
- return Bb:from_rect(b)
-end
-
-function Bb:nonnegative ()
- return self.x1>=0 and self.y1>=0
-end
-
-function Bb:comment()
- -- if options.debug then print(debug.traceback()) end
- return string.format('%%%%BoundingBox: %d %d %d %d',
- self.x1, self.y1, self.x2, self.y2)
-end
-
--- hires boundingboxes ---------------------------------------------
-
-HRBb = {}
-
-setmetatable(HRBb, {__index=Bb})
-
-function HRBb:from_rect(r)
- -- also handle the case that r is a 4-element array:
- if not r.x1 then r.x1 = r[1] end
- if not r.y1 then r.y1 = r[2] end
- if not r.x2 then r.x2 = r[3] end
- if not r.y2 then r.y2 = r[4] end
-
- for _,k in ipairs(self.coords) do
- if not r[k] or type(r[k])~='number' then
- errror('from_rect called with illegal parameters')
- end
- -- sanity check on size
- if r[k]+.5==r[k] or r[k]-.5==r[k] then
- errror('HRBb:from_rect: ' .. b[k] ..' greater than maxint')
- end
- local b = {}
- b.x1, b.x2 = math.min(r.x1, r.x2), math.max(r.x1, r.x2)
- b.y1, b.y2 = math.min(r.y1, r.y2), math.max(r.y1, r.y2)
- if b.x1==b.x2 or b.y1==b.y2 then
- errror('from_rect: width or height is zero')
- end
- setmetatable(b, {__index=self})
- return b
- end
-end
-
-HRBb.bb_pat = '^%s*%%%%HiResBoundingBox:'
-HRBb.bb_end = '^%s*%%%%HiResBoundingBox:%s*%(%s*atend%s*%)%s*$'
-
-function HRBb:from_comment(s)
- local p = self.bb_pat..'%s*([-+.%deE]+)'..string.rep('%s+([-+.%deE]+)',3)
- local b = {}
- b.x1, b.y1, b.x2, b.y2 = string.match(s, p)
- if not b.y2 then
- errror('HRBb.from_comment: illegal boundingbox string ' .. s)
- end
- for _,k in ipairs(self.coords) do
- b[k] = tonumber(b[k])
- end
- return HRBb:from_rect(b)
-end
-
-function HRBb:nonnegative ()
- return self.x1>=0 and self.y1>=0
-end
-
-function HRBb:comment()
- return string.format('%%%%HiResBoundingBox: %f %f %f %f',
- self.x1, self.y1, self.x2, self.y2)
-end
-
---[[
-
--- no longer used: gs handles this
--- call this one also via pcall
-function HRBb:wrapper()
-
- -- local fn = mktemp('ps')
- -- local f = io.open(fn, 'wb')
- -- f.write(string.format('<< /PageSize [%f %f] >> setpagedevice\n',
- -- self.x2 - self.x1, self.y2 - self.y1))
- -- f.write(string.format('gsave\n%f %f translate\n', -self.x1, -self.y1))
- -- f:close()
- -- return fn
-
- return string.format(
- '<< /PageSize [%f %f] >> setpagedevice gsave %f %f translate',
- self.x2 - self.x1, self.y2 - self.y1, -self.x1, -self.y1)
-end
-
---]]
-
--- manipulating eps/ps/pdf files -----------------------------------
-
-function identify()
- local f = io.open(infile, 'rb')
- if not f then
- errror('Failure to open '..infile..' for identification')
- end
- local filestart= f:read(23)
- f:close()
- if not filestart or filestart=='' then
- return false
- elseif string.match(filestart,'^\197\208\211\198') then -- c5 d0 d3 c6
- return 'epsPreview'
- elseif string.match(filestart,'^%%!PS%-Adobe%-%d%.%d EPSF%-%d%.%d') then
- return 'eps'
- elseif string.match(filestart,'^%%!PS%-Adobe%-%d%.%d') then
- for _, p in ipairs({'.eps', '.epi', '.epsi', '.epsf'}) do
- if string.sub(string.lower(infile), -1-string.len(p),-1) == p then
- return 'eps'
- else
- return 'ps'
- end
- end
- return 'ps'
- elseif string.match(filestart, '^%%PDF') then
- return 'pdf'
- else
- return false
- end
-end -- identify
-
-function pdf_props(path)
- local pdfdoc, pgs, maver, miver
- if pdfe then
- pdfdoc = pdfe.open(path)
- if pdfdoc then
- pgs = pdfe.getnofpages(pdfdoc)
- maver, miver = pdfe.getversion(pdfdoc)
- end
- if not (pdfdoc and pgs and maver and miver) then
- errror('pdfe failed to get information about '..path)
- end
- pdfe.close(pdfdoc)
- else
- local cat
- pdfdoc = epdf.open(path)
- if pdfdoc then
- cat = pdfdoc:getCatalog()
- if cat then
- pgs = cat:getNumPages()
- end
- maver = pdfdoc:getPDFMajorVersion()
- miver = pdfdoc:getPDFMinorVersion()
- end
- if not (pdfdoc and pgs and maver and miver) then
- errror('epdf failed to get information about '..path)
- end
- -- epdf.close(pdfdoc)
- end
- -- if os.type=='windows' then waitasec() end
- if maver > 1 then
- print(path..' has pdf major version \n'..tostring(maver)..
- ' which is unsupported;\n'..
- 'Continuing with fingers crossed...')
- end
- return pgs, miver, maver
-end -- pdf_props
-
-function info()
- local intype = identify()
- if not intype then
- print(infile..' has an unsupported filetype.')
- elseif intype~='pdf' then
- print(infile..' has type '..intype..'.')
- else
- local pgs, miver, maver = pdf_props(infile)
- print(infile..' has type pdf, version '..tostring(maver)..
- '.'..tostring(miver)..' and has '..tostring(pgs)..' pages.')
- end
- os.exit()
-end
-
--- PsPdf object -------------------------------------------------
-
-PsPdf = {}
-
--- creators
-
-function PsPdf:new(ext)
- local psp = {}
- setmetatable(psp, {__index = self})
- -- assign temp file
- psp.path = mktemp(string.lower(ext))
- if string.lower(ext)=='pdf' then
- psp.type = 'pdf'
- elseif string.lower(ext)=='eps' then
- psp.type = 'eps'
- elseif string.lower(ext)=='ps' then
- psp.type = 'ps'
- else
- psp.type = false
- end
- if psp.type=='eps' then
- psp.pages = 1
- end
- psp.bb = false
- psp.hrbb = false
- return psp
-end -- PsPdf:new
-
-function PsPdf:from_path(path)
- local psp = {}
- setmetatable(psp, {__index = self})
- psp.path = path
- if lfs.isfile(path) then
- -- turn existing file into PsPdf object.
- psp.type = identify(psp.path)
- if psp.type=='pdf' then
- psp.pages, psp.miver, psp.maver = pdf_props(psp.path)
- end
- else
- errror('PsPdf:from_path called with non-existant file '..path)
- end
- if psp.type=='eps' then
- psp.pages = 1
- end
- psp.bb = false
- psp.hrbb = false
- -- only calculate when needed
- return psp
-end -- PsPdf:from_path
-
--- do we need to downgrade the pdf to a lower version?
--- consider [e]ps lower than any pdf version
-function PsPdf:to_downgrade()
- if self.type~='pdf' then
- return false
- elseif options.type~='pdf' then
- return true
- elseif settings.pdf_version=='default' then
- return false
- elseif settings.pdf_version~='default' and
- self.maver+0.1*self.miver-0.001 > tonumber(settings.pdf_version) then
- -- -0.001: exact binary representation of pdf_version not guaranteed
- return true
- else
- return false
- end
-end
-
---[[ getting boundingbox property from file itself --------------
-
-get_bb_simple: use only for eps PsPdf objects we generated
-ourselves, so we can assume that the bbox comments are in the header
-and the hires bb lies within the lores bb.
-Of course the file itself is not rewritten.
-
---]]
-
-function PsPdf:get_bb_simple()
- if self.type~='eps' then
- errror('get_bb_simple called with non-eps file '..self.path)
- end
- self.bb = false
- self.hrbb = false
- local slurp = false
- local f = io.open(self.path, 'rb')
- if f then
- slurp = f:read(bufsize)
- f:close()
- end
- lines = {}
- for l in string.gmatch(slurp, '[^\n\r]+') do
- if string.match(l, Bb.bb_pat) then
- self.bb = Bb:from_comment(l)
- elseif string.match(l, HRBb.bb_pat) then
- self.hrbb = HRBb:from_comment(l)
- elseif self.bb then
- break -- stop looking; we expect hrbb next to bb
- end
- if self.bb and self.hrbb then break end
- end
- if not self.bb then
- errror('No valid boundingbox for generated file' .. self.path)
- end
- return self -- no real need for a return value
-end
-
-function PsPdf:bb_from_gs()
-
- if self.type=='ps' then
- errror('bb_from_gs called with ps file '..self.path)
- -- not needed for generic PostScript,
- -- page selection only works with pdf files, so we save ourselves
- -- the trouble of picking the right bbox from a list
- end
- if self.type=='eps' and not self.bb:nonnegative() then
- errror('bb_from_gs called on ' .. self.path ..
- ' which has some negative boundingbox coordinates')
- -- any_to_any should guard against such an invocation
- end
-
- -- Since Ghostscript writes the boundingbox comments to stderr,
- -- we need a shell to intercept this output:
-
- local bb_file = mktemp('dsc')
- -- a somewhat low resolution parameter may help gs
- -- deal with eps files with large coordinates
- -- but this may impact the accuracy of the HRBb
- local cmdline
- if self.type=='eps' and (self.bb.x2 > 850 or self.bb.y2 > 850) then
- cmdline = gs_prog .. ' -r300 ' .. table.concat(gs_options,' ')
- else
- cmdline = gs_prog .. ' ' .. table.concat(gs_options,' ')
- end
- if self.type=='pdf' then
- pg = options.page or 1
- cmdline = cmdline .. ' -dFirstPage#' .. tostring(pg) ..
- ' -dLastPage#' .. tostring(pg)
- end
- cmdline = cmdline .. ' -sDEVICE#bbox ' .. self.path .. ' 2>'..bb_file
-
- -- execute shell command
-
- local r, cmd
- write_log('os.execute: '..cmdline)
- r = os.execute(cmdline)
- if not r then
- errror('Cannot get fixed boundingbox for '..self.path)
- end
-
- -- read new bbox from ghostscript output
- -- can we really count on the plain bb coming first?
- -- OTOH, I would rather not introduce unnecessary complexity
- -- still, it may be better to match each line with [HR]Bb_pat
-
- local bb = false
- local hrbb = false
- local fin = io.open(bb_file, 'r')
- if fin then
- for i=1,10 do -- actually, 2 should suffice
- local l = fin:read("*line")
- if not l then break end
- if string.match(l, Bb.bb_pat) then
- bb = Bb:from_comment(l)
- end
- if string.match(l, HRBb.bb_pat) then
- hrbb = HRBb:from_comment(l)
- end
- end
- fin:close()
- end
- if not bb or not hrbb then
- errror('Cannot get fixed boundingbox for '..self.path)
- end
- return bb, hrbb
-end
-
--- eps_clean: remove some problem features from eps (new file & object)
-
-function PsPdf:eps_clean()
-
- -- return a PsPdf object referring to a new file
- -- without a preview header and with boundingbox(es) in the header.
- -- return a new file even if no changes were needed.
-
- local function bytes2num (s, i)
- -- convert substring s[i..i+3] to a number.
- -- by working byte for byte we avoid endian issues
- local n = string.byte(s, i+3)
- for j=2,0,-1 do n = 256*n + string.byte(s, i+j) end
- return n
- -- somehow the explicit expression below didn't work
- -- return ((256 * (256 * (256 * string.byte(s,i+3)) + string.byte(s,i+2))
- -- + string.byte(s,i+1)) + string.byte(s,i))
- end
-
- if self.type~='eps' and self.type~='epsPreview' then
- errror('epsclean called with non-eps file ' .. self.path)
- end
- local offset, ps_length = false, false
- local fin, fout
- if self.type=='eps' then
- offset = 0
- ps_length = lfs.attributes(self.path, 'size')
- else
- -- read TOC; see Adobe EPS specification
- -- interpret byte for byte, in case the platform is not little-endian
- fin = io.open(self.path, 'rb')
- if fin then
- local toc = fin:read(12)
- fin:close()
- if toc and string.len(toc)==12 then
- offset = bytes2num(toc, 5)
- ps_length = bytes2num(toc, 9)
- end
- end
- if not offset then
- errror('Could not read preview header of ' .. self.path)
- end
- end
-
- -- create the PsPdf object which is to be returned
-
- local psp
- psp = PsPdf:new('eps')
-
- -- read an initial and if necessary a final chunk of the file
- -- to find boundingbox comments.
-
- local atend = false
- local hr_atend = false
- local slurp -- the read buffer
- local l -- contains current scanned line; split off from slurp
- -- pre_lines: scanned header lines; alternately lines and eols
- local pre_lines = {}
- -- new_offset: offset plus combined length of scanned header lines
- local new_offset = offset
- -- post_lines: scanned trailer lines
- local post_lines = {}
- -- middle_length: ps_length minus scanned header- and and maybe trailer parts
- -- this is the length of file that will be copied wholesale.
- local middle_length
- local i, i_bb, i_hrbb
- local j, j_bb, j_hrbb, j_end
- -- j_end: index of final scanned trailer line
- -- no i_end necessary: for header lines we can use #pre_lines.
-
- fin = io.open(self.path, 'rb')
- if not fin then errror('Cannot read '..self.path) end
- fin:seek('set', offset)
-
- -- remaining, unscanned length of input buffer slurp
- local unscanned = math.min(ps_length,bufsize)
- slurp = fin:read(unscanned)
-
- -- unnecessary:
- psp.bb = nil
- psp.hrbb = nil
-
- i, i_bb, i_hrbb = 0, false, false
- while unscanned>0 do
- i = i+1
- if string.find(slurp,'[\n\r]')==1 then
- l,slurp = string.match(slurp, '^([\n\r]+)(.*)$')
- else
- l,slurp = string.match(slurp, '^([^\n\r]+)(.*)$')
- if string.match(l, Bb.bb_end) then
- atend = true
- i_bb = i
- elseif string.match(l, Bb.bb_pat) then
- psp.bb = Bb:from_comment(l)
- -- from_comment errors out on failure; no need to check return value
- i_bb = i
- elseif string.match(l, HRBb.bb_end) then
- hr_atend = true
- i_hrbb = i
- elseif string.match(l, HRBb.bb_pat) then
- psp.hrbb = HRBb:from_comment(l)
- i_hrbb = i
- end -- bbox line
- end -- eol/non-eol
- pre_lines[i] = l
- unscanned = unscanned - string.len(l)
- if (i_bb and (i_hrbb or (i_bb<(i-1)))) or unscanned<=0 then
- -- condition i_bb<i-1:
- -- We do not want to find the hrbb of an included eps.
- -- Therefore we stop looking for hrbb if it is not next to bb
- -- (with an intervening eol)
- -- Note that the header comments are not necessarily terminated
- -- with a %%EndComments line; see Adobe DSC spec 5001
- break
- end -- deciding whether to stop
- end -- while
- new_offset = offset + string.len(table.concat(pre_lines))
- middle_length = ps_length - string.len(table.concat(pre_lines))
-
- if atend or hr_atend then
- -- find boundingbox comments, starting from end of postscript
- if ps_length>bufsize then
- fin:seek('set',offset+ps_length-bufsize)
- unscanned = bufsize
- slurp = fin:read(unscanned)
- else
- -- use what is left from old slurp
- unscanned = string.len(slurp)
- end
- j = 1 -- count down from 0
- j_bb, j_hrbb, j_end = false, false, false
- while unscanned>0 do
- j = j - 1
- if string.find(slurp,'[\n\r]', string.len(slurp)) then
- slurp,l = string.match(slurp, '^(.-)([\n\r]+)$')
- -- '-': non-greedy matching
- else
- slurp,l = string.match(slurp, '^(.-)([^\n\r]+)$')
- if string.match(l, Bb.bb_pat) then
- psp.bb = Bb:from_comment(l)
- j_bb = j
- elseif string.match(l, HRBb.bb_pat) then
- psp.hrbb = HRBb:from_comment(l)
- j_hrbb = j
- end -- bbox line
- end -- eol/non-eol
- post_lines[j] = l
- unscanned = unscanned - string.len(l)
- if (psp.bb and
- (psp.hrbb or not hr_atend or j_bb>(j+1))) or unscanned<=0 then
- -- stop looking
- j_end = j
- break
- end -- deciding whether to stop
- end -- while
- middle_length = middle_length -
- string.len(table.concat(post_lines, '', j_end, 0))
- end --if atend
- fin:close()
- -- fix boundingbox lines
- if atend and j_bb then
- -- pre_lines[i_bb] = post_lines[j_bb]
- pre_lines[i_bb] = psp.bb:comment() -- WHY DOESNT THIS WORK ????
- post_lines[j_bb] = ''
- post_lines[j_bb+1] = ''
- end
- if hr_atend and j_hrbb then
- -- pre_lines[i_hrbb] = post_lines[j_hrbb]
- pre_lines[i_hrbb] = psp.hrbb:comment()
- post_lines[j_hrbb] = ''
- post_lines[j_hrbb+1] = ''
- end
- -- create cleaned eps file
- fout = io.open(psp.path, 'wb')
- if not fout then errror('Cannot create new file '..psp.path) end
- fout:write(table.concat(pre_lines))
- fout:close()
- slice_file(self.path, psp.path, middle_length, new_offset, 'ab')
- fout = io.open(psp.path, 'ab')
- fout:write(table.concat(post_lines, '', j_end, 0))
- fout:close()
- return psp
-end -- eps_clean
-
--- tight boundingbox (new file & object)
-
-function PsPdf:eps_crop()
-
- -- conversion is not done by an external program, although
- -- we invoke Ghostscript with a bbox device for a tight boundingbox.
- -- We use both the regular and the hires boundingbox from gs.
- -- The eps should already have been cleaned up by eps_clean,
- -- and the current boundingbox should not contain negative coordinates,
- -- otherwise the bbox output device may give incorrect results.
- -- Only the boundingbox in the eps is rewritten.
-
- -- create the PsPdf object which is to be returned
-
- local psp = PsPdf:new('eps')
-
- -- read new bbox from ghostscript output
-
- psp.bb, psp.hrbb = self:bb_from_gs()
-
- -- rewrite header with new boundingboxes
-
- local slurp -- the read buffer
- local l -- contains current scanned line; split off from slurp
- -- pre_lines: scanned header lines; alternately lines and eols
- local pre_lines = {}
- -- offset: combined length of scanned header lines
- local offset = 0
- local ps_length = lfs.attributes(self.path, 'size')
- local i, i_bb, i_hrbb
-
- fin = io.open(self.path, 'rb')
- if not fin then errror('Cannot read '..self.path) end
-
- -- remaining, unscanned length of input buffer slurp
- local unscanned = math.min(ps_length,bufsize)
- slurp = fin:read(unscanned)
- i, i_bb, i_hrbb = 0, false, false
- while unscanned>0 do
- i = i+1
- if string.find(slurp,'[\n\r]')==1 then
- l,slurp = string.match(slurp, '^([\n\r]+)(.*)$')
- else
- l,slurp = string.match(slurp, '^([^\n\r]+)(.*)$')
- if string.match(l, Bb.bb_pat) then
- i_bb = i
- elseif string.match(l, HRBb.bb_pat) then
- i_hrbb = i
- end -- bbox line
- end -- eol/non-eol
- pre_lines[i] = l
- unscanned = unscanned - string.len(l)
- if (i_bb and (i_hrbb or (i_bb<(i-1)))) or unscanned<=0 then
- break
- end
- end -- while
- fin:close()
- offset = string.len(table.concat(pre_lines))
-
- if i_hrbb then
- pre_lines[i_bb] = psp.bb:comment()
- pre_lines[i_hrbb] = psp.hrbb:comment()
- else
- -- jam both bbox comments into one slot, with an intervening eol.
- -- for the sake of conformity, we copy an existing eol.
- pre_lines[i_bb] = psp.bb:comment() .. pre_lines[i_bb-1] ..
- psp.hrbb:comment()
- end
-
- -- write a new eps file
-
- fout = io.open(psp.path, 'wb')
- if not fout then errror('Cannot write new file '.. psp.path) end
- fout:write(table.concat(pre_lines))
- fout:close()
- slice_file(self.path, psp.path,
- lfs.attributes(self.path,'size') - offset, offset, 'ab')
- options.bbox = false
- return psp
-end -- eps_crop
-
---[[
-
-most of these conversions involve a single invocation of gs, pdftops or texlua
-
-Each conversion fullfills all options that it can: gray, bbox and
-page. gray when converting to pdf, bbox when converting from eps or
-from pdf to pdf and page when converting from pdf. It then sets the
-fullfilled option(s) to false.
-
-We make sure to do the tight boundingbox before a file format downgrade:
-rasterization of the page or graphic frustrates boundingbox calculation.
-
-We like to preserve fonts as fonts. gs does this when generating
-pdf, but may fail for fonts such as cid and large truetype when
-generating PostScript. In such cases, pdftops may succeed. However,
-it seems that if the page contains an element that does not cleanly
-convert, pdftops simply rasterizes the entire page, and that this
-choice is made per page.
-
---]]
-
--- Converting from pdf to pdf using luatex; no grayscaling here
-
-function PsPdf:getpgbox()
- if options.page and options.page > self.pages then
- errror('PsPdf:getpgbox called with non-existent page '.. options.page)
- end
- local pg = options.page or 1
- local bb, hrbb, pgbox, pdfdoc, ppage
- if pdfe then
- pdfdoc = pdfe.open(self.path)
- if pdfdoc then
- ppage = pdfe.getpage(pdfdoc, pg)
- if not ppage then errror('did not get page') end
- if ppage then
- pgbox = pdfe.getbox(ppage, 'MediaBox')
- if not pgbox then
- pgbox = pdfe.getbox(ppage, 'CropBox')
- if not pgbox then
- pgbox = pdfe.getbox(ppage, 'TrimBox')
- if not pgbox then
- errror('No box acquired')
- end
- end
- end
- end
- end
- pdfe.close(pdfdoc)
- else
- local cat
- pdfdoc = epdf.open(self.path)
- if pdfdoc then
- cat = pdfdoc:getCatalog()
- if cat then
- ppage = cat:getPage(pg)
- if ppage then
- pgbox = ppage:getMediaBox()
- if not pgbox then
- pgbox = ppage:getCropBox()
- if not pgbox then
- pgbox = ppage:getTrimBox()
- end
- end
- end
- end
- end
- end
- -- normalization and further checks, including for non-nil,
- -- by HRBb:from_rect, which errors out on failures
- if pgbox then
- pgbox = HRBb:from_rect(pgbox)
- -- this also converts numeric array indices to x1 ... y2 if necessary
- else
- errror('Cannot get page box from '..self.path..' page '..pg)
- end
- return pgbox
-end -- PsPdf:getpgbox
-
-function PsPdf:pdf_crop()
-
- -- options to be fulfilled: page, boundingbox if possible
- -- embeds the pdf with boundingbox parameters into a new (lua)tex document
- if options.page and options.page > self.pages then
- errror('PsPdf:pdf_crop called with non-existent page '.. options.page)
- end
- local bb, hrbb, pgbox
- pgbox = self:getpgbox()
- if options.bbox and pgbox:nonnegative() then
- bb, hrbb = self:bb_from_gs()
- options.bbox = false
- else
- hrbb = pgbox
- end
-
- -- luatex is on searchpath
- local luatex_prog = 'luatex'
-
- -- write TeX file which includes cropped pdf page
- -- adapted from Heiko Oberdiek's pdfcrop utility.
- -- the table `pieces' will contain the component strings for the tex source
- -- first, for texlua <= 0.81
- local pieces = {}
- if status.luatex_version <= 80 then
- pieces[1] = '\\pdfoutput=1\n'
- else
- pieces[1] = [[
-\edef\pdfminorversion {\pdfvariable minorversion}
-\edef\pdfcompresslevel {\pdfvariable compresslevel}
-\edef\pdfobjcompresslevel {\pdfvariable objcompresslevel}
-\edef\pdfdecimaldigits {\pdfvariable decimaldigits}
-\edef\pdfhorigin {\pdfvariable horigin}
-\edef\pdfvorigin {\pdfvariable vorigin}
-\let\pdfpagewidth\pagewidth
-\let\pdfpageheight\pageheight
-\let\pdfximage\saveimageresource
-\let\pdfrefximage\useimageresource
-\let\pdflastximage\lastsavedimageresourceindex
-
-\outputmode=1
-]]
- end
- if self.maver > 1 then
- pieces[2] = '\\pdfminorversion=9\n'
- else
- pieces[2] = '\\pdfminorversion=' .. self.miver .. '\n'
- end
- if self.maver > 1 or self.miver > 4 then
- pieces[3] = [[
-\pdfcompresslevel=9
-\pdfobjcompresslevel=2
-\pdfdecimaldigits=4
-]]
- else
- pieces[3] = [[
-\pdfcompresslevel=9
-\pdfobjcompresslevel=0
-\pdfdecimaldigits=4
-]]
- end
- pieces[4] = [[
-\def\page #1 [#2 #3 #4 #5]{%
- \count0=#1\relax
- \setbox0=\hbox{%
- \pdfximage page #1 mediabox{]]
- pieces[5] = self.path
- pieces[6] = [[}%
- \pdfrefximage\pdflastximage
- }%
- \pdfhorigin=#2bp\relax
- \pdfvorigin=#3bp\relax
- \pagewidth=#4bp\relax
- \pageheight=#5bp\relax
- \ht0=\pageheight
- \shipout\box0\relax
-}
-]]
- pieces[7] = string.format([[
-\page %d [%f %f %f %f]
-\csname @@end\endcsname
-\end
-]],
- options.page or 1, -hrbb.x1, hrbb.y1, hrbb.x2-hrbb.x1, hrbb.y2-hrbb.y1)
-
- local textemp = mktemp('tex') -- this also took care of pdf:
- local pdftemp = string.gsub(textemp, 'tex$', 'pdf')
- -- if os.type=='windows' then waitasec() end
- local f = io.open(textemp, 'w')
- -- if os.type=='windows' then waitasec() end
- f:write(table.concat(pieces, ''))
- f:close()
- local cmd, res, psp
- -- if os.type=='unix' then
- cmd = {luatex_prog, '--safer', '--no-shell-escape', textemp}
- log_cmd(cmd)
- res = os.spawn(cmd)
- -- else
- -- cmd = luatex_prog..' --safer --no-shell-escape '..textemp
- -- log_cmd({cmd})
- -- -- os.execute('timeout /t 1 /nobreak >nul')
- -- res = os.execute(cmd)
- -- end
- if res and res==0 and lfs.attributes(pdftemp, 'size')>0 then
- psp = PsPdf:from_path(pdftemp)
- options.bbox = false
- options.page = false
- return psp
- else
- errror('pdf_crop failed on '..self.path)
- end
-end
-
-function PsPdf:eps_to_pdf()
-
- -- option to be fulfilled: gray
- -- set target and maybe pdf version if applicable
- if self.type~='eps' then
- errror('PsPdf:eps_to_pdf called for non-eps file '.. self.path)
- end
- local cmd
- maybe_add_version_parameter()
- cmd = tab_combine({{gs_prog}, gs_options, pdf_options})
- if options.gray then
- cmd = tab_combine({cmd, gray_options})
- end
- table.insert(cmd, '-dEPSCrop') -- uses existing hires bb
- local psp = PsPdf:new('pdf')
- table.insert(cmd, '-sOutputFile#'..psp.path)
- cmd = tab_combine({cmd, pdf_tail_options})
- table.insert(cmd, self.path)
- log_cmd(cmd)
- local res = os.spawn(cmd)
- if res and res==0 and lfs.attributes(psp.path, 'size')>0 then
- psp.pages, psp.miver, psp.maver = pdf_props(psp.path)
- options.gray = false
- return psp
- else
- errror('eps_to_pdf failed on '..self.path)
- end
-end -- eps_to_pdf
-
--- Converting from pdf to pdf with grayscaling and/or page selection
--- or just eliminating negative boundingbox
-
-function PsPdf:pdf_to_pdf()
-
- -- option to be fulfilled: gray, optionally page
- -- side effect: makes bbox non-negative.
- -- do not call this just for page selection because
- -- pdf_crop can do this in a less invasive manner
- if self.type~='pdf' then
- errror('PsPdf:pdf_to_pdf called for non-pdf file '.. self.path)
- end
- local cmd
- if options.page and options.page > self.pages then
- errror('PsPdf:pdf_to_pdf called with non-existent page '.. options.page)
- end
- cmd = tab_combine({{gs_prog}, gs_options, pdf_options})
- if options.gray then
- cmd = tab_combine({cmd, gray_options})
- end
- if options.page then
- table.insert(cmd, '-dFirstPage#'..tostring(options.page))
- table.insert(cmd, '-dLastPage#'..tostring(options.page))
- end
- maybe_add_version_parameter()
- local psp = PsPdf:new('pdf')
- table.insert(cmd, '-sOutputFile#'..psp.path)
- cmd = tab_combine({cmd, pdf_tail_options})
- table.insert(cmd, self.path)
- log_cmd(cmd)
- local res = os.spawn(cmd)
- if res and res==0 and lfs.attributes(psp.path, 'size')>0 then
- psp.pages, psp.miver, psp.maver = pdf_props(psp.path)
- options.gray = false
- options.page = false
- return psp
- else
- errror('pdf_to_pdf failed on '..self.path)
- end
-end -- pdf_to_pdf
-
-function PsPdf:pdf_to_eps()
-
- -- options to be fulfilled: page
- local psp = PsPdf:new('eps')
- local cmd, res
- -- any_to_any already checked the validity and relevance of options.page
- if pdftops then
- if options.page then
- cmd = tab_combine({{pdftops}, ps_options,
- {'-f', options.page, '-l', options.page,
- '-eps', self.path, psp.path}})
- else
- cmd = tab_combine({{pdftops}, ps_options,
- {'-eps', self.path, psp.path}})
- end
- log_cmd(cmd)
- if os.type=='windows' then
- -- suppress console output of 'No display font for...' messages,
- -- which are usually harmless and for which I know no easy fix
- -- pdftops -q does not do the trick on Windows,
- -- and redirection to logfile gives access denied under miktex
- -- res = os.spawn({'cmd', '/c', table.concat(cmd, ' ')..' 2>>'..log_bsl})
- res = os.execute(table.concat(cmd, ' ')..' 2>nul')
- else
- res = os.spawn(cmd)
- end
- if res and res==0 and lfs.attributes(psp.path, 'size')>0 then
- psp.pages = 1
- options.page = false
- else
- errror('pdf_to_eps failed on '..self.path)
- end
- -- fix for incorrect DSC header produced by some versions of pdftops:
- -- if necessary, change line `% Produced by ...' into `%%Produced by ...'
- -- this is usually the second line.
- -- otherwise the DSC header would be terminated before the bbox comment.
- -- this problem exists with pdftops from TL2011/w32.
- local slurp -- input buffer
- local fin = io.open(psp.path, 'rb')
- if not fin then errror('Cannot read '..psp.path) end
-
- -- remaining, unscanned length of input buffer slurp
- local unscanned = math.min(lfs.attributes(psp.path, 'size'),bufsize)
- slurp = fin:read(unscanned)
- local i, i_bb = 0, false
- local needs_fixing = false
- local pre_lines = {}
- local offset = 0
- while unscanned>0 do
- i = i+1
- if string.find(slurp,'[\n\r]')==1 then
- l,slurp = string.match(slurp, '^([\n\r]+)(.*)$')
- else
- l,slurp = string.match(slurp, '^([^\n\r]+)(.*)$')
- if string.match(l, Bb.bb_pat) then
- -- bbox line
- i_bb = i
- elseif string.match(l, '^%%%s') then -- `%' is escape char: doubled
- -- %X with X printable would be ok
- needs_fixing = true
- -- fix rightaway
- l = string.gsub(l, '^%%%s', '%%%%') -- same length
- end
- end -- eol/non-eol
- pre_lines[i] = l
- unscanned = unscanned - string.len(l)
- offset = offset + string.len(l)
- if i_bb then break end
- end -- while
- fin:close()
- if needs_fixing then
- -- write a new eps file
- local newfile = mktemp('eps')
- fout = io.open(newfile, 'wb')
- if not fout then errror('Cannot write new file '.. newfile) end
- fout:write(table.concat(pre_lines))
- fout:close()
- slice_file(psp.path, newfile,
- lfs.attributes(psp.path,'size') - offset, offset, 'ab')
- psp.path = newfile
- end -- needs_fixing
- else -- use ghostscript
- local epsdev = gs_epsdevice()
- if not epsdev then
- errror('Conversion to eps not supported by this ghostscript')
- end
- cmd = tab_combine({{gs_prog}, gs_options,
- {'-sDEVICE#'..epsdev, '-dHaveTrueTypes=true', '-dLanguageLevel#3'}})
- if options.gray then
- cmd = tab_combine({cmd, gray_options})
- end
- if options.page then
- table.insert(cmd, '-dFirstPage='..options.page)
- table.insert(cmd, '-dLastPage='..options.page)
- end
- table.insert(cmd, '-sOutputFile='..psp.path)
- table.insert(cmd, self.path)
- log_cmd(cmd)
- res = os.spawn(cmd)
- if res and res==0 and lfs.attributes(psp.path, 'size')>0 then
- psp.pages = 1
- options.page = false
- options.gray = false
- else
- errror('pdf_to_eps failed on '..self.path)
- end
- end -- use ghostscript
- psp:get_bb_simple()
- return psp
-
-end -- pdf_to_eps
-
-function PsPdf:ps_to_pdf()
-
- -- options to be fulfilled: gray
- if self.type~='ps' then
- errror('PsPdf:ps_to_pdf called for non-ps file '.. self.path)
- end
- local cmd
- cmd = tab_combine({{gs_prog}, gs_options, pdf_options})
- if options.gray then
- cmd = tab_combine({cmd, gray_options})
- end
- local psp = PsPdf:new('pdf')
- table.insert(cmd, '-sOutputFile#'..psp.path)
- cmd = tab_combine({cmd, pdf_tail_options})
- table.insert(cmd, self.path)
- log_cmd(cmd)
- local res = os.spawn(cmd)
- if res and res==0 and lfs.attributes(psp.path, 'size')>0 then
- psp.pages, psp.miver, psp.maver = pdf_props(psp.path)
- options.gray = false
- return psp
- else
- errror('ps_to_pdf failed on '..self.path)
- end
-
-end -- PsPdf:ps_to_pdf
-
-function PsPdf:pdf_to_ps()
-
- -- options to be fulfilled: page and, if not using pdftops, also gray
- local psp = PsPdf:new('ps')
- -- options.page checked by any_to_any
- psp.pages = self.pages
- local cmd, res
- if pdftops then
- cmd = tab_combine({{pdftops}, ps_options})
- if options.page then
- cmd = tab_combine({cmd, {'-f', options.page, '-l', options.page}})
- end
- cmd = tab_combine({cmd, {'-paper', 'match', self.path, psp.path}})
- else -- use ghostscript
- cmd = tab_combine({{gs_prog}, gs_options,
- {'-sDEVICE#ps2write', '-dHaveTrueTypes=true', '-dLanguageLevel#3'}})
- if options.gray then
- cmd = tab_combine({cmd, gray_options})
- end
- if options.page then
- cmd = tab_combine({cmd,
- {'-dFirstPage#'..options.page, '-dLastPage#'..options.page}})
- end
- table.insert(cmd, '-sOutputFile#'..psp.path)
- table.insert(cmd, self.path)
- end
- log_cmd(cmd)
- if os.type=='windows' and pdftops then
- -- suppress console output of 'No display font for...' messages,
- -- which are usually harmless and for which I know no easy fix
- -- pdftops -q does not do the trick on Windows,
- -- and redirection to logfile gives access denied under miktex
- -- res = os.spawn({'cmd', '/c', table.concat(cmd, ' ')..' 2>>'..log_bsl})
- res = os.execute(table.concat(cmd, ' ')..' 2>nul')
- else
- res = os.spawn(cmd)
- end
- if res and res==0 and lfs.attributes(psp.path, 'size')>0 then
- options.page = false
- -- gs will have grayscaled if requested but pdftops will not
- if not pdftops then options.gray = false end
- return psp
- else
- errror('pdf_to_ps failed on '..self.path)
- end
-end -- PsPdf:pdf_to_ps
-
-function PsPdf:ps_to_ps()
- -- we do not accept a page option since we do not know
- -- which pages are available.
- -- if no gray option then there is no point in invoking this function.
- local psp = PsPdf:new('ps')
- local cmd = tab_combine({{gs_prog}, gs_options,
- {'-sDEVICE#ps2write', '-dHaveTrueTypes=true', '-dLanguageLevel#3'}})
- if options.gray then
- cmd = tab_combine({cmd, gray_options})
- end
- table.insert(cmd, '-sOutputFile#'..psp.path)
- table.insert(cmd, self.path)
- log_cmd(cmd)
- local res = os.spawn(cmd)
- if res and res==0 and lfs.attributes(psp.path, 'size')>0 then
- options.gray = false
- return psp
- else
- errror('ps_to_ps failed on '..self.path)
- end
-end -- PsPdf:ps_to_ps
-
-function any_to_any()
-
- local psp = PsPdf:from_path(infile)
-
- -- sanitize some options
-
- if options.type=='ps' then
- options.bbox = false
- end
-
- if (options.bbox or options.type=='eps') and not options.page then
- options.page = 1
- end
-
- if psp.type=='pdf' then
- if options.page then
- local pgs = pdf_props(infile)
- if pgs<options.page then
- errror(infile..' has only '..pgs..' page(s).')
- elseif pgs==1 then
- options.page = false
- end
- end
- elseif psp.type=='eps' then
- options.page = false
- end
- -- psp.type=='ps': pages not yet known but maybe not needed
-
- local do_something = false
- if psp.type=='eps' then
- do_something = true -- do at least cleanup
- elseif psp.type~=options.type then
- do_something = true
- elseif options.page then
- do_something = true
- elseif options.bbox then
- do_something = true
- elseif options.gray then
- do_something = true
- elseif options.type=='pdf' then
- if psp:to_downgrade() then
- do_something = true
- elseif settings.pdf_target and settings.pdf_target~=default then
- do_something = true
- end
- end
- if not do_something then
- if infile~=outfile then
- slice_file(infile, outfile)
- end
- return true
- end
-
- -- `distiller' settings
- -- these depend on whether final output is pdf
- if options.type=='pdf' then
- if settings.pdf_target and (settings.pdf_target~='default') then
- table.insert(pdf_options, '-dPDFSETTINGS#/'..settings.pdf_target)
- end
- if settings.pdf_target~='screen' and settings.pdf_target~='ebook' then
- pdf_tail_options = {
- '-c', '<</NeverEmbed [ ] >> setdistillerparams', '-f'}
- end
- end
-
- --[[ Actual conversions
- each single-step conversion takes care of options it can handle
- and sets those options to false.
- Cropping a pdf is best be done before converting to postscript or
- a low (<1.4) pdf version.
-
- all invocations of external programs work on temporary files
- in the then-current temporary directory, with a simple generated
- filename. So no need to quote names of input- or output filenames.
- --]]
-
- local newfile
-
- if psp.type=='eps' or psp.type=='epsPreview' then
- -- As a side effect of eps_clean, the modified or unmodified source file
- -- is copied to our temp subdirectory.
- -- We always create a new file.
- psp = psp:eps_clean()
- if options.bbox and psp.bb:nonnegative() then
- psp = psp:eps_crop()
- end
- if options.type=='eps' then
- if options.gray or options.bbox then
- -- bbox: eps_crop was apparently not applicable: pdf roundtrip
- psp = psp:eps_to_pdf()
- if options.bbox then
- psp = psp:pdf_crop()
- end
- psp = psp:pdf_to_eps()
- end
- elseif options.type=='pdf' then
- psp = psp:eps_to_pdf()
- if options.bbox then
- psp = psp:pdf_crop()
- end
- if psp:to_downgrade() then
- maybe_add_version_parameter()
- psp = psp:pdf_to_pdf()
- end
- elseif options.type=='ps' then
- -- often, the eps file is fine as a postscript file.
- -- however, it may lack a showpage operator, or have a weird
- -- boundingbox. converting back-and-forth to pdf solves both problems.
- -- eps_to_pdf will take care of grayscaling
- -- a tight boundingbox option is not supported for ps output.
- psp = psp:eps_to_pdf():pdf_to_ps()
- end
- slice_file(psp.path, outfile)
- return true
-
- elseif psp.type=='ps' then
-
- -- preliminary:
- -- copy infile to a file in the temp directory, needed for gs -dSAFER
- newfile = mktemp(psp.type)
- slice_file(psp.path, newfile)
- psp.path = newfile
-
- if options.type=='ps' and not options.page then
- psp = psp:ps_to_ps()
- slice_file(psp.path, outfile)
- return true
- end
-
- -- remaining options require initial conversion to pdf
- psp = psp:ps_to_pdf()
- -- AFAIK, all high-level ps constructs are covered by any pdf version
- -- so this option should not cause unnecessary loss of structure
- maybe_add_version_parameter()
-
- if options.page and options.page>1 then
- -- could not check page option before
- local pgs = pdf_props(psp.path)
- if pgs<options.page then
- errror(infile..' has only '..pgs..' page(s).')
- elseif pgs==1 then
- options.page = false
- end
- end
-
- -- actual conversion
- if options.type=='eps' then
- if options.bbox then
- psp = psp:pdf_crop()
- end
- psp = psp:pdf_to_eps()
- elseif options.type=='pdf' then
- if options.bbox or options.page then
- psp = psp:pdf_crop()
- -- else no action needed
- end
- elseif options.type=='ps' then
- psp = psp:pdf_to_ps()
- end -- pdf => ps
- slice_file(psp.path, outfile)
- return true
-
- elseif psp.type=='pdf' then
-
- if options.type=='pdf' and settings.pdf_target=='default' and
- not options.gray and not options.bbox and not options.page and
- not psp:to_downgrade() then
- if infile~=outfile then
- slice_file(infile, outfile)
- end
- return true
- end
-
- -- preliminary:
- -- copy infile to a file in the temp directory, needed for gs -dSAFER
- newfile = mktemp(psp.type)
- slice_file(psp.path, newfile)
- psp = PsPdf:from_path(newfile)
- local pgbox
-
- -- actual conversion
- if options.type=='eps' then
- if options.bbox then
- pgbox = psp:getpgbox() -- page n. available from options table
- if not pgbox:nonnegative() or options.gray then
- -- fix in extra pdf-to-pdf step
- psp = psp:pdf_to_pdf()
- end
- -- we want to calculate a tight boundingbox before conversion to eps,
- -- because this conversion may cause rasterization and baffle
- -- gs' boundingbox calculations
- psp = psp:pdf_crop()
- elseif options.gray and pdftops then
- psp = psp:pdf_to_pdf()
- end
- psp = psp:pdf_to_eps()
- elseif options.type=='pdf' then
- -- pdf_crop can take care of bbox and page,
- -- but not of gray and not of some pdf options
- if options.bbox then
- pgbox = psp:getpgbox()
- if not pgbox:nonnegative() then
- -- pdf_to_pdf fixes negative bbox parameters
- -- and also takes care of page and gray
- psp = psp:pdf_to_pdf()
- end
- psp = psp:pdf_crop()
- end
- need_gs = false
- if psp:to_downgrade() then
- need_gs = true
- maybe_add_version_parameter()
- end
- if settings.pdf_target~='default' then
- need_gs = true
- end
- if options.gray then
- need_gs = true
- end
- if (not need_gs) and options.page then
- psp = psp:pdf_crop()
- -- less invasive that page selection by gs
- end
- if need_gs then
- psp = psp:pdf_to_pdf() -- will handle page selection too
- end
- elseif options.type=='ps' then
- if options.gray and pdftops then
- psp = psp:pdf_to_pdf():pdf_to_ps()
- else
- psp = psp:pdf_to_ps()
- end
- end -- pdf => ps
- slice_file(psp.path, outfile)
- return true
- end
-end -- any_to_any
-
--- system-dependent initialization -----------------------------------
-
--- current directory, at program start
-cwd = lfs.currentdir()
-if os.type == 'windows' then cwd = string.gsub(cwd, '\\', '/') end
-
--- child searchpath initially set to parent searchpath
--- childpath = os.getenv('PATH')
-
--- prepend (lua)tex directory to searchpath, if not already there
-maybe_add_path(os.selfdir, false)
-
--- Windows: miktex, TL or neither. is_miktex, is_tl_w32
--- no support yet for separate ghostscript
-is_miktex = false
-is_tl_w32 = false
-
-if os.type == 'windows' then
- if string.find (string.lower(kpse.version()), 'miktex') then
- is_miktex = true
- else
- local rt = string.gsub(os.selfdir,'[\\/][^\\/]+[\\/][^\\/]+$', '')
- if not rt then
- errror('Unrecognized TeX directory structure', 0)
- elseif lfs.isfile(rt..'/release-texlive.txt') then
- --[[
- -- TL version is easy to determine but is not needed
- local fin = io:open(rt..'release-texlive.txt', 'r')
- if fin then
- local l = fin:read('*line')
- tl_ver = string.match(l, 'version%s+(%d+)$')
- if tl_ver then tl_ver = tonumber(tl_ver) end
- end -- if fin
- --]]
- is_tl_w32 = true
- else
- errror('Not MikTeX and no file ' .. rt ..
- '/release-texlive.txt; TeX installation not supported.', 0)
- end -- if isfile
- end -- if not miktex
-end -- if windows
-
--- without Ghostscript we are dead in the water.
-gs_prog = false
-do
- local rt=''
- if os.type == 'unix' then
- if find_on_path('gs') then
- gs_prog = 'gs'
- else
- error('No ghostscript on searchpath!', 0)
- end
- elseif is_miktex then
- gs_prog = 'mgs.exe'
- -- neither MiKTeX's nor TL's ghostscript need GS_LIB to be set
- elseif is_tl_w32 then
- -- windows/TeX Live
- -- grandparent of texlua.exe directory .. ...
- -- rt = string.gsub(os.selfdir,'[\\/][^\\/]+[\\/][^\\/]+$', '')
- -- ..'/tlpkg/tlgs'
- -- maybe_add_path(rt..'/bin', false)
- -- -- gs_prog = 'gswin32c.exe'
- -- ---[[ problems with (at least) grayscaling
- gs_prog = 'rungs.exe'
- --]]
- else
- errror('Only TeX Live and MikTeX supported!', 0)
- end
-end -- do
-
--- directory for configuration and log
-epsdir = ''
-if os.type == 'windows' then
- epsdir = fw(os.getenv('APPDATA')) .. '/epspdf'
-else
- epsdir = os.getenv('HOME')..'/.epspdf'
-end
-rcfile = epsdir .. '/config'
-logfile = epsdir .. '/epspdf.log'
-
--- create epsdir if necessary
-if lfs.isfile(epsdir) then
- error('Cannot continue; epspdf directory ' .. epsdir .. ' is a file')
-elseif not lfs.isdir(epsdir) then
- if not lfs.mkdir(epsdir) then
- error('Failed to create epspdf directory ' .. epsdir)
- end
-end
-
--- start logging ---------------------------------
-
--- log rotate if logfile too big
-if lfs.attributes(logfile) and lfs.attributes(logfile).size > 100000 then
- local oldlog = logfile .. '.old'
- if lfs.attributes(oldlog) then
- if os.remove(oldlog) then os.rename(logfile,oldlog) end
- elseif lfs.attributes(logfile) then do
- -- separate epsdir runs with empty lines
- print_log('\n\nNew run')
- end end -- do elseif
-end -- if lfs...logfile
-
-write_log('epspdf '..table.concat(arg, ' '))
-
---[[
-
-settings, initial values
-
-priority, from low to high:
-
-- built-in defaults
-- settings read from and written to the configuration file
-- command-line options, defined in the opts table
-
-The options- and settings tables are initialized from built-in
-defaults. We go for false rather than undefined, because this
-results in an actual settings- or options entry.
-
-Command-line options are copied to either options or settings.
-We ignore illegal settings in the config file.
-
---]]
-
-pdf_targets = {'screen', 'ebook', 'printer', 'prepress', 'default'}
-pdf_versions = {'1.2', '1.3', '1.4', '1.5', '1.6', '1.7', 'default'}
--- ghostscript will substitute higher versions with
--- the highest-supported version
-
-settings = {}
-descriptions = {}
-
-settings.pdf_target = 'default'
-descriptions.pdf_target = 'One of ' .. join(pdf_targets, ', ', ' or ')
-
-settings.pdf_version = 'default'
-descriptions.pdf_version = 'One of ' .. join(pdf_versions, ', ', ' or ')
-
-settings.use_pdftops = true
-descriptions.use_pdftops = 'Use pdftops if available'
-
--- epspdf stores ps- and pdf viewer settings on behalf of the gui interface
--- but does not use them itself.
--- They will not be used at all under macos or windows.
-
-settings.ps_viewer = false
-descriptions.ps_viewer =
- 'Epspdftk: viewer for PostScript files; not used on Windows or Mac OS'
-
-settings.pdf_viewer = false
-descriptions.pdf_viewer =
- 'Epspdftk: viewer for pdf files; not used on Windows or Mac OS'
-
--- default_dir, which is used on all platforms, is only for the gui.
-
-if os.type == 'windows' then
- settings.default_dir =
- string.gsub(os.getenv('USERPROFILE'), '\\', '/')
-else
- settings.default_dir = os.getenv('HOME')
-end
-descriptions.default_dir =
- 'Epspdftk: initial directory; ignored by epspdf itself'
-
--- options -------------------------------------
-
--- besides settings, which can be saved, we also use options which are not.
--- these are mostly conversion options.
-
-options = {}
-options.page = false
-options.gray = false
-options.bbox = false
-options.debug = false
-options.type = false -- implied via output filename on command line
-
--- command-line fragments for conversions --------------------
-
--- We could make these `class attributes' for PsPdf but to what purpose?
--- For Windows shell commands, we need to substitute `#' for `='
--- when invoking Ghostscript. For simplicity, we do this across the board.
--- -P- : do not look first in current directory
-
-gs_options = {'-q', '-dNOPAUSE', '-dBATCH', '-P-', '-dSAFER'}
-
--- may add custom options later
-
-pdf_options = {'-sDEVICE#pdfwrite'} -- '-dUseCIEColor' causes serious slowdown
--- options for final conversion to pdf;
--- will be completed after reading settings and options
--- -f ensures that the input filename is not added to a -c string
-pdf_tail_options = {'-f'}
-gray_options = {'-dProcessColorModel#/DeviceGray',
- '-sColorConversionStrategy#Gray'}
-
-pdftops = false
--- gets a value only if we are going to use pdftops
-
-ps_options = {'-level3'}
-
--- `main program' inside scope-creating block ----------------------
-
-do -- main program
-
- local in_dir = false -- directory of infile
- local out_dir = false -- directory of outfile
-
- do -- Handle settings and command-line inside nested scope --------------
-
- read_settings(rcfile)
-
- local opts = {}
-
- opts.page = {
- type = 'string', val = nil,
- forms = {'-p', '--page', '--pagenumber'},
- placeholder = 'PNUM',
- negforms = nil,
- help = 'Page number; must be a positive integer'
- }
-
- opts.gray = {
- type = 'boolean', val = nil,
- forms = {'-g', '--grey', '--gray', '-G', '--GREY', '--GRAY'},
- negforms = nil,
- help = 'Convert to grayscale'
- }
-
- opts.bbox = {
- type = 'boolean', val = nil,
- forms = {'-b', '--bbox', '--BoundingBox'},
- negforms = nil,
- help = 'Compute tight boundingbox'
- }
-
- ---[[ ignored; included for backward compatibility
- opts.use_hires_bb = {
- type = 'boolean', val = nil,
- forms = {'-r', '--hires'},
- negforms = {'-n', '--no-hires'},
- }
-
- opts.custom = {
- type = 'string', val = nil,
- forms = {'-C', '--custom', '-P', '--psoptions'},
- negforms = nil
- }
- --]]
-
- opts.pdf_target = {
- type = 'string', val = nil,
- forms = {'-T', '--target'},
- placeholder = 'TARGET',
- negforms = nil,
- help = descriptions.pdf_target
- }
- opts.pdf_version = {
- type = 'string', val = nil,
- forms = {'-N', '--pdfversion'},
- placeholder = 'VERSION',
- negforms = nil,
- help = descriptions.pdf_version
- }
-
- opts.use_pdftops = {
- type = 'boolean', val = nil,
- forms = {'-U'},
- negforms = {'-I'},
- help = descriptions.use_pdftops
- }
-
- opts.info = {
- type = 'boolean', val = nil,
- forms = {'-i', '--info'},
- negforms = nil,
- help = 'Info: display detected filetype and exit'
- }
-
- opts.help = {
- type = 'boolean', val = nil,
- forms = {'-h', '--help'},
- negforms = nil,
- help = 'Display this help message and exit'
- }
-
- opts.version = {
- type = 'boolean', val = nil,
- forms = {'-v', '--version'},
- negforms = nil,
- help = 'Display version info and exit'
- }
-
- opts.save = {
- type = 'boolean', val = nil,
- forms = {'-s', '--save'},
- negforms = nil,
- help = 'Save some settings to configuration file'
- }
-
- opts.debug = {
- type = 'boolean', val = nil,
- forms = {'-d'},
- negforms = nil,
- help = 'Debug: do not remove temp files'
- }
-
- opts.gui = {
- type = 'string', val = nil,
- forms = {'--gui'},
- negforms = nil,
- help = nil -- reserved for use by epspdftk
- }
-
- -- a couple of functions only available during command-line parsing
-
- local function show_version ()
- print('Epspdf version 0.6.4\nCopyright (c) 2006-2019 Siep Kroonenberg')
- end
-
- local function help (mess) -- requires opts array
- if mess then
- print(mess..eol)
- end
- show_version()
- -- below, string.gsub unindents its long-string parameter.
- -- string.format removes the second return value of string.gsub.
- print( -- string.format('%s',
- string.gsub([[
-
- Convert between [e]ps and pdf formats
- Usage: epspdf[.tlu] [options] infile [outfile]
- Default for outfile is file.pdf if infile is file.eps or file.ps
- Default for outfile is file.eps if infile is file.pdf
- ]], '([\r\n]+) ', '%1')) --)
-
- -- need to enforce an ordering, otherwise we could have used pairs(opts)
- -- omitted below: no-op options
- -- one line where possible
- local indent_n = 12
- local intent_sp = string.rep(' ', indent_n)
- local indent_fmt = '%-' .. tostring(indent_n) .. 's'
- for _, o in ipairs({'page', 'gray', 'bbox', 'pdf_target', 'pdf_version',
- 'use_pdftops', 'save', 'info', 'debug', 'version', 'help'}) do
- local v = opts[o]
- if v and v.help then
- local synt = join(v.forms, ', ')
- if v.type ~= 'boolean' then synt = synt .. ' ' .. v.placeholder end
- if string.len(synt)<indent_n then
- print(string.format(indent_fmt, synt) .. v.help)
- else
- print(synt)
- print(intent_sp .. v.help)
- end
- if v.negforms then
- local neghelp = 'Reverses the above'
- synt = join(v.negforms, ', ')
- if string.len(synt)<indent_n then
- print(string.format(indent_fmt, synt) .. neghelp)
- else
- print(synt)
- print(intent_sp .. neghelp)
- end
- end
- end
- end -- for
- if mess then os.exit(1) else os.exit() end
- end -- help
-
- if #arg < 1 then help('No parameters') end
-
- -- command-line parsing
-
- -- -r="tata tata" is parsed by [tex]lua as a single argument
- -- lua/linux retains the quotes,
- -- lua/windows strips them.
- -- texlua strips them, both on unix and on windows.
-
- local i=1
- while i<=#arg and string.sub(arg[i],1,1)=='-' do
- local parsed = false
- local kk, vv = string.match(arg[i],'([^=]+)=(.*)$')
- if kk==nil then
- kk = arg[i] -- also vv==nil
- else
- vv = strip_outer_spaces(vv)
- end
- for p, o in pairs(opts) do
- if in_list(kk, o.forms) or in_list(kk, o.negforms) then
- parsed = true
- if o.type == 'boolean' then
- if vv then help(kk..' should not have a parameter.') end
- if in_list(kk, o.forms) then
- o.val = true
- else
- o.val = false
- end
- elseif vv then
- o.val = vv
- else
- i = i + 1
- if i>#arg then
- help('Missing parameter to '..kk)
- end
- o.val = strip_outer_spaces(arg[i])
- end -- testing for o.type or vv
- break -- for
- end -- if in_list
- end -- for
- if not parsed then help('illegal parameter '..kk) end
- i = i + 1
- end -- while
-
- -- check and interpret opts.
- -- Copy to either settings or to options table.
- -- at syntax error, abort via help function.
-
- -- page
-
- if opts.page.val then
- local pnum = tonumber(opts.page.val)
- if pnum<=0 or math.floor(pnum) ~= pnum then
- help(opts.page.val..' not a positive integer')
- else
- options.page = pnum
- end
- end
-
- -- grayscaling
-
- if opts.gray.val then
- options.gray = true
- else
- options.gray = false
- end
-
- -- boundingbox
-
- if opts.bbox.val then
- options.bbox = true
- else
- options.bbox = false
- end
-
- --[[
- -- using hires boundingbox
-
- if opts.use_hires_bb.val~=nil then
- settings.use_hires_bb = opts.use_hires_bb.val
- end
- --]]
-
- -- using pdftops
-
- if opts.use_pdftops.val~=nil then
- settings.use_pdftops = opts.use_pdftops.val
- end
-
- -- pdf target use
-
- if opts.pdf_target.val~=nil then
- if in_list(opts.pdf_target.val, pdf_targets) then
- settings.pdf_target = opts.pdf_target.val
- else
- help('Illegal value '..opts.pdf_target.val..' for pdf_target')
- end
- end
-
- -- pdf version
-
- if opts.pdf_version.val~=nil then
- if in_list(opts.pdf_version.val, pdf_versions) then
- settings.pdf_version = opts.pdf_version.val
- else
- help('Illegal value '..opts.pdf_version.val..' for pdf_version')
- end
- end
-
- -- pdftops should be on the path
- if settings.use_pdftops then
- if os.type=='windows' then
- pdftops = find_on_path('pdftops.exe')
- else
- pdftops = find_on_path('pdftops')
- end
- end
-
- -- other options
-
- if opts.save.val then
- write_settings(rcfile)
- end
-
- if opts.debug.val then
- options.debug = true
- end
-
- if opts.help.val then
- help()
- end
-
- -- opts.info.val: do later; need to get infile first
-
- if opts.version.val then
- show_version()
- os.exit()
- end
-
- if opts.gui.val then
- gui(opts.gui.val)
- end
-
- -- now we need 1 or 2 filenames, unless the user really only
- -- wanted to save options without further action.
-
- if i>#arg then
- if opts.save.val then os.exit() else help('No filenames') end
- end
-
- infile = arg[i]
- outfile = false
- if i<#arg then
- outfile = arg[i+1]
- end
- if (#arg>i and opts.info.val) or (#arg>i+1) then
- help('Surplus non-option parameters')
- end
-
- if not outfile and not opts.info.val then
- -- derive outfile from infile: [e]ps => pdf, pdf => eps
- if intype=='pdf' then
- outfile = string.gsub(infile,'%.[^%.]*$','eps')
- else
- outfile = string.gsub(infile,'%.[^%.]*$','.pdf')
- end
- end
-
- -- one final quick option
- if opts.info.val then
- info()
- end
-
- end -- do (decoding command-line)
-
- --[[
-
- Once it becomes clear that real work needs to be done,
- we shall create a temp directory.
-
- because of gs -dSAFER restrictions, infile must be in (a
- subdirectory of) the directory of the output file, e.g. in the
- temp directory. So we copy infile to the temp directory.
-
- --]]
-
- if not lfs.isfile(infile) or lfs.attributes(infile, 'size')==0 then
- errror(infile..' does not exist or is empty.')
- end
- infile, in_dir = absolute_path(infile)
- outfile, out_dir = absolute_path(outfile)
- if not out_dir then
- errror('Invalid output directory for '.. outfile)
- end
-
- -- directory for temporary files
-
- -- previously, we used a subdirectory of the target directory.
- -- however, since under windows cleanup may fail, we now try to use
- -- a directory under a dedicated temp directory, which has a better chance
- -- of getting cleaned up by the system.
-
- lfs.chdir(system_tempdir() or out_dir)
- -- no check for failure; we create a subdirectory in
- -- whatever is the current directory
- tempdir = os.tmpdir()
- if not tempdir then
- errror('Cannot create directory for temporary files')
- end
- lfs.chdir(tempdir)
-
- -- determine filetype from first few bytes of file
- intype = identify(infile)
-
- -- remaining cases: want a real conversion
- if not intype then
- errror(infile..' has an unsupported filetype')
- end
-
- -- valid output filetype?
- options.type = string.match(outfile, '.*%.([^%.]+)$')
- if not options.type or (options.type~='ps' and
- options.type~='eps' and options.type~='pdf') then
- errror('Output file '..outfile..
- ' should have extension .eps, .ps or .pdf')
- end
-
- if outfile==infile then
- slice_file(infile, infile..'.backup')
- -- copy, not move, since outfile may be infile if there was nothing to do
- end
-
- result = any_to_any(infile, outfile)
- if not lfs.isfile(outfile) or lfs.attributes(outfile, 'size')==0 then
- errror('Failed to generate '..outfile)
- end
-
- if not options.debug then
- cleantemp()
- end
-end
diff --git a/Build/source/texk/texlive/linked_scripts/epspdf/epspdftk.tcl b/Build/source/texk/texlive/linked_scripts/epspdf/epspdftk.tcl
deleted file mode 100755
index 5ea94b6f037..00000000000
--- a/Build/source/texk/texlive/linked_scripts/epspdf/epspdftk.tcl
+++ /dev/null
@@ -1,756 +0,0 @@
-#!/usr/bin/env wish
-
-# epspdf conversion utility, GUI frontend
-
-#####
-# Copyright (C) 2006-2020 Siep Kroonenberg
-# siepo at bitmuis dot nl
-#
-# This program is free software, licensed under the GNU GPL, >=2.0.
-# This software comes with absolutely NO WARRANTY. Use at your own risk!
-#####
-
-package require Tk
-
-if {[string index $::tcl_patchLevel 2] <5} {
- tk_messageBox -message "Tcl/Tk version >= 8.5 required;\naborting..."
- exit
-}
-
-# tired of writing out this combined test again and again
-set classic_unix [expr {$::tcl_platform(platform) eq "unix" && \
- $::tcl_platform(os) ne "Darwin"}]
-
-# normally, epspdf.tlu should be in the same directory
-# and texlua should be on the searchpath.
-# However, the Windows installer version wraps this script in a starpack.
-
-# logging: to a log window, not to a file
-proc write_log {s} {
- if {[winfo exists .log_t.text]} {
- .log_t.text configure -state normal
- .log_t.text insert end "$s\n"
- .log_t.text yview moveto 1
- .log_t.text configure -state disabled
- # } else {
- # puts $s
- }
-}
-
-### invoking epspdf.tlu #########################
-
-# Get full path of epspdf.tlu. It should be in the same directory as
-# either this script or of the starpack containing this script,
-# For non-windows versions, epspdftk might be called via a symlink.
-# Pdftops done elsewhere.
-
-proc set_progs {} {
- set scriptfile [file normalize [info script]]
- set eproot [file dirname $scriptfile]
- # if symlink, get the directory of the file it points to
- if {! [catch {file readlink $scriptfile}]} {
- # evaluate readlink from symlink directory
- set savedir [pwd]
- cd $eproot
- set eproot [file dirname [file normalize [file readlink $scriptfile]]]
- cd $savedir
- }
- # find the lua script
- set ::epspdf_tlu [file join $eproot "epspdf.tlu"]
- if {! [file exists $::epspdf_tlu]} {
- # if starpack, look in binary directory
- set eproot [file dirname [file normalize [info nameofexecutable]]]
- set ::epspdf_tlu [file join $eproot "epspdf.tlu"]
- }
- if {$::tcl_platform(platform) eq "windows"} {
- # For actual conversions, epspdf invokes third-party command-line programs.
- # To prevent the appearing of transient black console windows for such
- # invocations, epspdf will be invoked via a batchfile.
- # This is not necessary for getting info about a file.
- set ::epspdf_cmd [file join $eproot "epspdf4tk.cmd"]
- }
- if {! [file exists $::epspdf_tlu]} {
- tk_messageBox -type ok -icon error -message "Epspdf.tlu not found"
- exit 1
- }
- # texlua should be on the searchpath
- set ::texlua "texlua"
-
- # icon for starpack: add with sdx or with Windows utilities
-}
-
-set_progs
-
-### configured and automatic settings ##################################
-
-# is_prog used for checking configured viewers under non-osx unix
-proc is_prog {x} {
- if {[expr {$::tcl_platform(platform) ne "unix"}]} {return 0}
- # avoid current directory except with explicit directory
- if {[expr {[string first "/" $x] >= 0 && \
- [file executable [file normalize $x]]}]} {
- return 1
- }
- # also check search path
- set p [split $::env(PATH) ":"] ; # no need to accomodate msw
- foreach d $p {
- if {[expr {$d ne "" && [file executable [file join $d $x]]}]} {
- return 1
- }
- }
- return 0
-}
-
-# create a global empty settings array
-array set ::settings [list]
-
-# ask epspdf.tlu for currently configured settings.
-# this does not include automatically configured or transient settings.
-# the availability of viewers is handled here.
-proc getsettings {} {
- if [catch {exec $::texlua $::epspdf_tlu --gui=config_w} set_str] {
- error "Epspdf configuration error: $set_str"
- }
- # write_log "settings from epspdf.tlu:\n$set_str\n"
- set l [split $set_str "\r\n"]
- foreach e $l {
- # puts "settings: $e"
- # $e is either a string "var = value"
- # or the empty string between <cr> and <lf>
- set i [string first "=" $e]
- if {$i>0} {
- # write_log $e
- set para [string trim [string range $e 0 [expr $i-1]]]
- set val [string trim [string range $e [expr $i+1] end]]
- if {$val eq "true"} {set val 1}
- if {$val eq "false"} {set val 0}
- set ::settings($para) $val
- # write_log "setting $para is $val"
- }
- }
-
- # unix: viewer settings
- # It may depend on installed plugins whether a pdf viewer
- # can render postscript.
- # AFAIK, no such plugins exist for xpdf or mupdf.
- # chrome and firefox also only render pdf and not postscript.
- # configured viewer, if valid, heads the list
- if {$::classic_unix} {
-
- set ::pdf_viewers {}
- if {$::settings(pdf_viewer) ne "" && [is_prog $::settings(pdf_viewer)]} {
- lappend ::pdf_viewers $::settings(pdf_viewer)
- }
- foreach v {
- atril evince okular qpdfview mupdf xpdf zathura gv firefox chrome \
- chromium chromium-browser} {
- if {$v ne $::settings(pdf_viewer) && [is_prog $v]} {
- lappend ::pdf_viewers $v
- }
- }
- # puts [join $::pdf_viewers " "]
-
- set ::ps_viewers {}
- if {$::settings(ps_viewer) ne "" && [is_prog $::settings(ps_viewer)]} {
- lappend ::ps_viewers $::settings(ps_viewer)
- }
- foreach v $::pdf_viewers {
- if {$v ne $::settings(ps_viewer) && \
- $v ni {xpdf mupdf firefox chrome chromium chromium-browser}} {
- lappend ::ps_viewers $v
- }
- }
- # puts [join $::ps_viewers " "]
-
- if {[llength ::pdf_viewers] == 0} {
- tk_messageBox -message "No viewers found"
- } elseif {[llength ::ps_viewers] == 0} {
- tk_messageBox -message "No PostScript viewers found"
- }
- if {[llength ::pdf_viewers] > 0} {
- set ::settings(pdf_viewer) [lindex $::pdf_viewers 0]
- }
- if {[llength ::ps_viewers] > 0} {
- set ::settings(ps_viewer) [lindex $::ps_viewers 0]
- }
- }
-}
-
-getsettings
-
-proc write_settings {} {
- set s ""
- foreach el [array names ::settings] {
- set s "$s$el = $::settings($el)\n"
- }
- # write_log "\nsettings for epspdf.tlu\n$s\nend writing settings\n"
- if [catch {exec $::texlua $::epspdf_tlu --gui=config_r << $s} result] {
- error "Epspdf configuration error: $result"
- }
-}
-
-# directory and other file data
-
-if {$::argc > 0 && [file isdirectory [lindex $::argv 0]]} {
- set ::gfile(dir) [lindex $::argv 0]
-} elseif {[file isdirectory $::settings(default_dir)]} {
- set ::gfile(dir) $::settings(default_dir)
-} else {
- set ::gfile(dir) $::env(HOME)
-}
-set ::gfile(path) ""
-set ::gfile(type) ""
-set ::gfile(name) ""
-set ::gfile(npages) ""
-
-# transient options
-array set ::options [list gray "color" format "pdf" bbox 0 clean 1 \
- pages "single" page 1]
-
-proc viewable {} {
- if { $::gfile(name) eq "" || ! [file exists $::gfile(path)] || \
- $::gfile(type) eq "other" || $::gfile(type) eq ""} {
- return 0
- } elseif {! $::classic_unix} {
- return 1
- } elseif {$::settings(ps_viewer) ne "" && [regexp {ps} $::gfile(type)]} {
- return 1
- } elseif {$::settings(pdf_viewer) ne "" && $::gfile(type) eq "pdf"} {
- return 1
- } else {
- return 0
- }
-}
-
-### groundwork for GUI #################################
-
-# padding for buttons and frames
-proc ppack {b args} {pack $b {*}$args -padx 3 -pady 3}
-
-# bold font
-font create bfont {*}[font configure TkDefaultFont]
-font configure bfont -weight bold
-
-proc update_combo w {
- # check that a manually supplied entry is actually a program
- # proc used for postscript- and pdf viewers
- set vls [$w cget -values]
- set new [$w get]
- if {$new ni $vls} {
- if {[is_prog $new]} {
- set vls [linsert $vls 0 $new]
- $w configure -values $vls
- } else {
- tk_messageBox -title Error -icon error -message "$new not a program"
- raise .config_t
- focus $w
- }
- }
-}
-
-proc revert_combo w {
- # aborts entry of new value
- if {[$w current] < 0} {
- $w current 0
- }
-}
-
-### and now the actual GUI ###################################
-
-wm title . "PostScript- and pdf conversions"
-
-# help toplevel
-
-proc readhelp {} {
- .help_t.text configure -state normal
- # this also works for the starpack:
- set helpfile [file join [file dirname $::epspdf_tlu] "epspdf.help"]
- if {! [file exists $helpfile]} {
- # helpfile in starpack
- set helpfile [file join [file dirname [info script]] "epspdf.help"]
- }
- if {[catch {set fid [open $helpfile r]}]} {
- .help_t.text insert end "No helpfile $helpfile found\n"
- } else {
- while {[gets $fid line] >= 0} {.help_t.text insert end "$line\n"}
- close $fid
- }
- .help_t.text configure -state disabled
- .help_t.text yview moveto 0
-}
-
-toplevel .help_t
-wm title .help_t "EpsPdf help"
-pack [ttk::frame .help_t.bg -padding 3] -fill both -expand 1
-ppack [ttk::button .help_t.done -text "Close" -command {wm withdraw .help_t}] \
- -in .help_t.bg -side bottom -anchor e -padx 50
-text .help_t.text -wrap word -width 60 -height 20 -setgrid 1 \
- -yscrollcommand ".help_t.scroll set"
-ttk::scrollbar .help_t.scroll -command ".help_t.text yview"
-pack .help_t.scroll -in .help_t.bg -side right -fill y
-pack .help_t.text -in .help_t.bg -expand 1 -fill both
-readhelp
-.help_t.text configure -state disabled
-wm withdraw .help_t
-
-# log toplevel
-
-toplevel .log_t
-wm title .log_t "Epspdf log"
-pack [ttk::frame .log_t.bg -padding 3] -fill both -expand 1
-ppack [ttk::button .log_t.b -text "Close" -command {wm withdraw .log_t}] \
- -in .log_t.bg -side bottom -anchor e -padx 50
-text .log_t.text -wrap word -relief flat -height 15 -width 60 \
- -setgrid 1 -yscrollcommand ".log_t.scroll set"
-ttk::scrollbar .log_t.scroll -command ".log_t.text yview"
-pack .log_t.scroll -in .log_t.bg -side right -fill y
-pack .log_t.text -in .log_t.bg -expand 1 -fill both
-.log_t.text configure -state disabled
-wm withdraw .log_t
-
-### configure toplevel ###################
-
-toplevel .config_t
-wm title .config_t "Configure epspdf"
-pack [ttk::frame .config_t.bg -padding 3] -fill both -expand 1
-
-# The settings array is edited directly in the configuration screen:
-# for most control widgets, we need a global external variable anyway,
-# so we better use the global that is already there.
-# If the configuration screen is closed via the cancel button,
-# the original values will be re-read from disk.
-# If it is closed via the ok button, the new settings are written to disk.
-
-# viewers (not on windows or osx)
-
-if {$::classic_unix} {
- ppack [ttk::frame .config_t.viewf] -in .config_t.bg -ipadx 4 -fill x
- grid [ttk::label .config_t.viewf.title -font bfont -text "Viewers"] \
- -row 0 -column 0 -sticky w
- grid [ttk::label .config_t.viewf.lb_pdf -text "Pdf"] \
- -row 1 -column 0 -sticky w
- grid [ttk::label .config_t.viewf.lb_ps -text "PostScript"] \
- -row 2 -column 0 -sticky w
- grid [ttk::combobox .config_t.viewf.pdf] -row 1 -column 1 -sticky e
- .config_t.viewf.pdf configure -values $::pdf_viewers
- .config_t.viewf.pdf configure -textvariable ::settings(pdf_viewer)
- bind .config_t.viewf.pdf <Escape> {revert_combo %W}
- bind .config_t.viewf.pdf <Return> {update_combo %W}
- bind .config_t.viewf.pdf <FocusOut> {update_combo %W}
- grid [ttk::combobox .config_t.viewf.ps] -row 2 -column 1 -sticky e
- .config_t.viewf.ps configure -values $::ps_viewers
- .config_t.viewf.ps configure -textvariable ::settings(ps_viewer)
- bind .config_t.viewf.ps <Escape> {revert_combo %W}
- bind .config_t.viewf.ps <Return> {update_combo %W}
- bind .config_t.viewf.ps <FocusOut> {update_combo %W}
- grid columnconfigure .config_t.viewf 1 -weight 1 -pad 2
-}
-
-# settings for conversion to pdf
-
-ppack [ttk::frame .config_t.pdff] \
- -in .config_t.bg -ipadx 4 -fill x -pady [list 10 0]
-pack [ttk::label .config_t.pdff.title -font bfont -text "Conversion to pdf"] \
- -anchor w
-
-pack [ttk::label .config_t.pdff.l_target -text "Target use"] -anchor w
-pack [ttk::frame .config_t.pdff.f_targets] -fill x
-foreach t {default printer prepress screen ebook} {
- pack [ttk::radiobutton .config_t.pdff.f_targets.$t \
- -variable ::settings(pdf_target) \
- -text $t -value $t] -side left -padx 2 -pady 4 -anchor w
-}
-
-pack [ttk::label .config_t.pdff.l_version -text "Pdf version"] -anchor w
-pack [ttk::frame .config_t.pdff.f_version] -fill x
-foreach t {1.2 1.3 1.4 1.5 1.6 1.7 default} {
- regsub {\.} $t _ tp ; # replace dot in name: dots are path separators!
- pack [ttk::radiobutton .config_t.pdff.f_version.$tp \
- -variable ::settings(pdf_version) \
- -text $t -value $t] -side left -padx 2 -pady 4 -anchor w
-}
-
-# settings for conversion to EPS and PostScript
-
-ppack [ttk::frame .config_t.psf] \
- -in .config_t.bg -pady [list 10 0] -ipadx 4 -fill x
-pack [ttk::label .config_t.psf.l_ps -text "Conversion to EPS and PostScript" \
- -font bfont] -anchor w
-
-pack [ttk::checkbutton .config_t.psf.c \
- -text "Use pdftops if available"] -anchor w
-.config_t.psf.c configure -variable ::settings(use_pdftops) \
- -onvalue 1 -offvalue 0
-
-# buttons for closing the configuration screen
-
-pack [ttk::frame .config_t.buttonsf] -in .config_t.bg -pady [list 10 0] -fill x
-ppack [ttk::button .config_t.buttonsf.done -text "Done" -command putsettings] \
- -side right
-ppack [ttk::button .config_t.buttonsf.cancel -text "Cancel" \
- -command cancelsettings] -side right
-
-wm transient .config_t
-wm overrideredirect .config_t
-wm withdraw .config_t
-
-proc edit_settings {} {
- wm deiconify .config_t
- raise .config_t
- grab set .config_t
-}
-
-# store new settings
-proc putsettings {} {
- wm withdraw .config_t
- grab release .config_t
- write_settings
-}
-
-proc cancelsettings {} {
- wm withdraw .config_t
- grab release .config_t
- # re-read config file / reg entries
- getsettings
-}
-
-### main screen #############################
-
-proc show_w {w} {
- wm deiconify $w
- raise $w
-}
-
-pack [ttk::frame .bg -padding 3] -fill both -expand 1
-
-# buttons to call up configure-, log- and help screens
-
-pack [ttk::frame .topf] -in .bg -fill x
-ppack [ttk::button .topf.config_t -text "Configure" \
- -command edit_settings] -side left
-ppack [ttk::button .topf.help_t -text "Help" \
- -command {show_w .help_t}] -side right
-ppack [ttk::button .topf.logb -text "Show log" -command {show_w .log_t}] \
- -side right -anchor w
-
-# file info in grid layout
-
-ppack [ttk::frame .infof -relief sunken -border 1 -padding 3] -in .bg -fill x
-grid [ttk::label .infof.dir_label -text "Directory" -anchor w] \
- -row 1 -column 1 -sticky w
-grid [ttk::label .infof.dir_value -textvariable ::gfile(dir) -anchor w] \
- -row 1 -column 2 -sticky w
-
-grid [ttk::label .infof.name_label -text "File" -anchor w] \
- -row 2 -column 1 -sticky w
-grid [ttk::label .infof.name_value -textvariable ::gfile(name) -anchor w] \
- -row 2 -column 2 -sticky w
-
-grid [ttk::label .infof.type_label -text "Type" -anchor w] \
- -row 3 -column 1 -sticky w
-grid [ttk::label .infof.type_value -textvariable ::gfile(type) -anchor w] \
- -row 3 -column 2 -sticky w
-
-grid [ttk::label .infof.npages_label -text "Pages" -anchor w] \
- -row 4 -column 1 -sticky w
-grid [ttk::label .infof.npages_value -textvariable ::gfile(npages) -anchor w] \
- -row 4 -column 2 -sticky w
-
-grid columnconfigure .infof 1 -weight 1 -pad 2
-grid columnconfigure .infof 2 -weight 3 -pad 2
-
-# conversion options
-
-pack [ttk::frame .optsf] -in .bg -pady [list 10 0] -fill x
-
-# grayscaling
-pack [ttk::frame .optsf.gray] -side left -anchor nw
-pack [ttk::label .optsf.gray.l -text "Grayscaling"] -anchor w
-pack [ttk::radiobutton .optsf.gray.off -text "No color conversion" \
- -variable ::options(gray) -value "color"] -anchor w
-pack [ttk::radiobutton .optsf.gray.gray -text "Grayscale" \
- -variable ::options(gray) -value "gray"] -anchor w
-
-# output format
-pack [ttk::label .optsf.format] -side right -anchor ne
-pack [ttk::label .optsf.format.l -text "Output format"] -anchor w
-ttk::radiobutton .optsf.format.pdf -text "pdf" \
- -command set_widget_states -variable ::options(format) -value "pdf"
-ttk::radiobutton .optsf.format.eps -text "eps" -command set_widget_states \
- -variable ::options(format) -value "eps"
-ttk::radiobutton .optsf.format.ps -text "ps" -command set_widget_states \
- -variable ::options(format) -value "ps"
-pack .optsf.format.pdf -anchor w
-pack .optsf.format.eps -anchor w
-pack .optsf.format.ps -anchor w
-
-# boundingbox
-pack [ttk::checkbutton .bbox -text "Compute tight boundingbox" \
- -variable ::options(bbox) -command set_widget_states] \
- -in .bg -anchor w -pady [list 10 0]
-
-# page selection
-pack [ttk::frame .pagesf] -in .bg -fill x
-pack [ttk::radiobutton .pagesf.all -text "Convert all pages" \
- -variable ::options(pages) -value "all" -command set_widget_states] \
- -side left
-pack [ttk::radiobutton .pagesf.single -text "Page:" \
- -variable ::options(pages) -value "single" -command set_widget_states] \
- -side left -padx [list 10 0]
-pack [entry .pagesf.e -width 6 -textvariable ::options(page)] -side left
-#.pagesf.e configure -vcmd {page_valid %W} -validate focusout \
-# -invcmd "focusAndFlash %W [.pagesf.e cget -fg] [.pagesf.e cget -bg]"
-.pagesf.e configure -vcmd {page_valid %W} -validate focusout \
- -invcmd "see_red %W"
-
-# temp files
-pack [ttk::checkbutton .clean -text "Remove temp files" \
- -variable ::options(clean)] -in .bg -anchor w -pady [list 10 0]
-
-proc focusAndFlash {w fg bg {count 9}} {
- focus $w
- if {$count<1} {
- $w configure -foreground $fg -background $bg
- } else {
- if {$count%2} {
- $w configure -foreground $bg -background $fg
- } else {
- $w configure -foreground $fg -background $bg
- }
- after 200 [list focusAndFlash $w $fg $bg [expr {$count-1}]]
- }
-}
-
-proc see_red {w} {
- focus $w
- set orig [$w cget -bg]
- $w configure -bg red
- update idletasks
- after 1000
- $w configure -bg $orig
- update idletasks
-}
-
-proc page_valid {w} {
- # w entry widget
- set p [$w get]
- set isvalid 1
- #puts "check pageno $p"
- if {! [string is integer $p] || $p<=0} {
- set isvalid 0
- } elseif {$::gfile(npages) ne "" && [scan $p "%d"] > $::gfile(npages)} {
- set isvalid 0
- }
- return $isvalid
-}
-
-# end conversion options
-
-pack [ttk::label .status -justify left -text "Idle"] \
- -in .bg -side bottom -anchor w -fill x -expand 1
-
-# main buttons
-
-pack [ttk::frame .bottomf] -in .bg -side bottom -fill x
-ppack [ttk::button .bottomf.view -text "View" -command view] -side left
-ppack [ttk::button .bottomf.open -text "Open" -command openDialog] \
- -side left -padx 2
-ppack [ttk::button .bottomf.convert -text "Convert and save..." \
- -command saveDialog] -side left -padx 2
-ppack [ttk::button .bottomf.done -text "Done" -command exit] -side right
-
-proc view {} {
- if {! [viewable]} {
- tk_messageBox -icon warning -type ok \
- -message "No viewer for $::gfile(path)"
- return
- }
- if {$::tcl_platform(os) eq "Darwin"} {
- catch {exec open $::gfile(path) &}
- } elseif {$::tcl_platform(platform) ne "unix"} {
- # use shortname to sidestep quoting problems
- catch {exec cmd /x /c start [file attributes $::gfile(path) -shortname]}
- } else {
- if {$::gfile(type) eq "pdf"} {
- catch {exec $::settings(pdf_viewer) $::gfile(path) &}
- } elseif {$::gfile(type) ne "other" && $::gfile(type) ne ""} {
- catch {exec $::settings(ps_viewer) $::gfile(path) &}
- }
- }
-}
-
-proc openDialog {} {
- set types {
- {"PostScript and pdf" {.eps .epi .epsi .ps .prn .pdf}}
- {"Encapsulated PostScript" {.eps .epi .epsi}}
- {"General PostScript" {.ps .prn}}
- {"Pdf" {.pdf}}
- {"All files" *}
- }
- if {[file isdirectory $::gfile(dir)]} {
- set try [tk_getOpenFile -filetypes $types -initialdir $::gfile(dir)]
- } else {
- set try [tk_getOpenFile -filetypes $types]
- }
- if {$try != ""} {
- set ::gfile(path) [file normalize $try]
- set ::gfile(dir) [file dirname $::gfile(path)]
- set ::gfile(name) [file tail $::gfile(path)]
- set ::gfile(type) ""
- if {! [catch {exec $::texlua $::epspdf_tlu --gui=gui -i $::gfile(path)} \
- result]} {
- # parse output
- regexp {has type (\w+)(?:.+ (\d+) pages)?\.} $result \
- mtc ::gfile(type) ::gfile(npages)
- if {[regexp {^eps} $::gfile(type)]} {set ::gfile(npages) 1}
- }
- if {$::gfile(type) eq ""} {
- # unsupported type
- tk_messageBox -message "$try: unreadable or unsupported type" \
- -title "Error" -icon error
- }
- set ::settings(default_dir) $::gfile(dir)
- putsettings
- }
- set_widget_states
-}
-
-proc saveDialog {} {
- if {$::options(format) eq "pdf"} {
- set types {{"Pdf" {.pdf}}}
- } elseif {$::options(format) eq "ps"} {
- set types {{"PostScript" {.ps}}}
- } elseif {$::options(format) eq "eps"} {
- set types {{"Encapsulated PostScript" {.eps}}}
- }
- set try [tk_getSaveFile -filetypes $types -initialdir $::gfile(dir)]
- if {$try != ""} {
- # fix extension
- set try [file normalize $try]
- set idot [string last "." [file tail $try]]
- if {$idot == -1} {
- append try ".$::options(format)"
- } else {
- # don't bother checking whether the extension is already correct
- set try [string range $try 0 [string last "." $try]]
- append try $::options(format)
- }
- set try [file normalize $try]
- # epspdf can read persistent options from configuration.
- # only options from the options array need to be converted to parameters.
- set args [list]
- if {$::options(gray) eq "gray"} {lappend args "-g"}
- if {$::options(bbox)} {lappend args "-b"}
- if {! $::options(clean)} {lappend args "-d"}
- if {$::options(pages) eq "single"} {
- if {$::options(page) eq ""} {set ::options(page) 1}
- lappend args "-p" $::options(page)
- }
- lappend args $::gfile(path) $try
- .status configure -text "Working..." -justify "left"
- foreach b {view open convert done} {
- .bottomf.$b configure -state disabled
- }
- update idletasks; # force immediate redisplay main window
-
- set cmd {} ; # necessary? if- and else blocks do not seem to define scopes
- if {$::tcl_platform(platform) == "windows"} {
- set cmd [linsert $args 0 exec -ignorestderr $::epspdf_cmd --gui=gui]
- } else {
- set cmd [linsert $args 0 exec -ignorestderr \
- $::texlua $::epspdf_tlu --gui=gui]
- }
- set failed [catch $cmd result]
- write_log $result
- if $failed {
- tk_messageBox -icon error -type ok -message "Error; see log window"
- } else {
- set ::gfile(path) [file normalize $try]
- set ::gfile(dir) [file dirname $::gfile(path)]
- set ::gfile(type) $::options(format)
- set ::gfile(name) [file tail $::gfile(path)]
- if {$::gfile(type) eq "pdf"} {
- if {! [catch {
- exec $::texlua $::epspdf_tlu --gui=gui -i $::gfile(path)} \
- result]} {
- regexp {(\d+) pages\.$} $result mtc ::gfile(npages)
- }
- } elseif {$::gfile(type) eq "eps"} {
- set ::gfile(npages) 1
- }
- set ::settings(default_dir) $::gfile(dir)
- putsettings
- set ::options(page) 1
- }
- .status configure -text "Idle"
- foreach b {view open convert done} {
- .bottomf.$b configure -state normal
- }
- focus .bottomf.view
- set_widget_states
- }
-}
-
-proc set_widget_states {} {
- # states (normal/disabled) for various widgets.
- # their values should already be mutually consistent.
- # widgets concerned:
- # view / save
- # output format / bbox / single page / page no.
-
- # view
- if {[viewable]} {
- .bottomf.view configure -state normal
- } else {
- .bottomf.view configure -state disabled
- }
-
- # convert
- .bottomf.convert configure -state normal
- if {$::gfile(path) eq "" || ! [file exists $::gfile(path)]} { \
- .bottomf.convert configure -state disabled
- }
- if {$::gfile(type) eq "other"} {
- .bottomf.convert configure -state disabled
- }
- if {$::gfile(npages) ne "" && $::options(pages) eq "single" && \
- $::options(page) > $::gfile(npages)} {
- .bottomf.convert configure -state disabled
- }
-
- # type
- if {[regexp {ps|pdf} $::gfile(type)]} {
- foreach f {pdf eps ps} {.optsf.format.$f configure -state normal}
- } else {
- foreach f {pdf eps ps} {.optsf.format.$f configure -state disabled}
- }
-
- # pages and page
- foreach f {all single} {.pagesf.$f configure -state normal}
- if {$::options(format) eq "eps"} {
- .pagesf.all configure -state disabled
- set ::options(pages) "single"
- }
- if {$::options(format) eq "ps"} {
- .pagesf.single configure -state disabled
- set ::options(pages) "all"
- }
- if {$::options(pages) eq "all"} {
- .pagesf.e configure -state disabled
- } else {
- .pagesf.e configure -state normal
- }
-
- # boundingbox
- if {$::options(format) eq "eps"} {
- .bbox configure -state normal
- } elseif {$::options(pages) eq "all"} {
- .bbox configure -state disabled
- set ::options(bbox) 0
- } else {
- .bbox configure -state normal
- }
- update idletasks
-}
-
-set_widget_states
diff --git a/Build/source/texk/texlive/linked_scripts/epstopdf/epstopdf.pl b/Build/source/texk/texlive/linked_scripts/epstopdf/epstopdf.pl
deleted file mode 100755
index 5a9567615ab..00000000000
--- a/Build/source/texk/texlive/linked_scripts/epstopdf/epstopdf.pl
+++ /dev/null
@@ -1,1006 +0,0 @@
-#!/usr/bin/env perl
-# $Id: epstopdf.pl 48681 2018-09-16 23:03:58Z karl $
-# (Copyright lines below.)
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. The name of the author may not be used to endorse or promote
-# products derived from this software without specific prior written
-# permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-# ----------------------------------------------------------------
-# This is a script to transform an EPS file to PDF. Theoretically, any
-# Level 2 PS interpreter should work, although in practice using
-# Ghostscript is near-universal. Many more details below.
-#
-# One thing not supported is the case of
-# "%%BoundingBox: (atend)" when input is not seekable (e.g., from a pipe),
-#
-# emacs-page
-#
-my $ver = "2.28";
-# 2018/09/17 v2.28 (Karl Berry)
-# * -dCompatibilityLevel=1.5 by default, since gs9.25 switched to 1.7.
-# 2017/09/14 v2.27 (Karl Berry)
-# * extract value from --gsopt with $3 not $2 (extra regexp group
-# added previously), and check it with ^(...)$ so anchors apply to all.
-# (report to Karl from Yannick Berker, 7 Sep 2017 14:07:09.)
-# 2017/01/07 v2.26 (Norbert Preining, Karl Berry)
-# * allow cmdline of infile outfile.pdf.
-# * explicitly allow -o as abbreviation for --outfile,
-# to guard against future --options. (Also --output.)
-# 2016/06/30 v2.25 (Norbert Preining, Karl Berry)
-# * don't set (default) device until after restricted check.
-# * a few more debugging lines.
-# 2016/05/29 v2.24 (Karl Berry)
-# * new option --gray; patch from William Bader,
-# tex-k mail 9 Feb 2016 19:37:08.
-# * disallow --device completely in restricted mode,
-# to avoid maintenance of device list.
-# tex-live mail 10 Feb 2016 10:36:26.
-# 2015/01/22 v2.23 (Karl Berry)
-# * use # instead of = to placate msys; report from KUROKI Yusuke,
-# tex-k mail 20 Jan 2015 12:40:16.
-# 2014/06/18 v2.22 (Karl Berry)
-# * escape % in $outputfilename; report from William Fischer,
-# tex-k mail 16 Jun 2014 18:45:12.
-# 2014/01/17 v2.21 (Karl Berry)
-# * tweaks to help message, per reports from Knuth.
-# 2013/09/28 v2.20 (Heiko Oberdiek, and (a little) Karl Berry)
-# * New command line argument --(no)safer which allows setting
-# -dNOSAFER instead of -dSAFER (only for non-restricted).
-# * New command line argument --pdfsettings for
-# Ghostscript's -dPDFSETTINGS.
-# * New command line argument --(no)quiet.
-# * New command line argument --device for specifying a differnt
-# Ghostscript device (limited set of devices for restricted mode).
-# * New command line arguments --gsopts and --gsopt for adding
-# Ghostscript options.
-# * Full support of ghostscript's option -r, DPIxDPI added.
-# * Support for DOS EPS binary files (TN 5002) added.
-# * Removes PJL commands at start of file.
-# 2013/05/12 v2.19 (Karl Berry)
-# * explain option naming conventions (= defaults for Getopt::Long).
-# 2012/05/22 v2.18 (Karl Berry)
-# * use /usr/bin/env, since Ruby has apparently required #! for years,
-# and we rely on it for our other scripts, so why not.
-# (tex-k mail from Jean Krohn, 2 Aug 2010 15:57:54,
-# per http://osdir.com/ml/lang.ruby.general/2002-06/msg01388.html
-# and ruby-bugs:PR#315).
-# 2012/05/12 v2.17 (Karl Berry)
-# * uselessly placate -w. Debian bug 672281.
-# 2010/05/09 v2.16 (Karl Berry)
-# * make --nogs dump edited PostScript to stdout by default
-# (report from Reinhard Kotucha).
-# 2010/03/19 v2.15 (Karl Berry)
-# * let --outfile override --filter again.
-# * recognize MSWin64 as well as MSWin32, just in case.
-# 2010/03/08 v2.14 (Manuel P\'egouri\'e-Gonnard)
-# * In restricted mode, forbid --gscmd (all platforms) and call GS with full
-# path relative to self location (Windows).
-# 2010/02/26 v2.13 (Karl Berry)
-# * New release.
-# 2010/02/23 (Manuel P\'egouri\'e-Gonnard)
-# * Use kpsewhich for filename validation in restricted mode, both input and
-# output. Requires kpathsea 5.1.0 (TL2010), rejects the name with earlier
-# versions of kpsewhich.
-# * Call external programs with full path on win32 in order to avoid obvious
-# attacks with rogue versions of these programs in the current directory.
-# 2009/11/27 v2.12 (Karl Berry)
-# * Make --filter work again
-# 2009/11/25 (Manuel P\'egouri\'e-Gonnard)
-# * Better extension detection, suggested by A. Cherepanov.
-# 2009/10/18 (Manuel P\'egouri\'e-Gonnard)
-# * Better argument validation (Alexander Cherepanov).
-# * Use list form of pipe open() (resp. system()) to prevent injection.
-# Since Perl's fork() emulation doesn't work on Windows with Perl 5.8.8 from
-# TeX Live 2009, use a temporary file instead of a pipe on Windows.
-# 2009/10/14 (Manuel P\'egouri\'e-Gonnard)
-# * Added restricted mode.
-# 2009/09/27 v2.11 (Karl Berry)
-# * Fixed two bugs in the (atend) handling code (Martin von Gagern)
-# * Improved handling of CR line ending (Martin von Gagern)
-# * More error checking
-# * --version option
-# * Create source repository in TeX Live
-# 2009/07/17 v2.9.11gw
-# * Added -dSAFER to default gs options
-# TL2009 wants to use a restricted variant of -shell-escape,
-# allowing epstopdf to run. However without -dSAFER Ghostscript
-# allows writing to files (other than given in -sOutputFile)
-# and running commands (through Ghostscript pipe's language feature).
-# 2009/05/09 v2.9.10gw
-# * Changed cygwin name for ghostscript to gs
-# 2008/08/26 v2.9.9gw
-# * Switch to embed fonts (default=yes) (J.P. Chretien)
-# * turned no AutoRotatePages into an option (D. Kreil) (default = None)
-# * Added resolution switch (D. Kreil)
-# * Added BSD-style license
-# 2007/07/18 v2.9.8gw
-# 2007/05/18 v.2.9.7gw (Gerben Wierda)
-# * Merged both supplied 2.9.6 versions
-# 2007/05/15 v2.9.6tp (Theo Papadopoulo)
-# * Simplified the (atend) support
-# 2007/01/24 v2.9.6sw (Staszek Wawrykiewicz)
-# * patched to work also on Windows
-# 2005/10/06 v2.9.5gw (Gerben Wierda)
-# * Fixed a horrendous bug in the (atend) handling code
-# 2005/10/06 v2.9.4gw (Gerben Wierda)
-# * This has become the official version for now
-# 2005/10/01 v2.9.3draft (Gerben Wierda)
-# * Quote OutFilename
-# 2005/09/29 v2.9.2draft (Gerben Wierda)
-# * Quote OutFilename
-# 2004/03/17 v2.9.1draft (Gerben Wierda)
-# * No autorotate page
-# 2003/04/22 v2.9draft (Gerben Wierda)
-# * Fixed bug where with cr-eol files everything up to the first %!
-# * in the first 2048 bytes was gobbled (double ugh!)
-# 2002/02/21 v2.8draft (Gerben Wierda)
-# * Fixed bug where last line of buffer was not copied out (ugh!)
-# 2002/02/18 v2.8draft (Gerben Wierda)
-# * Handle different eol styles transparantly
-# * Applied fix from Peder Axensten for Freehand bug
-# 2001/03/05 v2.7 (Heiko Oberdiek)
-# * Newline before grestore for the case that there is no
-# whitespace at the end of the eps file.
-# 2000/11/05 v2.6 (Heiko Oberdiek)
-# * %%HiresBoundingBox corrected to %%HiResBoundingBox
-# 1999/05/06 v2.5 (Heiko Oberdiek)
-# * New options: --hires, --exact, --filter, --help.
-# * Many cosmetics: title, usage, ...
-# * New code for debug, warning, error
-# * Detecting of cygwin perl
-# * Scanning for %%{Hires,Exact,}BoundingBox.
-# * Scanning only the header in order not to get a wrong
-# BoundingBox of an included file.
-# * (atend) supported.
-# * uses strict; (earlier error detecting).
-# * changed first comment from '%!PS' to '%!';
-# * corrected (atend) pattern: '\s*\(atend\)'
-# * using of $bbxpat in all BoundingBox cases,
-# correct the first white space to '...Box:\s*$bb...'
-# * corrected first line (one line instead of two before 'if 0;';
-#
-# Thomas Esser, Sept. 1998: change initial lines to find
-# perl along $PATH rather than guessing a fixed location. The above
-# construction should work with most shells.
-#
-# Originally by Sebastian Rahtz, for Elsevier Science
-# with extra tricks from Hans Hagen's texutil and many more.
-
-### emacs-page
-### program identification
-my $program = "epstopdf";
-my $ident = '($Id: epstopdf.pl 48681 2018-09-16 23:03:58Z karl $)' . " $ver";
-my $copyright = <<END_COPYRIGHT ;
-Copyright 2009-2018 Karl Berry et al.
-Copyright 2002-2009 Gerben Wierda et al.
-Copyright 1998-2001 Sebastian Rahtz et al.
-License RBSD: Revised BSD <http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5>
-This is free software: you are free to change and redistribute it.
-There is NO WARRANTY, to the extent permitted by law.
-END_COPYRIGHT
-my $title = "$program $ident\n";
-
-my $on_windows = $^O =~ /^(MSWin|msys$)/;
-my $on_windows_or_cygwin = $on_windows || $^O eq "cygwin";
-
-### ghostscript command name
-my $GS = $on_windows ? "gswin32c" : "gs";
-
-### restricted mode
-my $restricted = 0;
-$restricted = 1 if $0 =~ /repstopdf/;
-
-### default values
-my $default_device = 'pdfwrite';
-
-### options
-$::opt_autorotate = "None";
-$::opt_compress = 1;
-$::opt_debug = 0;
-$::opt_device = "";
-$::opt_embed = 1;
-$::opt_exact = 0;
-$::opt_filter = 0;
-$::opt_gray = 0;
-$::opt_gs = 1;
-$::opt_gscmd = "";
-@::opt_gsopt = ();
-$::opt_help = 0;
-$::opt_hires = 0;
-$::opt_outfile = "";
-$::opt_pdfsettings = "";
-$::opt_res = '';
-$::opt_restricted = 0;
-$::opt_safer = 1;
-$::opt_quiet = 1;
-$::opt_version = 0;
-
-sub gsopts { push (@::opt_gsopt, split (' ', $_[1])); }
-
-# known-safe Ghostscript options and values.
-my %optcheck = qw<
- AlignToPixels 0|1
- AntiAliasColorImages true|false
- AntiAliasGrayImages true|false
- AntiAliasMonoImages true|false
- ASCII85EncodePages true|false
- AutoFilterColorImages true|false
- AutoFilterGrayImages true|false
- AutoPositionEPSFiles true|false
- AutoRotatePages /(None|All|PageByPage)
- BATCH true
- Binding /(Left|Right)
- CannotEmbedFontPolicy /(OK|Warning|Error)
- ColorConversionStrategy /(LeaveColorUnchanged|UseDeviceIndependentColor|UseDeviceIndependendColorForImages|sRGB|CMYK)
- ColorImageDepth -1|1|2|4|8
- ColorImageDownsampleThreshold 10(.0*)?|\d(.\d*)|\.\d+
- ColorImageDownsampleType /(Average|Bicubic|Subsample|None)
- ColorImageFilter /(DCTEncode|FlateEncode|JPXEncode)
- ColorImageResolution \d+
- COLORSCREEN true|0|false
- CompatibilityLevel 1\.[0-7]
- CompressFonts true|false
- CompressPages true|false
- ConvertCMYKImagesToRGB true|false
- ConvertImagesToIndexed true|false
- DefaultRenderingIntent /(Default|Perceptual|Saturation|AbsoluteColorimetric|RelativeColorimetric)
- DetectBlends true|false
- DetectDuplicateImages true|false
- DITHERPPI \d+
- DOINTERPOLATE true
- DoThumbnails true|false
- DownsampleColorImages true|false
- DownsampleGrayImages true|false
- DownsampleMonoImages true|false
- EmbedAllFonts true|false
- EmitDSCWarnings true|false
- EncodeColorImages true|false
- EncodeGrayImages true|false
- EncodeMonoImages true|false
- EndPage -?\d+
- FIXEDRESOLUTION true
- GraphicsAlphaBits 1|2|4
- GrayImageDepth -1|1|2|4|8
- GrayImageDownsampleThreshold \d+\.?\d*|\.\d+
- GrayImageDownsampleType /(Average|Bicubic)
- GrayImageFilter /(DCTEncode|FlateEncode|JPXEncode)
- GrayImageResolution \d+
- GridFitTT 0|1|2|3
- HaveTransparency true|false
- HaveTrueTypes true|false
- ImageMemory \d+
- LockDistillerParams true|false
- LZWEncodePages true|false
- MaxSubsetPct 100|[1-9][0-9]?
- MaxClipPathSize \d+
- MaxInlineImageSize \d+
- MaxShadingBitmapSize \d+
- MonoImageDepth -1|1|2|4|8
- MonoImageDownsampleThreshold \d+\.?\d*|\.\d+
- MonoImageDownsampleType /(Average|Bicubic|Subsample|None)
- MonoImageFilter /(CCITTFaxEncode|FlateEncode|RunLengthEncode)
- MonoImageResolution \d+
- NOCIE true
- NODISPLAY true
- NOEPS true
- NOINTERPOLATE true
- NOPSICC true
- NOSUBSTDEVICECOLORS true|false
- NOTRANSPARENCY true
- OPM 0|1
- Optimize true|false
- ParseDSCComments true|false
- ParseDSCCommentsForDocInfo true|false
- PreserveCopyPage true|false
- PreserveEPSInfo true|false
- PreserveHalftoneInfo true|false
- PreserveOPIComments true|false
- PreserveOverprintSettings true|false
- StartPage -?\d+
- PatternImagemask true|false
- PDFSETTINGS /(screen|ebook|printer|prepress|default)
- PDFX true|false
- PreserveDeviceN true|false
- PreserveSeparation true|false
- QUIET true
- SHORTERRORS true
- SubsetFonts true|false
- TextAlphaBits 1|2|4
- TransferFunctionInfo /(Preserve|Remove|Apply)
- UCRandBGInfo /(Preserve|Remove)
- UseCIEColor true|false
- UseFlateCompression true|false
- UsePrologue true|false
->;
-# In any case not suitable for restricted:
-# -dDOPS
-
-### usage
-my @bool = ("false", "true");
-my $resmsg = $::opt_res ? $::opt_res : "[use gs default]";
-my $rotmsg = $::opt_autorotate ? $::opt_autorotate : "[use gs default]";
-
-my $usage = <<"END_OF_USAGE";
-${title}Usage: $program [OPTION]... [EPSFILE [PDFFILE.pdf]]
-
-Convert an EPS file to PDF (or other formats), by default using Ghostscript.
-
-By default, the output name is the input name with any extension
-replaced by ".pdf". An output name ending with .pdf can also be given
-as a second argument on the command line, or the --outfile (-o) option
-can be used with any name.
-
-The output is PDF 1.5 by default; use --gsopt=-dCompatibilityLevel=1.7
-(for example) to change this.
-
-The resulting output is guaranteed to start at the 0,0 coordinate, and
-sets a page size exactly corresponding to the BoundingBox. Thus, the
-result does not need any cropping, and the PDF MediaBox is correct.
-
-If the bounding box in the input is incorrect, of course there will
-be resulting problems.
-
-Options:
- --help display this help and exit
- --version display version information and exit
-
- -o, --outfile=FILE write result to FILE (default based on input name)
- --restricted use restricted mode (default: $bool[$restricted])
-
- --(no)debug output debugging info (default: $bool[$::opt_debug])
- --(no)exact scan ExactBoundingBox (default: $bool[$::opt_exact])
- --(no)filter read standard input (default: $bool[$::opt_filter])
- --(no)gs run ghostscript (default: $bool[$::opt_gs])
- --(no)hires scan HiResBoundingBox (default: $bool[$::opt_hires])
-
-Options for Ghostscript:
- --gscmd=VAL pipe output to VAL (default: $GS)
- --gsopt=VAL single option for gs (see below)
- --gsopts=VAL options for gs (see below)
- --autorotate=VAL set AutoRotatePages (default: $rotmsg)
- recognized VAL choices: None, All, PageByPage;
- for EPS files, PageByPage is equivalent to All.
- --(no)compress use compression (default: $bool[$::opt_compress])
- --device=DEV use -sDEVICE=DEV (default: $default_device)
- --(no)embed embed fonts (default: $bool[$::opt_embed])
- --(no)gray grayscale output (default: $bool[$::opt_gray])
- --pdfsettings=VAL use -dPDFSETTINGS=/VAL (default is prepress if --embed,
- else empty); recognized VAL choices:
- screen, ebook, printer, prepress, default.
- --(no)quiet use -q (-dQUIET) (default: $bool[$::opt_quiet])
- --res=DPI|DPIxDPI set image resolution (default: $resmsg)
- ignored if option --debug is set.
- --(no)safer use -d(NO)SAFER (default: $bool[$::opt_safer])
-
-Examples all equivalently converting test.eps to test.pdf:
- \$ $program test.eps
- \$ $program test.eps test.pdf
- \$ cat test.eps | $program --filter >test.pdf
- \$ cat test.eps | $program -f -o=test.pdf
-
-Example for using HiResBoundingBox instead of BoundingBox:
- \$ $program --hires test.eps
-
-Example for producing epstopdf's attempt at corrected PostScript:
- \$ $program --nogs test.ps >testcorr.ps
-
-In all cases, you can add --debug (-d) to see more about what epstopdf
-is doing.
-
-More about the options for Ghostscript:
- Additional options to be used with gs can be specified
- with either or both of the two cumulative options --gsopts and --gsopt.
- --gsopts takes a single string of options, which is split at whitespace
- and each resulting word then added to the gs command line individually.
- --gsopt adds its argument as a single option to the gs command line.
- It can be used multiple times to specify options separately,
- and is necessary if an option or its value contains whitespace.
- In restricted mode, options are limited to those with names and values
- known to be safe. Some options taking booleans, integers or fixed
- names are allowed, those taking general strings are not.
-
-All options to epstopdf may start with either - or --, and may be
-unambiguously abbreviated. It is best to use the full option name in
-scripts to avoid possible collisions with new options in the future.
-
-When reporting bugs, please include an input file and all command line
-options so the problem can be reproduced.
-
-Report bugs to: tex-k\@tug.org
-epstopdf home page: <http://tug.org/epstopdf/>
-END_OF_USAGE
-
-### process options
-use Getopt::Long;
-GetOptions (
- "autorotate=s", # \ref{val_autorotate}
- "compress!",
- "debug!",
- "device=s",
- "embed!",
- "exact!",
- "gray!",
- "filter!",
- "gs!",
- "gscmd=s", # \ref{val_gscmd}
- "gsopt=s@", # \ref{val_gsopt}
- "gsopts=s" => \&gsopts, # \ref{val_gsopts}
- "help|h",
- "hires!",
- "outfile|output|o=s", # \ref{openout_any}
- "pdfsettings=s",
- "quiet",
- "res=s",
- "restricted",
- "safer!",
- "version",
-) or die "Try $0 --help for more information\n";
-
-### disable --quiet if option --debug is given
-$::opt_quiet = 0 if $::opt_debug;
-
-### restricted option
-$restricted = 1 if $::opt_restricted;
-
-### help functions
-sub debug { print STDERR "* @_\n" if $::opt_debug; }
-sub warning { print STDERR "==> Warning: @_\n"; }
-sub error { die "$title!!! Error: @_\n"; }
-sub errorUsage { die "$program: Error: @_ (try --help for more information)\n"; }
-sub warnerr { $restricted ? error(@_) : warning(@_); }
-
-### debug messages
-debug "Restricted mode activated" if $restricted;
-
-### safer external commands for Windows in restricted mode
-my $kpsewhich = 'kpsewhich';
-if ($restricted && $on_windows) {
- use File::Basename;
- my $mydirname = dirname $0;
- # $mydirname is the location of the Perl script
- $kpsewhich = "$mydirname/../../../bin/win32/$kpsewhich";
- $GS = "$mydirname/../../../tlpkg/tlgs/bin/$GS";
-}
-debug "kpsewhich command: $kpsewhich";
-
-### check if a name is "safe" according to kpse's open(in|out)_any
-# return true if name is ok, false otherwise
-sub safe_name {
- my ($mode, $name) = @_;
- my $option = "";
- $option = '-safe-in-name' if $mode eq 'in';
- $option = '-safe-out-name' if $mode eq 'out';
- error "Unknown check mode in safe_name(): $mode" unless $option;
- my @args = ($kpsewhich, '-progname', 'repstopdf', $option, $name);
- my $bad = system {$args[0]} @args;
- return ! $bad;
-}
-
-### help, version options.
-if ($::opt_help) {
- print $usage;
- exit 0;
-}
-
-if ($::opt_version) {
- print $title;
- print $copyright;
- exit 0;
-}
-
-### get input filename (\ref{openin_any} for validation)
-my $InputFilename = "";
-if ($::opt_filter) {
- @ARGV == 0 or
- errorUsage "Input file cannot be used with filter option";
- debug "Filtering: will read standard input";
-} else {
- # not filtering.
- @ARGV > 0 or errorUsage "Input filename missing";
- # allow infile outfile.pdf.
- if (@ARGV == 2) {
- if ($::opt_outfile) {
- errorUsage ("Multiple output specifications: second arg=$ARGV[1],"
- . " --outfile=$::opt_outfile");
- }
- if ($ARGV[1] !~ m/\.pdf$/i) {
- errorUsage "Output file argument requires .pdf extension: $ARGV[1]";
- }
- # seems we can use it.
- $::opt_outfile = $ARGV[1];
- debug "Output filename from argv:", $::opt_outfile;
- }
- @ARGV > 2 and errorUsage "Too many arguments: @ARGV";
-
- $InputFilename = $ARGV[0];
- debug "Input filename:", $InputFilename;
-}
-
-### emacs-page
-### building the gs invocation.
-
-### option gscmd
-if ($::opt_gscmd) {
- if ($restricted) { # \label{val_gscmd}
- error "Option forbidden in restricted mode: --gscmd";
- } else {
- debug "Switching from $GS to $::opt_gscmd";
- $GS = $::opt_gscmd;
- }
-}
-
-### start building GS command line for the pipe
-my @GS = ($GS);
-push @GS, '-q' if $::opt_quiet;
-push @GS, $::opt_safer ? '-dSAFER' : '-dNOSAFER';
-push @GS, '-dNOPAUSE';
-push @GS, '-dBATCH';
-push @GS, '-dCompatibilityLevel=1.5';
-
-### option device
-if ($::opt_device) {
- if ($restricted) {
- error "Option forbidden in restricted mode: --device";
- } else {
- debug "Switching from $default_device to $::opt_device";
- }
-} else {
- $::opt_device = $default_device;
-}
-
-push @GS, "-sDEVICE=$::opt_device";
-
-### option outfile
-my $OutputFilename = $::opt_outfile;
-if (! $OutputFilename) {
- if ($::opt_gs) {
- if ($::opt_filter) {
- debug "Filtering: will write standard output";
- $OutputFilename = "-";
- } else {
- # Ghostscript, no filter: replace input extension with .pdf.
- $OutputFilename = $InputFilename;
- my $ds = $on_windows_or_cygwin ? '\\/' : '/';
- $OutputFilename =~ s/\.[^\.$ds]*$//;
- $OutputFilename .= ".pdf";
- }
- } else {
- debug "No Ghostscript: will write standard output";
- $OutputFilename = "-";
- }
-}
-$OutputFilename =~ s/%/%%/g; # we will do the escaping for gs
-debug "Output filename:", $OutputFilename;
-push @GS, "-sOutputFile=$OutputFilename";
-
-### options compress, embed, res, autorotate
-$::opt_pdfsettings = 'prepress' if $::opt_embed and not $::opt_pdfsettings;
-if ($::opt_pdfsettings
- && $::opt_pdfsettings
- !~ s/^\/?(screen|ebook|printer|prepress|default)$/$1/) {
- warnerr "Invalid value for --pdfsettings: $::opt_pdfsettings";
- $::opt_pdfsettings = '';
-}
-# use # instead of = to avoid mingw path munging.
-push (@GS, "-dPDFSETTINGS#/$::opt_pdfsettings") if $::opt_pdfsettings;
-
-push @GS, qw[
- -dMaxSubsetPct=100
- -dSubsetFonts=true
- -dEmbedAllFonts=true
-] if $::opt_embed;
-
-push @GS, '-dUseFlateCompression=false' unless $::opt_compress;
-
-push @GS, qw(-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray)
- if $::opt_gray;
-
-if ($::opt_res and
- not $::opt_res =~ /^(\d+(x\d+)?)$/) {
- warnerr "Invalid resolution: $opt_res";
- $::opt_res = '';
-}
-push @GS, "-r$::opt_res" if $::opt_res;
-$resmsg = $::opt_res ? $::opt_res : "[use gs default]";
-
-# \label{val_autorotate}
-if ($::opt_autorotate and
- not $::opt_autorotate =~ /^(None|All|PageByPage)$/) {
- warnerr "Invalid value for --autorotate: $::opt_autorotate' "
- . "(use 'All', 'None' or 'PageByPage'";
- $::opt_autorotate = '';
-}
-# use # instead of = to avoid mingw path munging.
-push (@GS, "-dAutoRotatePages#/$::opt_autorotate") if $::opt_autorotate;
-$rotmsg = $::opt_autorotate ? $::opt_autorotate : "[use gs default]";
-
-foreach my $gsopt (@::opt_gsopt) {
- if ($restricted) {
- my $ok = 0;
- if ($gsopt =~ /^-[dD]([A-Za-z0-9]+)(=(.*))?$/) {
- my $name = $1;
- my $value = $3;
- $value = 'true' if not defined $value;
- if ($optcheck{$name} and $value =~ /^($optcheck{$name})$/) {
- $ok = 1;
- }
- else {
- warnerr "Option forbidden in restricted mode: --gsopt $gsopt";
- $gsopt = '';
- }
- }
- if (not $ok) {
- warnerr "Option forbidden in restricted mode: --gsopt $gsopt";
- $gsopt = '';
- }
- }
- push @GS, $gsopt if $gsopt;
-}
-
-### option BoundingBox types
-my $BBName = "%%BoundingBox:";
-!($::opt_hires and $::opt_exact) or
- error "Options --hires and --exact cannot be used together";
-$BBName = "%%HiResBoundingBox:" if $::opt_hires;
-$BBName = "%%ExactBoundingBox:" if $::opt_exact;
-debug "BoundingBox comment:", $BBName;
-
-### validate input file name in restricted mode \label{openin_any}
-if ($restricted and not $::opt_filter
- and not safe_name('in', $InputFilename)) {
- error "Input filename '$InputFilename' not allowed in restricted mode.";
-}
-
-### validate output file name in restricted mode \label{openout_any}
-if ($restricted and not safe_name('out', $OutputFilename)) {
- error "Output filename '$OutputFilename' not allowed in restricted mode.";
-}
-
-### option gs
-if ($::opt_gs) {
- debug "Ghostscript command:", $GS;
- debug "Compression:", ($::opt_compress) ? "on" : "off";
- debug "Embedding:", ($::opt_embed) ? "on" : "off";
- debug "Grayscale:", ($::opt_gray) ? "on" : "off";
- debug "PDFSettings:", $::opt_pdfsettings;
- debug "Resolution:", $resmsg;
- debug "Rotation:", $rotmsg;
-}
-
-### emacs-page
-### open input file
-if ($::opt_filter) {
- open(IN, '<-') || error("Cannot open stdin: $!");
-} else {
- open(IN, '<', $InputFilename) || error("Cannot open $InputFilename: $!");
-}
-binmode IN;
-
-### open output file
-my $outname; # used in error message at end
-my $tmp_filename; # temporary file for windows
-my $OUT; # filehandle for output (GS pipe or temporary file)
-use File::Temp 'tempfile';
-if ($::opt_gs) {
- if (! $on_windows_or_cygwin) { # list piped open works
- push @GS, qw(- -c quit);
- debug "Ghostscript pipe: @GS";
- open($OUT, '|-', @GS)
- or error "Cannot open Ghostscript for piped input: @GS";
- } else { # use a temporary file on Windows/Cygwin.
- ($OUT, $tmp_filename) = tempfile(UNLINK => 1);
- debug "Using temporary file '$tmp_filename'";
- }
- $outname = $GS;
-}
-else {
- debug "No Ghostscript: opening $OutputFilename";
- if ($OutputFilename eq "-") {
- $OUT = *STDOUT;
- } else {
- open($OUT, '>', $OutputFilename)
- || error ("Cannot write \"$OutputFilename\": $!");
- $outname = $OutputFilename;
- }
-}
-binmode $OUT;
-
-# reading a cr-eol file on a lf-eol system makes it impossible to parse
-# the header and besides it will read the intire file into yor line by line
-# scalar. this is also true the other way around.
-
-### emacs-page
-### scan a block, try to determine eol style
-
-my $buf;
-my $buflen;
-my @bufarray;
-my $inputpos;
-my $maxpos = -1;
-
-# We assume 2048 is big enough.
-my $EOLSCANBUFSIZE = 2048;
-
-# PJL
-my $UEL = "\x1B%-12345X";
-my $PJL = '@PJL[^\r\n]*\r?\n';
-
-$buflen = read(IN, $buf, $EOLSCANBUFSIZE);
-if ($buflen > 0) {
- my $crlfpos;
- my $lfpos;
- my $crpos;
-
- $inputpos = 0;
-
- # TN 5002 "Encapsulated PostScript File Format Specification"
- # specifies a DOS EPS binary file format for including a
- # device-specific screen preview.
- #
- # DOS EPS Binary File Header (30 Bytes):
- # * Bytes 0-3: 0xC5D0D3C6
- # * Bytes 4-7: Offset of PostScript section
- # * Bytes 8-11: Length of PostScript section
- # * ...
- # * Bytes 28-29: XOR checksum of bytes 0-27 or 0xFFFF
- if ($buflen > 30 and $buf =~ /^\xC5\xD0\xD3\xC6/) {
- debug "DOS EPS binary file header found";
- my $header = substr($buf, 0, 30);
- my ($offset_ps, $length_ps, $checksum) = unpack("x[V]VVx[V4]n", $header);
- debug " PS offset: $offset_ps";
- debug " PS length: $length_ps";
- $maxpos = $offset_ps + $length_ps;
- # validate checksum
- if ($checksum == 0xFFFF) {
- debug " No checksum";
- }
- else {
- debug " checksum: $checksum";
- my $cs = 0;
- map { $cs ^= $_ } unpack('n14', $header);
- if ($cs != $checksum) {
- warning "Wrong checksum of DOS EPS binary header";
- }
- }
- # go to the start of the PostScript section and refill buffer
- if ($::opt_filter) {
- if ($offset_ps <= $buflen) {
- $buf = substr($buf, $offset_ps);
- $buflen = $buflen - $offset_ps;
- $inputpos = $offset_ps;
- my $len = read(IN, $buf, $offset_ps, $buflen);
- $buflen += $len;
- }
- else {
- $inputpos = $buflen;
- $buflen = 0;
- my $skip = $offset_ps - $inputpos;
- while ($skip > 0) {
- $buflen = read(IN, $buf,
- $skip > $EOLSCANBUFSIZE ? $EOLSCANBUFSIZE : $skip);
- $buflen > 0 or error "Unexpected end of input stream";
- $inputpos += $buflen;
- $skip = $offset_ps - $inputpos;
- }
- $buflen = read(IN, $buf, $EOLSCANBUFSIZE);
- $buflen > 0 or error "Unexpected end of input stream";
- }
- }
- else {
- seek(IN, $offset_ps, 0) || error "Cannot seek to PostScript section";
- $inputpos = $offset_ps;
- $buflen = read(IN, $buf, $EOLSCANBUFSIZE);
- $buflen > 0 or error "Reading PostScript section failed";
- }
- }
- elsif ($buf =~ s/^($UEL($PJL)+)//) {
- $inputpos = length($1);
- debug "PJL commands removed at start of file: $inputpos bytes";
- }
- else {
- # remove binary junk before header
- # if there is no header, we assume the file starts with ascii style and
- # we look for a eol style anyway, to prevent possible loading of the
- # entire file
- if ($buf =~ /%!/) {
- # throw away binary junk before %!
- $buf =~ s/(.*?)%!/%!/o;
- $inputpos = length($1);
- debug "Binary junk at start of file: $inputpos byte(s)";
- }
- }
-
- $lfpos = index($buf, "\n");
- $crpos = index($buf, "\r");
- $crlfpos = index($buf, "\r\n");
-
- if ($crpos > 0 and ($lfpos == -1 or $lfpos > $crpos+1)) {
- # The first eol was a cr and it was not immediately followed by a lf
- $/ = "\r";
- debug "The first eol character was a CR ($crpos) and not immediately followed by a LF ($lfpos)";
- }
-
- # Now we have set the correct eol-character. Get one more line and add
- # it to our buffer. This will make the buffer contain an entire line
- # at the end. Then split the buffer in an array. We will draw lines from
- # that array until it is empty, then move again back to <IN>
- $buf .= <IN> unless eof(IN);
- $buflen = length($buf);
-
- # In case of DOS EPS binary files respect end of PostScript section.
- if ($maxpos> 0 and $inputpos + $buflen > $maxpos) {
- $buflen = $maxpos - $inputpos;
- $buflen > 0 or error "Internal error";
- $buf = substr($buf, 0, $buflen);
- }
-
- # Some extra magic is needed here: if we set $/ to \r, Perl's re engine
- # still thinks eol is \n in regular expressions (not very nice) so we
- # cannot split on ^, but have to split on a look-behind for \r.
- if ($/ eq "\r") {
- @bufarray = split(/(?<=\r)/ms, $buf); # split after \r
- }
- else {
- @bufarray = split(/^/ms, $buf);
- }
-}
-
-### getline
-sub getline
-{
- if ($#bufarray >= 0) {
- $_ = shift(@bufarray);
- }
- elsif ($maxpos > 0 and $inputpos >= $maxpos) {
- $_ = undef;
- }
- else {
- $_ = <IN>;
- if ($maxpos > 0) {
- my $skip = $maxpos - $inputpos - length($_);
- if ($skip < 0) {
- $_ = substr($_, 0, $skip);
- }
- }
- }
- $inputpos += length($_) if defined $_;
- return defined($_);
-}
-
-### scan first line
-my $header = 0;
-getline();
-if (/%!/) {
- # throw away binary junk before %!
- s/(.*)%!/%!/o;
-}
-$header = 1 if /^%/;
-debug "Scanning header for BoundingBox";
-print $OUT $_;
-
-### variables and pattern for BoundingBox search
-my $bbxpatt = '[0-9eE\.\-]';
- # protect backslashes: "\\" gets '\'
-my $BBValues = "\\s*($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)";
-my $BBCorrected = 0;
-
-sub CorrectBoundingBox
-{
- my ($llx, $lly, $urx, $ury) = @_;
- debug "Old BoundingBox:", $llx, $lly, $urx, $ury;
- my ($width, $height) = ($urx - $llx, $ury - $lly);
- my ($xoffset, $yoffset) = (-$llx, -$lly);
- debug "New BoundingBox: 0 0", $width, $height;
- debug "Offset:", $xoffset, $yoffset;
-
- print $OUT "%%BoundingBox: 0 0 $width $height$/";
- print $OUT "<< /PageSize [$width $height] >> setpagedevice$/";
- print $OUT "gsave $xoffset $yoffset translate$/";
-}
-
-### emacs-page
-### scan header
-if ($header) {
- HEADER: while (getline()) {
- ### Fix for freehand bug ### by Peder Axensten
- next HEADER if(!/\S/);
-
- ### end of header
- if (!/^%/ or /^%%EndComments/) {
- print $OUT $_;
- last;
- }
-
- ### BoundingBox with values
- if (/^$BBName$BBValues/o) {
- CorrectBoundingBox $1, $2, $3, $4;
- $BBCorrected = 1;
- last;
- }
-
- ### BoundingBox with (atend)
- if (/^$BBName\s*\(atend\)/) {
- debug $BBName, "(atend)";
- if ($::opt_filter) {
- warning "Cannot look for BoundingBox in the trailer",
- "with option --filter";
- last;
- }
- my $pos = $inputpos;
- debug "Current file position:", $pos;
-
- # looking for %%BoundingBox
- while (getline()) {
- # skip over included documents
- my $nestDepth = 0;
- $nestDepth++ if /^%%BeginDocument/;
- $nestDepth-- if /^%%EndDocument/;
- if ($nestDepth == 0 && /^$BBName$BBValues/o) {
- CorrectBoundingBox $1, $2, $3, $4;
- $BBCorrected = 1;
- last;
- }
- }
-
- # go back
- seek(IN, $pos, 0) or error "Cannot go back to line \"$BBName (atend)\"";
- $inputpos = $pos;
- @bufarray = ();
- last;
- }
-
- # print header line
- print $OUT $_;
- }
-}
-
-### print rest of file
-while (getline()) {
- print $OUT $_;
-}
-
-### emacs-page
-### close files
-close(IN);
-print $OUT "$/grestore$/" if $BBCorrected;
-close($OUT);
-
-### actually run GS if we were writing to a temporary file
-if (defined $tmp_filename) {
- push @GS, $tmp_filename;
- push @GS, qw(-c quit);
- debug "Ghostscript command: @GS";
- system @GS;
-}
-
-# if ghostscript exited badly, we should too.
-if ($? & 127) {
- error(sprintf "Writing to $outname failed, signal %d\n", $? & 127);
-} elsif ($? != 0) {
- error(sprintf "Writing to $outname failed, error code %d\n", $? >> 8);
-}
-
-warning "BoundingBox not found" unless $BBCorrected;
-debug "Done.";
-
-# vim: ts=8 sw=2 expandtab:
diff --git a/Build/source/texk/texlive/linked_scripts/exceltex/exceltex b/Build/source/texk/texlive/linked_scripts/exceltex/exceltex
deleted file mode 100755
index 919a0918f65..00000000000
--- a/Build/source/texk/texlive/linked_scripts/exceltex/exceltex
+++ /dev/null
@@ -1,824 +0,0 @@
-#!/usr/bin/perl -w
-# $Id: exceltex 155 2006-04-30 11:25:16Z pez $
-#
-# helper script for the exceltex latex package. reads contents of
-# M$ Excel files using the Spreadsheet::ParseExcel perl module.
-#
-# (c) 2004-2006 by Hans-Peter Doerr <doerr@cip.physik.uni-freiburg.de>
-#
-# exceltex is free software. you can redistribute or modify it under
-# the terms of the GNU GENERAL PUBLIC LICENSE Version 2. See COPYING for
-# details.
-
-use strict;
-
-my $VERSION = "0.5.1";
-my $DEBUG = 0;
-
-# this is the default encoding for all files written by exceltex
-my $ENCODING = "latin1";
-
-# some lookup tables
-my %L2N;
-{ my $i = 1; for ('A' .. 'Z') { $L2N{$_} = $i; ++$i } }
-
-my @N2L;
-{ for ('A' .. 'Z') { push(@N2L, $_) } }
-
-
-#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-package util;
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub DEBUG
-{
- my ($msg) = @_;
-
- if ($DEBUG)
- {
- chomp($msg);
- print STDERR "DEBUG: $msg\n";
- }
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub cell2xy
-{
- my ($cell) = @_;
-
- $cell = uc($cell);
- return undef if (! ($cell =~ m/^([A-Z]+)([0-9]+)$/));
-
- # return (column, row)
- return (col2x($1), $2-1);
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub xy2cell
-{
- my ($x, $y) = @_;
-
- # is is likely to be slow as hell
- return undef if (! ($x =~ m/^[0-9]+$/g && $y =~ m/^[0-9]+$/g));
-
- ++$y;
- return x2col($x) . "$y";
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub col2x
-{
- my ($l) = @_;
-
- my $len = length($l);
- my @S = split //, $l;
-
- my $n = 0;
-
- if ($len == 1) { $n = $L2N{$l} - 1 }
- if ($len == 2) { $n = 26 * $L2N{$S[0]} + $L2N{$S[1]} - 1 }
-
- return $n;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub x2col
-{
- my ($n) = @_;
-
- return undef if (! $n =~ m/[0-9]+/);
- my $l;
- if ($n > 25) { $l = $N2L[int($n/26)-1] . $N2L[$n % 26] }
- else { $l = $N2L[$n] }
-
- return $l;
-}
-
-
-
-
-
-#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-package main;
-
-use strict;
-use Getopt::Long;
-use Encode;
-
-my $Workbooks = {}; # workbook cache
-my $nItems = 0; # number of processed items
-my $nCells = 0; # number of processed cells
-my $nTabs = 0; # number of processed tabs
-my $Warnings = 0; # number of warnings
-
-my $Jobname = ""; # jobname of .tex file
-my $inputDir = ""; # data goes here
-my $indexFile = "";
-
-
-my $optFormat = 1; # use formatting?
-my $optColor = 1; # use colors?
-my $optComma = 0; # use comma for decimals
-my $optFmtSci = 0; # reformat scientific numbers?
-my $ignWarn = 0; # ignore warnings?
-my $euroSymbol = "EUR"; # use this for the EUR currency symbol
-
-my $cleanup = 0; # cleanup inputDir
-
-my $EXTNS = "excltx";
-
-# read global and local config files
-# will be overwritten by commandline options
-readConfigFile("$ENV{HOME}/.exceltexrc") if (-f "$ENV{HOME}/.exceltexrc");
-readConfigFile(".exceltexrc") if (-f ".exceltexrc");
-
-# handle commandline switches
-GetOptions('format!' => \$optFormat,
- 'color!' => \$optColor,
- 'comma!' => \$optComma,
- 'reformat-sn!' => \$optFmtSci,
- 'p|plain' => sub{$optFormat=0; $optColor=0; $optFmtSci=0;},
- 'd|debug' => \$DEBUG,
- 'c|cleanup' => \$cleanup,
- 'e|encoding=s' => \$ENCODING,
- 'o|euro-symbol=s' => \$euroSymbol,
- 'h|help' => sub{ usage(); exit 0;},
- 'v|version' => sub{ print "exceltex, version $VERSION\n"; exit 0},
- 'w|ignore-warnings' => \$ignWarn,
- ) || exit 2;
-
-if (@ARGV == 0) {
- usage();
- exit 2;
-}
-
-
-
-# encoding of output files
-$ENCODING = lc($ENCODING);
-if (! ($ENCODING eq "latin1" ||
- $ENCODING eq "iso-8859-1" ||
- $ENCODING eq "latin9" ||
- $ENCODING eq "iso-8859-15" ||
- $ENCODING eq "utf8"))
-{
- print STDERR "Unsupported encoding: $ENCODING\n";
- print STDERR "currently supported: iso-8859-1 (latin1), iso-8859-15 "
- . "(latin9), utf8\n";
- exit_error();
-}
-
-print "exceltex helper script, version $VERSION\n";
-
-
-# get jobname from first argument
-if ($ARGV[0] =~ m/(\w+)\.tex/g) {
- $Jobname = $1;
-}
-else { $Jobname = $ARGV[0]; }
-
-if (! defined($Jobname))
-{
- print STDERR "can't determine jobname.\n";
- exit_error();
-}
-
-util::DEBUG("jobname is: $Jobname\n");
-
-
-# data from spreadsheet goes here
-$inputDir = $Jobname . '-' . $EXTNS;
-$indexFile = $Jobname . '.' . $EXTNS;
-
-# cleanup?
-if ($cleanup)
-{
- cleanup();
- exit 0;
-}
-
-if (! -f $indexFile)
-{
- print STDERR "can't read index '$indexFile: $!.\n";
- print STDERR "run latex first to create the index.\n";
- exit_error();
-}
-
-# create data dir
-if (! -d $inputDir)
-{
- if (! mkdir $inputDir)
- {
- print STDERR "can't create data directory '$inputDir': $!\n";
- exit_error();
- }
-}
-
-
-# rock'n'roll
-processIndex($indexFile);
-
-
-# exiting message
-if ($Warnings)
-{
- print STDERR "exceltex finished with $nItems items ($nCells cells "
- . "and $nTabs tabulars)\n";
- print STDERR "*** not all items proccessed fine, there were "
- . "$Warnings Warnings\n";
- exit 0 if ($ignWarn);
- exit 1;
-}
-else
-{
- print "exceltex successfully finished with $nItems items ($nCells cells "
- . "and $nTabs tabulars)\n";
-}
-
-exit 0;
-
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub exit_error
-{
- print STDERR "aborting.\n";
- exit 2;
-}
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub usage
-{
- print <<__EOF;
-exceltex version $VERSION
-usage: exceltex [options] file[.tex]
-options:
- -h|--help show this help
- -v|--version show program version and exit
- -c|--cleanup remove temporary files created by previous runs
- -w|--ignore-warnings exit with status zero, even on warnings
- -o|--euro-symbol=sym use sym for displaying the euro currency symbol [EUR]
- -e|--encoding=enc set encoding to enc. Currently supported
- encodings are: latin1, latin9, utf8 [latin1]
- --[no]reformat-sn (dont) reformat scientific numbers to A X 10^B notation
- --[no]comma (dont) use comma for decimal numbers
- --[no]format (dont) use formatting
- --[no]nocolor (dont) use colors
- -p|--plain shorthand for --noformat --nocolor --noreformat-sn
-__EOF
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub readConfigFile
-{
- my ($file) = @_;
-
- open(I, "<$file") || return;
- while(<I>)
- {
- chomp();
- my ($key, $val) = split('=', $_);
-
- if ($key eq "encoding") { $ENCODING = $val }
- elsif ($key eq "reformat-sn") { $optFmtSci = $val }
- elsif ($key eq "color") { $optColor = $val }
- elsif ($key eq "format") { $optFormat = $val }
- elsif ($key eq "comma") { $optComma = $val }
- elsif ($key eq "euro-symbol") { $euroSymbol = $val }
- elsif ($key eq "plain") { $optColor=0; $optFormat=0}
- else { print STDERR "unsupported config option in '$file': "
- . "$key, ignoring\n" }
- }
- close(I);
-}
-
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub cleanup
-{
- if (-f $indexFile)
- {
- print "removing $indexFile\n";
- unlink($indexFile);
- }
- return if (! defined($inputDir));
- return if (! -d $inputDir);
-
- print "cleaning up $inputDir/\n";
- unlink <$inputDir/c-*>;
- unlink <$inputDir/t-*>;
-}
-
-
-
-# read index file, extract data, write to files
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub processIndex
-{
- my ($index) = @_;
-
- if (! open(I, "< $index"))
- {
- print STDERR "can't read index '$index': $!. Run latex first?\n";
- exit_error();
- }
-
- my $cellrefs = 0;
- while(<I>)
- {
- chomp($_);
-
- # if cellrefs is switched on, we store data in files with name
- # inputDir/[c,t]-file!sheet!cell
- if ($. == 1 && $_ eq ";cellrefs")
- {
- print "using cell referencing by name\n";
- $cellrefs = 1;
- }
-
- # ignore lines beginning with ;
- next if ($_ =~ m/^;/);
-
- my $type;
- my $idx = undef;
- my $source;
- my @flags;
-
- if ($cellrefs == 1) {($type, $source, @flags) = split(':', $_)}
- else {($type, $idx, $source, @flags) = split(':', $_)}
-
- # parse flags
- # not used yet
- if (@flags != 0)
- {
- my $ok = 0;
- foreach (@flags)
- {
- $ok = 1 if ($_ eq 'plain');
- }
- print STDERR "Index '$indexFile' corrupt at line $.: bad flag\n";
- exit_error();
- }
-
- if (! defined($source))
- {
- print STDERR "Index '$indexFile' corrupt at line $.\n";
- exit_error();
- }
-
- my ($f, $s, $c1, $c2) = parseSource($source, $type);
- if (! $s)
- {
- print STDERR "Index '$indexFile' corrupt at line $.\n";
- exit_error();
- }
-
- my $string = "";
- if ($type eq 't')
- {
- $string = getTabString($f, $s, $c1, $c2);
- }
- elsif ($type eq 'c')
- {
- $string = getCellString($f, $s, $c1);
- }
- else
- {
- print STDERR "Index '$indexFile' corrupt at line $.: "
- . "unknown $type '$type'\n";
- exit_error();
- }
-
- # no need to write empty data
- next if (! defined($string));
-
- $string = decode_utf8($string, 0);
- $string = encode($ENCODING, $string, 0);
-
- if (! writeBuf($type, $idx, $string, $source))
- {
- print STDERR "can't write cell data: $!.\n";
- exit_error();
- }
- }
- close(I);
-
- return 1;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub getFile
-{
- my $file = $Jobname . ".xls";
- return $file if (-f $file);
- return undef;
-}
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub parseSource
-{
- my ($string, $type) = @_;
-
- my @tokens = split('!', $string);
-
- my $file;
- my $sheet;
- my $cel1;
- my $cel2;
-
- if ($type eq 'c')
- {
- if (@tokens == 2)
- {
- $file = getFile();
- $sheet = $tokens[0];
- $cel1 = $tokens[1];
- }
- elsif (@tokens == 3)
- {
- $file = $tokens[0];
- $sheet = $tokens[1];
- $cel1 = $tokens[2];
- }
- else { return undef; }
- }
- elsif ($type eq 't')
- {
- if (@tokens == 3)
- {
- $file = getFile();
- $sheet = $tokens[0];
- $cel1 = $tokens[1];
- $cel2 = $tokens[2];
- }
- elsif (@tokens == 4)
- {
- $file = $tokens[0];
- $sheet = $tokens[1];
- $cel1 = $tokens[2];
- $cel2 = $tokens[3];
- }
- else { return undef; }
- }
- else { return (undef, undef, undef, undef); }
-
- return ($file, $sheet, $cel1, $cel2);
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub writeBuf
-{
- my ($type, $idx, $string, $source) = @_;
- return 1 if ($string eq "");
-
- my $wfile;
-
- if (! defined($idx)) { $wfile = $inputDir . "/" . $type . "-" . $source }
- else { $wfile = $inputDir . "/" . $type . "-" . $idx }
-
- return 0 if (! open (O, ">$wfile"));
- return 0 if (! print O $string);
- return 0 if (! close(O));
- return 1;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub getWorkbook
-{
- my ($file) = @_;
-
- if (! -f $file) {
- print STDERR "can't read '$file': it does not exists.\n";
- exit_error();
- }
-
- if (! defined($Workbooks->{$file}))
- {
- my $type = "xls";
- if ($file =~ m/^\w+\.(\w+)$/g) { $type = $1 };
-
- if ($type eq "xls")
- {
- print("reading '$file'\n");
- # readExcel->new() will exit, if anything bad happens
- $Workbooks->{$file} = readExcel->new($file);
- }
- }
-
- return $Workbooks->{$file};
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub texifyCell
-{
- my ($cel) = @_;
-
- my $MATH = 0; # wether to enclose string in $$ for math mode
- my $string = $cel->{value};
-
- return "" if (! defined($string) || $string eq "");
-
- # escape latex control characters
- $string =~ s/\{/\\\{/g;
- $string =~ s/\}/\\\}/g;
- # escape backslash if not followed by { or }
- $string =~ s/\\(?!({|}))/\\ensuremath\{\\backslash\}/g;
- $string =~ s/#/\\#/g;
- $string =~ s/\$/\\\$/g;
- $string =~ s/%/\\%/g;
- $string =~ s/&/\\&/g;
- $string =~ s/~/\\~/g;
- $string =~ s/_/\\_/g;
- $string =~ s/\^/\{\\verb ^ \}/g;
-
- # FIXME: needs more testing!
- # hack for EUR sign, works for me but is definetly ugly :(
- # will need some information on how exactly this
- # user-entered formatting stuff works (in excel)
- $string =~ s/\[.+\xac-{0,1}\d{1,3}\]/$euroSymbol/g; # EUR in currency cells
- $string =~ s/\[.+EUR\]/$euroSymbol/g; # "
- $string =~ s/.{1,1}\xac/$euroSymbol/g; # single EUR sign
-
-
- # use decimal comma if requested
- $string =~ s/(\d)\.(\d)/$1,$2/g if ($optComma == 1);
-
- # reformat scientific numbers if requested
- if ($optFmtSci == 1)
- {
- $MATH = 1 if ($string =~ s/([0-9]+)[eE]([+-][0-9]+)/
- simplifyScientificNumber($1, $2)/ge);
- }
-
- # apply cell formatting and colors if not requested otherweise
- $string = applyFormatting($string, $cel, $MATH) if($optFormat == 1);
-
- # same goes for colors
- $string = applyColor($string, $cel) if ($optColor == 1);
-
- util::DEBUG " texified => '$string'";
-
- return "\$$string\$" if ($MATH);
- return $string;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub applyFormatting
-{
- my ($s, $c, $m) = @_;
-
- # font bold?
- if ($c->{bold} && $m) { $s = "\\mathbf{$s}"; }
- elsif ($c->{bold}) { $s = "\\textbf{$s}"; }
-
- # font italic?
- if ($c->{italic} && $m) { $s = "\\mathit{$s}"; }
- elsif ($c->{italic}) { $s = "\\textit{$s}"; }
-
- # underlined? striked out?
- $s = "\\uline{$s}" if ($c->{underline});
- $s = "\\sout{$s}" if ($c->{strikeout});
-
- return $s;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub applyColor
-{
- my ($s, $c) = @_;
-
- # only evaluate color if it is not black anyway
- if ($c->{color} != 8)
- {
- # convert rrggbb hex color triplet to float rgb
- $s = "\\textcolor[rgb]{" . colormap($c->{color}) . "}{$s}";
- }
-
- return $s;
-}
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub colormap
-{
- my ($color) = @_;
-
- util::DEBUG(" color => $color\n");
-
- # get rgb triplet as floats
- return join(', ', map {hex($_)/255.0}
- unpack('a2a2a2', Spreadsheet::ParseExcel->ColorIdxToRGB($color)));
-}
-
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub simplifyScientificNumber
-{
- my ($f, $e) = @_;
-
- # extract signum
- my $s = substr($e, 0, 1);
- $s = '' if ($s eq "+");
-
- # remove signum & trailing zeros
- $e =~ s/^[+-]*//;
- $e =~ s/^0*(\d+)/$1/;
-
- return $f if ($e == 0);
- return sprintf("%s \\times 10^{%s%s}", $f, $s, $e);
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub warning
-{
- my ($msg) = @_;
-
- chomp($msg);
- print STDERR "warning: " . $msg . "\n";
- ++$Warnings;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub getCellString
-{
- my ($file, $sheet, $cell) = @_;
-
- util::DEBUG("get $file -> $sheet -> $cell\n");
-
- my $w = getWorkbook($file);
- return undef if (! defined($w));
-
- my ($x, $y) = util::cell2xy($cell);
- if (! defined($x) || ! defined($y)) {
- warning("cell '$cell' is invalid\n");
- return undef;
- }
-
- my $c = $w->getCell($sheet, $x, $y);
- warning($w->error()) if (! defined($c->{value}));
-
- ++$nItems;
- ++$nCells;
- return texifyCell($c);
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub getTabString
-{
- my ($file, $sheet, $cell1, $cell2) = @_;
-
- # cell1 is upper-left and cell2 is lower-right corner
- # of the selected cell-range
- my ($lfx, $upy) = util::cell2xy($cell1);
- my ($rtx, $loy) = util::cell2xy($cell2);
-
- if (! defined($lfx))
- {
- warning "cell '$cell1' is invalid\n";
- return undef;
- }
- if (! defined($rtx))
- {
- warning "cell '$cell2' is invlaid\n";
- return undef;
- }
-
- my $book = getWorkbook($file);
- my $buf;
-
- my $empty = 1;
-
- for (my $y = $upy; $y <= $loy; ++$y)
- {
- for (my $x = $lfx; $x <= $rtx; ++$x)
- {
- my $c = $book->getCell($sheet, $x, $y);
-
- warning($book->error()) if (! defined($c));
- $empty = 0 if(defined($c->{value}));
- $buf .= texifyCell($c);
- $buf .= " & " if ($x < $rtx);
- }
- $buf .= " \\\\\n";
- }
-
- warning("table $cell1!$cell2 is empty\n") if ($empty);
-
- ++$nItems;
- ++$nTabs;
- return $buf;
-}
-
-
-
-
-
-#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-package readExcel;
-
-use strict;
-use Spreadsheet::ParseExcel;
-use Encode;
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub new
-{
- my ($class, $file) = @_;
-
- my $self = {};
- $self->{ERROR} = "";
-
- if (! -f $file)
- {
- print STDERR "can't read '$file', it does not exists.\n";
- exit_error();
- }
-
- $self->{book} =
- Spreadsheet::ParseExcel::Workbook->Parse($file);
-
- if (! defined($self->{book}))
- {
- print STDERR "SpreadSheet::ParseExcel Error: "
- . "can't parse '$file' : $!\n";
- exit_error();
- }
-
- $self->{file} = $file;
- bless $self, $class;
-
- return $self;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub getCell
-{
- my ($self, $sheet, $x, $y) = @_;
-
- my $ws = $self->{book}->Worksheet($sheet);
- if (! defined($ws))
- {
- $self->_setError("sheet '$sheet' does not exist");
- return undef;
- }
-
- my $cell = $ws->Cell($y, $x);
-
- if(! $cell)
- {
- $self->_setError("cell '$sheet!" . util::xy2cell($x, $y) . "' is emtpy "
- . "or out of range");
-
- return { value => undef }
- }
-
- # we're internally operating with utf8, for now
- my $value = encode_utf8($cell->Value());
- util::DEBUG " value => '$value'";
-
- # return hash containing value and formatting
- return { value => $value,
- bold => $cell->{Format}->{Font}->{Bold},
- italic => $cell->{Format}->{Font}->{Italic},
- color => $cell->{Format}->{Font}->{Color},
- underline => $cell->{Format}->{Font}->{Underline},
- strikeout => $cell->{Format}->{Font}->{Strikeout}
- };
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub _setError
-{
- my ($self, $err) = @_;
- $self->{ERROR} = $err;
-}
-
-
-#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-sub error
-{
- my $self = shift;
- my $err = $self->{ERROR};
- $self->{ERROR} = undef;
- return $err;
-}
diff --git a/Build/source/texk/texlive/linked_scripts/fig4latex/fig4latex b/Build/source/texk/texlive/linked_scripts/fig4latex/fig4latex
deleted file mode 100755
index cda79cb1569..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fig4latex/fig4latex
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/usr/bin/env perl
-
-# Copyright 2009 Joseph E. Fields
-# email: fieldsj1@southernct.edu
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-$version = "0.2";
-
-# Version 0.2
-# Changed hashbang to use the '/usr/bin/env perl' hack for portability
-# Added a check on the return status of open("> Makefile").
-#
-# Version 0.1
-# Original release.
-
-#default values of a few variables
-
-$mag_factor = 1.0;
-$pdflatex = 0;
-$figure_directory = "./";
-
-
-&parse_command_line;
-
-
-if ($figure_directory =~ m/\/$/) {
- $pref = $figure_directory;
-} else {
- $pref = $figure_directory . "/";
-}
-
-
-#Look for files ending with the .fig extension in the current directory.
-
-opendir(THISDIR, ".");
-@fig_files = grep(/\.fig$/, readdir(THISDIR));
-
-open(MAKEFILE, "> Makefile") || die "Can't open Makefile for write. \n"; ;
-
-#First we run through the list of .fig files to make a list of corresponding
-#.tex files these are used as the dependencies for the "all" target.
-
-@tex_files = ();
-@base_names = ();
-
-foreach $fig (@fig_files) {
- $tex_file_name = $fig;
- $base = $fig;
- $tex_file_name =~ s/\.fig$/\.tex/;
- $base =~ s/\.fig$//;
- push(@tex_files, $tex_file_name);
- push(@base_names, $base);
-}
-print MAKEFILE "\#\n\# fig4latex makefile\n\#\n\n";
-print MAKEFILE "all: @tex_files\n\n";
-
-#For each .fig file we need to add appropriate lines to the Makefile
-
-if ($pdflatex == 1){
- $ext = ".pdf";
-} else {
- $ext = ".eps";
-}
-
-foreach $nm (@base_names) {
- print MAKEFILE "\# translation into pstex\n\n";
- print MAKEFILE "$nm\.tex: $nm$ext \n";
- print MAKEFILE "\tfig2dev -L pstex_t -p $pref$nm$ext -m $mag_factor $nm\.fig > $nm\.tex\n\n";
- print MAKEFILE "$nm\.pdf: $nm\.eps \n";
- print MAKEFILE "\tepstopdf $nm\.eps\n\n";
- print MAKEFILE "$nm\.eps: $nm\.fig \n";
- print MAKEFILE "\tfig2dev -L pstex -m $mag_factor $nm\.fig > $nm\.eps\n\n";
- print MAKEFILE "clean::\n";
- print MAKEFILE "\trm -f $nm\.tex $nm\.eps $nm\.pdf\n\n\n";
-}
-
-close(MAKEFILE);
-
-print "\nNow run \'make\' to update your graphics files.\n\n";
-print "If you are changing from PdfLaTeX (-p) to LaTeX (-l), or vice versa, \n";
-print "run \'make clean\' then \'make\'.\n\n";
-
-sub parse_command_line{
- while ($ARGV[0] =~ /^-/) {
- $_ = shift @ARGV; # in a subroutine
- if (/^-m$/) {
- $mag_factor = shift @ARGV;
- if ( ! ($mag_factor > 0.0) ) {
- print "\nThe next thing after the -m option is supposed to be a number\n";
- die("Bad arg for -m (magnification factor): $mag_factor\n\n");
- }
- }
- elsif (/^-p$/) {
- $pdflatex = 1;
- }
- elsif (/^-l$/) {
- $pdflatex = 0;
- }
- elsif (/^-d$/) {
- $figure_directory = shift @ARGV;
- if (! (-d "../".$figure_directory)) {
- print "\nArgument after -d must be the name of the directory\n";
- print "containing the figures, which you should currently be in!\n\n";
- die;
- }
- if ($figure_directory eq "") {
- print "\nPlease specify a path to the figures (relative to the\n";
- print " LaTeX source files). \n\n";
- die;
- }
- }
- elsif (/^-h$/ || /^--help$/) {
- &usage && die;
- }
- elsif (/^--version$/) {
- print "\nThis is Fig4latex, version $version.\n\n";
- die;
- }
- else {
- &usage && die;
- }
- }
-}
-
-sub usage{
- print <<"MULTILINE";
-
-Usage: fig4latex [-d dir] [-m NUM] [-p] [-l] [-h]
-
- -d DIR Directory containing the figures (a path relative to
- the directory where your LaTeX source files are).
- -m NUM Magnification factor.
- -p Pdflatex -- create makefile for use with pdflatex -- the images
- get converted to pdf format.
- -l Latex -- create makefile for use with (regular) latex -- the images
- are exported as eps format. (this is the default)
- -h Help -- print this message and quit.
-
-This program creates a Makefile. Running 'make' will then search the
-current director for .fig files and use fig2dev (pstex and pstex_t) to
-create .tex files which are \input into your latex file to include the
-graphic. Any text in the figure with the 'special' flag set is processed
-by LaTeX.
-MULTILINE
-}
-
diff --git a/Build/source/texk/texlive/linked_scripts/findhyph/findhyph b/Build/source/texk/texlive/linked_scripts/findhyph/findhyph
deleted file mode 100755
index b4a42ba35d3..00000000000
--- a/Build/source/texk/texlive/linked_scripts/findhyph/findhyph
+++ /dev/null
@@ -1,422 +0,0 @@
-#!/usr/bin/perl
-
-use warnings;
-use Getopt::Std;
-$opt_l = 'kKsSvVzZoOuUiIA'; # defaults for Slovak and Czech
-$opt_c = $opt_f = $opt_h = $opt_v = 0;
-getopts('cfphvl:');
-
-$version_msg = "findhyph version 3.4\n";
-$help_msg = "\nUsage: findhyph [options] <yourtexfile.log>\n" .
- "\n" .
- "Options: -c display hyphenated words in context\n" .
- " -f display font selectors\n" .
- " -h display this help message\n" .
- " -v display version\n" .
- " -p generate file with prepositions left at the end of line\n" .
- " -l=STRING use prepositions/conjunctions listed in STRING\n";
-
-print ($version_msg) if $opt_v;
-die ($help_msg) if $opt_h || !$ARGV[0];
-$filename = $ARGV[0];
-if ($filename =~ /\.(log|tex|dvi|ps|pdf)$/) {
- $filename = $`;
-}
-open(IN, "$filename.log") or die ("Can't read $filename.log: $!\n");
-open(O1, ">$filename.hyph") or die ("Can't write $filename.hyph: $!\n");
-if ($opt_p) {
- open(O2, ">$filename.prep") or die ("Can't write $filename.prep: $!\n");
-}
-
-$search = 0;
-$pageno_allowed = 0;
-$write_hyph_page = 0;
-$write_prep_page = 0;
-$act_text = "";
-$looseness = 0;
-
-while(<IN>) {
- s/[\r\n]*$//;
- if (/^\@looseness=(\-?\d+)$/) {
- $looseness = $1;
- }
- if (/^\@firstpass$/) {
- $pageno_allowed = 0;
- $endgraf = 0;
- $demerits = 1e10;
- $search = 1;
- $search_hyphens = 0;
- $act_break = 0;
- $act_text = "";
- @USED = ();
- %BREAKS = ();
- %LOOSE = ();
- next;
- }
- if (/^\@secondpass$/) {
- $search_hyphens = 1;
- $act_break = 0;
- $act_text = "";
- @USED = ();
- %BREAKS = ();
- %LOOSE = ();
- next;
- }
- if (/^\@emergencypass$/) {
- $act_break = 0;
- $act_text = "";
- @USED = ();
- %BREAKS = ();
- %LOOSE = ();
- next;
- }
- if ($search && /^@@(\d+): line (\d+)\..+ t=(\-?\d+) (?:s=\S+ (?:g|a)=\S+ )?\-\> @@(\d+)/) {
- $act_break = $1;
- $BREAKS{$act_break}{'prev'} = $4;
- if ($endgraf && $3 < $demerits) {
- $max_break = $1;
- $max_line = $2;
- $demerits = $3;
- }
- if ($endgraf && $looseness != 0) {
- $LOOSE{$1}{"line"} = $2;
- $LOOSE{$1}{"demerits"} = $3;
- }
- $act_text .= "\@$act_break\@";
- next;
- }
- if ($search && /^@\\par via @@/) {
- $endgraf = 1;
- next;
- }
- if ($search && /^@\\discretionary via @@/) {
- $search_hyphens = 1; # @firstpass may contain words hyphenated by user
- next; # using \discretionary
- }
- if ($search && /^@/) {
- next;
- }
- if ($search && $endgraf && $_ eq "") {
- $pageno_allowed = 1;
- do_hyph();
- $search = 0;
- $looseness = 0;
- next;
- }
- if ($search) {
- $act_text .= $_;
- } else {
- if ($pageno_allowed && /\[(\-?\d+)(\.\-?\d+){0,9} ?(\]|\{|\<|$)/) { # page number
- $pageno = $1;
- $pageno_allowed = 0;
- if ($write_hyph_page) {
- print O1 "[$pageno]\n\n";
- $write_hyph_page = 0;
- }
- if ($write_prep_page) {
- print O2 "[$pageno]\n\n";
- $write_prep_page = 0;
- }
- }
- }
-}
-
-close(O1);
-close(O2) if $opt_p;
-
-sub do_hyph {
- if ($looseness != 0) {
- $diff_line = 1e10;
- $diff_demer = 1e10;
- for $i (keys %LOOSE) {
- if (abs($LOOSE{$i}{"line"} - $max_line - $looseness) < $diff_line) {
- $diff_line = abs($LOOSE{$i}{"line"} - $max_line - $looseness);
- $diff_demer = $LOOSE{$i}{"demerits"};
- $max_break = $i;
- }
- if (abs($LOOSE{$i}{"line"} - $max_line - $looseness) == $diff_line &&
- $LOOSE{$i}{"demerits"} < $diff_demer) {
- $diff_demer = $LOOSE{$i}{"demerits"};
- $max_break = $i;
- }
- }
- }
- $br = $max_break;
- while (1) {
- $br = $BREAKS{$br}{'prev'};
- last if ($br == 0);
- $USED[$br] = 1;
- }
-
- for $i (1..$max_break-1) {
- if (not defined $USED[$i]) {
- $act_text =~ s/\@$i\@//;
- };
- }
-
- if ($opt_f) {
- $act_text =~ s/(\\\S+)\s+/$1\_/g;
- } else {
- $act_text =~ s/\\\S+\s+//g; # usually font selector, but also backslash in the text
- }
-
- for $i (1..$max_break-1) {
- if (defined $USED[$i]) {
- if ($search_hyphens) { # hyphenated words
- if ($act_text =~ /(\S+)(\@$i\@)(\S+)/) { # only hyphenated words match
- $out_pre = $1;
- $out_post = $3;
- if (substr($out_pre,-1) ne "-") { # hyphenated ligatures
- $out_pre_A = substr($out_pre,0,rindex($out_pre,"-"));
- $out_pre_B = substr($out_pre,rindex($out_pre,"-")+1);
- $out_pre = $out_pre_A;
- $out_post = $out_pre_B.$out_post;
- }
- if ($opt_c) {
- if ($act_text =~ /(\S+)\s+\S+\@$i\@/) {$out_pre = "$1 $out_pre";}
- if ($act_text =~ /\@$i\@\S+\s+(\S+)/) {$out_post = "$out_post $1";}
- }
- $out_pre =~ s/-//g;
- $out_post =~ s/-//g;
- $out_text = "$out_pre-$out_post";
- $out_text =~ s/\@\d+\@//g; # very narrow columns
- print O1 "$out_text\n";
- $write_hyph_page = 1;
- }
- }
- if ($opt_p) { # prepositions
- if ($act_text =~ / (\S) \@$i\@/) {
- $out_text = $1;
- if ($out_text =~ /^[$opt_l]$/) {
- if ($opt_c) {
- if($act_text =~ /(\S+) \S \@$i\@/) {$out_text = "$1 $out_text";}
- if($act_text =~ /\@$i\@ ?(\S+)/) {$out_text = "$out_text $1";}
- $out_text =~ s/-//g;
- $out_text =~ s/\@\d+\@//g; # very narrow columns
- }
- print O2 "$out_text\n";
- $write_prep_page = 1;
- }
- }
- }
- }
- }
-}
-
-__END__
-
-=encoding utf8
-
-=head1 NAME
-
-B<findhyph> – find words hyphenated by TeX in a document
-
-=head1 INSTALLATION
-
-Copy B<findhyph> or B<findhyph.bat> (depending on OS used) to a directory
-included in system PATH. Perl interpreter is required to be in
-C</usr/bin/> for Unix-like systems or in PATH when using B<findhyph.bat>.
-
-=head1 SYNOPSIS
-
-B<findhyph [options]> F<foo.log>
-
-
-=head1 DESCRIPTION
-
-To use this program:
-
-=over 4
-
-=item 1)
-
-set C<\tracingparagraphs=1> in a TeX document F<foo.tex> and run:
-
-=item 2)
-
-B<tex> F<foo.tex>
-
-=item 3)
-
-B<findhyph [options]> F<foo.log>
-
-=back
-
-If you are setting C<\looseness=E<lt>NE<gt>> to optimize paragraphs,
-you need to pass that information to the file F<foo.log> in a form
-C<@looseness=E<lt>NE<gt>> (on a separate line). You can use a macro like
-C<\def\setlooseness#1{\looseness=#1 \immediate\write-1{@looseness=#1}}>
-for this purpose. If the paragraph contains material in display math mode,
-you need to use the macro in all split parts of the paragraph.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-c>
-
-display hyphenated words in context
-
-=item B<-f>
-
-display font selectors and other strings starting with a backslash character
-
-=item B<-v>
-
-display program version
-
-=item B<-p>
-
-generate file containing information about one-letter prepositions and
-conjunctions left at the end of line
-
-=item B<-l=STRING>
-
-use prepositions/conjunctions listed in STRING instead of default list of
-prepositions and conjunctions C<kKsSvVzZoOuUiIA> used for Slovak and Czech
-language
-
-=back
-
-=head1 OUTPUT FILES
-
-=over 4
-
-=item F<foo.hyph>
-
-List of hyphenated words. All punctuation characters, parentheses and
-other character immediately preceding or following displayed words are included
-in this list. TeX constructs which are too difficult to display (C<\hbox{}>,
-C<\mark{}> etc.) are shown as C<[]>. Math mode is indicated by C<$> sign.
-
-Page numbers in square brackets refer to LOG file and may occasionally differ
-from the typeset document. The reason is that TeX may need to break more
-paragraphs than it would eventually fit on the page in order to find a page
-break.
-
-Words hyphenated in footnotes are listed before the words hyphenated in the
-paragraph in which the footnote is referenced.
-
-=item F<foo.prep>
-
-List of prepositions if option B<-p> is used.
-
-=back
-
-=head1 HISTORY
-
-=head4 1.0 (2001-04-08)
-
-=over 4
-
-=item *
-
-public release
-
-=back
-
-=head4 2.0 (2009-08-10)
-
-=over 4
-
-=item *
-
-fixes in line breaks detection algorithm; support for the third pass of line
-breaking algorithm in TeX (positive C<\emergencystretch>); support for
-discretionary breaks in the first pass
-
-=item *
-
-page number detection improved (recognized negative page numbers, compound page
-numbers when C<\count1> to C<\count9> registers are non-zero
-and C<[nn{mapfile}]>, C<[nnE<lt>pictureE<gt>]> and C<[nnE<lt>newlineE<gt>>
-formats used by pdfTeX; false page number detection should be much more rare)
-
-=item *
-
-configurable list of prepositions and conjunctions
-
-=item *
-
-hyphenated words can be displayed in context
-
-=item *
-
-suggestions and testing by Pavel Stříž
-
-=back
-
-=head4 3.0 (2012-02-01)
-
-=over 4
-
-=item *
-
-fixed a bug when total paragraph demerits are negative
-
-=item *
-
-C<\looseness> setting is now taken into account (thanks to Karel Horák
-for identifying the issue)
-
-=back
-
-=head4 3.1 (2012-11-03)
-
-=over 4
-
-=item *
-
-fixed displaying of hyphenated ligatures (bug reported by Karel Horák)
-
-=back
-
-=head4 3.2 (2012-11-21)
-
-=over 4
-
-=item *
-
-improved example definition of the C<\setlooseness> macro
-(thanks to Karl Berry)
-
-=back
-
-=head4 3.3 (2013-06-18)
-
-=over 4
-
-=item *
-
-fixed the manual page as suggested by Eric S. Raymond
-
-=back
-
-=head4 3.4 (2015-10-18)
-
-=over 4
-
-=item *
-
-fixed processing of logs produced using ε-TeX's C<\lastlinefit> option
-(bug reported by Karel Horák)
-
-=item *
-
-fixed cross-platform handling of linebreaks in the input file
-
-=back
-
-=head1 LICENSE
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-any later version.
-
-=head1 AUTHOR
-
-Copyright (c) Martin Budaj E<lt>m.b@speleo.skE<gt> 2000, 2001, 2009, 2012,
-2015
-
-=cut
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/afm2afm b/Build/source/texk/texlive/linked_scripts/fontools/afm2afm
deleted file mode 100755
index e5ace31b1c0..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fontools/afm2afm
+++ /dev/null
@@ -1,500 +0,0 @@
-#! /usr/bin/env perl
-
-=begin COPYRIGHT
-
-----------------------------------------------------------------------------
-
- Copyright (C) 2005-2020 Marc Penninga.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation, either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to
- Free Software Foundation, Inc.,
- 59 Temple Place,
- Suite 330,
- Boston, MA 02111-1307,
- USA
-
-----------------------------------------------------------------------------
-
-=end COPYRIGHT
-
-=cut
-
-use strict;
-use warnings;
-
-use File::Basename;
-use Getopt::Long;
-use Pod::Usage;
-
-my $VERSION = "20201218";
-
-parse_commandline();
-
-my $afm = read_afm($ARGV[0]);
-$afm->{kernpairs} = read_kpx($ARGV{kpx}, $afm->{kernpairs}) if $ARGV{kpx};
-
-if ($ARGV{output}) {
- $ARGV{output} .= '.afm' unless $ARGV{output} =~ m/[.]afm\z/xms;
- open my $output, '>', $ARGV{output}
- or die "[ERROR] can't open '$ARGV{output}': $!";
- select $output;
-}
-
-# If user specified encoding, use that; else, use encoding from .afm file
-my $enc = $ARGV{encoding} ? read_enc($ARGV{encoding})
- : get_enc($afm)
- ;
-# Make lookup table to quickly see if a character is present in the encoding
-my %char_in_enc = map { ($_ => 1) } @{$enc->{vector}};
-
-print_fontinfo($afm->{fontinfo}, $enc->{scheme});
-print_charmetrics($afm->{metrics}, $enc->{vector});
-print_kerndata($afm->{kernpairs}, $afm->{trackkerns}, \%char_in_enc);
-print_composites($afm->{composites}, \%char_in_enc);
-print "EndFontMetrics\n";
-
-close select *STDOUT if $ARGV{output};
-
-print_mapentry($afm->{fontinfo}, , $enc->{scheme})
- if $ARGV{encoding} && $ARGV{output};
-
-#-----------------------------------------------------------------------
-# Read the command-line options
-#-----------------------------------------------------------------------
-sub parse_commandline {
- Getopt::Long::GetOptions(
- 'help|?' => sub { pod2usage(-verbose => 1) },
- 'version' => sub { print "$VERSION\n"; exit },
- 'encoding=s' => \$ARGV{encoding},
- 'kpx=s' => \$ARGV{kpx},
- 'output=s' => \$ARGV{output},
- )
- or pod2usage(-verbose => 0);
-
- pod2usage(-verbose => 0) if @ARGV != 1;
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Read the input afm file
-#-----------------------------------------------------------------------
-sub read_afm {
- my $filename = shift;
- open my $afmfile, '<', $filename
- or die "[ERROR] can't open '$filename': $!";
-
- my %afm = (
- fontinfo => [],
- metrics => [],
- kernpairs => [],
- trackkerns => [],
- composites => [],
- );
-
- until ((my $line = <$afmfile>) =~ m/StartCharMetrics/xms) {
- push @{$afm{fontinfo}}, $line;
- }
-
- for (<$afmfile>) {
- if (m/\A\s* C \s/xms) { push @{$afm{metrics}}, $_; next }
- if (m/\A\s* KPX \s/xms) { push @{$afm{kernpairs}}, $_; next }
- if (m/\A\s* TrackKern \s/xms) { push @{$afm{trackkerns}}, $_; next }
- if (m/\A\s* CC \s/xms) { push @{$afm{composites}}, $_; next }
- }
-
- close $afmfile;
-
- return \%afm;
-}
-
-#-----------------------------------------------------------------------
-# Read additional kerning pairs from the kpx file
-#-----------------------------------------------------------------------
-sub read_kpx {
- my ($filename, $kpx) = @_;
- open my $kpxfile, '<', $filename
- or die "[ERROR] can't open '$filename': $!";
-
- my %seen = map { ($_ => 1) } @$kpx;
- for (<$kpxfile>) {
- if (m/\A\s* KPX \s/xms) { push @$kpx, $_ unless $seen{$_}++ }
- }
-
- close $kpxfile;
-
- return $kpx;
-}
-
-#-----------------------------------------------------------------------
-# Get encoding name and vector from the specified .enc file
-#-----------------------------------------------------------------------
-sub read_enc {
- my $filename = shift;
-
- open my $encfile, '<', $filename
- or die "[ERROR] can't open '$filename': $!";
- my $data = join ' ', map { s/%.+|\n//xmsg; $_ } <$encfile>;
- close $encfile;
-
- my ($scheme, $encoding)
- = $data =~ m{ /([-\w]+) \s* [[] (.+) []] \s* def }xms
- or die "[ERROR] parsing encoding file '$filename' failed";
-
- return { scheme => $scheme,
- vector => [ $encoding =~ m{ /([.\w]+) }xmsg ],
- };
-}
-
-#-----------------------------------------------------------------------
-# Get encoding from the input .afm file
-#-----------------------------------------------------------------------
-sub get_enc {
- my $afm = shift;
-
- my %enc = ( scheme => 'FontSpecific', vector => [ ('/.undef') x 256 ] );
-
- for my $line (@{$afm->{fontinfo}}) {
- if ($line =~ m/EncodingScheme \s+ ([-\w]+)/xms) {
- $enc{scheme} = $1;
- last;
- }
- }
- for my $line (@{$afm->{metrics}}) {
- my ($pos, $name)
- = $line =~ m/C \s+ ([-]?\d+) .+? N \s+ ([.\w]+)/xms
- or die;
- $enc{vector}[$pos] = $name unless $pos == -1;
- }
-
- return \%enc;
-}
-
-#-----------------------------------------------------------------------
-# Print the 'fontinfo' part of the output afm file
-#-----------------------------------------------------------------------
-sub print_fontinfo {
- my ($fontinfo, $scheme) = @_;
-
- for my $line (@$fontinfo) {
- $line = "EncodingScheme $scheme\n"
- if $line =~ m/EncodingScheme/xms;
- print $line;
- }
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Print character metrics for characters in specified encoding
-#-----------------------------------------------------------------------
-sub print_charmetrics {
- my ($metrics, $vector) = @_;
-
- my %metrics = map { m/(WX .+? N \s+ ([.\w]+) .+)/xms; ($2 => $1) }
- @$metrics;
-
- print "StartCharMetrics @{[ scalar grep { $metrics{$_} } @$vector ]}\n";
- for my $i (0 .. 255) {
- next unless $metrics{$vector->[$i]};
- print "C $i ; $metrics{$vector->[$i]}";
- }
- print "EndCharMetrics\n";
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Print kerning data for characters in specified encoding
-#-----------------------------------------------------------------------
-sub print_kerndata {
- my ($kernpairs, $trackkerns, $char_in_enc) = @_;
-
- my @kernpairs = grep { m/\A\s* KPX \s+ ([.\w]+) \s+ ([.\w]+)/xms
- and $char_in_enc->{$1}
- and $char_in_enc->{$2}
- }
- @$kernpairs;
-
- if (@kernpairs || @$trackkerns) {
- print "StartKernData\n";
- if (@kernpairs) {
- print "StartKernPairs @{[ scalar @kernpairs ]}\n";
- print @kernpairs;
- print "EndKernPairs\n";
- }
- if (@$trackkerns) {
- print "StartTrackKern @{[ scalar @$trackkerns ]}\n";
- print @$trackkerns;
- print "EndTrackKern\n";
- }
- print "EndKernData\n";
- }
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Print "composite" info for characters in specified encoding
-#-----------------------------------------------------------------------
-sub print_composites {
- my ($composites, $char_in_enc) = @_;
-
- # Each line mentions several characters: the composite and two or more
- # 'base' characters. We only print the line if all characters are
- # present in the specified encoding
- my @composites;
- COMPOSITE:
- for my $composite (@$composites) {
- my @chars = $composite =~ m/(?:CC \s+ ([.\w]+))/xmsg;
- for my $char (@chars) {
- next COMPOSITE unless $char_in_enc->{$char};
- }
- push @composites, $composite;
- }
-
- if (@composites) {
- print "StartComposites @{[ scalar @composites ]}\n";
- print @composites;
- print "EndComposites\n";
- }
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Print a mapfile entry for this re-encoded font
-#-----------------------------------------------------------------------
-sub print_mapentry {
- my ($fontinfo, $scheme) = @_;
-
- my $fontname = '';
- (my $fontfile = basename($ARGV[0] // '')) =~ s/[.]afm\z//xms;
- (my $output = basename($ARGV{output} // '')) =~ s/[.]afm\z//xms;
-
- for my $line (@$fontinfo) {
- if ($line =~ m/FontName \s+ ([-\w]+)/xms) {
- $fontname = $1;
- last;
- }
- }
-
- print {*STDOUT} qq(${output} ${fontname} <${fontfile}.pfb ),
- qq(<[$ARGV{encoding} "${scheme} ReEncodeFont"\n);
-
- return;
-
-}
-
-__END__
-
-
-############################################################################
-
- To create the documentation:
-
- pod2man --center="Marc Penninga" --release="fontools" --section=1 \
- afm2afm - | groff -Tps -man - | ps2pdf - afm2afm.pdf
-
-=pod
-
-=head1 NAME
-
-afm2afm - reencode an F<afm> file
-
-=head1 SYNOPSIS
-
-=over 8
-
-=item B<afm2afm>
-
-[B<-help>]
-[B<-version>]
-[B<-encoding>=I<< <encodingfile> >>]
-[B<-kpx>=I<< <kpxfile> >>]
-[B<-output>=I<< <outputfile> >>]
-B<< <afmfile> >>
-
-=back
-
-
-=head1 DESCRIPTION
-
-B<afm2afm> re-encodes an F<afm> file.
-
-Metrics (including kerning data) for characters not present in the
-chosen encoding are excluded from the output, which resuls in
-(potentially much) smaller files.
-
-Additional kerning pairs can be added to the output file.
-If you don't specify an encoding file,
-the F<afm> file isn't re-encoded;
-however, all unused (unencoded) data is still pruned.
-
-The program also generates an entry for a F<dvips>-style map file,
-but only if the F<afm> file has been re-encoded and
-the output was written to file
-(i.e., if both the I<-encoding> and I<-output> options were specified).
-
-
-=head1 OPTIONS AND ARGUMENTS
-
-=over 4
-
-=item B<-help>
-
-Print a short description of the syntax
-
-=item B<-version>
-
-Print version number and exit
-
-=item B<-encoding>=I<< <encodingfile> >>
-
-Re-encode to the enconding in I<< <encodingfile> >>
-
-=item B<-kpx>=I<< <kpxfile> >>
-
-Read additional kerning pairs from I<< <kpxfile> >> and add these to the output.
-This option cannot be used to override values from the input F<afm> file,
-since B<afm2afm> will write both old and new values to the output!
-
-The I<< <kpxfile> >> should contain kerning data in standard F<afm> format,
-i.e. for each kerning pair there should be a line
-
- KPX <left_glyph> <right_glyph> <amount>
-
-All other lines in the I<< <kpxfile> >> are ignored.
-
-=item B<-output>=I<< <outputfile> >>
-
-Write the result to I<< <outputfile> >> instead of C<stdout>.
-
-=item B<< <afmfile> >>
-
-The F<afm> file to be re-encoded.
-
-=back
-
-You may use either one or two dashes before options,
-and option names may be shortened to a unique prefix.
-
-
-=head1 AUTHOR
-
-Marc Penninga <marcpenninga@gmail.com>
-
-
-=head1 COPYRIGHT
-
-Copyright (C) 2005-2020 Marc Penninga.
-
-
-=head1 LICENSE
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published
-by the Free Software Foundation, either version 2 of the License,
-or (at your option) any later version.
-A copy of the GNU General Public License is included with B<afm2afm>;
-see the file F<GPLv2.txt>.
-
-
-=head1 DISCLAIMER
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
-
-
-=head1 VERSION
-
-This document describes B<afm2afm> version 20201218.
-
-
-=head1 RECENT CHANGES
-
-(See the source code for the rest of the story.)
-
-=over 12
-
-=item I<2019-05-20>
-
-Added the I<-version> option.
-
-=back
-
-
-=begin Really_old_history
-
-=over 12
-
-=item I<2013-08-07>
-
-Added the I<-kpx> command-line option.
-Replaced all C<given/when> constructions in the source code by C<if>'s,
-to avoid warnings about experimental features in Perl 5.18 and later.
-
-=item I<2012-02-01>
-
-Refactored the code; added the "no re-encoding, only pruning"
-functionality.
-
-=item I<2005-01-10>
-
-First version
-
-=item I<2005-01-25>
-
-Added printing of mapfile entry
-
-=item I<2005-02-18>
-
-Rewrote some of the code
-
-=item I<2005-03-08>
-
-Input files searched via B<kpsewhich> (where available)
-
-=item I<2005-03-15>
-
-Input files searched using B<kpsewhich> or B<findtexmf> (if available)
-
-=item I<2005-04-15>
-
-Updated creation of mapfile entry; look for font file to deduce the correct
-font file format (pfb, pfa, ttf). If no font file is found,
-pfb is assumed.
-
-=item I<2005-04-20>
-
-Program quits if the specified output file exists
-
-=item I<2005-04-29>
-
-Improved the documentation
-
-=item I<2005-07-29>
-
-Some updates to the documentation
-
-=item I<2006-01-12>
-
-A few minor changes to the code
-
-=back
-
-=cut
-
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/autoinst b/Build/source/texk/texlive/linked_scripts/fontools/autoinst
deleted file mode 100755
index 79eb1e13024..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fontools/autoinst
+++ /dev/null
@@ -1,4510 +0,0 @@
-#! /usr/bin/env perl
-
-=begin COPYRIGHT
-
-----------------------------------------------------------------------------
-
- Copyright (C) 2005-2020 Marc Penninga.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation, either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to
- Free Software Foundation, Inc.,
- 59 Temple Place,
- Suite 330,
- Boston, MA 02111-1307,
- USA
-
-----------------------------------------------------------------------------
-
-=end COPYRIGHT
-
-=cut
-
-use strict;
-use warnings;
-
-use Cwd ();
-use File::Path ();
-use File::Spec ();
-use Getopt::Long ();
-use Pod::Usage ();
-use POSIX ();
-
-my $VERSION = '20201218';
-
-my ($d, $m, $y) = (localtime time)[3 .. 5];
-my $TODAY = sprintf "%04d/%02d/%02d", $y + 1900, $m + 1, $d;
-
-my $RUNNING_AS_MAIN = (__PACKAGE__ eq 'main');
-
-
-=begin Comment
-
-----------------------------------------------------------------------------
-
- Autoinst consists of a number of parts:
-
- main Contains just the main() routine.
-
- Options Parses the command-line options.
- Note that the *processing* of the user's choices
- is mostly taken care of by the `Tables` package,
- since this processing involves adapting those tables.
-
- Log Logs the font parsing and creation process.
-
- Attr Contains tables and routines that represent
- font attributes (weight, width, shape).
-
- Font Parses an OpenType font's metadata.
-
- Tables Contains tables that drive the font creation process
- (especially the decisions which fonts to create).
-
- Work Generates all font files, driven by data from `Tables`.
-
- LaTeX Creates LaTeX support (.sty and .fd files).
-
- Otftotfm Drives `otftotfm` to actually generate the fonts.
-
- Util Some miscellaneous utility functions.
-
-----------------------------------------------------------------------------
-
-=end Comment
-
-=cut
-
-
-sub main {
- print "autoinst, version $VERSION\n";
-
- Options::parse_options();
- Tables::process_options();
-
- my %fontfamily;
- for my $fontfile (@ARGV) {
- my $font = Font::parse($fontfile);
- my $family = $font->{family};
- push @{$fontfamily{$family}}, $font;
- }
-
- while (my ($family, $fontlist) = each %fontfamily) {
-
- local %ARGV = %ARGV;
- Tables::process_family_dependent_options($fontlist);
-
- my $log = Log->new($ARGV{logfile});
- $log->log_options();
- $log->log_parsing($fontlist);
-
- # We defer asserting that all fonts were parsed in a unique way
- # until after the results of the parsing have been logged.
- Font::assert_unique($log, $fontlist);
-
- my $mappings = Attr::map_nfss_codes($fontlist);
- my ($from_nfss, $to_nfss) = @{$mappings};
- $log->log_nfss_mapping($from_nfss);
-
- my @workitems = Work::generate_worklist($fontlist);
- $log->log_worklist(\@workitems);
-
- my $targetdirs = Otftotfm::get_targetdirs($family, $fontlist);
- my @commands = map { Otftotfm::create_command($_, $targetdirs) }
- @workitems;
- $log->log_commands(\@commands) if $ARGV{verbose} >= 1;
-
- if (!$ARGV{dryrun}) {
- LaTeX::create_support_files(\@workitems, $family, $to_nfss);
- Otftotfm::run_commands(\@commands, $family, $log);
-
- if ($ARGV{t1suffix}) {
- Work::modify_fontnames($family, $fontlist);
- }
-
- print <<"END_MESSAGE_UPDMAP";
-[INFO] Done generating fonts!
- Please update TeX's databases (by calling 'texhash' and 'updmap'
- or their equivalents on your system) before using these fonts.
-END_MESSAGE_UPDMAP
- }
-
- $log->close();
- }
-
- return;
-}
-
-
-############################################################################
-
-
-package Attr;
-
-=begin Comment
-
- Some fontnames contain abbreviated words for width, weight and/or shape;
- we unabbreviate these using the following table.
-
-=end Comment
-
-=cut
-
-my %FULL_FORM = (
- cmp => 'compressed',
- comp => 'compressed',
- cond => 'condensed',
- demi => 'demibold',
- extcond => 'extracondensed',
- hair => 'hairline',
- incline => 'inclined',
- it => 'italic',
- ita => 'italic',
- md => 'medium',
- slant => 'slanted',
- ultra => 'ultrablack',
-);
-
-# Auxiliary table that reverses FULL_FORM; maps full forms to abbrevs.
-my %abbrev;
-while (my ($k, $v) = each %FULL_FORM) {
- push @{$abbrev{$v}}, $k;
-}
-
-# Add full forms as known abbreviations of themselves.
-for my $full (keys %abbrev) {
- push @{$abbrev{$full}}, $full;
-}
-
-# Internal helper: returns a list of known abbreviations of its argument.
-sub _get_abbreviated_forms {
- my $key = shift;
-
- return @{ $abbrev{$key} // [$key] };
-}
-
-
-=begin Comment
-
- LaTeX's NFSS contains a number of standard codes for weight and width:
- - weight: ul, el, l, sl, m, sb, b, eb, ub
- - width: uc, ec, c, sc, m, sx, x, ex, ux
-
- These codes are not always a perfect match with the weights and widths
- present in a font family; some families (especially many sans serif ones)
- contain more or different weights and widths, and the naming of those
- weights and widths isn't always consistent between font families.
- To handle this situation, we use a two-tiered approach:
- 1. We install all fonts using a "series" name that is the concatenation
- of whatever the font designer has chosen to call the weight and width
- (but in all *lower*case).
- 2. We add "alias" rules to the .fd files that map the standard NFSS codes
- to actual fonts.
-
- In step 1, we follow NFSS in leaving out any occurrence of
- the word "regular" unless *both* weight and width are Regular;
- in that case, the 'series' attribute becomes "regular".
-
- The two tables WEIGHT and WIDTH are used to control step 2.
- It contains several entries of the form
-
- sc => [ qw( semicondensed narrow ) ],
-
- This should be read as follows: the NFSS code "sc" is mapped to
- the *first* width on the right hand side present in the current family.
-
- Please note that the tables contain empty keys instead of "m" for the
- regular weight and width. NFSS actually combines weight and width into
- a single "series" attribute; a weight or width of "m" is left out of
- this combination (unless *both* weight and width are equal to "m"; then
- the series becomes "m", but that's a special case we deal with later on).
-
- In addition to the mapping of NFSS codes, the two mentioned tables are
- also used in parsing the font's metadata to determine its weight and
- width: any string that occurs on the right hand side is considered a
- possible name to be searched for.
-
- These tables can be extended to teach autoinst about new weights or
- widths. Suppose your font family contains a "Hemibold" weight, that
- you want mapped to the "sb" code. Then add the name "hemibold" to
- the right hand side of the "sb" entry in the WEIGHT table:
-
- sb => [ qw( semibold demibold medium hemibold ) ],
-
- In this case, since it's in last position, it's only mapped to "sb"
- if none of the other fonts are present. Put it earlier in the list
- to give it higher priority.
-
- Note that autoinst converts all metadata to lowercase to avoid
- inconsistent capitalization; so all entries in these tables should
- be *lowercase* as well.
-
- Technical notes:
- - We define WEIGHT and WIDTH first as arrays
- and then as hashtables; this allows us to use the array-variants
- as an *ordered* (by weight/width) list of values (in the routines
- get_all_nfss_weights and get_all_nfss_widths).
-
-=end Comment
-
-=cut
-
-my @WEIGHT = (
- ul => [ qw( ultralight thin 100 hairline ) ],
- el => [ qw( extralight 200 ) ],
- l => [ qw( light 300 ) ],
- sl => [ qw( semilight blond ) ],
- '' => [ qw( regular normal text book 400 normallight normaldark ) ],
- sb => [ qw( semibold demibold 600 medium 500 ) ],
- b => [ qw( bold 700 ) ],
- eb => [ qw( extrabold 800 ) ],
- ub => [ qw( ultrabold black heavy extrablack ultrablack 900 fatface
- ultraheavy poster super 1000 ) ],
-);
-
-my @WIDTH = (
- uc => [ qw( ultracondensed extracompressed ultracompressed ) ],
- ec => [ qw( extracondensed compressed compact ) ],
- c => [ qw( condensed ) ],
- sc => [ qw( semicondensed narrow ) ],
- '' => [ qw( regular ) ],
- sx => [ qw( semiextended semiexpanded wide ) ],
- x => [ qw( extended expanded ) ],
- ex => [],
- ux => [],
-);
-
-my %WEIGHT = @WEIGHT;
-@WEIGHT = grep { !ref } @WEIGHT;
-# Add abbreviated forms of weight names.
-for my $code (@WEIGHT) {
- $WEIGHT{$code}
- = [ map { _get_abbreviated_forms($_) } @{$WEIGHT{$code}} ];
-}
-
-my @allweights = grep { $_ !~ m/ medium | regular | text /xms }
- map { @{$_} } values %WEIGHT;
-@allweights = (
- Util::sort_desc_length(@allweights),
- qw(medium regular text)
-);
-
-
-my %WIDTH = @WIDTH;
-@WIDTH = grep { !ref } @WIDTH;
-# Add abbreviated forms.
-for my $code (@WIDTH) {
- $WIDTH{$code}
- = [ map { _get_abbreviated_forms($_) } @{$WIDTH{$code}} ];
-}
-
-my @allwidths = grep { $_ ne 'regular' } map { @{$_} } values %WIDTH;
-@allwidths = Util::sort_desc_length(@allwidths);
-
-
-=begin Comment
-
- The SHAPE table maps various shape names to NFSS codes.
-
- Like in the other * tables, entries may be added to teach autoinst
- about new shapes. Note that this table is "the other way around"
- compared to WEIGHT and WIDTH; those map NFSS codes to names,
- this one maps names to NFSS codes. That's because the data from
- this table is used in a slightly different way; notably, it isn't
- used in the map_nfss_codes routine.
-
-=end Comment
-
-=cut
-
-my %SHAPE = (
- roman => 'n',
- upright => 'n',
- italic => 'it',
- inclined => 'sl',
- oblique => 'sl',
- slanted => 'sl',
- romani => 'n', # Silentium has two roman shapes, but no italic;
- romanii => 'it', # so we cheat by mapping the second roman to 'it'
-);
-
-# Add abbreviated forms.
-for my $full (keys %abbrev) {
- if (defined $SHAPE{$full}) {
- for my $abbrev (_get_abbreviated_forms($full)) {
- $SHAPE{$abbrev} = $SHAPE{$full};
- }
- }
-}
-
-my @allshapes = Util::sort_desc_length(keys %SHAPE);
-
-
-# --------------------------------------------------------------------------
-# Returns the unabbreviated form of its argument,
-# or its argument itself if no unabbreviated form is known.
-# --------------------------------------------------------------------------
-sub unabbreviate {
- my $key = shift;
-
- return $FULL_FORM{$key} // $key;
-}
-
-
-# --------------------------------------------------------------------------
-# Prepends weight names to the WEIGHT table for a given NFSS code.
-# --------------------------------------------------------------------------
-sub set_weight {
- my ($key, @values) = @_;
-
- $WEIGHT{$key} = [ @values, @{$WEIGHT{$key}} ];
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns a list of NFSS weight names, sorted by weight.
-# --------------------------------------------------------------------------
-sub get_all_nfss_weights {
- return @WEIGHT;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns a list of all known weights, in an order suitable for searching.
-# --------------------------------------------------------------------------
-sub get_all_weights {
- return @allweights;
-}
-
-
-# --------------------------------------------------------------------------
-# Prepends weight names to the WIDTH table for a given NFSS code.
-# --------------------------------------------------------------------------
-sub set_width {
- my ($key, @values) = @_;
-
- $WIDTH{$key} = [ @values, @{$WIDTH{$key}} ];
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns a list of NFSS width names, sorted by width.
-# --------------------------------------------------------------------------
-sub get_all_nfss_widths {
- return @WIDTH;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns a list of all known widths, in an order suitable for searching.
-# --------------------------------------------------------------------------
-sub get_all_widths {
- return @allwidths;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns the NFSS code for the given shape.
-# --------------------------------------------------------------------------
-sub to_nfss {
- my $key = shift;
-
- return $SHAPE{$key};
-}
-
-
-# --------------------------------------------------------------------------
-# Returns a list of all known shapes, in an order suitable for searching.
-# --------------------------------------------------------------------------
-sub get_all_shapes {
- return @allshapes;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns mappings of NFSS codes to weight and width, and vice versa.
-# --------------------------------------------------------------------------
-sub map_nfss_codes {
- my $fontlist = shift;
-
- my (%weight, %width);
- for my $font (@{$fontlist}) {
- $weight{ $font->{weight} } //= $font->{weight_class};
- $width{ $font->{width} } //= $font->{width_class};
- }
-
- my $from_nfss = {
- weight => {},
- width => {},
- };
-
- for my $nfssweight (get_all_nfss_weights()) {
- $from_nfss->{weight}{$nfssweight}
- = [ grep { $weight{$_} } @{$WEIGHT{$nfssweight}} ];
- }
-
- # Some trickery to handle the case where the ul/ub codes are mapped
- # but the el/eb codes are still empty. We try two things:
- # 1. if there is a Thin (Heavy) weight and this is less extreme
- # than the weight mapped to ul (ub), we map Thin (Heavy) to ul (ub)
- # 2. otherwise we move the ul/ub weight to the el/eb position,
- # unless that weight is the Ultralight/Ultrabold weight
- if (!$ARGV{el} and !$ARGV{ul}) {
- if (@{$from_nfss->{weight}{ul}}
- and !@{$from_nfss->{weight}{el}}) {
- if ($weight{thin}
- and $weight{thin}
- > $weight{$from_nfss->{weight}{ul}[0]}) {
- $from_nfss->{weight}{el} = ['thin',];
- }
- elsif ($from_nfss->{weight}{ul}[0] ne 'ultralight') {
- $from_nfss->{weight}{el}
- = [ shift @{$from_nfss->{weight}{ul}} ];
- }
- }
- }
- if (!$ARGV{eb} and !$ARGV{ub}) {
- if (@{$from_nfss->{weight}{ub}}
- and !@{$from_nfss->{weight}{eb}}) {
- if ($weight{heavy}
- and $weight{heavy}
- < $weight{$from_nfss->{weight}{ub}[0]}) {
- $from_nfss->{weight}{eb} = ['heavy',]
- unless @{$from_nfss->{weight}{b}}
- and $weight{$from_nfss->{weight}{b}[0]}
- > $weight{heavy};
- }
- elsif ($from_nfss->{weight}{ub}[0] ne 'ultrabold') {
- $from_nfss->{weight}{eb}
- = [ shift @{$from_nfss->{weight}{ub}} ];
- }
- }
- }
-
- # Special case: if we don't have Regular but we *do* have Medium,
- # move Medium from the "sb" list to the "m" (i.e., Regular) one.
- if (!@{$from_nfss->{weight}{''}}) {
- my $alternate = ( grep { $weight{$_} } qw(medium 500) )[0];
- if ($alternate) {
- $from_nfss->{weight}{''} = [$alternate];
- $from_nfss->{weight}{sb}
- = [ grep { $_ ne $alternate } @{$from_nfss->{weight}{sb}} ];
- }
- }
-
- # Some more trickery to map the sl code to Book or Text (but of course
- # only if sl is empty and Book/Text is lighter than Regular)
- if (!@{$from_nfss->{weight}{sl}}) {
- $from_nfss->{weight}{sl}
- = [ grep { $weight{$_} < $weight{$from_nfss->{weight}{''}[0]} }
- @{$from_nfss->{weight}{''}} ];
- }
-
- NFSSWIDTH:
- for my $nfsswidth (get_all_nfss_widths()) {
- for my $width ( @{$WIDTH{$nfsswidth}} ) {
- if ($width{$width}) {
- $from_nfss->{width}{$nfsswidth} = [$width];
- next NFSSWIDTH;
- }
- }
- $from_nfss->{width}{$nfsswidth} = [];
- }
-
- # Reverse the %from_nfss mapping to get %to_nfss
- my %to_nfss;
- NFSSWEIGHT:
- for my $nfssweight (get_all_nfss_weights()) {
- next unless @{$from_nfss->{weight}{$nfssweight}};
- my $weight = $from_nfss->{weight}{$nfssweight}[0];
- $weight = "" if $weight eq 'regular';
-
- NFSSWIDTH:
- for my $nfsswidth (get_all_nfss_widths()) {
- my $nfssseries = ($nfssweight . $nfsswidth) || 'm';
-
- next unless @{$from_nfss->{width}{$nfsswidth}};
- my $width = $from_nfss->{width}{$nfsswidth}[0];
- $width = "" if $width eq 'regular';
- my $series = ($weight . $width) || 'regular';
- $to_nfss{$series} = $nfssseries;
- }
- }
-
- return [ $from_nfss, \%to_nfss ];
-}
-
-
-############################################################################
-
-
-package Font;
-
-# --------------------------------------------------------------------------
-# Constructor: returns a new Font object.
-# --------------------------------------------------------------------------
-sub _new {
- my ($class, $filename) = @_;
-
- my $self = {
- filename => $filename,
- width => 'regular',
- weight => 'regular',
- shape => 'roman',
- minsize => 0,
- maxsize => 0,
- is_smallcaps => 0,
- weight_class => 0,
- width_class => 0,
- nfss => 'rm',
- };
-
- return bless $self, $class;
-}
-
-
-# --------------------------------------------------------------------------
-# Factory function: parses a font's metadata and creates a Font object.
-# --------------------------------------------------------------------------
-sub parse {
- my $filename = shift;
-
- my $self = __PACKAGE__->_new($filename);
-
- my $metadata = _get_metadata($filename);
-
- $self->_parse_metadata($metadata)
- ->_parse_os2data()
- ->_parse_featuredata()
- ->_parse_sizedata()
- ->_parse_nfss_classification()
- ->_parse_fonttype()
- ;
-
- return $self;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns the output of otfinfo -i as a list of key-value pairs.
-# --------------------------------------------------------------------------
-sub _get_metadata {
- my $filename = shift;
-
- my $cmd = qq(otfinfo --info "$filename");
- open my $otfinfo, '-|', $cmd
- or die "[ERROR] Could not fork(): $!";
- my %data = map { my ($k,$v) = m/\A\s* ([^:]+?) \s*:\s* ([^\r\n]+)/xms;
- $k =~ s/\s+//xmsg;
- (lc $k => $v);
- }
- grep { m/\A\s* [^:]+? \s*:\s* [^\r\n]+/xms } <$otfinfo>;
- close $otfinfo
- or die "[ERROR] '$cmd' failed.";
-
- return \%data;
-}
-
-
-# --------------------------------------------------------------------------
-# Processes the basic metadata for this font.
-# --------------------------------------------------------------------------
-sub _parse_metadata {
- my ($self, $data) = @_;
-
- $self->{originalfamily} = $data->{family};
-
- for my $key (keys %{$data}) {
- $data->{$key} =~ s/\s+//xmsg;
- }
-
- $data->{family} = $data->{preferredfamily} || $data->{family};
- $data->{subfamily} = $data->{preferredsubfamily} || $data->{subfamily};
- $data->{fullname} =~ s/\A$data->{family}//xms;
- $data->{fullname} = lc $data->{fullname};
-
- # clean up family name (it's used in LaTeX command names)
- my @DIGITS = qw(Zero One Two Three Four Five Six Seven Eight Nine);
- $data->{family} =~ s/(?: LT | MT)(?: Std | Pro )\z//xms;
- $data->{family} =~ s/(\d)/$DIGITS[$1]/xmsge;
- $data->{family} =~ s/[^A-Za-z]+//xmsg;
-
- if ($data->{family} =~ m/\A DTL/xms) {
- $data->{family} =~ s/\A DTL//xms;
- $data->{subfamily} =~ s/\A (?: ST | T)//xms;
- }
-
- # remove Adobe's SmallText size, to avoid mistaking it for Text weight
- $data->{family} =~ s/(?: SmallText | SmText )\z//xmsi;
- $data->{subfamily} =~ s/(?: SmallText | SmText )\z//xmsi;
- $data->{fullname} =~ s/(?: SmallText | SmText )\z//xmsi;
-
- # Sometimes the relevant info is in Fullname, sometimes in Subfamily;
- # so we need to test against both
- my $fullinfo = lc "$data->{subfamily} | $data->{fullname}";
-
- # We need to be careful when parsing the font info; in particular
- # we must parse strings like 'UltraCondensed' as 'Regular' weight
- # and 'UltraCondensed' width, not as 'Ultra' weight and 'Condensed' width.
- # The following rules should prevent accidents:
- # 1. Search for matching widths before matching weights
- # (as none of the widths is a proper substring of some weight)
- # 2. Remove any recognised search string from the 'fullinfo'
- # 3. Test the weights 'medium' and 'regular' *last*, since these strings
- # may also occur in Subfamily without indicating the weight;
- # so we only take them to mean weight if we find no other hit.
- my @widths = Attr::get_all_widths();
- for my $width (@widths) {
- if ($fullinfo =~ m/$width/xms) {
- $self->{width} = $width;
- my $widths = join '|', @widths;
- $fullinfo =~ s/$widths//gxmsi;
- last;
- }
- }
- my @weights = Attr::get_all_weights();
- for my $weight (@weights) {
- if ($fullinfo =~ m/$weight/xms) {
- $self->{weight} = $weight;
- my $weights = join '|', @weights;
- $fullinfo =~ s/$weights//gxmsi;
- last;
- }
- }
- my @shapes = Attr::get_all_shapes();
- for my $shape (@shapes) {
- if ($fullinfo =~ m/$shape/xms) {
- $self->{shape} = $shape;
- my $shapes = join '|', @shapes;
- $fullinfo =~ s/$shapes//gxmsi;
- last;
- }
- }
-
- # In many font families, each font is in a subfamily of its own;
- # so we remove width, weight and shape from the 'subfamily' value.
- $data->{subfamily} =~ s/$self->{width}//xmsi;
- $data->{subfamily} =~ s/$self->{weight}//xmsi;
- $data->{subfamily} =~ s/$self->{shape}//xmsi;
-
- $self->{name} = $data->{postscriptname};
- $self->{family} = $data->{family};
- $self->{subfamily} = $data->{subfamily};
-
- # Take care to unabbreviate weight and width; CondensedUltra fonts
- # might end up as 'ultracondensed' instead of 'ultrablackcondensed'!
- $self->{width} = Attr::unabbreviate($self->{width});
- $self->{weight} = Attr::unabbreviate($self->{weight});
- $self->{shape} = Attr::unabbreviate($self->{shape});
-
- # Some font families put small caps into separate families;
- # we merge these into the 'main' family.
- # We have to test both 'family', 'subfamily' and 'name' for hints
- # that this is a small caps font, as some fonts (e.g., Dolly)
- # only mention this in their name.
- my $shapes = join '|', Util::sort_desc_length(qw(smallcaps sc smcp caps));
- if ($self->{family} =~ m/(.+?) (?: $shapes) \z/xmsi) {
- $self->{family} = $1;
- $self->{is_smallcaps} = 1;
- }
- if ($self->{subfamily} =~ m/(.+?) (?: $shapes) \z/xmsi) {
- $self->{subfamily} = $1;
- $self->{is_smallcaps} = 1;
- }
- if ($self->{name} =~ m/\A DTL/xms && $self->{subfamily} =~ s/Caps//xms) {
- $self->{is_smallcaps} = 1;
- }
- if ($self->{name} =~ m/(.+?) (?: $shapes) \z/xmsi) {
- $self->{is_smallcaps} = 1;
- }
- # Some font families put italic shapes into separate families;
- # we merge these into the 'main' family.
- $shapes = join '|', Util::sort_desc_length(qw(it italic));
- if ($self->{family} =~ m/(.+?) ($shapes) \z/xmsi
- and ($self->{shape} eq 'regular'
- or $self->{shape} eq Attr::unabbreviate(lc($2)))) {
- $self->{family} = $1;
- $self->{shape} = Attr::unabbreviate(lc($2));
- }
-
- # Some font families put different widths into separate families;
- # we merge these into the 'main' font family.
- my $widths = join '|', Attr::get_all_widths();
- if ($self->{family} =~ m/(.+?) ($widths) \z/xmsi
- and ($self->{width} eq 'regular'
- or $self->{width} eq Attr::unabbreviate(lc($2)))) {
- $self->{family} = $1;
- $self->{width} = Attr::unabbreviate(lc($2));
- }
-
- # Some font families put unusual weights into separate families;
- # we merge these into the 'main' font family. But we have to be
- # careful with the word 'Text': this might be part of the family name
- # (i.e., Libre Caslon Text) and should not be mistaken for a weight.
- my $weights = join '|', Attr::get_all_weights();
- if ($self->{family} =~ m/text \z/xmsi) {
- $weights =~ s/[|]? text//xms;
- }
- if ($self->{family} =~ m/(.+?) ($weights) \z/xmsi
- and ($self->{weight} eq 'regular'
- or $self->{weight} eq Attr::unabbreviate(lc($2)))) {
- $self->{family} = $1;
- $self->{weight} = Attr::unabbreviate(lc($2));
- }
-
- $self->{basicshape} = Attr::to_nfss($self->{shape});
-
- # We define 'series' as 'weight + width'. This matches NFSS,
- # but contradicts how most fonts are named (which is 'width + weight').
- $self->{series}
- = ($self->{width} eq 'regular') ? $self->{weight}
- : ($self->{weight} eq 'regular') ? $self->{width}
- : $self->{weight} . $self->{width}
- ;
-
- return $self;
-}
-
-
-# --------------------------------------------------------------------------
-# Parses usWeightClass and usWidthClass from the OS/2 table.
-# --------------------------------------------------------------------------
-sub _parse_os2data {
- my $self = shift;
-
- my $os2_table;
- eval {
- my $cmd = qq(otfinfo --dump-table "OS/2" "$self->{filename}");
- open my $otfinfo, '-|:raw', $cmd
- or die "could not fork(): $!";
- $os2_table = do { local $/; <$otfinfo> };
- close $otfinfo
- or die "'$cmd' failed";
- } or warn "[WARNING] $@";
-
- my ($weight_class, $width_class) = unpack '@4n @6n', $os2_table;
-
- $self->{weight_class} = $weight_class;
- $self->{width_class} = $width_class;
-
- return $self;
-}
-
-
-# --------------------------------------------------------------------------
-# Returns a list of features that this font supports.
-# We include 'kern' in this list even if there is only a 'kern' table
-# (but no feature), since otftotfm can also use the (legacy) table.
-# --------------------------------------------------------------------------
-sub _parse_featuredata {
- my $self = shift;
-
- my $cmd = qq(otfinfo --features "$self->{filename}");
- open my $otfinfo, '-|', $cmd
- or die "[ERROR] Could not fork(): $!";
- my @data = map { substr $_, 0, 4 } <$otfinfo>;
- close $otfinfo
- or die "[ERROR] '$cmd' failed.";
-
- $cmd = qq(otfinfo --tables "$self->{filename}");
- open $otfinfo, '-|', $cmd
- or die "[ERROR] Could not fork(): $!";
- my $data = do { local $/; <$otfinfo> };
- close $otfinfo
- or die "[ERROR] '$cmd' failed.";
-
- if ($data =~ m/\d+ \s+ kern/xms) {
- push @data, 'kern';
- }
-
- %{$self->{feature}} = map { $_ => 1 } @data;
-
- return $self;
-}
-
-
-# --------------------------------------------------------------------------
-# Extracts 'minsize' and 'maxsize' from the optical design size info.
-# --------------------------------------------------------------------------
-sub _parse_sizedata {
- my $self = shift;
-
- my $cmd = qq(otfinfo --optical-size "$self->{filename}");
- open my $otfinfo, '-|', $cmd
- or die "[ERROR] Could not fork(): $!";
- my $data = do { local $/; <$otfinfo> };
- close $otfinfo
- or die "[ERROR] '$cmd' failed.";
-
- my ($minsize, $maxsize)
- = $data =~ m/[(] ([\d.]+) \s* pt, \s*
- ([\d.]+) \s* pt \s* [])]/xms;
-
- $minsize //= 0;
- $maxsize //= 0;
-
- # fix some known bugs
- if ($self->{name} eq 'GaramondPremrPro-It'
- && $minsize == 6 && $maxsize == 8.9) {
- ($minsize, $maxsize) = (8.9, 14.9);
- }
- elsif ($self->{family} eq 'KeplerStd'
- && $self->{subfamily} =~ m/Caption/xms
- && $minsize == 8.9 && $maxsize == 13.9) {
- ($minsize, $maxsize) = (6, 8.9);
- }
- elsif ($self->{family} eq 'KeplerStd'
- && $self->{subfamily} =~ m/Subhead/xms
- && $minsize == 8.9 && $maxsize == 13.9) {
- ($minsize, $maxsize) = (13.9, 23);
- }
- elsif ($self->{family} eq 'KeplerStd'
- && $self->{subfamily} =~ m/Display/xms
- && $minsize == 8.9 && $maxsize == 13.9) {
- ($minsize, $maxsize) = (23, 72);
- }
-
- @{$self}{qw(minsize maxsize)} = ($minsize, $maxsize);
-
- return $self;
-}
-
-
-# --------------------------------------------------------------------------
-# Adds the NFSS classification (rm, sf, tt) to self.
-# --------------------------------------------------------------------------
-sub _parse_nfss_classification {
- my $self = shift;
-
- my $classification;
- eval {
- my $cmd = qq(otfinfo --dump-table "post" "$self->{filename}");
- open my $otfinfo, '-|:raw', $cmd
- or die "could not fork(): $!";
- my $post_table = do { local $/; <$otfinfo> };
- close $otfinfo
- or die "'$cmd' failed";
-
- my $is_fixed_pitch = unpack '@12N', $post_table;
-
- $self->{nfss} = $is_fixed_pitch ? 'tt'
- : $self->{filename} =~ m/mono(?!type)/xmsi ? 'tt'
- : $self->{filename} =~ m/sans/xmsi ? 'sf'
- : 'rm'
- ;
- } or warn "[WARNING] $@";
-
- return $self;
-}
-
-
-# --------------------------------------------------------------------------
-# Determines the OpenType flavor of this font.
-# --------------------------------------------------------------------------
-sub _parse_fonttype() {
- my $self = shift;
-
- my ($ext) = $self->{filename} =~ m/[.] ([^.]+) \z/xmsi;
- $ext = lc $ext;
-
- $self->{fonttype}
- = $ext eq 'otf' ? 'opentype'
- : $ext eq 'ttf' ? 'truetype'
- : ''
- ;
-
- if (!$self->{fonttype}) {
- open my $fontfile, '<:raw', $self->{filename}
- or die "[ERROR] Could not open '$self->{filename}': $!";
- my $fontsignature;
- read $fontfile, $fontsignature, 4;
- $self->{fonttype}
- = $fontsignature eq 'OTTO' ? 'opentype'
- : $fontsignature eq "\x00\x01\x00\x00" ? 'truetype'
- : ''
- ;
- close $fontfile;
- }
-
- if (!$self->{fonttype}) {
- die "[ERROR] Unknown font type ($self->{filename})"
- }
-
- return $self;
-}
-
-
-# Error messages, used in assert_unique().
-my $ERR_DETAIL =<<'END_ERR_DETAIL';
-[ERROR] I've parsed both %s
- and %s as
-
- Family: %s
- Weight: %s
- Width: %s
- Shape: %s
- Size: %s-%s
- Smallcaps: %s
-
-END_ERR_DETAIL
-
-my $ERR_PARSE =<<'END_ERR_PARSE';
-[ERROR] I failed to parse all fonts in a unique way;
- presumably some fonts have unusual widths, weights or shapes.
-
- Try one of the following:
- - Run 'autoinst' on a smaller set of fonts,
- omitting the ones that weren't parsed correctly;
- - Add the missing widths, weights or shapes to the tables
- 'WIDTH', 'WEIGHT' or 'SHAPE' in the source code;
-
- Please also send a bug report to the author.
-END_ERR_PARSE
-
-# --------------------------------------------------------------------------
-# Asserts all parsed fonts are unique.
-# --------------------------------------------------------------------------
-sub assert_unique {
- my ($log, $fontlist) = @_;
-
- # These attributes should uniquely identify each font.
- my @attributes
- = qw(family weight width shape minsize maxsize is_smallcaps);
-
- my (%seen, $err_details);
- for my $font (@{$fontlist}) {
- my $key = join "\x00", @{$font}{@attributes};
-
- if ($seen{$key}) {
- $err_details .= sprintf $ERR_DETAIL,
- $seen{$key}{filename},
- $font->{filename},
- @{$font}{@attributes};
- }
- else {
- $seen{$key} = $font;
- }
- }
-
- # Die with detailed error message if the font infos aren't unique.
- if ($err_details) {
- $log->log($err_details, $ERR_PARSE);
- die $err_details, $ERR_PARSE;
- }
-
- return 1;
-}
-
-
-############################################################################
-
-
-package LaTeX;
-
-# --------------------------------------------------------------------------
-# Creates .sty and .fd files for LaTeX.
-# --------------------------------------------------------------------------
-sub create_support_files {
- my ($worklist, $family, $nfss_mapping) = @_;
-
- # Organize the worklist by family, encoding, style, series and shape.
- my %fddata;
- for my $workitem (@{$worklist}) {
- my $encoding = $workitem->{encoding};
- my $figurestyle = $workitem->{figurestyle};
- my $series = $workitem->{font}{series};
- my $shape = $workitem->{fdshape};
- my $minsize = $workitem->{font}{minsize};
- my $maxsize = $workitem->{font}{maxsize};
-
- push @{$fddata{$encoding}{$figurestyle}{$series}{$shape}},
- [ $minsize, $maxsize, $workitem->{fontname} ];
- }
-
- create_stylefile($nfss_mapping, $family, \%fddata);
- while (my ($enc, $encdata) = each %fddata) {
- while (my ($sty, $stydata) = each %$encdata) {
- create_fdfile($nfss_mapping, $family, $enc, $sty, $stydata);
- }
- }
-
- return;
-}
-
-
-# This table is used to generate extra ssub rules in .fd files
-# to map missing Slanted shapes to Italic and vice versa.
-my %SSUB_SHAPE = (
- sl => 'it',
- scsl => 'scit',
- it => 'sl',
- scit => 'scsl',
-);
-
-# --------------------------------------------------------------------------
-# Creates a LaTeX style file.
-# --------------------------------------------------------------------------
-sub create_stylefile {
- my ($nfss_mapping, $fam, $data) = @_;
-
- my %seen = %{Util::get_keys($data)};
-
- my $fn = sprintf "%s.sty", $fam;
- my $dir = File::Spec->catdir(
- $ARGV{target}, 'tex', 'latex', $ARGV{typeface} || $fam);
- File::Path::make_path($dir);
- $fn = File::Spec->catfile($dir, $fn);
- open my $STY, '>', $fn or die "[ERROR] Can't create '$fn': $!";
- # We use binmode since TeX expects these files to have
- # Unix-style line ends even on Windows.
- binmode $STY;
-
- print {$STY} <<"END_STY_HEADER";
-\\NeedsTeXFormat{LaTeX2e}
-\\ProvidesPackage{$fam}
- [$TODAY (autoinst) Style file for $fam fonts.]
-
-END_STY_HEADER
-
- print {$STY} <<"END_STY_XKEYVAL";
-\\RequirePackage{xkeyval}
-\\newcommand*{\\$fam\@scale}{1}
-\\DeclareOptionX{scale}{\\renewcommand*{\\$fam\@scale}{#1}}
-\\DeclareOptionX{scaled}{\\renewcommand*{\\$fam\@scale}{#1}}
-
-END_STY_XKEYVAL
-
- if ($seen{LF} or $seen{TLF}) {
- print {$STY}
- "\\DeclareOptionX{lining}{\\edef\\$fam\@figurestyle{LF}}\n";
- }
- if ($seen{OsF} or $seen{TOsF}) {
- print {$STY}
- "\\DeclareOptionX{oldstyle}{\\edef\\$fam\@figurestyle{OsF}}\n";
- }
- if ($seen{TLF} or $seen{TOsF}) {
- print {$STY}
- "\\DeclareOptionX{tabular}{\\edef\\$fam\@figurealign{T}}\n";
- }
- if ($seen{LF} or $seen{OsF}) {
- print {$STY}
- "\\DeclareOptionX{proportional}{\\edef\\$fam\@figurealign{}}\n";
- }
-
- print {$STY} <<"END_STY_MAINFONT";
-\\DeclareOptionX{mainfont}{
- \\renewcommand{\\familydefault}{\\$ARGV{nfss}default}
-}
-END_STY_MAINFONT
-
- my $defaults
- = $seen{OsF} ? 'oldstyle,proportional'
- : $seen{TOsF} ? 'oldstyle,tabular'
- : $seen{LF} ? 'lining,proportional'
- : $seen{TLF} ? 'lining,tabular'
- : die "[ERROR] Internal bug, please report!"
- ;
-
- for my $series (qw(heavy black extrabold demibold semibold bold)) {
- if ( $seen{$series} ) {
- print {$STY}
- "\\DeclareOptionX{$series}{\\edef\\bfseries\@$ARGV{nfss}",
- "{$series}}\n";
- }
- }
-
- for my $series (qw(medium book text normal regular)) {
- if ( $seen{$series} ) {
- print {$STY}
- "\\DeclareOptionX{$series}{\\edef\\mdseries\@$ARGV{nfss}",
- "{$series}}\n";
- }
- }
-
- if ($ARGV{math}) {
- print {$STY} <<"END_STY_MATHOPTION";
-\\newif\\if$fam\@math\\$fam\@mathfalse
-\\DeclareOptionX{math}{\\$fam\@mathtrue}
-\\DeclareOptionX{nomath}{\\$fam\@mathfalse}
-
-\\newif\\if$fam\@mathgreek\\$fam\@mathgreektrue
-\\DeclareOptionX{mathgreek}{\\$fam\@mathgreektrue}
-\\DeclareOptionX{nomathgreek}{\\$fam\@mathgreekfalse}
-
-\\newcommand*{\\$fam\@mathstyle}{TeX}
-\\DeclareOptionX{math-style}{\\renewcommand*{\\$fam\@mathstyle}{#1}}
-
-END_STY_MATHOPTION
-
- if ($seen{LF} or $seen{TLF}) {
- print {$STY} "\\newcommand*{\\$fam\@mathfigurestyle}{LF}\n";
- }
- elsif ($seen{OsF} or $seen{TOsF}) {
- print {$STY} "\\newcommand*{\\$fam\@mathfigurestyle}{OsF}\n";
- }
-
- if ($seen{OsF} or $seen{TOsF}) {
- print {$STY}
- "\\DeclareOptionX{matholdstyle}\n",
- " {\\renewcommand*{\\$fam\@mathfigurestyle}{OsF}}\n";
- }
- if ($seen{LF} or $seen{TLF}) {
- print {$STY}
- "\\DeclareOptionX{mathlining}\n",
- " {\\renewcommand{\\$fam\@mathfigurestyle}{LF}}\n";
- }
- print {$STY} "\n";
-
- if ($seen{sw}) {
- print {$STY} <<"END_STY_MATHCALOPTION";
-\\newif\\if$fam\@mathcal\\$fam\@mathcalfalse
-\\DeclareOptionX{mathcal}{\\$fam\@mathcaltrue}
-
-END_STY_MATHCALOPTION
- }
- }
-
- print {$STY} <<"END_STY_PROCESSOPTIONS";
-\\ExecuteOptionsX{$defaults}
-\\ProcessOptionsX\\relax
-
-END_STY_PROCESSOPTIONS
-
- print {$STY} <<"END_STY_PACKAGES";
-\\RequirePackage{@{[ $seen{TS1} ? "fontenc,textcomp" : "fontenc" ]}}
-\\RequirePackage{ifthen}
-\\RequirePackage{mweights}
-
-END_STY_PACKAGES
-
- print {$STY} <<'END_STY_FONTAXES_START';
-\IfFileExists{fontaxes.sty}{
- \RequirePackage{fontaxes}
-END_STY_FONTAXES_START
-
- if ($seen{nw} or $seen{sw}) {
- print {$STY} <<'END_STY_FONTAXES_SW';
- \DeclareRobustCommand\swshape{\not@math@alphabet\swshape\relax
- \fontprimaryshape\itdefault\fontsecondaryshape\swdefault\selectfont}
- \fa@naming@exception{shape}{{n}{sw}}{nw}
- \fa@naming@exception{shape}{{it}{sw}}{sw}
-
-END_STY_FONTAXES_SW
- }
-
- if ($seen{Sup}) {
- print {$STY} <<'END_STY_FONTAXES_SUP';
- \fa@naming@exception{figures}{{superior}{proportional}}{Sup}
- \fa@naming@exception{figures}{{superior}{tabular}}{Sup}
- \def\supfigures{\@nomath\supfigures
- \fontfigurestyle{superior}\selectfont}
- \let\sufigures\supfigures
- \DeclareTextFontCommand{\textsup}{\supfigures}
- \let\textsu\textsup
- \let\textsuperior\textsup
-
-END_STY_FONTAXES_SUP
- }
-
- if ($seen{Inf}) {
- print {$STY} <<'END_STY_FONTAXES_INF';
- \fa@naming@exception{figures}{{inferior}{proportional}}{Inf}
- \fa@naming@exception{figures}{{inferior}{tabular}}{Inf}
- \def\inffigures{\@nomath\inffigures
- \fontfigurestyle{inferior}\selectfont}
- \let\infigures\inffigures
- \DeclareTextFontCommand{\textinf}{\inffigures}
- \let\textin\textinf
- \let\textinferior\textinf
-
-END_STY_FONTAXES_INF
- }
-
- if ($seen{Titl}) {
- print {$STY} <<'END_STY_FONTAXES_TITL';
- \fa@naming@exception{figures}{{titlingshape}{proportional}}{Titl}
- \fa@naming@exception{figures}{{titlingshape}{tabular}}{Titl}
- \def\tlshape{\@nomath\tlshape
- \fontfigurestyle{titlingshape}\selectfont}
- \DeclareTextFontCommand{\texttl}{\tlshape}
- \let\texttitling\texttl
-
-END_STY_FONTAXES_TITL
- }
-
- if ($seen{Orn}) {
- print {$STY} <<'END_STY_FONTAXES_ORN';
- \fa@naming@exception{figures}{{ornament}{proportional}}{Orn}
- \fa@naming@exception{figures}{{ornament}{tabular}}{Orn}
- \def\ornaments{\@nomath\ornaments
- \fontencoding{U}\fontfigurestyle{ornament}\selectfont}
- \DeclareTextFontCommand{\textornaments}{\ornaments}
-
-END_STY_FONTAXES_ORN
- }
-
- if ($seen{Numr}) {
- print {$STY} <<'END_STY_FONTAXES_NUMR';
- \fa@naming@exception{figures}{{numerators}{proportional}}{Numr}
- \fa@naming@exception{figures}{{numerators}{tabular}}{Numr}
-
-END_STY_FONTAXES_NUMR
- }
-
- if ($seen{Dnom}) {
- print {$STY} <<'END_STY_FONTAXES_DNOM';
- \fa@naming@exception{figures}{{denominators}{proportional}}{Dnom}
- \fa@naming@exception{figures}{{denominators}{tabular}}{Dnom}
-
-END_STY_FONTAXES_DNOM
- }
-
- print {$STY} "}{}\n\n";
-
- # For the scale=MatchLowercase option, we need the name for
- # one of the fonts from the family, to pass to plain TeX's
- # \font macro (as explained below, we cannot use NFSS's
- # font loading mechanism before we have calculated the correct
- # scaling parameter).
- my $testfont = eval {
- my $testenc = $ARGV{encoding}[0];
- my $testfig = ( grep { exists $data->{$testenc}{$_} }
- qw(OsF LF TOsF TLF) )[0] or die;
- my $testweight = ( grep { $nfss_mapping->{$_} eq "m" }
- keys %{$nfss_mapping} )[0] or die;
- my $testshape
- = ( grep { exists $data->{$testenc}{$testfig}{$testweight}{$_} }
- qw(n sc it sl)
- )[0] or die;
- return $data->{$testenc}{$testfig}{$testweight}{$testshape}[0][2]
- || die;
- };
-
- if (defined $testfont) {
- print {$STY} <<"END_STY_MATCHLOWERCASE";
-% Here we implement the scale=MatchLowercase option.
-% If this is given, we must compute the correct value of
-% the "\\$fam\@scale" parameter before loading the .fd files;
-% but to determine that value we of course need the font's x-height.
-% To avoid triggering the loading of .fd files,
-% we use plain TeX's \\font primitive to load the testfont.
-% We then compute the ratio of the current x-height to our font's x-height;
-% this is the "\\$fam\@scale" we will pass to the .fd files.
-\\ifthenelse{\\equal{\\$fam\@scale}{MatchLowercase}}
- { \\newlength{\\$fam\@currentx}
- \\settoheight{\\$fam\@currentx}{x}
- \\newlength{\\$fam\@xheight}
- \\settoheight{\\$fam\@xheight}
- {{\\font\\testfont=$testfont at \\f\@size pt\\testfont x}}
- \\renewcommand*{\\$fam\@scale}
- {\\strip\@pt\\dimexpr\\number\\numexpr\\number\\dimexpr\\$fam\@currentx\\relax*65536/\\number\\dimexpr\\$fam\@xheight\\relax\\relax sp\\relax}}
- {}
-
-END_STY_MATCHLOWERCASE
- }
-
- print {$STY} <<"END_STYLE_REST";
-\\renewcommand*
- {\\$ARGV{nfss}default}
- {$fam-\\$fam\@figurealign\\$fam\@figurestyle}
-
-END_STYLE_REST
-
- if ($ARGV{math}) {
- print {$STY} <<"END_STY_MATH";
-\\newif\\if$fam\@mathLATINup\\$fam\@mathLATINupfalse
-\\newif\\if$fam\@mathlatinup\\$fam\@mathlatinupfalse
-\\newif\\if$fam\@mathGREEKup\\$fam\@mathGREEKupfalse
-\\newif\\if$fam\@mathgreekup\\$fam\@mathgreekupfalse
-
-\\if$fam\@math
- \\DeclareSymbolFont{newoperators} {OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\mdseries\@$ARGV{nfss}}{n}
- \\SetSymbolFont{newoperators}{bold}{OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{n}
-
- \\DeclareSymbolFont{newletters} {OML}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\mdseries\@$ARGV{nfss}}{it}
- \\SetSymbolFont{newletters}{bold}{OML}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{it}
-
- \\DeclareSymbolFontAlphabet{\\mathrm}{newoperators}
- \\DeclareSymbolFontAlphabet{\\mathnormal}{newletters}
-
- \\def\\operator\@font{\\mathgroup\\symnewoperators}
- \\SetMathAlphabet{\\mathit}{normal}{OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\mdseries\@$ARGV{nfss}}{it}
- \\SetMathAlphabet{\\mathit}{bold} {OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{it}
-
- \\SetMathAlphabet{\\mathbf}{normal}{OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{n}
- \\SetMathAlphabet{\\mathbf}{bold} {OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{n}
-
- \\def\\re\@DeclareMathSymbol#1#2#3#4{%
- \\if\\relax\\noexpand#1\\let#1=\\undefined\\fi
- \\DeclareMathSymbol{#1}{#2}{#3}{#4}}
-
- \\def\\re\@DeclareMathDelimiter#1#2#3#4#5#6{%
- \\let#1=\\undefined
- \\DeclareMathDelimiter{#1}{#2}{#3}{#4}{#5}{#6}}
-
- \\def\\re\@DeclareMathAccent#1#2#3#4{%
- \\let#1=\\undefined
- \\DeclareMathAccent{#1}{#2}{#3}{#4}}
-
- \\re\@DeclareMathSymbol{0}{\\mathalpha}{newoperators}{`0}
- \\re\@DeclareMathSymbol{1}{\\mathalpha}{newoperators}{`1}
- \\re\@DeclareMathSymbol{2}{\\mathalpha}{newoperators}{`2}
- \\re\@DeclareMathSymbol{3}{\\mathalpha}{newoperators}{`3}
- \\re\@DeclareMathSymbol{4}{\\mathalpha}{newoperators}{`4}
- \\re\@DeclareMathSymbol{5}{\\mathalpha}{newoperators}{`5}
- \\re\@DeclareMathSymbol{6}{\\mathalpha}{newoperators}{`6}
- \\re\@DeclareMathSymbol{7}{\\mathalpha}{newoperators}{`7}
- \\re\@DeclareMathSymbol{8}{\\mathalpha}{newoperators}{`8}
- \\re\@DeclareMathSymbol{9}{\\mathalpha}{newoperators}{`9}
-
- \\re\@DeclareMathSymbol{a}{\\mathalpha}{newletters}{`a}
- \\re\@DeclareMathSymbol{b}{\\mathalpha}{newletters}{`b}
- \\re\@DeclareMathSymbol{c}{\\mathalpha}{newletters}{`c}
- \\re\@DeclareMathSymbol{d}{\\mathalpha}{newletters}{`d}
- \\re\@DeclareMathSymbol{e}{\\mathalpha}{newletters}{`e}
- \\re\@DeclareMathSymbol{f}{\\mathalpha}{newletters}{`f}
- \\re\@DeclareMathSymbol{g}{\\mathalpha}{newletters}{`g}
- \\re\@DeclareMathSymbol{h}{\\mathalpha}{newletters}{`h}
- \\re\@DeclareMathSymbol{i}{\\mathalpha}{newletters}{`i}
- \\re\@DeclareMathSymbol{j}{\\mathalpha}{newletters}{`j}
- \\re\@DeclareMathSymbol{k}{\\mathalpha}{newletters}{`k}
- \\re\@DeclareMathSymbol{l}{\\mathalpha}{newletters}{`l}
- \\re\@DeclareMathSymbol{m}{\\mathalpha}{newletters}{`m}
- \\re\@DeclareMathSymbol{n}{\\mathalpha}{newletters}{`n}
- \\re\@DeclareMathSymbol{o}{\\mathalpha}{newletters}{`o}
- \\re\@DeclareMathSymbol{p}{\\mathalpha}{newletters}{`p}
- \\re\@DeclareMathSymbol{q}{\\mathalpha}{newletters}{`q}
- \\re\@DeclareMathSymbol{r}{\\mathalpha}{newletters}{`r}
- \\re\@DeclareMathSymbol{s}{\\mathalpha}{newletters}{`s}
- \\re\@DeclareMathSymbol{t}{\\mathalpha}{newletters}{`t}
- \\re\@DeclareMathSymbol{u}{\\mathalpha}{newletters}{`u}
- \\re\@DeclareMathSymbol{v}{\\mathalpha}{newletters}{`v}
- \\re\@DeclareMathSymbol{w}{\\mathalpha}{newletters}{`w}
- \\re\@DeclareMathSymbol{x}{\\mathalpha}{newletters}{`x}
- \\re\@DeclareMathSymbol{y}{\\mathalpha}{newletters}{`y}
- \\re\@DeclareMathSymbol{z}{\\mathalpha}{newletters}{`z}
-
- \\re\@DeclareMathSymbol{A}{\\mathalpha}{newletters}{`A}
- \\re\@DeclareMathSymbol{B}{\\mathalpha}{newletters}{`B}
- \\re\@DeclareMathSymbol{C}{\\mathalpha}{newletters}{`C}
- \\re\@DeclareMathSymbol{D}{\\mathalpha}{newletters}{`D}
- \\re\@DeclareMathSymbol{E}{\\mathalpha}{newletters}{`E}
- \\re\@DeclareMathSymbol{F}{\\mathalpha}{newletters}{`F}
- \\re\@DeclareMathSymbol{G}{\\mathalpha}{newletters}{`G}
- \\re\@DeclareMathSymbol{H}{\\mathalpha}{newletters}{`H}
- \\re\@DeclareMathSymbol{I}{\\mathalpha}{newletters}{`I}
- \\re\@DeclareMathSymbol{J}{\\mathalpha}{newletters}{`J}
- \\re\@DeclareMathSymbol{K}{\\mathalpha}{newletters}{`K}
- \\re\@DeclareMathSymbol{L}{\\mathalpha}{newletters}{`L}
- \\re\@DeclareMathSymbol{M}{\\mathalpha}{newletters}{`M}
- \\re\@DeclareMathSymbol{N}{\\mathalpha}{newletters}{`N}
- \\re\@DeclareMathSymbol{O}{\\mathalpha}{newletters}{`O}
- \\re\@DeclareMathSymbol{P}{\\mathalpha}{newletters}{`P}
- \\re\@DeclareMathSymbol{Q}{\\mathalpha}{newletters}{`Q}
- \\re\@DeclareMathSymbol{R}{\\mathalpha}{newletters}{`R}
- \\re\@DeclareMathSymbol{S}{\\mathalpha}{newletters}{`S}
- \\re\@DeclareMathSymbol{T}{\\mathalpha}{newletters}{`T}
- \\re\@DeclareMathSymbol{U}{\\mathalpha}{newletters}{`U}
- \\re\@DeclareMathSymbol{V}{\\mathalpha}{newletters}{`V}
- \\re\@DeclareMathSymbol{W}{\\mathalpha}{newletters}{`W}
- \\re\@DeclareMathSymbol{X}{\\mathalpha}{newletters}{`X}
- \\re\@DeclareMathSymbol{Y}{\\mathalpha}{newletters}{`Y}
- \\re\@DeclareMathSymbol{Z}{\\mathalpha}{newletters}{`Z}
-
- \\re\@DeclareMathSymbol{\\imath}{\\mathord}{newletters}{"7B}
- \\re\@DeclareMathSymbol{\\jmath}{\\mathord}{newletters}{"7C}
-
- %
- % A number of math symbol declarations have been commented out,
- % since these characters generally do not work very well when
- % typesetting maths (either because of spacing issues or because
- % they don't mix with others symbols).
- % The commented-out declarations have been left in this style file
- % in case the user does want to re-activate those characters.
- %
-
- \\re\@DeclareMathSymbol{!}{\\mathclose}{newoperators}{"21}
- % \\re\@DeclareMathSymbol{+}{\\mathbin} {newoperators}{"2B}
- % \\re\@DeclareMathSymbol{:}{\\mathrel} {newoperators}{"3A}
- \\re\@DeclareMathSymbol{;}{\\mathpunct}{newoperators}{"3B}
- % \\re\@DeclareMathSymbol{=}{\\mathrel} {newoperators}{"3D}
- \\re\@DeclareMathSymbol{?}{\\mathclose}{newoperators}{"3F}
-
- % \\re\@DeclareMathSymbol{.}{\\mathord} {newletters}{"3A}
- \\re\@DeclareMathSymbol{,}{\\mathpunct}{newletters}{"3B}
- % \\re\@DeclareMathSymbol{<}{\\mathrel} {newletters}{"3C}
- % \\re\@DeclareMathSymbol{/}{\\mathord} {newletters}{"3D}
- % \\re\@DeclareMathSymbol{>}{\\mathrel} {newletters}{"3E}
-
- \\re\@DeclareMathSymbol{\\mathdollar}{\\mathord} {newoperators}{"24}
- \\re\@DeclareMathSymbol{\\colon} {\\mathpunct}{newoperators}{"3A}
-
- % \\DeclareMathDelimiter{(}{\\mathopen} {newoperators}{"28}{largesymbols}{"00}
- % \\DeclareMathDelimiter{)}{\\mathclose}{newoperators}{"29}{largesymbols}{"01}
- % \\DeclareMathDelimiter{[}{\\mathopen} {newoperators}{"5B}{largesymbols}{"02}
- % \\DeclareMathDelimiter{]}{\\mathclose}{newoperators}{"5D}{largesymbols}{"03}
- % \\DeclareMathDelimiter{/}{\\mathord} {newoperators}{"2F}{largesymbols}{"0E}
-
- \\re\@DeclareMathAccent{\\grave} {\\mathalpha}{newoperators}{"12}
- \\re\@DeclareMathAccent{\\acute} {\\mathalpha}{newoperators}{"13}
- \\re\@DeclareMathAccent{\\check} {\\mathalpha}{newoperators}{"14}
- \\re\@DeclareMathAccent{\\breve} {\\mathalpha}{newoperators}{"15}
- \\re\@DeclareMathAccent{\\bar} {\\mathalpha}{newoperators}{"16}
- \\re\@DeclareMathAccent{\\mathring}{\\mathalpha}{newoperators}{"17}
- \\re\@DeclareMathAccent{\\hat} {\\mathalpha}{newoperators}{"5E}
- \\re\@DeclareMathAccent{\\dot} {\\mathalpha}{newoperators}{"5F}
- \\re\@DeclareMathAccent{\\tilde} {\\mathalpha}{newoperators}{"7E}
- \\re\@DeclareMathAccent{\\ddot} {\\mathalpha}{newoperators}{"7F}
-
- \\if$fam\@mathgreek
- \\re\@DeclareMathSymbol{\\Gamma} {\\mathalpha}{newoperators}{"00}
- \\re\@DeclareMathSymbol{\\Delta} {\\mathalpha}{newoperators}{"01}
- \\re\@DeclareMathSymbol{\\Theta} {\\mathalpha}{newoperators}{"02}
- \\re\@DeclareMathSymbol{\\Lambda} {\\mathalpha}{newoperators}{"03}
- \\re\@DeclareMathSymbol{\\Xi} {\\mathalpha}{newoperators}{"04}
- \\re\@DeclareMathSymbol{\\Pi} {\\mathalpha}{newoperators}{"05}
- \\re\@DeclareMathSymbol{\\Sigma} {\\mathalpha}{newoperators}{"06}
- \\re\@DeclareMathSymbol{\\Upsilon}{\\mathalpha}{newoperators}{"07}
- \\re\@DeclareMathSymbol{\\Phi} {\\mathalpha}{newoperators}{"08}
- \\re\@DeclareMathSymbol{\\Psi} {\\mathalpha}{newoperators}{"09}
- \\re\@DeclareMathSymbol{\\Omega} {\\mathalpha}{newoperators}{"0A}
-
- \\re\@DeclareMathSymbol{\\alpha} {\\mathord}{newletters}{"0B}
- \\re\@DeclareMathSymbol{\\beta} {\\mathord}{newletters}{"0C}
- \\re\@DeclareMathSymbol{\\gamma} {\\mathord}{newletters}{"0D}
- \\re\@DeclareMathSymbol{\\delta} {\\mathord}{newletters}{"0E}
- \\re\@DeclareMathSymbol{\\epsilon} {\\mathord}{newletters}{"0F}
- \\re\@DeclareMathSymbol{\\zeta} {\\mathord}{newletters}{"10}
- \\re\@DeclareMathSymbol{\\eta} {\\mathord}{newletters}{"11}
- \\re\@DeclareMathSymbol{\\theta} {\\mathord}{newletters}{"12}
- \\re\@DeclareMathSymbol{\\iota} {\\mathord}{newletters}{"13}
- \\re\@DeclareMathSymbol{\\kappa} {\\mathord}{newletters}{"14}
- \\re\@DeclareMathSymbol{\\lambda} {\\mathord}{newletters}{"15}
- \\re\@DeclareMathSymbol{\\mu} {\\mathord}{newletters}{"16}
- \\re\@DeclareMathSymbol{\\nu} {\\mathord}{newletters}{"17}
- \\re\@DeclareMathSymbol{\\xi} {\\mathord}{newletters}{"18}
- \\re\@DeclareMathSymbol{\\pi} {\\mathord}{newletters}{"19}
- \\re\@DeclareMathSymbol{\\rho} {\\mathord}{newletters}{"1A}
- \\re\@DeclareMathSymbol{\\sigma} {\\mathord}{newletters}{"1B}
- \\re\@DeclareMathSymbol{\\tau} {\\mathord}{newletters}{"1C}
- \\re\@DeclareMathSymbol{\\upsilon} {\\mathord}{newletters}{"1D}
- \\re\@DeclareMathSymbol{\\phi} {\\mathord}{newletters}{"1E}
- \\re\@DeclareMathSymbol{\\chi} {\\mathord}{newletters}{"1F}
- \\re\@DeclareMathSymbol{\\psi} {\\mathord}{newletters}{"20}
- \\re\@DeclareMathSymbol{\\omega} {\\mathord}{newletters}{"21}
- \\re\@DeclareMathSymbol{\\varepsilon}{\\mathord}{newletters}{"22}
- \\re\@DeclareMathSymbol{\\vartheta} {\\mathord}{newletters}{"23}
- \\re\@DeclareMathSymbol{\\varpi} {\\mathord}{newletters}{"24}
- \\re\@DeclareMathSymbol{\\varrho} {\\mathord}{newletters}{"25}
- \\re\@DeclareMathSymbol{\\varsigma} {\\mathord}{newletters}{"26}
- \\re\@DeclareMathSymbol{\\varphi} {\\mathord}{newletters}{"27}
- \\fi
-
- \\ifthenelse{\\equal{\\$fam\@mathstyle}{TeX}}
- {\\$fam\@mathGREEKuptrue}
- {}
- \\ifthenelse{\\equal{\\$fam\@mathstyle}{french}}
- {\\$fam\@mathLATINuptrue
- \\$fam\@mathGREEKuptrue
- \\$fam\@mathgreekuptrue}
- {}
- \\ifthenelse{\\equal{\\$fam\@mathstyle}{upright}}
- {\\$fam\@mathLATINuptrue
- \\$fam\@mathlatinuptrue
- \\$fam\@mathGREEKuptrue
- \\$fam\@mathgreekuptrue}
- {}
-
- \\if$fam\@mathLATINup
- \\re\@DeclareMathSymbol{A}{\\mathalpha}{newoperators}{`A}
- \\re\@DeclareMathSymbol{B}{\\mathalpha}{newoperators}{`B}
- \\re\@DeclareMathSymbol{C}{\\mathalpha}{newoperators}{`C}
- \\re\@DeclareMathSymbol{D}{\\mathalpha}{newoperators}{`D}
- \\re\@DeclareMathSymbol{E}{\\mathalpha}{newoperators}{`E}
- \\re\@DeclareMathSymbol{F}{\\mathalpha}{newoperators}{`F}
- \\re\@DeclareMathSymbol{G}{\\mathalpha}{newoperators}{`G}
- \\re\@DeclareMathSymbol{H}{\\mathalpha}{newoperators}{`H}
- \\re\@DeclareMathSymbol{I}{\\mathalpha}{newoperators}{`I}
- \\re\@DeclareMathSymbol{J}{\\mathalpha}{newoperators}{`J}
- \\re\@DeclareMathSymbol{K}{\\mathalpha}{newoperators}{`K}
- \\re\@DeclareMathSymbol{L}{\\mathalpha}{newoperators}{`L}
- \\re\@DeclareMathSymbol{M}{\\mathalpha}{newoperators}{`M}
- \\re\@DeclareMathSymbol{N}{\\mathalpha}{newoperators}{`N}
- \\re\@DeclareMathSymbol{O}{\\mathalpha}{newoperators}{`O}
- \\re\@DeclareMathSymbol{P}{\\mathalpha}{newoperators}{`P}
- \\re\@DeclareMathSymbol{Q}{\\mathalpha}{newoperators}{`Q}
- \\re\@DeclareMathSymbol{R}{\\mathalpha}{newoperators}{`R}
- \\re\@DeclareMathSymbol{S}{\\mathalpha}{newoperators}{`S}
- \\re\@DeclareMathSymbol{T}{\\mathalpha}{newoperators}{`T}
- \\re\@DeclareMathSymbol{U}{\\mathalpha}{newoperators}{`U}
- \\re\@DeclareMathSymbol{V}{\\mathalpha}{newoperators}{`V}
- \\re\@DeclareMathSymbol{W}{\\mathalpha}{newoperators}{`W}
- \\re\@DeclareMathSymbol{X}{\\mathalpha}{newoperators}{`X}
- \\re\@DeclareMathSymbol{Y}{\\mathalpha}{newoperators}{`Y}
- \\re\@DeclareMathSymbol{Z}{\\mathalpha}{newoperators}{`Z}
- \\fi
-
- \\if$fam\@mathlatinup
- \\DeclareSymbolFont{upletters} {OML}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\mdseries\@$ARGV{nfss}}{n}
- \\SetSymbolFont{upletters}{bold}{OML}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{n}
-
- \\re\@DeclareMathSymbol{a}{\\mathord}{upletters}{`a}
- \\re\@DeclareMathSymbol{b}{\\mathord}{upletters}{`b}
- \\re\@DeclareMathSymbol{c}{\\mathord}{upletters}{`c}
- \\re\@DeclareMathSymbol{d}{\\mathord}{upletters}{`d}
- \\re\@DeclareMathSymbol{e}{\\mathord}{upletters}{`e}
- \\re\@DeclareMathSymbol{f}{\\mathord}{upletters}{`f}
- \\re\@DeclareMathSymbol{g}{\\mathord}{upletters}{`g}
- \\re\@DeclareMathSymbol{h}{\\mathord}{upletters}{`h}
- \\re\@DeclareMathSymbol{i}{\\mathord}{upletters}{`i}
- \\re\@DeclareMathSymbol{j}{\\mathord}{upletters}{`j}
- \\re\@DeclareMathSymbol{k}{\\mathord}{upletters}{`k}
- \\re\@DeclareMathSymbol{l}{\\mathord}{upletters}{`l}
- \\re\@DeclareMathSymbol{m}{\\mathord}{upletters}{`m}
- \\re\@DeclareMathSymbol{n}{\\mathord}{upletters}{`n}
- \\re\@DeclareMathSymbol{o}{\\mathord}{upletters}{`o}
- \\re\@DeclareMathSymbol{p}{\\mathord}{upletters}{`p}
- \\re\@DeclareMathSymbol{q}{\\mathord}{upletters}{`q}
- \\re\@DeclareMathSymbol{r}{\\mathord}{upletters}{`r}
- \\re\@DeclareMathSymbol{s}{\\mathord}{upletters}{`s}
- \\re\@DeclareMathSymbol{t}{\\mathord}{upletters}{`t}
- \\re\@DeclareMathSymbol{u}{\\mathord}{upletters}{`u}
- \\re\@DeclareMathSymbol{v}{\\mathord}{upletters}{`v}
- \\re\@DeclareMathSymbol{w}{\\mathord}{upletters}{`w}
- \\re\@DeclareMathSymbol{x}{\\mathord}{upletters}{`x}
- \\re\@DeclareMathSymbol{y}{\\mathord}{upletters}{`y}
- \\re\@DeclareMathSymbol{z}{\\mathord}{upletters}{`z}
-
- \\re\@DeclareMathSymbol{\\imath}{\\mathord}{upletters}{"7B}
- \\re\@DeclareMathSymbol{\\jmath}{\\mathord}{upletters}{"7C}
- \\fi
-
- \\if$fam\@mathgreek
- \\if$fam\@mathGREEKup
- \\else
- \\re\@DeclareMathSymbol{\\Gamma} {\\mathalpha}{newletters}{"00}
- \\re\@DeclareMathSymbol{\\Delta} {\\mathalpha}{newletters}{"01}
- \\re\@DeclareMathSymbol{\\Theta} {\\mathalpha}{newletters}{"02}
- \\re\@DeclareMathSymbol{\\Lambda} {\\mathalpha}{newletters}{"03}
- \\re\@DeclareMathSymbol{\\Xi} {\\mathalpha}{newletters}{"04}
- \\re\@DeclareMathSymbol{\\Pi} {\\mathalpha}{newletters}{"05}
- \\re\@DeclareMathSymbol{\\Sigma} {\\mathalpha}{newletters}{"06}
- \\re\@DeclareMathSymbol{\\Upsilon}{\\mathalpha}{newletters}{"07}
- \\re\@DeclareMathSymbol{\\Phi} {\\mathalpha}{newletters}{"08}
- \\re\@DeclareMathSymbol{\\Psi} {\\mathalpha}{newletters}{"09}
- \\re\@DeclareMathSymbol{\\Omega} {\\mathalpha}{newletters}{"0A}
- \\fi
-
- \\if$fam\@mathgreekup
- \\DeclareSymbolFont{upletters} {OML}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\mdseries\@$ARGV{nfss}}{n}
- \\SetSymbolFont{upletters}{bold}{OML}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{n}
-
- \\re\@DeclareMathSymbol{\\alpha} {\\mathord}{upletters}{"0B}
- \\re\@DeclareMathSymbol{\\beta} {\\mathord}{upletters}{"0C}
- \\re\@DeclareMathSymbol{\\gamma} {\\mathord}{upletters}{"0D}
- \\re\@DeclareMathSymbol{\\delta} {\\mathord}{upletters}{"0E}
- \\re\@DeclareMathSymbol{\\epsilon} {\\mathord}{upletters}{"0F}
- \\re\@DeclareMathSymbol{\\zeta} {\\mathord}{upletters}{"10}
- \\re\@DeclareMathSymbol{\\eta} {\\mathord}{upletters}{"11}
- \\re\@DeclareMathSymbol{\\theta} {\\mathord}{upletters}{"12}
- \\re\@DeclareMathSymbol{\\iota} {\\mathord}{upletters}{"13}
- \\re\@DeclareMathSymbol{\\kappa} {\\mathord}{upletters}{"14}
- \\re\@DeclareMathSymbol{\\lambda} {\\mathord}{upletters}{"15}
- \\re\@DeclareMathSymbol{\\mu} {\\mathord}{upletters}{"16}
- \\re\@DeclareMathSymbol{\\nu} {\\mathord}{upletters}{"17}
- \\re\@DeclareMathSymbol{\\xi} {\\mathord}{upletters}{"18}
- \\re\@DeclareMathSymbol{\\pi} {\\mathord}{upletters}{"19}
- \\re\@DeclareMathSymbol{\\rho} {\\mathord}{upletters}{"1A}
- \\re\@DeclareMathSymbol{\\sigma} {\\mathord}{upletters}{"1B}
- \\re\@DeclareMathSymbol{\\tau} {\\mathord}{upletters}{"1C}
- \\re\@DeclareMathSymbol{\\upsilon} {\\mathord}{upletters}{"1D}
- \\re\@DeclareMathSymbol{\\phi} {\\mathord}{upletters}{"1E}
- \\re\@DeclareMathSymbol{\\chi} {\\mathord}{upletters}{"1F}
- \\re\@DeclareMathSymbol{\\psi} {\\mathord}{upletters}{"20}
- \\re\@DeclareMathSymbol{\\omega} {\\mathord}{upletters}{"21}
- \\re\@DeclareMathSymbol{\\varepsilon}{\\mathord}{upletters}{"22}
- \\re\@DeclareMathSymbol{\\vartheta} {\\mathord}{upletters}{"23}
- \\re\@DeclareMathSymbol{\\varpi} {\\mathord}{upletters}{"24}
- \\re\@DeclareMathSymbol{\\varrho} {\\mathord}{upletters}{"25}
- \\re\@DeclareMathSymbol{\\varsigma} {\\mathord}{upletters}{"26}
- \\re\@DeclareMathSymbol{\\varphi} {\\mathord}{upletters}{"27}
- \\fi
- \\fi
-\\fi
-
-END_STY_MATH
-
- if ($seen{sw}) {
- print {$STY} <<"END_STY_MATHCAL";
-\\if$fam\@mathcal
- \\SetMathAlphabet{\\mathcal}{normal}{OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\mdseries\@$ARGV{nfss}}{sw}
- \\SetMathAlphabet{\\mathcal}{bold} {OT1}{$fam-\\$fam\@figurealign\\$fam\@mathfigurestyle}{\\bfseries\@$ARGV{nfss}}{sw}
-\\fi
-
-END_STY_MATHCAL
- }
- }
-
- print {$STY} "\\endinput\n";
- close $STY;
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Creates a .fd file for LaTeX.
-# --------------------------------------------------------------------------
-sub create_fdfile {
- my ($nfss_mapping, $fam, $enc, $sty, $data) = @_;
-
- my $fn = sprintf "%s%s-%s.fd", $enc, $fam, $sty;
- my $dir = File::Spec->catdir(
- $ARGV{target}, 'tex', 'latex', $ARGV{typeface} || $fam);
- File::Path::make_path($dir);
- $fn = File::Spec->catfile($dir, $fn);
- open my $FD, '>', $fn
- or die "[ERROR] Can't create '$fn': $!";
- binmode $FD;
-
- print {$FD} <<"END_FD_HEADER";
-%% Generated by autoinst on $TODAY
-%%
-\\ProvidesFile{$enc$fam-$sty.fd}
- [$TODAY (autoinst) Font definitions for $enc/$fam-$sty.]
-
-\\ifcsname s\@fct\@alias\\endcsname\\else
-\\gdef\\s\@fct\@alias{\\sub\@sfcnt\\\@font\@aliasinfo}
-\\gdef\\\@font\@aliasinfo#1{%
- \\\@font\@info{Font\\space shape\\space `\\curr\@fontshape'\\space will
- \\space be\\space aliased\\MessageBreak to\\space `\\mandatory\@arg'}%
-}
-\\fi
-
-\\expandafter\\ifx\\csname $fam\@scale\\endcsname\\relax
- \\let\\$fam\@\@scale\\\@empty
-\\else
- \\edef\\$fam\@\@scale{s*[\\csname $fam\@scale\\endcsname]}%
-\\fi
-
-\\DeclareFontFamily{$enc}{$fam-$sty}{@{[
- $ARGV{nfss} eq 'tt' ? '\hyphenchar\font=-1'
- : $enc eq 'OML' ? '\skewchar\font=127'
- : q{}
-]}}
-
-END_FD_HEADER
-
- while (my ($series, $fdseries) = each %$data) {
- my $nfssseries = $nfss_mapping->{$series};
-
- my $alias = $series;
- if (defined $nfssseries) {
- print {$FD} "\n% ---- $nfssseries = $series ----\n\n";
- $series = $nfssseries;
- }
- else {
- print {$FD} "\n% ---- $series ----\n\n";
- }
- while (my ($shape, $fdshape) = each %$fdseries) {
- print {$FD}
- "\\DeclareFontShape{$enc}{$fam-$sty}{$series}{$shape}{\n";
- my @sizes = sort { $a->[0] <=> $b->[0] }
- @{$fdshape};
- $sizes[0][0] = $sizes[-1][1] = '';
- $sizes[$_][0] = $sizes[$_ - 1][1] for (1 .. $#sizes);
- for my $size (@sizes) {
- print {$FD} " <$size->[0]-$size->[1]> ",
- "\\$fam\@\@scale $size->[2]\n";
- }
- print {$FD} "}{}\n\n";
-
- if (defined $nfssseries) {
- print {$FD} <<"END_ALIAS_SERIES";
-\\DeclareFontShape{$enc}{$fam-$sty}{$alias}{$shape}{
- <-> alias * $fam-$sty/$nfssseries/$shape
-}{}
-
-END_ALIAS_SERIES
- }
- }
-
- # ssub italic for missing slanted, or vice versa
- while (my ($shape, $replace) = each %SSUB_SHAPE) {
- if (!exists $fdseries->{$shape} && exists $fdseries->{$replace}) {
- print {$FD} <<"END_SSUB_SHAPE";
-\\DeclareFontShape{$enc}{$fam-$sty}{$series}{$shape}{
- <-> ssub * $fam-$sty/$series/$replace
-}{}
-
-END_SSUB_SHAPE
- if (defined $nfssseries) {
- print {$FD} <<"END_SSUB_ALIAS";
-\\DeclareFontShape{$enc}{$fam-$sty}{$alias}{$shape}{
- <-> ssub * $fam-$sty/$alias/$replace
-}{}
-
-END_SSUB_ALIAS
- }
- $fdseries->{$shape} = 1;
- }
- }
- }
-
- my %seen;
- while (my ($series, $nfssseries) = each %{$nfss_mapping}) {
- if (exists $data->{$series}) {
- for my $shape (keys %{$data->{$series}}) {
- $seen{$nfssseries}{$shape} = 1;
- }
- }
- }
-
- print {$FD} "\n% ---- Extra 'ssub' rules to map 'bx' to 'b' ----\n\n";
- for my $shape (keys %{$seen{b}}) {
- if (!exists $seen{bx}{$shape}) {
- print {$FD} <<"END_SSUB_BX";
-\\DeclareFontShape{$enc}{$fam-$sty}{bx}{$shape}{
- <-> ssub * $fam-$sty/b/$shape
-}{}
-
-END_SSUB_BX
- }
- }
-
- print {$FD} "\\endinput\n";
- close $FD;
-
- return;
-}
-
-
-############################################################################
-
-
-package Log;
-
-# --------------------------------------------------------------------------
-# Constructor: creates new Log object, writing to $logfile.
-# --------------------------------------------------------------------------
-sub new {
- my ($class, $filename) = @_;
-
- if (-e $filename) {
- print "[WARNING] File '$filename' already exists;\n" .
- " appending new log data to end.\n";
- }
- open my $log, '>>', $filename
- or die "$0: cannot create '$filename': $!";
-
- return bless $log, $class;
-}
-
-
-# --------------------------------------------------------------------------
-# Writes a message to the log file.
-# --------------------------------------------------------------------------
-sub log {
- my ($self, $msg) = @_;
-
- print {$self} $msg;
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Closes the logfile associated with this Log object.
-# --------------------------------------------------------------------------
-sub close {
- my $self = shift;
-
- close $self;
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Logs the command line options.
-# --------------------------------------------------------------------------
-sub log_options {
- my $self = shift;
-
- print {$self} <<"END_ARGUMENTS";
-
-
-############################################################################
-
-
-@{[ POSIX::strftime("[%F %T]", localtime time) ]} $0, version $VERSION
-
-Command was:
-
- "$ARGV{cmdline}"
-
-----------------------------------------------------------------------------
-
-I'm using the following options:
-
- encoding(s): @{[ join ', ', @{$ARGV{encoding}} ]}
- NFSS: $ARGV{nfss} @{[ $ARGV{nfss} eq 'rm' ? '(serif)'
- : $ARGV{nfss} eq 'sf' ? '(sanserif)'
- : $ARGV{nfss} eq 'tt' ? '(typewriter)'
- : '(unknown)'
- ]}
-
- lining: @{[ $ARGV{lining} ? 'yes' : 'no' ]}
- oldstyle: @{[ $ARGV{oldstyle} ? 'yes' : 'no' ]}
- proportional: @{[ $ARGV{proportional} ? 'yes' : 'no' ]}
- tabular: @{[ $ARGV{tabular} ? 'yes' : 'no' ]}
- ts1: @{[ $ARGV{textcomp} ? 'yes' : 'no' ]}
- smallcaps: @{[ $ARGV{smallcaps} ? 'yes' : 'no' ]}
- swash: @{[ $ARGV{swash} ? 'yes' : 'no' ]}
- titling: @{[ $ARGV{titling} ? 'yes' : 'no' ]}
- superiors: @{[ $ARGV{superiors} ? 'yes' : 'no' ]}
- inferiors: $ARGV{inferiors}
- ornaments: @{[ $ARGV{ornaments} ? 'yes' : 'no' ]}
- fractions: @{[ $ARGV{fractions} ? 'yes' : 'no' ]}
- ligatures: @{[ $ARGV{ligatures} ? 'yes' : 'no' ]}
-
- target: $ARGV{target}
- extra: $ARGV{extra}
-
- figurekern: @{[ $ARGV{figurekern} ? 'keep' : 'remove' ]}
-
- nfssweight: @{[ join q{, }, @{$ARGV{nfssweight}} ]}
- nfsswidth: @{[ join q{, }, @{$ARGV{nfsswidth}} ]}
-
- math: @{[ $ARGV{math} ? 'yes' : 'no' ]}
- mathspacing: $ARGV{mathspacing}
-
- fontname suffix: @{[ $ARGV{t1suffix} || '(none)' ]}
-
-END_ARGUMENTS
-
- if ($ARGV{fig_height} or $ARGV{fig_width}) {
- print {$self} <<"END_FIGURE_DEFAULTS";
- default figures: @{[
- $ARGV{fig_width} eq 'pnum' ? 'proportional'
- : 'tabular'
- ]} @{[
- $ARGV{fig_height} eq 'onum' ? 'oldstyle'
- : 'lining'
- ]}
-
-END_FIGURE_DEFAULTS
- }
-
- if ($ARGV{dryrun}) {
- print {$self} " DRY RUN\n\n";
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Logs command line options and the results of font info parsing.
-# --------------------------------------------------------------------------
-sub log_parsing {
- my ($self, $fontlist) = @_;
-
- print {$self} '-' x 76 . "\n\n" . "Results of font info parsing:\n";
-
- for my $font (@{$fontlist}) {
- print {$self} <<"END_PARSE_FONT";
-
- $font->{filename}
- Name: $font->{name}
- Family: $font->{family}
- Subfamily: $font->{subfamily}
- Weight: $font->{weight} ($font->{weight_class})
- Width: $font->{width} ($font->{width_class})
- Shape: $font->{shape} @{[ $font->{is_smallcaps}
- ? 'smallcaps' : '' ]}
- Size: $font->{minsize}-$font->{maxsize}
- Features: @{[ join q(, ), sort keys %{$font->{feature}} ]}
-END_PARSE_FONT
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Logs the mapping of NFSS codes to weights and widths.
-# --------------------------------------------------------------------------
-sub log_nfss_mapping {
- my ($self, $nfss_mapping) = @_;
-
- print {$self} "\n" . '-' x 76 . "\n\nNFSS mappings:\n\n";
- for my $weight (Attr::get_all_nfss_weights()) {
- printf {$self} " %-3s => %s\n",
- $weight || 'm',
- $nfss_mapping->{weight}{$weight}[0] || '';
- }
- printf {$self} "\n";
- for my $width (Attr::get_all_nfss_widths()) {
- printf {$self} " %-3s => %s\n",
- $width || 'm',
- $nfss_mapping->{width}{$width}[0] || '';
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Logs all fonts we're going to create.
-# --------------------------------------------------------------------------
-sub log_worklist {
- my ($self, $worklist) = @_;
-
- my @workitems
- = sort { $a->{font}{filename} cmp $b->{font}{filename}
- || $a->{encoding} cmp $b->{encoding}
- || $a->{figurestyle} cmp $b->{figurestyle}
- }
- @{$worklist};
-
- my $prevfn = q{};
- for my $workitem (@workitems) {
- if ($prevfn ne $workitem->{font}{filename}) {
- print {$self} <<"END_FONTINFO";
-
- ------------------------------------------------------------------------
-
- $workitem->{font}{filename}
-
- Generating these encodings, figure styles and shapes:
-
- ENC STYLE SHAPE FEATURES USED
-
-END_FONTINFO
- }
- printf {$self} " %-3s %-4s %-4s %s\n",
- $workitem->{encoding},
- $workitem->{figurestyle},
- $workitem->{fdshape},
- join(q{, }, @{$workitem->{features}});
- $prevfn = $workitem->{font}{filename};
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Logs all generated otftotfm commands.
-# --------------------------------------------------------------------------
-sub log_commands {
- my ($self, $commandlist) = @_;
-
- print {$self} "\n\n";
- print {$self} join "\n\n", @{$commandlist};
- print {$self} "\n";
-
- return;
-}
-
-
-############################################################################
-
-
-package Options;
-
-my $USAGE =<<'END_USAGE';
-
-'autoinst' is a wrapper around Eddie Kohler's TypeTools
-(http://www.lcdf.org/type/), for installing OpenType fonts in LaTeX.
-
-Usage: autoinst [options] font[s]
-
-Possible options:
- -encoding=ENC[,ENC]* Specify text encoding(s) (default: OT1,LY1,T1)
-
- -(no)lining Toggle creation of lining digits
- -(no)oldstyle Toggle creation of oldstyle digits
- -(no)proportional Toggle creation of proportional digits
- -(no)tabular Toggle creation of tabular digits
- -(no)ts1 Toggle creation of TS1 fonts
- -(no)smallcaps Toggle creation of smallcaps
- -(no)swash Toggle creation of swash
- -(no)titling Toggle creation of titling
- -(no)superiors Toggle creation of fonts with superior characters
- -noinferiors
- -inferiors=[none|auto|subs|sinf|dnom]
- Use this style for subscripts (see docs)
- -(no)ornaments Toggle creation of ornament fonts
- -(no)fractions Toggle creation of fonts with digits for fractions
- -(no)ligatures Toggle manual addition of f-ligatures to font
-
- -serif Install font as serif font
- -sanserif Install font as sanserif font
- -typewriter Install font as typewriter font
-
- -defaultlining
- -defaultoldstyle Specify which figure style should be
- -defaulttabular considered 'default' for this font; see docs
- -defaultproportional
-
- -extra="EXTRA" Add EXTRA to the otftotfm command for all fonts
- -target="DIRECTORY" Install files into specified TEXMF tree
- -vendor="VENDOR" Only used for naming directories
- -typeface="TYPEFACE" Only used for naming directories
-
- -(no)figurekern Keep or remove kerns between tabular figures
-
- -nfssweight=XX=YYYY Map the "XX" NFSS code to the "YYYY" weight
- -nfsswidth=XX=YYYY Map the "XX" NFSS code to the "YYYY" width
-
- -help Print this text and exit
- -doc Print the complete documentation and exit
- -dryrun Don't generate fonts, only log what would be done
- -logfile="FILE" Write log to "FILE" (default: <fontfamily>.log)
- -verbose Print more data to log file
- -version Print version number and exit
-
- -math Generate basic math fonts
- -mathspacing=AMOUNT Letterspace the math fonts by AMOUNT/1000 em
-
- -t1suffix=SUFFIX Add SUFFIX to name of generated pfb fonts
-
- font[s] The fonts (.otf or .ttf format) to install.
-
-Please report any bugs or suggestions to <marcpenninga@gmail.com>.
-END_USAGE
-
-# Default values for the command-line arguments.
-%ARGV = (
- encoding => 'OT1,LY1,T1',
- textcomp => '2', # 0 = no, 1 = yes, 2 = ('T1' ? yes : no)
- lining => '1', # 0 = no, 1 = yes
- oldstyle => '1', # 0 = no, 1 = yes
- proportional => '1', # 0 = no, 1 = yes
- tabular => '1', # 0 = no, 1 = yes
- smallcaps => '1', # 0 = no, 1 = yes
- swash => '1', # 0 = no, 1 = yes
- titling => '1', # 0 = no, 1 = yes
- superiors => '1', # 0 = no, 1 = yes
- inferiors => 'none', # values: none, auto, subs, sinf, dnom
- ornaments => '1', # 0 = no, 1 = yes
- fractions => '0', # 0 = no, 1 = yes
- ligatures => '2', # 0 = no, 1 = yes, 2 = ('tt' ? no : yes)
- nfss => '',
- fig_height => '',
- fig_width => '',
- extra => '',
- target => '',
- vendor => 'lcdftools',
- typeface => '',
- dryrun => '0', # 0 = no, 1 = yes
- logfile => '',
- figurekern => '1', # 0 = no, 1 = yes
- verbose => 0,
- nfsswidth => [],
- nfssweight => [],
- math => 0,
- mathspacing => 0,
- t1suffix => 'none',
-);
-
-
-# --------------------------------------------------------------------------
-# Parses the command-line options and removes these from @ARGV.
-# --------------------------------------------------------------------------
-sub parse_options {
- $ARGV{cmdline} = join ' ', ($0, @ARGV);
-
- Getopt::Long::GetOptions(
- 'help|?' => sub { print $USAGE; exit },
- 'version' => sub { exit },
- 'doc' => sub { Pod::Usage::pod2usage(-verbose => 2) },
- 'encoding=s' => \$ARGV{encoding},
- 'ts1!' => \$ARGV{textcomp},
- 'lining!' => \$ARGV{lining},
- 'oldstyle!' => \$ARGV{oldstyle},
- 'proportional!' => \$ARGV{proportional},
- 'tabular!' => \$ARGV{tabular},
- 'smallcaps!' => \$ARGV{smallcaps},
- 'swash!' => \$ARGV{swash},
- 'titling!' => \$ARGV{titling},
- 'superiors!' => \$ARGV{superiors},
- 'noinferiors' => sub { $ARGV{inferiors} = 'none' },
- 'inferiors:s' => \$ARGV{inferiors},
- 'ornaments!' => \$ARGV{ornaments},
- 'fractions!' => \$ARGV{fractions},
- 'ligatures!' => \$ARGV{ligatures},
- 'serif' => sub { $ARGV{nfss} = 'rm' },
- 'sanserif' => sub { $ARGV{nfss} = 'sf' },
- 'typewriter' => sub { $ARGV{nfss} = 'tt' },
- 'defaultlining' => sub { $ARGV{fig_height} = 'lnum' },
- 'defaultoldstyle' => sub { $ARGV{fig_height} = 'onum' },
- 'defaulttabular' => sub { $ARGV{fig_width} = 'tnum' },
- 'defaultproportional' => sub { $ARGV{fig_width} = 'pnum' },
- 'extra=s' => \$ARGV{extra},
- 'target=s' => \$ARGV{target},
- 'vendor=s' => \$ARGV{vendor},
- 'typeface=s' => \$ARGV{typeface},
- 'dryrun' => \$ARGV{dryrun},
- 'figurekern!' => \$ARGV{figurekern},
- 'logfile=s' => \$ARGV{logfile},
- 'verbose+' => \$ARGV{verbose},
- 'nfssweight=s%' => sub {
- my ($ignored, $key, $values) = @_;
- $key = lc $key;
- push @{$ARGV{nfssweight}},
- "$key=$values";
- my @values = split m/,/, lc $values;
- $key = q{} if $key eq 'm';
- Attr::set_weight($key, @values);
- $ARGV{$key} = 'user-defined';
- },
- 'nfsswidth=s%' => sub {
- my ($ignored, $key, $values) = @_;
- $key = lc $key;
- my @values = split m/,/, lc $values;
- push @{$ARGV{nfsswidth}},
- "$key=$values";
- $key = q{} if $key eq 'm';
- Attr::set_width($key, @values);
- $ARGV{$key} = 'user-defined';
- },
- 'math!' => \$ARGV{math},
- 'mathspacing=i' => \$ARGV{mathspacing},
- 't1suffix:s' => \$ARGV{t1suffix},
- )
- or die "$USAGE";
-
- if (!@ARGV) {
- Pod::Usage::pod2usage(
- -msg => '[ERROR] No font files given, nothing to do!',
- -verbose => 1);
- }
-
- return;
-}
-
-
-############################################################################
-
-
-package Otftotfm;
-
-# --------------------------------------------------------------------------
-# Returns a string with all "directory" options for otftotfm set.
-# Also creates directories that don't exist yet.
-# --------------------------------------------------------------------------
-sub get_targetdirs {
- my ($family, $fontlist) = @_;
-
- my %has_fonttype = map { ($_->{fonttype} => 1) } @{$fontlist};
-
- my @filetypes = qw(tfm vf);
- if ($has_fonttype{opentype}) { push @filetypes, qw(type1) }
- if ($has_fonttype{truetype}) { push @filetypes, qw(truetype) }
-
- my %dir = map { ( $_ => File::Spec->catdir(
- $ARGV{target},
- 'fonts',
- $_,
- $ARGV{vendor},
- $ARGV{typeface} || $family) )
- }
- @filetypes;
-
- $dir{$_}
- = File::Spec->catdir(
- $ARGV{target}, 'fonts', $_, 'dvips', $ARGV{typeface} || $family)
- for qw(enc map);
-
- File::Path::make_path(values %dir) unless $ARGV{dryrun};
-
- my $result
- = join q{ },
- map { qq(--${_}-directory="$dir{$_}") }
- @filetypes;
- $result .= qq( --encoding-directory="$dir{enc}" --map-file=")
- . File::Spec->catfile($dir{map}, "$family.map")
- . '"';
-
- return $result;
-}
-
-
-# The official names for various coding schemes.
-my %SCHEME = (
- OT1 => 'TEX TEXT',
- OML => 'TEX MATH ITALIC',
- T1 => 'EXTENDED TEX FONT ENCODING - LATIN',
- TS1 => 'TEX TEXT COMPANION SYMBOLS 1---TS1',
- LY1 => 'TEX TYPEWRITER AND WINDOWS ANSI',
- LGR => 'GREEK FONT ENCODING - LGR',
- T2A => 'TEX CYRILLIC FONT ENCODING - T2A',
- T2B => 'TEX CYRILLIC FONT ENCODING - T2B',
- T2C => 'TEX CYRILLIC FONT ENCODING - T2C',
- T3 => 'TEX IPA ENCODING',
- TS3 => 'TEX IPA SYMBOL ENCODING',
-);
-
-# --------------------------------------------------------------------------
-# Generates a command for otftotfm from a work item.
-# --------------------------------------------------------------------------
-sub create_command {
- my ($workitem, $targetdirs) = @_;
-
- my $want_ligkerns
- = ( $ARGV{ligatures} == 1 )
- || Util::any( map { $_ eq 'liga' } @{$workitem->{features}} );
-
- return join q( ), 'otftotfm',
- '--automatic',
- "--encoding=$workitem->{enc_file}",
- $targetdirs,
- '--no-updmap',
- '--force',
- ($SCHEME{$workitem->{encoding}}
- ? qq(--coding-scheme="$SCHEME{$workitem->{encoding}}")
- : q()),
- (map { "--feature=$_" } @{$workitem->{features}}),
- ($want_ligkerns
- ? ( '--ligkern="f i =: fi"',
- '--ligkern="f l =: fl"',
- '--ligkern="f f =: ff"',
- '--ligkern="ff i =: ffi"',
- '--ligkern="ff l =: ffl"' )
- : q()),
- Tables::get_extra($workitem->{figurestyle}),
- Tables::get_extra($workitem->{style}),
- $ARGV{extra},
- qq("$workitem->{font}{filename}"),
- $workitem->{fontname},
- ;
-}
-
-
-# --------------------------------------------------------------------------
-# Executes all commands.
-# --------------------------------------------------------------------------
-sub run_commands {
- my ($commandlist, $family, $log) = @_;
-
- my $oops = 0;
- $| = 1; # turn on autoflush, to make a poor man's progress bar
- print "[INFO] Generating fonts for $family ";
- for my $command (@{$commandlist}) {
- print '.';
- open my $otftotfm, '-|', "$command 2>&1"
- or die "could not fork(): $!";
- my $msgs = do { local $/; <$otftotfm> };
- close $otftotfm
- or do {
- warn "\n$command\n\n$msgs\n";
- $log->log("\n$command\n\n$msgs\n");
- $oops = 1;
- };
- }
- print "\n";
- $| = 0;
- if ($oops) {
- warn <<"END_OTFTOTFM_WARNING";
-[ERROR] One or more calls to 'otftotfm' returned a non-zero status code;
- please check the messages above and in the log file.
-END_OTFTOTFM_WARNING
- }
-
- return;
-}
-
-
-############################################################################
-
-
-package Tables;
-
-=begin Comment
-
- The %STYLE table is used in deciding which font styles
- (normal, small caps, swash or textcomp) to generate.
-
- Each key in this table names a style; the corresponding value
- is an anonymous hash with several key/value pairs:
- code An anonymous hash with three possible keys:
- 'n' -> the NFSS code to use for this variant shape
- if the 'basic shape' is upright;
- 'it' -> the NFSS code to use for this variant shape
- if the 'basic shape' is italic
- 'sl' -> the NFSS code to use for this variant shape
- if the 'basic shape' is slanted (aka oblique);
- If any entry is missing, the corresponding version
- of this variant style will not be built.
- reqd A list of required OpenType features;
- this style is built if the font supports at least *one*
- of these features.
- nice A list of optional OpenType features;
- these are used if the font supports them, but don't
- prevent this style from being built when missing.
- extra Extra options passed to otftotfm when creating this style.
- name A string added to the name of the generated font,
- to make it unique.
-
- Textcomp is treated as a 'style' even though it is technically
- an encoding; that is just the easiest way to do things.
-
-=end Comment
-
-=cut
-
-my %STYLE = (
- normal => {
- code => { n => 'n', it => 'it', sl => 'sl' },
- reqd => [],
- nice => [],
- extra => '',
- name => '',
- },
- smallcaps => {
- code => { n => 'sc', it => 'scit', sl => 'scsl' },
- reqd => [ 'smcp' ],
- nice => [],
- extra => '--unicoding="germandbls =: SSsmall" --unicoding="ff =: FFsmall" --unicoding="fi =: FIsmall" --unicoding="ffi =: FFIsmall" --unicoding="fl =: FLsmall" --unicoding="ffl =: FFLsmall"',
- name => 'sc',
- },
- swash => {
- code => { n => 'nw', it => 'sw' },
- reqd => [ 'swsh' ],
- nice => [ 'dlig' ],
- extra => '--include-alternates="*.swash"',
- name => 'swash',
- },
- textcomp => {
- code => { n => 'n', it => 'it', sl => 'sl' },
- reqd => [],
- nice => [ 'onum' ],
- extra => '',
- name => '',
- },
- math => {
- code => { n => 'n', it => 'it', sl => 'sl' },
- reqd => [],
- nice => [ 'onum' ],
- extra => '--math-spacing=127',
- name => '',
- },
-);
-
-=begin Comment
-
- The %FIGURESTYLE table is used in deciding which figure styles to generate.
- Each figure style (lining, oldstyle, tabular, proportional, superior,
- inferior etc.) becomes a separate font family. We also treat Ornaments
- as a figure style here; that's just the easiest way to handle them.
-
- Each key in this table names a figure style; the corresponding
- value is an anonymous hash with four key/value pairs:
- reqd A list of required OpenType features; this style is built
- if the font supports *all* these features.
- nice A list of optional OpenType features;
- these are used if the font supports them, but don't
- prevent this style from being built when missing.
- extra Extra options passed to otftotfm when creating this style.
- style An anonymous array of 'variant' styles to build with
- this figure style.
-
- The 'reqd' and 'nice' subtables for the TLF, LF, TOsF and OsF styles
- are empty; these are filled in at run time, depending on
- which figure style is default for the current font.
-
- The 'reqd' subtable for the Inf style is also empty; this may be filled
- with 'subs', 'sinf' or 'dnom' depending on the -inferiors options.
-
-=end Comment
-
-=cut
-
-my %FIGURESTYLE = (
- TLF => {
- reqd => [],
- nice => [ 'kern', 'liga' ],
- extra => '',
- styles => [ qw(normal smallcaps swash textcomp math) ],
- },
- LF => {
- reqd => [],
- nice => [ 'kern', 'liga' ],
- extra => '',
- styles => [ qw(normal smallcaps swash textcomp math) ],
- },
- TOsF => {
- reqd => [],
- nice => [ 'kern', 'liga' ],
- extra => '',
- styles => [ qw(normal smallcaps swash textcomp math) ],
- },
- OsF => {
- reqd => [],
- nice => [ 'kern', 'liga' ],
- extra => '',
- styles => [ qw(normal smallcaps swash textcomp math) ],
- },
- Sup => {
- reqd => [ 'sups' ],
- nice => [],
- extra => '--ligkern="* {KL} *"',
- styles => [ 'normal' ],
- },
- Inf => {
- reqd => [],
- nice => [],
- extra => '--ligkern="* {KL} *"',
- styles => [ 'normal' ],
- },
- Numr => {
- reqd => [ 'numr'],
- nice => [],
- extra => '--ligkern="* {KL} *"',
- styles => [ 'normal' ],
- },
- Dnom => {
- reqd => [ 'dnom' ],
- nice => [],
- extra => '--ligkern="* {KL} *"',
- styles => [ 'normal' ],
- },
- Titl => {
- reqd => [ 'titl' ],
- nice => [ 'kern', 'liga' ],
- extra => '',
- styles => [ 'normal' ],
- },
- Orn => {
- reqd => [ 'ornm' ],
- nice => [],
- extra => '--ligkern="* {KL} *"',
- styles => [ 'normal' ],
- },
-);
-
-
-# --------------------------------------------------------------------------
-# Getter; returns a list of all known figure styles.
-# --------------------------------------------------------------------------
-sub get_all_figurestyles {
- return keys %FIGURESTYLE;
-}
-
-
-# --------------------------------------------------------------------------
-# Getter; returns all styles to generate for the given figure style.
-# --------------------------------------------------------------------------
-sub get_styles {
- my $figurestyle = shift;
-
- return grep { defined $STYLE{$_} }
- @{$FIGURESTYLE{$figurestyle}{styles}};
-}
-
-
-# --------------------------------------------------------------------------
-# Getter; returns a list of req'd features for the given (figure) style.
-# --------------------------------------------------------------------------
-sub get_reqd_features {
- my $what = shift;
-
- my $result = $FIGURESTYLE{$what}{reqd} // $STYLE{$what}{reqd} // [];
-
- return @{$result};
-}
-
-
-# --------------------------------------------------------------------------
-# Getter; returns a list of add'l features for the given (figure) style.
-# --------------------------------------------------------------------------
-sub get_nice_features {
- my $what = shift;
-
- my $result = $FIGURESTYLE{$what}{nice} // $STYLE{$what}{nice} // [];
-
- return @{$result};
-}
-
-
-# --------------------------------------------------------------------------
-# Getter; returns a list of all features for the given (figure) style.
-# --------------------------------------------------------------------------
-sub get_features {
- my $what = shift;
-
- return ( get_reqd_features($what), get_nice_features($what) );
-}
-
-
-# --------------------------------------------------------------------------
-# Getter; returns the name of the given style.
-# --------------------------------------------------------------------------
-sub get_name {
- my $what = shift;
-
- return $STYLE{$what}{name} // '';
-}
-
-
-# --------------------------------------------------------------------------
-# Getter; returns the 'extra' arguments for the given (figure) style.
-# --------------------------------------------------------------------------
-sub get_extra {
- my $what = shift;
-
- return $FIGURESTYLE{$what}{extra} // $STYLE{$what}{extra} // '';
-}
-
-
-# --------------------------------------------------------------------------
-# Getter; returns the NFSS code for the given style and 'basic' shape.
-# --------------------------------------------------------------------------
-sub get_fdshape {
- my ($style, $basicshape) = @_;
-
- return $STYLE{$style}{code}{$basicshape};
-}
-
-
-# --------------------------------------------------------------------------
-# Processes the command-line options. This is split into a number
-# of smaller steps, that each process a group of related options.
-# --------------------------------------------------------------------------
-sub process_options {
- process_styles_options();
- process_encoding_options();
- process_target_options();
- process_output_options();
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Processes all options that select or deselect styles.
-# --------------------------------------------------------------------------
-sub process_styles_options {
- delete $STYLE{smallcaps} unless $ARGV{smallcaps};
- delete $STYLE{swash} unless $ARGV{swash};
-
- delete $FIGURESTYLE{Titl} unless $ARGV{titling};
- delete $FIGURESTYLE{Sup} unless $ARGV{superiors};
- delete $FIGURESTYLE{Orn} unless $ARGV{ornaments};
- delete @FIGURESTYLE{qw(Numr Dnom)} unless $ARGV{fractions};
- $ARGV{inferiors} ||= 'auto';
- if ($ARGV{inferiors} eq 'none') { delete $FIGURESTYLE{Inf} }
- elsif ($ARGV{inferiors} eq 'auto') { $FIGURESTYLE{Inf}{reqd} = ['auto'] }
- elsif ($ARGV{inferiors} eq 'subs') { $FIGURESTYLE{Inf}{reqd} = ['subs'] }
- elsif ($ARGV{inferiors} eq 'sinf') { $FIGURESTYLE{Inf}{reqd} = ['sinf'] }
- elsif ($ARGV{inferiors} eq 'dnom') { $FIGURESTYLE{Inf}{reqd} = ['dnom'] }
- else {
- # Apparently we mistook the first argument (font name) for
- # an optional argument to -inferiors; let's undo that.
- unshift @ARGV, $ARGV{inferiors};
- $ARGV{inferiors} = 'auto';
- $FIGURESTYLE{Inf}{reqd} = ['auto'];
- }
-
- # Fix the %FIGURESTYLE table to take 'default' figure styles into account.
- if ($ARGV{fig_height} eq 'onum') {
- push @{$FIGURESTYLE{TLF}{reqd}}, 'lnum';
- push @{$FIGURESTYLE{LF}{reqd}}, 'lnum';
- push @{$FIGURESTYLE{TOsF}{nice}}, 'onum';
- push @{$FIGURESTYLE{OsF}{nice}}, 'onum';
- }
- else {
- push @{$FIGURESTYLE{TLF}{nice}}, 'lnum';
- push @{$FIGURESTYLE{LF}{nice}}, 'lnum';
- push @{$FIGURESTYLE{TOsF}{reqd}}, 'onum';
- push @{$FIGURESTYLE{OsF}{reqd}}, 'onum';
- }
-
- if ($ARGV{fig_width} eq 'pnum') {
- push @{$FIGURESTYLE{TLF}{reqd}}, 'tnum';
- push @{$FIGURESTYLE{TOsF}{reqd}}, 'tnum';
- push @{$FIGURESTYLE{LF}{nice}}, 'pnum';
- push @{$FIGURESTYLE{OsF}{nice}}, 'pnum';
- }
- else {
- push @{$FIGURESTYLE{TLF}{nice}}, 'tnum';
- push @{$FIGURESTYLE{TOsF}{nice}}, 'tnum';
- push @{$FIGURESTYLE{LF}{reqd}}, 'pnum';
- push @{$FIGURESTYLE{OsF}{reqd}}, 'pnum';
- }
-
- delete @FIGURESTYLE{qw(LF TLF)} unless $ARGV{lining};
- delete @FIGURESTYLE{qw(OsF TOsF)} unless $ARGV{oldstyle};
- delete @FIGURESTYLE{qw(LF OsF)} unless $ARGV{proportional};
- delete @FIGURESTYLE{qw(TLF TOsF)} unless $ARGV{tabular};
-
- if (!$ARGV{figurekern}) {
- my @digits = qw(zero one two three four five six seven eight nine);
- my $tkern
- = join ' ', map { my $left = $_;
- map { qq(--ligkern="$left {} $_") } @digits
- }
- @digits;
-
- $FIGURESTYLE{TLF}{extra} = $tkern;
- $FIGURESTYLE{TOsF}{extra} = $tkern;
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Processes the options for selecting encodings.
-# --------------------------------------------------------------------------
-sub process_encoding_options {
-
- # All specified encodings should either be built-in,
- # or have an accompanying .enc file in the current directory.
- $ARGV{encoding} =~ s/\s+//xmsg;
- my @encodings = split /,/, $ARGV{encoding};
- for my $enc (@encodings) {
- if ($enc !~ m/\A(OT1|T1|TS1|LY1|LGR|T2[ABC]|T3|TS3)\z/xmsi) {
- my $try = $enc;
- $try .= '.enc' if $try !~ m/[.]enc\z/xms;
- if (!-e $try) {
- die "[ERROR] No .enc file found for '$enc'";
- }
- }
- }
- my @textencodings = grep { $_ !~ m/TS1/xmsi } @encodings;
- $ARGV{encoding} = \@textencodings;
-
- # TS1-encoded fonts are generated if:
- # - the user explicitly asked for TS1, or
- # - the text encodings contain T1 and the user didn't turn off TS1
- if ($ARGV{textcomp} == 1
- or ($ARGV{textcomp} >= 1
- and grep { uc $_ eq 'T1' } @{$ARGV{encoding}})) {
- $ARGV{textcomp} = 1;
- }
- else {
- delete $STYLE{textcomp};
- }
-
- if ($ARGV{math}) {
- if (!( grep { $_ eq 'OT1' } @{$ARGV{encoding}} )) {
- $ARGV{encoding} = [ 'OT1', @{$ARGV{encoding}} ];
- }
- }
- else {
- delete $STYLE{math}
- }
-
- if ($ARGV{mathspacing}) {
- if (defined $STYLE{math}{extra}) {
- $STYLE{math}{extra} .= " --letterspacing=$ARGV{mathspacing}";
- }
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Processes the options related to the target TEXMF directory.
-# --------------------------------------------------------------------------
-sub process_target_options{
-
- my $localtarget = File::Spec->catdir( Cwd::getcwd(), 'autoinst_output' );
- if (!$ARGV{target}) {
- my $is_windows_os = ( $^O =~ /^MSWin/i );
- my $kpsepath = $is_windows_os
- ? eval { qx( kpsewhich -expand-var=\$TEXMFLOCAL;\$TEXMFHOME ) }
- : eval { qx( kpsewhich -expand-var='\$TEXMFLOCAL:\$TEXMFHOME' ) }
- ;
- if (!$kpsepath) {
- warn <<"END_WARNING_KPSEWHICH";
-[WARNING] Call to "kpsewhich" failed.
- Maybe your TeX system doesn't use the kpathsea library?
-
- Consider using the "-target" command line option
- to specify a TEXMF tree where autoinst should install all files.
-END_WARNING_KPSEWHICH
- }
- else {
- my $pathsep = $is_windows_os ? ';' : ':';
- for my $dir ( split m/$pathsep/xms, substr $kpsepath, 0, -1 ) {
- if (-w $dir) { $ARGV{target} = $dir; last }
- if (-e $dir) { next }
- my $par = File::Spec->catdir( $dir, File::Spec->updir() );
- if (-w $par) { $ARGV{target} = $dir; last }
- }
- }
- }
-
- if (!$ARGV{target}) {
- $ARGV{target} = $localtarget;
- warn <<"END_WARNING_DUMPING_FILES";
-[WARNING] No user-writable TEXMF-tree found!
-
- I'm putting all generated files in "$ARGV{target}".
-
- Please install these files into a suitable TEXMF directory,
- update the filename database and run 'updmap' (or similar);
- see your TeX installation's documentation.
-END_WARNING_DUMPING_FILES
- }
-
- if ($ARGV{target} =~ m/\s/xms) {
- warn <<"END_WARNING_SPACES_IN_PATHS";
-[WARNING] The pathname of your target directory contains spaces:
- "$ARGV{target}"
- If you experience any problems, try re-running autoinst
- on a target directory without spaces in its name.
-END_WARNING_SPACES_IN_PATHS
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Processes the output related options.
-# --------------------------------------------------------------------------
-sub process_output_options{
- # If the user gave -t1suffix *without* value as the last option,
- # Getopt::Long may mistake the next argument (a font filename)
- # for the value of -t1suffix; we take care of this case
- # by testing whether the value refers to an existing file
- # and repairing things if necessary.
- if (-e $ARGV{t1suffix}) {
- unshift @ARGV, $ARGV{t1suffix};
- $ARGV{t1suffix} = '';
- }
-
- $ARGV{t1suffix} ||= 'PS';
-
- if ($ARGV{t1suffix} eq 'none') {
- $ARGV{t1suffix} = '';
- }
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Processes command line options with font family-specific defaults.
-# --------------------------------------------------------------------------
-sub process_family_dependent_options {
- my $fontlist = shift;
-
- if (!$ARGV{nfss}) {
- $ARGV{nfss} = $fontlist->[0]{nfss};
- }
- # If the user didn't explicitly say anything about ligatures,
- # activate them unless the font is a typewriter font.
- if ($ARGV{ligatures} == 2 and $ARGV{nfss} eq 'tt') {
- $ARGV{ligatures} = 0;
- }
-
- # We can only handle the '-inferiors=auto' option now;
- # since we need to know which inferior figures this font supports,
- # we have to do the font info parsing first.
- if ($ARGV{inferiors} eq 'auto') {
- choose_inferiors($fontlist);
- }
-
- $ARGV{logfile} ||= sprintf "%s.log", lc $fontlist->[0]{family};
-
- return;
-}
-
-
-# --------------------------------------------------------------------------
-# Processes the -inferiors=auto option, given a list of fonts.
-# We look through these fonts and simply pick the very first
-# type of inferiors we see (we assume that this type is supported
-# by all fonts in this family).
-# --------------------------------------------------------------------------
-sub choose_inferiors {
- my $fontlist = shift;
-
- FONT:
- for my $font (@{$fontlist}) {
- for my $inf (qw(sinf subs dnom)) {
- if (exists $font->{feature}{$inf}) {
- $ARGV{inferiors} = "auto (-> $inf)";
- $FIGURESTYLE{Inf}{reqd} = [$inf];
- last FONT;
- }
- }
- }
-
- # If we didn't find any inferior figures,
- # delete the 'Inf' entry from the %FIGURESTYLE table
- # to indicate we don't want to generate this style.
- if ($ARGV{inferiors} eq 'auto') {
- delete $FIGURESTYLE{Inf};
- $ARGV{inferiors} = "auto (-> none)";
- }
-
- return;
-}
-
-
-############################################################################
-
-
-package Util;
-
-# --------------------------------------------------------------------------
-# Tests if all given predicates are true.
-# --------------------------------------------------------------------------
-sub all {
- return !( grep { !$_ } @_ );
-}
-
-
-# --------------------------------------------------------------------------
-# Tests if any of the given predicates are true.
-# --------------------------------------------------------------------------
-sub any {
- return grep { $_ } @_;
-}
-
-
-# --------------------------------------------------------------------------
-# Walks a (nested) dictionary and returns a lookup table with all keys.
-# --------------------------------------------------------------------------
-sub get_keys {
- my $dict = shift;
- my $seen = shift // {};
-
- while (my ($k, $v) = each %$dict) {
- $seen->{$k} = 1;
- get_keys($v, $seen) if ref $v eq 'HASH';
- }
-
- return $seen;
-}
-
-
-# --------------------------------------------------------------------------
-# Sorts its arguments so that longer strings come before shorter ones.
-# --------------------------------------------------------------------------
-sub sort_desc_length {
- return reverse sort { length($a) <=> length($b) } @_;
-}
-
-
-############################################################################
-
-
-package Work;
-
-
-# --------------------------------------------------------------------------
-# Decides which styles, figure styles and encodings to generate
-# for the given fonts.
-# --------------------------------------------------------------------------
-sub generate_worklist {
- my $fontlist = shift;
-
- my @worklist = map { { font => $_ } } @{$fontlist};
-
- # 1. For each font, decide which figure styles should be created.
- @worklist = map { expand_figurestyles($_) } @worklist;
-
- # 2. For each (font, figure style) combination,
- # decide which styles should be created.
- @worklist = map { expand_styles($_) } @worklist;
-
- # 3. For each (font, figure style, style) combination,
- # decide which encodings should be created.
- @worklist = map { expand_encodings($_) } @worklist;
-
- # 4. Some miscellaneous finishing touches.
- @worklist = grep { $_ } map { cleanup($_) } @worklist;
-
- return @worklist;
-}
-
-
-# --------------------------------------------------------------------------
-# Determines which figure styles to create for the given work item.
-# A figure style is created if the current font contains all of
-# the 'reqd' features for this figure style.
-# Returns a list of new work items, one for each figure style.
-# --------------------------------------------------------------------------
-sub expand_figurestyles {
- my $workitem = shift;
-
- my $font = $workitem->{font};
-
- my @results;
- for my $figurestyle (Tables::get_all_figurestyles()) {
- my @reqd = Tables::get_reqd_features($figurestyle);
- my $has_all_reqd = Util::all(map { $font->{feature}{$_} } @reqd);
- if ($has_all_reqd) {
- my %new_workitem = %{$workitem};
- $new_workitem{figurestyle} = $figurestyle;
- push @results, \%new_workitem;
- }
- }
-
- return @results;
-}
-
-
-# --------------------------------------------------------------------------
-# Determines which styles to create for the given work item.
-# A style is created if the current font has at least one of the
-# 'reqd' features for this style, or if there are no 'reqd' features.
-# Returns a list of new work items, one for each style.
-# --------------------------------------------------------------------------
-sub expand_styles {
- my $workitem = shift;
-
- my ($font, $figurestyle) = @{$workitem}{qw(font figurestyle)};
-
- my @results;
- for my $style (Tables::get_styles($figurestyle)) {
- my @reqd = Tables::get_reqd_features($style);
- my $has_any_reqd
- = (scalar @reqd == 0)
- || Util::any(map { $font->{feature}{$_} } @reqd);
- if ($has_any_reqd) {
- my %new_workitem = %{$workitem};
- $new_workitem{style} = $style;
- push @results, \%new_workitem;
- }
- }
-
- return @results;
-}
-
-
-# --------------------------------------------------------------------------
-# Determines which encodings to use for the given work item;
-# returns a list of new work items, one for each encoding.
-# --------------------------------------------------------------------------
-sub expand_encodings {
- my $workitem = shift;
-
- my ($font, $figurestyle, $style)
- = @{$workitem}{qw(font figurestyle style)};
- my @encodings = $style eq 'textcomp' ? qw(ts1)
- : $figurestyle eq 'Orn' ? qw(ly1)
- : $style eq 'math' ? qw(oml)
- : @{$ARGV{encoding}}
- ;
-
- my @results;
- for my $encoding (@encodings) {
- my %new_workitem = %{$workitem};
- $new_workitem{encoding} = $encoding;
- push @results, \%new_workitem;
- }
-
- return @results;
-}
-
-
-# --------------------------------------------------------------------------
-# Adds some miscellaneous finishing touches to the given work item.
-# --------------------------------------------------------------------------
-sub cleanup {
- my $workitem = shift;
-
- my ($font, $figurestyle, $style)
- = @{$workitem}{qw(font figurestyle style)};
-
- # Don't generate smallcaps version of TS1-encoded fonts,
- # as these contain the same glyphs as the regular version.
- if ($font->{is_smallcaps}) {
- if ($style eq 'textcomp') {
- return;
- }
- else {
- $style = 'smallcaps';
- }
- }
-
- # Look up the NFSS code for this font's shape...
- $workitem->{fdshape} = Tables::get_fdshape($style, $font->{basicshape});
- # ... but drop this workitem if we shouldn't generate this shape.
- if (!defined $workitem->{fdshape}) {
- return;
- }
-
- # Figure out whether the encoding option refers to a custom encoding file
- # in the current directory, or to the name of one of our standard
- # encodings. In the latter case, we add the 'fontools_' prefix.
- my $try = $workitem->{encoding};
- $try .= '.enc' if $try !~ m/[.]enc\z/xms;
- if (-e $try) {
- $workitem->{enc_file} = $try;
- }
- else {
- ($workitem->{enc_file} = $workitem->{encoding})
- =~ s{ \A (OT1|OML|T1|TS1|LY1|LGR|T2[ABC]|T3|TS3) \z }
- {fontools_\L$1\E}xmsi;
- }
-
- # Ornaments have no text encoding, and don't need kerning and ligatures.
- if ($figurestyle eq 'Orn') {
- $workitem->{encoding} = 'u';
- }
-
- # Compile list of OpenType features to use with this font.
- my %feature = map { ($_ => 1) }
- grep { $font->{feature}{$_} }
- ( Tables::get_features($figurestyle),
- Tables::get_features($style) );
- if ($feature{lnum} && $feature{onum}) {
- delete $feature{lnum};
- }
-
- # Don't create ligatures if the user doesn't want them.
- delete $feature{liga} if !$ARGV{ligatures};
-
- # Don't create kerns and ligatures for symbol or math fonts.
- delete @feature{qw(kern liga)}
- if $workitem->{encoding} =~ m/\A ( TS\d | OML ) \z/xmsi;
-
- $workitem->{features} = [ sort keys %feature ];
-
- # Generate a unique name for this font.
- $workitem->{fontname}
- = join '-', grep { $_ } $font->{name},
- lc $figurestyle,
- lc Tables::get_name($style),
- lc $workitem->{encoding};
-
- $workitem->{encoding} = uc $workitem->{encoding};
-
- return $workitem;
-}
-
-
-# --------------------------------------------------------------------------
-# Modify the font and file names of all generated .pfb files.
-# --------------------------------------------------------------------------
-sub modify_fontnames {
- my ($family, $fontlist) = @_;
-
- my %has_fonttype = map { ($_->{fonttype} => 1) } @{$fontlist};
- return unless $has_fonttype{opentype};
-
- my $pfb_dir = File::Spec->catdir(
- $ARGV{target},
- 'fonts',
- 'type1',
- $ARGV{vendor},
- $ARGV{typeface} || $family);
-
- # The otftotfm-generated map file refers to the original otf files;
- # we need to change this to use our name-modified Type1 fonts instead.
- my $mapfile = File::Spec->catfile(
- $ARGV{target},
- 'fonts',
- 'map',
- 'dvips',
- $ARGV{typeface} || $family,
- $family . '.map');
- open my $map, '<', $mapfile
- or die "[ERROR] Cannot open '$mapfile' for reading";
- my $mapdata = do { local $/; <$map> };
- close $map;
-
- my $NOTICE = 'Converted to Type1 by autoinst/cfftot1; '
- . 'for use with pdfTeX only! ';
-
- my $newfam = $family . $ARGV{t1suffix};
-
- for my $font (@{$fontlist}) {
- next unless $font->{fonttype} eq 'opentype';
-
- my $full_family = $font->{originalfamily};
- if (index($full_family, $family) > -1) {
- $full_family = $family;
- }
- else {
- while ($full_family =~ m/[ ]/xms) {
- (my $no_space = $full_family) =~ s/[ ]+//xmsg;
- last if $no_space eq $family;
- $full_family =~ s/[ ]\S*\z//xms;
- }
- $full_family ||= $family;
- }
- my $newfullfam = $full_family . q( ) . $ARGV{t1suffix};
-
- my $newname = $font->{name};
- if ($newname =~ m/$family/xms) {
- $newname =~ s/$family/$newfam/xms;
- }
- else {
- $newname =~ s/(.+?)(-|\z)/$1$ARGV{t1suffix$2}/xms;
- }
-
- for my $suffix (q(), q(LCDFJ)) {
- my $oldfn = File::Spec->catfile(
- $pfb_dir, $font->{name} . $suffix . '.pfb');
- my $newfn = File::Spec->catfile(
- $pfb_dir, $newname . $suffix . '.pfb');
-
- next unless -e $oldfn;
- if ($suffix eq 'LCDFJ' and -z $oldfn) {
- unlink $oldfn;
- next;
- }
-
- my $cmd = qq(t1disasm "$oldfn");
- open my $t1disasm, '-|:raw', $cmd
- or die "[ERROR] Could not fork(): $!";
- my @pfbdata = readline $t1disasm;
- close $t1disasm
- or die "[ERROR] '$cmd' failed";
-
- for (@pfbdata) {
- if (m/%!PS-AdobeFont-1.0:[ ] | \/FontName[ ]/xms) {
- s/$font->{name}/$newname/;
- }
- if (m/\/Notice[ ]/xms) {
- s/[(]/($NOTICE/xms;
- }
- if (m/\/FullName[ ] | \/FamilyName[ ]/xms) {
- s/$full_family/$newfullfam/
- or s/(.+?)(-|\z)/$1$ARGV{t1suffix}$2/;
- }
- }
-
- $cmd = qq(t1asm --pfb >"$newfn");
- open my $t1asm, '|-:raw', $cmd
- or die "[ERROR] Could not fork(): $!";
- print {$t1asm} @pfbdata;
- close $t1asm
- or die "[ERROR] '$cmd' failed";
-
- unlink $oldfn unless $oldfn eq $newfn;
-
- $mapdata =~ s/$font->{name}$suffix.pfb/$newname$suffix.pfb/g;
- }
- }
-
- open $map, '>', $mapfile
- or die "[ERROR] Cannot open '$mapfile' for writing";
- print {$map} $mapdata;
- close $map;
-
- return;
-}
-
-
-############################################################################
-
-
-package main;
-
-if ($RUNNING_AS_MAIN) {
- main();
-}
-
-
-__END__
-
-
-############################################################################
-
-
- To create the documentation:
-
- pod2man --center='Marc Penninga' --release='fontools' --section=1 \
- autoinst - | groff -Tps -man - | ps2pdf - autoinst.pdf
-
-
-=pod
-
-=head1 NAME
-
-autoinst - wrapper around the F<LCDF TypeTools>,
-for installing and using OpenType fonts in LaTeX.
-
-
-=head1 SYNOPSIS
-
-B<autoinst> I<-help>
-
-B<autoinst> [I<options>] B<font(s)>
-
-
-=head1 DESCRIPTION
-
-Eddie Kohler's I<LCDF TypeTools> are superb tools for installing
-OpenType fonts in LaTeX, but they can be hard to use:
-they need many, often long, command lines
-and don't generate the F<fd> and F<sty> files LaTeX needs.
-B<autoinst> simplifies the use of the I<TypeTools> for font installation
-by generating and executing all commands for I<otftotfm>
-and by creating and installing all necessary F<fd> and F<sty> files.
-
-Given a family of font files (in F<otf> or F<ttf> format),
-B<autoinst> will create several LaTeX font families:
-
-=over 2
-
-=over 3
-
-=item -
-
-Four text families (with lining and oldstyle digits,
-each in both tabular and proportional variants),
-all with the following shapes:
-
-=over 2
-
-=over 8
-
-=item I<n>
-
-Roman (i.e., upright) text
-
-=item I<it>, I<sl>
-
-Italic and slanted (sometimes called oblique) text
-
-=item I<sc>
-
-Small caps
-
-=item I<scit>, I<scsl>
-
-Italic and slanted small caps
-
-=item I<sw>
-
-Swash
-
-=item I<nw>
-
-`Upright swash'
-
-=back
-
-=back
-
-=item -
-
-For each T1-encoded text family:
-a family of TS1-encoded symbol fonts, in roman, italic and slanted shapes.
-
-=item -
-
-Families with superiors, inferiors, numerators and denominators,
-in roman, italic and slanted shapes.
-
-=item -
-
-Families with `Titling' characters;
-these `... replace the default glyphs
-with corresponding forms designed specifically for titling.
-These may be all-capital and/or larger on the body,
-and adjusted for viewing at larger sizes'
-(according to the OpenType Specification).
-
-=item -
-
-An ornament family, also in roman, italic and slanted shapes.
-
-=back
-
-=back
-
-Of course, if your fonts don't contain italics, oldstyle digits, small caps
-etc., the corresponding shapes and families are not created.
-In addition, the creation of most families and shapes can be controlled
-by the user (see L</COMMAND-LINE OPTIONS> below).
-
-These families use the I<FontPro> project's naming scheme:
-I<< <FontFamily>-<Suffix> >>, where I<< <Suffix> >> is:
-
-=over 8
-
-=item I<LF>
-
-proportional (i.e., figures have varying widths) lining figures
-
-=item I<TLF>
-
-tabular (i.e., all figures have the same width) lining figures
-
-=item I<OsF>
-
-proportional oldstyle figures
-
-=item I<TOsF>
-
-tabular oldstyle figures
-
-=item I<Sup>
-
-superior characters (note that most fonts have only an incomplete set of
-superior characters: digits, some punctuation and the letters I<abdeilmnorst>;
-normal forms are used for other characters)
-
-=item I<Inf>
-
-inferior characters; usually only digits and some punctuation,
-normal forms for other characters
-
-=item I<Titl>
-
-Titling characters; see above
-
-=item I<Orn>
-
-ornaments
-
-=item I<Numr>, I<Dnom>
-
-numerators and denominators
-
-=back
-
-The individual fonts are named I<< <FontName>-<suffix>-<shape>-<enc> >>,
-where I<< <suffix> >> is the same as above (but in lowercase),
-I<< <shape> >> is either empty, `sc' or `swash',
-and I<< <enc> >> is the encoding (also in lowercase).
-A typical name in this scheme would be `FiraSans-Light-osf-sc-ly1'.
-
-
-=head2 Using the fonts in your LaTeX documents
-
-B<autoinst> generates a style file for using the fonts in LaTeX documents,
-named F<< <FontFamily>.sty >>. This style file also takes care of loading
-the F<fontenc> and F<textcomp> packages.
-To use the fonts, add the command C<<< \usepackage{I<< <FontFamily> >>} >>>
-to the preamble of your document.
-
-This style file defines a number of options:
-
-=over 4
-
-=item C<mainfont>
-
-Redefine C<\familydefault> to make this font the main font
-for the document.
-This is a no-op if the font is installed as a serif font;
-but if the font is installed as a sanserif or typewriter font,
-this option saves you from having to redefine C<\familydefault>
-yourself.
-
-=item C<lining>, C<oldstyle>, C<tabular>, C<proportional>
-
-Choose which figure style to use.
-The defaults are `oldstyle' and `proportional' (if available).
-
-=item C<<< scale=I<< <number> >> >>>, C<scale=MatchLowercase>
-
-Scale the font by a factor of I<< <number> >>.
-E.g., to increase the size of the font by 5%, use
-C<<< \usepackage[scale=1.05]{I<< <FontFamily> >>} >>>.
-The special value C<MatchLowercase> may be used to scale the font
-so that its x-height matches that of the previously active font
-(which is usually Computer Modern, unless you have loaded another
-font package before this one).
-The name C<scaled> may be used as a synonym for C<scale>.
-
-=item C<medium>, C<book>, C<text>, C<normal>, C<regular>
-
-Select the weight that LaTeX will use as the `regular' weight.
-
-=item C<heavy>, C<black>, C<extrabold>, C<demibold>, C<semibold>, C<bold>
-
-Select the weight that LaTeX will use as the `bold' weight.
-
-=back
-
-The last two groups of options will only work if
-you have the F<mweights> package installed.
-The default here is not to change LaTeX's default,
-i.e. use the `m' and `b' weights.
-
-The style file will also try to load the F<fontaxes> package
-(on CTAN), which gives easy access to various font shapes and styles.
-Using the machinery set up by F<fontaxes>, the generated style file
-defines a number of commands (which take the text to be typeset as argument)
-and declarations (which don't take arguments, but affect all text up to
-the end of the current group) to access titling, superior and inferior
-characters:
-
-
- DECLARATION COMMAND SHORT FORM OF COMMAND
-
- \tlshape \texttitling \texttl
- \supfigures \textsuperior \textsup, \textsu
- \inffigures \textinferior \textinf, \textin
-
-
-In addition, the C<\swshape> and C<\textsw> commands are redefined to place
-swash on F<fontaxes>' secondary shape axis (F<fontaxes> places it on the
-primary shape axis) to make them behave properly when nested, so that
-C<\swshape\upshape> will give upright swash.
-
-There are no commands for accessing the numerator and denominator
-fonts; these can be selected using F<fontaxes>' standard commands,
-e.g., C<\fontfigurestyle{numerator}\selectfont>.
-
-These commands are only generated for existing shapes and number styles;
-no commands are generated for shapes and styles that don't exist,
-or whose generation was turned off by the user.
-Also these commands are built on top of F<fontaxes>, so if that package
-cannot be found, you're limited to using the lower-level commands from
-standard NFSS (C<\fontfamily>, C<\fontseries>, C<\fontshape> etc.).
-
-By default, B<autoinst> generates text fonts with OT1, LY1 and T1
-encodings, and the generated style files use T1 as the default text encoding.
-Other encodings can be chosen using the I<-encoding> option
-(see L</COMMAND-LINE OPTIONS> below).
-
-
-=head2 Maths
-
-This is an experimental feature; B<USE AT YOUR OWN RISK!>
-Test the results thoroughly before using them in real documents,
-and be warned that future versions of B<autoinst> may introduce
-incompatible changes.
-
-The I<-math> option tells B<autoinst> to generate basic math fonts.
-When enabled, the generated style file defines a few extra options
-to access these math fonts:
-
-=over 4
-
-=item C<math>
-
-Use these fonts for the maths in your document.
-
-=item C<mathlining>, C<matholdstyle>
-
-Choose which figure style to use in maths.
-The default is `mathlining'.
-
-=item C<mathcal>
-
-Use the swash characters from your fonts as the C<\mathcal> alphabet.
-(This option only exists if your fonts actually contain swash characters
-and a C<swsh> feature to access them).
-
-=item C<nomathgreek>
-
-Don't redeclare greek letters in math.
-
-=item C<<< math-style=I<< <style> >> >>>
-
-Choose the `math style' to use.
-With C<math-style=ISO>, all latin and greek letters in math are italic;
-with C<math-style=TeX> (the default), uppercase greek is upright;
-with C<math-style=french>, all greek as well as uppercase latin is upright;
-and with C<math-style=upright> all letters are upright.
-
-=back
-
-Note that this `math' option only changes digits, latin and greek letters,
-plus a few basic punctuation characters; all other mathematical symbols,
-operators, delimiters etc. are left as they were before.
-If you don't want to use TeX's default versions of those symbols,
-load another math package (such as F<mathdesign> or F<newtxmath>)
-before loading the B<autoinst>-generated style file.
-
-Finally, note that B<autoinst> doesn't check if your fonts actually contains
-all of the required characters;
-it just assumes that they do and sets up the style file accordingly.
-Even if your fonts contain greek, characters such as C<\varepsilon>
-may be missing.
-You may also find that some glyphs I<are> present in your fonts,
-but don't work well in equations or don't match with other symbols;
-edit the generated style file to remove the declarations of
-these offending characters.
-Once again: test the results before using them!
-If the characters themselves are fine but spaced too tightly,
-you may try increasing the side bearings in math fonts with
-the I<-mathspacing> option (see below), e.g. C<-mathspacing=50>.
-
-
-=head2 NFSS codes
-
-LaTeX's New Font Selection System (NFSS)
-identifies fonts by a combination of family,
-series (the concatenation of weight and width), shape and size.
-B<autoinst> parses the font's metadata to determine these parameters.
-When this fails (usually because the font family contains uncommon weights,
-widths or shapes),
-B<autoinst> ends up with different fonts having the I<same> values
-for these font parameters; such fonts cannot be used in NFSS,
-since there's no way distinguish them.
-When B<autoinst> detects such a situation, it will print an error message
-and abort.
-If that happens, either rerun B<autoinst> on a smaller set of fonts,
-or add the missing widths, weights and shapes to the tables C<WIDTH>,
-C<WEIGHT> and C<SHAPE> in the source code.
-Please also send a bug report (see L<AUTHOR> below).
-
-The mapping of shapes to NFSS codes is done using the following table:
-
- SHAPE CODE
- -------------------------------- ----
- Roman, Upright n
- Italic it
- Oblique, Slant(ed), Incline(d) sl
-
-(I<Exception:> Adobe Silentium Pro contains two Roman shapes;
-we map the first of these to `n', for the second one we (ab)use the `it' code
-as this family doesn't contain an Italic shape.)
-
-For weights and widths, B<autoinst> tries to the standard NFSS codes
-(ul, el, l, sl, m, sb, b, eb and ub for weights;
-uc, ec, c, sc, m, sx, x, ex and ux for widths)
-as much as possible.
-Of course, not all 81 combinations of these NFSS weights and widths will map
-to existing fonts;
-and conversely it may not be possible to assign every existing font
-a unique code in a sane way (especially for the weights, some font families
-offer more choices or finer granularity than NFSS's codes can handle;
-e.g., Fira Sans contains fifteen(!) different weights,
-including an additional `Medium' weight between Regular and Semibold).
-Therefore every font is also assigned a `series' name that is simply
-the concatenation of its weight and width
-(after expanding any abbreviations and converting to lowercase).
-A font with `Cond' width and `Ultra' weight will then be known
-as `ultrablackcondensed'.
-
-The exact mapping between fonts and NFSS codes can be found
-in the generated F<fd> files and in the log file
-(pro tip: run B<autoinst> with the I<-dryrun> option
-to check the chosen mapping beforehand).
-The I<-nfssweight> and I<-nfsswidth> command-line options can be used
-to finetune the mapping between NFSS codes and fonts.
-
-To access specific weights or widths,
-one can always use the C<\fontseries> command with the full series name
-(i.e., C<\fontseries{demibold}\selectfont>).
-
-
-=head2 Ornaments
-
-Ornament fonts are regular LY1-encoded fonts, with a number of
-`regular' characters replaced by ornament glyphs.
-The OpenType specification says that fonts should only put their
-ornaments in place of the lowercase ASCII letters, but some fonts
-put them in other positions (such as those of the digits) as well.
-
-Ornaments can be accessed like C<{\ornaments a}> and
-C<{\ornaments\char"61}>, or equivalently
-C<\textornaments{a}> and C<\textornaments{\char"61}>.
-To see which ornaments a font contains (and at which positions),
-run LaTeX on the file F<nfssfont.tex> (which is included in any
-standard LaTeX installation), supply the name of the ornament font
-(i.e., C<GaramondLibre-Regular-orn-u>) and give the command C<\table\bye>;
-this will create a table of all glyphs in that font.
-
-Note that versions of B<autoinst> up to 20200428 handled ornaments
-differently, and fonts and style files generated by those versions
-are not compatible with files generated by newer versions.
-
-
-=head1 WARNINGS AND CAVEATS
-
-=head2 OpenType fonts and licensing issues
-
-Since F<pdfTeX> cannot subset otf-flavoured OpenType fonts,
-I<otftotfm> will convert such fonts to Type1 (pfb) format.
-However, many fonts (at least those licensed under the SIL Open Font License)
-do not allow distributing such converted versions under their original name.
-
-To meet these licensing requirements, B<autoinst> provides
-a C<-t1suffix> command-line option that appends
-a (user-defined) suffix to the names (both filename and internal font name)
-of all generated Type1 fonts; see L</COMMAND-LINE OPTIONS> below.
-
-
-=head2 A note for MiKTeX users
-
-Automatically installing the fonts into a suitable TEXMF tree
-(as B<autoinst> tries to do by default) only works for TeX-installations
-that use the F<kpathsea> library; with TeX distributions that implement
-their own directory searching (such as MiKTeX), B<autoinst> will complain
-that it cannot find the F<kpsewhich> program and move all generated files
-into a subdirectory C<./autoinst_output/> of the current directory.
-If you use such a TeX distribution, you should either move these files
-to their correct destinations by hand, or use the I<-target> option
-(see L</COMMAND-LINE OPTIONS> below) to manually specify a TEXMF tree.
-
-Also, some OpenType fonts contain so many kerning pairs that the resulting
-F<pl> and F<vpl> files are too big for MiKTeX's F<pltotf> and F<vptovf>;
-the versions that come with W32TeX (F<http://www.w32tex.org>)
-and TeXLive (F<http://tug.org/texlive>) don't seem to have this problem.
-
-
-=head2 A note for MacTeX users
-
-By default, B<autoinst> will try to install all generated files into
-the $TEXMFLOCAL tree; when this directory isn't user-writable,
-it will use the $TEXMFHOME tree instead. Unfortunately, MacTeX's version
-of C<updmap-sys> doesn't search in $TEXMFHOME,
-and hence MacTeX will not find the new fonts.
-
-To remedy this, either run B<autoinst> as root (so that it can install
-everything into $TEXMFLOCAL) or manually run C<updmap -user> to tell
-TeX about the files in $TEXMFHOME.
-The latter option does, however, have some caveats;
-see F<https://tug.org/texlive/scripts-sys-user.html>.
-
-
-
-=head1 COMMAND-LINE OPTIONS
-
-B<autoinst> tries hard to do The Right Thing (TM) by default,
-so you usually won't need these options;
-but most aspects of its operation can be fine-tuned if you want to.
-
-You may use either one or two dashes before options,
-and option names may be shortened to a unique prefix
-(e.g., B<-encoding> may be abbreviated to B<-enc> or even B<-en>,
-but B<-e> is ambiguous (it may mean either B<-encoding> or B<-extra>)).
-
-
-=head2 General options
-
-=over 4
-
-=item B<-help>
-
-Print a (relatively) short help text and exit.
-
-=item B<-dryrun>
-
-Don't generate output; just parse input fonts and write
-a log file saying what B<autoinst> would have done.
-
-=item B<-verbose>
-
-Add more details to the log file.
-
-=item B<-version>
-
-Print B<autoinst>'s version number and exit.
-
-=back
-
-
-=head2 Font creation options
-
-=over 4
-
-=item B<-encoding>=I<encoding[,encoding]>
-
-Generate the specified encoding(s) for the text fonts.
-Multiple encodings may be specified as a comma-separated list
-(without spaces!); the default choice of encodings is `OT1,LY1,T1'.
-
-For each specified encoding XYZ, B<autoinst> will first see if there is
-an encoding file F<XYZ.enc> in the current directory, and if found it will
-use that; otherwise it will use one of its built-in encoding files.
-Currently B<autoinst> comes with support for the OT1, T1/TS1, LY1, LGR,
-T2A/B/C and T3/TS3 encodings.
-(These files are called F<fontools_ot1.enc> etc. to avoid name clashes
-with other packages; the `fontools_' prefix may be omitted.)
-
-=item B<-ts1>/B<-nots1>
-
-Control the creation of TS1-encoded fonts. The default is B<-ts1>
-if the text encodings (see I<-encoding> above) include T1,
-B<-nots1> otherwise.
-
-=item B<-lining>/B<-nolining>
-
-Control the creation of fonts with lining figures. The default is
-B<-lining>.
-
-=item B<-oldstyle>/B<-nooldstyle>
-
-Control the creation of fonts with oldstyle figures. The default is
-B<-oldstyle>.
-
-=item B<-proportional>/B<-noproportional>
-
-Control the creation of fonts with proportional figures. The default is
-B<-proportional>.
-
-=item B<-tabular>/B<-notabular>
-
-Control the creation of fonts with tabular figures. The default is
-B<-tabular>.
-
-=item B<-smallcaps>/B<-nosmallcaps>
-
-Control the creation of small caps fonts. The default is
-B<-smallcaps>.
-
-=item B<-swash>/B<-noswash>
-
-Control the creation of swash fonts. The default is B<-swash>.
-
-=item B<-titling>/B<-notitling>
-
-Control the creation of titling families. The default is B<-titling>.
-
-=item B<-superiors>/B<-nosuperiors>
-
-Control the creation of fonts with superior characters.
-The default is B<-superiors>.
-
-=item B<-noinferiors>
-
-=item B<-inferiors> [ = B<none> | B<auto> | B<subs> | B<sinf> | B<dnom> ]
-
-The OpenType standard defines several kinds of digits that might be used
-as inferiors or subscripts: `Subscripts' (OpenType feature `subs'),
-`Scientific Inferiors' ('sinf'), and `Denominators' ('dnom').
-This option allows the user to determine which of these styles B<autoinst>
-should use for the inferior characters.
-Alternatively, the value `auto' tells B<autoinst> to use the first value
-in `sinf', `subs' or `dnom' that is supported by the font.
-Saying just B<-inferiors> is equivalent to B<-inferiors=auto>;
-otherwise the default is B<-noinferiors>.
-
-I<< If you specify a style of inferiors that isn't present in the font,
-B<autoinst> will fall back to its default behaviour of not creating fonts
-with inferiors at all; it won't try to substitute one of the other styles. >>
-
-=item B<-fractions>/B<-nofractions>
-
-Control the creation of fonts with numerators and denominators.
-The default is B<-nofractions>.
-
-=item B<-ligatures>/B<-noligatures>
-
-Some fonts create glyphs for the standard f-ligatures (ff, fi, fl, ffi, ffl),
-but don't provide a `liga' feature to access these.
-This option tells B<autoinst> to add extra C<LIGKERN> rules to
-the generated fonts to enable the use of these ligatures.
-The default is B<-ligatures>, except for typewriter fonts.
-
-Specify B<-noligatures> to disable generation of ligatures even for fonts
-that do contain a `liga' feature.
-
-=item B<-ornaments>/B<-noornaments>
-
-Control the creation of ornament fonts. The default is B<-ornaments>.
-
-=item B<-serif>/B<-sanserif>/B<-typewriter>
-
-Install the font as a serif, sanserif or typewriter font, respectively.
-This changes how you access the font in LaTeX:
-with C<\rmfamily>/C<\textrm>, C<\sffamily>/C<\textsf>
-or C<\ttfamily>/C<\texttt>.
-
-Installing the font as a typewriter font will cause two further changes:
-it will - by default - turn off the use of f-ligatures
-(though this can be overridden with the I<-ligatures> option),
-and it will disable hyphenation for this font.
-This latter effect cannot be re-enabled in B<autoinst>;
-if you want typewriter text to be hyphenated, use the F<hyphenat> package.
-
-If none of these options is specified, B<autoinst> tries to guess:
-if the font's filename contains the string `mono'
-or if the field C<isFixedPitch> in the font's I<post> table is True,
-it will select B<-typewriter>;
-else if the filename contains `sans' it will select B<-sanserif>;
-otherwise it will opt for B<-serif>.
-
-=item B<-math>
-
-Tells B<autoinst> to create basic math fonts (see above).
-
-=item B<-mathspacing>=I<amount>
-
-Letterspace each character in the math fonts by I<amount> units,
-where 1000 units equal one em.
-In my opinion, many text fonts benefit from letterspacing by 50 to 100 units
-when used in maths; some fonts need even more. Use your own judgement!
-
-=back
-
-
-=head2 Output options
-
-=over 4
-
-=item B<-t1suffix> [ = I<SUFFIX> ]
-
-Tell B<autoinst> to modify the font names of all generated Type1-fonts,
-by adding I<SUFFIX> to the family name.
-If you use this option without specifying a I<SUFFIX> value,
-B<autoinst> will use the value ``PS''.
-The default behaviour when this option is not given
-is to not modify font names at all.
-
-See also L</OpenType fonts and licensing issues> above.
-
-=item B<-target>=I<DIRECTORY>
-
-Install all generated files into the TEXMF tree at I<DIRECTORY>.
-
-By default, B<autoinst> searches the $TEXMFLOCAL and $TEXMFHOME trees
-and installs all files into the first user-writable TEXMF tree it finds.
-If B<autoinst> cannot find such a user-writable directory
-(which shouldn't happen, since $TEXMFHOME is supposed to be user-writable)
-it will print a warning message and put all files into the subdirectory
-C<./autoinst_output/> of the current directory.
-It's then up to the user to move the generated files to a better location
-and update all relevant databases
-(usually by calling F<texhash> and F<updmap>).
-
-=item B<-vendor>=I<VENDOR>
-
-=item B<-typeface>=I<TYPEFACE>
-
-These options are equivalent to F<otftotfm>'s I< --vendor> and I< --typeface>
-options: they change the `vendor' and `typeface' parts of the names of the
-subdirectories in the TEXMF tree where generated files will be stored.
-The default values are `lcdftools' and the font's FontFamily name.
-These options change I<only> directory names,
-not the names of any generated files.
-
-=item B<-logfile>=I<filename>
-
-Write log data to F<filename> instead of the default F<< <fontfamily>.log >>.
-If the file already exists, B<autoinst> appends to it;
-it doesn't overwrite an existing file.
-
-=back
-
-
-=head2 Specialist options
-
-=over 4
-
-=item B<-defaultlining>/B<-defaultoldstyle>
-
-=item B<-defaulttabular>/B<-defaultproportional>
-
-Tell B<autoinst> which figure style is the current font family's default
-(i.e., which figures you get when you don't specify any OpenType features).
-
-I<Don't use these options unless you are certain you need them!>
-They are only needed for fonts that don't provide OpenType features
-for their default figure style; and even in that case,
-B<autoinst>'s default values (B<-defaultlining> and B<-defaulttabular>)
-are usually correct.
-
-=item B<-nfssweight>=I<code>=I<weight>
-
-=item B<-nfsswidth>=I<code>=I<width>
-
-Map the NFSS code I<code> to the given weight or width,
-overriding the built-in tables.
-Each of these options may be given multiple times,
-to override more than one NFSS code.
-Example: to map the `ul' code to the `Thin' weight,
-use C<-nfssweight=ul=thin>.
-To inhibit the use of the `ul' code completely,
-use C<-nfssweight=ul=>.
-
-=item B<-extra>=I<extra>
-
-Append I<extra> as extra options to the command lines for I<otftotfm>.
-To prevent I<extra> from accidentily being interpreted as options
-to B<autoinst>, it should be properly quoted.
-
-=item B<-nofigurekern>
-
-Some fonts provide kerning pairs for tabular figures.
-This is very probably not what you want
-(e.g., numbers in tables won't line up exactly).
-This option adds extra I< --ligkern> options
-to the commands for I<otftotfm> to suppress such kerns.
-Note that this option leads to very long commands (it adds
-one hundred I< --ligkern> options), which may cause problems on some systems.
-
-=back
-
-
-=head1 SEE ALSO
-
-Eddie Kohler's B<TypeTools> and B<T1Utils> (F<http://www.lcdf.org/type>).
-
-B<Perl> can be obtained from F<http://www.perl.org>;
-it is included in most Linux distributions.
-For Windows, try ActivePerl (F<http://www.activestate.com>)
-or Strawberry Perl (F<http://strawberryperl.com>).
-
-B<LuaTeX> (F<http://www.luatex.org>) and
-B<XeTeX> (F<http://www.tug.org/xetex>)
-are Unicode-aware TeX engines that can use OpenType fonts directly,
-without any (La)TeX-specific support files.
-
-The B<FontPro> project (F<https://github.com/sebschub/FontPro>)
-offers very complete LaTeX support (even for typesetting maths) for
-Adobe's Minion Pro, Myriad Pro and Cronos Pro font families.
-
-
-=head1 AUTHOR
-
-Marc Penninga (F<marcpenninga@gmail.com>)
-
-When sending a bug report, please give as much relevant information as
-possible; this usually includes (but may not be limited to) the log file
-(please add the I<-verbose> command-line option, for extra info).
-If you see any error messages, please include these I<verbatim>;
-don't paraphase.
-
-
-=head1 COPYRIGHT
-
-Copyright (C) 2005-2020 Marc Penninga.
-
-
-=head1 LICENSE
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published
-by the Free Software Foundation, either version 2 of the License,
-or (at your option) any later version.
-A copy of the text of the GNU General Public License is included in
-the I<fontools> distribution; see the file F<GPLv2.txt>.
-
-
-=head1 DISCLAIMER
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-
-=head1 VERSION
-
-This document describes B<autoinst> version 20201218.
-
-
-=head1 RECENT CHANGES
-
-(See the source for the full story, all the way back to 2005.)
-
-=over 12
-
-=item I<2020-12-18>
-
-Fixed a problem with files not being found on Windows.
-Added extra C<--unicoding> options to prevent getting
-lowercase f-ligatures in smallcaps for some buggy fonts.
-Optimized font info parsing for DTL and TypeBy font families.
-Cleaned up the code for better maintainability.
-
-=item I<2020-07-29>
-
-Some changes in the generated F<sty> and F<fd> files,
-to improve compatibility with the F<microtype> package.
-Made sure that F<pfb> fonts are always generated whenever
-the input fonts are in F<otf> format.
-Added the C<-t1suffix> command-line option,
-to modify the font and file names of those generated Type1 fonts.
-
-=item I<2020-06-19>
-
-Added the C<nomathgreek> option to generated style files.
-Reorganized the generated style files to make them more
-standards-conforming.
-
-=item I<2020-05-27>
-
-Added basic (and still somewhat experimental) math support.
-Implemented the C<scale=MatchLowercase> option value
-in the generated style files.
-`Wide' fonts are mapped to the `sx' NFSS code instead of `x',
-to cater for League Mono Variable's Wide and Extended widths.
-The generated style files now use C<\textsup> and C<\textinf>
-instead of the more cryptic C<\textsu> and C<\textin> to access
-superior and inferior characters
-(though the old forms are retained for backwards compatibility).
-
-=item I<2020-05-11>
-
-When present, use encoding files in the current working directory
-in preference of the ones that come with B<autoinst>.
-Changed the way ornament fonts are created; ornament glyphs are now
-always included in the position chosen by the font's designer.
-
-=item I<2020-04-28>
-
-Fix a bug where the first font argument would be mistaken for
-an argument to I<-inferiors>.
-
-=item I<2020-01-29>
-
-Don't create empty subdirectories in the target TEXMF tree.
-
-=back
-
-
-=begin Really_old_history
-
-=over 12
-
-=item I<2019-11-18>
-
-Fine-tuned calling of F<kpsewhich> on Windows (patch by Akira Kakuto).
-The font info parsing now also recognises numerical weights, e.g. in Museo.
-
-=item I<2019-10-29>
-
-The generated style files now use T1 as the default text encoding.
-
-=item I<2019-10-27>
-
-The mapping in F<fd> files between font series and standard NFSS attributes
-now uses the new I<alias> function instead of I<ssub> (based on code by
-Frank Mittelbach).
-The way F<otftotfm> is called was changed to work around a Perl/Windows bug;
-the old way might cause the process to hang.
-Using the I<-target> option now implies I<-noupdmap>, since choosing
-a non-standard target directory interferes with kpathsea/texhash and updmap.
-
-=item I<2019-10-01>
-
-Handle I<-target> directories with spaces in their path names.
-Tweaked messages and logs to make them more useful to the user.
-
-=item I<2019-07-12>
-
-Replaced single quotes in calls to F<otfinfo> with double quotes,
-as they caused problems on Windows 10.
-
-=item I<2019-06-25>
-
-=over 3
-
-=item -
-
-Added the I<-mergeweights> and I<-mergeshapes> options,
-and improved I<-mergewidths>.
-
-=item -
-
-Improved the parsing of fonts' widths and weights.
-
-=item -
-
-Improved the mapping of widths and weights to NFSS codes.
-
-=item -
-
-Changed logging code so that that results of font info parsing
-are always logged, even (especially!) when parsing fails.
-
-=item -
-
-Added a warning when installing fonts from multiple families.
-
-=item -
-
-Added simple recognition for sanserif and typewriter fonts.
-
-=item -
-
-Fixed error checking after calls to F<otfinfo>
-(B<autoinst> previously only checked whether C<fork()> was successful,
-not whether the actual call to F<otfinfo> worked).
-
-=item -
-
-Fixed a bug in the I<-inferiors> option;
-when used without a (supposedly optional) value,
-it would silently gobble the next option instead.
-
-=back
-
-=item I<2019-05-22>
-
-Added the I<mainfont> option to the generated F<sty> files.
-Prevented hyphenation for typewriter fonts
-(added C<\hyphenchar\font=-1> to the C<\DeclareFontFamily> declarations).
-Added the I<-version> option.
-
-=item I<2019-05-17>
-
-Changed the way the F<-ligatures> option works:
-F<-ligatures> enables f-ligatures (even without a `liga' feature),
-F<-noligatures> now disables f-ligatures (overriding a `liga' feature).
-
-=item I<2019-05-11>
-
-Separate small caps families are now also recognised when the family name
-ends with `SC' (previously B<autoinst> only looked for `SmallCaps').
-
-=item I<2019-04-22>
-
-Fixed a bug in the generation of swash shapes.
-
-=item I<2019-04-19>
-
-Fixed a bug that affected -mergesmallcaps with multiple encodings.
-
-=item I<2019-04-16>
-
-Added the <-mergesmallcaps> option, to handle cases where
-the small caps fonts are in separate font families.
-Titling shape is now treated as a separate family instead of a distinct shape;
-it is generated only for fonts with the `titl' feature.
-Only add f-ligatures to fonts when explicitly asked to (I<-ligatures>).
-
-=item I<2019-04-11>
-
-Tried to make the log file more relevant.
-Added the I<-nfssweight> and I<-nfsswidth> options,
-and finetuned the automatic mapping between fonts and NFSS codes.
-Changed the name of the generated log file to F<< <fontfamily>.log >>,
-and revived the I<-logfile> option to allow overriding this choice.
-Made I<-mergewidths> the default (instead of I<-nomergewidths>).
-
-=item I<2019-04-01>
-
-Fine-tuned the decision where to put generated files;
-in particular, create $TEXMFHOME if it doesn't already exist
-and $TEXMFLOCAL isn't user-writable.
-
-When we can't find a user-writable TEXMF tree,
-put all generated files into a subdirectory C<./autoinst_output/>
-instead of all over the current working directory.
-
-Added `auto' value to the I<inferiors> option,
-to tell B<autoinst> to use whatever inferior characters are available.
-
-=item I<2019-03-14>
-
-Overhauled the mapping of fonts (more specifically of weights and widths;
-the mapping of shapes didn't change) to NFSS codes.
-Instead of inventing our own codes to deal with every possible weight
-and width out there, we now create `long' codes based on the names
-in the font metadata.
-Then we add `ssub' rules to the F<fd> files to map the standard NFSS codes
-to our fancy names (see the section B<NFSS codes>;
-based on discussions with Frank Mittelbach and Bob Tennent).
-
-=item I<2018-08-10>
-
-Added encoding files for LGR and T2A/B/C to I<fontools>.
-
-=item I<2018-03-26>
-
-Added the I<-(no)mergewidths> option; tried to improve the documentation.
-
-=item I<2018-03-26>
-
-Added the `Text' weight and the I<-(no)mergewidths> option.
-Changed the NFSS codes for `Thin' and `Book' to `i' and `o', respectively.
-Tried to improve the documentation.
-
-=item I<2018-01-09>
-
-Added the `sl' weight for font families (such as Fira Sans) that contain both
-`Book' and `Regular' weights (reported by Bob Tennent).
-Added the `Two', `Four', `Eight' and `Hair' weights (for Fira Sans).
-
-=item I<2017-06-16>
-
-Changed the I<-inferiors> option from a binary yes-or-no choice to allow
-the user to choose one of the `subs', `sinf' and `dnom' features.
-B<autoinst> now always creates a log file.
-
-=item I<2017-03-21>
-
-Updated the F<fontools_ot1.enc> encoding file to include the `Lslash'
-and `lslash' glyphs (thanks to Bob Tennent).
-
-=item I<2015-11-22>
-
-Bugfix: LaTeX doesn't like command names with dashes in it.
-
-=item I<2015-05-13>
-
-Fixed an error message that mixed up width and weight.
-
-=item I<2014-04-04>
-
-Fixed a bug in the font info parsing code.
-
-=item I<2014-01-21>
-
-`Oblique' or `slanted' fonts are now mapped to NFSS code `sl' instead
-of `it'; added `ssub' rules to the F<fd> files to substitute slanted fonts
-for italic ones if the latter are missing. Fixed a few bugs.
-
-=item I<2014-01-03>
-
-Added the I<-dryrun> and I<-logfile> options; changed which info is logged.
-Added the I<-lining>, I<-oldstyle>, I<-tabular> and I<-proportional>
-options; the old options with those names have been renamed to
-I<-defaultlining>, I<-defaultoldstyle> etc.
-
-=item I<2013-10-31>
-
-The previous change required Perl v5.14 or newer;
-now it also works with older versions.
-
-=item I<2013-10-01>
-
-Added the I<-lining>, I<-oldstyle>, I<-tabular> and I<-proportional>
-command line options.
-
-=item I<2013-07-25>
-
-The generated F<sty> files now use the I<mweights> package instead of
-redefining C<\mddefault> and C<\bfdefault>.
-Added C<scale> as an alias for the package option C<scaled>.
-
-=item I<2013-02-06>
-
-Bugfix: the directory names for map and encoding files contained
-the `vendor' instead of the `typeface'.
-
-=item I<2013-01-03>
-
-Added extra `ssub' rules to the F<fd> files that substitute `b' for `bx'.
-Verbose mode now also prints all generated commands before they're executed.
-
-=item I<2012-10-25>
-
-Added extra `ssub' rules to the F<fd> files that substitute italic
-shapes for slanted ones.
-
-=item I<2012-09-25>
-
-Added the I<-vendor>, I<-typeface> and I<-(no)updmap> command line options.
-
-=item I<2012-07-06>
-
-Documentation update.
-
-=item I<2012-03-06>
-
-Implemented the `splitting the font family into multiple subfamilies'
-emergency strategy when font info parsing fails.
-Added recognition for a number of unusual widths, weights and shapes.
-
-=item I<2012-02-29>
-
-Fixed a bug in the font parsing code,
-where possible widths, weights and shapes where tested in the wrong order;
-this led to `ExtraLight' fonts being recognised as `Light'.
-Added recognition for `Narrow' and `Wide' widths.
-Also added the I<-(no)figurekern> command-line option.
-
-=item I<2012-02-01>
-
-Reorganised the code, and fixed some bugs in the process.
-Added the I<-target> command-line option.
-Made B<autoinst> install the F<fd> and F<sty> files in
-the same TEXMF tree as the other generated files.
-Generate OT1, T1 and LY1 encoded text fonts by default.
-Made I<-titling> a default option (instead of I<-notitling>).
-Updated the documentation.
-
-=item I<2011-06-15>
-
-Fixed the font info parsing code for some fonts that are
-too lazy to spell out `Italic' in full.
-
-=item I<2010-04-29>
-
-The I< --feature=kern> option is only used for fonts that
-contain either a I<kern> feature or a I<kern> table.
-Font feature selection commands in the F<sty> file are only
-generated for shapes and figure styles that are supported
-by the current font, and whose generation has not been
-turned off using the command-line options.
-Fixed the font info parsing to work with the Condensed fonts
-in the Minion Pro family.
-
-=item I<2010-04-23>
-
-Always provide the I< --feature=kern> option to F<otftotfm>,
-even if the font doesn't have a I<kern> feature;
-this will make F<otftotfm> use the I<kern> table if present.
-For fonts without a I<liga> feature, add I< --ligkern>
-options for the common f-ligatures to the F<otftotfm> command line,
-so that any ligatures present in the font will still be used.
-Bug fix: the generated F<sty> files now work for font families
-with names containing digits.
-
-=item I<2009-04-09>
-
-Prefixed the filenames of the included encoding files with
-I<fontools_>, to prevent name clashes with other packages.
-
-=item I<2009-04-06>
-
-A small patch to the C<get_orn> subroutine:
-it now also recognises the I<bullet.xxx> ornament glyphs
-in Adobe Kepler Pro.
-
-=item I<2007-08-07>
-
-Fixed a small bug with filename quoting on Windows.
-
-=item I<2007-07-31>
-
-Changed the tables that map weights and widths to NFSS codes:
-in some extended families, different combinations of
-weight and width were mapped to the same series.
-Added a work-around for incorrect size info in some Kepler fonts.
-Fixed a small bug in the generated commands for otftotfm
-(sometimes, the `onum' feature was included twice).
-Added encoding file for OT1 to the I<fontools> collection.
-
-=item I<2007-07-27>
-
-Two bugfixes: a closing brace was missing in the generated style file,
-and the NFSS series was formed as `width plus weight' instead of the reverse.
-
-=item I<2007-06-10>
-
-Bugfix: silently replacing \DeclareOption, \ProcessOptions and
-\ExecuteOptions with their counterparts from the xkeyval package
-caused problems for some other packages.
-
-=item I<2007-06-04>
-
-Added the I< --no-updmap> option to all generated commands for F<otftotfm>
-(except the last); this should yield a significant speed-up for large
-families (suggested by Steven E. Harris).
-Tweaked the font info parsing to work around a bug in the naming of
-some FontFont fonts, where every font is in a family of its own.
-Added the `scaled' option (including the loading of F<xkeyval>)
-to the generated style file.
-Extended the output of the I<-verbose> option.
-
-=item I<2007-02-08>
-
-Yet Another Complete Rewrite.
-The code is now much more readable and more flexible;
-the program can now handle fonts from different families,
-as well as multiple text encodings.
-Rewrote the font info parsing code to work for Arno Pro.
-
-=item I<2006-10-11>
-
-The program determines the fonts' weights, widths and shapes by parsing
-the output from C<otfinfo --info> instead of the font filename.
-This should make B<autoinst> work for non-Adobe fonts.
-Filenames with spaces now work as well.
-
-=item I<2006-08-31>
-
-Made the generated style files try to include `fontaxes.sty';
-changed the names of the generated fonts and families
-(to make the previous change possible);
-added command-line options for most font styles and shapes;
-tweaked the filename parsing code for Cronos Pro and Gill Sans Pro;
-added runtime generation of encoding vectors for ornament fonts
-(because GaramondPremier's ornament names differ from other fonts);
-changed the NFSS-code for italic small caps and titling to `scit' and `tlit'
-(to work with F<fontaxes>);
-and edited (and hopefully improved) the documentation.
-
-=item I<2005-10-03>
-
-When creating LY1, T1, OT1 or TS1 encoded fonts, the I<-coding-scheme>
-option is added to the commands for F<otftotfm>; this should make the
-generated F<pl> and F<vpl> files acceptable to I<fontinst>.
-Also elaborated the documentation somewhat and fixed a small bug.
-
-=item I<2005-09-22>
-
-Added check to see if filename parsing succeeded;
-updated the filename parsing code to cater for GaramondPremier Pro,
-Silentium Pro and some non-Adobe fonts;
-added the I<-sanserif> and I<-typewriter> options and hacked the
-style files to support using several different font families in one document.
-
-=item I<2005-09-12>
-
-Cleaned up the code (it now runs under the F<strict> and F<warnings> pragmas);
-fixed a (rather obscure) bug that occurred when creating TS1-encoded
-fonts for families with multiple optical masters and oldstyle digits;
-added the I<medium, semibold> etc. options to the style file;
-and improved the layout of the generated files.
-
-=item I<2005-08-11>
-
-The generated commands weren't actually executed, only printed...
-Also added a small hack to cater for fonts
-(such as some recent versions of MinionPro)
-that contain swash characters but don't provide a `swsh' feature.
-
-=item I<2005-08-10>
-
-Dropped the `fontname' scheme in favor of a more verbose naming scheme,
-since many filenames were still more than eight characters long anyway.
-Added F<nfssext.sty>-like commands to the generated style file.
-Changed the default encoding to LY1 and added the `inferior' shape.
-
-=item I<2005-08-01>
-
-Rewrote (and hopefully improved) the user interface;
-changed the program to by default execute the generated F<otftotfm> command
-lines rather than writing them to a file;
-added automatic determination of the `fontname' code for the font family;
-changed the NFSS code for italic small caps to `si'; added titling shapes;
-changed the generated style
-file to include an interface for the ornaments and to load Lehman's NFSS
-extensions F<nfssext.sty> if this is installed; corrected the `fontname' codes
-for OT1, T1, LY1 and user-specific encodings; extended the output generated by
-the I<-verbose> option; and rewrote and extended the documentation.
-
-=item I<2005-06-16>
-
-Did some more finetuning to the filename-parsing code.
-
-=item I<2005-05-31>
-
-Generate correct fontname for OT1-encoded fonts.
-
-=item I<2005-05-18>
-
-Tried to make the filename-parsing code a bit more robust by adding several
-weights and widths; changed the error that's displayed when filename parsing
-fails; commented the code.
-
-=item I<2005-04-29>
-
-Rewrote large parts of the code (yes it I<was> even worse).
-
-=item I<2005-04-18>
-
-Changed default text-encoding to T1, added TS1.
-
-=item I<2005-03-29>
-
-Added support for font families with multiple widths.
-
-=item I<2005-03-15>
-
-First version.
-
-=back
-
-=end Really_old_history
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/ot2kpx b/Build/source/texk/texlive/linked_scripts/fontools/ot2kpx
deleted file mode 100755
index 164fc2b1492..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fontools/ot2kpx
+++ /dev/null
@@ -1,932 +0,0 @@
-#! /usr/bin/env perl
-
-=begin COPYRIGHT
-
-----------------------------------------------------------------------------
-
- Copyright (C) 2005-2020 Marc Penninga.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation, either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to
- Free Software Foundation, Inc.,
- 59 Temple Place,
- Suite 330,
- Boston, MA 02111-1307,
- USA
-
-----------------------------------------------------------------------------
-
-=end COPYRIGHT
-
-=cut
-
-use strict;
-use warnings;
-
-use integer;
-use Getopt::Long ();
-use List::Util @List::Util::EXPORT_OK;
-use Pod::Usage;
-
-my $VERSION = "20201218";
-
-our ($NUM_GLYPHS, $UNITS_PER_EM, %kern);
-
-sub main {
- %ARGV = (
- print_func => \&print_kpx,
- );
-
- Getopt::Long::GetOptions(
- 'help|?' => sub { pod2usage(-verbose => 0) },
- 'version' => sub { print "$VERSION\n"; exit },
- 'doc' => sub { pod2usage(-verbose => 2) },
- 'afm' => sub { $ARGV{print_func} = \&print_kpx },
- 'kpx' => sub { $ARGV{print_func} = \&print_kpx },
- 'lua' => sub { $ARGV{print_func} = \&print_lua },
- ) or pod2usage(-verbose => 0);
- pod2usage(-verbose => 0) if @ARGV != 1;
-
- my %font = OTF::get_tables($ARGV[0]);
-
- $NUM_GLYPHS = unpack '@4n', $font{maxp};
- $UNITS_PER_EM = unpack '@18n', $font{head};
-
- my @glyph_name = map { sprintf "index%d", $_ } 0 .. $NUM_GLYPHS - 1;
- if (defined $font{CFF}) {
- OTF::CFF::get_glyph_names($font{CFF}, \@glyph_name);
- }
-
- if (defined $font{kern}) {
- OTF::Kern::parse_kerntable($font{kern});
- }
-
- if (defined $font{GPOS}) {
- my @lookup_list_indices
- = OTF::GPOS::get_lookup_list_indices($font{GPOS});
- my @all_lookups = OTF::GPOS::get_lookups($font{GPOS});
- my @lookups = @all_lookups[@lookup_list_indices];
- my @subtables = map { OTF::GPOS::get_subtables($_) } @lookups;
-
- for my $subtable (@subtables) {
- my $pos_format = unpack 'n', $subtable;
- if ($pos_format == 1) {
- OTF::GPOS::parse_pos_format_1($subtable);
- }
- elsif ($pos_format == 2) {
- OTF::GPOS::parse_pos_format_2($subtable);
- }
- else {
- warn "[ERROR] invalid PosFormat $pos_format ignored";
- }
- }
- }
-
- &{$ARGV{print_func}}( \%kern, \@glyph_name );
- return;
-}
-
-# ------------------------------------------------------------------------
-# Print kerning data in Adobe's KPX format
-# ------------------------------------------------------------------------
-sub print_kpx {
- my %kern = %{ shift @_ };
- my @glyph = @{ shift @_ };
-
- my $num_kernpairs = sum map { scalar keys %{$kern{$_}} } keys %kern;
- print "StartKernData\nStartKernPairs $num_kernpairs\n";
- for my $l (sort { $glyph[$a] cmp $glyph[$b] } keys %kern) {
- my $l_glyph = $glyph[$l];
- for my $r (sort { $glyph[$a] cmp $glyph[$b] } keys %{$kern{$l}}) {
- print "KPX $l_glyph $glyph[$r] ",
- "$kern{$l}{$r}\n";
- }
- }
- print "EndKernPairs\nEndKernData\n";
-}
-
-# ------------------------------------------------------------------------
-# Print kerning data as a Luatex custom font feature
-# ------------------------------------------------------------------------
-sub print_lua {
- my %kern = %{ shift @_ };
- my @glyph = @{ shift @_ };
-
- print <<'END_FEATURE_PREFIX';
-fonts.handlers.otf.addfeature {
- name = 'kern',
- type = 'kern',
- data = {
-END_FEATURE_PREFIX
-
- for my $l ( sort { $glyph[$a] cmp $glyph[$b] } keys %kern ) {
- print ' ' x 8, "[ '$glyph[$l]' ] = {";
- for my $r ( sort { $glyph[$a] cmp $glyph[$b] } keys %{$kern{$l}} ) {
- print "\n", ' ' x 12, "[ '$glyph[$r]' ] = $kern{$l}{$r},";
- }
- print " },\n";
- }
-
- print <<'END_FEATURE_POSTFIX';
- }
-}
-END_FEATURE_POSTFIX
-}
-
-########################################################################
-
-
-package OTF;
-
-#-----------------------------------------------------------------------
-# Return a hash with all tables (as strings) from the font
-#-----------------------------------------------------------------------
-sub get_tables {
- my $filename = shift;
-
- open my $fontfile, '<:raw', $filename
- or die "[ERROR] can't open $filename: $!";
- my $fontdata = do { local $/; <$fontfile> };
- close $fontfile;
-
- my ($sfnt_version, @tables) = unpack 'a4nx6/(a16)', $fontdata;
-
- die "[ERROR] $filename: unknown font type"
- unless $sfnt_version eq "\x00\x01\x00\x00"
- || $sfnt_version eq 'OTTO';
-
- my %table = map { my ($tag, $offset, $length) = unpack 'A4@8N@12N', $_;
- ($tag => substr $fontdata, $offset, $length);
- }
- @tables;
-
- return %table;
-}
-
-
-########################################################################
-
-
-package OTF::CFF;
-
-my @STANDARD_STRINGS = qw(
- .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
-);
-
-#-----------------------------------------------------------------------
-#
-#-----------------------------------------------------------------------
-sub get_glyph_names {
- my ($CFF, $glyph_name) = @_;
-
- # skip header; parse (and ignore) NAME index
- my ($rest) = _parse_index(substr $CFF, unpack '@2C', $CFF);
-
- # parse TopDict index
- ($rest, my @top_dict) = _parse_index($rest);
- if (@top_dict > 1) {
- warn "[WARNING] multiple fonts in single file not supported";
- }
- my %top_dict = _parse_dict($top_dict[0]);
- if ($NUM_GLYPHS != unpack 'n', substr($CFF, $top_dict{17}, 2)) {
- die "[ERROR] NumGlyphs different in 'maxp' and 'CFF' tables";
- }
-
- # parse String index
- ($rest, my @strings) = _parse_index($rest);
- @strings = (@STANDARD_STRINGS, @strings);
-
- my $charset = substr $CFF, $top_dict{15};
- my $format = unpack 'C', $charset;
- if ($format == 0) {
- my @codes = unpack "\@1n@{[ $NUM_GLYPHS - 1 ]}", $charset;
- @$glyph_name = @strings[0, @codes];
- }
- elsif ($format == 1) {
- my $i = 0;
- $glyph_name->[$i++] = $strings[0];
- for (my $j = 0; $i < $NUM_GLYPHS; $j++) {
- my ($first, $n_left)
- = unpack "\@@{[ 1 + 3*$j ]}nC", $charset;
- $glyph_name->[$i + $_] = $strings[$first + $_]
- for 0 .. $n_left;
- $i += 1 + $n_left;
- }
- }
- elsif ($format == 2) {
- my $i = 0;
- $glyph_name->[$i++] = $strings[0];
- for (my $j = 0; $i < $NUM_GLYPHS; $j++) {
- my ($first, $n_left)
- = unpack "\@@{[ 1 + 4*$j ]}nn", $charset;
- $glyph_name->[$i + $_] = $strings[$first + $_]
- for 0 .. $n_left;
- $i += 1 + $n_left;
- }
- }
- else {
- warn "[ERROR] invalid CharsetFormat '$format' ignored";
- }
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Parse Adobe's INDEX format (see CFF spec); return "rest" plus data array
-#-----------------------------------------------------------------------
-sub _parse_index {
- my $index = shift;
-
- my ($count, $off_size) = unpack 'nC', $index;
- my @offsets = unpack "\@3(a$off_size)@{[ $count + 1 ]}", $index;
- if ($off_size == 1) { $_ = unpack 'C', $_ for @offsets }
- elsif ($off_size == 2) { $_ = unpack 'n', $_ for @offsets }
- elsif ($off_size == 4) { $_ = unpack 'N', $_ for @offsets }
- elsif ($off_size == 3) {
- for my $offset (@offsets) {
- my @bytes = map 'C3', $offset;
- $offset = ($bytes[0] << 16) + ($bytes[1] << 8) + $bytes[2];
- }
- }
- else {
- warn "[ERROR] invalid OffSize $off_size ignored";
- }
- $_ += 2 + $off_size * ($count + 1) for @offsets;
-
- my @data;
- for my $i (0 .. $count - 1) {
- $data[$i]
- = substr $index, $offsets[$i], $offsets[$i + 1] - $offsets[$i];
- }
-
- return substr($index, $offsets[$count]), @data;
-}
-
-#-----------------------------------------------------------------------
-# Parse Adobe's DICT format (see CFF spec); return data hash
-#-----------------------------------------------------------------------
-sub _parse_dict {
- my $dict = shift;
-
- my @bytes = unpack 'C*', $dict;
- my (@operands, %dict);
- while (@bytes) {
- if (( 0 <= $bytes[0] && $bytes[0] <= 11)
- || (13 <= $bytes[0] && $bytes[0] <= 22))
- {
- my $operator = shift @bytes;
- ($dict{$operator} = join q{ }, @operands) =~ s/^\s+//xms;
- @operands = ();
- }
- elsif ($bytes[0] == 12) {
- my $operator = join q{ }, splice @bytes, 0, 2;
- ($dict{$operator} = join q{ }, @operands) =~ s/^\s+//xms;
- @operands = ();
- }
- elsif ($bytes[0] == 28
- || $bytes[0] == 29
- || $bytes[0] == 30
- || (32 <= $bytes[0] && $bytes[0] <= 254))
- {
- push @operands, _get_number(\@bytes);
- }
- else {
- warn "[ERROR] invalid byte $bytes[0] in DICT ignored";
- shift @bytes;
- }
- }
-
- return %dict;
-}
-
-#-----------------------------------------------------------------------
-# Parse Adobe's variable-length numbers (see CFF spec); shorten arg array
-#-----------------------------------------------------------------------
-sub _get_number {
- my $bytes = shift;
-
- my $b0 = shift @$bytes;
- if ($b0 == 28) {
- my ($b1, $b2) = splice @$bytes, 0, 2;
- return ($b1 << 8) | $b2;
- }
- elsif ($b0 == 29) {
- my ($b1, $b2, $b3, $b4) = splice @$bytes, 0, 4;
- return ((((($b1 << 8) + $b2) << 8) + $b3) << 8) + $b4;
- }
- elsif ($b0 == 30) {
- # Reals not implemented; just dump appropriate number of bytes
- until (($b0 & 0xf0) == 0xf0 || ($b0 & 0xf) == 0xf) {
- $b0 = shift @$bytes;
- }
- }
- elsif (32 <= $b0 && $b0 <= 246) {
- return $b0 - 139;
- }
- elsif (247 <= $b0 && $b0 <= 250) {
- my $b1 = shift @$bytes;
- return 256 * ($b0 - 247) + $b1 + 108;
- }
- elsif (251 <= $b0 && $b0 <= 254) {
- my $b1 = shift @$bytes;
- return -256 * ($b0 - 251) - $b1 - 108;
- }
-}
-
-
-########################################################################
-
-
-package OTF::GPOS;
-
-#-----------------------------------------------------------------------
-# Return list of all Lookups from the GPOS table
-#-----------------------------------------------------------------------
-sub get_lookups {
- my $GPOS = shift;
-
- my $lookup_list = substr $GPOS, unpack '@8n', $GPOS;
- my @lookup_offsets = unpack 'n/n', $lookup_list;
-
- return map { substr $lookup_list, $_ } @lookup_offsets;
-}
-
-#-----------------------------------------------------------------------
-# Return list of all LookupListIndices pointed to by 'kern' feature
-#-----------------------------------------------------------------------
-sub get_lookup_list_indices {
- my $GPOS = shift;
-
- my $feature_list = substr $GPOS, unpack '@6n', $GPOS;
- my %lookup_list_index;
- for my $feature_record (unpack 'n/(a6)', $feature_list) {
- my ($tag, $offset) = unpack 'a4n', $feature_record;
- next if $tag ne 'kern';
-
- my $feature = substr $feature_list, $offset;
- my @lookup_list_indices = unpack '@2n/n', $feature;
- $lookup_list_index{$_} = 1 for @lookup_list_indices;
- }
-
- return keys %lookup_list_index;
-}
-
-#-----------------------------------------------------------------------
-# Return list of all subtables in Lookup table
-#-----------------------------------------------------------------------
-sub get_subtables {
- my $lookup = shift;
-
- my ($lookup_type, @subtable_offsets) = unpack 'n@4n/n', $lookup;
- if ($lookup_type != 2) {
- warn "[WARNING] LookupType $lookup_type not implemented";
- return;
- }
-
- return map { substr $lookup, $_ } @subtable_offsets;
-}
-
-#-----------------------------------------------------------------------
-# Parse subtable in PairPosFormat 1, store kern pairs in global %kern
-#-----------------------------------------------------------------------
-sub parse_pos_format_1 {
- my $subtable = shift;
-
- my ($coverage_offset, $value_format_1, $value_format_2, @pair_set_offsets)
- = unpack '@2nnnn/n', $subtable;
-
- my @coverage = _get_coverage(substr $subtable, $coverage_offset);
- my @pair_sets = map { substr $subtable, $_ } @pair_set_offsets;
- if (@coverage != @pair_sets) {
- warn "[ERROR] Coverage table doesn't match PairSet table";
- return;
- }
-
- my ($record_size, $value_offset)
- = _parse_value_formats($value_format_1, $value_format_2, 2, 2);
-
- while (1) {
- my $pair_set = shift @pair_sets or last;
- my $first = shift @coverage;
-
- my @pair_value_records = unpack "n/(a$record_size)", $pair_set;
-
- for my $pair_value_record (@pair_value_records) {
- my ($second, $value)
- = unpack "n\@${value_offset}s>", $pair_value_record;
- next if $value == 0;
- $kern{$first}{$second} ||= 1000 * $value / $UNITS_PER_EM;
- }
- }
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Parse subtable in PairPosFormat 2, store kern pairs in global %kern
-#-----------------------------------------------------------------------
-sub parse_pos_format_2 {
- my $subtable = shift;
-
- my ($coverage_offset, $value_format_1, $value_format_2,
- $class_def_1, $class_def_2, $class_1_count, $class_2_count)
- = unpack '@2nnnnnnn', $subtable;
-
- my @coverage = _get_coverage(substr $subtable, $coverage_offset);
-
- my ($class_2_record_size, $value_offset)
- = _parse_value_formats($value_format_1, $value_format_2, 0, 0);
-
- my @class_1 = _get_class(substr $subtable, $class_def_1);
- my @class_2 = _get_class(substr $subtable, $class_def_2);
-
- my $class_1_record_size = $class_2_count * $class_2_record_size;
- my @class_1_records
- = unpack "\@16(a$class_1_record_size)$class_1_count", $subtable;
-
- for my $class_1 (0 .. $class_1_count - 1) {
- my $class_1_record = $class_1_records[$class_1];
- my @class_2_records
- = unpack "(a$class_2_record_size)$class_2_count", $class_1_record;
-
- for my $class_2 (0 .. $class_2_count - 1) {
- my $class_2_record = $class_2_records[$class_2];
- my $value = unpack "\@${value_offset}s>", $class_2_record;
- next if $value == 0;
- $value = 1000 * $value / $UNITS_PER_EM;
-
- my @first = grep { $class_1[$_] == $class_1 } @coverage;
- my @second = grep { $class_2[$_] == $class_2 } 0 .. $#class_2;
-
- for my $first (@first) {
- for my $second (@second) {
- $kern{$first}{$second} ||= $value;
- }
- }
- }
- }
-
- return;
-}
-
-#-----------------------------------------------------------------------
-# Get class number for all glyphs
-#-----------------------------------------------------------------------
-sub _get_class {
- my $class = shift;
-
- my @class = (0) x $NUM_GLYPHS;
-
- my $class_format = unpack 'n', $class;
- if ($class_format == 1) {
- my ($start_glyph, @class_value) = unpack '@2nn/n', $class;
- @class[$start_glyph .. $start_glyph + $#class_value]
- = @class_value;
- }
- elsif ($class_format == 2) {
- my @class_ranges = unpack '@2n/(a6)', $class;
- for my $class_range (@class_ranges) {
- my ($start, $end, $class) = unpack 'nnn', $class_range;
- @class[$start .. $end] = ($class) x ($end - $start + 1);
- }
- }
- else {
- warn "[ERROR] invalid ClassFormat '$class_format' ignored";
- return;
- }
-
- return @class;
-}
-
-
-#-----------------------------------------------------------------------
-# Determine size of ValueRecord and offset of XAdvance value in it
-#-----------------------------------------------------------------------
-sub _parse_value_formats {
- my ($value_format_1, $value_format_2, $record_size, $value_offset) = @_;
-
- unless ($value_format_1 & 0x4 && $value_format_2 == 0) {
- warn "[WARNING] ValueFormat ($value_format_1, ",
- "$value_format_2) not implemented";
- return;
- }
-
- for my $bit ((0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80)) {
- $record_size += 2 if $value_format_1 & $bit;
- }
- for my $bit ((0x1, 0x2)) {
- $value_offset += 2 if $value_format_1 & $bit;
- }
-
- return ($record_size, $value_offset);
-}
-
-#-----------------------------------------------------------------------
-# Return a list of GlyphIDs in a Coverage table
-#-----------------------------------------------------------------------
-sub _get_coverage {
- my $coverage = shift;
-
- my $coverage_format = unpack 'n', $coverage;
- if ($coverage_format == 1) {
- return unpack '@2n/n', $coverage;
- }
- elsif ($coverage_format == 2) {
- my @range_records = unpack '@2n/(a6)', $coverage;
-
- return map { my ($start, $end) = unpack 'nn', $_;
- $start .. $end;
- }
- @range_records;
- }
- else {
- warn "[WARNING] unknown CoverageFormat $coverage_format ignored";
- }
-}
-
-
-########################################################################
-
-
-package OTF::Kern;
-
-#-----------------------------------------------------------------------
-# Parse "kern"table, store kern pairs in global %kern
-#-----------------------------------------------------------------------
-sub parse_kerntable {
- my $kern = shift;
-
- my $num_tables = unpack '@2n', $kern;
- my $start_subtable = 4;
- for my $i (0 .. $num_tables - 1) {
- my $subtable = substr $kern, $start_subtable;
- my ($length, $coverage) = unpack '@2nn', $subtable;
- $start_subtable += $length;
-
- if ($coverage != 0x1) {
- warn "[WARNING] kern table format '$coverage' not implemented";
- next;
- }
-
- my @kern_pairs = unpack '@6nx6/(a6)', $subtable;
- for my $kern_pair (@kern_pairs) {
- my ($first, $second, $value) = unpack 'nns>', $kern_pair;
- next if $value == 0;
-
- $kern{$first}{$second} ||= 1000 * $value / $UNITS_PER_EM;
- }
- }
-
- return;
-}
-
-
-########################################################################
-
-
-package main;
-
-main();
-
-__END__
-
-
-########################################################################
-
-
- To create the documentation:
-
- pod2man --center="Marc Penninga" --release="fontools" --section=1 \
- ot2kpx - | groff -Tps -man - | ps2pdf - ot2kpx.pdf
-
-=pod
-
-=head1 NAME
-
-ot2kpx - extract kerning information from OpenType fonts
-
-
-=head1 SYNOPSIS
-
-B<ot2kpx> [ I<-afm> | I<-kpx> | I<-lua> ] B<< <fontfile> >>
-
-
-=head1 DESCRIPTION
-
-B<ot2kpx> extract the kerning data from OpenType fonts and prints it
-to C<stdout>, either in Adobe's KPX format (for adding to an F<afm> file)
-or as a Luatex custom feature, for use with the C<\directlua> command.
-
-
-=head1 OPTIONS AND ARGUMENTS
-
-=over 4
-
-=item B<-help>
-
-Print a short help text and exit.
-
-=item B<-version>
-
-Print B<ot2kpx>'s version and exit.
-
-=item B<-afm>, B<-kpx>
-
-Output the kerning data in Adobe's KPX format, as used in F<afm> files.
-This is the default output format.
-
-=item B<-lua>
-
-Output the kerning data as a Luatex custom font feature,
-to be included in a C<\directlua> command.
-
-=item B<< <fontfile> >>
-
-The OpenType font (both F<otf> and F<ttf> format are supported).
-
-=back
-
-
-=head1 RESTRICTIONS
-
-=over 4
-
-=item B<->
-
-B<ot2kpx> doesn't implement all of the OpenType specification.
-Things that are missing include: support for font files containing
-multiple fonts, LookupTables with LookupTypes other than 2,
-"kern" tables with format other than 0 and ValueRecords with
-other types of data than just XAdvance data.
-
-Most of these limitations won't matter, since the missing features
-are rare (the only fonts I know of that use them are the non-western fonts
-that come with Adobe Reader). Furthermore, many of these features define
-(according to the OpenType specification) I<"subtle, device-dependent
-adjustments at specific font sizes or device resolutions">;
-since there's no way to express such adjustments in F<afm> format,
-ignoring them seems to be the only option anyway.
-
-=item B<->
-
-B<ot2kpx> collects kerning data first from the "kern" table, then from
-all LookupTables associated with the "kern" feature; if a kerning pair
-occurs multiple times, the first value seen is chosen.
-There are (or may be) several issues with this approach:
-
-=over 4
-
-=item -
-
-The OpenType specification says that fonts in F<otf> format shouldn't
-use the "kern" table at all, just the lookups from the "GPOS" table.
-Many such fonts do, however, contain a "kern" table, but no "GPOS" table;
-so we use the "kern" table anyway.
-
-=item -
-
-Instead of reading all LookupTables, it might be better to let the user
-specify a script and language and process only the LookupTables for
-those values.
-However, at least in the fonts I checked, all script/language combinations
-eventually point to the I<same> "kern" LookupTables, so this approach
-wouldn't make any difference (apart from further complicating the code).
-
-=back
-
-=back
-
-
-=head1 AUTHOR
-
-Marc Penninga <marcpenninga@gmail.com>
-
-
-=head1 COPYRIGHT
-
-Copyright (C) 2005-2020 Marc Penninga.
-
-
-=head1 LICENSE
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published
-by the Free Software Foundation, either version 2 of the License,
-or (at your option) any later version.
-A copy of the GNU General Public License is included with B<ot2kpx>;
-see the file F<GPLv2.txt>.
-
-
-=head1 DISCLAIMER
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
-
-
-=head1 VERSION
-
-This document describes B<ot2kpx> version 20201218.
-
-
-=head1 RECENT CHANGES
-
-(See the source code for the rest of the story.)
-
-=over 12
-
-=item I<2019-05-20>
-
-Added the I<-version> option.
-
-=item I<2019-04-15>
-
-Added the I<-lua> command-line option to get output in Luatex's
-custom feature format.
-
-=back
-
-
-=begin Really_old_history
-
-=over 12
-
-=item I<2013-08-07>
-
-Replaced all C<given/when> constructions in the source code by C<if>'s,
-to avoid warnings about experimental features in Perl 5.18 and later.
-
-=item I<2012-02-01>
-
-Refactored the code, and fixed a number of bugs in the process.
-Updated the documentation.
-
-=item I<2005-01-10>
-
-First version
-
-=item I<2005-02-18>
-
-Rewrote some of the code
-
-=item I<2005-03-08>
-
-Input files searched via B<kpsewhich> (where available)
-
-=item I<2005-03-15>
-
-Input files searched using B<kpsewhich> or B<findtexmf>
-
-=item I<2005-03-21>
-
-Test if GPOS table is present before trying to read it
-
-=item I<2005-04-29>
-
-Improved the documentation
-
-=item I<2005-05-25>
-
-Changed warning that's given when the font contains no GPOS table, to an
-informational message.
-
-=item I<2005-07-29>
-
-A few updates to the documentation
-
-=back
-
-=cut
-
diff --git a/Build/source/texk/texlive/linked_scripts/fragmaster/fragmaster.pl b/Build/source/texk/texlive/linked_scripts/fragmaster/fragmaster.pl
deleted file mode 100755
index 35606bcbe08..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fragmaster/fragmaster.pl
+++ /dev/null
@@ -1,569 +0,0 @@
-#!/usr/bin/perl -w
-
-######################################################################
-#
-# fragmaster.pl
-#
-# creates EPS and PDF graphics from source EPS and control files
-# with \psfrag commands
-#
-# Version: 1.6
-#
-# Copyright (C) 2004 Tilman Vogel <tilman vogel web de> (dot at dot)
-# Copyright (C) 2011 Agustin Martin <agustin martin hispalinux es> (dot at dot)
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# See pod section at the end of this script for more information
-# ----------------------------------------------------------------------------
-
-use strict;
-use Cwd;
-use File::Temp qw(tempdir);
-use Pod::Usage;
-
-my $force;
-my $debug;
-my $global_dirfm_mtime;
-my $global_dirfm_file = "fragmaster.dfm";
-my $fragmaster_status = "fragmaster.sts";
-my $global_fmclass = "article";
-my $global_fmclassopt = "12pt";
-my $global_fmopt = "";
-my @global_fmhead = ();
-my @global_fmfile = ();
-my %dirdata_last_status = ();
-
-
-foreach my $option ( @ARGV ){
- if ( $option eq "--force" ){
- $force++;
- } elsif ( $option eq "--debug" ){
- print STDERR "Debug enabled\n";
- $debug++;
- } elsif ( $option =~ s/^--dirfm(=|\#)// ) {
- if ( -e $option ){
- $global_dirfm_file = $option;
- print STDERR "fragmaster: using \"$global_dirfm_file\" directory control file.\n"
- if $debug;
- } else {
- die "fragmaster: Could not find given \"$option\" directory control file. Aborting ....\n";
- }
- } elsif ( $option eq "-h" || $option eq "--help" ) {
- pod2usage(1);
- exit 1;
- } elsif ( $option eq "-m" || $option eq "--man" ) {
- pod2usage(-exitstatus => 0, -verbose => 2);
- exit 1;
- } else {
- print STDERR "\nfragmaster: Unsupported option \"$option\"\n\n";
- pod2usage(1);
- exit 1;
- }
-}
-
-# Function definitions
-
-# ----------------------------------------------------------------------------
-sub win32_which {
-# ----------------------------------------------------------------------------
-# Look if given basename matches a win32 executable under $PATH
-# ----------------------------------------------------------------------------
- my $basename = shift;
- my @extensions = (".exe");
-
- foreach my $path ( '.', split(';',$ENV{'PATH'}) ){
- foreach my $ext ( @extensions ){
- my $exec_location = "$path\\$basename$ext";
- if ( -x "$exec_location" ){
- print STDERR "fragmaster: Found gs executable at \"$exec_location\"\n"
- if $debug;
- return $basename;
- } else {
- print STDERR "fragmaster: No gs executable found at \"$exec_location\"\n"
- if $debug;
- }
- }
- }
-}
-
-# ----------------------------------------------------------------------------
-sub parse_fmfile {
-# ----------------------------------------------------------------------------
- my $file = shift;
- my %fmdata = ();
- my @fmfile = (); # A copy of original file
- my @fmhead = (); # Preamble to use
- my $fmopt; # Options to \includegraphics
- my $fmclass; # Class to use
- my $fmclassopt; # Options for class invocation
-
- die "fragmaster::parse_fmfile: No file to parse passed as argument. Aborting ...\n"
- unless $file;
-
- open FMFILE, "<$file"
- or die "fragmaster: Cannot read \"$file\"!. Aborting ...\n";
-
- while (<FMFILE>) {
- chomp;
- push @fmfile, " $_%";
- s/\s+$//; # Strip trailing whitespace
- $fmopt = $1 if /fmopt:\s*(.*)/;
- $fmclass = $1 if /fmclass:\s*(.*)/;
- $fmclassopt = $1 if /fmclassopt:\s*(.*)/;
- if (/head:/) {
- while(<FMFILE>) {
- chomp;
- push @fmfile, " $_%";
- last if /end head/;
- # Remove comment prefix
- s/^[\s%]*//;
- push @fmhead, "$_%";
- }
- }
- }
- close FMFILE;
- $fmdata{'fmfile'} = \@fmfile if scalar @fmfile;
- $fmdata{'fmpreamble'} = \@fmhead if scalar @fmhead;
- $fmdata{'fmclass'} = $fmclass if $fmclass;
- $fmdata{'fmclassopt'} = $fmclassopt if $fmclassopt;
- $fmdata{'fmopt'} = $fmopt if $fmopt;
- print STDERR
- "fragmaster::parse_fmfile: Keys found in \"$file\": ",
- join(', ',sort keys %fmdata ), "\n"
- if $debug;
- return \%fmdata;
-}
-
-# ----------------------------------------------------------------------------
-
-my $cwd = getcwd;
-
-die "fragmaster: Current path contains whitespace. LaTeX cannot handle this correctly, move somewhere else. Aborting ... \n"
- if $cwd =~ /\s/;
-
-# Get modification time for $global_dirfm_file if exists. Also used as existence flag.
-$global_dirfm_mtime = -M $global_dirfm_file if ( -e $global_dirfm_file );
-
-# Look for fragmaster _fm files.
-my %all_basenames = ();
-foreach (<*_fm>){
- s/_fm$//;
- $all_basenames{$_}++;
-}
-die "fragmaster: No fm_files found. Aborting ...\n"
- unless ( scalar %all_basenames );
-
-# Check if there is a status file for last processing with dir control file
-if ( -e $fragmaster_status ){
- open my $LAST, "< $fragmaster_status"
- or die "fragmaster: Could not open \"$fragmaster_status\" for read. Aborting ...\n";
- while ( <$LAST> ){
- next if m/^\s*\#/;
- next if m/^\s*~/;
- chomp;
- if ( m/^([^:]+):(.*)$/ ) {
- $dirdata_last_status{$1} = $2;
- print STDERR "fragmaster: Last dfm used for \"$1\": \"$dirdata_last_status{$1}\"\n"
- if $debug;
- } else {
- print STDERR "fragmaster: Wrongly formatted line in \"$fragmaster_status\": \"$_\". Ignoring ...\n";
- }
- }
- close $LAST;
-}
-
-# Remove no longer present files from status file
-foreach my $base ( sort keys %dirdata_last_status ){
- delete $dirdata_last_status{$base} unless ( defined $all_basenames{$base} );
-}
-
-# For each _fm file found, check if we need to rebuild
-my %doit_basenames = ();
-foreach my $base ( sort keys %all_basenames ) {
- my $fm_file = "$base" . "_fm";
- my $source = "$fm_file.eps";
-
- if ( -f $source ) {
- my $dest_eps = "$base.eps";
- my $dest_pdf = "$base.pdf";
- my $do_it = $force;
-
- unless ( $do_it ) {
- # Rebuild if there is any mismatch betwen last and current per-dir file.
- if ( $global_dirfm_mtime ){
- if ( defined $dirdata_last_status{$base} ){
- $do_it++ unless ( $global_dirfm_file eq $dirdata_last_status{$base} );
- } else {
- $do_it++;
- }
- } elsif ( defined $dirdata_last_status{$base} ){
- $do_it++;
- }
- }
-
- unless ( $do_it ) {
- if ( -f $dest_eps && -f $dest_pdf ){
- # Sort after modification times. Redo if any source is newer than any dest.
- my @dest_stamps = (-M $dest_eps, -M $dest_pdf);
- my @sources_stamps = (-M $fm_file, -M $source );
- push @sources_stamps, $global_dirfm_mtime if $global_dirfm_mtime;
- my $oldest_dest = (sort { $b <=> $a } @dest_stamps)[0];
- my $youngest_source = (sort { $a <=> $b } @sources_stamps)[0];
- $do_it++ if $oldest_dest > $youngest_source;
- } else {
- $do_it++;
- }
- }
-
- $doit_basenames{$base}++ if $do_it;
- } else {
- print "fragmaster: \"$fm_file\" skipped. Cannot find associated EPS file \"$source\".\n";
- }
-}
-
-# Do nothing if targets are up to date and --force was not set
-unless ( scalar %doit_basenames ){
- print STDERR "fragmaster: all targets are up-to-date.\n";
- exit;
-}
-
-# Create master tempdir for the temporary files
-my $base_tempdir =
- tempdir( "fragmaster.XXXXXX", # Use a fragmaster prefix for base tempdir
- CLEANUP => ( ! $debug ), # Remove tempdir tree on exit unless $debug
- DIR => $cwd ) # Create base tempdir under current dir
- or die "fragmaster: Cannot make temporary directory!";
-print "fragmaster: Using $base_tempdir/\n";
-
-# Check which name to use for ghostscript.
-my $gs_prog = "gs";
-
-if ( $^O =~ /^MSWin/ ){
- $gs_prog = win32_which("gswin32c") # Try first standard name
- || win32_which("mgs") # Be kind with miktex
- || "gswin32c"; # May be a wrapper with different extension. Try.
-}
-
-# If we have a per-directory control file with values set, use them to override defaults.
-if ( -e $global_dirfm_file ){
- my $fmdata = parse_fmfile($global_dirfm_file);
- $global_fmclass = $fmdata->{'fmclass'} if ( defined $fmdata->{'fmclass'} );
- $global_fmclassopt = $fmdata->{'fmclassopt'} if ( defined $fmdata->{'fmclassopt'} );
- $global_fmopt = $fmdata->{'fmopt'} if ( defined $fmdata->{'fmopt'} );
- @global_fmhead = @{$fmdata->{'fmpreamble'}} if ( defined $fmdata->{'fmpreamble'} );
-}
-
-# (Re-)build targets
-foreach my $base ( sort keys %doit_basenames ) {
- my $fm_file = "$base" . "_fm";
- my $source = "$fm_file.eps";
- my $dest_eps = "$base.eps";
- my $dest_pdf = "$base.pdf";
-
- print "fragmaster: $fm_file, $source -> $dest_eps, $dest_pdf\n";
-
- # Parse per-graphic _fm control file
- my $fmdata = parse_fmfile($fm_file);
- my $fmclass = ( defined $fmdata->{'fmclass'} ) ? $fmdata->{'fmclass'} : $global_fmclass;
- my $fmclassopt = ( defined $fmdata->{'fmclassopt'} ) ? $fmdata->{'fmclassopt'} : $global_fmclassopt;
- my $fmopt = ( defined $fmdata->{'fmopt'} ) ? $fmdata->{'fmopt'} : $global_fmopt;
- my @fmhead = ( defined $fmdata->{'fmpreamble'} ) ? @{$fmdata->{'fmpreamble'}} : @global_fmhead;
- my @fmfile = ( defined $fmdata->{'fmfile'} ) ? @{$fmdata->{'fmfile'}} : @global_fmfile;
-
- my $texstring = "\\documentclass[$fmclassopt]{$fmclass}
-\\usepackage{graphicx,psfrag,color}
-";
- # Enter heading info
- $texstring .= "$_\n" foreach (@fmhead);
-
- $texstring .= '
-\setlength{\topmargin}{-1in}
-\setlength{\headheight}{0pt}
-\setlength{\headsep}{0pt}
-\setlength{\topskip}{0pt}
-\setlength{\textheight}{\paperheight}
-\setlength{\oddsidemargin}{-1in}
-\setlength{\evensidemargin}{-1in}
-\setlength{\textwidth}{\paperwidth}
-\setlength{\parindent}{0pt}
-\special{! TeXDict begin /landplus90{true}store end }
-%\special{! statusdict /setpage undef }
-%\special{! statusdict /setpageparams undef }
-\pagestyle{empty}
-\newsavebox{\pict}
-\graphicspath{{../../}}
-
-\begin{document}
- \begin{lrbox}{\pict}%
-';
- $texstring .= "$_\n" foreach (@fmfile);
- $texstring .= " \\includegraphics[$fmopt]{$source}%\n";
- $texstring .= ' \end{lrbox}
- \special{papersize=\the\wd\pict,\the\ht\pict}
- \usebox{\pict}
-\end{document}
-';
-
- my $tempdir = "$base_tempdir/$base";
- mkdir $tempdir;
-
- # Writing TeX file
- open TEXFILE, ">$tempdir/fm.tex"
- or die "fragmaster: Cannot write LaTeX file!";
- print TEXFILE $texstring;
- close TEXFILE;
-
- chdir($tempdir)
- or die "fragmaster: Cannot chdir to \"$tempdir\"!. Aborting ...\n";
-
- system("latex fm.tex") == 0
- or die "fragmaster: Cannot latex \"fm.tex\"!. Aborting ...\n";
-
- # Using -E here, causes dvips to detect
- # the psfrag phantom stuff and to set the BoundingBox wrong
- system("dvips -E -P pdf fm.dvi -o fm.ps") == 0
- or die "fragmaster: Cannot dvips!. Aborting ...\n";
-
- chdir($cwd)
- or die "fragmaster: Cannot chdir back up!. Aborting ...\n";
-
- # Read original eps file as created by dvips -E.
- my $psfile;
- {
- local $/ = undef;
- open PS, "<$tempdir/fm.ps"
- or die "fragmaster: Cannot read \"fm.ps\"!. Aborting ...\n";
- $psfile = <PS>;
- close PS;
- }
-
- # Calculate real Bounding Box using ghostscript bbox device, also available
- # in strippped-down texlive gs. Currently, it writes result only to STDERR.
- my $bbox_line;
- my $bbox_cmd = "$gs_prog -q -sDEVICE#bbox -dNOPAUSE -dBATCH \"$tempdir/fm.ps\" 2> \"$tempdir/fm.bb\"";
- print STDERR "fragmaster: $bbox_cmd\n" if $debug;
- system("$bbox_cmd") == 0
- or die "fragmaster: Failed to obtain Bounding Box file with ghostscript bbox device.\n";
- open BB,"<$tempdir/fm.bb"
- or die "fragmaster: Could not read Bounding Box file \"$tempdir/fm.bb\". Aborting ...\n";
- while (<BB>) {
- if ( /^\%\%BoundingBox:/ ){
- chomp;
- $bbox_line = $_;
- last;
- }
- }
- close BB;
- die "fragmaster: No Bounding Box entry found in \"$tempdir/fm.bb\". Aborting ...\n"
- unless $bbox_line;
- print STDERR "fragmaster: $bbox_line\n"
- if $debug;
-
- # Fix Bounding Box and write corrected eps file.
- $psfile =~ s/^\%\%BoundingBox:.*/$bbox_line/m;
- open EPS, ">$dest_eps"
- or die "fragmaster: Cannot write \"$dest_eps\"!. Aborting ...\n";
- print EPS $psfile;
- close EPS;
-
- # Create pdf file after corrected ps file.
- system("epstopdf $dest_eps --outfile=$dest_pdf") == 0
- or die "fragmaster: Cannot epstopdf!. Aborting ...\n";
-
- # Update per-dir info in status file if everything was OK. We need to do this
- # after processing each entry. Otherwise an error may leave things inconsistent.
- if ( $global_dirfm_mtime ){
- $dirdata_last_status{$base} = $global_dirfm_file; # Mark per-dir file used
- } else {
- delete $dirdata_last_status{$base}; # or leave empty otherwise
- }
-
- print STDERR
- "fragmaster: \"$base\" processed, current files with dfm: \n [" ,
- join(', ',sort keys %dirdata_last_status),
- "]\n"
- if $debug;
- open my $LAST, "> $fragmaster_status"
- or die "fragmaster: Could not open \"$fragmaster_status\" for write. Aborting ...\n";
-
- print $LAST "\# This file is automatically generated by fragmaster. Do not edit.\n";
- foreach ( sort keys %dirdata_last_status ){
- print $LAST "$_:$dirdata_last_status{$_}\n";
- }
- close $LAST;
-}
-
-__END__
-
-=pod
-
-=head1 NAME
-
-fragmaster - Using psfrag constructs with pdflatex
-
-=head1 SYNOPSIS
-
- fragmaster [options]
-
- Create EPS and PDF files with embedded psfrag substitutions.
-
- Options:
- -h,--help Brief usage guide.
- -m,--man Show full man page (needs perldoc)
- --debug Show more info and leave temporary files behind.
- --force Rebuild everything ignoring modification times.
- --dirfm=file Use given file as optional per-directory
- fragmaster fm control file instead of default
- "fragmaster.dfm".
-
-=head1 DESCRIPTION
-
-B<fragmaster> is a perl script that helps using psfrag constructs with
-B<pdflatex>.
-
-B<psfrag> is a LaTeX package which allows to replace text elements in
-included EPS graphics by arbitrary LaTeX output. Because B<psfrag>
-uses Postscript for making the replacements, in principle you can't
-use B<psfrag> with B<pdflatex> which doesn't have any interfaces to
-postscript.
-
-B<fragmaster> produces a new EPS from your original EPS which already
-contains all those B<psfrag> replacements. This new EPS graphic
-actually can be converted to PDF including all replacements. The
-resulting "encapsulated" PDF can then be used with pdflatex.
-
-B<fragmaster> will scan the current directory for files which end in
-F<_fm> and have a F<_fm.eps> counterpart.
-Looking at the modification dates, the script checks if the output
-files have to be rebuilt and does so if necessary
-(a little like "make" would do it).
-
-In your LaTeX document you can include the produced graphics using
-
- \includegraphics{<graphics>}
-
-conveniently omitting file extension.
-B<latex> will choose the EPS, B<pdflatex> will choose the PDF.
-
-=head2 B<fragmaster> control file and other related files.
-
-To use the script you have to create two files per graphic:
-
- * <graphics>_fm.eps: the EPS file itself,
- * <graphics>_fm: a fragmaster control file.
-
-From these files the psfragged graphics will be created:
-
- * <graphics>.eps,
- * <graphics>.pdf
-
-The F<_fm> control file is basically a LaTeX file
-(with optionally special comments) and can look like this:
-
- % Just an ordinary comment
- %
- % Some special comments:
- % fmclass: book
- % fmclassopt: 11pt
- % fmopt: width=6cm
- %
- % Another special comment:
- % head:
- % \usepackage{amsmath}
- % end head
-
- % psfrag commands:
- \psfrag{x}{$x$}
- \psfrag{y}{$y = x^2$}
-
-Special comment C<fmclass:> will make the script use given class
-instead of default C<article> class.
-
-Special comment C<fmclassopt:> will make the script use given options
-as class options instead of default C<12pt>.
-
-The special comment C<fmopt:> will be evaluated such that the
-following text will by passed as optional argument to
-C<\includegraphics>.
-This way you can e.g. adjust the relation between graphics size
-and font size using something like C<fmopt: width=6cm>.
-No global default for this.
-
-The special comment construct C<head:/end head> causes the lines in
-between to be included in the preamble of the LaTeX temporary document
-after having the leading comment characters "%" stripped off.
-This way, you can include LaTeX packages, as in C<\usepackage{amsmath}>.
-No global default for this.
-
-=head2 Per-directory B<fragmaster> dir control file.
-
-You can set per-directory C<fmclass:>, C<fmclassopt:>, C<fmopt:> and
-C<head:/end head> options by means of a per-directory fragmaster control
-file F<fragmaster.dfm> with similar syntax as above.
-You can use another file by means of the B<--dirfm> option.
-Note that options set this way are mutually exclusive, any option set
-in per-file F<_fm> file will completely override associated option in
-per-directory file, and options set in per-directory file will
-override initial defaults (C<\documentclass[12pt]{article}>).
-Empty options are ignored.
-
-This is work in progress and still needs extensive checking. Double-check
-that modification date based rebuilds are working properly.
-
-=head1 KNOWN PROBLEMS
-
-In case the EPS will be produced as landscape graphics, i.e. B<gv> shows
-I<Landscape> instead of I<Portrait> in the menu bar, and the graphic will
-end up turned around 90 degrees in your document, then it is likely
-that your original EPS is wider than it is tall.
-In this case some (more recent) versions of B<dvips> make the "smart"
-assumption that your graphic is landscape, even though the graphic's
-proportions don't tell anything about the orientation of its contents...
-This still can happen in case your input EPS matches a standard paper size.
-
-Anyway, you can make B<dvips> behave nicer by specifying the following
-line in F</usr/share/texmf/dvips/config/config.pdf>
-(or a local equivalent inside F</usr/local/share/texmf>):
-
-@ custom 0pt 0pt
-
-In the likely case that you're wondering why, I'd recommend the
-B<dvipsk> sources warmly to you...
-
-=head1 AUTHOR
-
-Tilman Vogel <tilman vogel web de> (dot at dot) and
-Agustin Martin <agustin martin hispalinux es> (dot at dot)
-
-=head1 HISTORY
-
-This script was inspired by a posting from
-Karsten Roemke <k roemke gmx de> (dot at dot) with subject
-"psfrag pdflatex, lange her"
-in de.comp.text.tex on 2003-11-11 05:25:44 PST.
-
-Karsten Roemke was inspired for his solution by postings from
-Thomas Wimmer.
-
-=head1 COPYRIGHT
-
- Copyright (C) 2004 Tilman Vogel
- Copyright (C) 2011 Agustin Martin
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
diff --git a/Build/source/texk/texlive/linked_scripts/getmap/getmapdl.lua b/Build/source/texk/texlive/linked_scripts/getmap/getmapdl.lua
deleted file mode 100644
index e264e0b7836..00000000000
--- a/Build/source/texk/texlive/linked_scripts/getmap/getmapdl.lua
+++ /dev/null
@@ -1,870 +0,0 @@
-#!/usr/bin/env texlua
---
--- getmapdl [options]
---
--- downloads an OpenStreetMap, Google Maps or Google Street View map
--- specified by [options] or parses gpx, gps and kml files to create
--- encoded polylines
---
--- License: LPPL
---
-local http = require("socket.http")
-local ltn12 = require("ltn12")
--- local url = require("socket.url")
--- avoid bug in luatex v1.0.7
--- copied socket.url's escape function into local function url_escape
-function url_escape(s)
- return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
- return string.format("%%%02x", string.byte(c))
- end))
-end
-
-local OSMURL = "http://open.mapquestapi.com/staticmap/v4/getplacemap"
-local GMURL = "http://maps.googleapis.com/maps/api/staticmap"
-local GSVURL = "http://maps.googleapis.com/maps/api/streetview"
-local KEY = ""
-local MODE = ""
-local LOCATION = ""
-local XSIZE = ""
-local CENTER = ""
-local YSIZE = ""
-local SIZE = ""
-local SCALE = ""
-local ZOOM = ""
-local TYPE = ""
-local IMAGETYPE = ""
-local COLOR = ""
-local NUMBER = ""
-local VISIBLE = ""
-local IPATH = ""
-local FPATH = ""
-local MARKERS = ""
-local HEADING = ""
-local FOV = ""
-local PITCH = ""
-local LANGUAGE = ""
-local GPFILE = ""
-local KMLFILE = ""
-local BOUND = 0.1
-local OFILE = "getmap"
-local QUIET = "false"
-local VERSION = "v1.5a (2018/07/18)"
-
-function pversion()
- print("getmapdl.lua " .. VERSION)
- print("(C) Josef Kleber License: LPPL")
- os.exit(0)
-end
-
-function phelp()
- print([[
-getmapdl.lua [options]
-
- downloads an OpenStreetMap, Google Maps or Google Street View map
- specified by [options] or parses gpx, gps and kml files to create
- encoded polylines
-
- Options:
-
- -m specify the mode (osm|gm|gsv|gpx2epl|gps2epl|gpx2gps|kml2epl|kml2gps)
-
- -l specify a location
- e.g. 'Bergheimer StraĂźe 110A, 69115 Heidelberg, Germany'
-
- -x specify a xsize (600)
-
- -y specify a ysize (400)
-
- -S short form to specify a size, e.g. 600,400 (osm) or 600x400 (gm)
-
- -s specify a scale factor in the range 1692-221871572 (osm) or
- 1-2 (gm)
-
- -z specify a zoom in the range 1-18 (osm) or 0-21 (17) (gm)
-
- -t specify map type {map|sathyb} (map) (osm) or
- {roadmap|satellite|hybrid|terrain} (roadmap) (gm)
-
- -i specify image type {png|gif|jpg|jpeg} (png) (osm) or
- {png|png8|png32|gif|jpg|jpg-baseline} (png) (gm)
-
- -c specify icon color (yelow_1) (osm) or (blue) (gm)
- see: http://open.mapquestapi.com/staticmap/icons.html
- https://developers.google.com/maps/documentation/staticmaps/#MarkerStyles
-
- -n specify the icon number (1)
-
- -o specify output basename without file extension (getmap.IMAGETYPE)
-
- -q quiet; no output!
-
- -v prints version information
-
- -h prints help information
-
- gm mode only:
-
- -L specify the language of map labels (xx language code (en,de,fr,...))
-
- -M specify markers; see:
- https://developers.google.com/maps/documentation/staticmaps/index#Markers
- e.g.: &markers=size:mid|color:blue|label:1|address or more of these
- location and zoom will be ignored if used!
-
- -C specify center of the map
-
- -V specify a list of visible locations (loc1|loc2)
-
- -P specify path from location to location
- e.g.: &path=weight:7|color:purple|loc1|loc2
-
- -p specify a file holding the path specification
- (maybe needed for encoded polylines)
-
- gsv mode only:
-
- -H specify heading (view) (0) (0 -- 360) (east: 90, ...)
-
- -T specify the pitch (angle) (0) (-90 -- 90)
-
- -F specify horizontal field of view (90) (0 -- 120)
- The field of view is expressed in degrees and a kind of zoom!
-
- gpx2epl, gps2epl and gpx2gps mode only:
-
- -G specify the gpx or gps file
-
- kml2epl and kml2gps mode only:
-
- -K specify the kml file
-
- gps2gps mode only:
-
- -B specify the bound for reducing way points (default: 0.1)
-
-]])
- pversion()
-end
-
-function getmap_error(exitcode, errortext)
- io.stderr:write ("Error (" .. exitcode .. "): " .. errortext .. "\n")
- os.exit(exitcode)
-end
-
-function getmap_warning(warningtext)
- io.stderr:write("WARNING: " .. warningtext .. "\n")
-end
-
-function check_number(var, varname)
- if not(string.match(var, '^[-]?[0-9]+$')) then
- getmap_error(2, varname .. " can't be " .. var .. "! Not a number!")
- end
-end
-
-function check_range(var,min,max,exitcode,varname)
- check_number(var,varname)
- if (tonumber(var) < tonumber(min) or tonumber(var) > tonumber(max)) then
- getmap_error(exitcode, varname .. " = " .. var .. "; must be in the range of " .. min .. "-" .. max)
- end
-end
-
-function round(number, precision)
- return math.floor(number*math.pow(10,precision)+0.5) / math.pow(10,precision)
-end
-
-function encodeNumber(number)
- local num = number
- num = num * 2
- if num < 0
- then
- num = (num * -1) - 1
- end
- local t = {}
- while num >= 32
- do
- local num2 = 32 + (num % 32) + 63
- table.insert(t,string.char(num2))
- num = math.floor(num / 32) -- use floor to keep integer portion only
- end
- table.insert(t,string.char(num + 63))
- return table.concat(t)
-end
-
-function printepl(epltable)
- local string = table.concat(epltable)
- -- sometimes the sting contains unwanted control characters
- local stingwithoutcontrolcharacters = string:gsub("%c", "")
- print(stingwithoutcontrolcharacters)
-end
-
-function isnotnumber(number)
- if tonumber(number) == nil then
- return true
- else
- return false
- end
-end
-
-function dbtbound(Onum, num, bound)
- local absdiff = math.abs(tonumber(Onum) - tonumber(num))
- if absdiff >= tonumber(bound) then
- return true
- else
- return false
- end
-end
-
-do
- local newarg = {}
- local i, limit = 1, #arg
- while (i <= limit) do
- if arg[i] == "-l" then
- LOCATION = arg[i+1]
- i = i + 1
- elseif arg[i] == "-C" then
- CENTER = arg[i+1]
- i = i + 1
- elseif arg[i] == "-m" then
- MODE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-k" then
- KEY = arg[i+1]
- i = i + 1
- elseif arg[i] == "-x" then
- XSIZE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-y" then
- YSIZE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-S" then
- SIZE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-s" then
- SCALE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-z" then
- ZOOM = arg[i+1]
- i = i + 1
- elseif arg[i] == "-t" then
- TYPE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-i" then
- IMAGETYPE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-c" then
- COLOR = arg[i+1]
- i = i + 1
- elseif arg[i] == "-n" then
- NUMBER = arg[i+1]
- i = i + 1
- elseif arg[i] == "-L" then
- LANGUAGE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-M" then
- MARKERS = arg[i+1]
- i = i + 1
- elseif arg[i] == "-H" then
- HEADING = arg[i+1]
- i = i + 1
- elseif arg[i] == "-T" then
- PITCH = arg[i+1]
- i = i + 1
- elseif arg[i] == "-F" then
- FOV = arg[i+1]
- i = i + 1
- elseif arg[i] == "-V" then
- VISIBLE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-P" then
- IPATH = arg[i+1]
- i = i + 1
- elseif arg[i] == "-p" then
- FPATH = arg[i+1]
- i = i + 1
- elseif arg[i] == "-G" then
- GPFILE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-K" then
- KMLFILE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-B" then
- BOUND = arg[i+1]
- i = i + 1
- elseif arg[i] == "-o" then
- OFILE = arg[i+1]
- i = i + 1
- elseif arg[i] == "-q" then
- QUIET = 1
- elseif arg[i] == "-v" then
- pversion()
- elseif arg[i] == "-h" then
- phelp()
- else
- newarg[#newarg+1] = arg[i]
- end
- i = i + 1
- end
- arg = newarg
-end
-
-if QUIET == 1 then
- getmap_warning("-q option currently not supported!")
-end
-
-if MODE == "gpx2epl" then
- local file = GPFILE
- local name
- local desc
- local Olatitude = 0
- local Olongitude = 0
- local epl = {}
-
- for line in io.lines(file)
- do
- local latitude
- local longitude
- local encnum
-
- if string.match(line, "<trk>") then
- Olatitude = 0
- Olongitude = 0
- name = ""
- desc = ""
- epl = {}
- end
- if string.match(line, "<name") then
- name = string.match(line, '<name>(.-)</name>')
- if name == nil then
- name = "Name (E)"
- end
- end
- if string.match(line, "<desc") then
- desc = string.match(line, '<desc>(.-)</desc>')
- if desc == nil then
- desc = ""
- end
- end
- if string.match(line, "<trkseg") then
- print("Route: " .. name .. " [" .. desc .. "]")
- end
- if string.match(line, "<trkpt") then
- latitude = string.match(line, 'lat="(.-)"')
- longitude = string.match(line, 'lon="(.-)"')
- latitude = round(latitude,5)*100000
- longitude = round(longitude,5)*100000
- encnum = encodeNumber(latitude - Olatitude)
- table.insert(epl,encnum)
- encnum = encodeNumber(longitude - Olongitude)
- table.insert(epl,encnum)
- Olatitude = latitude
- Olongitude = longitude
- end
- if string.match(line, "</trk>") then
- printepl(epl)
- print("\n")
- end
- end
- os.exit(0)
-end
-
-if MODE == "gpx2gps" then
- local file = GPFILE
- local name
- local desc
-
- for line in io.lines(file)
- do
- local latitude
- local longitude
- local encnum
-
- if string.match(line, "<trk>") then
- name = ""
- desc = ""
- end
- if string.match(line, "<name") then
- name = string.match(line, '<name>(.-)</name>')
- if name == nil then
- name = "Name (E)"
- end
- end
- if string.match(line, "<desc") then
- desc = string.match(line, '<desc>(.-)</desc>')
- if desc == nil then
- desc = ""
- end
- end
- if string.match(line, "<trkseg") then
- print("Route: " .. name .. " [" .. desc .. "]")
- end
- if string.match(line, "<trkpt") then
- latitude = string.match(line, 'lat="(.-)"')
- longitude = string.match(line, 'lon="(.-)"')
- latitude = round(latitude,5)
- longitude = round(longitude,5)
- print(latitude .. "," .. longitude)
- end
- if string.match(line, "</trk>") then
- print("\n")
- end
- end
- os.exit(0)
-end
-
-if MODE == "gps2gps" then
- local file = GPFILE
- local bound = BOUND
- local incount = 0
- local outcount = 0
- local routecount = 1
- local latitude
- local longitude
- local Olatitude
- local Olongitude
- local Llatitude
- local Llongitude
- local ignorenextline = false
- local firstroute = true
-
- for line in io.lines(file)
- do
- latitude, longitude = line:match("([^,]+),([^,]+)")
- if ignorenextline == true then
- line = ""
- ignorenextline = false
- end
- -- if line contains "Point:" then gps coordinates
- -- in the next line must be ignored!
- if line:match("Point:") then
- ignorenextline = true
- end
- if line:match("Route:") then
- if firstroute == true then
- firstroute = false
- routecount = 0
- else
- -- print last pair of coordinates
- print(Llatitude .. "," .. Llongitude)
- outcount = outcount + 1
- io.stderr:write("\nRoute " .. routecount .. ": reduced gps coordinates (Bound = " .. bound .. "): " .. incount .. " -> " .. outcount)
- end
- incount = 0
- outcount = 0
- routecount = routecount + 1
- print("\n" .. line .. "\n")
- line = ""
- end
- if line == "" or isnotnumber(latitude) or isnotnumber(longitude)
- then
- -- empty line or no gps coordinates -> do nothing
- else
- latitude = round(latitude,5)
- longitude = round(longitude,5)
- Llatitude = latitude
- Llongitude = longitude
- incount = incount + 1
- if incount == 1 then
- Olatitude = latitude
- Olongitude = longitude
- print(Olatitude .. "," .. Olongitude)
- outcount = outcount + 1
- else
- if dbtbound(Olatitude,latitude,bound) or dbtbound(Olongitude,longitude,bound) then
- print(latitude .. "," .. longitude)
- outcount = outcount + 1
- Olatitude = latitude
- Olongitude = longitude
- end
- end
- end
- end
- -- print last pair of coordinates
- print(Llatitude .. "," .. Llongitude)
- outcount = outcount + 1
- io.stderr:write("\nRoute " .. routecount .. ": reduced gps coordinates (Bound = " .. bound .. "): " .. incount .. " -> " .. outcount)
- os.exit(0)
-end
-
-if MODE == "gps2epl" then
- local file = GPFILE
- local Olatitude = 0
- local Olongitude = 0
- local epl = {}
- local firstroute = true
-
- for line in io.lines(file)
- do
- local latitude
- local longitude
- local encnum
-
- latitude, longitude = line:match("([^,]+),([^,]+)")
- if ignorenextline == true then
- line = ""
- ignorenextline = false
- end
- -- if line contains "Point:" then gps coordinates
- -- in the next line must be ignored!
- if line:match("Point:") then
- ignorenextline = true
- end
- if line:match("Route:") then
- if firstroute == true then
- firstroute = false
- else
- printepl(epl)
- Olatitude = 0
- Olongitude = 0
- epl = {}
- end
- print("\n" .. line .. "\n")
- line = ""
- end
- if line == "" or isnotnumber(latitude) or isnotnumber(longitude)
- then
- -- empty line or no gps coordinates -> do nothing
- else
- latitude = round(latitude,5)*100000
- longitude = round(longitude,5)*100000
- encnum = encodeNumber(latitude - Olatitude)
- table.insert(epl,encnum)
- encnum = encodeNumber(longitude - Olongitude)
- table.insert(epl,encnum)
- Olatitude = latitude
- Olongitude = longitude
- end
- end
- printepl(epl)
- os.exit(0)
-end
-
-if MODE == "kml2gps" or MODE == "kml2epl" then
- local file = KMLFILE
- local name
- local cdata
- local cotype
- local Olatitude = 0
- local Olongitude = 0
- local epl = {}
-
- for line in io.lines(file)
- do
- local latitude
- local longitide
- local elevation
-
- -- reset for new route
- if string.match(line, "<Placemark>") then
- Olatitude = 0
- Olongitude = 0
- cotype = nil
- epl = {}
- end
- if string.match(line, "<name>") then
- name = string.match(line, '<name>(.-)</name>')
- if name == nil then
- name = "Name (E)"
- end
- end
- if string.match(line, "CDATA") then
- cdata = string.match(line, 'CDATA%[(.-)%]')
- if cdata == nil then
- cdata = ""
- end
- end
- if string.match(line, "<Point>") then
- cotype = "point"
- end
- if string.match(line, "<LineString>") then
- cotype = "route"
- end
- if cotype == "point" or cotype == "route" then
- if string.match(line, "<coordinates>") then
- local colist = string.match(line, '<coordinates>(.-)</coordinates>')
- if cotype == "route" then
- print("Route: " .. name)
- else
- print("Point: " .. name .. " [" .. cdata .. "]")
- end
- for cocsv in string.gmatch(colist, "%S+") do
- longitude, latitude, altitude = cocsv:match("([^,]+),([^,]+),([^,]+)")
- latitude = round(latitude,5)
- longitude = round(longitude,5)
- if MODE == "kml2epl" then
- local encnum
- if cotype == "route" then
- latitude = latitude*100000
- longitude = longitude*100000
- encnum = encodeNumber(latitude - Olatitude)
- table.insert(epl,encnum)
- encnum = encodeNumber(longitude - Olongitude)
- table.insert(epl,encnum)
- Olatitude = latitude
- Olongitude = longitude
- else
- print(latitude .. "," .. longitude)
- end
- else
- print(latitude .. "," .. longitude)
- end
- end
- if MODE == "kml2epl" and cotype == "route" then
- printepl(epl)
- end
- print("\n")
- end
- end
- end
- os.exit(0)
-end
-
-print("\n")
-
-if KEY == "" then
- if MODE == "osm" then
- KEY="Kmjtd|luu7n162n1,22=o5-h61wh"
- getmap_warning("KEY not specified; using mapquest example key as default!")
- end
-end
-
-if LOCATION == "" then
- LOCATION = "Bergheimer StraĂźe 110A, 69115 Heidelberg, Germany"
- getmap_warning("LOCATION not specified; using Dante e.V. Office as default!")
-end
-
-if MODE == "gm" then
- if ZOOM == "" then
- ZOOM=17
- getmap_warning("ZOOM not specified; using ZOOM=17 as default!")
- end
-end
-
-if XSIZE == "" then
- XSIZE=600
- getmap_warning("XSIZE not specified; using XSIZE=600 as default!")
-end
-
-if YSIZE == "" then
- YSIZE=400
- getmap_warning("YSIZE not specified; using YSIZE=400 as default!")
-end
-
-if SIZE == "" then
- if MODE == "gm" then
- SIZE = XSIZE .. "x" .. YSIZE
- elseif MODE == "gsv" then
- SIZE = XSIZE .. "x" .. YSIZE
- elseif MODE == "osm" then
- SIZE = XSIZE .. "," .. YSIZE
- end
-end
-
-if SCALE == "" then
- if MODE == "gm" then
- SCALE=1
- getmap_warning("SCALE not specified, using SCALE=1 as default!")
- elseif MODE == "osm" then
- if ZOOM == "" then
- SCALE=3385
- getmap_warning("SCALE not specified, using SCALE=3385 as default!")
- end
- end
-end
-
-if TYPE == "" then
- if MODE == "gm" then
- TYPE = "roadmap"
- getmap_warning("TYPE not specified; using roadmap as default!")
- elseif MODE == "osm" then
- TYPE = "map"
- getmap_warning("TYPE not specified; using map as default!")
- end
-end
-
-if IMAGETYPE == "" then
- if MODE == "gsv" then
- else
- IMAGETYPE="png"
- getmap_warning("IMAGETYPE not specified; using png as default!")
- end
-end
-
-if COLOR == "" then
- if MODE == "gm" then
- COLOR="blue"
- getmap_warning("COLOR not specified; using blue as default!")
- elseif MODE == "osm" then
- COLOR="yellow_1"
- getmap_warning("COLOR not specified; using yellow_1 as default!")
- end
-end
-
-if NUMBER == "" then
- if MODE == "gsv" then
- else
- NUMBER=1
- getmap_warning("NUMBER not specified; using 1 as default!")
- end
-end
-
-if MODE == "gsv" then
- if HEADING == "" then
- HEADING=0
- getmap_warning("HEADING not specified; using 0 as default!")
- end
-
- if FOV == "" then
- FOV=90
- getmap_warning("FOV not specified; using 90 as default!")
- end
-
- if PITCH == "" then
- PITCH=0
- getmap_warning("PITCH not specified; using 0 as default!")
- end
-end
-
-if MODE == "gm" then
- if ZOOM == "" then
- ZOOM = 17
- else
- check_range(ZOOM,0,21,11,"ZOOM")
- end
- check_range(XSIZE,1,640,12,"XSIZE")
- check_range(YSIZE,1,640,13,"YSIZE")
- check_range(SCALE,1,2,14,"SCALE")
-elseif MODE == "gsv" then
- check_range(XSIZE,1,640,12,"XSIZE")
- check_range(YSIZE,1,640,13,"YSIZE")
- check_range(HEADING,0,360,15,"HEADING")
- check_range(FOV,0,120,16,"FOV")
- check_range(PITCH,-90,90,17,"PITCH")
-elseif MODE == "osm" then
- check_range(XSIZE,1,3840,11,"XSIZE")
- check_range(YSIZE,1,3840,12,"YSIZE")
- if ZOOM == "" then
- check_range(SCALE,1692,221871572,13,"SCALE")
- else
- check_range(ZOOM,1,18,14,"ZOOM")
- end
- check_number(NUMBER,"NUMBER")
-end
-
-local UKEY = ""
-local ULOCATION = ""
-local UZOOM = ""
-local USCALEZOOM = ""
-local UMARKERS = ""
-local USIZE = ""
-local USCALE = ""
-local UTYPE = ""
-local USHOWICON = ""
-local UIMAGETYPE = ""
-local UVISIBLE = ""
-local UIPATH = ""
-local UFPATH = ""
-local EPLFILE = ""
-local UHEADING = ""
-local UFOV = ""
-local UPITCH = ""
-local ULANGUAGE = ""
-local UOFILE = ""
-local IMGURL = ""
-
-if MODE == "gm" then
- ULOCATION = "center=" .. url_escape(LOCATION)
- if MARKERS == "" then
- UMARKERS = "&markers=size:mid|color:" .. COLOR .. "|label:" .. NUMBER .. "|" .. url_escape(LOCATION)
- UZOOM = "&zoom=" .. url_escape(ZOOM)
- else
- UMARKERS = "" .. url_escape(MARKERS)
- -- correct cruft escaping of "&markers="
- UMARKERS = UMARKERS:gsub("%%26markers%%3d","&markers=")
- UZOMM = ""
- if CENTER == "" then
- ULOCATION = ""
- else
- ULOCATION = "center=" .. url_escape(CENTER)
- end
- end
- USIZE = "&size=" .. url_escape(SIZE)
- USCALE = "&scale=" .. url_escape(SCALE)
- UTYPE = "&maptype=" .. url_escape(TYPE)
- UIMAGETYPE = "&format=" .. url_escape(IMAGETYPE)
- if IMAGETYPE == "jpg-baseline" then
- IMAGETYPE = "jpg"
- end
- if VISIBLE == "" then
- UVISIBLE = ""
- else
- UVISIBLE = "&visible=" .. url_escape(VISIBLE)
- end
- if IPATH == "" then
- UIPATH = ""
- else
- UIPATH = "" .. url_escape(IPATH)
- -- correct cruft escaping of "&path="
- UIPATH = UIPATH:gsub("%%26path%%3d","&path=")
- end
- if FPATH == "" then
- UFPATH = ""
- else
- EPLFILE = io.open(FPATH, "r")
- local contents = EPLFILE:read()
- EPLFILE:close()
- UFPATH = "" .. url_escape(contents)
- -- correct cruft escaping of "&path="
- UFPATH = UFPATH:gsub("%%26path%%3d","&path=")
- end
- if LANGUAGE == "" then
- ULANGUAGE=""
- else
- ULANGUAGE="&language=" .. LANGUAGE
- end
- UOFILE = OFILE .. "." .. IMAGETYPE
- IMGURL = GMURL .. "?" .. ULOCATION .. USIZE .. UZOOM .. UMARKERS .. UTYPE .. USCALE .. UIMAGETYPE .. UVISIBLE .. UIPATH .. UFPATH .. ULANGUAGE .. "&sensor=false&key=AIzaSyDXlmAP7TENopGqgCkW9Ec3Wymno3a2cBg"
-elseif MODE == "gsv" then
- ULOCATION = "location=" .. url_escape(LOCATION)
- USIZE = "&size=" .. url_escape(SIZE)
- UHEADING = "&heading=" .. url_escape(HEADING)
- UFOV = "&fov=" .. url_escape(FOV)
- UPITCH = "&pitch=" .. url_escape(PITCH)
- UOFILE = OFILE .. ".jpg"
- IMGURL = GSVURL .. "?" .. ULOCATION .. USIZE .. UHEADING .. UFOV .. UPITCH .. "&sensor=false&key=AIzaSyDXlmAP7TENopGqgCkW9Ec3Wymno3a2cBg"
-elseif MODE == "osm" then
- UKEY = "?key=" .. url_escape(KEY)
- ULOCATION = "&location=" .. url_escape(LOCATION)
- USIZE = "&size=" .. url_escape(SIZE)
- if ZOOM == "" then
- USCALEZOOM = "&scale=" .. url_escape(SCALE)
- else
- USCALEZOOM = "&zoom=" .. url_escape(ZOOM)
- end
- UTYPE = "&type=" .. url_escape(TYPE)
- UIMAGETYPE = "&imagetype=" .. url_escape(IMAGETYPE)
- USHOWICON = "&showicon=" .. url_escape(COLOR) .. "-" .. url_escape(NUMBER)
- UOFILE = OFILE .. "." .. IMAGETYPE
- IMGURL = OSMURL .. UKEY .. ULOCATION .. USIZE .. USCALEZOOM .. UTYPE .. UIMAGETYPE .. USHOWICON
-end
-
-local ret, msg
-local ofile
-ofile, msg = io.open(UOFILE, "wb")
-if not ofile then
- getmap_error(21, msg)
-end
-print("\n\ngetmapdl.lua:")
-print("url = " .. IMGURL)
-print("url length = " .. string.len(IMGURL) .. " bytes")
-print("output = " .. UOFILE)
-if string.len(IMGURL) > 2048 then
- getmap_error(23, "URL exceeds length limit of 2048 bytes!")
-end
-ret, msg = http.request{
- url = IMGURL,
- sink = ltn12.sink.file(ofile)
-}
-if not ret then
- getmap_error(22, msg)
-end
-os.exit(0)
diff --git a/Build/source/texk/texlive/linked_scripts/git-latexdiff/git-latexdiff b/Build/source/texk/texlive/linked_scripts/git-latexdiff/git-latexdiff
deleted file mode 100755
index 028dc9befde..00000000000
--- a/Build/source/texk/texlive/linked_scripts/git-latexdiff/git-latexdiff
+++ /dev/null
@@ -1,907 +0,0 @@
-#!/bin/bash
-
-# Main author: Matthieu Moy <git@matthieu-moy.fr>
-# (See the Git history for other contributors)
-#
-# BSD 2-Clause License
-#
-# Copyright (c) 2012 - 2020, Matthieu Moy
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright notice, this
-# list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# git-latexdiff is a wrapper around latexdiff
-# (http://www.ctan.org/pkg/latexdiff) that allows using it to diff two
-# revisions of a LaTeX file.
-#
-# The script internally checks out the full tree for the specified
-# revisions, calls latexpand to flatten the document and then calls
-# latexdiff-so (if available, otherwise latexdiff). Therefore,
-# this works if the document is split into multiple .tex files.
-#
-# Try "git latexdiff -h" for more information.
-#
-# To install, just copy git-latexdiff in your $PATH.
-
-# Missing features (patches welcome ;-):
-# - diff the index
-# - hardlink temporary checkouts as much as possible
-
-# Alternatives:
-#
-# There is another script doing essentially the same here:
-# https://github.com/cawka/latexdiff/blob/master/latexdiff-git
-# My experience is that latexdiff-git is more buggy than
-# git-latexdiff, but they probably just don't have the same bugs ;-)
-#
-# There are a bunch of other alternatives cited here:
-#
-# http://tex.stackexchange.com/questions/1325/using-latexdiff-with-git
-#
-# Ideally, these scripts should be merged.
-
-set -o errexit
-set -o pipefail
-set -o noclobber
-# Used when symlinking files from the working tree: symlink .* files
-# too.
-shopt -s dotglob
-
-# Some versions of git set $GIT_WORK_TREE when ran through an alias.
-# This wouldn't work with git-latexdiff which plays with different
-# work trees.
-unset GIT_DIR
-unset GIT_WORK_TREE
-
-# (Comment and 'unset' line borrowed from Git's source code)
-# Having this variable in your environment would break scripts because
-# you would cause "cd" to be taken to unexpected places. If you
-# like CDPATH, define it for your interactive shell sessions without
-# exporting it.
-# But we protect ourselves from such a user mistake nevertheless.
-unset CDPATH
-
-# 1.6.0 is substituted by the install script here,
-# but not within git_latexdiff_compute_version().
-git_latexdiff_version='1.6.0'
-
-git_latexdiff_compute_version () {
- if [ "$git_latexdiff_version" = '@GIT_LATEXDIFF''_VERSION@' ]; then
- (cd "$(dirname "$0")" && git describe --tags HEAD 2>/dev/null || echo 'Unknown version')
- else
- echo "$git_latexdiff_version"
- fi
-}
-
-usage () {
- cat << EOF
-Usage: $(basename "$0" | sed 's/git-/git /') [options] OLD [NEW]
- $(basename "$0" | sed 's/git-/git /') [options] OLD --
- $(basename "$0" | sed 's/git-/git /') [options] -- OLD
-Call latexdiff on two Git revisions of a file.
-
-OLD and NEW are Git revision identifiers. NEW defaults to HEAD.
-If "--" is used for NEW, then diff against the working directory.
-
-Options:
- --help this help message
- --help-examples show examples of usage
- --main <file> name of the main LaTeX, R Sweave,
- or Emacs Org mode file.
- The search for the only file containing 'documentclass'
- will be attempted, if not specified.
- For non-LaTeX files, a reasonable \`prepare\` command
- will be used unless explicitly provided
- --no-view don't display the resulting PDF file
- --latex run latex instead of pdflatex
- --xelatex run xelatex instead of pdflatex
- --lualatex run lualatex instead of pdflatex
- --tectonic run tectonic instead of pdflatex
- --bibtex, --bbl display changes in the bibliography
- (runs bibtex to generate *.bbl files and
- include them in the source file using
- latexpand --expand-bbl before computing
- the diff)
- --biber like --bibtex, but runs biber instead.
- --run-bibtex, -b run bibtex as well as latex to generate the PDF file
- (pdflatex,bibtex,pdflatex,pdflatex)
- NOTE: --bibtex usually works better
- --run-biber run BibLaTex-Biber as well as latex to generate the PDF file
- (pdflatex,biber,pdflatex,pdflatex)
- NOTE: --biber usually works better
- --view view the resulting PDF file
- (default if -o is not used)
- --pdf-viewer <cmd> use <cmd> to view the PDF file (default: \$PDFVIEWER)
- --no-cleanup don't cleanup temp dir after running
- --no-flatten don't call latexpand to flatten the document
- --cleanup MODE Cleanup temporary files according to MODE:
-
- - keeppdf (default): keep only the
- generated PDF file
-
- - none: keep all temporary files
- (may eat your diskspace)
-
- - all: erase all generated files.
- Problematic with --view when the
- viewer is e.g. evince, and doesn't
- like when the file being viewed is
- deleted.
-
- --latexmk use latexmk
- --build-dir use pdfs from specific build directory
- --latexopt pass additional options to latex (e.g. -shell-escape)
- -o <file>, --output <file>
- copy resulting PDF into <file> (usually ending with .pdf)
- Implies "--cleanup all"
- --tmpdirprefix where temporary directory will be created (default: /tmp).
- Relative path will use repository root as a base
- --verbose, -v give more verbose output
- --quiet redirect output from subprocesses to log files
- --prepare <cmd> run <cmd> before latexdiff (e.g. run make to generate
- included files)
- --filter <cmd> run <cmd> after latexdiff and before compilation
- (e.g. to fix up latexdiff output)
- --ln-untracked symlink uncommited files from the working directory
- --version show git-latexdiff version.
- --subtree checkout the tree at and below the main file
- (enabled by default, disable with --whole-tree)
- --whole-tree checkout the whole tree (contrast with --subtree)
- --ignore-latex-errors keep on going even if latex gives errors, so long as
- a PDF file is produced
- --ignore-makefile ignore the Makefile, build as though it doesn't exist
- -* other options are passed directly to latexdiff
- --latexpand OPT pass option OPT to latexpand. Use multiple times like
- --latexpand OPT1 --latexpand OPT2 to pass multiple options.
- --latexdiff-flatten use --flatten from latexdiff instead of latexpand
-
-Unrecognized options are passed unmodified to latexdiff.
-EOF
-}
-
-examples () {
- cat <<EOF
-Examples:
-
-Diff the previous revision with the latest commit:
-
- git latexdiff HEAD^
-
-Diff the latest commit with the working tree:
-
- git latexdiff HEAD --
-
-Diff latest commit with branch master:
-
- git latexdiff master HEAD
-
-Pass --type=CHANGEBAR to latexdiff to get changebars in the margins
-instead of red+trike/blue+underline diff:
-
- git latexdiff --type=CHANGEBAR HEAD^
-
-Use a specific latexdiff configuration file:
-
- git latexdiff --config /path/to/file HEAD^
-EOF
-}
-
-die () {
- echo "fatal: $*"
- exit 1
-}
-
-verbose () {
- if test "$verbose" = 1 ; then
- printf "%s ..." "$@"
- fi
-}
-
-verbose_progress () {
- if test "$verbose" = 1 ; then
- printf "."
- fi
-}
-
-verbose_done () {
- if test "$verbose" = 1 ; then
- echo " ${1:-done}."
- fi
-}
-
-verbose_say () {
- if test "$verbose" = 1 ; then
- printf "%s\n" "$@"
- fi
-}
-
-old=
-new=
-main=
-view=maybe
-cleanup=keeppdf
-verbose=0
-bibtex=0
-biber=0
-output=
-initial_dir=$PWD
-tmpdir_prefix="/tmp"
-prepare_cmd=
-flatten=1
-subtree=1
-uselatexmk=
-use_build_dir=
-latexopt=
-ln_untracked=0
-quiet=0
-ignorelatexerrors=0
-latexdiffopt=()
-latexpand=()
-bbl=0
-latexdiff_flatten=0
-latex=0
-xelatex=0
-lualatex=0
-tectonic=0
-BIBTEX_EXEC=bibtex
-
-while test $# -ne 0; do
- case "$1" in
- "--help"|"-h")
- usage
- exit 0
- ;;
- "--help-examples")
- examples
- exit 0
- ;;
- "--main")
- test $# -gt 1 && shift || die "missing argument for $1"
- main=$1
- ;;
- "--no-view")
- view=0
- ;;
- "--view")
- view=1
- ;;
- "--pdf-viewer")
- test $# -gt 1 && shift || die "missing argument for $1"
- PDFVIEWER="$1"
- ;;
- "--no-cleanup")
- cleanup=none
- ;;
- "--ignore-latex-errors")
- ignorelatexerrors=1
- ;;
- "--cleanup")
- shift
- case "$1" in
- "none"|"all"|"keeppdf")
- cleanup="$1"
- ;;
- *)
- echo "Bad argument --cleanup $1"
- usage
- exit 1
- ;;
- esac
- ;;
- "--no-flatten")
- flatten=0
- ;;
- "--ignore-makefile")
- ignoremake=1
- ;;
- "-o"|"--output")
- test $# -gt 1 && shift || die "missing argument for $1"
- output=$1
- cleanup=all
- ;;
- "-b"|"--bibtex")
- bbl=1
- ;;
- "--latex")
- latex=1
- ;;
- "--xelatex")
- xelatex=1
- ;;
- "--lualatex")
- lualatex=1
- ;;
- "--tectonic")
- tectonic=1
- ;;
- "--biber")
- BIBTEX_EXEC=biber
- bbl=1
- ;;
- "--run-bibtex")
- bibtex=1
- ;;
- "--run-biber")
- biber=1
- ;;
- "--verbose"|"-v")
- verbose=1
- ;;
- "--quiet")
- quiet=1
- ;;
- "--version")
- git_latexdiff_compute_version
- exit 0
- ;;
- "--subtree")
- subtree=1
- ;;
- "--whole-tree")
- subtree=0
- ;;
- "--prepare")
- shift
- prepare_cmd="$1"
- ;;
- "--filter")
- shift
- filter_cmd="$1"
- ;;
- "--build-dir")
- test $# -gt 1 && shift || die "missing argument for $1"
- use_build_dir=$1
- ;;
- "--latexmk")
- uselatexmk=1
- ;;
- "--latexpand")
- shift
- latexpand=("${latexpand[@]}" "$1")
- ;;
- "--bbl")
- bbl=1
- ;;
- "--latexdiff-flatten")
- latexdiff_flatten=1
- flatten=0
- ;;
- "--latexopt")
- shift
- latexopt=$1
- ;;
- "--ln-untracked")
- ln_untracked=1
- ;;
- "--no-ln-untracked")
- ln_untracked=0
- ;;
- "--tmpdirprefix")
- shift
- tmpdir_prefix="$1"
- ;;
- -*)
- if test "$1" = "--" ; then
- if test -z "$new" ; then
- new=$1
- else
- echo "Bad argument $1"
- usage
- exit 1
- fi
- else
- case "$1" in
- '--type'|'-t'|'--subtype'|'-s'|'--floattype'|'-f'|\
- '--config'|'-c'|'-p'|'--encoding'|'-e'|\
- '--label'|'-L'|'--exclude-safecmd'|'-A'|\
- '--replace-safecmd'|'--append-safecmd'|'-a'|\
- '--exclude-textcmd'|'-X'|'--replace-textcmd'|\
- '--append-textcmd'|'-x'|'--replace-context1cmd'|\
- '--append-context1cmd'|'--replace-context2cmd'|\
- '--append-context2cmd'|'--packages'|'--math-markup'|\
- '--driver')
- # Options taking an immediate argument in
- # latexdiff => add both the option and its
- # argument.
- latexdiffopt+=("$1" "$2")
- shift
- ;;
- '--preamble')
- # Same, but with a file argument. Make it
- # absolute to avoid issues when cd-ing
- # somewhere else.
- absolute="$(cd $(dirname "$2"); pwd)/$(basename "$2")"
- latexdiffopt+=("$1" "$absolute")
- shift
- ;;
- *)
- latexdiffopt+=("$1")
- ;;
- esac
- fi
- ;;
- *)
- if test -z "$1" ; then
- echo "Empty string not allowed as argument"
- usage
- exit 1
- elif test -z "$old" ; then
- old=$1
- elif test -z "$new" ; then
- new=$1
- else
- echo "Bad argument $1"
- usage
- exit 1
- fi
- ;;
- esac
- shift
-done
-
-initial_repo=$(git rev-parse --show-toplevel)
-
-if test -z "$new" ; then
- new=HEAD
-fi
-
-if test -z "$old" ; then
- echo "fatal: Please, provide at least one revision to diff with."
- usage
- exit 1
-fi
-
-if test -z "$PDFVIEWER" ; then
- verbose "Auto-detecting PDF viewer"
- candidates="xdg-open evince okular xpdf acroread"
- if test "$(uname)" = Darwin ; then
- # open exists on GNU/Linux, but does not open PDFs
- candidates="open $candidates"
- fi
-
- for command in $candidates; do
- if command -v "$command" >/dev/null 2>&1; then
- PDFVIEWER="$command"
- break
- else
- verbose_progress
- fi
- done
- verbose_done "$PDFVIEWER"
-fi
-
-case "$view" in
- maybe|1)
- if test -z "$PDFVIEWER" ; then
- echo "warning: could not find a PDF viewer on your system."
- echo "warning: Please set \$PDFVIEWER or use --pdf-viewer CMD."
- PDFVIEWER=false
- fi
- ;;
-esac
-
-if test $flatten = 1 &&
- ! command -v latexpand 2>/dev/null; then
- echo "Warning: latexpand not found. Falling back to latexdiff --flatten."
- latexdiff_flatten=1
- flatten=0
-fi
-
-if test $latex = 1; then
- LATEX_EXEC=latex
-elif test $xelatex = 1; then
- LATEX_EXEC=xelatex
-elif test $lualatex = 1; then
- LATEX_EXEC=lualatex
-elif test $tectonic = 1; then
- LATEX_EXEC=tectonic
-else
- LATEX_EXEC=pdflatex
-fi
-
-if test $biber = 1; then
- BIBTEX_EXEC=biber
-fi
-
-## end option parsing ##
-
-check_knitr () {
- if test -z "$prepare_cmd"; then
- prepare_cmd="Rscript -e \"library(knitr); knit('$main')\""
- fi
- main="${main%\.*}.tex"
-}
-
-check_org () {
- if test -z "$prepare_cmd"; then
- prepare_cmd="emacs --batch --eval \"(load \\\"~/.emacs\\\")\" \"$main\" -f org-latex-export-to-latex --kill"
- fi
- main="${main%\.*}.tex"
-}
-
-log_cmd () {
- log=$1
- shift
- if [ "$quiet" = 1 ]; then
- "$@" >$log 2>&1
- else
- "$@"
- fi
-}
-
-# main is relative to initial_dir (if returned)
-if test -z "$main" ; then
- printf "%s" "No --main provided, trying to guess ... "
- main=$(git grep -l '^[ \t]*\\documentclass')
- # May return multiple results, but if so the result won't be a file.
- if test -r "$main" ; then
- echo "Using $main as the main file."
- else
- if test -z "$main" ; then
- echo "No candidate for main file."
- else
- echo "Multiple candidates for main file:"
- printf "%s\n" "$main" | sed 's/^/\t/'
- fi
- die "Please, provide a main file with --main FILE.tex."
- fi
-fi
-
-if test ! -r "$main" ; then
- die "Cannot read $main."
-fi
-
-ext=${main##*\.}
-case "$ext" in
- Rnw) check_knitr ;;
- Rtex) check_knitr ;;
- org) check_org ;;
- *) ;;
-esac
-
-# Set LATEXDIFF_EXEC to either latexdiff or latexdiff-so. Prefer
-# latexdiff-so if available.
-if command -v latexdiff-so >/dev/null 2>&1; then
- LATEXDIFF_EXEC=latexdiff-so
-elif command -v latexdiff >/dev/null 2>&1; then
- LATEXDIFF_EXEC=latexdiff
-else
- die "latexdiff-so and latexdiff couldn't be found. Check your PATH."
-fi
-verbose_done "$LATEXDIFF_EXEC"
-
-verbose "Creating temporary directories"
-
-git_prefix=$(git rev-parse --show-prefix)
-git_dir="$(git rev-parse --git-dir)" || die "Not a git repository?"
-cd "$(git rev-parse --show-cdup)" || die "Can't cd back to repository root"
-git_dir=$(cd "$git_dir"; pwd)
-git_worktree=$(pwd)
-
-relative_main_dir=$(dirname "$main")
-# make main relative to git root directory
-if test -n "$git_prefix" ; then
- main=$git_prefix$main
-fi
-mainbase=$(basename "$main" .tex)
-maindir=$(dirname "$main")
-
-tmpdir=$tmpdir_prefix/git-latexdiff.$$
-mkdir "$tmpdir" || die "Cannot create temporary directory."
-
-cd "$tmpdir" || die "Cannot cd to $tmpdir"
-if test "$(uname -o 2>/dev/null)" = "Msys"; then
- tmpdir=$(pwd -W)
-else
- tmpdir=$(pwd)
-fi
-
-mkdir old new || die "Cannot create old and new directories."
-
-verbose_done
-verbose_say "Temporary directories: $tmpdir/old and $tmpdir/new"
-verbose "Checking out old and new version"
-
-cd old || die "Cannot cd to old/"
-if test "$ln_untracked" = 1; then
- (
- mkdir -p "$maindir" && cd "$maindir" &&
- log_cmd ln-old.log ln -s "$initial_repo"/"$maindir"/* .
- ) || true
-fi
-
-if test "$subtree" = 1 && test -n "$git_prefix"; then
- checkoutroot=$git_prefix
-else
- checkoutroot="."
-fi
-# create the build directory (containing the final PDFs) if the param was set
-if test -n "$use_build_dir" ; then
- builddir="$use_build_dir"
-else
- builddir="$relative_main_dir"
-fi
-
-# Checkout a subtree, without touching the index ("git checkout" would)
-(cd "$git_dir" && git archive --format=tar "$old" "$checkoutroot") | tar -xf -
-# Also expand the possible submodules
-(cd "$git_worktree" && git submodule foreach --recursive 'git archive --format=tar "$sha1" | tar -xf - --directory '$tmpdir/old'/$displaypath')
-verbose_progress
-cd ../new || die "Cannot cd to new/"
-if test "$new" == "--"; then
- # Copy working tree files
- (cd "$git_worktree" && git ls-files -- "$checkoutroot" | tar -cf - -T -) | tar -xf -
-else
- # checkout new revision
- (cd "$git_dir" && git archive --format=tar "$new" "$checkoutroot") | tar -xf -
- (cd "$git_worktree" && git submodule foreach --recursive 'git archive --format=tar "$sha1" | tar -xf - --directory '$tmpdir/new'/$displaypath')
-fi
-if test "$ln_untracked" = 1; then
- (
- mkdir -p "$maindir" && cd "$maindir" &&
- log_cmd ln-new.log ln -s "$initial_repo"/"$maindir"/* .
- ) || true
-fi
-
-verbose_progress
-cd ..
-
-verbose_done
-
-for dir in old new
-do
- verbose "Running preparation command $prepare_cmd in $dir/$git_prefix"
- ( cd "$dir/$git_prefix/" && log_cmd prepare.log eval "$prepare_cmd" )
- if test ! -f "$dir/$main"; then
- die "$prepare_cmd did not produce $dir/$main."
- fi
- verbose_done
-done
-
-if test $tectonic != 1; then
- if [ "$ignorelatexerrors" = 1 ]; then
- latexopt="$latexopt -interaction=batchmode"
- elif [ "$quiet" = 1 ]; then
- latexopt="$latexopt -interaction=nonstopmode"
- else
- latexopt="$latexopt -interaction=errorstopmode"
- fi
-fi
-
-# Option to use latexdiff --flatten instead of latexpand
-if test "$latexdiff_flatten" = 1; then
- latexdiffopt+=("--flatten")
-fi
-
-# Shortcut to include bbl
-if test "$bbl" = 1; then
- if test "$biber" = 1; then
- bblexpand=("--expand-bbl" "$mainbase.bbl")
- # In theory, this (with recent enough latexpand) should work
- # better. In practice it doesn't seem to work though.
- # bblexpand=("--biber" "$mainbase.bbl")
- else
- bblexpand=("--expand-bbl" "$mainbase.bbl")
- fi
-else
- bblexpand=()
-fi
-
-ignore_errors_maybe() {
- if [ "$compile_error" = 1 ] && [ "$ignorelatexerrors" = 1 ]; then
- echo "LaTeX errors were found - but attempting to carry on."
- compile_error=0
- fi
-}
-
-# Create flattened documents and keep for debugging
-if test "$flatten" = 1; then
- if [ "$bbl" = 1 ]; then
- if [ ! -f "old/$maindir$mainbase.bbl" ]; then
- verbose "Attempting to regenerate missing old/$maindir$mainbase.bbl"
- oldPWD=$PWD
- cd old/"$maindir"
- log_cmd pdflatex0.log $LATEX_EXEC $latexopt "$mainbase" || {
- compile_error=1
- error_msg="command 'pdflatex' (automatically run in old due to --bbl) failed."
- }
- log_cmd "$BIBTEX_EXEC"0.log $BIBTEX_EXEC "$mainbase" || {
- compile_error=1
- error_msg="command '$BIBTEX_EXEC' (automatically run in old due to --bbl) failed."
- }
- cd "$oldPWD"
- ignore_errors_maybe
- if [ "$compile_error" = 1 ]; then
- die "Failed to regenerate .bbl for old version"
- fi
- fi
- if [ ! -f "new/$maindir$mainbase.bbl" ]; then
- verbose "Attempting to regenerate missing new/$maindir$mainbase.bbl"
- oldPWD=$PWD
- cd new/"$maindir"
- log_cmd pdflatex0.log $LATEX_EXEC $latexopt "$mainbase" || {
- compile_error=1
- error_msg="command 'pdflatex' (automatically run in new due to --bbl) failed."
- }
- log_cmd "$BIBTEX_EXEC"0.log $BIBTEX_EXEC "$mainbase" || {
- compile_error=1
- error_msg="command '$BIBTEX_EXEC' (automatically run in new due to --bbl) failed."
- }
- cd "$oldPWD"
- ignore_errors_maybe
- if [ "$compile_error" = 1 ]; then
- die "Failed to regenerate .bbl for new version"
- fi
- fi
- fi
- verbose "Running latexpand"
- (
- cd old/"$maindir" &&
- latexpand "$mainbase".tex "${latexpand[@]}" "${bblexpand[@]}"
- ) > old-"$mainbase"-fl.tex \
- || die "latexpand failed for old version"
- (
- cd new/"$maindir" &&
- latexpand "$mainbase".tex "${latexpand[@]}" "${bblexpand[@]}"
- ) > new-"$mainbase"-fl.tex \
- || die "latexpand failed for new version"
- verbose_done
-
- verbose "Running $LATEXDIFF_EXEC ${latexdiffopt[*]} old-${mainbase}-fl.tex new-${mainbase}-fl.tex > ./diff.tex"
- "$LATEXDIFF_EXEC" "${latexdiffopt[@]}" old-"$mainbase"-fl.tex new-"$mainbase"-fl.tex > diff.tex \
- || die "$LATEXDIFF_EXEC failed"
- verbose_done
-
- verbose "mv ./diff.tex new/$main"
- mv -f new/"$main" new/"$main".orig
- mv -f diff.tex new/"$main"
- verbose_done
-else
- verbose "Running $LATEXDIFF_EXEC ${latexdiffopt[*]} old/$main new/$main > ./diff.tex"
- "$LATEXDIFF_EXEC" "${latexdiffopt[@]}" old/"$main" new/"$main" > diff.tex \
- || die "$LATEXDIFF_EXEC failed"
- verbose_done
-
- verbose "mv ./diff.tex new/$main"
- mv -f new/"$main" new/"$main.orig"
- mv -f diff.tex new/"$main"
- verbose_done
-fi
-
-if [ ! -z "$filter_cmd" ]; then
- verbose "Running filter command $filter_cmd in new/"
- ( cd "new/" && log_cmd filter.log eval "$filter_cmd" )
- if [ ! -f "new/$main" ]; then
- die "$filter_cmd removed new/$main."
- fi
- verbose_done
-fi
-
-verbose "Compiling result"
-
-compile_error=0
-
-oldPWD=$PWD
-cd new/"$maindir" || die "Can't cd to new/$maindir"
-if test -f Makefile && test "$ignoremake" != 1 ; then
- log_cmd make.log make || {
- compile_error=1
- error_msg="command 'make' failed."
- }
-elif test "$uselatexmk" = 1; then
- log_cmd latexmk.log latexmk -f -pdf -silent $latexopt "$mainbase" || {
- compile_error=1
- error_msg="command 'latexmk' failed."
- }
-elif test "$tectonic" = 1; then
- log_cmd tectonic.log tectonic $latexopt "$mainbase.tex" || {
- compile_error=1
- error_msg="command 'tectonic' failed."
- }
-else
- log_cmd pdflatex1.log $LATEX_EXEC $latexopt "$mainbase" || {
- compile_error=1
- error_msg="command pdflatex (first run) failed."
- }
- if test "$bibtex" = 1 || test "$biber" = 1 ; then
- log_cmd "$BIBTEX_EXEC".log $BIBTEX_EXEC "$mainbase" || {
- compile_error=1
- error_msg="command '$BIBTEX_EXEC' failed."
- }
- fi
- log_cmd pdflatex2.log $LATEX_EXEC $latexopt "$mainbase" || {
- compile_error=1
- error_msg="command 'pdflatex' (second run) failed."
- }
- log_cmd pdflatex3.log $LATEX_EXEC $latexopt "$mainbase" || {
- compile_error=1
- error_msg="command 'pdflatex' (third run) failed."
- }
-fi
-cd "$oldPWD"
-
-# Same relative path as where we've been called from, but in the
-# temporary new/ directory:
-cd new/"$git_prefix"
-
-verbose_done
-
-ignore_errors_maybe
-
-if test $latex = 1; then
- dvips "$mainbase".dvi
- ps2pdf "$mainbase".ps
-fi
-
-pdffile="$builddir/$mainbase".pdf
-if test ! -r "$pdffile" ; then
- echo "No PDF file generated."
- echo "Working directory: $PWD"
- echo "Expected PDF: $pdffile"
- compile_error=1
-elif test ! -s "$pdffile" ; then
- echo "PDF file generated is empty."
- compile_error=1
-fi
-
-if test "$compile_error" = "1" ; then
- echo "Error during compilation. Please examine and cleanup if needed:"
- echo "Directory: $tmpdir/new/$maindir"
- echo " File: $mainbase.tex"
- echo " Problem: $error_msg"
- # Don't clean up to let the user diagnose.
- exit 1
-fi
-
-if test -n "$output" ; then
- abs_pdffile="$PWD/$pdffile"
- (cd "$initial_dir" && mv "$abs_pdffile" "$output")
- pdffile="$output"
- echo "Output written on $pdffile"
-elif [ -f "$pdffile" ]; then
- new_pdffile="$tmpdir"/"$mainbase".pdf
- mv "$pdffile" "$new_pdffile"
- pdffile="$new_pdffile"
-fi
-
-# Change directory so nothing will keep us from cleaning
-cd "$initial_dir"
-
-if test "$view" = 1 || ( test "$view" = maybe && test -z "$output" ) ; then
- "$PDFVIEWER" "$pdffile"
-fi
-
-case "$cleanup" in
- "all")
- verbose "Cleaning-up result"
- rm -fr "$tmpdir"
- verbose_done
- ;;
- "keeppdf")
- verbose "Cleaning-up all but pdf (kept in $pdffile)"
- rm -fr "$tmpdir"/old "$tmpdir"/new
- verbose_done
- ;;
- "none")
- verbose_say "Generated files kept in $tmpdir/"
- ;;
-esac
diff --git a/Build/source/texk/texlive/linked_scripts/glossaries/makeglossaries b/Build/source/texk/texlive/linked_scripts/glossaries/makeglossaries
deleted file mode 100755
index fe1e1248d9b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/glossaries/makeglossaries
+++ /dev/null
@@ -1,1679 +0,0 @@
-#!/usr/bin/env perl
-
-# File : makeglossaries
-# Author : Nicola Talbot
-# Version : 4.45
-# Description: simple Perl script that calls makeindex or xindy.
-# Intended for use with "glossaries.sty" (saves having to remember
-# all the various switches)
-
-# This file is distributed as part of the glossaries LaTeX package.
-# Copyright 2019 Nicola L.C. Talbot
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.3
-# of this license or any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3 or later is part of all distributions of LaTeX
-# version 2005/12/01 or later.
-#
-# This work has the LPPL maintenance status `maintained'.
-#
-# The Current Maintainer of this work is Nicola Talbot.
-
-# This work consists of the files glossaries.dtx and glossaries.ins
-# and the derived files glossaries.sty, glossaries-prefix.sty,
-# glossary-hypernav.sty, glossary-inline.sty, glossary-list.sty,
-# glossary-long.sty, glossary-longbooktabs.sty, glossary-longragged.sty,
-# glossary-mcols.sty, glossary-super.sty, glossary-superragged.sty,
-# glossary-tree.sty, glossaries-compatible-207.sty,
-# glossaries-compatible-307.sty, glossaries-accsupp.sty,
-# glossaries-babel.sty, glossaries-polyglossia.sty, glossaries.perl.
-# Also makeglossaries and makeglossaries-lite.lua.
-
-my $version="4.45 (2020-01-18)";
-
-# History:
-# v4.43:
-# * No change.
-# v4.41:
-# * No change.
-# v4.40:
-# * No change.
-# v4.39:
-# * No change.
-# v4.38:
-# * No change.
-# v4.37:
-# * No change.
-# v4.36:
-# * No change.
-# v4.35:
-# * No change.
-# v4.34:
-# * Added check for \glsxtr@resource
-# v4.33:
-# * Version number synchronized with glossaries.sty
-# v2.21:
-# * Fixed spelling of \GlsAddXdyLocation
-# * Adjusted range encap clash
-# v2.20 (2016/12/16)
-# * Added check for \glsxtr@makeglossaries
-# v2.19 (2016/05/27)
-# * Improved check in &parse_for_xindy_nosort
-# v2.18 (2016/01/24)
-# * Added &parse_for_xindy_nosort to help diagnose xindy's empty
-# index key warning/error.
-# * Added check for makeindex's multiple encap warning.
-# v2.17 (2015/11/30)
-# * Escaped { in regular expressions.
-# http://www.dickimaw-books.com/cgi-bin/bugtracker.cgi?action=view&key=101
-# v2.16 (2015/06/28)
-# * Added check for "german" and codepage that doesn't contain
-# "din5007", "duden" or "braille". If missing, "din5007-" is
-# prefixed to the codepage.
-# v2.15 (2014/07/30)
-# * Removed hard-coded three character extension assumption
-# www.dickimaw-books.com/cgi-bin/bugtracker.cgi?action=view&key=55
-# * Added message to indicate the number of ignored glossaries
-# when the extension is specified.
-# v2.14 (2014/03/06)
-# * Added -Q and -k options
-# v2.13 (2014/01/21)
-# * Added check for leading and trailing quotes in filename
-# v2.12 (2014/01/20)
-# * Added check for '*' in istfilename
-# * Fixed bug report
-# http://www.dickimaw-books.com/cgi-bin/bugtracker.cgi?action=view&key=33
-# * Added error text hashes
-# v2.11 (2014/01/17):
-# * Added check for backslashes in -x, -m and -d paths
-# * Added double-quotes around $appname in &run_app
-# v2.10 (2013/12/01):
-# * initialise $language to suppress warnings
-# v2.09 (2013-11-12):
-# * added check for -q switch when issuing warnings.
-# v2.08 (2013-10-14):
-# * added -x and -m options
-# v2.07 (2013-06-17):
-# * added check for success on chdir if -d used
-# * added dialect map
-# v2.06 (2013-04-21):
-# * added "din5007" as default if language is set to "german"
-# v2.05 (2012-11-12):
-# * added -d option
-# v2.04 (2012-04-19):
-# * fixed bug in &scan_aux
-# v2.03 (2011-04-12):
-# * added warning about possibly needing 'nomain' package option
-# v2.02 (2011-04-2):
-# * Prints version number at start of run unless -q
-# * Added more diagnostics.
-# v2.01 (2010-09-29):
-# * Added 'use warnings'
-# v2.0 (2010-06-30) :
-# * Made file handle local in &scan_aux
-# v1.9 (2010-06-14) :
-# * Check for \@input
-# v1.8 (2009-11-03) :
-# * Create an empty output file if the input file is empty
-# without calling xindy/makeindex
-# v1.7 (2009-09-23) :
-# * Issue warning rather than error when empty/non existant file
-# checks fail
-# v1.6 (2009-05-24) :
-# * main glossary no longer automatically added
-# (only added if information in aux file)
-# * if file extension is specified, check added to ensure it
-# corresponds to a known glossary extension.
-# * added file existance test and file empty test
-# v1.5 (2008-12-26) :
-# * added support for xindy
-# * picks up ordering information from aux file
-# v1.4 (2008-05-10) :
-# * added support for filenames with spaces.
-# v1.3 (2008-03-08) :
-# * changed first line from /usr/bin/perl -w to /usr/bin/env perl
-# (Thanks to Karl Berry for suggesting this.)
-# v1.2 (2008-03-02) :
-# * added support for --help and --version
-# * improved error handling
-# v1.1 (2008-02-13) :
-# * added -w and strict
-# * added check to ensure .tex file not passed to makeglossaries
-#
-# v1.0 (2007-05-10) : Initial release.
-
-use Getopt::Std;
-use strict;
-# v2.01 added the following line
-use warnings;
-# v2.05 added $opt_d
-# v2.08 added $opt_x and $opt_m
-use vars qw($opt_q $opt_t $opt_o $opt_s $opt_p $opt_g $opt_c $opt_r
- $opt_l $opt_i $opt_L $opt_n $opt_C $opt_d $opt_x $opt_m $opt_Q
- $opt_k);
-
-
-$Getopt::Std::STANDARD_HELP_VERSION = 1;
-
-# v1.5 added -L <lang> for xindy (but language can be specified in
-# .tex file)
-# v1.5 added -n (print the command that would be issued but
-# don't actually run the command)
-getopts('s:o:t:p:L:C:ilqQkrcgnd:x:m:');
-
-unless ($#ARGV == 0)
-{
- die "makeglossaries: Need exactly one file argument.\n",
- "Use `makeglossaries --help' for help.\n";
-}
-
-# v2.02: added:
-print "makeglossaries version $version\n" unless ($opt_q);
-
-# v2.07: added babel dialect -> xindy language map:
-my %languagemap =
-(
- 'american' => 'english',
- 'austrian' => 'german',
- 'british' => 'english',
- 'francais' => 'french',
- 'frenchb' => 'french',
- 'germanb' => 'german',
- 'lsorbian' => 'lower-sorbian',
- 'magyar' => 'hungarian',
- 'naustrian' => 'german',
- 'ngermanb' => 'german',
- 'ngerman' => 'german', # v2.16
- 'norsk' => 'norwegian',
- 'portuges' => 'portuguese',
- 'russianb' => 'russian',
- 'slovene' => 'slovenian',
- 'UKenglish' => 'english',
- 'USenglish' => 'english',
- 'ukraineb' => 'ukrainian',
- 'usorbian' => 'upper-sorbian'
-);
-
-# v2.07 added check for success and for -q
-# v2.05 added:
-
-if ($opt_d)
-{
- # v2.11 check for backslash character if on Windows
- $opt_d=~s/\\/\//g if $^O=~/Win/;
-
- if (chdir $opt_d)
- {
- print "Changed to '$opt_d'\n" unless ($opt_q);
- }
- else
- {
- die "Unable to chdir to '$opt_d' $!\n";
- }
-}
-
-# v2.02: added:
-# v2.19: changed value
-my $xdynotist = 2;
-# v2.13: removed
-#my $needcompatibilitymode=2;
-
-# v2.13: added $istnotfound
-my $istnotfound = 3;
-
-# v2.13: added error text:
-my %makeindex_error_text =
- (
- $xdynotist => "Style name indicates makeindex, but may be in xindy format.\n"
- . "Remember to use \\setStyleFile to specify the name\n"
- . "of the style file rather than redefining \\istfilename\n"
- . "explicitly.",
- $istnotfound => "Style file not found. (Have you used \\noist by mistake?)"
- );
-
-my %xindy_error_text =
- (
- 'nosort' => "Sort key required for entries only containing command names.",
- 'istnotxdy' =>
- "Style name has xdy extension, but may be in makeindex format.\n"
- . "Remember to use \\setStyleFile to specify the name\n"
- . "of the style file rather than redefining \\istfilename\n"
- . "explicitly.",
- 'missingendquote' =>
- "You may have missed a \" character in a command such as \\GlsAddXdyLocation.",
- 'nolanguage' =>
- "No language detected.\nHave you remembered to use \\printglossary\n".
- "or \\printglossaries in your document?",
- 'nomain' =>
- "\nRemember to use package option 'nomain' if you don't\n".
- "want to use the main glossary.",
-#v2.21: fixed spelling of \GlsAddXdyLocation
- 'badlocation' =>
- "You may have forgotten to add a location \n"
- . "class with \\GlsAddXdyLocation or you may have \n"
- . "the format incorrect.\n",
- 'comp207' => "You may need to add 'compatible-2.07' package option.",
- 'noxdyfile' => "Style file not found. (Have you used \\noist by mistake?)"
- );
-
-# define known extensions
-
-# v1.6: removed adding main glossary here as there's no guarantee
-# that it's been used. If it has been used, the information will
-# be picked up later in the aux file
-my %exttype = (
-# main => {in=>'glo', out=>'gls', 'log'=>'glg'},
- );
-
-# v1.5 define require languages for xindy
-
-my %language = ();
-my %codepage = ();
-
-my $ext = '';
-my $name = $ARGV[0];
-
-# v2.13 added:
-#$name=~s/^"(.*)"$/$1/;
-# v2.15: fix provided by Herb Schulz to allow for extensions that
-# aren't exactly three characters:
-# (HS) changes fix for 3 character extension limit
-my ($basename,$extension) = ($name =~ m/^(.*?)(?:\.([^\.]*))?$/);
-# (HS) end of changes fix for 3 character extension limit
-
-# make sure $extension is defined. (If there was no match in the
-# above, it cause an uninitialised error later.)
-$extension = '' unless ($extension);
-
-# Make sure users don't try passing the tex file:
-
-#if (length($ARGV[0]) > 3 and substr($ARGV[0],-4,1) eq ".")
-#{
-# $name = substr($ARGV[0],0,length($ARGV[0])-4);
-#
-# $ext = substr($ARGV[0],-3,3);
-#
-# if (lc($ext) eq 'tex')
-# (HS) changes fix for 3 character extension limit
-#if (length($ARGV[0]) > 3 and substr($ARGV[0],-4,1) eq ".")
-#{
-# $name = substr($ARGV[0],0,length($ARGV[0])-4);
-#
-# $ext = substr($ARGV[0],-3,3);
-#
-# if (lc($ext) eq 'tex')
- if (lc($extension) eq 'tex')
- {
- die("Don't pass the tex file to makeglossaries:\n"
- ."either omit the extension to make all the glossaries, "
- ."or specify one of the glossary files, e.g. $name.glo, to "
- ."make just that glossary.\n")
- }
-#}
-# (HS) end of fix for 3 character extension limit
-
-# (HS) changes fix for 3 character extension limit
-$ext = $extension;
-$name = $basename;
-# (HS) end of changes fix for 3 character extension limit
-
-# v2.01 add check to see if aux file exists
-
-unless (-e "$name.aux")
-{
- die "Auxiliary file '$name.aux' doesn't exist. Have you run LaTeX?\n";
-}
-
-my $istfile = "";
-
-my $glslist = "";
-
-# should letter ordering be used? (v1.5 added)
-
-my $letterordering = defined($opt_l);
-
-# v2.19 added:
-my $extramkidxopts = '';
-
-# v4.34 added:
-my $foundbib2glsresource = '';
-
-# Check aux file for other glossary types,
-# style file name and various other bits of information.
-
-&scan_aux($name);
-
-# has the style file been specified?
-unless ($istfile)
-{
- if ($foundbib2glsresource)
- {
- die "Found \\glsxtr\@resource in '$name.aux',\n",
- "but not found \\\@istfilename.\n",
- "You need to run bib2gls not makeglossaries.\n";
- }
- else
- {
- die "No \\\@istfilename found in '$name.aux'.\n",
- "Did your LaTeX run fail?\n",
- "Did your LaTeX run produce any output?\n",
- "Did you remember to use \\makeglossaries?\n";
- }
-}
-
-# v2.08 added $xindyapp and $makeindexapp
-# By default assume they are on the operating system's path
-my $xindyapp = ($opt_x ? $opt_x :'xindy');
-my $makeindexapp = ($opt_m ? $opt_m :'makeindex');
-
-# v2.11 check for backslash character if on Windows
-if ($^O=~/Win/)
-{
- $xindyapp=~s/\\/\//g;
- $makeindexapp=~s/\\/\//g;
-}
-
-# v1.5 save the general xindy switches
-
-my $xdyopts = '';
-
-# v2.01 replaced 'unless ($opt_L eq "")' with 'if ($opt_L)'
-if ($opt_L)
-{
- $xdyopts .= " -L $opt_L";
-}
-
-# save all the general makeindex switches
-
-my $mkidxopts = '';
-
-if ($opt_i)
-{
- $mkidxopts .= " -i";
-}
-
-if ($letterordering)
-{
- $mkidxopts .= " -l";
- $xdyopts .= " -M ord/letorder";
-}
-
-if ($opt_q)
-{
-# v2.01 removed following lines. (This script now deals with
-# printing messages to STDOUT.)
- #$mkidxopts .= " -q";
- #$xdyopts .= " -q";
-}
-
-if ($opt_r)
-{
- $mkidxopts .= " -r";
-}
-
-if ($opt_c)
-{
- $mkidxopts .= " -c";
-}
-
-if ($opt_g)
-{
- $mkidxopts .= " -g";
-}
-
-# v2.01 replaced 'unless ($opt_p eq "")' with 'if ($opt_p)'
-if ($opt_p)
-{
- $mkidxopts .= " -p $opt_p";
-}
-
-if ($extramkidxopts)
-{
- $mkidxopts .= " $extramkidxopts";
-}
-
-# v2.01 replaced 'unless ($opt_s eq "")' with 'if ($opt_s)'
-if ($opt_s)
-{
- # v2.01 check if user has specified -s <file>.ist but aux file
- # indicates .xdy ought to be used and vice-versa. Also check if
- # requested style file exists
-
- unless (-e $opt_s)
- {
- die "\n",
- "Requested style file '$opt_s' doesn't exist.\n\n";
- }
-
- if ($istfile=~/\.xdy$/ and $opt_s!~/\.xdy$/)
- {
- die "\n",
- "The auxiliary file indicates that you should be using xindy,\n",
- "but you have specified makeindex style file '$opt_s'\n",
- "Make sure you don't specify 'xindy' as a package option if\n",
- "you want to use makeindex.\n\n",
- "\\usepackage[makeindex]{glossaries}\n\n";
- }
- elsif ($istfile!~/\.xdy$/ and $opt_s=~/\.xdy$/)
- {
- die "\n",
- "The auxiliary file indicates that you should be using\n",
- "makeindex, but you have specified xindy style file '$opt_s'.\n",
- "Make sure you specify 'xindy' as a package option if you\n",
- "want to use xindy.\n\n",
- "\\usepackage[xindy]{glossaries}\n\n";
- }
-
- $istfile = $opt_s;
-}
-
-# Use xindy if style file ends with .xdy otherwise use makeindex
-
-my $usexindy = ($istfile=~m/\.xdy\Z/);
-
-if ($ext)
-{
- # an extension has been specified, so only process
- # the specified file
-
- # v1.6 %thistype is no longer given a default value
- my %thistype;
-
- my $thislang = "";
- my $thiscodepage = "";
-
- my @types = ($glslist ? split /,/, $glslist : keys %exttype);
-
- foreach my $type (@types)
- {
- if ($exttype{$type}{'in'} eq $ext)
- {
- %thistype = %{$exttype{$type}};
-
- $thislang = $language{$type};
-
- $thiscodepage = $codepage{$type};
-
- last;
- }
- }
-
- # v1.6 If %thistype hasn't been defined, then the given
- # extension doesn't correspond to any known glossary type
-
- # v2.01 replaced deprecated 'defined(%thistype)' with %thistype
- unless (%thistype)
- {
- die "The file extension '$ext' doesn't correspond to any\n",
- "known glossary extension. Try running makeglossaries\n",
- "without an extension, e.g. makeglossaries \"$name\".\n";
- }
-
- my $outfile;
-
-# v2.01 replaced 'if ($opt_o eq "")' with 'unless ($opt_o)'
- unless ($opt_o)
- {
- $outfile = "$name.$thistype{out}";
- }
- else
- {
- $outfile = $opt_o;
- }
-
- my $transcript;
-
-# v2.01 replaced 'if ($opt_t eq "")' with 'unless ($opt_t)'
- unless ($opt_t)
- {
- $transcript = "$name.$thistype{'log'}";
- }
- else
- {
- $transcript = $opt_t;
- }
-
-# v2.01 remove old transcript file
-
- unless ($opt_n)
- {
- unlink($transcript);
- }
-
- if ($usexindy)
- {
- &xindy("$name.$ext", $outfile, $transcript,$istfile,
- $thislang, $thiscodepage, $xdyopts, $opt_q, $opt_n, $xindyapp);
- }
- else
- {
- &makeindex("$name.$ext",$outfile,$transcript,$istfile,
- $mkidxopts,$opt_q, $opt_n, $makeindexapp, 1);
- }
-
-
- # v2.15 added:
-
- my $num_omitted = $#types;
-
- if ($num_omitted == 1)
- {
- print "1 glossary ignored.\n" unless $opt_q;
- }
- elsif ($num_omitted > 1)
- {
- print "$num_omitted glossaries ignored.\n" unless $opt_q;
- }
-}
-else
-{
- # no file extension specified so process all glossary types
-
- my @types = ($glslist ? split /,/, $glslist : keys %exttype);
-
- foreach my $type (@types)
- {
- my %thistype = %{$exttype{$type}};
-
- my $inputfile = "$name.$thistype{in}";
-
- my $outfile;
-
-# v2.01 changed 'if ($opt_o eq "")' with 'unless ($opt_o)'
- unless ($opt_o)
- {
- $outfile = "$name.$thistype{out}";
- }
- else
- {
- $outfile = $opt_o;
- }
-
- # v1.7 print warnings to STDOUT instead of STDERR
-
- # v1.6 added file existence test
- unless (-e $inputfile)
- {
- # v2.09 suppress warning if -q switch in use
- print "Warning: File '$inputfile' doesn't exist.\n",
- "*** Skipping glossary '$type'. ***\n" unless ($opt_q);
- next;
- }
-
- unless (-r $inputfile)
- {
- print "Warning: No read access for '$inputfile' $!\n",
- "*** Skipping glossary '$type'. ***\n" unless ($opt_q);
- next;
- }
-
- my $transcript;
-
-# v2.01 changed 'if ($opt_t eq "")' with 'unless ($opt)'
- unless ($opt_t)
- {
- $transcript = "$name.$thistype{'log'}";
- }
- else
- {
- $transcript = $opt_t;
- }
-
- # v1.6 added file empty test
- if (-z $inputfile)
- {
- my $message =
- "Warning: File '$inputfile' is empty.\n".
- "Have you used any entries defined in glossary '$type'?\n";
-
- if ($type eq 'main')
- {
- $message .=
- "Remember to use package option 'nomain' if you\n".
- "don't want to use the main glossary.\n";
- }
-
- # v2.09 suppress warning if -q switch in use
- warn $message unless $opt_q;
-
- # Write warning to transcript file.
-
- if (open TRANSFD, ">$transcript")
- {
- print TRANSFD $message;
- close TRANSFD;
- }
-
- # create an empty output file and move on to the next glossary
-
- if (open OFD, ">$outfile")
- {
- print OFD "\\null\n";
- close OFD;
- }
- else
- {
- warn "Unable to create '$outfile' $!\n";
- }
-
- next;
- }
-
-# v2.01 remove old transcript file
-
- unless ($opt_n)
- {
- unlink($transcript);
- }
-
- if ($usexindy)
- {
- &xindy($inputfile,$outfile,$transcript,$istfile,
- $language{$type},$codepage{$type},
- $xdyopts,$opt_q,$opt_n, $xindyapp);
- }
- else
- {
- &makeindex($inputfile,$outfile,$transcript,
- $istfile,$mkidxopts,$opt_q,$opt_n, $makeindexapp, 1);
- }
- }
-}
-
-sub scan_aux{
- my $name = shift;
-
- # v2.0 added
- local(*AUXFILE);
-
- if (open AUXFILE, "$name.aux")
- {
- while (<AUXFILE>)
- {
- #v2.14 added
- if (m/\\\@gls\@reference/ and not $glslist)
- {
- die "Your document has used \\makenoidxglossaries\n",
- "You don't need makeindex or xindy.\n";
- }
-
- if (m/\\glsxtr\@makeglossaries\{(.*)\}/)
- {
- #v2.20 added
-
- $glslist = $1;
-
- unless ($opt_q)
- {
- print "only processing subset '$glslist'\n";
- }
- }
- elsif (m/\\\@input\{(.+)\.aux\}/)
- {
- # v1.9 added
- # v2.17 escaped { in regex
- &scan_aux($1);
-
- # v2.04 added
- # (Fix provided by Daniel Grund)
- next;
- }
- elsif (m/\\\@newglossary\s*\{(.*)\}\{(.*)\}\{(.*)\}\{(.*)\}/)
- {
- # v2.17 escaped { in regex
-
- $exttype{$1}{'log'} = $2;
- $exttype{$1}{'out'} = $3;
- $exttype{$1}{'in'} = $4;
-
- unless ($opt_q)
- {
- print "added glossary type '$1' ($2,$3,$4)\n";
- }
- }
- elsif (m/\\\@istfilename\s*\{([^}]*)\}/)
- {
- # v2.17 escaped { in regex
-
- $istfile = $1;
-
- # check if double quotes were added to \jobname
- # v2.12 added check for xdy (bug ID 33)
- $istfile=~s/^"(.*)"\.(ist|xdy)$/$1.$2/;
-
- # v2.12 if on Windows, substitute any '*' with ' '
- # to compensate for MiKTeX bug
- # http://sourceforge.net/p/miktex/bugs/2301/
-
- if ($^O=~/Win/)
- {
- $istfile=~tr/\*/ /;
- }
- }
- elsif (m/\\\@xdylanguage\s*\{([^}]+)\}\{([^}]*)\}/)
- {
- # v1.5 added
- # v2.17 escaped { in regex
-
- $language{$1} = $2;
- }
- elsif (m/\\\@gls\@codepage\s*\{([^}]+)\}\{([^}]*)\}/)
- {
- # v1.5 added
- # v2.17 escaped { in regex
-
- $codepage{$1} = $2;
- }
- elsif (m/\\\@gls\@extramakeindexopts\{(.*)\}/)
- {
- # v2.19 added
-
- $extramkidxopts .= $1;
- }
- elsif (m/\\glsxtr\@resource/)
- {
- # v4.34 added
-
- # No error at this point as a hybrid method is allowed.
- # Error only occurs if no \@istfilename found.
-
- $foundbib2glsresource = 1;
- }
-
- # v1.5 added
- # Allow -l switch to override specification in aux file
- unless (defined($opt_l))
- {
- # v2.17 escaped { in regex
- if (m/\\\@glsorder\s*\{([^}]+)\}/)
- {
- my $ordering = $1;
-
- if ($ordering eq "word")
- {
- $letterordering = 0;
- }
- elsif ($ordering eq "letter")
- {
- $letterordering = 1;
- }
- else
- {
- warn
- "Unknown ordering '$ordering'\n",
- "Assuming word ordering\n" unless ($opt_q);
- $letterordering = 0;
- }
- }
- }
- }
-
- close AUXFILE;
- }
- else
- {
- warn "Unable to open $name.aux: $!\n";
- }
-}
-
-# v2.01 new subroutine run_app added
-sub run_app{
- my($appname, $appargs, $trans, $quiet, $dontexec) = @_;
-
- local(*STATUS);
-
- my $status = '';
- my $warnings = '';
- my $errno = 0;
- my $log = '';
-
- print "$appname $appargs\n" if ($dontexec or not $quiet);
-
- return if ($dontexec);
-
- # v2.11 added double-quotes around $appname
- # v2.14 added -k switch
- if (not $opt_k and open (STATUS, "\"$appname\" $appargs 2>&1 |"))
- {
- while (<STATUS>)
- {
- print unless ($quiet);
-
- $warnings .= $_ if (/WARNING:/);
-
- $status .= $_ unless (/^[\w]+ing/ or /^Finished/ or /^Usage:/);
-
- $log .= $_;
- }
-
- close STATUS;
- }
- else
- {
- unless ($opt_k)
- {
- $warnings = "Unable to fork \"$appname\" with redirection $!\n";
-
- # v2.14 added check for quiet switches
- warn $warnings,
- "Retrying without redirection.\n" unless ($quiet or $opt_Q);
- }
-
- $status = `\"$appname\" $appargs`;
-
- $log = $status;
-
- print $status unless ($quiet);
- }
-
- if ($?)
- {
- # v2.14 Fixed error number assignment
- $errno = ($? >> 8);
-
- # v2.14 Added check for existence of transcript
- unless (-e $trans)
- {
- $log .= "\n$appname didn't create a transcript.\n";
-
- if (not $appname=~/\//)
- {
- # No path specified
- $log .= "Check that $appname has been installed and\nis on your system's PATH.\n";
-
- if (defined $ENV{PATH})
- {
- $log .= "Your PATH environment variable is set to: \n"
- . $ENV{PATH} . "\n";
- }
- else
- {
- $log .= "I'm sorry, I can't detect your PATH environment variable\n";
- }
-
- $log .= "Try manually running:\n\"$appname\" $appargs\n";
- }
- elsif (not -e $appname)
- {
- if ($^O=~/Win/)
- {
- if (-e "$appname.exe" or -e "$appname.bat")
- {
- $log .= "Try manually running:\n\"$appname\" $appargs\n";
- }
- else
- {
- $log .= "File '$appname' doesn't exist.\n";
- }
- }
- else
- {
- $log .= "File '$appname' doesn't exist.\n";
- }
- }
- else
- {
- $log .= "Try manually running:\n\"$appname\" $appargs\n";
- }
- }
-
- if (open LOGFILE, ">>$trans")
- {
- print LOGFILE "\n\n*** Unable to execute: '\"$appname\" $appargs' ***\n\n";
- print LOGFILE "Failed with error code $errno.\n\n";
-
- if ($log)
- {
- print LOGFILE "Status report:\n\n";
- print LOGFILE "$log", "\n";
- }
-
- print LOGFILE "Warnings:\n\n",$warnings, "\n" if $warnings;
- close LOGFILE;
- }
- else
- {
- warn "Unable to open '$trans' $!\n";
- }
- }
-
- if ($log=~/\(0 entries accepted,/
- or ( ($log=~/(\d+) warnings?/ and $1 gt 0))
- or $log=~/not found/)
- {
- # Attempt to diagnose what's gone wrong
-
- if (open TRANS, $trans)
- {
- while (<TRANS>)
- {
- if (/Index style file .* not found/)
- {
- $errno = $istnotfound;
- last;
- }
- elsif (/Unknown specifier ;/)
- {
- $errno = $xdynotist;
- last;
- }
- elsif (/## Warning \(.*\):\s*$/)
- {
- $warnings .= $_ . <TRANS>;
- }
- }
-
- close TRANS;
- }
-
- }
-
- return ($status, $warnings, $errno);
-}
-
-# v2.08 added $app parameter
-sub makeindex{
- my($in,$out,$trans,$ist,$rest,$quiet,$dontexec,$app,$repairencaps) = @_;
-
- my $args = "$rest -s \"$ist\" -t \"$trans\" -o \"$out\" \"$in\"";
-
-# v2.01 replaced code with call to &run_app
-
- my ($status, $warnings, $errno)
- = &run_app($app, $args, $trans, $quiet, $dontexec);
-
- return if ($dontexec);
-
- if ($errno)
- {
- my $diagnostic = '';
-
- if ($makeindex_error_text{$errno})
- {
- $diagnostic = $makeindex_error_text{$errno};
- }
- else
- {
- $diagnostic = "Can't find diagnostic message for error code $errno";
- }
-
- if (open LOGFILE, ">>$trans")
- {
- print LOGFILE "\nmakeglossaries diagnostic messages:\n$diagnostic\n";
- close LOGFILE;
- }
-
- die "\n***Call to makeindex failed***\n",
- ($diagnostic ?
- "\nPossible cause of problem:\n\n". $diagnostic . "\n\n":
- "\n"
- ),
- "Check '$trans' for details\n";
- }
-
- # 2.18: added check and repair for multiple encaps
- if ($warnings)
- {
- warn $warnings unless $quiet;
-
- if ($repairencaps and $warnings=~/multiple encaps/)
- {
- unless ($quiet)
- {
- print "Multiple encaps detected. Attempting to remedy.\n";
- print "Reading $in...\n";
- }
-
- # if $in can't be opened at this point something wrong
- # has occurred (otherwise how did makeindex manage to open
- # it?)
-
- open INFD, $in or die "Can't open '$in' $!\n";
-
- my @entries = ();
-
- while (<INFD>)
- {
- if (/\\glossaryentry\{(.*)\|([^\|]*)\}\{(.*?)\}/)
- {
- my %entry =
- (
- 'entry' => $1,
- 'encap' => $2,
- 'location' => $3
- );
-
- my $add = 1;
-
- for (my $idx = 0; $idx <= $#entries; $idx++)
- {
- my $existing = $entries[$idx];
-
- if ($entry{'entry'} eq $existing->{'entry'}
- and $entry{'location'} eq $existing->{'location'}
- and $entry{'encap'} ne $existing->{'encap'})
- {
- $add = 0 if ($add == 1);
-
- # Range encaps should take precedence.
-
- if ($entry{'encap'}=~/^[\(\)]/)
- {
- $add = 2;
-
- if ($existing->{'encap'}=~/^[\(\)]/)
- {
- # too complicated, keep both
-
- last;
- }
- else
- {
- # remove existing
-
- splice @entries, $idx, 1;
-
- $idx--;
- }
- }
- elsif ($existing->{'encap'}=~/^[\(\)]/)
- {
- if ($entry{'encap'}=~/^[\(\)]/)
- {
- # too complicated, keep both
-
- $add = 1;
- last;
- }
- # (otherwise drop new entry)
- }
- elsif (&encap_overrides($entry{'encap'},
- $existing->{'encap'}))
- {
- $entries[$idx] = \%entry;
- }
- }
- }
-
- push @entries, \%entry if $add > 0;
- }
- else
- {
- warn "Abandoning attempt. Can't parse: $_" unless $quiet;
-
- close INFD;
- return;
- }
- }
-
- close INFD;
-
- if (open OUTFD, ">$in")
- {
- print "Writing $in...\n" unless $quiet;
-
- foreach my $entry (@entries)
- {
- print OUTFD '\\glossaryentry{',
- $entry->{'entry'}, '|',
- $entry->{'encap'}, '}{',
- $entry->{'location'}, '}', "\n";
- }
-
- close OUTFD;
-
- print "Retrying\n" unless $quiet;
-
- &makeindex($in,$out,$trans,$ist,$rest,$quiet,$dontexec,$app,0);
- }
- else
- {
- warn "Can't open '$in' $!\n" unless $quiet;
- }
- }
- }
-}
-
-# 2.18 new
-# This is a subroutine in case of possible extension.
-# For example, what happens in the event of 'textbf' and 'emph'?
-# Should one override the other or be combined? Combining is harder
-# as it would need a corresponding LaTeX command. (bib2gls deals
-# with this better through its --map-formats switcn.)
-# 2.21 check for range encap moved earlier
-
-sub encap_overrides{
- my ($newencap, $existing) = @_;
-
- ($existing=~/\\glsnumberformat\s*$/ or $newencap!~/\\glsnumberformat\s*$/ )
-}
-
-# v2.08 added $app parameter
-sub xindy{
- my($in,$out,$trans,$ist,$language,$codepage,$rest,$quiet,
- $dontexec, $app) = @_;
- my($args, $langparam, $main, $retry);
- my($module);
-
- $module = $ist;
- $module=~s/\.xdy\Z//;
-
- if ($language)
- {
- # map babel names to xindy names
-
- $language = $languagemap{$language} if ($languagemap{$language});
-
- $langparam = "-L $language";
- }
- else
- {
- $langparam = "";
- # v2.10 initialise $language to suppress warnings
- $language = "";
- }
-
- # most languages work with xindy's default codepage, but
- # some don't, so if the codepage isn't specific, check
- # the known cases that will generate an error
- # and supply a default. (For all other cases, it's up to the
- # user to supply a codepage.)
-
-# v2.01 changed 'if ($codepage eq "")' to 'unless ($codepage)'
- unless ($codepage)
- {
- if ($language eq 'dutch')
- {
- $codepage = "ij-as-ij";
- }
- elsif ($language eq 'german')
- {
- $codepage = "din5007";
- }
- elsif ($language eq 'gypsy')
- {
- $codepage = "northrussian";
- }
- elsif ($language eq 'hausa')
- {
- $codepage = "utf";
- }
- elsif ($language eq 'klingon')
- {
- $codepage = "utf";
- }
- elsif ($language eq 'latin')
- {
- $codepage = "utf";
- }
- elsif ($language eq 'mongolian')
- {
- $codepage = "cyrillic";
- }
- elsif ($language eq 'slovak')
- {
- $codepage = "small";
- }
- elsif ($language eq 'spanish')
- {
- $codepage = "modern";
- }
- elsif ($language eq 'vietnamese')
- {
- $codepage = "utf";
- }
- }
- elsif ($language eq 'german' and $codepage!~/(din5007|duden|braille)/)
- {
-#v2.16 added check for german din/duden
-
- $codepage = "din5007-$codepage";
- }
-
-
- my $codepageparam = "";
-
- if ($codepage)
- {
- $codepageparam = "-C $codepage";
- }
-
- $main = join(' ',
- "-I xindy",
- "-M \"$module\"",
- "-t \"$trans\"",
- "-o \"$out\"",
- "\"$in\"");
-
- $args = join(' ', $rest, $langparam, $codepageparam, $main);
-
-# v2.01 replaced code with call to &run_app
-
- my ($status, $warnings, $errno)
- = &run_app($app, $args, $trans, $quiet, $dontexec);
-
- return if ($dontexec);
-
- if ($status=~/Cannot locate xindy module for language ([^\s]+) in codepage ([^\s]+)/)
- {
- $args = join(' ', $rest, $langparam, $main);
-
- unless ($quiet)
- {
- my $message = "$&\nRetrying using default codepage.\n";
-
- warn $message;
-
- $retry .= $message;
- }
-
- ($status, $warnings, $errno)
- = &run_app('xindy', $args, $trans, $quiet, $dontexec);
-
- }
-
- if ($status=~/Cannot locate xindy module for language ([^\s]+)/
- and $1 ne 'general')
- {
- $args = join(' ', $rest, "-L general", $main);
-
- unless ($quiet)
- {
- my $message = "$&\nRetrying with -L general\n";
-
- warn $message;
- $retry .= $message;
- }
-
- ($status, $warnings, $errno)
- = &run_app('xindy', $args, $trans, $quiet, $dontexec);
-
- }
-
- if ($errno)
- {
- # attempt further diagnostic
-
- my $diagnostic = '';
-
- if ($status=~/index 0 should be less than the length of the string/m)
- {
- $diagnostic = $xindy_error_text{nosort};
-
- $diagnostic .= &parse_for_xindy_nosort($in);
- }
- elsif ($status=~/variable .+ has no value/m)
- {
- # v2.19 fixed misspelt key
- $diagnostic = $xindy_error_text{istnotxdy};
- }
- elsif ($status=~/Could not find file /m)
- {
- # v2.19 added
- $diagnostic = $xindy_error_text{noxdyfile};
- }
- elsif ($status=~/Possible read-error due to ill-formed string " :sep/m)
- {
- $diagnostic = $xindy_error_text{missingendquote};
- }
- elsif (not $language)
- {
- # If the language hasn't been set, then it may be
- # because the document doesn't contain
- # \printglossaries/\printglossary or it may be
- # because the user has a customized style file that
- # contains the language settings.
-
- $diagnostic = $xindy_error_text{nolanguage};
-
- if ($in eq 'glo')
- {
- # or it may be that the user doesn't want to use the main
- # glossary and has forgotten to suppress it with the
- # "nomain" package option
-
- $diagnostic .= $xindy_error_text{nomain};
- }
- }
-
- # v2.19 added:
- if ($diagnostic and open LOGFILE, ">>$trans")
- {
- print LOGFILE "\nmakeglossaries diagnostic messages:\n\n$diagnostic\n";
- close LOGFILE;
- }
-
- die "\n***Call to xindy failed***\n",
- ($diagnostic ?
- "\nPossible cause of problem:\n\n". $diagnostic . "\n\n":
- "\n"),
- "Check '$trans' for details\n";
- }
-
- # Check xindy warnings
-
- if ($status=~/^WARNING:/m)
- {
- my $diagwarn = '';
-
- if ($status=~/did not match any location-class/m)
- {
- $diagwarn = $xindy_error_text{badlocation};
- }
-
- if ($status=~/unknown attribute `pageglsnumberformat'/m)
- {
- $diagwarn .= $xindy_error_text{comp207};
- }
-
- if ($status=~/Would replace complete index key by empty string, ignoring/m)
- {
- $diagwarn .= $xindy_error_text{nosort};
- $diagwarn .= &parse_for_xindy_nosort($in);
- }
-
- if ($diagwarn)
- {
- warn "\n**Warning:**\n\n", $diagwarn, "\n";
-
- $warnings .= "\nmakeglossaries diagnostic messages:\n\n"
- . $diagwarn;
- }
- }
-
- if ($retry or $warnings)
- {
- if (open LOGFILE, ">>$trans")
- {
- print LOGFILE "\n$warnings";
-
- if ($retry)
- {
- print LOGFILE "\nmakeglossaries messages:\n\n", $retry;
- }
-
- close LOGFILE;
- }
- else
- {
- warn "Unable to open '$trans' $!\n";
- }
- }
-}
-
-# v2.18 added:
-sub parse_for_xindy_nosort{
- my ($in) = @_;
-
- my $msg = join("\n", "",
- "Attempting to determine which entries have problem sort keys.",
- "Parsing '$in'");
-
- my %entries = ();
-
- if (open FD, $in)
- {
- while (<FD>)
- {
-# v2.19 extra conditions added
- if (/:tkey \(\("((?:\\\\[a-zA-Z@]+ *)+)" "\\\\glossentry\{(.*)\}"\) \)/)
- {
- my $label = $2;
-
- unless ($entries{$label})
- {
- $entries{$label}->{sort} = $label;
- $entries{$label}->{suggestion} = $label;
- $entries{$label}->{suggestion}=~s/([\\\s]+)//g;
-
- }
- }
- elsif (/:tkey \(\("(\\\\[a-zA-Z@]+ *{(?:\\\\[a-zA-Z@]+ *)+})+" "\\\\glossentry\{(.*)\}"\) \)/)
- {
-# name in the form \cs{\cs}
- my $label = $2;
-
- unless ($entries{$label})
- {
- $entries{$label}->{sort} = $1;
- $entries{$label}->{suggestion} = $label;
- $entries{$label}->{suggestion}=~s/^[a-zA-Z]+[:\-\.]//;
- $entries{$label}->{suggestion}=~s/([^\w]+)//g;
- }
- }
- elsif (/:tkey \(\("(\$\s*(?:\{?\\\\[a-zA-Z@]+ *\}?)+\$)" "\\\\glossentry\{(.*)\}"\) \)/)
- {
-# name in the form $\cs$
- my $label = $2;
-
- unless ($entries{$label})
- {
- $entries{$label}->{sort} = $1;
- $entries{$label}->{suggestion} = $label;
- $entries{$label}->{suggestion}=~s/^[a-zA-Z]+[:\-\.]//;
- $entries{$label}->{suggestion}=~s/([^\w]+)//g;
- }
- }
- }
-
- close FD;
-
- my @labels = keys %entries;
-
- my $n = $#labels+1;
-
- if ($n == 0)
- {
- $msg .= "\nCouldn't find anything! Sorry, I'm stumped.";
- }
- else
- {
- $msg .= ($n == 1 ? "\n1 problematic entry found:\n"
- : "\n$n problematic entries found:\n");
-
- foreach my $label (@labels)
- {
- my $thisentry = $entries{$label};
-
- $msg .= "\nLabel: '$label'. Sort value : '$thisentry->{sort}'";
- $msg .= "\n(Try adding sort={$thisentry->{suggestion}} to the definition.)";
- }
- }
- }
- else
- {
- $msg .= "\nFailed to open '$in' $!\n";
- }
-
- $msg;
-}
-
-sub HELP_MESSAGE{
- print "\nSyntax : makeglossaries [options] <filename>\n\n";
- print "For use with the glossaries package to pass relevant\n";
- print "files to makeindex or xindy.\n\n";
- print "<filename>\tBase name of glossary file(s). This should\n";
- print "\t\tbe the name of your main LaTeX document without any\n";
- print "\t\textension.\n";
- print "\nGeneral Options:\n\n";
- print "-o <gls>\tUse <gls> as the output file.\n";
- print "\t\t(Don't use -o if you have more than one glossary.)\n";
- print "-q\t\tQuiet mode.\n";
- print "-Q\t\tSilence unable to fork warning.\n";
- print "-k\t\tDon't try to use piped redirection.\n";
- print "-l\t\tLetter ordering.\n";
- print "-s <sty>\tEmploy <sty> as the style file.\n";
- print "-t <log>\tEmploy <log> as the transcript file.\n";
- print "\t\t(Don't use -t if you have more than one glossary\n";
- print "\t\tor the transcripts will be overwritten.)\n";
- print "-d <directory>\tDirectory in which the .aux, .glo etc files are located.\n",
- "\t\t(Default is the directory in which <filename> resides.)\n";
- print "-n\t\tPrint the command that would normally be executed,\n",
- "\t\tbut don't execute it.\n";
-
- print "\nXindy Options:\n\n";
- print "-L <language>\tUse <language>.\n";
- print "-x <file>\tFull path to xindy executable.\n",
- "\t\t(Default assumes xindy is on the operating system's path.)\n";
-
- print "\nMakeindex Options:\n";
- print "(See makeindex documentation for further details on these ";
- print "options.)\n\n";
- print "-c\t\tCompress intermediate blanks.\n";
- print "-g\t\tEmploy German word ordering.\n";
- print "-p <num>\tSet the starting page number to be <num>.\n";
- print "-r\t\tDisable implicit page range formation.\n";
- print "-m <file>\tFull path to makeindex executable.\n",
- "\t\t(Default assumes makeindex is on the operating system's path.)\n";
-}
-
-sub VERSION_MESSAGE{
-
- my $verYear = '';
-
- if ($version=~/(\d{4})-\d{2}-\d{2}/)
- {
- $verYear = "-$1";
- }
-
- print "Makeglossaries Version $version\n";
- print "Copyright (C) 2007$verYear Nicola L C Talbot\n";
- print "This material is subject to the LaTeX Project Public License.\n";
-}
-
-1;
-
-=head1 NAME
-
-makeglossaries - Calls makeindex/xindy for LaTeX documents using glossaries package
-
-=head1 SYNOPSIS
-
-B<makeglossaries> [B<-o> I<file>] [B<-q>] [B<-Q>] [B<-k>] [B<-n>]
-[B<-s> I<file>] [B<-t> I<file>] [B<-L> I<language>] [B<-c>] [B<-g>] [B<-l>]
-[B<-p> I<num>] [B<-r>] [B<-d> I<aux dir>] [B<-m> I<file>] [B<-x> I<file>]
-[B<--version>] [B<--help>] I<basename>
-
-=head1 DESCRIPTION
-
-B<makeglossaries> is designed for use with LaTeX documents that
-use the glossaries package. The mandatory argument I<basename> should
-be the name of the LaTeX document without the .tex extension.
-B<makeglossaries> will read the auxiliary file to determine whether
-B<makeindex> or B<xindy> should be called. All the information
-required to be passed to the relevant indexing application should
-also be contained in the auxiliary file, but may be overridden by
-the option arguments to B<makeglossaries>.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-q>
-
-Quiet mode. Reduces chatter to standard output.
-
-=item B<-Q>
-
-Silences warning about being unable to fork.
-
-=item B<-k>
-
-Don't try forking with piped redirection. (Lessens the
-effect of -q)
-
-=item B<-n>
-
-Print the commands that would normally be executed but don't run them.
-
-=item B<-o> I<file>
-
-Use I<file> as the output file. (Only suitable for documents
-containing a single glossary, otherwise each glossary will be
-overridden.)
-
-=item B<-s> I<file>
-
-Use I<file> as the style file. Note that if you use this option,
-you need to know whether B<makeindex> or B<xindy> will be called, as
-they have different style files.
-
-=item B<-t> I<file>
-
-Use I<file> as the transcript file.
-
-=item B<-l>
-
-Letter ordering.
-
-=item B<-L> I<language>
-
-This option only has an effect if B<xindy> is called. Sets the
-language. See B<xindy> documentation for further details.
-
-=item B<-c>
-
-Compress intermediate blanks (B<makeindex> only).
-
-=item B<-g>
-
-Employ German word ordering (B<makeindex> only).
-
-=item B<-p> I<num>
-
-Sets the starting page number to be I<num> (B<makeindex> only).
-
-=item B<-r>
-
-Disable implicit page range formation (B<makeindex> only).
-
-=item B<-d> I<aux dir>
-
-Specify the directory the .aux, .glo etc files are located.
-Defaults to the parent directory of the base file I<filename>.
-
-=item B<-m> I<file>
-
-Specify the full path name for B<makeindex> to I<file> in the
-event that B<makeindex> isn't on the operating system's path.
-
-=item B<-x> I<file>
-
-Specify the full path name for B<xindy> to I<file> in the
-event that B<xindy> isn't on the operating system's path.
-
-=item B<--version>
-
-Prints version number and exits.
-
-=item B<--help>
-
-Prints help message and exits.
-
-=back
-
-=head1 REQUIRES
-
-Perl, Getopt::Std, and makeindex or xindy (depending on glossaries
-package options).
-
-=head1 LICENSE
-
-This is free software distributed under the LaTeX Project Public
-License. There is NO WARRANTY.
-See L<http://www.latex-project.org/lppl.txt> for details.
-
-=head1 AUTHOR
-
-Nicola L. C. Talbot,
-L<http://www.dickimaw-books.com/>
-
-=head1 RECOMMENDED READING
-
-The glossaries manual:
-
- texdoc glossaries
-
-=cut
diff --git a/Build/source/texk/texlive/linked_scripts/glossaries/makeglossaries-lite.lua b/Build/source/texk/texlive/linked_scripts/glossaries/makeglossaries-lite.lua
deleted file mode 100755
index 5e2272ff094..00000000000
--- a/Build/source/texk/texlive/linked_scripts/glossaries/makeglossaries-lite.lua
+++ /dev/null
@@ -1,563 +0,0 @@
-#!/usr/bin/env texlua
---[[
- File : makeglossaries-lite.lua
- Author : Nicola Talbot
-
- Lua alternative to the makeglossaries Perl script.
-
- Since Lua has limitations, this script isn't an exact
- replacement to the Perl script. In particular the makeglossaries -d
- switch isn't implemented in this Lua version.
- This also doesn't provide the more detailed diagnostics that the Perl
- version does nor does it attempt any language mappings. Since xindy
- requires Perl, don't use this script if you want to use xindy. Instead
- use the Perl makeglossaries script.
-
- This file is distributed as part of the glossaries LaTeX package.
- Copyright 2019 Nicola L.C. Talbot
- This work may be distributed and/or modified under the
- conditions of the LaTeX Project Public License, either version 1.3
- of this license or any later version.
- The latest version of this license is in
- http://www.latex-project.org/lppl.txt
- and version 1.3 or later is part of all distributions of LaTeX
- version 2005/12/01 or later.
-
- This work has the LPPL maintenance status `maintained'.
-
- This work consists of the files glossaries.dtx and glossaries.ins
- and the derived files glossaries.sty, glossaries-prefix.sty,
- glossary-hypernav.sty, glossary-inline.sty, glossary-list.sty,
- glossary-long.sty, glossary-longbooktabs.sty, glossary-longragged.sty,
- glossary-mcols.sty, glossary-super.sty, glossary-superragged.sty,
- glossary-tree.sty, glossaries-compatible-207.sty,
- glossaries-compatible-307.sty, glossaries-accsupp.sty,
- glossaries-babel.sty, glossaries-polyglossia.sty, glossaries.perl.
- Also makeglossaries and makeglossaries-lite.lua.
-
- History:
- * 4.45:
- - no change.
- * 4.44:
- - no change.
- * 4.41:
- - no change.
- * 4.40:
- - no change.
- * 4.39:
- - corrected script name in version and help messages
- * 4.38:
- - no change.
- * 4.37:
- - no change.
- * 4.36:
- - fixed check for double-quotes (from \jobname when the file name
- contains spaces).
- * 4.35:
- - no change.
- * 4.34:
- - added check for \glsxtr@resource
- * 4.33:
- - version number synchronized with glossaries.sty
- * 1.3
- - added check for \glsxtr@makeglossaries
- * 1.2 (2016-05-27)
- - added check for \@gls@extramakeindexopts
- - added check for nil codepage
- * 1.1
- - changed first line from lua to texlua
---]]
-
-thisversion = "4.45 (2020-01-18)"
-
-quiet = false
-dryrun = false
-
-infile = nil
-outfile = nil
-styfile = nil
-logfile = nil
-
-isxindy = false
-
-isbib2gls = false
-
-xindylang = nil
-xindyexec = "xindy"
-
-makeindex_c = false
-makeindex_g = false
-letterorder = false
-makeindex_r = false
-makeindex_p = nil
-makeindex_extra = nil
-makeindex_m = "makeindex"
-
-function version()
-
- verYear = string.match(thisversion, "%d%d%d%d");
-
- print(string.format("makeglossaries-lite version %s", thisversion))
- print(string.format("Copyright (C) 2015-%s Nicola L C Talbot", verYear))
- print("This material is subject to the LaTeX Project Public License.")
-end
-
-function help()
- version()
- print([[
-Syntax : makeglossaries-lite [options] <filename>
-
-For use with the glossaries package to pass relevant
-files to makeindex or xindy.
-
-<filename> Base name of glossary file(s). This should
- be the name of your main LaTeX document without any
- extension. If you do add an extension, only that
- glossary file will be processed.
-
-General Options:
-
--o <gls> Use <gls> as the output file.
- (Don't use -o if you have more than one glossary.)
--s <sty> Employ <sty> as the style file.
--t <log> Employ <log> as the transcript file.
- (Don't use -t if you have more than one glossary
- or the transcripts will be overwritten.)
--q Quiet mode.
--l Letter ordering.
--n Print the command that would normally be executed,
- but don't execute it (dry run).
---help Print this help message.
---version Print the version.
-
-Xindy Options:
-
--L <language> Use <language>.
--x <file> Full path to xindy executable.
- (Default assumes xindy is on the operating system's path.)
-
-Makeindex Options:
-(See makeindex documentation for further details on these options.)
-
--c Compress intermediate blanks.
--g Employ German word ordering.
--p <num> Set the starting page number to be <num>.
--r Disable implicit page range formation.
--m <file> Full path to makeindex executable.
- (Default assumes makeindex is on the operating system's path.)
-
-This is a light-weight Lua alternative to the makeglossaries Perl script.
-If you want to use xindy, it's better to use the Perl makeglossaries version
-instead.
-
-]])
-end
-
-function dorun(name, glg, gls, glo, language, codepage)
-
- if isxindy then
- doxindy(name, glg, gls, glo, language, codepage)
- else
- domakeindex(name, glg, gls, glo)
- end
-
-end
-
-function doxindy(name, glg, gls, glo, language, codepage)
-
- if codepage == nil
- then
- codepage = "utf8"
- end
-
- cmd = string.format('"%s" -I xindy -L %s -C %s -M "%s" -t "%s" -o "%s"',
- xindyexec, language, codepage, styfile, glg, gls)
-
- if letterorder then cmd = string.format('%s -M ord/letorder', cmd) end
-
- if quiet then cmd = string.format('%s -q', cmd) end
-
- cmd = string.format('%s "%s"', cmd, glo)
-
- if dryrun then
-
- print(cmd)
-
- else
-
- assert(os.execute(cmd),
- string.format("Failed to execute '%s'", cmd))
-
- end
-
-end
-
-function domakeindex(name, glg, gls, glo)
-
- cmd = string.format('"%s"', makeindex_m)
-
- if makeindex_c then cmd = cmd .. " -c" end
-
- if makeindex_g then cmd = cmd .. " -g" end
-
- if letterorder then cmd = cmd .. " -l" end
-
- if makeindex_extra then cmd = cmd .. " " .. makeindex_extra end
-
- if quiet then cmd = cmd .. " -q" end
-
- if glg ~= nil then cmd = string.format('%s -t "%s"', cmd, glg) end
-
- if gls ~= nil then cmd = string.format('%s -o "%s"', cmd, gls) end
-
- if makeindex_p ~= nil then
- cmd = string.format("%s -p %s", cmd, makeindex_p)
- end
-
- if styfile ~= nil then
- cmd = string.format('%s -s "%s"', cmd, styfile)
- end
-
- cmd = string.format('%s "%s"', cmd, glo)
-
- if dryrun then
- print(cmd)
- else
- assert(os.execute(cmd),
- string.format("Failed to execute '%s'", cmd))
- end
-
-end
-
-if #arg < 1
-then
- error("Syntax error: filename expected. Use --help for help.")
-end
-
-i = 1
-
-while i <= #arg do
-
--- General Options
- if arg[i] == "-q" then
- quiet = true
- elseif arg[i] == "-n"
- then
- dryrun = true
- elseif arg[i] == "-o"
- then
- i = i + 1
- if i > #arg then error("-o requires a filename") end
- outfile = arg[i]
- elseif arg[i] == "-s"
- then
- i = i + 1
- if i > #arg then error("-s requires a filename") end
- styfile = arg[i]
- elseif arg[i] == "-t"
- then
- i = i + 1
- if i > #arg then error("-t requires a filename") end
- logfile = arg[i]
- elseif arg[i] == "--version"
- then
- version()
- os.exit()
- elseif arg[i] == "--help"
- then
- help()
- os.exit()
--- General options for the Perl version that aren't implemented by
--- this light-weight version:
- elseif (arg[i] == "-Q") or (arg[i] == "-k")
- then
- print(string.format("Ignoring option '%s' (only available with the Perl version).", arg[i]))
- elseif arg[i] == "-d"
- then
- error(string.format(
- "The '%s' option isn't available for this light-weight version.\nYou will need to use the Perl version instead.",
- arg[i]))
-
--- Xindy Options
- elseif arg[i] == "-L"
- then
- i = i + 1
- if i > #arg then error("-L requires a language name") end
- xindylang = arg[i]
- elseif arg[i] == "-x"
- then
- i = i + 1
- if i > #arg then error("-x requires a filename") end
- xindyexec = arg[i]
-
--- Makeindex Options
- elseif arg[i] == "-c"
- then
- makeindex_c = true
- elseif arg[i] == "-g"
- then
- makeindex_g = true
- elseif arg[i] == "-l"
- then
- letterorder = true
- elseif arg[i] == "-r"
- then
- makeindex_r = true
- elseif arg[i] == "-p"
- then
- i = i + 1
- if i > #arg then error("-p requires a page number") end
- makeindex_p = arg[i]
- elseif arg[i] == "-m"
- then
- i = i + 1
- if i > #arg then error("-m requires a filename") end
- makeindex_m = arg[i]
-
--- Unknown Option
- elseif string.sub(arg[i], 1, 1) == "-"
- then
- error(
- string.format("Syntax error: unknown option '%s'. Use '--help' for help.",
- arg[i]));
-
--- Input file
- elseif infile == nil
- then
- infile = arg[i]
- else
- error("Syntax error: only one filename permitted");
- end
-
- i = i + 1
-end
-
-if not quiet then
- print(string.format("makeglossaries.lua version %s", thisversion))
-end
-
-if infile == nil
-then
- error("Syntax error: missing filename")
-end
-
-i, j = string.find(infile, "%.%a*$")
-
-ext = nil
-inbase = infile
-
-if i ~= nil
-then
- ext = string.sub(infile, i, j);
-
- lext = string.lower(ext)
-
- inbase = string.sub(infile, 1, i-1);
-
- -- Just in case user has accidentally specified the aux or tex file
- if lext == ".aux" or lext == ".tex"
- then
- ext = nil
- infile = inbase
- end
-end
-
-auxfile = inbase..".aux"
-
-if not quiet then print(string.format("Parsing '%s'", auxfile)) end
-
-assert(io.input(auxfile),
- string.format("Unable to open '%s'", auxfile))
-
-aux = io.read("*a")
-
-if string.find(aux, "\\glsxtr@resource") ~= nil
-then
- isbib2gls = true
-end
-
-if styfile == nil
-then
-
--- v4.36: corrected check for double-quotes
-
- styfile = string.match(aux, "\\@istfilename{([^}]*)}")
- styfile = string.gsub(styfile, "\"", "");
-
- if styfile == nil
- then
- if isbib2gls
- then
- error([[
-No \@istfilename found but found \glsxtr@resource.
-You need to run bib2gls not makeglossaries-lite.
- ]])
- else
- error([[
-No \@istfilename found.
-Did your LaTeX run fail?
-Did your LaTeX run produce any output?
-Did you remember to use \makeglossaries?
- ]])
- end
- end
-end
-
-i = string.len(styfile)
-
-if string.sub(styfile, i-3, i) == ".xdy"
-then
- isxindy = true
-end
-
-if not letterorder
-then
- if string.match(aux, "\\@glsorder{letter}") ~= nil
- then
- letterorder = true
- end
-end
-
-makeindex_extra = string.match(aux, "\\@gls@extramakeindexopts{([^}]*%.?%a*)}")
-
-if dryrun then print("Dry run mode. No commands will be executed.") end
-
-onlyname = nil
-
-glossaries = {}
-
-for name, glg, gls, glo in
- string.gmatch(aux, "\\@newglossary{([^}]+)}{([^}]+)}{([^}]+)}{([^}]+)}") do
-
- if not quiet then
- print(string.format("Found glossary type '%s' (%s,%s,%s)",
- name, glg, gls, glo))
- end
-
- glossaries[name] = {}
-
- glossaries[name].glg = glg
- glossaries[name].gls = gls
- glossaries[name].glo = glo
-
- if "."..glo == ext then
-
- onlyname = name
-
- end
-
- if isxindy then
-
- if xindylang == nil then
- glossaries[name].language = string.match(aux,
- "\\@xdylanguage{"..name.."}{([^}]+)}");
- else
- glossaries[name].language = xindylang
- end
-
- glossaries[name].codepage = string.match(aux,
- "\\@gls@codepage{"..name.."}{([^}]+)}");
-
- end
-
-end
-
-onlytypes = string.match(aux, "\\glsxtr@makeglossaries{([^}]+)}")
-
-if onlytypes ~= nil
-then
- if not quiet then
- print(string.format("Only process subset: '%s'", onlytypes))
- end
-
- onlyglossaries = {}
-
- for name in string.gmatch(onlytypes, '([^,]+)') do
- onlyglossaries[name] = glossaries[name]
- end
-
- glossaries = onlyglossaries
-end
-
-if ext == nil
-then
-
- done = false
-
- for name, value in pairs(glossaries) do
-
- glg = value.glg
- gls = value.gls
- glo = value.glo
-
- if logfile == nil then
- glg = inbase .. "." .. glg
- else
- glg = logfile
- end
-
- if outfile == nil then
- gls = inbase .. "." .. gls
- else
- gls = outfile
- end
-
- glo = infile .. "." .. glo
-
- dorun(name, glg, gls, glo, value.language, value.codepage)
-
- done = true
- end
-
- if not done then
- error([[
-No \@newglossary commands found in aux file.
-Did you remember to use \makeglossaries?
-Did you accidentally suppress the default glossary using "nomain"
-and not provide an alternative glossary?
-]])
- end
-
-else
-
- if onlyname == nil then
-
- glo = infile
- gls = outfile
- glg = logfile
-
- language = xindylang
- codepage = 'utf8'
-
- if language == nil then language = 'english' end
-
- if gls == nil then gls = infile..".gls" end
-
- else
-
- value = glossaries[onlyname]
-
- glg = value.glg
- gls = value.gls
- glo = infile
-
- if logfile == nil then
- glg = inbase .. "." .. glg
- else
- glg = logfile
- end
-
- if outfile == nil then
- gls = inbase .. "." .. gls
- else
- gls = outfile
- end
-
- end
-
- if codepage == nil then
- codepage = 'utf8';
- end
-
- dorun(onlyname, glg, gls, glo, language, codepage)
-end
diff --git a/Build/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl b/Build/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl
deleted file mode 100755
index 8d965a63f5f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl
+++ /dev/null
@@ -1,219 +0,0 @@
-#!/usr/bin/env perl
-use warnings;
-
-#############################################################
-#############################################################
-
-########################################################################
-# hyperxmp-add-bytecount #
-# Adds/updates byteCount specification in XMP packet in pdf file(s) #
-# made by hyperxmp, with byteCount = file size. #
-# Copyright (C) 2020 John Collins <jcc8@psu.edu> #
-# and Scott Pakin, <scott+hyxmp@pakin.org> #
-# #
-# This program may be distributed and/or modified under the conditions #
-# of the LaTeX Project Public License, either version 1.3c of this #
-# license or (at your option) any later version. #
-# #
-# The latest version of this license is in: #
-# #
-# http://www.latex-project.org/lppl.txt #
-# #
-# and version 1.3c or later is part of all distributions of LaTeX #
-# version 2008/05/04 or later. #
-########################################################################
-
-$name = 'hyperref-add-bytecount';
-$version = '1.1-2020-11-20';
-$maintainer
- = 'John Collins, jcc8@psu.edu; Scott Pakin, scott+hyxmp@pakin.org';
-
-my $exit_code = 0;
-
-if ( (! @ARGV) || ($ARGV[0] =~ /^(-|--)(h|help)$/) ) {
- print "$name $version.\n",
- "Usage: $name [options] pdf_filename(s)\n",
- " Adds/updates byteCount specification in XMP packet in pdf file(s) from\n",
- " hyperxmp, with byteCount = file size.\n",
- " No change if there's no XMP packet of the form produced by hyperxmp.\n",
- "Options:\n",
- " -help or -h Output usage information.\n",
- " -version or -v Output version information.\n",
- "Bug reports to:\n $maintainer.\n";
- exit;
-} elsif ( $ARGV[0] =~ /^(-|--)(v|version)$/ ) {
- print "$name $version.\n",
- "Bug reports to:\n $maintainer.\n";
- exit;
-}
-
-foreach (@ARGV) {
- if ( ! fix_pdf($_) ) { $exit_code = 1; }
-}
-
-exit $exit_code;
-
-#======================================================
-
-sub fix_pdf {
- # Change/insert byteCount field with correct file length, while preserving
- # the file size and the length of the stream containing xmp metadata.
- # Return 1 on success, else 0.
-
- local $pdf_name = shift;
- local $tmp_name = "$pdf_name.new.pdf";
- local $pdf_size = (stat($pdf_name))[7];
- warn "Inserting/correcting byteCount field in '$pdf_name' ...\n";
-
- # Strings surrounding (and identifying) the byteCount field, and other
- # parts of the xmp packet:
- local $xmp_start = '<x:xmpmeta xmlns:x="adobe:ns:meta/">';
- local $decl_bC = '<pdfaProperty:name>byteCount</pdfaProperty:name>';
- local $pre_bC = '<prism:byteCount>';
- local $post_bC = '</prism:byteCount>';
- local $pC = '<prism:pageCount>';
- local $rd_end = '</rdf:Description>';
- local $xmp_end = '</x:xmpmeta>';
-
- local *PDF;
- local *TMP;
-
- if (! open PDF, "<", $pdf_name ) {
- warn " Cannot read '$pdf_name'\n";
- return 0;
- }
- if ( ! open TMP, ">", $tmp_name ) {
- warn " Cannot write temporary file '$tmp_name'\n";
- close PDF;
- return 0;
- }
- local $status = 0; # 0 = no XMP packet, 1 = success, >= errors
- while ( <PDF> ) {
- # Only examine first XMP packet:
- if ( ($status == 0) && /^\s*\Q$xmp_start\E/ ) {
- local @xmp = $_;
- local $len_padding = 0;
- local $xmp_after_line = '';
- &xmp_get_mod;
- print TMP @xmp;
- # Insert correct padding to leave file size unchanged:
- while ( $len_padding > 0 ) {
- my $len_line = 64;
- if ( $len_line > $len_padding ) { $len_line = $len_padding; }
- $len_padding -= $len_line;
- print TMP (' ' x ($len_line - 1) ), "\n";
- }
- print TMP $xmp_after_line;
- $xmp_after_line = '';
- }
- else {
- print TMP "$_";
- }
- }
- close PDF;
- close TMP;
-
- if ($status == 0) {
- warn " Could not insert/modify byteCount, since no XMP packet was found.\n";
- warn " So '$pdf_name' is unchanged,\n",
- " and I will delete temporary file '$tmp_name'.\n";
- unlink $tmp_name;
- } elsif ($status == 1) {
- rename $tmp_name, $pdf_name
- or die " Cannot move temporary file '$tmp_name' to '$pdf_name'.\n",
- " Error is '$!'\n";
- } else {
- warn " Could not insert correct byteCount. See above for reason.\n";
- warn " So '$pdf_name' is unchanged,\n",
- " and I will delete temporary file '$tmp_name'.\n";
- unlink $tmp_name;
- }
- return ($status == 1);
-}
-
-#======================================================
-
-sub xmp_get_mod {
- # Get xmp packet, given that @xmp contains its first line.
- # Get amount of trailing padding, and line after that.
- # If possible, insert a byteCount field:
- # Either replace existing specification, if it exists,
- # or insert one in expected place for hyperxmp, if the XMP packet
- # matches what hyperxmp would produce.
- # Return xmp packet in @xmp, amount of padding needed in $len_padding,
- # line after that in $xmp_after_line, and error code in $error.
- # Set $status appropriately: 1 for success; >=1 for failure.
-
- $len_padding = 0;
- $xmp_after_line = '';
-
- my $bC_index = -1;
- my $xmp_end_found = 0;
- my $decl_bC_found = 0;
- while ( <PDF> ) {
- push @xmp, $_;
- if ( /^\s*\Q$xmp_end\E/ ) {
- $xmp_end_found = 1;
- # Get amount of padding;
- while (<PDF>) {
- if ( /^\s*$/ ) {
- $len_padding += length($_);
- } else {
- $xmp_after_line = $_;
- last;
- }
- }
- last;
- }
- elsif ( $bC_index >= 0 ){
- next;
- }
- # Rest of conditions only apply if no place yet found for byteCount
- # specification.
- elsif ( /^(\s*)\Q$pre_bC\E.*?\Q$post_bC\E\s*$/ ) {
- $bC_index = $#xmp;
- }
- elsif ( /^\s*\Q$decl_bC\E/ ) {
- $decl_bC_found = 1;
- }
- elsif ( /^(\s*)\Q$rd_end\E/ ){
- # End of rdf:Description block.
- # So having previous declaration of byteCount is irrelevant.
- $decl_bC_found = 0;
- }
- elsif ( $decl_bC_found && /^(\s*)\Q$pC\E/ ){
- $bC_index = $#xmp;
- pop @xmp;
- push @xmp, '', $_;
- }
-
- } # End reading of XMP
-
- if ($bC_index < 0) {
- if ( ! $xmp_end_found ) {
- warn " End of XMP packet not found.\n";
- $status = 2;
- }
- elsif ( ! $decl_bC_found ) {
- warn " XMP packet not in appropriate hyperxmp-compatible format.\n";
- $status = 3;
- }
- return;
- }
- my $new_line = ' ' . $pre_bC . $pdf_size . $post_bC . "\n";
- my $old_line = $xmp[$bC_index];
- my $delta_len = length($new_line) - length($old_line);
- if ($delta_len > $len_padding) {
- warn " Cannot get padding correct for '$pdf_name'.\n",
- " Length change of bC line = $delta_len; ",
- " Padding bytes available = $len_padding.\n";
- $status = 4;
- return;
- } else {
- $len_padding -= $delta_len;
- $xmp[$bC_index] = $new_line;
- $status = 1;
- }
-}
-
-#======================================================
diff --git a/Build/source/texk/texlive/linked_scripts/installfont/installfont-tl b/Build/source/texk/texlive/linked_scripts/installfont/installfont-tl
deleted file mode 100755
index 7a046426a94..00000000000
--- a/Build/source/texk/texlive/linked_scripts/installfont/installfont-tl
+++ /dev/null
@@ -1,614 +0,0 @@
-#!/bin/bash
-#
-# installfont-tl [options]
-#
-# installs a LaTeX font family (Postscript Type1, Truetype, Opentype)
-# (font series from light to ultra bold + (faked) small caps + faked
-# slanted, but no expert fonts) for using them with LaTeX (TeXLive)
-# The script tries to rename the fonts automatically (optional).
-# Otherwise the *.afm and *.pfb files must be named in Karl Berry scheme
-# (e.g. 5bbr8a.pfb)
-# (tested with TeXLive2013/Cygwin) v1.7 (15.07.2013)
-# (C) Josef Kleber 2009-2010,2013 License: LPPL
-#
-VERSION="v1.7 (2013/07/15)"
-#
-FONTFAMILY="5bb"
-FONTNAME="Softmaker Barbedor"
-FONTCOMMAND="FFBarbedor"
-FONTSCALEPREFIX="Sbb"
-FONTTYPE="pst1"
-PACKAGENAME="barbedor"
-PACKAGEDATE="2010/03/05"
-PACKAGEVERSION="v1.0"
-MAPFILENAME=""
-OFN="false"
-WINLOCALTEXMF="`kpsewhich --expand-var='$TEXMFLOCAL' | sed s/\r//`"
-USEDOS=`uname | cut -c1-6`
-if [ "$USEDOS" = "CYGWIN" ]
-then
- WINLOCALTEXMFII="`cygpath -u $WINLOCALTEXMF`"
- LOCALTEXMF="$WINLOCALTEXMFII"
-else
- LOCALTEXMF="$WINLOCALTEXMF"
-fi
-FONTSUBDIR="MyFonts/Barbedor"
-# Font encoding default: 8a (AdobeStandardEncoding)
-FONTENCODING="8a"
-# Font cut default: r (regular) don't change!
-FONTCUT="r"
-#
-OTFFONTFEATURES="-fkern -fliga"
-UNINSTALL="false"
-INSTALLAS="rmdefault"
-SMFFSTY="%"
-LOG="false"
-#
-function printHelp()
-{
- echo -e \
- " `basename $0` [options]\n"\
- " installs a font family for using it with LaTeX\n\n"\
- " Options:\n\n"\
- " -f, --fontfamily Name of the LaTeX font family, e.g. ptm (Adobe Times)\n\n"\
- " -n, --fontname Font name, e.g. Adobe Times\n\n"\
- " -c, --fontcommand Name of the command that will switch to the font\n\n"\
- " -P, --fontscaleprefix prefix of the scale macro, which should be different\n"\
- " for each font (no digits allowed)\n\n"\
- " -t, --fonttype Font type (pst1(default)|ttf|otf)\n\n"\
- " -p, --packagename Name of the LaTeX package\n\n"\
- " -d, --packagedate Date of the LaTeX package\n\n"\
- " -v, --packageversion Version of the LaTeX package\n\n"\
- " -l, --localtexmf root of your local TeX tree, e.g. /cygdrive/c/LocalTeXMF\n\n"\
- " -m, --mapfilename file name of the map file\n\n"\
- " -O. --origfontname use original font names instead of Karl Berry names\n\n"\
- " -s, --fontsubdir location where the fonts and support files should be\n"\
- " installed, e.g. MyFonts/AdobeTimes\n\n"\
- " -e, --fontencoding encoding of the font\n"\
- " (default: 8a (AdobeStandardEncoding))\n\n"\
- " -o, --otffontfeatures choosing Opentype font features\n"\
- " (default: -fkern -fliga)\n\n"\
- " -u, --uninstall will uninstall the font family. You must specify\n"\
- " --localtexmf and --fontsubdir\n\n"\
- " -R, --rmdefault installs font family as roman (serif) font family (default)\n\n"\
- " -S, --sfdefault installs font family as sans serif font family\n\n"\
- " -T, --ttdefault installs font family as typewriter font family\n\n"\
- " -V, --version will print the version number of `basename $0`\n\n"\
- " -L, --log will write the terminal output of the main programms into the\n"\
- " LOG file instead of the screen\n\n"\
- " -h, --help will print this help statement\n\n"\
- " See http://latex.josef-kleber.de/index.htm or\n"\
- " http://latex.josef-kleber.de/en_index.htm\n"\
- " for more information"
- exit 0;
-}
-function printVersion()
-{
- echo "This is version $VERSION of `basename $0`"
- exit 0;
-}
-#
-if [ $# -eq 0 ]
-then
- echo -e "`basename $0`: Could not find command line arguments.\nUse the '--help' option for explanation."
- echo -e "Continue with default script variables? (y/n)"
- read ANSWER
- if [ $ANSWER = "n" -o $ANSWER = "N" ]
- then
- exit 1
- fi
-fi
-#
-LONGOPTS="fontfamily:,fontname:,fontcommand:,fontscaleprefix:,fonttype:,packagename:,packagedate:,packageversion:,mapfilename:,origfilename,localtexmf:,fontsubdir:,fontencoding:,otffontfeatures:,uninstall,rmdefault,sfdefault,ttdefault,log,version,help"
-SHORTOPTS="f:n:c:P:t:p:d:v:m:Ol:s:e:o:uRSTVLh"
-ARGS=$(getopt -l "$LONGOPTS" "$SHORTOPTS" "$@")
-if [ $? -ne 0 ]
-then
- echo -e "`basename $0`: Could not process command line arguments.\nUse the '--help' option for explanation."
- exit 1
-fi
-#
-eval set -- "$ARGS"
-#
-while [ $# -gt 0 ]; do
- ARG=$1
- case "$ARG" in
- --help|-h) shift; printHelp;;
- --version|-V) shift; printVersion;;
- --rmdefault|-R) shift; INSTALLAS="rmdefault";;
- --sfdefault|-S) shift; INSTALLAS="sfdefault";;
- --ttdefault|-T) shift; INSTALLAS="ttdefault";;
- --uninstall|-u) shift; UNINSTALL="true";;
- --log|-L) shift; LOG="true";;
- --fontfamily|-f) shift; FONTFAMILY="$1"; shift;;
- --fontname|-n) shift; FONTNAME="$1"; shift;;
- --fontcommand|-c) shift; FONTCOMMAND="$1"; shift;;
- --fontscaleprefix|-P) shift; FONTSCALEPREFIX="$1"; shift;;
- --fonttype|-t) shift; FONTTYPE="$1"; shift;;
- --packagename|-p) shift; PACKAGENAME="$1"; shift;;
- --packagedate|-d) shift; PACKAGEDATE="$1"; shift;;
- --packageversion|-v) shift; PACKAGEVERSION="$1"; shift;;
- --mapfilename|-m) shift; MAPFILENAME="$1"; shift;;
- --origfontname|-O) shift; OFN="true";;
- --localtexmf|-l) shift; LOCALTEXMF="$1"; shift;;
- --fontsubdir|-s) shift; FONTSUBDIR="$1"; shift;;
- --fontencoding|-e) shift; FONTENCODING="$1"; shift;;
- --otffontfeatures|-o) shift; FONTFAMILY="$1"; shift;;
- --) shift; break;;
- *) break;;
- esac
-done
-#
-rm LOG 2>>/dev/null;
-#
-if [ -z $MAPFILENAME ]
-then
- MAPFILENAME=$FONTFAMILY
-fi
-#
-typeset -i STEP=0
-#
-if [ $UNINSTALL = "true" ]
-then
- DIR="${LOCALTEXMF}/fonts/tfm/${FONTSUBDIR}/"
- echo -e "$\n\n$DIR"
- DIR="${LOCALTEXMF}/fonts/vf/${FONTSUBDIR}/"
- echo $DIR
- DIR="${LOCALTEXMF}/fonts/type1/${FONTSUBDIR}/"
- echo $DIR
- DIR="${LOCALTEXMF}/fonts/map/dvips/${FONTSUBDIR}/"
- echo $DIR
- DIR="${LOCALTEXMF}/tex/latex/${FONTSUBDIR}/"
- echo $DIR
- echo -e "\n\nDo you want to delete these directories? (y/n)"
- read ANSWER
- if [ $ANSWER = "y" -o $ANSWER = "Y" ]
- then
- DIR="${LOCALTEXMF}/fonts/tfm/${FONTSUBDIR}/"
- rm -f -r $DIR
- DIR="${LOCALTEXMF}/fonts/vf/${FONTSUBDIR}/"
- rm -f -r $DIR
- DIR="${LOCALTEXMF}/fonts/type1/${FONTSUBDIR}/"
- rm -f -r $DIR
- DIR="${LOCALTEXMF}/fonts/map/dvips/${FONTSUBDIR}/"
- rm -f -r $DIR
- DIR="${LOCALTEXMF}/tex/latex/${FONTSUBDIR}/"
- rm -f -r $DIR
- exit 0
- else
- exit 1
- fi
-fi
-#
-if [ $FONTTYPE = "ttf" ]
-then
- ((STEP++))
- echo -e "\n\n$STEP) Convert font(s) to Postscript Type1\n\n"
- for file in *.TTF;
- do
- mv "$file" "${file%TTF}ttf" 2>>/dev/null;
- done
- for file in *.ttf;
- do
- ttf2pt1 -a -b -l adobestd "$file";
- done
-fi
-#
-if [ $FONTTYPE = "otf" ]
-then
- ((STEP++))
- echo -e "\n\n$STEP) Convert font(s) to Postscript Type1\n\n"
- for file in *.OTF;
- do
- mv "$file" "${file%OTF}otf" 2>>/dev/null;
- done
- for file in *.otf;
- do
- otftotfm $OTFFONTFEATURES -e - "$file" 555;
- done
- for file in *.pfb;
- do
- pf2afm "$file";
- done
- rm *.tfm
- rm *.enc
-fi
-#
-echo -e "\n\nTry to rename the font(s) automatically? (y/n)"
-read ANSWER
-if [ $ANSWER = "y" -o $ANSWER = "Y" ]
-then
- ((STEP++))
- echo -e "\n\n$STEP) Renaming fonts\n\n"
- mkdir -p Backup
- cp *.afm *.AFM ./Backup 2>>/dev/null
- cp *.pfb *.PFB ./Backup 2>>/dev/null
- for file in *.AFM;
- do
- mv "$file" "${file%AFM}afm" 2>>/dev/null;
- done
- for file in *.PFB;
- do
- mv "$file" "${file%PFB}pfb" 2>>/dev/null;
- done
- FONTNUMBER=$(ls -al *.pfb 2>>/dev/null | wc -l)
- if [ $FONTNUMBER -le 1 ]
- then
- if [ $FONTNUMBER -eq 0 ]
- then
- echo "No font(s) to rename!"
- exit 1
- else
- for file in *.afm;
- do
- mv "$file" ${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- done
- for file in *.pfb;
- do
- mv "$file" ${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.pfb}/" >>map.sed;
- done
- fi
- else
- mkdir -p Rename
- # rename small caps font(s)
- FILES=$(grep -e "Smc" -e "Caps" -e "SCOsF" *.afm | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- FONTCUT="rc"
- FWEIGHT=$(grep -e "Light" "$file" | wc -l)
- if [ $FWEIGHT -gt 0 ]
- then
- FONTCUT="lc"
- else
- FWEIGHT=$(grep -e "Semibold" -e "SemiBold" "$file" | wc -l)
- if [ $FWEIGHT -gt 0 ]
- then
- FONTCUT="sc"
- else
- FWEIGHT=$(grep -e "Demi" -e "Demibold" -e "DemiBold" "$file" | wc -l)
- if [ $FWEIGHT -gt 0 ]
- then
- FONTCUT="dc"
- else
- FWEIGHT=$(grep -e "Extrabold" -e "ExtraBold" "$file" | wc -l)
- if [ $FWEIGHT -gt 0 ]
- then
- FONTCUT="xc"
- else
- FWEIGHT=$(grep -e "Heavy" -e "Ultrabold" -e "UltraBold" "$file" | wc -l)
- if [ $FWEIGHT -gt 0 ]
- then
- FONTCUT="uc"
- else
- FWEIGHT=$(grep -e "Bold" -e "bold" "$file" | wc -l)
- if [ $FWEIGHT -gt 0 ]
- then
- FONTCUT="bc"
- fi
- fi
- fi
- fi
- fi
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- done
- # rename the extra light font(s)
- FILES=$(grep -e "XLight" -e "Xlight" -e "extra light" *.afm | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="ji"
- else
- FONTCUT="j"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- SMFFSTY="\RequirePackage{softmakerfreefont}%"
- done
- # rename the light font(s)
- FILES=$(grep -e "Light" *.afm | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="li"
- else
- FONTCUT="l"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- SMFFSTY="\RequirePackage{softmakerfreefont}%"
- done
- # rename the semi(bold) font
- FILES=$(grep -e "Semibold" -e "SemiBold" *.afm | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="si"
- else
- FONTCUT="s"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- SMFFSTY="\RequirePackage{softmakerfreefont}%"
- done
- # rename the demi(bold) font
- FILES=$(grep -e "FontName" -e "FullName" *.afm | grep -e "Demi" -e "Demibold" -e "DemiBold" | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="di"
- else
- FONTCUT="d"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- SMFFSTY="\RequirePackage{softmakerfreefont}%"
- done
- # rename the extra bold font
- FILES=$(grep -e "Extrabold" -e "ExtraBold" *.afm | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="xi"
- else
- FONTCUT="x"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- done
- # rename the ultra bold/heavy font
- FILES=$(grep -e "Heavy" -e "Ultrabold" -e "UltraBold" *.afm | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="ui"
- else
- FONTCUT="u"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- SMFFSTY="\RequirePackage{softmakerfreefont}%"
- done
- # rename the bold font
- FILES=$(grep -e "Bold" -e "bold" *.afm | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="bi"
- else
- FONTCUT="b"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- done
- # rename the regular font
- FILES=$(grep -e "Regular" -e "Medium" -e "Book" --exclude=installfont * | grep -e ".afm" | cut -d':' -f1 | uniq)
- for file in $FILES
- do
- ITALICANGLE=$(grep -e "ItalicAngle" "$file" | tr ' ' '+' | cut -d'+' -f2 | cut -d'.' -f1)
- if [ $ITALICANGLE -lt 0 -o $ITALICANGLE -gt 0 ]
- then
- FONTCUT="ri"
- else
- FONTCUT="r"
- fi
- mv "$file" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.afm;
- mv "${file%afm}pfb" ./Rename/${FONTFAMILY}${FONTCUT}${FONTENCODING}.pfb;
- echo -e "s/<${FONTFAMILY}${FONTCUT}${FONTENCODING}/<${file%.afm}/" >>map.sed;
- done
- mv ./Rename/* .
- rmdir ./Rename
- fi
- ls -al *.pfb *.afm
- echo -e "\n\nPlease check the font name(s). Continue? (y/n)"
- read ANSWER
- if [ $ANSWER = "n" -o $ANSWER = "N" ]
- then
- rm *.afm
- rm *.pfb
- rm *.sed
- mv ./Backup/* .
- rmdir ./Backup
- exit 1
- fi
-fi
-#
-((STEP++))
-echo -e "\n\n$STEP) Creating metrics and virtual fonts\n\n"
-cat >${FONTFAMILY}-drv.tex <<EOF
-\input fontinst.sty
-\needsfontinstversion{1.926}
-\recordtransforms{${FONTFAMILY}-rec.tex}
-\latinfamily{${FONTFAMILY}}{}
-\endrecordtransforms
-\bye
-EOF
-if [ $LOG = "true" ]
-then
- tex ${FONTFAMILY}-drv.tex >>LOG 2>&1
-else
- tex ${FONTFAMILY}-drv.tex
-fi
-#
-((STEP++))
-echo -e "\n\n$STEP) Compiling metrics and virtual fonts\n\n"
-for file in *.pl;
-do
- if [ $LOG = "true" ]
- then
- pltotf $file ${file%pl}tfm >>LOG 2>&1
- else
- pltotf $file ${file%pl}tfm
- fi
-done
-for file in *.vpl;
-do
- if [ $LOG = "true" ]
- then
- vptovf $file ${file%vpl}vf ${file%vpl}tfm >>LOG 2>&1
- else
- vptovf $file ${file%vpl}vf ${file%vpl}tfm
- fi
-done
-#
-((STEP++))
-echo -e "\n\n$STEP) Creating the map file\n\n"
-cat >${FONTFAMILY}-map.tex <<EOF
-\input finstmsc.sty
-\resetstr{PSfontsuffix}{.pfb}
-\adddriver{dvips}{${FONTFAMILY}.map}
-\input ${FONTFAMILY}-rec.tex
-\donedrivers
-\bye
-EOF
-if [ $LOG = "true" ]
-then
- tex ${FONTFAMILY}-map.tex >>LOG 2>&1
-else
- tex ${FONTFAMILY}-map.tex
-fi
-if [ $OFN = "true" ]
-then
- sed -f map.sed ${FONTFAMILY}.map >${MAPFILENAME}.map
- unix2dos ${MAPFILENAME}.map 2>>/dev/null;
- rm ${FONTFAMILY}.map
- UMAP="${MAPFILENAME}"
-else
- UMAP="${FONTFAMILY}"
-fi
-#
-((STEP++))
-echo -e "\n\n$STEP) Creating the style file"
-cat >${PACKAGENAME}.sty <<EOF
-\NeedsTeXFormat{LaTeX2e}%
-\ProvidesPackage{$PACKAGENAME}[$PACKAGEDATE $PACKAGEVERSION $FONTNAME]%
-\RequirePackage{textcomp}%
-\RequirePackage{xkeyval}%
-\define@key{${PACKAGENAME}.sty}{scaled}[1.0]%
-{%
- \def\\${FONTSCALEPREFIX}@scale{#1}%
-}%
-\define@key{${PACKAGENAME}.sty}{leading}[1.0]%
-{%
- \linespread{#1}%
-}%
-\ExecuteOptionsX{scaled}%
-\ProcessOptionsX\relax%
-\renewcommand*{\\${INSTALLAS}}{$FONTFAMILY}%
-\newcommand\\${FONTCOMMAND}{\fontfamily{$FONTFAMILY}\fontseries{m}\fontshape{n}\selectfont}%
-\endinput%
-EOF
-#
-((STEP++))
-echo -e "\n\n$STEP) Insert scale factor into the fd files"
-cat >installfont.sed <<EOF
-9 i\\
-\\n\\\\expandafter\\\\ifx\\\\csname ${FONTSCALEPREFIX}@scale\\\\endcsname\\\\relax\\n \\\\let\\\\${FONTSCALEPREFIX}@@scale\\\\@empty\\n\\\\else\\n \\\\edef\\\\${FONTSCALEPREFIX}@@scale{s*[\\\\csname ${FONTSCALEPREFIX}@scale\\\\endcsname]}\\n\\\\fi\\n
-s/<-> /<-> \\\\${FONTSCALEPREFIX}@@scale /
-EOF
-#
-for file in *.fd;
-do
- mv $file ${file%fd}fdb;
- sed -f installfont.sed ${file%fd}fdb >$file;
-done
-#
-((STEP++))
-echo -e "\n\n$STEP) Installing font(s) and support files"
-DIR="${LOCALTEXMF}/fonts/tfm/${FONTSUBDIR}/"
-if [ ! -d $DIR ]
-then
- mkdir -p $DIR
-fi
-mv *.tfm $DIR
-DIR="${LOCALTEXMF}/fonts/vf/${FONTSUBDIR}/"
-if [ ! -d $DIR ]
-then
- mkdir -p $DIR
-fi
-mv *.vf $DIR
-DIR="${LOCALTEXMF}/fonts/type1/${FONTSUBDIR}/"
-if [ $OFN = "true" ]
-then
- cd Backup
- if [ ! -d $DIR ]
- then
- mkdir -p $DIR
- fi
- cp *.pfb $DIR
- cd ..
-else
- if [ ! -d $DIR ]
- then
- mkdir -p $DIR
- fi
- cp *.pfb $DIR
-fi
-DIR="${LOCALTEXMF}/fonts/map/dvips/${FONTSUBDIR}/"
-if [ ! -d $DIR ]
-then
- mkdir -p $DIR
-fi
-mv *.map $DIR
-DIR="${LOCALTEXMF}/tex/latex/${FONTSUBDIR}/"
-if [ ! -d $DIR ]
-then
- mkdir -p $DIR
-fi
-mv *.fd $DIR
-DIR="${LOCALTEXMF}/tex/latex/${FONTSUBDIR}/"
-if [ ! -d $DIR ]
-then
- mkdir -p $DIR
-fi
-mv *.sty $DIR
-#
-((STEP++))
-echo -e "\n\n$STEP) Update FNDB"
-echo -e "\n\n"
-texhash
-#
-((STEP++))
-echo -e "\n\n$STEP) Include the map file"
-echo -e "\n\n"
-updmap --enable Map ${UMAP}.map
-rm *.mtx
-rm *.pl
-rm *.vpl
-rm *.log
-rm *.tex
-rm *.fdb
-rm *.sed
-if [ -d Backup ]
-then
- rm *.afm
- rm *.pfb
- mv ./Backup/* .
- rmdir ./Backup
-fi
-echo -e "\n\nThe font(s) should be installed now!"
-exit 0 \ No newline at end of file
diff --git a/Build/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl b/Build/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl
deleted file mode 100755
index d527eddfdbd..00000000000
--- a/Build/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl
+++ /dev/null
@@ -1,3456 +0,0 @@
-#!/usr/bin/env perl
-#
-# This is file 'jfmutil.pl'.
-#
-# Copyright (c) 2008-2020 Takayuki YATO (aka. "ZR")
-# GitHub: https://github.com/zr-tex8r
-# Twitter: @zr_tex8r
-#
-# This software is distributed under the MIT License.
-#
-use strict;
-
-#------------------------------------------------- ZRTeXtor module
-package ZRTeXtor;
-our $VERSION = 1.007_00;
-our $mod_date = "2019/09/02";
-use Encode qw(encode decode);
-
-# Here follows excerpt from ZRTeXtor.pm
-#================================================= BEGIN
-######## general ########
-
-our $binmode = 0; # always read/write in binary mode
-our $errmsg; # last error message
-use constant { HUGE => 1e20, EPS => 1e-7 };
- # TU = TFM factor, DU = DVI factor
-use constant { TU => 1 << 20, DU => 1 << 16, B31 => 1 << 31 };
-use constant { M32 => 0xFFFFFFFF, M31 => 0x7FFFFFFF };
-use constant { # kanji encoding names
- K_JIS => 'iso-2022-jp', K_EUC => 'euc-jp',
- K_SJIS => 'shiftjis', K_UTF8 => 'UTF-8',
- KI_JIS => 'jis0208-raw', KI_UNI => 'UTF-16BE',
- KI_XJIS => '*xjis*', K_XJIS => '*xjis*',
-};
-# for get_temp_name
-our $get_temp_base = '__zrtx';
-our (@get_temp_id);
-
-## error($msg, ...)
-# Sets the error message and returns nothing (undef in scalar).
-# Usually a defined value is returned in success.
-sub error
-{
- $errmsg = join('', map { (ref $_) ? '[obj]' : $_ } (@_));
- return;
-}
-
-## fatal($msg, ...)
-# Intended for internal errors....
-sub fatal
-{
- return error("!!FATAL(", @_, ")");
-}
-
-##<*> textool_error()
-# Obtains the error message of the last error. This string
-# can be used in error handling of your own style.
-sub textool_error
-{
- return $errmsg;
-}
-
-##<*> textool_version()
-# Returns the version information on this library.
-sub textool_version
-{
- my ($t, @fs);
- $t = sprintf("%.5f", $VERSION);
- (@fs = $t =~ m|^(\d+)\.(\d\d\d)(\d\d)$|)
- or return fatal("textool_version");
- $t = sprintf("%d.%d.%d", @fs);
- return ("$t", $mod_date);
-}
-
-## get_temp_name()
-# Returns a temporary file name which is unique in the process.
-# Note: Trailing digits in font names can have special meaning
-# in some TeX tools.
-sub get_temp_name
-{
- ++$get_temp_id[0];
- return join('', $get_temp_base, $$, @get_temp_id[1, 0, 2]);
-}
-
-## get_temp_anme_init()
-# Initializer for get_temp_name.
-sub get_temp_name_init
-{
- my ($t); $get_temp_id[0] = 0;
- $t = join('', map { ('a' .. 'z')[int(rand() * 26)] } (0 .. 5));
- @get_temp_id[1, 2] = map { substr($t, $_, 3) } (0, 3);
-}
-
-##<*> read_whole_file($fnam, $swbin)
-# Reads in file $fnam and returns its content as a string.
-# If $swbin or the global flag $binmode is true the file is read
-# in binary mode.
-sub read_whole_file
-{
- my ($fnam, $swbin) = @_; my ($hf, $txt); local ($/);
- (defined $fnam) or return;
- open($hf, '<', $fnam)
- or return error("cannot open for read: $fnam");
- if ($binmode || $swbin) { binmode($hf); }
- $txt = readline($hf);
- close($hf);
- return $txt;
-}
-
-##<*> write_whole_file($fnam, $txt, $swbin)
-# Creates (or crobbers) the file $fnam and write $txt to it.
-# If $swbin or the global flag $binmode is true it writes in
-# binary mode.
-sub write_whole_file
-{
- my ($fnam, $txt, $swbin) = @_; my ($hf);
- open($hf, '>', $fnam)
- or return error("cannot open for write: $fnam");
- if ($binmode || $swbin) { binmode($hf); }
- print $hf ($txt);
- close($hf);
- return 1;
-}
-
-## unpack_num($s)
-# Decodes a unsigned number in big-endian string.
-sub unpack_num
-{
- my ($s) = @_;
- return unpack("N", substr("\0\0\0\0$s", length($s)));
-}
-
-## unpack_snum($s)
-# Decodes a signed number in big-endian string.
-my @snum_bound = (0, 0x80, 0x8000, 0x800000, B31);
-sub unpack_snum
-{
- my ($s) = @_; my ($b, $v);
- $b = $snum_bound[length($s)];
- $v = unpack("N", substr("\0\0\0\0$s", length($s)));
- return ($v >= $b) ? ($v - $b - $b) : $v;
-}
-
-## pack_num($v)
-# Encodes a unsigned number in big-endian string, with the length
-# prefix. In scalar context the returned values are concatenated.
-sub pack_num
-{
- my ($v) = @_; my ($t, $l);
- ($t = pack('N', $v)) =~ s/^\0{1,3}//; $l = length($t);
- return (wantarray) ? ($l, $t) : (chr($l) . $t);
-}
-
-## pack_snum($v)
-# Signed version of pack_num.
-sub pack_snum
-{
- my ($v) = @_; my ($t, $l);
- ($t = pack('N', $v)) =~
- s/^\0{1,3}([\x00-\x7f])|^\xff{1,3}([\x80-\xff])/$+/;
- $l = length($t);
- return (wantarray) ? ($l, $t) : (chr($l) . $t);
-}
-
-## signed($v)
-# Converts 'unsigned long' to 'signed long'.
-sub signed
-{
- my ($v) = @_; $v &= M32;
- return ($v >= B31) ? ($v - B31 - B31) : $v;
-}
-
-## round($v)
-# Rounds a real value to an integer.
-sub round
-{
- my ($v) = @_;
- return int($v + (($v < 0) ? -0.5 : +0.5));
-}
-
-##<*> arraymap($map, $swmm)
-# Converts a code map in hash form into array form.
-sub arraymap
-{
- my ($map, $swmm) = @_; my ($sc, $dc, @u, @amap);
- if (ref $map eq 'HASH') {
- @u = sort { $a <=> $b } (keys %$map);
- foreach $sc (@u) {
- $dc = $map->{$sc};
- if (ref $dc eq 'ARRAY') {
- if ($swmm) {
- foreach (@$dc) { push(@amap, [$sc, $_]); }
- } else { push(@amap, [$sc, $dc->[0]]); }
- } elsif (defined $dc) { push(@amap, [$sc, $dc]); }
- }
- return \@amap;
- } elsif (ref $map eq 'ARRAY') { return $map; }
- else { return; }
-}
-
-## squote($str)
-# S-quotes a string.
-sub squote
-{
- my ($str) = @_; $str =~ s/([\\\'])/\\$1/g;
- return "'$str'";
-}
-
-## zdquote($str)
-# ZD-quotes a string.
-sub zdquote
-{
- my ($str) = @_; $str =~ s/([\\\"])/\\$1/g;
- $str =~ s/([^\x20-\x7e])/sprintf("\\%02X",$1)/ge;
- return "\"$str\"";
-}
-
-######## 'x' section ########
-
-use IPC::Open3; # for open3()
-our %cmd_name = (
- kpsewhich => 'kpsewhich',
- tftopl => 'ptftopl',
- pltotf => 'ppltotf',
- uptftopl => 'uptftopl',
- uppltotf => 'uppltotf',
- vftovp => 'vftovp',
- vptovf => 'vptovf',
- opl2ofm => 'opl2ofm',
-);
-
-##<*> x_captured_exec(@cmd);
-# Spawns the command @cmd, captures its stdout and stderr into
-# strings, and returns them.
-# --- Am I doing right?
-sub x_captured_exec
-{
- my (@cmd) = @_; my ($pid, @fs, @ds);
- local(*CHIN, *CHOUT, *CHERR, $/);
- L1:{
- @fs = (get_temp_name(), get_temp_name());
- open(CHOUT, '+>', $fs[0]) or last;
- open(CHERR, '+>', $fs[1]) or last;
- ($pid = open3(\*CHIN, '>&CHOUT', '>&CHERR', @cmd)) or last;
- waitpid($pid, 0);
- seek(CHOUT, 0, 0); $ds[0] = <CHOUT>;
- seek(CHERR, 0, 0); $ds[1] = <CHERR>;
- }
- close(CHIN); close(CHOUT); close(CHERR);
- unlink(@fs);
- return (@ds);
-}
-
-##<*> x_tftopl
-# Wrapper for 'tftopl' command.
-sub x_tftopl
-{
- my ($tfm, $cmd) = @_; my ($ftmp, $ftfm, $fpl, $cout, $cerr);
- if (!defined $cmd) { $cmd = $cmd_name{tftopl}; }
- if ($tfm =~ m/\.tfm$/i && $tfm !~ /\0/) { $ftfm = $tfm; }
- else {
- $ftfm = $ftmp = get_temp_name() . ".tfm";
- (write_whole_file($ftmp, $tfm, 1)) or return;
- }
- $fpl = get_temp_name() . ".pl";
- ($cout, $cerr) = x_captured_exec("$cmd $ftfm $fpl");
- if (defined $ftmp) { unlink($ftmp); }
- $cout = read_whole_file($fpl); unlink($fpl);
- if ($cout eq '' || $cout =~ /CHANGED!\)\s*$/) {
- return error("tftopl failed: $ftfm");
- }
- return pl_parse($cout);
-}
-
-##<*> x_uptftopl
-# Wrapper for 'uptftopl' command.
-# Use of x_tftopl($tfm, "uptftopl") does not seem to work right.
-# Perhaps getting uptftopl to 'output to terminal' confuses
-# uptftopl as to handling UTF-8 strings....
-sub x_uptftopl
-{
- my ($tfm, $cmd) = @_; my ($ftmp, $ftfm, $fpl, $cout, $cerr);
- if (!defined $cmd) { $cmd = $cmd_name{uptftopl}; }
- if ($tfm =~ m/\.tfm$/i && $tfm !~ /\0/) { $ftfm = $tfm; }
- else {
- $ftfm = $ftmp = get_temp_name() . ".tfm";
- (write_whole_file($ftmp, $tfm, 1)) or return;
- }
- $fpl = get_temp_name() . ".pl";
- ($cout, $cerr) = x_captured_exec("$cmd $ftfm $fpl");
- if (defined $ftmp) { unlink($ftmp); }
- $cout = read_whole_file($fpl); unlink($fpl);
- if ($cout eq '' || $cout =~ /CHANGED!\)\s*$/) {
- return error("tftopl failed: $ftfm");
- }
- if ($cout =~ m/CHARSINTYPE/) { $cout = pl_adjust_lit_paren($cout); }
- return pl_parse($cout);
-}
-
-##<*> x_pltotf
-# Wrapper for 'pltotf' command.
-sub x_pltotf
-{
- my ($pl, $cmd) = @_;
- my ($ftmp, $fpl, $cout, $ftfm, $tfm, $tn);
- if (!defined $cmd) { $cmd = $cmd_name{pltotf}; }
- $tn = get_temp_name(); $ftfm = "$tn.tfm";
- if (ref $pl eq 'ARRAY') { $pl = pl_form($pl); }
- if ($pl =~ m/\.pl$/i) { $fpl = $pl; }
- else {
- $fpl = $ftmp = "$tn.pl";
- (write_whole_file($ftmp, $pl)) or return;
- }
- $cout = `$cmd $fpl $ftfm`; # no output to stderr
- if (defined $ftmp) { unlink($ftmp); }
- (-f $ftfm) or return error("pltotf failed: $fpl");
- $tfm = read_whole_file($ftfm, 1); unlink($ftfm);
- foreach (split(/\n/, $cout)) {
- if (m/^\s*$/ || m/^I had to round some / ||
- m/Input file is in kanji /) { next; }
- return error("pltotf failed: $fpl");
- }
- return $tfm;
-}
-
-##<*> x_vptovf
-# Wrapper for 'vptovf' command.
-sub x_vptovf
-{
- my ($pl, $cmd) = @_;
- my ($ftmp, $fpl, $cout, $ftfm, $tfm, $fvf, $vf, $tn);
- if (!defined $cmd) { $cmd = $cmd_name{vptovf}; }
- $tn = get_temp_name(); $ftfm = "$tn.tfm"; $fvf = "$tn.vf";
- if (ref $pl eq 'ARRAY') { $pl = pl_form($pl); }
- if ($pl =~ m/\.vpl$/i) { $fpl = $pl; }
- else {
- $fpl = $ftmp = "$tn.vpl";
- (write_whole_file($ftmp, $pl)) or return;
- }
- $cout = `$cmd $fpl $fvf $ftfm`; # no output to stderr
- if (defined $ftmp) { unlink($ftmp); }
- (-f $ftfm && -f $fvf) or return error("vptovf failed: $fpl");
- $tfm = read_whole_file($ftfm, 1); unlink($ftfm);
- $vf = read_whole_file($fvf, 1); unlink($fvf);
- foreach (split(/\n/, $cout)) {
- if (m/^\s*$/ || m/^I had to round some / ||
- m/Input file is in kanji / || m/LIG/) { next; }
- return error("vptovf failed: $fpl");
- }
- return ($vf, $tfm);
-}
-
-##<*> x_opl2ofm
-# Wrapper for 'opl2ofm' command.
-sub x_opl2ofm
-{
- my ($pl) = @_; my ($cmd, $ftmp, $fpl, $cout, $ftfm, $tfm, $tn);
- $tn = get_temp_name(); $ftfm = "$tn.ofm";
- if (ref $pl eq 'ARRAY') { $pl = pl_form($pl); }
- if ($pl =~ m/\.opl$/i) { $fpl = $pl; }
- else {
- $fpl = $ftmp = "$tn.opl";
- (write_whole_file($ftmp, $pl)) or return;
- }
- $cmd = $cmd_name{opl2ofm};
- $cout = `$cmd $fpl $ftfm`; # no output to stderr
- if (defined $ftmp) { unlink($ftmp); }
- (-f $ftfm) or return error("opl2ofm failed: $fpl");
- $tfm = read_whole_file($ftfm, 1); unlink($ftfm);
- foreach (split(m/\n/, $cout)) {
- if (m/^\s*$/ || m/^I had to round some / ||
- m/Input file is in kanji /) { next; }
- return error("opl2ofm failed: $fpl");
- }
- return $tfm;
-}
-
-
-######## 'pl' section ########
-
-####---- Handling General Property Lists
-
-# * Data structure: pl-list, pl-struct
-# A PL Text consists of a sequence of Lispish lists (without the
-# outermost parentheses). In 'raw' structures, Lispish lists are
-# represented by Perl arrays with straightforward conversion
-# (all atomic elements are strings). Such an array is called
-# 'pl-list' here. The entire PL is represented as an array of
-# pl-lists, called 'pl-struct' here.
-# However, in 'cooked' structures, some numerical data are
-# interpreted. For example, raw data
-# 'D', '0100' (a part of a pl-list)
-# are cooked they change to
-# [ CNUM, 100, 'D' ], '0100'
-# and moreover the assignment of 500 to this part results in
-# [ CNUM, 500, 'D' ], undef
-# And its conversion back into text is 'O 764', because 500 cannot
-# be expressed in 'D' notation.
-
-use constant CNUM => ' '; # flag signifying a cooked number
-our $freenum = 0;
-
-my %pl_facecode = ( # 'F' notation
- MRR => 0, MIR => 1, BRR => 2, BIR => 3, LRR => 4, LIR => 5,
- MRC => 6, MIC => 7, BRC => 8, BIC => 9, LRC => 10, LIC => 11,
- MRE => 12, MIE => 13, BRE => 14, BIE => 15, LRE => 16, LIE => 17
-);
-my %pl_facecode_rev = (reverse %pl_facecode);
-
-##<*> pl_parse($txt)
-# Converts a PL text $txt to a 'cooked' pl-struct.
-sub pl_parse
-{
- my ($txt) = @_; my ($pl, $ent);
- (defined($pl = pl_parse_list("($txt)"))) or return;
- (pl_cook_list($pl)) or return;
- foreach $ent (@$pl) {
- if (!ref $ent) { return error("bareword found: ", $ent); }
- }
- return $pl;
-}
-
-##<*> pl_parse_list($txt)
-# Converts a text $txt of a Lispish list to a 'raw' pl-list.
-sub pl_parse_list
-{
- my ($txt) = @_; my (@toks, $pp, $t, $swjis);
- if (($swjis = $txt =~ m/\x1B\x24/)) { $txt = pl_conv_jis_out($txt); }
- @toks = grep { $_ ne "" } (split(/(\()|(\))|\s+/, $txt));
- if ($swjis) {
- foreach (@toks) {
- if (m/[\x80-\xff]/) { $_ = pl_conv_jis_in($_); }
- }
- }
- if ($toks[0] ne '(') { return error("missing paren at top"); }
- $pp = pl_corres_paren(\@toks, 0);
- if ($pp == $#toks) {
- return pl_parse_sub(\@toks, 1, $pp - 1);
- } elsif ($pp < 0) {
- return error("unmatched parens (end at level ", -$pp, ")");
- } else {
- return error("unmatched parens (extra tokens)");
- }
-}
-sub pl_conv_jis_out {
- my ($txt) = @_; my ($t, $pos, @cnks);
- $pos = pos($txt) = 0;
- while ($txt =~
- m/(\x1B\x24[\x42\x40]([\x21-\x7E]+)\x1B\x28[\x42\x4A])/g) {
- ($t = $2) =~ tr/\x21-\x7E/\xA1-\xFE/;
- push(@cnks, substr($txt, $pos, pos($txt) - length($1) - $pos), $t);
- $pos = pos($txt);
- }
- return join('', @cnks, substr($txt, $pos));
-}
-sub pl_conv_jis_in {
- my ($txt) = @_; my ($t, $pos, @cnks);
- $pos = pos($txt) = 0;
- while ($txt =~ m/([\xA1-\xFE]+)/g) {
- ($t = $1) =~ tr/\xA1-\xFE/\x21-\x7E/;
- push(@cnks, substr($txt, $pos, pos($txt) - length($1) - $pos),
- "\x1B\x24\x42$t\x1B\x28\x42");
- $pos = pos($txt);
- }
- return join('', @cnks, substr($txt, $pos));
-}
-
-## pl_adjust_lit_paren($pl)
-sub pl_adjust_lit_paren
-{
- my ($pl) = @_; my ($mod, $repl, $lin, @lins);
- @lins = split(m/\n/, $pl);
- foreach (0 .. $#lins) {
- $lin = $lins[$_];
- if ($mod == 2) {
- if ($lin =~ m/^\s*\)\s*$/) {
- $lins[$_ - 1] =~ s/\)/X0029/; $repl = 1;
- }
- $mod = 0;
- } elsif ($mod == 1) {
- if ($lin =~ m/^\s*\)\s*$/) { $mod = 2; }
- else {
- if ($lin =~ m/\(/) { $lins[$_] =~ s/\(/X0028/g; $repl = 1; }
- if ($lin =~ m/\)/) { $lins[$_] =~ s/\)/X0029/g; $repl = 1; }
- if ($lin =~ m/\bU [\dA-F]{4}/) {
- $lins[$_] =~ s/\bU ([\dA-F]{4})/U$1/g; $repl = 1;
- }
- }
- }
- if ($lin =~ m/^\(CHARSINTYPE /) { $mod = 1; }
- }
- return ($repl) ? join("\n", @lins) : $pl;
-}
-
-## pl_parse_sub(...)
-# Subcontractor of pl_parse_list.
-sub pl_parse_sub
-{
- my ($toks, $sp, $ep) = @_; my (@pl, $tok, $p, $pp, $pl2);
- for ($p = $sp; $p <= $ep; $p++) {
- $tok = $toks->[$p];
- if ($tok eq '(') {
- $pp = pl_corres_paren($toks, $p);
- ($p < $pp && $pp <= $ep) or return fatal(0);
- (defined($pl2 = pl_parse_sub($toks, $p + 1, $pp - 1))) or return;
- push(@pl, $pl2); $p = $pp;
- } else {
- push(@pl, $tok);
- }
- }
- return \@pl;
-}
-
-## pl_corres_paren($toks, $p)
-# Returns the index of the ')' token which corresponds with the
-# '(' token at index $p in an array $toks.
-sub pl_corres_paren
-{
- my ($toks, $p) = @_; my ($tok, $lv);
- for ($lv = 1, ++$p; $p <= $#$toks; $p++) {
- $tok = $toks->[$p];
- if ($tok eq '(') { ++$lv; }
- elsif ($tok eq ')') { --$lv; }
- if ($lv == 0) { last; }
- }
- return ($lv > 0) ? -$lv : $p;
-}
-
-##<*> pl_cook_list($pl)
-# Makes a raw pl-list $pl cooked.
-sub pl_cook_list
-{
- my ($pl) = @_; my ($k, $ent, $res);
- for ($k = 0; $k <= $#$pl; $k++) {
- $ent = $pl->[$k];
- if (ref $ent) {
- if ($ent->[0] eq 'COMMENT') {
- splice(@$pl, $k, 1); redo;
- } elsif ($ent->[0] ne CNUM) {
- (pl_cook_list($ent)) or return;
- }
- } elsif ($ent =~ /^[CKDFOHR]$/ && $k < $#$pl) {
- (defined pl_proc_num($pl, $k)) or return;
- ++$k;
- }
- }
- return $pl;
-}
-
-##<*> pl_form($pl, $ind)
-# Converts a pl-struct $pl into a PL text. Here $ind is the amount
-# of indent: if negative the result is in in-line form.
-sub pl_form
-{
- my ($pl, $ind) = @_; my (@cnks, $ent, $txt);
- foreach $ent (@$pl) {
- (defined($txt = pl_form_list($ent, $ind))) or return;
- push(@cnks, $txt);
- }
- if ($ind >= 0) { return join("\n", @cnks, ''); }
- else { return join(' ', @cnks); }
-}
-
-# for pl_form_list
-my $pl_rx_kent = qr/^[^\x20-\x7e]|^[JUX][0-9A-Fa-f]{4,6}$/;
-
-##<*> pl_form_list($pl, $ind)
-# Converts a pl-list $pl into a Lispish list.
-sub pl_form_list
-{
- my ($pl, $ind) = @_; my (@cnks, @lins, @toks);
- my ($k, $t, $lsepp, $lsep, $ent, $tok, $txt);
- if ($ind >= 0) {
- push(@cnks, '('); $ind += 3;
- $lsepp = $lsep = "\n" . ' ' x $ind;
- } else { push(@cnks, '('); $lsepp = $lsep = ' '; }
- for ($k = 0; $k <= $#$pl; $k++) {
- $ent = $pl->[$k];
- if (ref $ent) {
- if ($ent->[0] eq CNUM) {
- $tok = $pl->[$k + 1]; ++$k;
- if (defined $tok) { push(@lins, $ent->[2], $tok); }
- else {
- (@toks = pl_form_num($ent->[2], $ent->[1])) or return;
- push(@lins, @toks);
- }
- } else {
- if (@lins) { push(@cnks, join(' ', @lins), $lsepp); }
- (defined($txt = pl_form_list($ent, $ind))) or return;
- @lins = (); push(@cnks, $txt, $lsep);
- }
- } elsif ($k > 0 && $ind >= 0 && $ent =~ m/$pl_rx_kent/) {
- if (@lins) { push(@cnks, join(' ', @lins), $lsepp); }
- $t = '';
- while ($pl->[$k] =~ m/$pl_rx_kent/) {
- if (length($t) + length($pl->[$k]) + $ind > 72) { last; }
- $t .= $pl->[$k] . ' '; ++$k;
- }
- --$k; chop($t); @lins = (); push(@cnks, $t, $lsep);
- } else { push(@lins, $ent); }
- }
- push(@cnks, join(' ', @lins), ')');
- if ($ind < 0 && $cnks[-3] eq $lsep) { $cnks[-3] = ''; }
- return join('', @cnks);
-}
-
-##<*> pl_value($pl, $k, $sw)
-# Reads the number at position $k in pl-list $pl. Note that
-# $k is the position of form prefix and not the string represeting
-# the nubmer itself.
-# The value will be rounded to integers unless $sw is true.
-sub pl_value
-{
- my ($pl, $k, $sw) = @_; my ($ent);
- $ent = $pl->[$k];
- if (ref $ent && $ent->[0] eq CNUM) {
- return ($sw) ? $ent->[1] : round($ent->[1]);
- }
- return pl_proc_num($pl, $k);
-}
-
-## pl_proc_num($pl, $k)
-# Converts the number token at position $k in pl-list $pl to
-# cooked form.
-sub pl_proc_num
-{
- my ($pl, $k) = @_; my ($v, $fl, $tok);
- ($fl, $tok) = ($pl->[$k], $pl->[$k + 1]);
- if (defined($v = pl_parse_num($fl, $tok))) {
- $pl->[$k] = [ CNUM, $v, $fl ]; return $v;
- } else {
- return error("malformed number (", $fl, " ", $tok, ")");
- }
-}
-
-##<*> pl_set_value($pl, $k, $v)
-# Changes the number at position $k in pl-list $pl to $v.
-sub pl_set_value
-{
- my ($pl, $k, $v) = @_; my ($ent);
- $ent = $pl->[$k];
- (ref $ent && $ent->[0] eq CNUM)
- or return error("illegal assignment", $ent);
- $pl->[$k + 1] = undef; $ent->[1] = $v;
- return 1;
-}
-
-##<*> pl_set_real($pl, $k)
-# Changes the 'R'-form number at position $k in pl-list $pl to
-# $v, which is a non-scaled value.
-sub pl_set_real
-{
- my ($pl, $k, $v) = @_; my ($ent);
- $ent = $pl->[$k];
- (ref $ent && $ent->[0] eq CNUM && $ent->[2] eq 'R')
- or return error("illegal assignment", $ent);
- $pl->[$k + 1] = undef; $ent->[1] = $v * TU;
- return 1;
-}
-
-##<*> pl_set_value($pl, $k, $v)
-# Changes the form prefix of the number at position $k in
-# pl-list $pl to $v.
-sub pl_set_numtype
-{
- my ($pl, $k, $v) = @_; my ($ent);
- $ent = $pl->[$k];
- (ref $ent && $ent->[0] eq CNUM)
- or return error("illegal assignment", $ent);
- $pl->[$k + 1] = undef; $ent->[2] = $v;
- return 1;
-}
-
-
-##<*> pl_prefer_hex($sw)
-# Sets the value of the global flag $pl_prefer_hex. If its value is
-# true, then 'H' (instead of 'O') is used as a fallback of 'D'/'C'.
-our $pl_prefer_hex = 0;
-sub pl_prefer_hex { $pl_prefer_hex = $_[0]; }
-
-## pl_parse_num($fl, $tok)
-# Converts a number token to the number it expresses. Here $fl is
-# a form prefix and $tok is a token,
-sub pl_parse_num
-{
- my ($fl, $tok) = @_; my ($ll, $ul, $v);
- $ll = 0; $ul = M32;
- if (ref $tok) { return; }
- if ($fl eq 'C') {
- $v = ($tok =~ /^[\x21-\x7e]$/ && ord($tok));
- } elsif ($fl eq 'K') {
- $v = jcode_ord($tok);
- } elsif ($fl eq 'D') {
- $v = ($tok =~ /^-?\d+$/ && $tok); $ul = 255;
- } elsif ($fl eq 'F') {
- $v = (exists $pl_facecode{$tok} && $pl_facecode{$tok});
- } elsif ($fl eq 'O') {
- $v = ($tok =~ /^[0-7]+$/ && oct($tok)); $ul = M32;
- } elsif ($fl eq 'H' || $fl eq 'I') {
- $v = ($tok =~ /^[\da-f]+$/i && hex($tok)); $ul = M32;
- } elsif ($fl eq 'R') {
- $v = ($tok =~ /^[\+\-]?(\d*\.)?\d+$/ && pl_scale_real($tok));
- $ll = - B31; $ul = M31;
- }
- if ($freenum && $fl ne 'R') { $ul = M32; $ll = -$ul; }
- if (!($ll <= $v && $v <= $ul)) { $v = undef; }
- return $v;
-}
-
-## pl_form_num($fl, $v)
-# Expresses the number $v in form $fl. If the number cannot (or
-# should not) be expressed in form $fl, then $fl is fallen back
-# to another suitable value. It returns ($fl, $tok) where $tok
-# is the resulted expression and $fl is the possibly adapted
-# value of form prefix.
-sub pl_form_num
-{
- my ($fl, $v) = @_; my ($tok);
- $tok = $fl;
- if ($fl eq 'F' && $v > 17) { $fl = 'D'; }
- if ($fl eq 'C' && !pl_isprint($v)) { $fl = 'I'; }
- if ($fl eq 'K' && (!pl_isjprint($v))) { $fl = 'H'; }
- if ($fl eq 'D' && $v > 255) { $fl = 'I'; }
- if ($fl eq 'I') { $fl = ($pl_prefer_hex) ? 'H' : 'O'; }
- if (($fl eq 'R' && !(- B31 <= $v && $v <= M31))
- || ($fl ne 'R' && !(0 <= $v && $v <= M32))) {
- return error("number is out of range ($v for $tok)");
- }
- if ($fl eq 'C') { $tok = chr($v); }
- elsif ($fl eq 'K') { $tok = jcode_chr($v); }
- elsif ($fl eq 'D') { $tok = $v; }
- elsif ($fl eq 'F') { $tok = $pl_facecode_rev{$v}; }
- elsif ($fl eq 'O') { $tok = sprintf("%o", $v); }
- elsif ($fl eq 'H') { $tok = sprintf("%X", $v); }
- elsif ($fl eq 'R') { $tok = pl_form_real($v / TU); }
- return ($fl, $tok);
-}
-
-# Note: In PL, big numbers (>255) in decimal are not allowed,
-# whereas they are allowed in VPL.
-
-## pl_form_real($a)
-# Expresses a real number in the same way as in PL.
-sub pl_form_real
-{
- my ($a) = @_; my ($d, @t);
- if ($a < -0.5 / TU) { $a = -$a; @t = ("-"); }
- $a = int($a * TU + 0.5);
- { use integer;
- push(@t, $a / TU, "."); $a %= TU;
- $a = $a * 10 + 5; $d = 10;
- do {
- if ($d > 0x100000) { $a = $a + 0x80000 - $d / 2; }
- push(@t, $a / 0x100000); $a = $a % 0x100000 * 10; $d *= 10;
- } until ($a <= $d);
- }
- return join('', @t);
-}
-
-## pl_scale_real($a)
-# Returns a real value scaled to tfm-unit, rounded to integer.
-sub pl_scale_real
-{
- my ($a) = @_;
- return int($a * TU + (($a < 0) ? -0.5 : +0.5));
-}
-
-
-## pl_isprint($c)
-# Tests if the number $c is to output really in 'C' form.
-sub pl_isprint
-{
- my ($c) = @_;
- return (0 <= $c && $c <= 255 && chr($c) =~ /^\w/);
-}
-
-## pl_isjprint($c)
-# Tests if the number $c is to output in 'K' form.
-sub pl_isjprint
-{
- my ($c) = @_;
- return defined(jcode_chr($c));
-}
-
-####---- Rearranging pl-structs
-
-##<*> pl_rearrange($pl)
-# Sorts the pl-lists in a pl-struct $pl so that they are in
-# 'usual' order.
-sub pl_rearrange
-{
- my ($pl) = @_;
- @$pl = sort { pl_prop_pos($a) <=> pl_prop_pos($b) } (@$pl);
- return $pl;
-}
-
-# for pl_prop_pos
-my %pl_prop_pos_base = (
-# 0xZ0001 --> 0xZXXXXXX
-# 0xZ0002 --> 0xZXX0000
-# 0xZ0003 --> 0xZXXYYYY
- DIRECTION => 0x0000010,
- VTITLE => 0x0000011,
- FAMILY => 0x0000012,
- FACE => 0x0000013,
- HEADER => 0x1000001,
- CODINGSCHEME => 0x2000010,
- DESIGNUNITS => 0x2000011,
- DESIGNSIZE => 0x2000012,
- CHECKSUM => 0x2000013,
- SEVENBITSAFEFLAG => 0x2000014,
- FONTDIMEN => 0x2000015,
- BOUNDARYCHAR => 0x2000016,
- MAPFONT => 0x3000001,
- LIGTABLE => 0x4000010,
- GLUEKERN => 0x4000010,
- CODESPACE => 0x5000000,
- CHARSINTYPE => 0x5000002,
- CHARSINSUBTYPE => 0x5000003,
- TYPE => 0x6000002,
- SUBTYPE => 0x6000003,
- CHARACTER => 0x7000001,
-);
-
-## pl_prop_pos($pl)
-# Subcontractor for pl_rearrange.
-sub pl_prop_pos
-{
- my ($pl) = @_; my ($v, $u);
- $v = $pl_prop_pos_base{$pl->[0]};
- if (!defined $v) { return 0xFFFFFFF; }
- $u = ($v & 0xffffff);
- if ($u == 1) {
- return ($v & 0xf000000) | pl_value($pl, 1);
- } elsif ($u == 2) {
- return ($v & 0xf000000) | (pl_value($pl, 1) << 16);
- } elsif ($u == 3) {
- return ($v & 0xf000000) | (pl_value($pl, 1) << 16) | pl_value($pl, 3);
- } else { return $v; }
-}
-
-####---- Rearranging pl-lists
-
-##<*> pl_clone($pl)
-# Returns a deep clone of a pl-list, where the original and the
-# clone share no reference.
-sub pl_clone
-{
- my ($pl) = @_;
- if (ref $pl eq "ARRAY") {
- return [ map { pl_clone($_) } (@$pl) ];
- } else { return $pl; }
-}
-
-##<*> pl_sclone($pl)
-# Returns a one-level clone of a pl-list, considering cooked
-# number forms which should be uniquified.
-sub pl_sclone
-{
- my ($pl) = @_;;
- if (ref $pl eq "ARRAY") {
- return [ map {
- (ref $_ eq "ARRAY" && $_->[0] eq CNUM) ? [ @$_ ] : $_
- } (@$pl) ];
- } else { return $pl; }
-}
-
-
-####---- Handling PL/JPL/OPL/VPL Structs
-
-# The three functions below generate a header part (stuffs before
-# FONTDIMEN and optionally FONTDIMEN). Here $in is a hash ref with
-# the following effective keys:
-# direction, family, vtitle, face, codingscheme, designunits,
-# designsize, checksum, sevenbitsafeflag, boundarychar
-# they each correspond with the property of the same name. Of them
-# 'designsize' has the default value 10, but it can be cancelled
-# by 'designsize' key with the explicit undef value.
-# If $fd is not undef, it specifies FONTDIMEN list: if $fd is an
-# array ref it is seen as pl-list of FONTDIMEN and placed inside
-# the output pl-list; if $fd is a hash ref then pl_fontdimen($fd)
-# is placed instead.
-# Note: currently these three functions give the same result.
-
-##<*> pl_header($in, $fd)
-sub pl_header
-{ return pl_header_gen($_[0], $_[1], 0); }
-
-##<*> pl_header_vpl($in, $fd)
-sub pl_header_vpl
-{ return pl_header_gen($_[0], $_[1], 8); }
-
-##<*> pl_header_opl($in, $fd, $swl1)
-sub pl_header_opl
-{ return pl_header_gen($_[0], $_[1], ($_[2]) ? 2 : 1); }
-
-## pl_header_gen($in, $fd, $sw)
-# Subcontractor for the above three pl_header_* functions.
-sub pl_header_gen
-{
- my ($in, $fd, $sw) = @_; my ($t, $pe, $dsiz, $ol, @pl);
- if (exists $in->{ofmlevel}) { $ol = $in->{ofmlevel}; }
- elsif ($sw == 1 || $sw == 2) { $ol = $sw - 1; }
- $dsiz = (exists $in->{designsize}) ? $in->{designsize} : 10;
- if (defined $ol) {
- $pe = pl_cook(['OFMLEVEL', 'H', $ol]);
- pl_set_value($pe, 1, $ol); push(@pl, $pe);
- }
- if (defined $in->{direction}) {
- push(@pl, ['DIRECTION', $in->{direction}]);
- }
- if (defined $in->{family}) {
- push(@pl, ['FAMILY', $in->{family}]);
- }
- if (defined $in->{vtitle}) {
- push(@pl, ['VTITLE', $in->{vtitle}]);
- }
- if (defined $in->{face}) {
- $pe = pl_cook(['FACE', 'F', 0]);
- pl_set_value($pe, 1, $in->{face}); push(@pl, $pe);
- }
- if (defined $in->{codingscheme}) {
- push(@pl, ['CODINGSCHEME', $in->{codingscheme}]);
- }
- if (defined $in->{designunits}) {
- $pe = pl_cook(['DESIGNUNITS', 'R', 0]);
- pl_set_real($pe, 1, $in->{designunits}); push(@pl, $pe);
- }
- if (defined $dsiz) {
- $pe = pl_cook(['DESIGNSIZE', 'R', 0]);
- pl_set_real($pe, 1, $dsiz); push(@pl, $pe);
- }
- if (defined $in->{checksum}) {
- $pe = pl_cook(['CHECKSUM', 'O', 0]);
- pl_set_value($pe, 1, $in->{checksum}); push(@pl, $pe);
- }
- if (defined $in->{sevenbitsafeflag}) {
- push(@pl, ['SEVENBITSAFEFLAG', $in->{sevenbitsafeflag}]);
- }
- if (ref $fd eq 'ARRAY') {
- push(@pl, $fd);
- }
- if (ref $fd eq 'HASH') {
- push(@pl, pl_fontdimen($fd));
- }
- if (defined $in->{boundarychar}) {
- $pe = pl_cook(['BOUNDARYCHAR', 'C', 0]);
- pl_set_value($pe, 1, $in->{boundarychar}); push(@pl, $pe);
- }
- return \@pl;
-}
-
-##<*> pl_fontdimen($in)
-# Generates a FONTDIMEN list. $in is a hash ref with the following
-# effective keys:
-# slant, space, stretch, shrink, xheight, quad, extraspace;
-# they each correspond with the property of the same name. All
-# of them have a default value.
-sub pl_fontdimen
-{
- my ($in) = @_; my ($q, $t, $pl);
- (defined $in) or $in = { };
- $pl = pl_cook(['FONTDIMEN',
- ['SLANT', 'R', 0], ['SPACE', 'R', 0],
- ['STRETCH', 'R', 0], ['SHRINK', 'R', 0],
- ['XHEIGHT', 'R', 0], ['QUAD', 'R', 0],
- ['EXTRASPACE', 'R', 0]]);
- $q = $in->{quad}; (defined $q) or $q = 1;
- pl_set_real($pl->[6], 1, $q);
- $t = $in->{slant}; (defined $t) or $t = 0;
- pl_set_real($pl->[1], 1, $t);
- $t = $in->{space}; (defined $t) or $t = $q / 3;
- pl_set_real($pl->[2], 1, $t);
- $t = $in->{stretch}; (defined $t) or $t = $q / 6;
- pl_set_real($pl->[3], 1, $t);
- $t = $in->{shrink}; (defined $t) or $t = $q / 9;
- pl_set_real($pl->[4], 1, $t);
- $t = $in->{xheight}; (defined $t) or $t = $q / 2;
- pl_set_real($pl->[5], 1, $t);
- $t = $in->{extraspace}; (defined $t) or $t = $q / 9;
- pl_set_real($pl->[7], 1, $t);
- return $pl;
-}
-
-##<*> pl_fontdimen_jpl($in)
-# Generates a FONTDIMEN list of JPL. Here $in is the same as in
-# pl_fontdimen, except that two additional keys 'extrastretch'
-# and 'extrashrink' are used and default setting is different.
-sub pl_fontdimen_jpl
-{
- my ($in) = @_; my ($q, $t, $pl);
- (defined $in) or $in = { };
- $pl = pl_cook(['FONTDIMEN',
- ['SLANT', 'R', 0], ['SPACE', 'R', 0],
- ['STRETCH', 'R', 0], ['SHRINK', 'R', 0],
- ['XHEIGHT', 'R', 0], ['QUAD', 'R', 0],
- ['EXTRASPACE', 'R', 0], ['EXTRASTRETCH', 'R', 0],
- ['EXTRASHRINK', 'R', 0]]);
- $q = $in->{quad}; (defined $q) or $q = 1;
- pl_set_real($pl->[6], 1, $q);
- $t = $in->{slant}; (defined $t) or $t = 0;
- pl_set_real($pl->[1], 1, $t);
- $t = $in->{space}; (defined $t) or $t = 0;
- pl_set_real($pl->[2], 1, $t);
- $t = $in->{stretch}; (defined $t) or $t = $q / 10;
- pl_set_real($pl->[3], 1, $t);
- $t = $in->{shrink}; (defined $t) or $t = 0;
- pl_set_real($pl->[4], 1, $t);
- $t = $in->{xheight}; (defined $t) or $t = $q;
- pl_set_real($pl->[5], 1, $t);
- $t = $in->{extraspace}; (defined $t) or $t = $q / 4;
- pl_set_real($pl->[7], 1, $t);
- $t = $in->{extrastretch}; (defined $t) or $t = $q / 5;
- pl_set_real($pl->[8], 1, $t);
- $t = $in->{extrashrink}; (defined $t) or $t = $q / 8;
- pl_set_real($pl->[9], 1, $t);
- return $pl;
-}
-
-# for pl_fonrdimen_?pl_rmt
-our @pl_keys_quad_u_jpl = (
- 0x4E00, 0x3042, 0x306E, 0xFF2D, 0x004D, 0x2014
-);
-our @pl_keys_quad_u_opl = (
- 0x2001, 0x2003, 0x004D, 0x2014
-);
-our @pl_keys_space_u_opl = (
- 0x0020, 0x00A0
-);
-
-##<*> pl_fontdimen_opl_rmt($rmt)
-# Generates a FONTDIMEN list of OPL with values estimated from
-# the glyph metric $rmt.
-sub pl_fontdimen_opl_rmt
-{
- my ($rmt) = @_; my ($t, $in);
- $in = { };
- (defined($t = pl_key_width($rmt, \@pl_keys_quad_u_opl)))
- and $in->{quad} = $t;
- (defined($t = pl_key_width($rmt, \@pl_keys_space_u_opl)))
- and $in->{space} = $t;
- return pl_fontdimen($in);
-}
-
-##<*> pl_fontdimen_jpl_rmt($rmt)
-# Generates a FONTDIMEN list of JPL with values estimated from
-# the glyph metric $rmt.
-sub pl_fontdimen_jpl_rmt
-{
- my ($rmt) = @_; my ($t, $in);
- $in = { };
- (defined($t = pl_key_width($rmt, \@pl_keys_quad_u_jpl)))
- and $in->{quad} = $t;
- return pl_fontdimen($in);
-}
-
-## pl_key_width($rmt)
-# Subcontractor of pl_fontdimen_?pl_rmt.
-sub pl_key_width
-{
- my ($rmt, $keys) = @_; my ($t, %hsh);
- foreach (@$rmt) { $hsh{$_->[0]} = $_; }
- foreach (@$keys) {
- (defined($t = $hsh{$_})) or next;
- return $t->[1];
- }
- return;
-}
-
-## pl_cook($pl)
-# Cooks a pl-list $pl and returns it. (Sometimes more convenient
-# than pl_cook_list.)
-*pl_cook = \&pl_cook_list;
-
-# for pl_get_metric
-my %pl_char_part_pos = (
- CHARWD => 1, CHARHT => 2, CHARDP => 3, CHARIC => 4
-);
-
-##<*> pl_get_metric($pl)
-# Reads the metric data from the CHARACTER set of pl-struct $pl
-# and converts them to a raw metric array.
-sub pl_get_metric
-{
- my ($pl) = @_; my ($t, $p, $pe, $pe2, $ent, @rmt);
- foreach $pe (@$pl) {
- if ($pe->[0] eq 'CHARACTER') {
- (defined($t = pl_value($pe, 1))) or return;
- $ent = [ $t ];
- foreach $pe2 (@{$pe}[3 .. $#$pe]) {
- if (defined($p = $pl_char_part_pos{$pe2->[0]})) {
- (defined($t = pl_value($pe2, 1))) or return;
- $ent->[$p] = $t / TU;
- }
- }
- push(@rmt, $ent);
- }
- }
- return \@rmt;
-}
-
-# for pl_char_part
-my @pl_char_part_name = qw( * CHARWD CHARHT CHARDP CHARIC );
-
-##<*> pl_char_part
-# Converts a raw metric array to an array of CHARACTER lists.
-# Partial inverse of pl_get_metric
-sub pl_char_part
-{
- my ($rmt) = @_; my ($ent, $pe, $pe2, $pl);
- $pl = [ ];
- foreach $ent (@$rmt) {
- $pe = pl_cook(['CHARACTER', 'C', 0]);
- pl_set_value($pe, 1, $ent->[0]);
- foreach (1 .. 4) {
- if (defined($ent->[$_])) {
- $pe2 = pl_cook([$pl_char_part_name[$_], 'R', 0]);
- pl_set_real($pe2, 1, $ent->[$_]); push(@$pe, $pe2);
- }
- }
- push(@$pl, $pe);
- }
- return $pl;
-}
-
-##<*> pl_char_part_jpl($imt, $vmt, $swu)
-# ...
-sub pl_char_part_jpl
-{
- my ($imt, $vmt, $swu) = @_; my ($t, $cc, $ti, $jp);
- my (@cit, $pl, $pe, @u);
- $jp = ($swu) ? 'U' : 'J';
- foreach $cc (keys %$imt) {
- push(@{$cit[$imt->{$cc}]}, $cc);
- }
- foreach $ti (1 .. $#cit) {
- @u = map { sprintf("%s%04X", $jp, $_) }
- (sort { $a <=> $b } (@{$cit[$ti]}));
- $pe = pl_cook(['CHARSINTYPE', 'D', 0, @u]);
- pl_set_value($pe, 1, $ti); push(@$pl, $pe);
- }
- foreach $ti (0 .. $#$vmt) {
- $pe = pl_cook(['TYPE', 'D', 0, ['CHARWD', 'R', 0],
- ['CHARHT', 'R', 0], ['CHARDP', 'R', 0]]);
- pl_set_value($pe, 1, $ti);
- pl_set_real($pe->[3], 1, $vmt->[$ti][0]);
- pl_set_real($pe->[4], 1, $vmt->[$ti][1]);
- pl_set_real($pe->[5], 1, $vmt->[$ti][2]);
- push(@$pl, $pe);
- }
- return $pl;
-}
-
-
-######## 'jcode' section ########
-
-our $jcode_ex = K_JIS;
-our $jcode_in = KI_JIS;
-our $jfm_forced_prefix;
-
-my %jcode_ex_sym = ( jis => K_JIS, euc => K_EUC,
- sjis => K_SJIS, utf8 => K_UTF8,
- none => undef, xjis => K_XJIS );
-my %jcode_in_sym = ( jis => KI_JIS, unicode => KI_UNI,
- none => undef, xjis => KI_XJIS );
- # 'xjis' is for internal use
-
-##<*> jcode_set($xjc, $ijc)
-# Declares external [internal] Japanese code to be $xjc [$ijc],
-# which is a key of %jcode_ex_sym [%jcode_in_sym].
-sub jcode_set
-{
- my ($xjc, $ijc) = @_; my ($t);
- if (defined $xjc) {
- (exists $jcode_ex_sym{$xjc}) or return;
- $jcode_ex = $jcode_ex_sym{$xjc};
- }
- if (defined $ijc) {
- (exists $jcode_in_sym{$ijc}) or return;
- $jcode_in = $jcode_in_sym{$ijc};
- }
- #if (!defined $jcode_ex || !defined $jcode_in) {
- # $jcode_ex = $jcode_in = undef;
- #}
- return 1;
-}
-
-##<*> jcode_chr($cod)
-# Converts a code value of the internal code to a string containing
-# the character encoded in the external code.
-sub jcode_chr
-{
- my ($cod) = @_; my ($xs, $is);
- (defined $jcode_in && defined $jcode_ex) or return;
- (0 <= $cod && $cod <= 0xFFFF) or return;
- $xs = chr($cod >> 8) . chr($cod & 0xFF);
- eval {
- $is = decode($jcode_in, $xs, Encode::FB_CROAK);
- $xs = encode($jcode_ex, $is, Encode::FB_CROAK);
- };
- ($@ eq '' && length($is) == 1) or return;
- return $xs;
-}
-
-##<*> jcode_ord($xs)
-# Inverse of jcode_chr.
-sub jcode_ord
-{
- my ($xs) = @_; my ($is, $cod, $f);
- (defined $jcode_in && defined $jcode_ex) or return;
- if ($jcode_in eq KI_XJIS && $jcode_ex eq K_XJIS) {
- $xs =~ m/\x1B\x24\x42(..)\x1B\x28\x42/ or return;
- return unpack('n', $1);
- }
- eval {
- $is = decode($jcode_ex, $xs, Encode::FB_CROAK);
- (length($is) == 1) or die;
- };
- ($@ eq '') or return;
- if ($jcode_in eq KI_UNI) { return ord($is); }
- eval {
- $xs = encode($jcode_in, $is, Encode::FB_CROAK);
- };
- ($@ eq '' && $xs =~ m/^(.)(.)$/s) or return;
- return (ord($1) << 8 | ord($2));
-}
-
-######## 'kpse' section ########
-
-our $kpse_init_done;
-our $kpse_delim;
-our %kpse_format_alias = (
- cmap => 'cmap files',
-);
-
-##<*> kpse($fnam, $opt)
-# Executes 'kpsewhich' for filename $fnam with option $opt.
-# If $opt is a scalar, it means the value for 'format' option.
-# If $opt is a hash ref, then the value for keys 'dpi', 'engine',
-# 'mode', 'progname' and 'format' corresponds with the value of the
-# option with same name and the boolean value for key 'mustexist'
-# corresponds with existence of 'must-exist' option. For 'option'
-# value, aliasing specified with %kpse_format_alias is done.
-sub kpse
-{
- my ($fnam, $opt) = @_; my ($cmd, $res);
- ($kpse_init_done || kpse_init()) or return undef;
- $opt = kpse_parse_option($opt, $fnam); $cmd = $cmd_name{kpsewhich};
- if (ref $opt eq 'ARRAY') { return kpse_manual($fnam, $opt); }
- $res = `$cmd $opt "$fnam"`; chomp($res);
- if (-f $res) { return $res; }
- else { # returns undef, not nothing
- error("kpse failed to find a file: $fnam"); return undef;
- }
-}
-
-##<*> kpse_init()
-# Initializes the kpse section of this module.
-sub kpse_init
-{
- my ($res, $cmd);
- (!defined $kpse_init_done)
- or return error("kpsewhich failure");
- $cmd = $cmd_name{kpsewhich};
- if (($res = `$cmd -show-path=tex`) eq '') {
- $kpse_init_done = 0;
- return error("kpsewhich failure");
- }
- if ($res =~ m/^\.\:/) { $kpse_delim = ':'; }
- elsif ($res =~ m/;/) { $kpse_delim = ';'; }
- else { $kpse_delim = ':'; }
- $kpse_init_done = 1;
- return 1;
-}
-
-## kpse_parse_option($opt)
-# Subcontractor of kpse.
-sub kpse_parse_option
-{
- my ($opt, $fnam) = @_; my ($o, $t, @copts);
- if (ref $opt eq 'ARRAY') { return $opt; } # for future extension
- elsif (ref $opt eq 'HASH') {
- foreach $o (qw(dpi engine mode progname)) {
- if (exists $opt->{$o}) {
- push(@copts, "-$o=" . $opt->{$o});
- }
- }
- if ($opt->{mustexist}) { push(@copts, '-must-exist'); }
- $opt = $opt->{format};
- }
- if ($opt eq '' && $fnam =~ m/\.vf$/i) { $opt = "vf"; }
- if ($opt ne '') {
- if (defined($t = $kpse_format_alias{$opt})) { $opt = $t; }
- push(@copts, "-format=\"$opt\"");
- }
- return join(' ', @copts);
-}
-
-######## 'vf' section ########
-
-##<*> vf_strict($sw)
-# Sets strict mode in parsing or forming VF.
-our $vf_strict = 1;
-sub vf_strict { $vf_strict = $_[0]; }
-
-## vf_simple_move_code($sw)
-# Sets the value of $vf_simple_move_code. If it is true, then
-# vf_form does not exploit w, x, y, z registers in compiling
-# move operations in DVI code.
-our $vf_simple_move_code = 0;
-sub vf_simple_move_code { $vf_simple_move_code = $_[0]; }
-
-##-------- Procedures on ZVP0 format
-
-##<*> vf_parse($dat, $swdh)
-# Converts a (binary) VF data $dat to a pl-struct describing
-# ZPL0 data. If something invalid is found in DVI code and $swdh
-# is true, then DVI is written with a DIRECTHEX entry.
-sub vf_parse
-{
- my ($dat, $swdh) = @_;
- my ($t, $u, @fs, $pos, $pl, $pe, $stg);
- (defined $swdh) or $swdh = !$vf_strict;
- (length($dat) >= 3) or return vf_synerror("in preamble");
- @fs = unpack("CCC/a*NN", $dat); $pos = length($fs[2]) + 11;
- ($#fs == 4 && $fs[0] == 247 && $fs[1] == 202)
- or return vf_synerror("in preamble");
- $pl = pl_header_vpl({ vtitle => $fs[2], checksum => $fs[3],
- designsize => $fs[4] / TU });
- for (;;) {
- $t = ord(substr($dat, $pos, 1));
- if ($stg <= 2 && 0 <= $t && $t <= 241) { # short_charN
- @fs = unpack("CCa3a$t", substr($dat, $pos, $t + 5)); $pos += $t + 5;
- ($#fs == 3 && length($fs[3]) == $t)
- or return vf_synerror("premature end");
- $pe = pl_cook(['CHARACTER', 'C', 0,
- ['CHARWD', 'R', 0], undef]);
- if (defined($t = vf_dvi_parse($fs[3]))) { $pe->[4] = $t; }
- elsif (!$swdh) {
- return vf_synerror("illegal dvi code (char $fs[1])");
- } else { $pe->[4] = vf_dvi_dumb_parse($u); }
- pl_set_value($pe->[3], 1, unpack_num($fs[2])); # (unsigned)
- pl_set_value($pe, 1, $fs[1]);
- $stg = 2; push(@$pl, $pe);
- } elsif ($stg <= 2 && $t == 242) { # long_char
- @fs = unpack("CNNN", substr($dat, $pos, 13)); $pos += 13;
- $u = substr($dat, $pos, $fs[1]); $pos += $fs[1];
- #-- give a cooked list for efficiency
- #$pe = pl_cook(['CHARACTER', 'C', 0,
- # ['CHARWD', 'R', 0], undef]);
- $pe = (['CHARACTER', [CNUM, 0, 'C'], 0,
- ['CHARWD', [CNUM, 0, 'R'], 0], undef]);
- if (defined($t = vf_dvi_parse($u))) { $pe->[4] = $t; }
- elsif (!$swdh) {
- return vf_synerror("illegal dvi code (char $fs[2])");
- } else { $pe->[4] = vf_dvi_dumb_parse($u); }
- pl_set_value($pe->[3], 1, signed($fs[3]));
- pl_set_value($pe, 1, $fs[2]);
- $stg = 2; push(@$pl, $pe);
- } elsif ($stg <= 1 && 243 <= $t && $t <= 246) { # fnt_defN
- $t -= 242;
- @fs = unpack("Ca${t}NNNCC", substr($dat, $pos, $t + 15)); $pos += $t + 15;
- ($#fs == 6) or return vf_synerror("premature end");;
- $t = $fs[5] + $fs[6]; $u = substr($dat, $pos, $t); $pos += $t;
- (length($u) == $t) or return vf_synerror("premature end");;
- $fs[6] = substr($u, $fs[5]); $fs[5] = substr($u, 0, $fs[5]);
- $pe = pl_cook(['MAPFONT', 'D', 0, ['FONTAREA', 0],
- ['FONTNAME', 0],, ['FONTCHECKSUM', 'O', 0],
- ['FONTAT', 'R', 0], ['FONTDSIZE', 'R', 0]]);
- $pe->[3][1] = $fs[5]; $pe->[4][1] = $fs[6];
- pl_set_value($pe->[5], 1, $fs[2]);
- pl_set_value($pe->[6], 1, $fs[3]);
- pl_set_value($pe->[7], 1, $fs[4]);
- pl_set_value($pe, 1, unpack_num($fs[1]));
- if ($fs[5] eq '') { splice(@$pe, 3, 1); }
- $stg = 1; push(@$pl, $pe);
- } elsif ($stg == 2 && $t == 248) { # post
- (($u = substr($dat, $pos, $t)) =~ /^\xf8+$/)
- or return vf_synerror("in postamble");
- last;
- } else { return vf_synerror("unexpected byte $t"); }
- }
- return $pl;
-}
-
-## vf_dvi_parse($dat)
-# Subcontractor of vf_parse.
-sub vf_dvi_parse
-{
- my ($dat) = @_;
- my ($t, $u, @fs, $pos, $pl, $pe, $stk, $stg);
- $pl = ['MAP']; $stk = [{}];
- for ($pos = 0; $pos < length($dat); ) {
- $t = ord(substr($dat, $pos, 1));
- if (0 <= $t && $t <= 127) { # set_charN
- $pe = pl_cook(['SETCHAR', 'C', 0]); $pos += 1;
- pl_set_value($pe, 1, $t); push(@$pl, $pe);
- } elsif (128 <= $t && $t <= 131) { # setN
- $t -= 127; @fs = unpack("Ca$t", substr($dat, $pos));
- $pos += $t + 1; ($#fs == 1) or return;
- $pe = pl_cook(['SETCHAR', 'C', 0]);
- pl_set_value($pe, 1, unpack_num($fs[1])); push(@$pl, $pe);
- } elsif ($t == 132) { # setrule
- @fs = unpack("CNN", substr($dat, $pos));
- $pos += 9; ($#fs == 2) or return;
- $pe = pl_cook(['SETRULE', 'R', 0, 'R', 0]);
- pl_set_value($pe, 1, signed($fs[1]));
- pl_set_value($pe, 3, signed($fs[2])); push(@$pl, $pe);
- } elsif ($t == 141) { # push
- $pos += 1; push(@$pl, ['PUSH']); push(@$stk, {});
- } elsif ($t == 142) { # pop
- $pos += 1; push(@$pl, ['POP']); pop(@$stk);
- (@$stk) or return;
- } elsif (143 <= $t && $t <= 146) { # rightN
- ($pe, $pos) = vf_dvi_move1($dat, $pos, $stk, 'r', $t - 142);
- (defined $pe) or return; push(@$pl, $pe);
- } elsif ($t == 147) { # w0
- ($pe, $pos) = vf_dvi_move0($dat, $pos, $stk, 'w');
- (defined $pe) or return; push(@$pl, $pe);
- } elsif (148 <= $t && $t <= 151) { # wN
- ($pe, $pos) = vf_dvi_move1($dat, $pos, $stk, 'w', $t - 147);
- (defined $pe) or return; push(@$pl, $pe);
- } elsif ($t == 152) { # x0
- ($pe, $pos) = vf_dvi_move0($dat, $pos, $stk, 'x');
- (defined $pe) or return; push(@$pl, $pe);
- } elsif (153 <= $t && $t <= 156) { # xN
- ($pe, $pos) = vf_dvi_move1($dat, $pos, $stk, 'x', $t - 152);
- (defined $pe) or return; push(@$pl, $pe);
- } elsif (157 <= $t && $t <= 160) { # downN
- ($pe, $pos) = vf_dvi_move1($dat, $pos, $stk, 'd', $t - 156);
- (defined $pe) or return; push(@$pl, $pe);
- } elsif ($t == 161) { # y0
- ($pe, $pos) = vf_dvi_move0($dat, $pos, $stk, 'y');
- (defined $pe) or return; push(@$pl, $pe);
- } elsif (162 <= $t && $t <= 165) { # yN
- ($pe, $pos) = vf_dvi_move1($dat, $pos, $stk, 'y', $t - 161);
- (defined $pe) or return; push(@$pl, $pe);
- } elsif ($t == 166) { # z0
- ($pe, $pos) = vf_dvi_move0($dat, $pos, $stk, 'z');
- (defined $pe) or return; push(@$pl, $pe);
- } elsif (167 <= $t && $t <= 170) { # zN
- ($pe, $pos) = vf_dvi_move1($dat, $pos, $stk, 'z', $t - 166);
- (defined $pe) or return; push(@$pl, $pe);
- } elsif (171 <= $t && $t <= 234) { # fnt_numN
- $t -= 171; $pe = pl_cook(['SELECTFONT', 'D', 0]); $pos += 1;
- pl_set_value($pe, 1, $t); push(@$pl, $pe);
- } elsif (235 <= $t && $t <= 238) { # fntN
- $t -= 234; @fs = unpack("Ca$t", substr($dat, $pos));
- $pos += $t + 1; ($#fs == 1) or return;
- $pe = pl_cook(['SELECTFONT', 'D', 0]);
- pl_set_value($pe, 1, unpack_num($fs[1])); push(@$pl, $pe);
- } elsif (239 <= $t && $t <= 242) { # xxxN
- $t -= 238; @fs = unpack("Ca$t", substr($dat, $pos));
- $pos += $t + 1; ($#fs == 1) or return;
- $t = unpack_num($fs[1]); $u = substr($dat, $pos, $t);
- $pos += $t; ($t == length($u)) or return;
- $pe = vf_dvi_special($u); push(@$pl, $pe);
- } elsif ($t == 255) { # dir (JVF)
- @fs = unpack("CC", substr($dat, $pos));
- $pos += 2; ($#fs == 1) or return;
- $pe = pl_cook(['DIR', 'D', 0]);
- pl_set_value($pe, 1, $fs[1]); push(@$pl, $pe);
- } else { return; }
- }
- return $pl;
-}
-
-## vf_synerror($msg)
-# Error messages in vf_parse.
-sub vf_synerror
-{
- return error("VF syntax error: $_[0]");
-}
-
-# for vf_dvi_move1 / vf_dvi_move0
-my %vf_dvi_move = (
- r => 'MOVERIGHT', w => 'MOVERIGHT', x => 'MOVERIGHT',
- d => 'MOVEDOWN', y => 'MOVEDOWN', z => 'MOVEDOWN',
-);
-
-## vf_dvi_move1(...)
-# Subcontractor of vf_dvi_parse.
-sub vf_dvi_move1
-{
- my ($dat, $pos, $stk, $r, $l) = @_; my ($t, $pe, @fs);
- @fs = unpack("Ca$l", substr($dat, $pos));
- $pos += $l + 1; ($#fs == 1) or return;
- $stk->[-1]{$r} = $t = unpack_snum($fs[1]);
- $pe = pl_cook([$vf_dvi_move{$r}, 'R', 0]);
- pl_set_value($pe, 1, $t);
- return ($pe, $pos);
-}
-
-## vf_dvi_move0(...)
-# Subcontractor of vf_dvi_parse.
-sub vf_dvi_move0
-{
- my ($dat, $pos, $stk, $r) = @_; my ($t, $pe);
- (defined($t = $stk->[-1]{$r})) or return;
- $pe = pl_cook([$vf_dvi_move{$r}, 'R', 0]);
- pl_set_value($pe, 1, $t);
- return ($pe, $pos + 1);
-}
-
-## vf_dvi_special($dat)
-# Subcontractor of vf_dvi_parse.
-sub vf_dvi_special
-{
- my ($dat) = @_; my ($t, $u, $pl); local ($errmsg);
- L1:{
- $t = "($dat)"; ($t !~ m/[^\x20-\x7e]/) or last;
- (defined($pl = pl_parse_list($t))) or last;
- (vf_issafe_list($pl)) or last;
- $u = pl_form_list($pl, -1);
- return ['SPECIAL', $dat];
- }
- return ['SPEICALHEX', uc(unpack('H*', $dat))];
-}
-
-## vf_issafe_list($pl)
-# Subcontractor of vf_dvi_special.
-sub vf_issafe_list
-{
- my ($pl) = @_; my ($ent);
- foreach $ent (@$pl) {
- if (ref $ent) {
- (vf_issafe_list($ent)) or return 0;
- } elsif ($ent =~ /^[CKDFOHR]$/ || $ent eq 'COMMENT') {
- return 0;
- }
- }
- return 1;
-}
-
-## vf_dvi_dumb_parse($dat)
-# Subcontractor of dvi_parse.
-sub vf_dvi_dumb_parse
-{
- my ($dat) = @_;
- my ($t);
- $t = uc(unpack("H*", $dat));
- return ['MAP', ['DIRECTHEX', $t]];
-}
-
-##<*> vf_form($pl)
-# Inverse of vf_parse.
-sub vf_form
-{
- my ($pl) = @_;
- my ($t, $u, $v, $pe, @fs, @chds, @cfds, @ccps);
- @chds = (247, 202, "", 0, 10 * TU);
- foreach $pe (@$pl) {
- if ($pe->[0] eq 'VTITLE') {
- ($#$pe <= 1) or return vf_fsynerror("bad argument", $pe);
- (length($pe->[1]) <= 255)
- or return vf_fsynerror("VTITLE string too long", $pe->[1]);
- $chds[2] = $pe->[1];
- } elsif ($pe->[0] eq 'CHECKSUM') {
- ($#$pe == 2 && defined($t = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- $chds[3] = $t;
- } elsif ($pe->[0] eq 'DESIGNSIZE') {
- ($#$pe == 2 && defined($t = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- $chds[4] = $t;
- } elsif ($pe->[0] eq 'MAPFONT') {
- ($#$pe >= 2 && defined($t = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- ($u, $t) = pack_num($t);
- @fs = ($u + 242, $t, 0, TU, 10 * TU, 0, 0, '', '');
- foreach $pe (@{$pe}[3 .. $#$pe]) {
- if (!ref $pe) {
- return vf_fsynerror("unexpected bareword", $pe);
- } elsif ($pe->[0] eq 'FONTCHECKSUM') {
- ($#$pe == 2 && defined($fs[2] = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- } elsif ($pe->[0] eq 'FONTAT') {
- ($#$pe == 2 && defined($fs[3] = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- } elsif ($pe->[0] eq 'FONTDSIZE') {
- ($#$pe == 2 && defined($fs[4] = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- } elsif ($pe->[0] eq 'FONTAREA') {
- ($#$pe == 1 && length($pe->[1]) <= 255)
- or return vf_fsynerror("bad argument", $pe);
- $fs[7] = $pe->[1]; $fs[5] = length($pe->[1]);
- } elsif ($pe->[0] eq 'FONTNAME') {
- ($#$pe == 1 && length($pe->[1]) <= 255)
- or return vf_fsynerror("bad argument", $pe);
- $fs[8] = $pe->[1]; $fs[6] = length($pe->[1]);
- } elsif (!$vf_strict) {
- return vf_fsynerror("unknown property", $pe);
- }
- }
- push(@cfds, pack("Ca*NNNCCa*a*", @fs));
- } elsif ($pe->[0] eq 'CHARACTER') {
- ($#$pe >= 2 && defined($t = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- $v = 0; $u = undef;
- foreach $pe (@{$pe}[3 .. $#$pe]) {
- if (!ref $pe) {
- return vf_fsynerror("unexpected bareword", $pe);
- } elsif ($pe->[0] eq 'CHARWD') {
- ($#$pe == 2 && defined($v = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- } elsif ($pe->[0] eq 'MAP') {
- (defined($u = vf_dvi_form($pe, $t))) or return;
- } elsif (!$vf_strict) {
- return vf_fsynerror("unknown property", $pe);
- }
- }
- if (!defined $u) {
- $u = pl_cook(['MAP', ['SETCHAR']]);
- (defined($u = vf_dvi_form($u, $t))) or return;
- }
- if (0 <= $t && $t <= 255 && 0 <= $v && $v <= 0xFFFFFF &&
- length($u) <= 241) { # short form
- @fs = (length($u), $t, substr(pack('N', $v), 1), $u);
- push(@ccps, pack("CCa3a*", @fs));
- } else {
- @fs = (242, length($u), $t, $v, $u);
- push(@ccps, pack("CNNNa*", @fs));
- }
- } elsif ($vf_strict) {
- return vf_fsynerror("unknown property", $pe);
- }
- }
- $t = pack("CCC/a*NN", @chds);
- $t = join('', $t, @cfds, @ccps);
- $t .= "\xf8" x (4 - length($t) % 4);
- return $t;
-}
-
-## vf_dvi_form($pl, $cc)
-# Subcontractor of vf_form
-sub vf_dvi_form
-{
- my ($pl, $cc) = @_;
- my ($t, $u, $v, $l, $pe, $stk, @cnks);
- $stk = [{}];
- foreach $pe (@{$pl}[1 .. $#$pl]) {
- if ($pe->[0] eq 'SETCHAR') {
- if ($#$pe == 0) { $t = $cc; }
- elsif ($#$pe == 2 && defined($t = pl_value($pe, 1))) {
- } else { return vf_fsynerror("bad argument", $pe); }
- if (0 <= $t && $t <= 127) {
- push(@cnks, chr($t));
- } else {
- ($l, $t) = pack_num($t);
- push(@cnks, pack("Ca*", $l + 127, $t));
- }
- } elsif ($pe->[0] eq 'SETRULE') {
- ($#$pe == 4 && defined($t = pl_value($pe, 1)) &&
- defined($u = pl_value($pe, 3)))
- or return vf_fsynerror("bad argument", $pe);
- push(@cnks, pack("CNN", 132, $t, $u));
- } elsif ($pe->[0] eq 'PUSH') {
- push(@$stk, {}); push(@cnks, chr(141));
- } elsif ($pe->[0] eq 'POP') {
- pop(@$stk); (@$stk) or vf_fsynerror("cannot POP (char $cc)");
- push(@cnks, chr(142));
- } elsif ($pe->[0] eq 'MOVERIGHT') {
- (defined($t = vf_dvi_f_move($pe, $stk->[-1], 'r',+1))) or return;
- push(@cnks, $t);
- } elsif ($pe->[0] eq 'MOVELEFT') {
- (defined($t = vf_dvi_f_move($pe, $stk->[-1], 'r',-1))) or return;
- push(@cnks, $t);
- } elsif ($pe->[0] eq 'MOVEDOWN') {
- (defined($t = vf_dvi_f_move($pe, $stk->[-1], 'd',+1))) or return;
- push(@cnks, $t);
- } elsif ($pe->[0] eq 'MOVEUP') {
- (defined($t = vf_dvi_f_move($pe, $stk->[-1], 'd',-1))) or return;
- push(@cnks, $t);
- } elsif ($pe->[0] eq 'SELECTFONT') {
- ($#$pe == 2 && defined($t = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- if (0 <= $t && $t <= 63) {
- push(@cnks, chr($t + 171));
- } else {
- ($l, $t) = pack_num($t);
- push(@cnks, pack("Ca*", $l + 234, $t));
- }
- } elsif ($pe->[0] eq 'SPECIAL') {
- $t = pl_form_list($pe, -1);
- ($t =~ m|^\(SPECIAL\s?(.*)\)$|) or return fatal("vf_dvi_form");
- $u = $1; ($l, $t) = pack_num(length($u));
- push(@cnks, pack("Ca*a*", 238 + $l, $t, $u));
- } elsif ($pe->[0] eq 'SPECIALHEX') {
- ($u = join('', @{$pe}[1 .. $#$pl])) =~ s/\s+//g;
- ($u =~ m/^([0-9A-Fa-f]{2})+$/)
- or return vf_fsynerror("bad arguments", $pe);
- $u = pack("H*", $u); ($l, $t) = pack_num(length($u));
- push(@cnks, pack("Ca*a*", 238 + $l, $t, $u));
- } elsif ($pe->[0] eq 'DIR') {
- ($#$pe == 2 && defined($t = pl_value($pe, 1)) && $t <= 1)
- or return vf_fsynerror("bad argument", $pe);
- push(@cnks, pack("CC", 255, $t));
- } elsif ($pe->[0] eq 'DIRECTHEX') {
- ($u = join('', @{$pe}[1 .. $#$pl])) =~ s/\s+//g;
- ($u =~ m/^([0-9A-Fa-f]{2})+$/)
- or return vf_fsynerror("bad arguments", $pe);
- $u = pack("H*", $u); push(@cnks, $u);
- } else {
- return vf_fsynerror("unknown DVI operator: ", $pe);
- }
- }
- return join('', @cnks);
-}
-
-## vf_dvi_f_move($pe, $stk, $r, $sgn)
-# Subcontractor of vf_dvi_form.
-sub vf_dvi_f_move
-{
- my ($pe, $stk, $r, $sgn) = @_; my ($v, $l, $t, $w, $x, $b);
- ($#$pe == 2 && defined($v = pl_value($pe, 1)))
- or return vf_fsynerror("bad argument", $pe);
- if ($sgn < 0) { $v = -$v; }
- ($l, $t) = pack_snum($v);
- ($w, $x, $b) = ($r eq 'r') ? ('w', 'x', 142) : ('y', 'z', 156);
- if ($vf_simple_move_code) { $t = pack("Ca*", $b + $l, $t); }
- elsif (!exists $stk->{$w}) {
- $stk->{$w} = $v; $t = pack("Ca*", $b + $l + 5, $t);
- } elsif ($stk->{$w} == $v) { $t = chr($b + 5); }
- elsif (!exists $stk->{$x}) {
- $stk->{$x} = $v; $t = pack("Ca*", $b + $l + 10, $t);
- } elsif ($stk->{$x} == $v) { $t = chr($b + 10); }
- else { $t = pack("Ca*", $b + $l, $t); }
- return $t;
-}
-
-## vf_fsynerror($msg)
-# Error messages in vf_form.
-sub vf_fsynerror
-{
- my ($msg, $pl) = @_;
- if (ref $pl) { $pl = pl_form_list($pl, -1); }
- return error("VPL syntax error: $msg: $pl");
-}
-
-##<*> vf_for_mapping($map, $fn, $rmt)
-#
-sub vf_for_mapping
-{
- my ($map, $fn, $rmt) = @_; my ($e, $pe, $pe2, $pl, %hrmt);
- if (defined $rmt) {
- foreach (@$rmt) { $hrmt{$_->[0]} = $_; }
- }
- (defined($map = arraymap($map))) or return;
- $pl = pl_header_vpl({});
- push(@$pl, pl_cook(['MAPFONT', 'D', 0, ['FONTNAME', $fn]]));
- foreach $e (@$map) {
- if (defined $rmt && !defined $hrmt{$e->[0]}) { next; }
- $pe = pl_cook(['CHARACTER', 'C', 0,
- ['MAP', ['SETCHAR', 'C', 0]]]);
- pl_set_value($pe, 1, $e->[0]);
- pl_set_value($pe->[3][1], 1, $e->[1]);
- if (defined $rmt) {
- $pe2 = pl_cook(['CHARWD', 'R', 0]);
- pl_set_real($pe2, 1, $hrmt{$e->[0]}[1]);
- splice(@$pe, 3, 0, $pe2);
- }
- push(@$pl, $pe);
- }
- return $pl;
-}
-
-##<*> vf_mapfont($pl, $fn)
-# Returns the FONTNAME value of MAPFONT id $fn in VPL $pl.
-# If $fn is undef then it returns ref to the hash that maps
-# id to fontmame.
-sub vf_mapfont
-{
- my ($pl, $fn) = @_; my ($t, $pe, $pe2, %hsh);
- foreach $pe (@$pl) {
- if ($pe->[0] eq 'MAPFONT') {
- ($pe2) = grep { $_->[0] eq 'FONTNAME' } (@{$pe}[3 .. $#$pe]);
- (defined $pe2) or next;
- if (!defined $fn) {
- $hsh{pl_value($pe, 1)} = $pe2->[1];
- } elsif (defined($t = pl_value($pe, 1)) && $t == $fn) {
- return $pe2->[1];
- }
- }
- }
- return (defined $fn) ? () : \%hsh;
-}
-
-##<*> vf_set_mapfont($pl, $fn, $fnam)
-# Sets the FONTNAME value of MAPFONT id $fn to $fname
-# in VPL $pl.
-sub vf_set_mapfont
-{
- my ($pl, $fn, $fnam) = @_; my ($t, $pe, $pe2, %hsh);
- foreach $pe (@$pl) {
- if ($pe->[0] eq 'MAPFONT' &&
- defined($t = pl_value($pe, 1)) && $t == $fn) {
- ($pe2) = grep { $_->[0] eq 'FONTNAME' } (@{$pe}[3 .. $#$pe]);
- (defined $pe2) or return 0;
- $pe2->[1] = $fnam; return 1;
- }
- }
- return 0;
-}
-
-##-------- Procedures on ZVP format
-
-my %vf_zvp_category = (
-# 1: to JPL, 2: to ZVP0, 3: both, 0: special
- DIRECTION => 1,
- VTITLE => 2,
- FAMILY => 1,
- FACE => 1,
- HEADER => 1,
- CODINGSCHEME => 1,
- DESIGNUNITS => 1,
- DESIGNSIZE => 3,
- CHECKSUM => 3,
- SEVENBITSAFEFLAG => 1,
- FONTDIMEN => 1,
- BOUNDARYCHAR => 1,
- MAPFONT => 2,
- LIGTABLE => 1,
- GLUEKERN => 0,
- CODESPACE => 0,
- CHARSINTYPE => 0,
- CHARSINSUBTYPE => 0,
- TYPE => 0,
- SUBTYPE => 0,
- CHARACTER => 0,
-);
-my %vf_zvp_category_char = (
- CHARWD => 0,
- CHARHT => 2,
- CHARDP => 3,
- CHARIC => 4,
-);
-
-##<*> debug_vf_form($val)
-our ($debug_vf_form);
-sub debug_vf_form { $debug_vf_form = $_[0]; }
-
-##<*> vf_form_ex($pl)
-# Converts ZPL $pl to VF $vf and TFM $tfm and returns pair
-# ($vf, $tfm).
-sub vf_form_ex
-{
- my ($pl) = @_; my ($plv, $plt, $vf, $tfm);
- (($plv, $plt) = vf_divide_zvp($pl)) or return;
- if ($debug_vf_form) {
- return (pl_form($plv), pl_form($plt));
- }
- (defined($vf = vf_form($plv))) or return;
- (defined($tfm = jfm_form($plt))) or return;
- return ($vf, $tfm);
-}
-
-
-## vf_divide_zvp($pl)
-# Subcontractor of vf_form_ex. Divides $pl into ZVP0 part
-# $plv and ZPL part $plt and returns ($plv, $plt).
-sub vf_divide_zvp
-{
- my ($pl) = @_; my ($t, $u, $k, $pe, $pe2, @v);
- my ($tyd1, $zcat, $rpe, $cspc, @cit, @cist, $glkrn);
- my (@plv, @plt, @tydsc, @stydsc, %char, %type, %stype);
- # First I classify each enry in $pl into @plv (ZVP0 part)
- # and @plt (ZPL part) and extract necessary information
- # to @cit, @tydsc, etc.
- # $cspc is charlist describing codespace
- # $cit[$t] is charlist of type $t
- # $cist[$t][$u] is charlist of subtype $t $u
- # $tydsc[$t] is 'description' of type $t
- # $stydsc[$t][$u] is 'description' of subtype $t $u
- # $char{$cc} is 'description' of char $cc
- # Here 'description' is the pair of CHARWD and MAP.
- # Currenetly CHARWD specified for subtypes and characters
- # are ignored (values set for corresponding types are
- # used), thus CHARWD entry of descriptions of subtypes
- # and chars are unused.
- foreach $pe (@$pl) {
- (defined($zcat = $vf_zvp_category{$pe->[0]})) or next;
- if ($zcat & 2) { push(@plv, $pe); }
- if ($zcat & 1) { push(@plt, $pe); }
- if ($zcat == 0) {
- if ($pe->[0] eq 'GLUEKERN') {
- $glkrn = $pe;
- } elsif ($pe->[0] eq 'CODESPACE') {
- if ($#$pe == 1 && !ref $pe->[1]
- && $pe->[1] =~ m/^[\w\-]{6,}$/) {
- $t = uc($pe->[1]);
- (defined($cspc = jfm_charlist($t)))
- or return error("unknown charlist name '$t'");
- } else {
- $cspc = jfm_grab_charlist($pe, 1);
- }
- } elsif ($pe->[0] eq 'CHARSINTYPE') {
- (defined($t = pl_value($pe ,1))) or return;
- (0 < $t && $t < 256)
- or return error("CIT with invalid type number ($t)");
- $cit[$t] = jfm_grab_charlist($pe, 3);
- } elsif ($pe->[0] eq 'CHARSINSUBTYPE') {
- (defined($t = pl_value($pe, 1))) or return;
- (0 <= $t && $t < 256)
- or return error("CIST with invalid type number ($t)");
- (defined($u = pl_value($pe, 3))) or return;
- (0 < $u && $u < 0x10000)
- or return error("CIST with invalid subtype number ($u)");
- $cist[$t][$u] = jfm_grab_charlist($pe, 5);
- } elsif ($pe->[0] eq 'TYPE') {
- (defined($t = pl_value($pe, 1))) or return;
- (0 <= $t && $t < 256)
- or return error("TYPE with invalid type number ($t)");
- $tyd1 = $tydsc[$t] = [ ];
- for ($k = 3; $k <= $#$pe; $k++) {
- $pe2 = $pe->[$k];
- if (defined($u = $vf_zvp_category_char{$pe2->[0]})) {
- $tyd1->[$u] = $pe2;
- } elsif ($pe2->[0] eq 'MAP') { $tyd1->[1] = $pe2; }
- }
- } elsif ($pe->[0] eq 'SUBTYPE') {
- (defined($t = pl_value($pe, 1))) or return;
- (0 <= $t && $t < 256)
- or return error("SUBTYPE with invalid type number ($t)");
- (defined($u = pl_value($pe, 3))) or return;
- (0 < $u && $u < 0x10000)
- or return error("SUBTYPE with invalid subtype number ($u)");
- $tyd1 = $stydsc[$t][$u] = [ ];
- for ($k = 5; $k <= $#$pe; $k++) {
- $pe2 = $pe->[$k];
- if (defined($u = $vf_zvp_category_char{$pe2->[0]})) {
- $tyd1->[$u] = $pe2;
- } elsif ($pe2->[0] eq 'MAP') { $tyd1->[1] = $pe2; }
- }
- } elsif ($pe->[0] eq 'CHARACTER') {
- (defined($t = pl_value($pe ,1))) or return;
- (0 <= $t && $t <= 0xFFFFFF)
- or return error("char code out of range ($t)");
- $tyd1 = $char{$t} = [ ];
- for ($k = 3; $k <= $#$pe; $k++) {
- $pe2 = $pe->[$k];
- # only MAP is significant
- if ($pe2->[0] eq 'MAP') { $tyd1->[1] = $pe2; }
- # tyd1->[0] is currently unused
- }
- }
- }
- }
- # default codespace is GL94DB
- (defined $cspc) or $cspc = jfm_charlist('GL94DB');
- # Next I check consistency about existence of entries
- # (e.g. CIT 4 should exist iff TYPE 4 exists).
- ($#cist >= 0 && $#cit < 0) and $#cit = 0;
- (defined $tydsc[0])
- or return error("no TYPE for type 0");
- (vf_check_match("TYPE", \@tydsc, "CIT", \@cit, 1, "type"))
- or return;
- foreach (0 .. $#tydsc) {
- (vf_check_match("SUBTYPE", $stydsc[$_], "CIST", $cist[$_],
- 1, "subtype $_")) or return;
- }
- # Next I recompile JFM properties for support of subtypes with different
- # CHARWD values; then I output the resulted GLUEKERN, CHARSIN... lists,
- # and TYPE lists.
- vf_recompile_gluekern($glkrn, \@cit, \@cist, \@tydsc, \@stydsc);
- if (defined $glkrn) { push(@plt, $glkrn); }
- foreach $t (0 .. $#cit) {
- (defined $cit[$t]) or next;
- local $jfm_forced_prefix = 'X';
- push(@plt, jfm_form_cit($t, $cit[$t]));
- }
- @v = sort { $a <=> $b } (values %vf_zvp_category_char);
- foreach $t (0 .. $#tydsc) {
- (defined($tyd1 = $tydsc[$t])) or next;
- $rpe = pl_cook(['TYPE', 'D', 0]); pl_set_value($rpe, 1, $t);
- push(@$rpe, grep { defined $_ } (@{$tyd1}[@v]));
- push(@plt, $rpe); #qq
- }
- # Next I make hash %type from charcode to type and %stype
- # from charcode to subtype, converting from $cspc, @cit,
- # and @cist. The key set of %type is equal to codespace.
- # $type{$cc} is type of char $cc (can be 0)
- # $stype{$cc} is subtype of char $cc (cannot be 0)
- (vf_assign_type($cspc, \%type, \%stype, 0)) or return;
- foreach $t (1 .. $#cit) {
- (vf_assign_type($cit[$t], \%type, \%stype, $t)) or return;
- }
- foreach $t (0 .. $#cit) {
- foreach $u (1 .. $#{$cist[$t]}) {
- (vf_assign_type($cist[$t][$u], \%type, \%stype, $t, $u))
- or return;
- }
- }
- # Last I generate the char packet part of ZVP0, using
- # information gathered so far.
- $t = vf_generate_char_packet(\@tydsc, \@stydsc,
- \%char, \%type, \%stype);
- push(@plv, @$t);
-#print(pl_form(\@plv), ('-') x 60, "\n", pl_form(\@plt));exit;
- return (\@plv, \@plt);
-}
-
-## vf_generate_char_packet(...)
-# Subcontractor of vf_divide_zvp. Generates the char packet
-# part of ZVP0.
-sub vf_generate_char_packet
-{
- my ($tydsc, $stydsc, $char, $type, $stype) = @_;
- my ($t, $pe, $ty, $cc, @ccs, @pl);
- @ccs = sort { $a <=> $b } (keys %$type);
- foreach $cc (@ccs) {
- $pe = pl_cook(['CHARACTER', 'C', 0]);
- pl_set_value($pe, 1, $cc);
- $ty = $type->{$cc};
- push(@$pe, $tydsc->[$ty][0]); # CHARWD entry
- # add MAP entry
- if (defined($t = $char->{$cc})) {
- push(@$pe, $t->[1]);
- } elsif (defined($t = $stype->{$cc})) {
- push(@$pe, $stydsc->[$ty][$t][1]);
- } else {
- push(@$pe, $tydsc->[$ty][1]);
- }
- push(@pl, $pe);
- }
- return \@pl;
-}
-
-sub vf_recompile_gluekern
-{
- my ($glkrn, $cit, $cist, $tydsc, $stydsc) = @_;
- my ($t, $u, $tyd0, $tyd, $ty, $nty, $sty, $nsty);
- my (@tyrel, @tygrp, $orgnty, @glkrn1);
- $orgnty = $#$tydsc;
- # type migration
- for ($ty = 0; $ty <= $#$tydsc; $ty++) {
- (defined $tydsc->[$ty]) or next;
- undef $nty; $tyd0 = $tydsc->[$ty];
- foreach $sty (1 .. $#{$stydsc->[$ty]}) {
- (defined $stydsc->[$ty][$sty]) or next;
- $tyd = $stydsc->[$ty][$sty];
- (defined $tyd->[1]) or $tyd->[1] = pl_clone($tyd0->[1]);
- if (vf_resolve_metric($tyd0, $tyd)) { next; }
- if (defined $nty) {
- $nsty = ($#{$stydsc->[$nty]} + 1 || 1);
- $stydsc->[$nty][$nsty] = $stydsc->[$ty][$sty];
-#print("move $ty/$sty to $nty/$nsty\n");
-#print("CIT/$nty ", dumpp($cit->[$nty]), " -> ");
- vf_clist_add($cit->[$nty], $cist->[$ty][$sty]);
- $cist->[$nty][$nsty] = $cist->[$ty][$sty];
-#print(dumpp($cit->[$nty]), "\n");
- } else {
- $nty = $#$tydsc + 1; $tyrel[$ty] = $nty;
- $tydsc->[$nty] = $stydsc->[$ty][$sty];
-#print("move $ty/$sty to $nty\n");
- $cit->[$nty] = $cist->[$ty][$sty];
- }
-#print("CIT/$ty ", dumpp($cit->[$ty]), " -> ");
- vf_clist_remove($cit->[$ty], $cist->[$ty][$sty]);
-#print(dumpp($cit->[$ty]), "\n");
- undef $stydsc->[$ty][$sty]; undef $cist->[$ty][$sty];
- }
- }
- # compile @tygrp from @tyrel
- foreach $ty (0 .. $orgnty) {
- $tygrp[$ty] = $u = [$ty]; $t = $ty;
- while (defined $tyrel[$t]) { $t = $tyrel[$t]; push(@$u, $t); }
- }
- # create new GLUEKERN list
- foreach $u (@$glkrn) {
- if (ref $u &&
- ($u->[0] eq 'KRN' || $u->[0] eq 'GLUE' || $u->[0] eq 'LABEL')) {
- foreach $ty (@{$tygrp[pl_value($u, 1)]}) {
- $t = pl_sclone($u); pl_set_value($t, 1, $ty);
- push(@glkrn1, $t);
- }
- } else { push(@glkrn1, $u); }
- }
- @$glkrn = @glkrn1;
-}
-## vf_clise_remove(...)
-# Subcontractor of vf_recompile_gluekern.
-sub vf_clist_remove {
- my ($lst1, $lst2) = @_; my (%hs);
- vf_clist_check(\%hs, $lst1, 1); vf_clist_check(\%hs, $lst2);
- @$lst1 = sort { $a <=> $b } (keys %hs);
-}
-
-## vf_clise_add(...)
-# Subcontractor of vf_recompile_gluekern.
-sub vf_clist_add {
- my ($lst1, $lst2) = @_; my (%hs);
- vf_clist_check(\%hs, $lst1, 1); vf_clist_check(\%hs, $lst2, 1);
- @$lst1 = sort { $a <=> $b } (keys %hs);
-}
-
-## vf_clist_check(...)
-# Subcontractor of vf_recompile_gluekern.
-sub vf_clist_check {
- my ($hs, $clst, $val) = @_; my ($e, $sc, $ec);
- foreach $e (@$clst) {
- ($sc, $ec) = (ref $e) ? @$e : ($e, $e);
- foreach ($sc .. $ec) {
- if (defined $val) { $hs->{$_} = $val; } else { delete $hs->{$_}; }
- }
- }
-}
-
-## vf_resolve_metric(...)
-# Subcontractor of vf_recompile_gluekern.
-sub vf_resolve_metric {
- my ($tyd1, $tyd2) = @_; my ($wd1, $nam, $idx, $same);
- $same = 1;
- foreach $nam (keys %vf_zvp_category_char) {
- $idx = $vf_zvp_category_char{$nam};
- $wd1 = (defined $tyd1->[$idx]) ? pl_value($tyd1->[$idx], 1) : 0;
- if (defined $tyd2->[$idx]) {
- if ($wd1 != pl_value($tyd2->[$idx], 1)) { undef $same; }
- } else {
- $tyd2->[$idx] = pl_cook([$nam, 'R', 0]);
- pl_set_value($tyd2->[$idx], 1, $wd1);
- }
- }
- return $same;
-}
-
-## vf_assign_type($cl, $type, $stype, $ty, $sty)
-# Subcontractor of vf_divide_zvp. If $sty is defined, it maps
-# chars in $cl to $sty in hash $stype->[$ty]; otherwise it maps
-# chars in$cl to $ty in hash $type.
-sub vf_assign_type
-{
- my ($cl, $type, $stype, $ty, $sty) = @_;
- my ($t, $c, $s, $e);
- foreach $c (@$cl) {
- ($s, $e) = (ref $c) ? @$c : ($c, $c);
- foreach ($s .. $e) {
- if (defined $sty) { # set subtype
- ($type->{$_} == $ty) or return error(
- sprintf("inconsistent subtype assignment to char %04X" .
- " (subtype %s %s vs type %s)",
- $_, $ty, $sty, $type->{$_}));
- (!defined $stype->{$_}) or return error(
- sprintf("subtype reassignment to char %04X" .
- " (subtype %s vs %s)",
- $_, $sty, $stype->{$_}));
- $stype->{$_} = $sty;
- } elsif ($ty != 0) { # set type >0
- (defined $type->{$_}) or return error(
- sprintf("type assignment (%s) to char out of codespace:" .
- "char %04X",
- $ty, $_));
- ($type->{$_} == 0) or return error(
- sprintf("type reassignment to char %04X" .
- " (type %s vs %s)",
- $_, $ty, $type->{$_}));
- $type->{$_} = $ty;
- } else { # set type 0
- $type->{$_} = $ty;
- }
- }
- }
- return 1;
-}
-
-## vf_check_match($lbla, $lsta, $lblb, $lstb, $pos, $srt)
-# Subcontractor of vf_divide_zvp.
-sub vf_check_match
-{
- my ($lbla, $lsta, $lblb, $lstb, $pos, $srt) = @_; my ($mpos);
- $mpos = ($#$lsta > $#$lstb) ? $#$lsta : $#$lstb;
- foreach ($pos .. $mpos) {
- if (defined $lsta->[$_] && !defined $lstb->[$_]) {
- return error("$lbla entry without matching $lblb ($srt $_)");
- } elsif (defined $lstb->[$_] && !defined $lsta->[$_]) {
- return error("$lblb entry without matching $lbla ($srt $_)");
- }
- }
- return 1;
-}
-
-
-##<*> vf_parse_ex($vf, $jfm)
-sub vf_parse_ex
-{
- my ($vf, $jfm) = @_; my ($plv, $plt, $cit, $typ);
- my ($pl, $tydsc, $chdsc, $cspc, $cist, $stydsc, $chdsc);
- $plv = vf_parse($vf) or return;
- ($plt, $cit, $typ) = jfm_half_parse($jfm) or return;
- ($pl, $tydsc, $chdsc) = vf_restructure($plv, $plt) or return;
- ($cspc, $cist, $stydsc, $chdsc) =
- vf_analyze_dimap($chdsc, $tydsc, $typ, $cit) or return;
- $pl = vf_compose_zvp($pl, $cspc, $cist, $stydsc, $chdsc);
- return $pl;
-}
-
-sub vf_restructure
-{
- my ($plv, $plt) = @_; my ($t, $u, $pe, $zcat, %chk);
- my (@pl, @tydsc, %chdsc);
- # ZPL
- foreach $pe (@$plt) {
- $zcat = $vf_zvp_category{$pe->[0]};
- if ($zcat == 1) {
- push(@pl, $pe);
- } elsif ($zcat == 3) {
- push(@pl, $pe); $chk{$pe->[0]} = pl_value($pe, 1);
- } elsif ($zcat == 0) {
- if ($pe->[0] eq 'CHARSINTYPE' || $pe->[0] eq 'GLUEKERN') {
- push(@pl, $pe);
- } elsif ($pe->[0] eq 'TYPE') {
- push(@pl, $pe); $t = pl_value($pe, 1);
- $u = pl_cook(['MAP']); push(@$pe, $u);
- $tydsc[$t] = [$pe->[3], $u];
- }
- } elsif (!defined $zcat) {
- return fatal("vf_restructure");
- }
- }
- # ZVP0
- foreach $pe (@$plv) {
- $zcat = $vf_zvp_category{$pe->[0]};
- if ($zcat == 2) {
- push(@pl, $pe);
- } elsif ($zcat == 3 && $vf_strict) {
- $t = pl_value($pe, 1); $u = $chk{$pe->[0]};
- ($t == $u ||
- ($pe->[0] eq 'CHECKSUM' && ($t == 0 || $u == 0)))
- or return error("inconsistent value: ", $pe->[0]);
- } elsif ($zcat == 0) {
- if ($pe->[0] eq 'CHARACTER') {
- $t = pl_value($pe, 1);
- $chdsc{$t} = [$pe->[3], $pe->[4]];
- }
- } elsif (!defined $zcat) {
- return fatal("vf_restructure");
- }
- }
- return (\@pl, \@tydsc, \%chdsc);
-}
-
-## vf_analyze_dimap
-sub vf_analyze_dimap
-{
- my ($chdsc, $tydsc, $typ, $citpe) = @_;
- my ($t, $u, $k, $cc, @ccs, $pe, @fs, $ty, $chd, @dmaps, %cnt);
- my ($cspc, @cit, @cist, @stydsc, %chdsc2);
- #@dmaps = ({}) x scalar(@$tydsc);
- # coderange consistency
- @fs = sort { $a <=> $b } (keys %$typ);
- foreach $cc (@fs) {
- (defined $chdsc->{$cc}) and next;
- if ($vf_strict) {
- return error(sprintf("charpacket missing in VF: code %04X", $cc));
- }
- delete $typ->{$cc};
- }
- #
- @ccs = sort { $a <=> $b } (keys %$chdsc);
- foreach $cc (@ccs) {
- $ty = $typ->{$cc}; $chd = $chdsc->{$cc};
- push(@{$cit[$ty]}, $cc);
- if ($vf_strict) {
- (pl_value($tydsc->[$ty][0], 1) == pl_value($chd->[0], 1))
- or return error(
- sprintf("CHARWD value mismatch: code %04X", $cc));
- }
- $pe = vf_contract_selfcode($chd->[1], $cc);
- $t = pl_form_list($pe, -1);
- push(@{$dmaps[$ty]{$t}}, $cc);
- }
- #
- if (defined($t = jfm_charlist_name(\@ccs))) {
- $cspc = [ $t ];
- } else { $cspc = jfm_form_charlist(\@ccs); }
- foreach $ty (0 .. $#dmaps) {
- (defined($u = $dmaps[$ty])) or next;
- foreach (keys %$u) { $cnt{$_} = scalar(@{$u->{$_}}); }
- @fs = sort {
- $cnt{$b} <=> $cnt{$a} || $u->{$a}[0] <=> $u->{$b}[0]
- } (keys %$u);
- foreach $k (0 .. $#fs) {
- $u = $dmaps[$ty]{$fs[$k]};
- if ($k == 0 || ($cnt{$fs[$k]} > 1 && $k < 256)) {
- $cist[$ty][$k] = jfm_form_charlist($u);
- $stydsc[$ty][$k][1] =
- vf_contract_selfcode($chdsc->{$u->[0]}[1], $u->[0]);
- } else {
- foreach (@$u) {
- $chdsc2{$_}[1] = $chdsc->{$_}[1];
- }
- }
- }
- @{$tydsc->[$ty][1]} = @{$stydsc[$ty][0][1]};
- undef $cist[$ty][0]; undef $stydsc[$ty][0];
- if ($ty > 0) {
- $t = jfm_form_charlist($cit[$ty]);
- push(@{$citpe->[$ty]}, @$t);
- }
- }
- return ($cspc, \@cist, \@stydsc, \%chdsc2);
-}
-
-sub vf_compose_zvp
-{
- my ($pl, $cspc, $cist, $stydsc, $chdsc) = @_;
- my ($t, $u, $ty, $sty, $cc, $pe);
- $pe = pl_cook(['CODESPACE']); push(@$pl, $pe);
- push(@$pe, @$cspc);
- foreach $ty (0 .. $#$stydsc) {
- foreach $sty (0 .. $#{$stydsc->[$ty]}) {
- if (defined($t = $cist->[$ty][$sty])) {
- $pe = pl_cook(['CHARSINSUBTYPE', 'D', 0, 'D', 0]);
- pl_set_value($pe, 1, $ty); pl_set_value($pe, 3, $sty);
- push(@$pe, @$t); push(@$pl, $pe);
- }
- if (defined($t = $stydsc->[$ty][$sty])) {
- $pe = pl_cook(['SUBTYPE', 'D', 0, 'D', 0]);
- pl_set_value($pe, 1, $ty); pl_set_value($pe, 3, $sty);
- push(@$pe, $t->[1]); push(@$pl, $pe);
- }
- }
- }
- foreach $cc (keys %$chdsc) {
- $pe = pl_cook(['CHARACTER', 'C', 0]);
- pl_set_value($pe, 1, $cc);
- push(@$pe, $chdsc->{$cc}[1]); push(@$pl, $pe);
- }
- pl_rearrange($pl);
- return $pl;
-}
-
-## vf_contract_selfcode
-sub vf_contract_selfcode
-{
- my ($pl, $cc) = @_; my ($k, $pe, $pl2);
- $pl2 = pl_sclone($pl);
- foreach $k (1 .. $#$pl2) {
- $pe = $pl2->[$k];
- if ($pe->[0] eq 'SETCHAR' &&
- $#$pe > 0 && pl_value($pe, 1) == $cc) {
- $pl2->[$k] = pl_cook(['SETCHAR']);
- }
- }
- return $pl2;
-}
-
-##<*> vf_expand_named_charlist
-#
-sub vf_expand_named_charlist {
- my ($pl) = @_; my ($t);
- ($pl->[0] eq 'CODESPACE') or return;
- (defined($t = jfm_charlist($pl->[1]))) or return;
- $t = jfm_form_charlist($t, 0);
- splice(@$pl, 1, 1, @$t);
-}
-
-
-######## 'jfm' section ########
-
-# jfm_form (ZPL -> JFM)
-# Jx --[jc(x)=Ic(i)]-> i (!uptex?)--> Ji --[ppltotf]--> (JFM)
-# Ux --[uc(x)=Ic(i)]-> (uptex?)---> Ui --[uppltotf]->
-# Xx --[x=i]--------->
-# K $ --[Ee($)=Ic(i)]->
-# jfm_parse (JFM -> ZPL)
-# (JFM) (!uptex?)--[ptftopl]-> $ --[je($)=Ic(x)]-> Jx/Ux/Xx
-# (uptex?)--[uptftopl]-> $ --[ue($)=Ic(x)]->
-
-# for jfm_injcode
-my %jfm_pfx_ijc = ( J => KI_JIS, U => KI_UNI, X => undef );
-my %jfm_ijc_pfx = ( reverse %jfm_pfx_ijc );
-
-##<*> jfm_use_uptex_tool($sw)
-# Decides if upTeX tools are used to do jfm_parse. Here truth
-# value of $sw means upTeX-pltotf should/shouldn't be used.
-our $jfm_use_uptex_tool = 0;
-sub jfm_use_uptex_tool
-{
- my ($sw) = @_; my ($t);
- $t = ($cmd_name{uptftopl} eq '' || $cmd_name{uppltotf} eq '');
- if ($sw && $t) { return error("upTeX tools disabled"); }
- $jfm_use_uptex_tool = $sw;
- return 1;
-}
-
-##<*> jfm_parse($jfm)
-# Converts JFM data $jfm to a pl-struct describing ZPL.
-sub jfm_parse
-{
- my ($jfm) = @_; my ($pl, $cit, $typ);
- ($pl, $cit, $typ) = jfm_half_parse($jfm) or return;
- return jfm_record_cit($pl, $cit, $typ);
-}
-
-## jfm_half_parse($jfm)
-# Converts JFM data $jfm to a 'half-parsed' form.
-sub jfm_half_parse
-{
- my ($jfm) = @_; my ($cmd, $pl, $map, $cit, $typ);
- if ($jfm_use_uptex_tool) {
- $pl = x_uptftopl($jfm) or return;
- jfm_interprocess($pl) or return;
- return jfm_grab_cit($pl, 'utf8', 'unicode');
- } else {
- $cmd = $cmd_name{tftopl} . ' -kanji=jis';
- (($jfm, $map) = jfm_parse_preprocess($jfm)) or return;
- $pl = x_tftopl($jfm, $cmd) or return;
- jfm_interprocess($pl) or return;
- return jfm_parse_postprocess($pl, $map);
- }
-}
-
-##<*> jfm_form($pl)
-# Converts a pl-struct $pl describing a JPLZ to JFM data.
-sub jfm_form
-{
- my ($pl) = @_; my ($cmd, $map, $jfm);
- if ($jfm_use_uptex_tool) {
- local $jfm_forced_prefix = 'U';
- (defined($pl = jfm_normalize($pl))) or return;
- return x_pltotf($pl, $cmd_name{uppltotf});
- } else {
- $cmd = $cmd_name{pltotf} . ' -kanji=jis';
- ((($pl, $map) = jfm_form_preprocess($pl))) or return;
- $jfm = x_pltotf($pl, $cmd) or return;
- return jfm_form_postprocess($jfm, $map);
- }
-}
-
-## jfm_grab_cit($pl)
-sub jfm_grab_cit
-{
- my ($pl, $xjc, $ijc) = @_; my ($t, $cl, $ty, $pe);
- my (@pl2, %typ, @cit, @ccs);
- local ($jcode_ex) =
- (defined $xjc) ? $jcode_ex_sym{$xjc} : $jcode_ex;
- local ($jcode_in) =
- (defined $ijc) ? $jcode_in_sym{$ijc} : $jcode_in;
- foreach $pe (@$pl) {
- if ($pe->[0] eq 'CHARSINTYPE') {
- pl_cook_list($pe);
- (defined($ty = pl_value($pe, 1))) or return;
- $cl = jfm_grab_charlist($pe, 3) or return;
- foreach $t (@$cl) {
- if (ref $t) {
- foreach ($t->[0] .. $t->[1]) { $typ{$_} = $ty; }
- } else { $typ{$t} = $ty; }
- }
- $cit[$ty] = $t = pl_cook(['CHARSINTYPE', 'D', 0]);
- pl_set_value($t, 1, $ty); push(@pl2, $t);
- } else { push(@pl2, $pe); }
- }
- return (\@pl2, \@cit, \%typ);
-}
-
-## jfm_normalize($pl, $xjc, $ijc)
-# Normalizes pl-struct $pl, i.e., converts ZPL to ordinary PL.
-# Here $xjc and $ijc mean source and internal kanji codes that
-# are effective in this process (unchanged if undef).
-sub jfm_normalize
-{
- my ($pl, $xjc, $ijc) = @_; my ($citpe, $typ);
- (($pl, $citpe, $typ) = jfm_grab_cit($pl, $xjc, $ijc)) or return;
- (defined($pl = jfm_record_cit($pl, $citpe, $typ))) or return;
- return $pl;
-}
-
-## jfm_record_cit($pl, $citpe, $typ)
-# Assembles a half-parsed form to get a complete ZPL.
-sub jfm_record_cit
-{
- my ($pl, $citpe, $typ) = @_; my ($t, $u, $cc, @ccs, @cit);
- @ccs = sort { $a <=> $b } (keys %$typ);
- foreach $cc (@ccs) {
- push(@{$cit[$typ->{$cc}]}, $cc);
- }
- foreach $t (1 .. $#cit) {
- (defined $cit[$t]) or next;
- $u = jfm_form_charlist($cit[$t]);
- push(@{$citpe->[$t]}, @$u);
- }
- return $pl;
-}
-
-## jfm_form_preprocess
-# Subcontactor of jfm_form.
-sub jfm_form_preprocess
-{
- my ($pl) = @_; my ($pl2, $cit, $typ, $jc, $cc, @ccs, %map);
- ((($pl2, $cit, $typ) = jfm_grab_cit($pl))) or return;
- @ccs = sort { $a <=> $b } (keys %$typ);
- $jc = 0x2121;
- foreach $cc (@ccs) {
- push(@{$cit->[$typ->{$cc}]}, sprintf("J%04X", $jc));
- $map{$jc} = $cc; $jc = jfm_nextcode($jc) or return;
- }
- return ($pl2, \%map);
-}
- # Valid codespace in pltotf: [21-28|30-74][21-7F] (7238 chars)
-
-## jfm_form_postprocess
-# Subcontactor of jfm_form.
-sub jfm_form_postprocess
-{
- my ($jfm, $map) = @_; my ($k, $pct, $lct, $ct, @fs);
- @fs = unpack('nnnn', $jfm);
- ($#fs == 3 && $fs[2] * 4 == length($jfm) &&
- ($fs[0] == 9 || $fs[0] == 11)) or return;
- $pct = $fs[3] * 4 + 28; $lct = $fs[1] * 4;
- $ct = substr($jfm, $pct, $lct); @fs = unpack('n*', $ct);
- for ($k = 2; $k <= $#fs; $k += 2) {
- my $cc = $map->{$fs[$k]};
- $fs[$k] = ($cc & 0xFFFF); $fs[$k+1] |= ($cc >> 16 << 8);
- }
- $ct = pack('n*', @fs);
- return substr($jfm, 0, $pct) . $ct . substr($jfm, $pct + $lct);
-}
-
-## jfm_parse_preprocess
-# Subcontactor of jfm_half_parse.
-sub jfm_parse_preprocess
-{
- my ($jfm) = @_; my ($k, $pct, $lct, $ct, @fs, $jc, %map);
- @fs = unpack('nnnn', $jfm);
- ($#fs == 3 && $fs[2] * 4 == length($jfm) &&
- ($fs[0] == 9 || $fs[0] == 11)) or return;
- $pct = $fs[3] * 4 + 28; $lct = $fs[1] * 4;
- $ct = substr($jfm, $pct, $lct); @fs = unpack('n*', $ct);
- for ($jc = 0x2121, $k = 2; $k <= $#fs; $k += 2) {
- $map{$jc} = ($fs[$k] | $fs[$k+1] >> 8 << 16);
- $fs[$k] = $jc; $fs[$k+1] &= 0xFF;
- $jc = jfm_nextcode($jc) or return;
- }
- $ct = pack('n*', @fs);
- $jfm = substr($jfm, 0, $pct) . $ct . substr($jfm, $pct + $lct);
- return ($jfm, \%map);
-}
-
-## jfm_parse_postprocess
-# Subcontactor of jfm_half_parse.
-sub jfm_parse_postprocess
-{
- my ($pl, $map, $pfx) = @_; my ($cit, $typ, %typ2, $cc);
- ($pl, $cit, $typ) = jfm_grab_cit($pl, 'xjis', 'xjis') or return;
- foreach $cc (keys %$typ) {
- $typ2{$map->{$cc}} = $typ->{$cc};
- }
- return ($pl, $cit, \%typ2);
-}
-
-## jfm_nextcode($jc)
-# Subcontactor of jfm_form_preprocess and jfm_parse_preprocess.
-sub jfm_nextcode
-{
- my ($jc) = @_;
- if ((++$jc & 0xFF) < 0x7F) { return $jc; }
- if ($jc == 0x747F) {
- return error("too many chars have non-zero type");
- } elsif ($jc == 0x287F) { $jc = 0x3021; }
- else { $jc += 162; }
- return $jc;
-}
-
-## jfm_injcode($f, $xc)
-# Subcontactor of jfm_form_preprocess.
-sub jfm_injcode
-{
- my ($pfx, $xc) = @_; local ($jcode_ex);
- # Note: here encodings meant for 'internal' use are
- # used as 'external' excoding.
- (defined($jcode_ex = $jfm_pfx_ijc{$pfx})) or return;
- if ($jcode_ex eq $jcode_in) { return $xc; }
- return jcode_ord(chr($xc >> 8) . chr($xc & 0xff));
-}
-
-
-## jfm_interprocess($pl)
-sub jfm_interprocess
-{
- my ($pl) = @_; my ($pe, $pe2, $ok);
- foreach $pe (@$pl) {
- if ($pe->[0] eq 'TYPE') {
- $ok = 1; pl_set_numtype($pe, 1, 'D') or return;
- } elsif ($pe->[0] eq 'CHARSINTYPE') {
- $ok = 1; pl_set_numtype($pe, 1, 'D') or return;
- } elsif ($pe->[0] eq 'GLUEKERN') {
- foreach $pe2 (@$pe) {
- (ref $pe2) or next;
- ($pe2->[0] eq 'LABEL' ||
- $pe2->[0] eq 'GLUE' || $pe2->[0] eq 'KRN') or next;
- pl_set_numtype($pe2, 1, 'D') or return;
- }
- }
- }
- ($ok) or return error("input TFM is not JFM");
- return 1;
-}
-
-##-------- Procedures on charlist
-
-# A charlist is an array, each entry of which is either a code
-# value or a array-ref consisting of two values, which means
-# a code range. For example,
-# [ 0x50, [ 0x100, 0x1FF ], 0x234 ]
-# is a charlist consisting of 258 code values.
-
-our %jfm_charlist_registry = (
- 'UNICODE-BMP' => [ [0x0000, 0xFFFF] ],
- 'GL94DB' => [ map { [ ($_ << 8) | 0x21, ($_ << 8) | 0x7E ] }
- (0x21 .. 0x7E) ],
-);
-
-##<*> jfm_use_charlist_name()
-our $jfm_use_charlist_name = 1;
-sub jfm_use_charlist_name { $jfm_use_charlist_name = $_[0]; }
-
-## jfm_charlist($name)
-sub jfm_charlist
-{
- return $jfm_charlist_registry{$_[0]};
-}
-
-## jfm_charlist_name($cl)
-sub jfm_charlist_name
-{
- my ($cl) = @_;
- my ($k, $f1, $f2, $l1, $l2, $cl2, $nam, @nams, $res);
- (@$cl && $jfm_use_charlist_name) or return;
- $f1 = (ref $cl->[0]) ? $cl->[0][0] : $cl->[0];
- @nams = sort { $a cmp $b } (keys %jfm_charlist_registry);
- L1:foreach $nam (@nams) {
- $cl2 = $jfm_charlist_registry{$nam};
- $f2 = (ref $cl2->[0]) ? $cl2->[0][0] : $cl2->[0];
- ($f1 == $f2) or next;
- if (!defined $l1) { $l1 = jfm_length_charlist($cl); }
- $l2 = jfm_length_charlist($cl2);
- ($l1 == $l2) or next;
- $cl = jfm_rangify_charlist($cl);
- ($#$cl == $#$cl2) or next;
- foreach $k (0 .. $#$cl) {
- if (ref $cl->[$k] && ref $cl2->[$k]) {
- ($cl->[$k][0] == $cl2->[$k][0] &&
- $cl->[$k][1] == $cl2->[$k][1]) or next L1;
- } elsif (!ref $cl->[$k] && !ref $cl2->[$k]) {
- ($cl->[$k] == $cl2->[$k]) or next L1;
- } else { next L1; }
- }
- $res = $nam; last L1;
- }
- return $res;
-}
-
-sub jfm_length_charlist
-{
- my ($cl) = @_; my ($s);
- $s = 0;
- foreach (@$cl) {
- if (ref $_) { $s += $_->[1] - $_->[0] + 1; }
- else { $s += 1; }
- }
- return $s;
-}
-
-## for jfm_rangify_charlist()
-our $jfm_rangify_threshold = 8;
-
-## jfm_rangify_charlist($cl)
-sub jfm_rangify_charlist
-{
- my ($cl) = @_; my ($cc, $scc, $ecc,@cl2);
- foreach $cc (@$cl, []) {
- if (defined $scc && !ref $cc && $cc == $ecc + 1) {
- $ecc = $cc;
- } else {
- if (!defined $scc) { # do nothing
- } elsif ($ecc - $scc < $jfm_rangify_threshold) {
- push(@cl2, $scc .. $ecc);
- } else {
- push(@cl2, [$scc, $ecc]);
- }
- if (ref $cc) {
- push(@cl2, $cc); $scc = $ecc = undef;
- } else {
- $scc = $ecc = $cc;
- }
- }
- }
- pop(@cl2);
- return \@cl2;
-}
-
-## jfm_form_cit($ty, $cl, $sym)
-sub jfm_form_cit
-{
- my ($ty, $cl) = @_; my ($t, $pe);
- $pe = pl_cook(['CHARSINTYPE', 'D', 0]);
- pl_set_value($pe, 1, $ty);
- $t = jfm_form_charlist($cl, 0); push(@$pe, @$t);
- return $pe;
-}
-
-## jfm_form_charlist($cl, $swrng)
-sub jfm_form_charlist
-{
- my ($cl, $swrng) = @_; my ($cc, $pe, @cl2, $nf, $pfx);
- $pfx = $jfm_ijc_pfx{$jcode_in};
- $nf = ($pl_prefer_hex) ? 'H' : 'O';
- if (defined $jfm_forced_prefix) { $pfx = $jfm_forced_prefix; }
- (defined $swrng)
- or $swrng = (!defined $jcode_in && !defined $jfm_forced_prefix);
- if ($swrng) { $cl = jfm_rangify_charlist($cl); }
- foreach $cc (@$cl) {
- if (ref $cc) {
- $pe = pl_cook(['CTRANGE', $nf, 0, $nf, 0]);
- pl_set_value($pe, 1, $cc->[0]);
- pl_set_value($pe, 3, $cc->[1]);
- push(@cl2, $pe);
- } else {
- push(@cl2, sprintf("%s%04X", $pfx, $cc));
- }
- }
- return \@cl2;
-}
-
-## jfm_grab_charlist($pe, $pos)
-sub jfm_grab_charlist
-{
- my ($pe, $pos) = @_; my ($k, $e, $t, $u, $cc, @cl);
- for ($k = $pos; $k <= $#$pe; $k++) {
- $e = $pe->[$k];
- if (ref $e && $e->[0] eq CNUM) {
- (defined($cc = pl_value($pe, $k))) or return;
- push(@cl, $cc); ++$k;
- } elsif ($e =~ m/^([JUX])([0-9A-Fa-f]{1,6})$/) {
- if (!defined $jcode_in || $1 eq 'X') {
- push(@cl, hex($2));
- } else {
- (defined($cc = jfm_injcode($1, hex($2)))) or return;
- push(@cl, $cc);
- }
- } elsif ($e =~ m/^[^\x21-\x7e]/) {
- (defined($cc = jcode_ord($e)))
- or return error("malformed $cc kanji character: ",
- unpack('H*', $e));
- push(@cl, $cc);
- } elsif (ref $e && $e->[0] eq 'CTRANGE') {
- (defined($t = pl_value($e, 1)) &&
- defined($u = pl_value($e, 3))) or return;
- push(@cl, [$t, $u]);
- } else {
- return error("illegal element in CHARSINTYPE: ", $e);
- }
- }
- return \@cl;
-}
-
-#================================================= END
-($jcode_in, $jcode_ex) = (undef, undef);
-get_temp_name_init();
-if (defined $errmsg) { error("initialization failed"); }
-
-#------------------------------------------------- dumb importer
-package main;
-{
- no strict;
- foreach (qw(
- textool_error textool_version
- read_whole_file write_whole_file
- pl_parse pl_form pl_prefer_hex pl_value
- jcode_set
- kpse
- vf_parse vf_form vf_parse_ex vf_form_ex vf_strict
- jfm_use_uptex_tool jfm_parse jfm_form
- )) {
- *{$_} = *{"ZRTeXtor::".$_};
- }
-}
-
-#------------------------------------------------- pxutil stuffs
-# Here follows excerpt from pxutil.pl
-#================================================= BEGIN
-use Encode qw(encode decode);
-my $prog_name = 'jfmutil';
-my $version = '1.3.1';
-my $mod_date = '2020/05/04';
-#use Data::Dump 'dump';
-#
-my ($sw_hex, $sw_uptool, $sw_noencout, $inenc, $exenc, $sw_lenient);
-my ($sw_compact);
-my ($proc_name, $infile, $in2file ,$outfile, $out2file);
-
-#### main procedure
-
-my %procs = (
- vf2zvp0 => \&main_vf2zvp0,
- zvp02vf => \&main_zvp02vf,
- vf2zvp => \&main_vf2zvp,
- zvp2vf => \&main_zvp2vf,
- tfm2zpl => \&main_tfm2zpl,
- zpl2tfm => \&main_zpl2tfm,
-);
-
-sub main {
- if (defined textool_error()) { error(); }
- local $_ = shift(@ARGV);
- if (!defined $_) {
- show_usage();
- } elsif (($proc_name) = m/^:?(\w+)$/) {
- my $proc = $procs{$proc_name};
- (defined $proc) or error("unknown subcommand name", $proc_name);
- $proc->();
- } elsif (m/^-/) {
- if (m/^--?h(?:elp)?$/) {
- show_usage();
- } elsif (m/^-(?:V|-version)$/) {
- show_version();
- } else { error("unknown (or invalid usage of) option", $_); }
- } else { error("invalid argument", $_); }
-}
-
-sub main_vf2zvp0 {
- my ($t);
- read_option();
- $t = read_whole_file(kpse($infile), 1) or error();
- $t = vf_parse($t) or error();
- $t = pl_form($t) or error();
- write_whole_file($outfile, $t) or error();
-}
-
-sub main_zvp02vf {
- my ($t);
- read_option();
- $t = read_whole_file(kpse($infile)) or error();
- $t = pl_parse($t) or error();
- ($sw_compact) and $t = do_compact_vf($t);
- $t = vf_form($t) or error();
- write_whole_file($outfile, $t, 1) or error();
-}
-
-sub main_zvp2vf {
- my ($t, $u);
- read_option();
- if ($sw_uptool) { jfm_use_uptex_tool(1); }
- $t = read_whole_file(kpse($infile)) or error();
- $t = pl_parse($t) or error();
- ($t, $u) = vf_form_ex($t) or error();
- write_whole_file($outfile, $t, 1) or error();
- write_whole_file($out2file, $u, 1) or error();
-}
-sub main_vf2zvp {
- my ($t, $vf, $tfm);
- read_option();
- if ($sw_uptool) { jfm_use_uptex_tool(1); }
- $vf = read_whole_file(kpse($infile), 1) or error();
- $tfm = read_whole_file(kpse($in2file), 1) or error();
- $t = vf_parse_ex($vf, $tfm) or error();
- $t = pl_form($t) or error();
- write_whole_file($outfile, $t) or error();
-}
-
-sub main_tfm2zpl {
- my ($t);
- read_option();
- if ($sw_uptool) { jfm_use_uptex_tool(1); }
- $t = read_whole_file(kpse($infile), 1) or error();
- $t = jfm_parse($t) or error();
- $t = pl_form($t) or error();
- write_whole_file($outfile, $t) or error();
-}
-
-sub main_zpl2tfm {
- my ($t);
- read_option();
- if ($sw_uptool) { jfm_use_uptex_tool(1); }
- $t = read_whole_file(kpse($infile)) or error();
- $t = pl_parse($t) or error();
- $t = jfm_form($t) or error();
- write_whole_file($outfile, $t, 1) or error();
-}
-
-sub is_simple_char {
- local ($_) = @_;
- ($#$_ == 4 &&
- $_->[0] eq 'CHARACTER' &&
- $_->[3][0] eq 'CHARWD' &&
- $_->[4][0] eq 'MAP'
- ) or return;
- my $cc = ::pl_value($_, 1);
- $_ = $_->[4];
- ($#$_ == 1 &&
- $_->[1][0] eq 'SETCHAR' &&
- ::pl_value($_->[1], 1) == $cc
- ) or return;
- return 1;
-}
-
-sub do_compact_vf {
- my ($t) = @_;
- $t = [ grep { !is_simple_char($_) } (@$t) ];
- return $t;
-}
-
-sub show_usage {
- print(usage_message());
- exit;
-}
-sub show_version {
- print("$prog_name version $version\n");
- exit;
-}
-sub usage_message {
- my ($v, $m);
- ($v, $m) = textool_version() or error();
- return <<"EOT1", <<"EOT2";
-This is $prog_name v$version <$mod_date> by 'ZR'.
-[ZRTeXtor library v$v <$m> by 'ZR']
-Usage: $prog_name vf2zvp0 [<options>] <in.vf> [<out.zvp0>]
- $prog_name zvp02vf [<options>] <in.zvp0> [<out.vf>]
- $prog_name vf2zvp [<options>] <in.vf> [<in.tfm> <out.zvp>]
- $prog_name zvp2vf [<options>] <in.zvp> [<out.vf> <out.tfm>]
- $prog_name zpl2tfm [<options>] <in.zvp0> [<out.vf>]
- $prog_name tfm2zpl [<options>] <in.zvp0> [<out.vf>]
-Arguments:
- <in.xxx> input files
- N.B. Input TFM/VF files are searched by Kpathsea. (ZVP/ZVP9 are not.)
- <out.xxx> output files
-Options:
- --hex output charcode in 'H' form [default]
- -o / --octal output charcode in 'O' form
- --uptool use upTeX tools (uppltotf etc.)
- --lenient ignore non-fatal error on VFs
- --compact output VF in compact form
- The following options affect interpretation of 'K' form.
- --kanji=ENC set source encoding: ENC=jis/sjis/euc/utf8/none
- --kanji-internal=ENC set internal encoding: ENC=jis/unicode/none
- -j / --jis == --kanji=jis --kanji-internal=jis
- -u / --unicode == --kanji=utf8 --kanji-internal=unicode
- -E / --no-encoding == --kanji=none --kanji-internal=none
-EOT1
- -h / --help show this help message and exit
- -V / --version show version
-EOT2
-}
-
-#### command-line options
-
-sub read_option {
- my ($opt, $arg);
- $sw_hex = 1; $sw_uptool = 0;
- while ($ARGV[0] =~ m/^-/) {
- $opt = shift(@ARGV);
- if ($opt =~ m/^--?h(elp)?$/) {
- show_usage();
- } elsif ($opt =~ m/^-(?:V|-version)?$/) {
- show_version();
- } elsif ($opt eq '--hex') {
- $sw_hex = 1;
- } elsif ($opt eq '--octal' || $opt eq '-o') {
- $sw_hex = 0;
- } elsif ($opt eq '--uptool') {
- $sw_uptool = 1;
- } elsif ($opt eq '--lenient') {
- $sw_lenient = 1;
- } elsif ($opt eq '--no-encoding' || $opt eq '-E') {
- ($exenc, $inenc) = ('none', 'none');
- } elsif ($opt eq '--jis' || $opt eq '-j') {
- ($exenc, $inenc) = ('jis', 'jis');
- } elsif ($opt eq '--unicode' || $opt eq '-u') {
- ($exenc, $inenc) = ('utf8', 'unicode');
- } elsif (($arg) = $opt =~ m/^--kanji[=:](.*)$/) {
- $exenc = $arg;
- } elsif (($arg) = $opt =~ m/^--kanji-internal[=:](.*)$/) {
- $inenc = $arg;
- } elsif ($opt eq '--compact') {
- $sw_compact = 1;
- } else {
- error("invalid option", $opt);
- }
- }
- jcode_set($exenc)
- or error("unknown source kanji code: $exenc");
- jcode_set(undef, $inenc)
- or error("unknown internal kanji code: $inenc");
- #if ($inenc eq 'unicode') { $sw_uptool = 1; }
- if ($sw_hex) { pl_prefer_hex(1); }
- if ($sw_lenient) { vf_strict(0); }
- if ($proc_name eq 'vf2zvp0') {
- ($infile, $outfile) = fix_pathname(".vf", ".zvp0");
- } elsif ($proc_name eq 'zvp02vf') {
- ($infile, $outfile) = fix_pathname(".zvp0", ".vf");
- } elsif ($proc_name eq 'vf2zvp') {
- ($infile, $in2file, $outfile) =
- fix_pathname(".vf", ".tfm", ".zvp");
- } elsif ($proc_name eq 'zvp2vf') {
- ($infile, $outfile, $out2file) =
- fix_pathname(".zvp", ".vf", ".tfm");
- } elsif ($proc_name eq 'tfm2zpl') {
- ($infile, $outfile) = fix_pathname(".tfm", ".zpl");
- } elsif ($proc_name eq 'zpl2tfm') {
- ($infile, $outfile) = fix_pathname(".zpl", ".tfm");
- }
- if ($sw_compact && $proc_name ne 'zvp02vf') {
- alert("option unsupported for '$proc_name'", "--compact");
- }
- ($infile ne $outfile)
- or error("input and output file have same name", $infile);
-}
-
-sub fix_pathname {
- my (@ext) = @_; my (@path);
- (0 <= $#ARGV && $#ARGV <= $#ext)
- or error("wrong number of arguments");
- @{$path[0]} = split_path($ARGV[0]);
- (defined $path[0][2]) or $path[0][2] = $ext[0];
- foreach (1 .. $#ext) {
- if (defined $ARGV[$_]) {
- @{$path[$_]} = split_path($ARGV[$_]);
- (defined $path[$_][2]) or $path[$_][2] = $ext[$_];
- } else {
- @{$path[$_]} = (undef, $path[0][1], $ext[$_]);
- }
- }
- return map { join('', @{$path[$_]}) } (0 .. $#_);
-}
-
-sub split_path {
- my ($pnam) = @_; my ($dnam, $fbas, $ext);
- ($dnam, $fbas) = ($pnam =~ m|^(.*/)(.*)$|) ? ($1, $2) :
- (undef, $pnam);
- ($fbas, $ext) = ($fbas =~ m|^(.+)(\..*)$|) ? ($1, $2) :
- ($fbas, undef);
- return ($dnam, $fbas, $ext);
-}
-
-#### user interface
-
-sub show_info {
- print STDERR (join(": ", $prog_name, @_), "\n");
-}
-
-sub alert {
- show_info("warning", @_);
-}
-
-sub error {
- show_info((@_) ? (@_) : textool_error());
- exit(-1);
-}
-
-#================================================= END
-
-#------------------------------------------------- extra interfaces
-
-*usage_message_org = \&usage_message;
-
-*usage_message = sub {
- local ($_) = usage_message_org();
- my ($part1, $part2) = (<<"EOT1", <<"EOT2");
-
-* ZVP Conversion
-EOT1
-
-* VF Replication
-Usage: $prog_name vfcopy [<options>] <in.vf> <out.vf> <out_base.tfm>...
- $prog_name vfinfo [<options>] <in.vf>
- $prog_name jodel [<options>] <in.vf> <prefix>
-Arguments:
- <in.vf> input virtual font name
- N.B. Input TFM/VF files are searched by Kpathsea.
- <out.vf> output virtual font name
- <out_base.tfm> names of raw TFMs referred by the output virtual font;
- each entry replaces a font mapping in the input font in
- the given order, so the exactly same number of entries
- must be given as font mappings
- <prefix> prefix of output font names (only for jodel)
-Options:
- -z / --zero change first fontmap id in vf to zero
- --uptex assume input font to be for upTeX (only for jodel)
- --unicode generate VF for 'direct-unicode' mode imposed by pxufont
- package; this option is supported only for upTeX fonts and
- thus implies '--uptex' (only for jodel)
- --compact output VF in compact form
-
-* VF Compaction
-Usage: $prog_name compact <in.vf> <out.vf>
-
-* Common Options
- -h / --help show this help message and exit
- -V / --version show version
-EOT2
- s/(Usage:)/$part1$1/; s/\z/$part2/;
- return $_;
-};
-
-%procs = (%procs,
- vfinfo => \&main_vfinfo,
- vfcopy => \&main_vfcopy,
- jodel => \&main_jodel,
- compact => \&main_compact,
-);
-
-sub main_vfinfo {
- PXCopyFont::read_option('vfinfo');
- PXCopyFont::info_vf();
-}
-
-sub main_vfcopy {
- PXCopyFont::read_option('vfcopy');
- PXCopyFont::copy_vf();
-}
-
-sub main_jodel {
- PXCopyFont::read_option('jodel');
- PXCopyFont::jodel();
-}
-
-sub main_compact {
- PXCompact::read_option('compact');
- PXCompact::compact();
-}
-
-#------------------------------------------------- pxcopyfont stuffs
-package PXCopyFont;
-
-*error = *main::error;
-
-our ($src_main, $dst_main, @dst_base, $op_zero, $op_uptex, $op_quiet);
-our ($op_compact, $op_dbgone);
-
-sub info {
- ($op_quiet) or ::show_info(@_);
-}
-
-sub copy_vf {
- local $_ = ::read_whole_file(::kpse("$src_main.vf"), 1) or error();
- ($op_compact) and $_ = compact_vf($_);
- my $vfc = parse_vf($_);
- my ($nb, $nb1) = (scalar(@{$vfc->[0]}), scalar(@dst_base));
- info("number of base TFMs in '$src_main'", $nb);
- if ($dst_base[-1] eq '...' && $nb1 <= $nb) {
- foreach ($nb1-1 .. $nb-1) { $dst_base[$_] = $vfc->[0][$_][1]; }
- } elsif ($nb != $nb1) {
- error("wrong number of base TFMs given", $nb1);
- }
- ::write_whole_file("$dst_main.vf", form_vf($vfc), 1) or error();
- ::write_whole_file("$dst_main.tfm",
- ::read_whole_file(::kpse("$src_main.tfm"), 1), 1) or error();
- foreach my $k (0 .. $#dst_base) {
- my $sfn = $vfc->[0][$k][1]; my $dfn = $dst_base[$k];
- ($sfn ne $dfn) or next;
- ::write_whole_file("$dfn.tfm",
- ::read_whole_file(::kpse("$sfn.tfm"), 1), 1) or error();
- }
-}
-
-sub parse_vf {
- my ($vf) = @_; my (@fs, @lst, $pos);
- @fs = unpack("CCC", $vf);
- ($fs[0] == 0xf7 && $fs[1] == 0xca) or return;
- $pos = $fs[2] + 11; my $hd = substr($vf, 0, $pos);
- while (1) {
- @fs = unpack("CC", substr($vf, $pos, 2));
- (243 <= $fs[0] && $fs[0] <= 246) or last;
- my $fid = ($fs[0] == 243) ? $fs[1] : 999;
- my $t = $fs[0] - 242 + 13;
- @fs = unpack("a${t}CC", substr($vf, $pos, 260));
- my $l = $fs[1] + $fs[2]; my $n = substr($vf, $pos + $t + 2, $l);
- $pos += $t + 2 + $l; push(@lst, [ $fs[0], $n, $fid ]);
- if ($n !~ m/^[\x21-\x7e]+$/) {
- $n =~ s/([^\x21-\x5b\x5d-\x7e])/sprintf("\\x%02x", ord($1))/g;
- error("bad tfm name recorded in VF", $n);
- }
- }
- my $ft = substr($vf, $pos); $ft =~ s/\xf8+\z//g;
- return [ \@lst, $hd, $ft ];
-}
-
-sub info_vf {
- local $_ = ::read_whole_file(::kpse("$src_main.vf"), 1) or error();
- my $vfc = parse_vf($_);
- foreach (@{$vfc->[0]}) {
- printf("%d=%s\n", $_->[2], $_->[1]);
- }
-}
-
-sub form_vf {
- my ($vfc) = @_; my (@lst);
- if ($op_zero) {{
- my $t = $vfc->[0][0] or last;
- ($t->[2] == 0) and last; # already zero
- info("change first fontmap id to zero (from " . $t->[2] . ")");
- substr($t->[0], 1, 1) = "\0"; $t->[2] = 0;
- }}
- foreach my $k (0 .. $#{$vfc->[0]}) {
- my $t = $vfc->[0][$k]; my $sfn = $t->[1];
- my $dfn = $dst_base[$k];
- (length($dfn) < 256) or error("TFM name too long", $dfn);
- info("id=".$t->[2], $sfn, $dfn);
- push(@lst, $t->[0], "\0" . chr(length($dfn)), $dfn);
- }
- my $tfm = join('', $vfc->[1], @lst, $vfc->[2]);
- return $tfm . ("\xf8" x (4 - length($tfm) % 4));
-}
-
-sub compact_vf {
- my ($vf) = @_;
- my $pl = ::vf_parse($vf) or error();
- $pl = [ grep { !::is_simple_char($_) } (@$pl) ];
- $vf = ::vf_form($pl) or error();
- return $vf;
-}
-
-sub read_option {
- my ($proc) = @_;
- $op_zero = 0; $op_uptex = 0; $op_quiet = 0;
- $op_compact = 0; $op_dbgone = 0;
- while ($ARGV[0] =~ m/^-/) {
- my $opt = shift(@ARGV);
- if ($opt =~ m/^--?h(elp)?$/) {
- ::show_usage();
- } elsif ($opt =~ m/^-(?:V|-version)?$/) {
- ::show_version();
- } elsif ($opt eq '-z' || $opt eq '--zero') {
- $op_zero = 1;
- } elsif ($opt eq '--uptex') {
- $op_uptex = 1;
- } elsif ($opt eq '--unicode') {
- $op_uptex = 2;
- } elsif ($opt eq '--compact') {
- $op_compact = 1;
- } elsif ($opt eq '--debug-one') { # undocumented
- $op_dbgone = 1;
- } elsif ($opt eq '--quiet') { # undocumented
- $op_quiet = 2;
- } else {
- error("invalid option", $opt);
- }
- }
- ($src_main, $dst_main, @dst_base) = @ARGV;
- $src_main =~ s/\.vf$//;
- (defined $src_main) or error("no argument given");
- (($proc eq 'vfinfo') ? (!defined $dst_main) :
- ($proc eq 'vfcopy') ? (defined $dst_main) :
- ($proc eq 'jodel') ? (defined $dst_main && $#dst_base == -1) : 1)
- or error("wrong number of arguments");
- if ($proc eq 'vfcopy') {
- $dst_main =~ s/\.vf$//;
- foreach (@dst_base) { s/\.tfm$//; }
- ($src_main ne $dst_main)
- or error("output vf name is same as input");
- (@dst_base) or error("no base tfm name given");
- }
- if ($proc eq 'jodel') {
- (!$op_zero) or error("invalid in jodel command", "-z/--zero");
- ($dst_main =~ m/^\w+$/)
- or error("bad characters in prefix", $dst_main);
- (length($dst_main) <= 100) or error("prefix too long", $dst_main);
- } else {
- (!$op_uptex) or error("invalid except in jodel command", "--uptex");
- }
-}
-
-#------------------------------- jodel
-
-our %standard_vf = (
- 'rml' => [1, 'JhXXXN-h'],
- 'rmlv' => [1, 'JhXXXN-v'],
- 'uprml-h' => [2, 'uphXXXN-h'],
- 'uprml-hq' => [2, 'jodhXXX-hq'],
- 'uprml-v' => [2, 'uphXXXN-v'],
- 'gbm' => [1, 'JhXXXN-h'],
- 'gbmv' => [1, 'JhXXXN-v'],
- 'upgbm-h' => [2, 'uphXXXN-h'],
- 'upgbm-hq' => [2, 'jodhXXX-hq'],
- 'upgbm-v' => [2, 'uphXXXN-v'],
-);
-our @shape = (
- 'minl', 'minr', 'minb', 'gothr', 'gothb', 'gotheb', 'mgothr'
-);
-
-our ($jengine, $jtate, @jvfname, %jvfidx, %jvfparsed);
-
-sub jodel {
- ($op_dbgone) and @shape = @shape[1];
- jodel_analyze();
- if ($op_uptex == 2) {
- ($jengine == 2)
- or error("direct-unicode mode is only supported for pure upTeX fonts");
- foreach (values %standard_vf) {
- ($_->[1] =~ m/^jod/) and $_->[1] =~ s/jod/zu-jod/;
- }
- }
- foreach (@shape) {
- jodel_generate($_, '');
- jodel_generate($_, 'n');
- }
-}
-
-sub jodel_vf_name {
- my ($shp, $nn, $idx) = @_;
- my $zu = ($op_uptex == 2) ? 'zu-' : '';
- my $i = ($idx > 0) ? "$idx" : '';
- my $up = (jodel_for_uptex()) ? 'up' : '';
- my $hv = ($jtate) ? 'v' : 'h';
- return "$zu$dst_main-$i-${up}nml$shp$nn-$hv";
-}
-sub jodel_tfm_name {
- my ($shp, $nn, $nam) = @_;
- local $_ = $nam; my $jod = ($nn eq 'n') ? 'jod' : '';
- s/XXX/\Q$shp\E/; s/N/\Q$nn\E/; s/J/\Q$jod\E/;
- return $_;
-}
-sub jodel_for_uptex {
- return ($jengine == 2 || ($jengine == 3 && $op_uptex));
-}
-
-{
- my (%jkpse);
- sub jodel_kpse {
- my ($in) = @_;
- if (exists $jkpse{$in}) { return $jkpse{$in}; }
- my $out = ::kpse($in); $jkpse{$in} = $out;
- return $out;
- }
-}
-
-sub jodel_clone {
- my ($val) = @_;
- if (ref($val) eq '') {
- return $val;
- } elsif (ref($val) eq 'ARRAY') {
- return [ map { jodel_clone($_) } (@$val) ];
- } else { error("OOPS", 98, ref($val)); }
-}
-
-sub jodel_analyze {
- local ($_);
- info("**** Analyze VF '$src_main'");
- $_ = ::read_whole_file(jodel_kpse("$src_main.tfm"), 1) or error();
- $jtate = (unpack('n', $_) == 9);
- info("direction", ($jtate) ? 'tate' : 'yoko');
- @jvfname = ($src_main); $jengine = 0;
- info("base TFMs", "");
- for (my $i = 0; $i <= $#jvfname; $i++) {
- my $nvf = $jvfname[$i];
- $_ = ::read_whole_file(jodel_kpse("$nvf.vf"), 1)
- or error(($i > 0) ? ("non-standard raw TFM", $nvf) : ());
- ($op_compact) and $_ = compact_vf($_);
- $_ = parse_vf($_) or error();
- $jvfidx{$nvf} = $i; $jvfparsed{$nvf} = $_;
- my @lst = map { $_->[1] } @{$_->[0]};
- info(" $nvf -> @lst");
- foreach (@lst) {
- if (exists $standard_vf{$_}) {
- $jengine |= $standard_vf{$_}[0];
- next;
- }
- (exists $jvfidx{$_}) and next;
- push(@jvfname, $_);
- }
- }
- my $eng = (jodel_for_uptex()) ? 'upTeX' : 'pTeX';
- ($jengine == 3) and $eng .= ' (mixed)';
- info("engine", $eng);
-}
-
-sub jodel_generate {
- my ($shp, $nn) = @_; local ($_);
- my $dnvf0 = jodel_vf_name($shp, $nn, 0);
- info("*** Generate VF '$dnvf0'");
- foreach my $i (0 .. $#jvfname) {
- my $snvf = $jvfname[$i];
- my $dnvf = jodel_vf_name($shp, $nn, $i);
- my $vfc = jodel_clone($jvfparsed{$snvf});
- my (@slst, @dlst);
- foreach my $e (@{$vfc->[0]}) {
- my $sbas = $e->[1]; my $dbas;
- if (exists $standard_vf{$sbas}) {
- $dbas = jodel_tfm_name($shp, $nn, $standard_vf{$sbas}[1]);
- } elsif (exists $jvfidx{$sbas}) {
- $dbas = jodel_vf_name($shp, $nn, $jvfidx{$sbas});
- } else { error("OOPS", 95, "$sbas"); }
- push(@slst, $sbas); push(@dlst, $dbas);
- $e->[1] = $dbas;
- }
- info("from", "$snvf -> @slst");
- info(" to", "$dnvf -> @dlst");
- ::write_whole_file("$dnvf.vf", jodel_form_vf($vfc), 1) or error();
- ::write_whole_file("$dnvf.tfm",
- ::read_whole_file(jodel_kpse("$snvf.tfm"), 1), 1) or error();
- }
-}
-
-sub jodel_form_vf {
- my ($vfc) = @_; my (@lst);
- foreach my $k (0 .. $#{$vfc->[0]}) {
- my $t = $vfc->[0][$k]; my $dfn = $t->[1];
- push(@lst, $t->[0], "\0" . chr(length($dfn)), $dfn);
- }
- my $tfm = join('', $vfc->[1], @lst, $vfc->[2]);
- return $tfm . ("\xf8" x (4 - length($tfm) % 4));
-}
-
-#------------------------------------------------- 'compact' stuffs
-package PXCompact;
-
-*error = *main::error;
-
-our ($src_name, $dst_name, $op_quiet);
-
-sub info {
- ($op_quiet) or ::show_info(@_);
-}
-
-sub num_chars {
- my ($pl) = @_; my $c = 0;
- foreach (@$pl) { $c += 1 if ($_->[0] eq 'CHARACTER'); }
- return $c;
-}
-
-sub compact {
- local $_ = ::read_whole_file(::kpse("$src_name.vf"), 1) or error();
- my $pl = ::vf_parse($_) or error();
- my ($siz, $nc) = (length($_), num_chars($pl));
- info("from", "$siz bytes, $nc chars", "$src_name.vf");
- $pl = [ grep { !::is_simple_char($_) } (@$pl) ];
- $_ = ::vf_form($pl) or error();
- ($siz, $nc) = (length($_), num_chars($pl));
- ::write_whole_file("$dst_name.vf", $_, 1) or error();
- info(" to", "$siz bytes, $nc chars", "$dst_name.vf");
-}
-
-sub read_option {
- my ($proc) = @_;
- $op_quiet = 0;
- while ($ARGV[0] =~ m/^-/) {
- my $opt = shift(@ARGV);
- if ($opt =~ m/^--?h(elp)?$/) {
- ::show_usage();
- } elsif ($opt =~ m/^-(?:V|-version)?$/) {
- ::show_version();
- } elsif ($opt eq '--quiet') { # undocumented
- $op_quiet = 2;
- } else {
- error("invalid option", $opt);
- }
- }
- ($#ARGV == 1) or error("wrong number of arguments");
- ($src_name, $dst_name) = @ARGV;
- $src_name =~ s/\.vf$//; $dst_name =~ s/\.vf$//;
-}
-
-#------------------------------------------------- go to main
-package main;
-main();
-## EOF
diff --git a/Build/source/texk/texlive/linked_scripts/ketcindy/ketcindy.pl b/Build/source/texk/texlive/linked_scripts/ketcindy/ketcindy.pl
deleted file mode 100644
index e5efbc0c98e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ketcindy/ketcindy.pl
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env perl
-#
-# KETCindy starter script
-#
-# (C) 2017-2018 Norbert Preining
-# Licensed under the same license terms as ketpic itself, that is GPLv3+
-#
-
-use strict;
-$^W = 1;
-
-use Digest::MD5;
-use File::Copy;
-
-my $BinaryName = "Cinderella2";
-my $TemplateFile = "template1basic.cdy";
-my $devnull = "/dev/null";
-my $prog = "ketcindy";
-my $systype;
-if (win32()) {
- $systype = "Windows";
- $devnull = "nul";
-} else {
- $systype = `uname`;
- chomp($systype);
-}
-my $HOME = ($systype eq "Windows") ? $ENV{'USERPROFILE'} : $ENV{'HOME'};
-my $workdir ="$HOME/ketcindy";
-
-my $cinderella;
-if ($#ARGV >= 0) {
- if ($ARGV[0] eq '-c') {
- $cinderella = ($ARGV[1] ? $ARGV[1] : "");
- }
-} else {
- $cinderella = which($BinaryName);
-}
-
-if (! "$cinderella") {
- if ($systype eq 'Darwin') {
- if (-r '/Applications/Cinderella2.app/Contents/MacOS/Cinderella2') {
- $cinderella = '/Applications/Cinderella2.app/Contents/MacOS/Cinderella2';
- }
- } elsif ($systype eq 'Windows') {
- if (-f 'c:/Program Files (x86)/Cinderella/Cinderella2.exe') {
- $cinderella = 'c:/Program Files (x86)/Cinderella/Cinderella2.exe';
- }
- }
-}
-
-if (! "$cinderella") {
- die "$prog: Cannot find $BinaryName!";
-}
-
-if ( ! -x "$cinderella" ) {
- die "$prog: Program $cinderella is not executable!";
-}
-
-# find real path
-my $realcind = win32() ? $cinderella : `realpath "$cinderella"`;
-chomp($realcind);
-my ($cinddir, $bn) = dirname_and_basename($realcind);
-
-my $plugindir = ($systype eq 'Darwin') ? "$cinddir/../PlugIns" : "$cinddir/Plugins";
-
-my $plugin = "$plugindir/KetCindyPlugin.jar";
-my $dirheadplugin = "$plugindir/ketcindy.ini";
-
-# find Jar
-chomp(my $KetCdyJar = `kpsewhich -format=texmfscripts KetCindyPlugin.jar`);
-# search for template.cdy
-chomp(my $TempCdy = `kpsewhich -format=texmfscripts $TemplateFile`);
-chomp(my $DirHead=`kpsewhich -format=texmfscripts ketcindy.ini`);
-
-if (-z "$TempCdy" || -z "$KetCdyJar") {
- die "$prog: Cannot find $TemplateFile via kpsewhich, is ketpic installed?";
-}
-
-
-if ( ! -r "$plugin" || ! -r "$dirheadplugin" ) {
- print "$prog: Cinderella is *NOT* set up for KETCindy!\n";
- print "$prog: You need to copy\n";
- print "$prog: $KetCdyJar\n";
- print "$prog: $DirHead\n";
- print "$prog: into\n";
- print "$prog: $plugindir\n";
- print "\n";
- exit(1);
-}
-
-my $myjarmd = md5digest($KetCdyJar);
-my $sysjarmd = md5digest($plugin);
-
-if ( $myjarmd ne $sysjarmd ) {
- print "$prog: The installed version of the plugin in\n";
- print "$prog: $plugin\n";
- print "$prog: differs from the version shipped in\n";
- print "$prog: $KetCdyJar\n";
- print "$prog: You might need to update the former one with the later one!\n";
-}
-
-# print "DEBUG workdir =$workdir=\n";
-# print "DEBUG TemplateFile =$TemplateFile=\n";
-mkdir($workdir);
-copy($TempCdy, $workdir) or die "$prog: Copy failed: $!";
-
-# print "Exec $cinderella $workdir/$TemplateFile\n";
-if (win32()) {
- # no idea why a normal call with exec did not find the template file
- my $out = `"$cinderella" "$workdir/$TemplateFile"`;
-} else {
- exec($cinderella, "$workdir/$TemplateFile");
-}
-
-
-sub md5digest {
- my $file = shift;
- open(FILE, $file) || die "$prog: open($file) failed: $!";
- binmode(FILE);
- my $out = Digest::MD5->new->addfile(*FILE)->hexdigest;
- close(FILE);
- return $out;
-}
-
-# taken from TeXLive::TLUtils.pm
-sub win32 {
- if ($^O =~ /^MSWin/i) {
- return 1;
- } else {
- return 0;
- }
-}
-sub which {
- my ($prog) = @_;
- my @PATH;
- my $PATH = getenv('PATH');
-
- if (&win32) {
- my @PATHEXT = split (';', getenv('PATHEXT'));
- push (@PATHEXT, ''); # in case argument contains an extension
- @PATH = split (';', $PATH);
- for my $dir (@PATH) {
- for my $ext (@PATHEXT) {
- if (-f "$dir/$prog$ext") {
- return "$dir/$prog$ext";
- }
- }
- }
-
- } else { # not windows
- @PATH = split (':', $PATH);
- for my $dir (@PATH) {
- if (-x "$dir/$prog") {
- return "$dir/$prog";
- }
- }
- }
- return "";
-}
-sub dirname_and_basename {
- my $path=shift;
- my ($share, $base) = ("", "");
- if (win32()) {
- $path=~s!\\!/!g;
- }
- # do not try to make sense of paths ending with /..
- return (undef, undef) if $path =~ m!/\.\.$!;
- if ($path=~m!/!) { # dirname("foo/bar/baz") -> "foo/bar"
- # eliminate `/.' path components
- while ($path =~ s!/\./!/!) {};
- # UNC path? => first split in $share = //xxx/yy and $path = /zzzz
- if (win32() and $path =~ m!^(//[^/]+/[^/]+)(.*)$!) {
- ($share, $path) = ($1, $2);
- if ($path =~ m!^/?$!) {
- $path = $share;
- $base = "";
- } elsif ($path =~ m!(/.*)/(.*)!) {
- $path = $share.$1;
- $base = $2;
- } else {
- $base = $path;
- $path = $share;
- }
- return ($path, $base);
- }
- # not a UNC path
- $path=~m!(.*)/(.*)!; # works because of greedy matching
- return ((($1 eq '') ? '/' : $1), $2);
- } else { # dirname("ignore") -> "."
- return (".", $path);
- }
-}
-sub getenv {
- my $envvar=shift;
- my $var=$ENV{"$envvar"};
- return 0 unless (defined $var);
- if (&win32) {
- $var=~s!\\!/!g; # change \ -> / (required by Perl)
- }
- return "$var";
-}
-
-
diff --git a/Build/source/texk/texlive/linked_scripts/kotex-utils/jamo-normalize.pl b/Build/source/texk/texlive/linked_scripts/kotex-utils/jamo-normalize.pl
deleted file mode 100755
index 3c7bcb08b5b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/kotex-utils/jamo-normalize.pl
+++ /dev/null
@@ -1,6648 +0,0 @@
-#!/usr/bin/env perl
-
-# jamo-normalize.pl
-#
-# Copyright (c) 2003-2015 Dohyun Kim <nomos at ktug org>
-#
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.3c
-# of this license or (at your option) any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3c or later is part of all distributions of LaTeX
-# version 2006/05/20 or later.
-#
-# written by Dohyun Kim <nomos at ktug org>
-# public domain
-#
-
-#use strict;
-#use warnings;
-
-my %OPT;
-
-while (@ARGV) {
- my $opt = shift @ARGV;
- if ($opt =~ /-b/i) { $OPT{boundary} = 1 }
- elsif ($opt =~ /-p/i) { $OPT{topua} = 1 }
- elsif ($opt =~ /-d/i) { $OPT{decompose} = 1 }
- elsif ($opt =~ /-o/i) { $OPT{frompua} = 1 }
- elsif ($opt =~ /-t/i) { $OPT{latintm} = 1 }
- elsif ($opt =~ /-r/i) { $OPT{reordertm} = 1 }
- elsif ($opt =~ /-i/i) { $OPT{normalhanja} = 1 }
- elsif ($opt =~ /-c/i) { $OPT{compatjamo} = 1 }
- else {
- (my $prog = $0) =~ s/.*[\/\\]//;
- print
- "Usage: $prog [options] < in_file > out_file\n\n",
- " Translate Hangul Jamo sequence to Hangul syllables\n\n",
- " -b : insert ZWS between syllable blocks (not for practical use)\n",
- " -c : convert conjoining Jamo to compatibility Jamo\n",
- " -d : decomposition only, and no further recomposition\n",
- " -i : convert compatibility Hanja to normal Hanja\n",
- " -o : decompose PUA Old Hangul syllables to Jamo sequence\n",
- " -p : compose Jamo sequence to PUA Old Hangul syllables\n",
- " -r : reorder Hangul Tone Marks to the first of syllable block\n",
- " (not for practical use)\n",
- " -t : convert U+00B7 or U+003A to Hangul Tone Marks\n";
- exit;
- }
-}
-
-##### variables #####
-
-my $cho = "\x{1100}-\x{115F}\x{A960}-\x{A97C}";
-my $jung = "\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}";
-my $jong = "\x{11A8}-\x{11FF}\x{D7CB}-\x{D7FB}";
-my $tmrk = "\x{302E}\x{302F}";
-my $boundary = "\x{200B}";
-my $syllblock = "[$cho][$jung][$jong]?[$tmrk]?";
-my $jamos = "[$cho$jung$jong$tmrk]";
-
-my %jamo2cjamo = (
- 0x1100 => 0x3131, 0x1101 => 0x3132, 0x1102 => 0x3134, 0x1103 => 0x3137,
- 0x1104 => 0x3138, 0x1105 => 0x3139, 0x1106 => 0x3141, 0x1107 => 0x3142,
- 0x1108 => 0x3143, 0x1109 => 0x3145, 0x110A => 0x3146, 0x110B => 0x3147,
- 0x110C => 0x3148, 0x110D => 0x3149, 0x110E => 0x314A, 0x110F => 0x314B,
- 0x1110 => 0x314C, 0x1111 => 0x314D, 0x1112 => 0x314E, 0x1114 => 0x3165,
- 0x1115 => 0x3166, 0x111A => 0x3140, 0x111C => 0x316E, 0x111D => 0x3171,
- 0x111E => 0x3172, 0x1120 => 0x3173, 0x1121 => 0x3144, 0x1122 => 0x3174,
- 0x1123 => 0x3175, 0x1127 => 0x3176, 0x1129 => 0x3177, 0x112B => 0x3178,
- 0x112C => 0x3179, 0x112D => 0x317A, 0x112E => 0x317B, 0x112F => 0x317C,
- 0x1132 => 0x317D, 0x1136 => 0x317E, 0x1140 => 0x317F,
-# 0x1145 => 0x3182, 0x1146 => 0x3183,
- 0x1147 => 0x3180, 0x114C => 0x3181, 0x1157 => 0x3184, 0x1158 => 0x3185,
- 0x1159 => 0x3186, 0x115B => 0x3167, 0x115C => 0x3135, 0x115D => 0x3136,
- 0x1161 => 0x314F, 0x1162 => 0x3150, 0x1163 => 0x3151, 0x1164 => 0x3152,
- 0x1165 => 0x3153, 0x1166 => 0x3154, 0x1167 => 0x3155, 0x1168 => 0x3156,
- 0x1169 => 0x3157, 0x116A => 0x3158, 0x116B => 0x3159, 0x116C => 0x315A,
- 0x116D => 0x315B, 0x116E => 0x315C, 0x116F => 0x315D, 0x1170 => 0x315E,
- 0x1171 => 0x315F, 0x1172 => 0x3160, 0x1173 => 0x3161, 0x1174 => 0x3162,
- 0x1175 => 0x3163, 0x1184 => 0x3187, 0x1185 => 0x3188, 0x1188 => 0x3189,
- 0x1191 => 0x318A, 0x1192 => 0x318B, 0x1194 => 0x318C, 0x119E => 0x318D,
- 0x11A1 => 0x318E,
-# 0x11A8 => 0x3131, 0x11A9 => 0x3132, 0x11AA => 0x3133, 0x11AB => 0x3134,
-# 0x11AC => 0x3135, 0x11AD => 0x3136, 0x11AE => 0x3137, 0x11AF => 0x3139,
-# 0x11B0 => 0x313A, 0x11B1 => 0x313B, 0x11B2 => 0x313C, 0x11B3 => 0x313D,
-# 0x11B4 => 0x313E, 0x11B5 => 0x313F, 0x11B6 => 0x3140, 0x11B7 => 0x3141,
-# 0x11B8 => 0x3142, 0x11B9 => 0x3144, 0x11BA => 0x3145, 0x11BB => 0x3146,
-# 0x11BC => 0x3147, 0x11BD => 0x3148, 0x11BE => 0x314A, 0x11BF => 0x314B,
-# 0x11C0 => 0x314C, 0x11C1 => 0x314D, 0x11C2 => 0x314E, 0x11C6 => 0x3166,
-# 0x11C7 => 0x3167, 0x11C8 => 0x3168, 0x11CC => 0x3169, 0x11CE => 0x316A,
-# 0x11D3 => 0x316B, 0x11D7 => 0x316C, 0x11D9 => 0x316D, 0x11DC => 0x316E,
-# 0x11DD => 0x316F, 0x11DF => 0x3170, 0x11E2 => 0x3171, 0x11E6 => 0x3178,
-# 0x11E7 => 0x317A, 0x11E8 => 0x317C, 0x11EA => 0x317D, 0x11EB => 0x317F,
-# 0x11EE => 0x3180, 0x11F0 => 0x3181, 0x11F1 => 0x3182, 0x11F2 => 0x3183,
-# 0x11F4 => 0x3184, 0x11F9 => 0x3186, 0x11FF => 0x3165,
- 0xA964 => 0x313A, 0xA966 => 0x316A, 0xA968 => 0x313B, 0xA969 => 0x313C,
- 0xA96C => 0x313D, 0xA971 => 0x316F,
-# 0xD7CD => 0x3138, 0xD7E3 => 0x3173, 0xD7E6 => 0x3143, 0xD7E7 => 0x3175,
-# 0xD7E8 => 0x3176, 0xD7EF => 0x317E, 0xD7F9 => 0x3149,
-);
-
-my @HYpuaJamo;
-if ($OPT{frompua} or $OPT{topua}) { @HYpuaJamo = arr_hypua2jamo(); }
-
-##### main routine #####
-
-binmode (STDIN,":utf8");
-binmode (STDOUT,":utf8");
-
-while (<>) {
- print STDERR ".";
- &syllable2jamo;
- if ($OPT{frompua}) {
- &hypua2jamo;
- &hypuasingle2jamo;
- }
- &compose_jamo;
- &insert_filler;
- &ascii2tonemark if $OPT{latintm};
- &insert_boundary if $OPT{boundary};
- &reorder_tonemark if $OPT{reordertm};
- unless ($OPT{decompose}) {
- &jamo2hypua if $OPT{topua};
- &jamo2syllable;
- &jamo2jamocomp if $OPT{compatjamo};
- }
- &normalize_hanja if $OPT{normalhanja};
- print;
-}
-
-print STDERR "\n";
-
-##### subroutines #####
-
-sub reorder_tonemark {
- my @blocks = split /($syllblock)/;
- for my $i (0 .. $#blocks) {
- if ($i % 2 == 0) {
- $blocks[$i] =~ s/([$tmrk])/$1\x{25CC}/g;
- }
- else {
- $blocks[$i] =~ s/([$cho$jung$jong]+)([$tmrk])$/$2$1/;
- }
- }
- $_ = join '',@blocks;
-}
-
-sub ascii2tonemark {
- s/\x{B7}([$cho][$jung][$jong]?)(?![$tmrk])/$1\x{302E}/g;
- s/\x{3A}([$cho][$jung][$jong]?)(?![$tmrk])/$1\x{302F}/g;
-}
-
-sub hypua2jamo {
- for my $i (0 .. $#HYpuaJamo) {
- my $puachar = chr $HYpuaJamo[$i][0];
- my $jamoseq = "";
- for my $j (1 .. $#{$HYpuaJamo[$i]}) {
- $jamoseq .= chr $HYpuaJamo[$i][$j];
- }
- s/$puachar/$jamoseq/g;
- }
-}
-
-sub jamo2hypua {
- for my $i (0 .. $#HYpuaJamo) {
- my $puachar = chr $HYpuaJamo[$i][0];
- my $jamoseq = "";
- for my $j (1 .. $#{$HYpuaJamo[$i]}) {
- $jamoseq .= chr $HYpuaJamo[$i][$j];
- }
- s/$jamoseq/$puachar/g;
- }
-}
-
-sub insert_boundary {
- chomp;
- my @parts = split /($syllblock)/, $_;
- my @newparts;
- for my $i (0 .. $#parts) {
- if ($i % 2 == 0) {
- next unless $parts[$i];
- my @subparts = split /($jamos)/, $parts[$i];
- my @newsubparts;
- for my $i (0 .. $#subparts) {
- push @newsubparts, $subparts[$i] if $subparts[$i];
- }
- push @newparts, join ($boundary, @newsubparts);
- }
- else {
- push @newparts, $parts[$i];
- }
- }
- $_ = join $boundary, @newparts;
- $_ .= "\n";
-}
-
-sub insert_filler {
- s/(?<![$jung])([$jong])/\x{115F}\x{1160}$1/g;
- s/(?<![$cho])([$jung])/\x{115F}$1/g;
- s/([$cho])(?![$jung])/$1\x{1160}/g;
-}
-
-sub syllable2jamo { # no decomposition of control sequence
- my @nocs = split /(\\[\x{AC00}-\x{D7A3}]+)/;
- for (my $i=0; $i<@nocs; $i=$i+2) {
- $nocs[$i] =~ s/([\x{AC00}-\x{D7A3}])/do_syllable2jamo($1)/ge;
- }
- $_ = join '', @nocs;
-}
-
-sub do_syllable2jamo {
- my $syl = ord shift;
- my $LC = ($syl - 0xac00) / (21 * 28) + 0x1100;
- my $MV = (($syl - 0xac00) % (21 * 28)) / 28 + 0x1161;
- my $TC = ($syl - 0xac00) % 28 + 0x11a7;
- my $result = chr($LC).chr($MV);
- $result .= chr($TC) unless $TC == 0x11a7;
- return $result;
-}
-
-sub jamo2syllable {
- # ě´ě„±.중성.종성
- s/([\x{1100}-\x{1112}])
- ([\x{1161}-\x{1175}])
- ([\x{11A8}-\x{11C2}])
- /do_jamo2syllable(ord $1, ord $2, ord $3)/gex;
- # ě´ě„±.중성
- s/([\x{1100}-\x{1112}])
- ([\x{1161}-\x{1175}])
- (?![$jong])
- /do_jamo2syllable(ord $1, ord $2, 0)/gex;
-}
-
-sub do_jamo2syllable {
- my ($LC,$MV,$TC) = @_;
- my $syllable = ($LC - 0x1100) * 21;
- $syllable = ($syllable + $MV - 0x1161) * 28;
- $syllable += $TC - 0x11a7 if $TC;
- $syllable += 0xac00;
- return chr $syllable;
-}
-
-sub jamo2jamocomp {
- s/([$cho])\x{1160}/do_jamo2jamocomp($1)/ge;
- s/\x{115F}([$jung])(?![$jong])/do_jamo2jamocomp($1)/ge;
- # s/\x{115F}\x{1160}([$jong])/do_jamo2jamocomp($1)/ge;
-}
-
-sub do_jamo2jamocomp {
- my $jamo = shift;
- my $cjamo = $jamo2cjamo{ord $jamo};
- return chr $cjamo if $cjamo;
- return "$jamo\x{1160}" if $jamo =~ /[$cho]/;
- return "\x{115F}$jamo" if $jamo =~ /[$jung]/;
- return "\x{115F}\x{1160}$jamo" if $jamo =~ /[$jong]/;
-}
-
-sub normalize_hanja {
- s/\x{F900}/\x{8C48}\x{FE00}/g;
- s/\x{F901}/\x{66F4}\x{FE00}/g;
- s/\x{F902}/\x{8ECA}\x{FE00}/g;
- s/\x{F903}/\x{8CC8}\x{FE00}/g;
- s/\x{F904}/\x{6ED1}\x{FE00}/g;
- s/\x{F905}/\x{4E32}\x{FE00}/g;
- s/\x{F906}/\x{53E5}\x{FE00}/g;
- s/\x{F907}/\x{9F9C}\x{FE00}/g;
- s/\x{F908}/\x{9F9C}\x{FE01}/g;
- s/\x{F909}/\x{5951}\x{FE00}/g;
- s/\x{F90A}/\x{91D1}\x{FE00}/g;
- s/\x{F90B}/\x{5587}\x{FE00}/g;
- s/\x{F90C}/\x{5948}\x{FE00}/g;
- s/\x{F90D}/\x{61F6}\x{FE00}/g;
- s/\x{F90E}/\x{7669}\x{FE00}/g;
- s/\x{F90F}/\x{7F85}\x{FE00}/g;
- s/\x{F910}/\x{863F}\x{FE00}/g;
- s/\x{F911}/\x{87BA}\x{FE00}/g;
- s/\x{F912}/\x{88F8}\x{FE00}/g;
- s/\x{F913}/\x{908F}\x{FE00}/g;
- s/\x{F914}/\x{6A02}\x{FE00}/g;
- s/\x{F915}/\x{6D1B}\x{FE00}/g;
- s/\x{F916}/\x{70D9}\x{FE00}/g;
- s/\x{F917}/\x{73DE}\x{FE00}/g;
- s/\x{F918}/\x{843D}\x{FE00}/g;
- s/\x{F919}/\x{916A}\x{FE00}/g;
- s/\x{F91A}/\x{99F1}\x{FE00}/g;
- s/\x{F91B}/\x{4E82}\x{FE00}/g;
- s/\x{F91C}/\x{5375}\x{FE00}/g;
- s/\x{F91D}/\x{6B04}\x{FE00}/g;
- s/\x{F91E}/\x{721B}\x{FE00}/g;
- s/\x{F91F}/\x{862D}\x{FE00}/g;
- s/\x{F920}/\x{9E1E}\x{FE00}/g;
- s/\x{F921}/\x{5D50}\x{FE00}/g;
- s/\x{F922}/\x{6FEB}\x{FE00}/g;
- s/\x{F923}/\x{85CD}\x{FE00}/g;
- s/\x{F924}/\x{8964}\x{FE00}/g;
- s/\x{F925}/\x{62C9}\x{FE00}/g;
- s/\x{F926}/\x{81D8}\x{FE00}/g;
- s/\x{F927}/\x{881F}\x{FE00}/g;
- s/\x{F928}/\x{5ECA}\x{FE00}/g;
- s/\x{F929}/\x{6717}\x{FE00}/g;
- s/\x{F92A}/\x{6D6A}\x{FE00}/g;
- s/\x{F92B}/\x{72FC}\x{FE00}/g;
- s/\x{F92C}/\x{90CE}\x{FE00}/g;
- s/\x{F92D}/\x{4F86}\x{FE00}/g;
- s/\x{F92E}/\x{51B7}\x{FE00}/g;
- s/\x{F92F}/\x{52DE}\x{FE00}/g;
- s/\x{F930}/\x{64C4}\x{FE00}/g;
- s/\x{F931}/\x{6AD3}\x{FE00}/g;
- s/\x{F932}/\x{7210}\x{FE00}/g;
- s/\x{F933}/\x{76E7}\x{FE00}/g;
- s/\x{F934}/\x{8001}\x{FE00}/g;
- s/\x{F935}/\x{8606}\x{FE00}/g;
- s/\x{F936}/\x{865C}\x{FE00}/g;
- s/\x{F937}/\x{8DEF}\x{FE00}/g;
- s/\x{F938}/\x{9732}\x{FE00}/g;
- s/\x{F939}/\x{9B6F}\x{FE00}/g;
- s/\x{F93A}/\x{9DFA}\x{FE00}/g;
- s/\x{F93B}/\x{788C}\x{FE00}/g;
- s/\x{F93C}/\x{797F}\x{FE00}/g;
- s/\x{F93D}/\x{7DA0}\x{FE00}/g;
- s/\x{F93E}/\x{83C9}\x{FE00}/g;
- s/\x{F93F}/\x{9304}\x{FE00}/g;
- s/\x{F940}/\x{9E7F}\x{FE00}/g;
- s/\x{F941}/\x{8AD6}\x{FE00}/g;
- s/\x{F942}/\x{58DF}\x{FE00}/g;
- s/\x{F943}/\x{5F04}\x{FE00}/g;
- s/\x{F944}/\x{7C60}\x{FE00}/g;
- s/\x{F945}/\x{807E}\x{FE00}/g;
- s/\x{F946}/\x{7262}\x{FE00}/g;
- s/\x{F947}/\x{78CA}\x{FE00}/g;
- s/\x{F948}/\x{8CC2}\x{FE00}/g;
- s/\x{F949}/\x{96F7}\x{FE00}/g;
- s/\x{F94A}/\x{58D8}\x{FE00}/g;
- s/\x{F94B}/\x{5C62}\x{FE00}/g;
- s/\x{F94C}/\x{6A13}\x{FE00}/g;
- s/\x{F94D}/\x{6DDA}\x{FE00}/g;
- s/\x{F94E}/\x{6F0F}\x{FE00}/g;
- s/\x{F94F}/\x{7D2F}\x{FE00}/g;
- s/\x{F950}/\x{7E37}\x{FE00}/g;
- s/\x{F951}/\x{964B}\x{FE00}/g;
- s/\x{F952}/\x{52D2}\x{FE00}/g;
- s/\x{F953}/\x{808B}\x{FE00}/g;
- s/\x{F954}/\x{51DC}\x{FE00}/g;
- s/\x{F955}/\x{51CC}\x{FE00}/g;
- s/\x{F956}/\x{7A1C}\x{FE00}/g;
- s/\x{F957}/\x{7DBE}\x{FE00}/g;
- s/\x{F958}/\x{83F1}\x{FE00}/g;
- s/\x{F959}/\x{9675}\x{FE00}/g;
- s/\x{F95A}/\x{8B80}\x{FE00}/g;
- s/\x{F95B}/\x{62CF}\x{FE00}/g;
- s/\x{F95C}/\x{6A02}\x{FE01}/g;
- s/\x{F95D}/\x{8AFE}\x{FE00}/g;
- s/\x{F95E}/\x{4E39}\x{FE00}/g;
- s/\x{F95F}/\x{5BE7}\x{FE00}/g;
- s/\x{F960}/\x{6012}\x{FE00}/g;
- s/\x{F961}/\x{7387}\x{FE00}/g;
- s/\x{F962}/\x{7570}\x{FE00}/g;
- s/\x{F963}/\x{5317}\x{FE00}/g;
- s/\x{F964}/\x{78FB}\x{FE00}/g;
- s/\x{F965}/\x{4FBF}\x{FE00}/g;
- s/\x{F966}/\x{5FA9}\x{FE00}/g;
- s/\x{F967}/\x{4E0D}\x{FE00}/g;
- s/\x{F968}/\x{6CCC}\x{FE00}/g;
- s/\x{F969}/\x{6578}\x{FE00}/g;
- s/\x{F96A}/\x{7D22}\x{FE00}/g;
- s/\x{F96B}/\x{53C3}\x{FE00}/g;
- s/\x{F96C}/\x{585E}\x{FE00}/g;
- s/\x{F96D}/\x{7701}\x{FE00}/g;
- s/\x{F96E}/\x{8449}\x{FE00}/g;
- s/\x{F96F}/\x{8AAA}\x{FE00}/g;
- s/\x{F970}/\x{6BBA}\x{FE00}/g;
- s/\x{F971}/\x{8FB0}\x{FE00}/g;
- s/\x{F972}/\x{6C88}\x{FE00}/g;
- s/\x{F973}/\x{62FE}\x{FE00}/g;
- s/\x{F974}/\x{82E5}\x{FE00}/g;
- s/\x{F975}/\x{63A0}\x{FE00}/g;
- s/\x{F976}/\x{7565}\x{FE00}/g;
- s/\x{F977}/\x{4EAE}\x{FE00}/g;
- s/\x{F978}/\x{5169}\x{FE00}/g;
- s/\x{F979}/\x{51C9}\x{FE00}/g;
- s/\x{F97A}/\x{6881}\x{FE00}/g;
- s/\x{F97B}/\x{7CE7}\x{FE00}/g;
- s/\x{F97C}/\x{826F}\x{FE00}/g;
- s/\x{F97D}/\x{8AD2}\x{FE00}/g;
- s/\x{F97E}/\x{91CF}\x{FE00}/g;
- s/\x{F97F}/\x{52F5}\x{FE00}/g;
- s/\x{F980}/\x{5442}\x{FE00}/g;
- s/\x{F981}/\x{5973}\x{FE00}/g;
- s/\x{F982}/\x{5EEC}\x{FE00}/g;
- s/\x{F983}/\x{65C5}\x{FE00}/g;
- s/\x{F984}/\x{6FFE}\x{FE00}/g;
- s/\x{F985}/\x{792A}\x{FE00}/g;
- s/\x{F986}/\x{95AD}\x{FE00}/g;
- s/\x{F987}/\x{9A6A}\x{FE00}/g;
- s/\x{F988}/\x{9E97}\x{FE00}/g;
- s/\x{F989}/\x{9ECE}\x{FE00}/g;
- s/\x{F98A}/\x{529B}\x{FE00}/g;
- s/\x{F98B}/\x{66C6}\x{FE00}/g;
- s/\x{F98C}/\x{6B77}\x{FE00}/g;
- s/\x{F98D}/\x{8F62}\x{FE00}/g;
- s/\x{F98E}/\x{5E74}\x{FE00}/g;
- s/\x{F98F}/\x{6190}\x{FE00}/g;
- s/\x{F990}/\x{6200}\x{FE00}/g;
- s/\x{F991}/\x{649A}\x{FE00}/g;
- s/\x{F992}/\x{6F23}\x{FE00}/g;
- s/\x{F993}/\x{7149}\x{FE00}/g;
- s/\x{F994}/\x{7489}\x{FE00}/g;
- s/\x{F995}/\x{79CA}\x{FE00}/g;
- s/\x{F996}/\x{7DF4}\x{FE00}/g;
- s/\x{F997}/\x{806F}\x{FE00}/g;
- s/\x{F998}/\x{8F26}\x{FE00}/g;
- s/\x{F999}/\x{84EE}\x{FE00}/g;
- s/\x{F99A}/\x{9023}\x{FE00}/g;
- s/\x{F99B}/\x{934A}\x{FE00}/g;
- s/\x{F99C}/\x{5217}\x{FE00}/g;
- s/\x{F99D}/\x{52A3}\x{FE00}/g;
- s/\x{F99E}/\x{54BD}\x{FE00}/g;
- s/\x{F99F}/\x{70C8}\x{FE00}/g;
- s/\x{F9A0}/\x{88C2}\x{FE00}/g;
- s/\x{F9A1}/\x{8AAA}\x{FE01}/g;
- s/\x{F9A2}/\x{5EC9}\x{FE00}/g;
- s/\x{F9A3}/\x{5FF5}\x{FE00}/g;
- s/\x{F9A4}/\x{637B}\x{FE00}/g;
- s/\x{F9A5}/\x{6BAE}\x{FE00}/g;
- s/\x{F9A6}/\x{7C3E}\x{FE00}/g;
- s/\x{F9A7}/\x{7375}\x{FE00}/g;
- s/\x{F9A8}/\x{4EE4}\x{FE00}/g;
- s/\x{F9A9}/\x{56F9}\x{FE00}/g;
- s/\x{F9AA}/\x{5BE7}\x{FE01}/g;
- s/\x{F9AB}/\x{5DBA}\x{FE00}/g;
- s/\x{F9AC}/\x{601C}\x{FE00}/g;
- s/\x{F9AD}/\x{73B2}\x{FE00}/g;
- s/\x{F9AE}/\x{7469}\x{FE00}/g;
- s/\x{F9AF}/\x{7F9A}\x{FE00}/g;
- s/\x{F9B0}/\x{8046}\x{FE00}/g;
- s/\x{F9B1}/\x{9234}\x{FE00}/g;
- s/\x{F9B2}/\x{96F6}\x{FE00}/g;
- s/\x{F9B3}/\x{9748}\x{FE00}/g;
- s/\x{F9B4}/\x{9818}\x{FE00}/g;
- s/\x{F9B5}/\x{4F8B}\x{FE00}/g;
- s/\x{F9B6}/\x{79AE}\x{FE00}/g;
- s/\x{F9B7}/\x{91B4}\x{FE00}/g;
- s/\x{F9B8}/\x{96B8}\x{FE00}/g;
- s/\x{F9B9}/\x{60E1}\x{FE00}/g;
- s/\x{F9BA}/\x{4E86}\x{FE00}/g;
- s/\x{F9BB}/\x{50DA}\x{FE00}/g;
- s/\x{F9BC}/\x{5BEE}\x{FE00}/g;
- s/\x{F9BD}/\x{5C3F}\x{FE00}/g;
- s/\x{F9BE}/\x{6599}\x{FE00}/g;
- s/\x{F9BF}/\x{6A02}\x{FE02}/g;
- s/\x{F9C0}/\x{71CE}\x{FE00}/g;
- s/\x{F9C1}/\x{7642}\x{FE00}/g;
- s/\x{F9C2}/\x{84FC}\x{FE00}/g;
- s/\x{F9C3}/\x{907C}\x{FE00}/g;
- s/\x{F9C4}/\x{9F8D}\x{FE00}/g;
- s/\x{F9C5}/\x{6688}\x{FE00}/g;
- s/\x{F9C6}/\x{962E}\x{FE00}/g;
- s/\x{F9C7}/\x{5289}\x{FE00}/g;
- s/\x{F9C8}/\x{677B}\x{FE00}/g;
- s/\x{F9C9}/\x{67F3}\x{FE00}/g;
- s/\x{F9CA}/\x{6D41}\x{FE00}/g;
- s/\x{F9CB}/\x{6E9C}\x{FE00}/g;
- s/\x{F9CC}/\x{7409}\x{FE00}/g;
- s/\x{F9CD}/\x{7559}\x{FE00}/g;
- s/\x{F9CE}/\x{786B}\x{FE00}/g;
- s/\x{F9CF}/\x{7D10}\x{FE00}/g;
- s/\x{F9D0}/\x{985E}\x{FE00}/g;
- s/\x{F9D1}/\x{516D}\x{FE00}/g;
- s/\x{F9D2}/\x{622E}\x{FE00}/g;
- s/\x{F9D3}/\x{9678}\x{FE00}/g;
- s/\x{F9D4}/\x{502B}\x{FE00}/g;
- s/\x{F9D5}/\x{5D19}\x{FE00}/g;
- s/\x{F9D6}/\x{6DEA}\x{FE00}/g;
- s/\x{F9D7}/\x{8F2A}\x{FE00}/g;
- s/\x{F9D8}/\x{5F8B}\x{FE00}/g;
- s/\x{F9D9}/\x{6144}\x{FE00}/g;
- s/\x{F9DA}/\x{6817}\x{FE00}/g;
- s/\x{F9DB}/\x{7387}\x{FE01}/g;
- s/\x{F9DC}/\x{9686}\x{FE00}/g;
- s/\x{F9DD}/\x{5229}\x{FE00}/g;
- s/\x{F9DE}/\x{540F}\x{FE00}/g;
- s/\x{F9DF}/\x{5C65}\x{FE00}/g;
- s/\x{F9E0}/\x{6613}\x{FE00}/g;
- s/\x{F9E1}/\x{674E}\x{FE00}/g;
- s/\x{F9E2}/\x{68A8}\x{FE00}/g;
- s/\x{F9E3}/\x{6CE5}\x{FE00}/g;
- s/\x{F9E4}/\x{7406}\x{FE00}/g;
- s/\x{F9E5}/\x{75E2}\x{FE00}/g;
- s/\x{F9E6}/\x{7F79}\x{FE00}/g;
- s/\x{F9E7}/\x{88CF}\x{FE00}/g;
- s/\x{F9E8}/\x{88E1}\x{FE00}/g;
- s/\x{F9E9}/\x{91CC}\x{FE00}/g;
- s/\x{F9EA}/\x{96E2}\x{FE00}/g;
- s/\x{F9EB}/\x{533F}\x{FE00}/g;
- s/\x{F9EC}/\x{6EBA}\x{FE00}/g;
- s/\x{F9ED}/\x{541D}\x{FE00}/g;
- s/\x{F9EE}/\x{71D0}\x{FE00}/g;
- s/\x{F9EF}/\x{7498}\x{FE00}/g;
- s/\x{F9F0}/\x{85FA}\x{FE00}/g;
- s/\x{F9F1}/\x{96A3}\x{FE00}/g;
- s/\x{F9F2}/\x{9C57}\x{FE00}/g;
- s/\x{F9F3}/\x{9E9F}\x{FE00}/g;
- s/\x{F9F4}/\x{6797}\x{FE00}/g;
- s/\x{F9F5}/\x{6DCB}\x{FE00}/g;
- s/\x{F9F6}/\x{81E8}\x{FE00}/g;
- s/\x{F9F7}/\x{7ACB}\x{FE00}/g;
- s/\x{F9F8}/\x{7B20}\x{FE00}/g;
- s/\x{F9F9}/\x{7C92}\x{FE00}/g;
- s/\x{F9FA}/\x{72C0}\x{FE00}/g;
- s/\x{F9FB}/\x{7099}\x{FE00}/g;
- s/\x{F9FC}/\x{8B58}\x{FE00}/g;
- s/\x{F9FD}/\x{4EC0}\x{FE00}/g;
- s/\x{F9FE}/\x{8336}\x{FE00}/g;
- s/\x{F9FF}/\x{523A}\x{FE00}/g;
- s/\x{FA00}/\x{5207}\x{FE00}/g;
- s/\x{FA01}/\x{5EA6}\x{FE00}/g;
- s/\x{FA02}/\x{62D3}\x{FE00}/g;
- s/\x{FA03}/\x{7CD6}\x{FE00}/g;
- s/\x{FA04}/\x{5B85}\x{FE00}/g;
- s/\x{FA05}/\x{6D1E}\x{FE00}/g;
- s/\x{FA06}/\x{66B4}\x{FE00}/g;
- s/\x{FA07}/\x{8F3B}\x{FE00}/g;
- s/\x{FA08}/\x{884C}\x{FE00}/g;
- s/\x{FA09}/\x{964D}\x{FE00}/g;
- s/\x{FA0A}/\x{898B}\x{FE00}/g;
- s/\x{FA0B}/\x{5ED3}\x{FE00}/g;
- s/\x{FA2E}/\x{90DE}\x{FE00}/g;
- s/\x{FA2F}/\x{96B7}\x{FE00}/g;
-}
-
-sub compose_jamo {
- s/\x{1105}\x{1100}\x{1100}/\x{A965}/g;
- s/\x{1105}\x{1103}\x{1103}/\x{A967}/g;
- s/\x{1105}\x{1107}\x{1107}/\x{A96A}/g;
- s/\x{1105}\x{1107}\x{110B}/\x{A96B}/g;
- s/\x{1107}\x{1107}\x{110B}/\x{112C}/g;
- s/\x{1107}\x{1109}\x{1100}/\x{1122}/g;
- s/\x{1107}\x{1109}\x{1103}/\x{1123}/g;
- s/\x{1107}\x{1109}\x{1107}/\x{1124}/g;
- s/\x{1107}\x{1109}\x{1109}/\x{1125}/g;
- s/\x{1107}\x{1109}\x{110C}/\x{1126}/g;
- s/\x{1107}\x{1109}\x{1110}/\x{A972}/g;
- s/\x{1109}\x{1107}\x{1100}/\x{1133}/g;
- s/\x{1109}\x{1109}\x{1107}/\x{A975}/g;
- s/\x{1109}\x{1109}\x{1109}/\x{1134}/g;
- s/\x{110C}\x{110C}\x{1112}/\x{A978}/g;
- s/\x{1100}\x{1100}/\x{1101}/g;
- s/\x{1100}\x{1103}/\x{115A}/g;
- s/\x{1102}\x{1100}/\x{1113}/g;
- s/\x{1102}\x{1102}/\x{1114}/g;
- s/\x{1102}\x{1103}/\x{1115}/g;
- s/\x{1102}\x{1107}/\x{1116}/g;
- s/\x{1102}\x{1109}/\x{115B}/g;
- s/\x{1102}\x{110C}/\x{115C}/g;
- s/\x{1102}\x{1112}/\x{115D}/g;
- s/\x{1103}\x{1100}/\x{1117}/g;
- s/\x{1103}\x{1103}/\x{1104}/g;
- s/\x{1103}\x{1105}/\x{115E}/g;
- s/\x{1103}\x{1106}/\x{A960}/g;
- s/\x{1103}\x{1107}/\x{A961}/g;
- s/\x{1103}\x{1109}/\x{A962}/g;
- s/\x{1103}\x{110C}/\x{A963}/g;
- s/\x{1105}\x{1100}/\x{A964}/g;
- s/\x{1105}\x{1101}/\x{A965}/g;
- s/\x{1105}\x{1102}/\x{1118}/g;
- s/\x{1105}\x{1103}/\x{A966}/g;
- s/\x{1105}\x{1104}/\x{A967}/g;
- s/\x{1105}\x{1105}/\x{1119}/g;
- s/\x{1105}\x{1106}/\x{A968}/g;
- s/\x{1105}\x{1107}/\x{A969}/g;
- s/\x{1105}\x{1108}/\x{A96A}/g;
- s/\x{1105}\x{1109}/\x{A96C}/g;
- s/\x{1105}\x{110B}/\x{111B}/g;
- s/\x{1105}\x{110C}/\x{A96D}/g;
- s/\x{1105}\x{110F}/\x{A96E}/g;
- s/\x{1105}\x{1112}/\x{111A}/g;
- s/\x{1105}\x{112B}/\x{A96B}/g;
- s/\x{1106}\x{1100}/\x{A96F}/g;
- s/\x{1106}\x{1103}/\x{A970}/g;
- s/\x{1106}\x{1107}/\x{111C}/g;
- s/\x{1106}\x{1109}/\x{A971}/g;
- s/\x{1106}\x{110B}/\x{111D}/g;
- s/\x{1107}\x{1100}/\x{111E}/g;
- s/\x{1107}\x{1102}/\x{111F}/g;
- s/\x{1107}\x{1103}/\x{1120}/g;
- s/\x{1107}\x{1107}/\x{1108}/g;
- s/\x{1107}\x{1109}/\x{1121}/g;
- s/\x{1107}\x{110A}/\x{1125}/g;
- s/\x{1107}\x{110B}/\x{112B}/g;
- s/\x{1107}\x{110C}/\x{1127}/g;
- s/\x{1107}\x{110E}/\x{1128}/g;
- s/\x{1107}\x{110F}/\x{A973}/g;
- s/\x{1107}\x{1110}/\x{1129}/g;
- s/\x{1107}\x{1111}/\x{112A}/g;
- s/\x{1107}\x{1112}/\x{A974}/g;
- s/\x{1107}\x{112B}/\x{112C}/g;
- s/\x{1107}\x{112D}/\x{1122}/g;
- s/\x{1107}\x{112F}/\x{1123}/g;
- s/\x{1107}\x{1132}/\x{1124}/g;
- s/\x{1107}\x{1136}/\x{1126}/g;
- s/\x{1107}\x{1139}/\x{A972}/g;
- s/\x{1108}\x{110B}/\x{112C}/g;
- s/\x{1109}\x{1100}/\x{112D}/g;
- s/\x{1109}\x{1102}/\x{112E}/g;
- s/\x{1109}\x{1103}/\x{112F}/g;
- s/\x{1109}\x{1105}/\x{1130}/g;
- s/\x{1109}\x{1106}/\x{1131}/g;
- s/\x{1109}\x{1107}/\x{1132}/g;
- s/\x{1109}\x{1109}/\x{110A}/g;
- s/\x{1109}\x{110A}/\x{1134}/g;
- s/\x{1109}\x{110B}/\x{1135}/g;
- s/\x{1109}\x{110C}/\x{1136}/g;
- s/\x{1109}\x{110E}/\x{1137}/g;
- s/\x{1109}\x{110F}/\x{1138}/g;
- s/\x{1109}\x{1110}/\x{1139}/g;
- s/\x{1109}\x{1111}/\x{113A}/g;
- s/\x{1109}\x{1112}/\x{113B}/g;
- s/\x{1109}\x{111E}/\x{1133}/g;
- s/\x{1109}\x{1132}/\x{A975}/g;
- s/\x{110A}\x{1107}/\x{A975}/g;
- s/\x{110A}\x{1109}/\x{1134}/g;
- s/\x{110B}\x{1100}/\x{1141}/g;
- s/\x{110B}\x{1103}/\x{1142}/g;
- s/\x{110B}\x{1105}/\x{A976}/g;
- s/\x{110B}\x{1106}/\x{1143}/g;
- s/\x{110B}\x{1107}/\x{1144}/g;
- s/\x{110B}\x{1109}/\x{1145}/g;
- s/\x{110B}\x{110B}/\x{1147}/g;
- s/\x{110B}\x{110C}/\x{1148}/g;
- s/\x{110B}\x{110E}/\x{1149}/g;
- s/\x{110B}\x{1110}/\x{114A}/g;
- s/\x{110B}\x{1111}/\x{114B}/g;
- s/\x{110B}\x{1112}/\x{A977}/g;
- s/\x{110B}\x{1140}/\x{1146}/g;
- s/\x{110C}\x{110B}/\x{114D}/g;
- s/\x{110C}\x{110C}/\x{110D}/g;
- s/\x{110D}\x{1112}/\x{A978}/g;
- s/\x{110E}\x{110F}/\x{1152}/g;
- s/\x{110E}\x{1112}/\x{1153}/g;
- s/\x{1110}\x{1110}/\x{A979}/g;
- s/\x{1111}\x{1107}/\x{1156}/g;
- s/\x{1111}\x{110B}/\x{1157}/g;
- s/\x{1111}\x{1112}/\x{A97A}/g;
- s/\x{1112}\x{1109}/\x{A97B}/g;
- s/\x{1112}\x{1112}/\x{1158}/g;
- s/\x{1121}\x{1100}/\x{1122}/g;
- s/\x{1121}\x{1103}/\x{1123}/g;
- s/\x{1121}\x{1107}/\x{1124}/g;
- s/\x{1121}\x{1109}/\x{1125}/g;
- s/\x{1121}\x{110C}/\x{1126}/g;
- s/\x{1121}\x{1110}/\x{A972}/g;
- s/\x{1132}\x{1100}/\x{1133}/g;
- s/\x{113C}\x{113C}/\x{113D}/g;
- s/\x{113E}\x{113E}/\x{113F}/g;
- s/\x{114E}\x{114E}/\x{114F}/g;
- s/\x{1150}\x{1150}/\x{1151}/g;
- s/\x{1159}\x{1159}/\x{A97C}/g;
- s/\x{A964}\x{1100}/\x{A965}/g;
- s/\x{A966}\x{1103}/\x{A967}/g;
- s/\x{A969}\x{1107}/\x{A96A}/g;
- s/\x{A969}\x{110B}/\x{A96B}/g; # newly added
- s/\x{1169}\x{1161}\x{1175}/\x{116B}/g;
- s/\x{1169}\x{1163}\x{1175}/\x{11A7}/g;
- s/\x{1169}\x{1165}\x{1175}/\x{1180}/g;
- s/\x{1169}\x{1167}\x{1175}/\x{1181}/g;
- s/\x{1169}\x{1169}\x{1175}/\x{D7B1}/g;
- s/\x{116D}\x{1161}\x{1175}/\x{D7B3}/g;
- s/\x{116D}\x{1163}\x{1175}/\x{1185}/g;
- s/\x{116E}\x{1161}\x{1175}/\x{118A}/g;
- s/\x{116E}\x{1165}\x{1173}/\x{118B}/g;
- s/\x{116E}\x{1165}\x{1175}/\x{1170}/g;
- s/\x{116E}\x{1167}\x{1175}/\x{118C}/g;
- s/\x{116E}\x{1175}\x{1175}/\x{D7B6}/g;
- s/\x{1172}\x{1161}\x{1175}/\x{D7B7}/g;
- s/\x{1172}\x{1165}\x{1175}/\x{1190}/g;
- s/\x{1172}\x{1167}\x{1175}/\x{1192}/g;
- s/\x{1173}\x{1165}\x{1175}/\x{D7BB}/g;
- s/\x{1173}\x{1175}\x{116E}/\x{1197}/g;
- s/\x{1175}\x{1163}\x{1169}/\x{D7BD}/g;
- s/\x{1175}\x{1163}\x{1175}/\x{D7BE}/g;
- s/\x{1175}\x{1167}\x{1175}/\x{D7C0}/g;
- s/\x{1175}\x{1169}\x{1175}/\x{D7C1}/g;
- s/\x{119E}\x{1165}\x{1175}/\x{D7C6}/g;
- s/\x{1161}\x{1169}/\x{1176}/g;
- s/\x{1161}\x{116E}/\x{1177}/g;
- s/\x{1161}\x{1173}/\x{11A3}/g;
- s/\x{1161}\x{1175}/\x{1162}/g;
- s/\x{1163}\x{1169}/\x{1178}/g;
- s/\x{1163}\x{116D}/\x{1179}/g;
- s/\x{1163}\x{116E}/\x{11A4}/g;
- s/\x{1163}\x{1175}/\x{1164}/g;
- s/\x{1165}\x{1169}/\x{117A}/g;
- s/\x{1165}\x{116E}/\x{117B}/g;
- s/\x{1165}\x{1173}/\x{117C}/g;
- s/\x{1165}\x{1175}/\x{1166}/g;
- s/\x{1167}\x{1163}/\x{11A5}/g;
- s/\x{1167}\x{1169}/\x{117D}/g;
- s/\x{1167}\x{116E}/\x{117E}/g;
- s/\x{1167}\x{1175}/\x{1168}/g;
- s/\x{1169}\x{1161}/\x{116A}/g;
- s/\x{1169}\x{1162}/\x{116B}/g;
- s/\x{1169}\x{1163}/\x{11A6}/g;
- s/\x{1169}\x{1164}/\x{11A7}/g;
- s/\x{1169}\x{1165}/\x{117F}/g;
- s/\x{1169}\x{1166}/\x{1180}/g;
- s/\x{1169}\x{1167}/\x{D7B0}/g;
- s/\x{1169}\x{1168}/\x{1181}/g;
- s/\x{1169}\x{1169}/\x{1182}/g;
- s/\x{1169}\x{116C}/\x{D7B1}/g;
- s/\x{1169}\x{116E}/\x{1183}/g;
- s/\x{1169}\x{1175}/\x{116C}/g;
- s/\x{116A}\x{1175}/\x{116B}/g;
- s/\x{116D}\x{1161}/\x{D7B2}/g;
- s/\x{116D}\x{1162}/\x{D7B3}/g;
- s/\x{116D}\x{1163}/\x{1184}/g;
- s/\x{116D}\x{1164}/\x{1185}/g;
- s/\x{116D}\x{1165}/\x{D7B4}/g;
- s/\x{116D}\x{1167}/\x{1186}/g;
- s/\x{116D}\x{1169}/\x{1187}/g;
- s/\x{116D}\x{1175}/\x{1188}/g;
- s/\x{116E}\x{1161}/\x{1189}/g;
- s/\x{116E}\x{1162}/\x{118A}/g;
- s/\x{116E}\x{1165}/\x{116F}/g;
- s/\x{116E}\x{1166}/\x{1170}/g;
- s/\x{116E}\x{1167}/\x{D7B5}/g;
- s/\x{116E}\x{1168}/\x{118C}/g;
- s/\x{116E}\x{116E}/\x{118D}/g;
- s/\x{116E}\x{1175}/\x{1171}/g;
- s/\x{116E}\x{117C}/\x{118B}/g;
- s/\x{116E}\x{D7C4}/\x{D7B6}/g;
- s/\x{116F}\x{1173}/\x{118B}/g;
- s/\x{116F}\x{1175}/\x{1170}/g;
- s/\x{1171}\x{1175}/\x{D7B6}/g;
- s/\x{1172}\x{1161}/\x{118E}/g;
- s/\x{1172}\x{1162}/\x{D7B7}/g;
- s/\x{1172}\x{1165}/\x{118F}/g;
- s/\x{1172}\x{1166}/\x{1190}/g;
- s/\x{1172}\x{1167}/\x{1191}/g;
- s/\x{1172}\x{1168}/\x{1192}/g;
- s/\x{1172}\x{1169}/\x{D7B8}/g;
- s/\x{1172}\x{116E}/\x{1193}/g;
- s/\x{1172}\x{1175}/\x{1194}/g;
- s/\x{1173}\x{1161}/\x{D7B9}/g;
- s/\x{1173}\x{1165}/\x{D7BA}/g;
- s/\x{1173}\x{1166}/\x{D7BB}/g;
- s/\x{1173}\x{1169}/\x{D7BC}/g;
- s/\x{1173}\x{116E}/\x{1195}/g;
- s/\x{1173}\x{1173}/\x{1196}/g;
- s/\x{1173}\x{1175}/\x{1174}/g;
- s/\x{1173}\x{119B}/\x{1197}/g;
- s/\x{1174}\x{116E}/\x{1197}/g;
- s/\x{1175}\x{1161}/\x{1198}/g;
- s/\x{1175}\x{1163}/\x{1199}/g;
- s/\x{1175}\x{1164}/\x{D7BE}/g;
- s/\x{1175}\x{1167}/\x{D7BF}/g;
- s/\x{1175}\x{1168}/\x{D7C0}/g;
- s/\x{1175}\x{1169}/\x{119A}/g;
- s/\x{1175}\x{116C}/\x{D7C1}/g;
- s/\x{1175}\x{116D}/\x{D7C2}/g;
- s/\x{1175}\x{116E}/\x{119B}/g;
- s/\x{1175}\x{1172}/\x{D7C3}/g;
- s/\x{1175}\x{1173}/\x{119C}/g;
- s/\x{1175}\x{1175}/\x{D7C4}/g;
- s/\x{1175}\x{1178}/\x{D7BD}/g;
- s/\x{1175}\x{119E}/\x{119D}/g;
- s/\x{117F}\x{1175}/\x{1180}/g;
- s/\x{1182}\x{1175}/\x{D7B1}/g;
- s/\x{1184}\x{1175}/\x{1185}/g;
- s/\x{1189}\x{1175}/\x{118A}/g;
- s/\x{118E}\x{1175}/\x{D7B7}/g; # newly added
- s/\x{118F}\x{1175}/\x{1190}/g;
- s/\x{1191}\x{1175}/\x{1192}/g;
- s/\x{1199}\x{1169}/\x{D7BD}/g;
- s/\x{1199}\x{1175}/\x{D7BE}/g; # newly added
- s/\x{119A}\x{1175}/\x{D7C1}/g;
- s/\x{119E}\x{1161}/\x{D7C5}/g;
- s/\x{119E}\x{1165}/\x{119F}/g;
- s/\x{119E}\x{1166}/\x{D7C6}/g;
- s/\x{119E}\x{116E}/\x{11A0}/g;
- s/\x{119E}\x{1175}/\x{11A1}/g;
- s/\x{119E}\x{119E}/\x{11A2}/g;
- s/\x{119F}\x{1175}/\x{D7C6}/g; # newly added
- s/\x{11A6}\x{1175}/\x{11A7}/g; # newly added
- s/\x{D7B0}\x{1175}/\x{1181}/g; # newly added
- s/\x{D7B2}\x{1175}/\x{D7B3}/g; # newly added
- s/\x{D7B5}\x{1175}/\x{118C}/g; # newly added
- s/\x{D7BA}\x{1175}/\x{D7BB}/g; # newly added
- s/\x{D7BF}\x{1175}/\x{D7C0}/g; # newly added
- s/\x{11A8}\x{11BA}\x{11A8}/\x{11C4}/g;
- s/\x{11AE}\x{11AE}\x{11B8}/\x{D7CE}/g;
- s/\x{11AE}\x{11BA}\x{11A8}/\x{D7D1}/g;
- s/\x{11AF}\x{11A8}\x{11A8}/\x{D7D5}/g;
- s/\x{11AF}\x{11A8}\x{11BA}/\x{11CC}/g;
- s/\x{11AF}\x{11A8}\x{11C2}/\x{D7D6}/g;
- s/\x{11AF}\x{11AE}\x{11C2}/\x{11CF}/g;
- s/\x{11AF}\x{11AF}\x{11BF}/\x{D7D7}/g;
- s/\x{11AF}\x{11B7}\x{11A8}/\x{11D1}/g;
- s/\x{11AF}\x{11B7}\x{11BA}/\x{11D2}/g;
- s/\x{11AF}\x{11B7}\x{11C2}/\x{D7D8}/g;
- s/\x{11AF}\x{11B8}\x{11AE}/\x{D7D9}/g;
- s/\x{11AF}\x{11B8}\x{11BA}/\x{11D3}/g;
- s/\x{11AF}\x{11B8}\x{11BC}/\x{11D5}/g;
- s/\x{11AF}\x{11B8}\x{11C1}/\x{D7DA}/g;
- s/\x{11AF}\x{11B8}\x{11C2}/\x{11D4}/g;
- s/\x{11AF}\x{11BA}\x{11BA}/\x{11D6}/g;
- s/\x{11AF}\x{11F9}\x{11C2}/\x{D7DC}/g;
- s/\x{11B7}\x{11AB}\x{11AB}/\x{D7DF}/g;
- s/\x{11B7}\x{11B8}\x{11BA}/\x{D7E1}/g;
- s/\x{11B7}\x{11BA}\x{11BA}/\x{11DE}/g;
- s/\x{11B8}\x{11AF}\x{11C1}/\x{D7E4}/g;
- s/\x{11B8}\x{11BA}\x{11AE}/\x{D7E7}/g;
- s/\x{11BA}\x{11B8}\x{11BC}/\x{D7EB}/g;
- s/\x{11BA}\x{11BA}\x{11A8}/\x{D7EC}/g;
- s/\x{11BA}\x{11BA}\x{11AE}/\x{D7ED}/g;
- s/\x{11BC}\x{11A8}\x{11A8}/\x{11ED}/g; # legacy enc
- s/\x{11BD}\x{11B8}\x{11B8}/\x{D7F8}/g;
- s/\x{11EB}\x{11B8}\x{11BC}/\x{D7F4}/g;
- s/\x{11F0}\x{11A8}\x{11A8}/\x{11ED}/g;
- s/\x{11A8}\x{11A8}/\x{11A9}/g;
- s/\x{11A8}\x{11AB}/\x{11FA}/g;
- s/\x{11A8}\x{11AF}/\x{11C3}/g;
- s/\x{11A8}\x{11B8}/\x{11FB}/g;
- s/\x{11A8}\x{11BA}/\x{11AA}/g;
- s/\x{11A8}\x{11BE}/\x{11FC}/g;
- s/\x{11A8}\x{11BF}/\x{11FD}/g;
- s/\x{11A8}\x{11C2}/\x{11FE}/g;
- s/\x{11A8}\x{11E7}/\x{11C4}/g;
- s/\x{11AA}\x{11A8}/\x{11C4}/g;
- s/\x{11AB}\x{11A8}/\x{11C5}/g;
- s/\x{11AB}\x{11AB}/\x{11FF}/g;
- s/\x{11AB}\x{11AE}/\x{11C6}/g;
- s/\x{11AB}\x{11AF}/\x{D7CB}/g;
- s/\x{11AB}\x{11BA}/\x{11C7}/g;
- s/\x{11AB}\x{11BD}/\x{11AC}/g;
- s/\x{11AB}\x{11BE}/\x{D7CC}/g;
- s/\x{11AB}\x{11C0}/\x{11C9}/g;
- s/\x{11AB}\x{11C2}/\x{11AD}/g;
- s/\x{11AB}\x{11EB}/\x{11C8}/g;
- s/\x{11AE}\x{11A8}/\x{11CA}/g;
- s/\x{11AE}\x{11AE}/\x{D7CD}/g;
- s/\x{11AE}\x{11AF}/\x{11CB}/g;
- s/\x{11AE}\x{11B8}/\x{D7CF}/g;
- s/\x{11AE}\x{11BA}/\x{D7D0}/g;
- s/\x{11AE}\x{11BD}/\x{D7D2}/g;
- s/\x{11AE}\x{11BE}/\x{D7D3}/g;
- s/\x{11AE}\x{11C0}/\x{D7D4}/g;
- s/\x{11AE}\x{11E7}/\x{D7D1}/g;
- s/\x{11AE}\x{D7CF}/\x{D7CE}/g;
- s/\x{11AF}\x{11A8}/\x{11B0}/g;
- s/\x{11AF}\x{11A9}/\x{D7D5}/g;
- s/\x{11AF}\x{11AA}/\x{11CC}/g;
- s/\x{11AF}\x{11AB}/\x{11CD}/g;
- s/\x{11AF}\x{11AE}/\x{11CE}/g;
- s/\x{11AF}\x{11AF}/\x{11D0}/g;
- s/\x{11AF}\x{11B7}/\x{11B1}/g;
- s/\x{11AF}\x{11B8}/\x{11B2}/g;
- s/\x{11AF}\x{11B9}/\x{11D3}/g;
- s/\x{11AF}\x{11BA}/\x{11B3}/g;
- s/\x{11AF}\x{11BB}/\x{11D6}/g;
- s/\x{11AF}\x{11BC}/\x{D7DD}/g;
- s/\x{11AF}\x{11BF}/\x{11D8}/g;
- s/\x{11AF}\x{11C0}/\x{11B4}/g;
- s/\x{11AF}\x{11C1}/\x{11B5}/g;
- s/\x{11AF}\x{11C2}/\x{11B6}/g;
- s/\x{11AF}\x{11D8}/\x{D7D7}/g;
- s/\x{11AF}\x{11DA}/\x{11D1}/g;
- s/\x{11AF}\x{11DD}/\x{11D2}/g;
- s/\x{11AF}\x{11E1}/\x{D7D8}/g;
- s/\x{11AF}\x{11E4}/\x{D7DA}/g;
- s/\x{11AF}\x{11E5}/\x{11D4}/g;
- s/\x{11AF}\x{11E6}/\x{11D5}/g;
- s/\x{11AF}\x{11EB}/\x{11D7}/g;
- s/\x{11AF}\x{11F0}/\x{D7DB}/g;
- s/\x{11AF}\x{11F9}/\x{11D9}/g;
- s/\x{11AF}\x{11FE}/\x{D7D6}/g;
- s/\x{11AF}\x{D7E3}/\x{D7D9}/g;
- s/\x{11B0}\x{11A8}/\x{D7D5}/g;
- s/\x{11B0}\x{11BA}/\x{11CC}/g;
- s/\x{11B0}\x{11C2}/\x{D7D6}/g;
- s/\x{11B1}\x{11A8}/\x{11D1}/g;
- s/\x{11B1}\x{11BA}/\x{11D2}/g;
- s/\x{11B1}\x{11C2}/\x{D7D8}/g;
- s/\x{11B2}\x{11AE}/\x{D7D9}/g;
- s/\x{11B2}\x{11BA}/\x{11D3}/g;
- s/\x{11B2}\x{11BC}/\x{11D5}/g;
- s/\x{11B2}\x{11C1}/\x{D7DA}/g;
- s/\x{11B2}\x{11C2}/\x{11D4}/g;
- s/\x{11B3}\x{11BA}/\x{11D6}/g;
- s/\x{11B7}\x{11A8}/\x{11DA}/g;
- s/\x{11B7}\x{11AB}/\x{D7DE}/g;
- s/\x{11B7}\x{11AF}/\x{11DB}/g;
- s/\x{11B7}\x{11B7}/\x{D7E0}/g;
- s/\x{11B7}\x{11B8}/\x{11DC}/g;
- s/\x{11B7}\x{11B9}/\x{D7E1}/g;
- s/\x{11B7}\x{11BA}/\x{11DD}/g;
- s/\x{11B7}\x{11BB}/\x{11DE}/g;
- s/\x{11B7}\x{11BC}/\x{11E2}/g;
- s/\x{11B7}\x{11BD}/\x{D7E2}/g;
- s/\x{11B7}\x{11BE}/\x{11E0}/g;
- s/\x{11B7}\x{11C2}/\x{11E1}/g;
- s/\x{11B7}\x{11EB}/\x{11DF}/g;
- s/\x{11B7}\x{11FF}/\x{D7DF}/g;
- s/\x{11B8}\x{11AE}/\x{D7E3}/g;
- s/\x{11B8}\x{11AF}/\x{11E3}/g;
- s/\x{11B8}\x{11B5}/\x{D7E4}/g;
- s/\x{11B8}\x{11B7}/\x{D7E5}/g;
- s/\x{11B8}\x{11B8}/\x{D7E6}/g;
- s/\x{11B8}\x{11BA}/\x{11B9}/g;
- s/\x{11B8}\x{11BC}/\x{11E6}/g;
- s/\x{11B8}\x{11BD}/\x{D7E8}/g;
- s/\x{11B8}\x{11BE}/\x{D7E9}/g;
- s/\x{11B8}\x{11C1}/\x{11E4}/g;
- s/\x{11B8}\x{11C2}/\x{11E5}/g;
- s/\x{11B8}\x{11E8}/\x{D7E7}/g;
- s/\x{11B9}\x{11AE}/\x{D7E7}/g;
- s/\x{11BA}\x{11A8}/\x{11E7}/g;
- s/\x{11BA}\x{11AE}/\x{11E8}/g;
- s/\x{11BA}\x{11AF}/\x{11E9}/g;
- s/\x{11BA}\x{11B7}/\x{D7EA}/g;
- s/\x{11BA}\x{11B8}/\x{11EA}/g;
- s/\x{11BA}\x{11BA}/\x{11BB}/g;
- s/\x{11BA}\x{11BD}/\x{D7EF}/g;
- s/\x{11BA}\x{11BE}/\x{D7F0}/g;
- s/\x{11BA}\x{11C0}/\x{D7F1}/g;
- s/\x{11BA}\x{11C2}/\x{D7F2}/g;
- s/\x{11BA}\x{11E6}/\x{D7EB}/g;
- s/\x{11BA}\x{11E7}/\x{D7EC}/g;
- s/\x{11BA}\x{11E8}/\x{D7ED}/g;
- s/\x{11BA}\x{11EB}/\x{D7EE}/g;
- s/\x{11BB}\x{11A8}/\x{D7EC}/g;
- s/\x{11BB}\x{11AE}/\x{D7ED}/g;
- s/\x{11BC}\x{11A8}/\x{11EC}/g; # legacy enc
- s/\x{11BC}\x{11A9}/\x{11ED}/g; # legacy enc
- s/\x{11BC}\x{11B7}/\x{D7F5}/g; # legacy enc ă…‡ă…(ms)
- s/\x{11BC}\x{11BA}/\x{11F1}/g; # legacy enc ㅇᆺ (ms)
- s/\x{11BC}\x{11BC}/\x{11EE}/g; # legacy enc
- s/\x{11BC}\x{11BF}/\x{11EF}/g; # legacy enc
- s/\x{11BC}\x{11C2}/\x{D7F6}/g; # legacy enc ㅇᇂ (ms)
- s/\x{11BD}\x{11B8}/\x{D7F7}/g;
- s/\x{11BD}\x{11BD}/\x{D7F9}/g;
- s/\x{11BD}\x{D7E6}/\x{D7F8}/g;
- s/\x{11C1}\x{11B8}/\x{11F3}/g;
- s/\x{11C1}\x{11BA}/\x{D7FA}/g;
- s/\x{11C1}\x{11BC}/\x{11F4}/g;
- s/\x{11C1}\x{11C0}/\x{D7FB}/g;
- s/\x{11C2}\x{11AB}/\x{11F5}/g;
- s/\x{11C2}\x{11AF}/\x{11F6}/g;
- s/\x{11C2}\x{11B7}/\x{11F7}/g;
- s/\x{11C2}\x{11B8}/\x{11F8}/g;
- s/\x{11CE}\x{11C2}/\x{11CF}/g;
- s/\x{11D0}\x{11BF}/\x{D7D7}/g;
- s/\x{11D9}\x{11C2}/\x{D7DC}/g;
- s/\x{11DC}\x{11BA}/\x{D7E1}/g;
- s/\x{11DD}\x{11BA}/\x{11DE}/g;
- s/\x{11E3}\x{11C1}/\x{D7E4}/g;
- s/\x{11EA}\x{11BC}/\x{D7EB}/g;
- s/\x{11EB}\x{11B8}/\x{D7F3}/g;
- s/\x{11EB}\x{11E6}/\x{D7F4}/g;
- s/\x{11EC}\x{11A8}/\x{11ED}/g;
- s/\x{11F0}\x{11A8}/\x{11EC}/g;
- s/\x{11F0}\x{11A9}/\x{11ED}/g;
- s/\x{11F0}\x{11B7}/\x{D7F5}/g;
- s/\x{11F0}\x{11BA}/\x{11F1}/g;
- s/\x{11F0}\x{11BF}/\x{11EF}/g;
- s/\x{11F0}\x{11C2}/\x{D7F6}/g;
- s/\x{11F0}\x{11EB}/\x{11F2}/g;
- s/\x{11F0}\x{11F0}/\x{11EE}/g;
- s/\x{D7CD}\x{11B8}/\x{D7CE}/g;
- s/\x{D7D0}\x{11A8}/\x{D7D1}/g;
- s/\x{D7DE}\x{11AB}/\x{D7DF}/g;
- s/\x{D7F3}\x{11BC}/\x{D7F4}/g;
- s/\x{D7F7}\x{11B8}/\x{D7F8}/g;
-}
-
-sub hypuasingle2jamo {
- s/\x{F784}/\x{115F}/g;
- s/\x{F785}/\x{1100}/g;
- s/\x{F786}/\x{1101}/g;
- s/\x{F787}/\x{115A}/g;
- s/\x{F788}/\x{1102}/g;
- s/\x{F789}/\x{1113}/g;
- s/\x{F78A}/\x{1114}/g;
- s/\x{F78B}/\x{1115}/g;
- s/\x{F78C}/\x{1116}/g;
- s/\x{F78D}/\x{115B}/g;
- s/\x{F78E}/\x{115C}/g;
- s/\x{F78F}/\x{115D}/g;
- s/\x{F790}/\x{1103}/g;
- s/\x{F791}/\x{1117}/g;
- s/\x{F792}/\x{1104}/g;
- s/\x{F793}/\x{115E}/g;
- s/\x{F794}/\x{A960}/g;
- s/\x{F795}/\x{A961}/g;
- s/\x{F796}/\x{A962}/g;
- s/\x{F797}/\x{A963}/g;
- s/\x{F798}/\x{1105}/g;
- s/\x{F799}/\x{A964}/g;
- s/\x{F79A}/\x{A965}/g;
- s/\x{F79B}/\x{1118}/g;
- s/\x{F79C}/\x{A966}/g;
- s/\x{F79D}/\x{A967}/g;
- s/\x{F79E}/\x{1119}/g;
- s/\x{F79F}/\x{A968}/g;
- s/\x{F7A0}/\x{A969}/g;
- s/\x{F7A1}/\x{A96A}/g;
- s/\x{F7A2}/\x{A96B}/g;
- s/\x{F7A3}/\x{A96C}/g;
- s/\x{F7A4}/\x{A96D}/g;
- s/\x{F7A5}/\x{A96E}/g;
- s/\x{F7A6}/\x{111A}/g;
- s/\x{F7A7}/\x{111B}/g;
- s/\x{F7A8}/\x{1106}/g;
- s/\x{F7A9}/\x{A96F}/g;
- s/\x{F7AA}/\x{A970}/g;
- s/\x{F7AB}/\x{111C}/g;
- s/\x{F7AC}/\x{A971}/g;
- s/\x{F7AD}/\x{111D}/g;
- s/\x{F7AE}/\x{1107}/g;
- s/\x{F7AF}/\x{111E}/g;
- s/\x{F7B0}/\x{111F}/g;
- s/\x{F7B1}/\x{1120}/g;
- s/\x{F7B2}/\x{1108}/g;
- s/\x{F7B3}/\x{1121}/g;
- s/\x{F7B4}/\x{1122}/g;
- s/\x{F7B5}/\x{1123}/g;
- s/\x{F7B6}/\x{1124}/g;
- s/\x{F7B7}/\x{1125}/g;
- s/\x{F7B8}/\x{1126}/g;
- s/\x{F7B9}/\x{A972}/g;
- s/\x{F7BA}/\x{1127}/g;
- s/\x{F7BB}/\x{1128}/g;
- s/\x{F7BC}/\x{A973}/g;
- s/\x{F7BD}/\x{1129}/g;
- s/\x{F7BE}/\x{112A}/g;
- s/\x{F7BF}/\x{A974}/g;
- s/\x{F7C0}/\x{112B}/g;
- s/\x{F7C1}/\x{112C}/g;
- s/\x{F7C2}/\x{1109}/g;
- s/\x{F7C3}/\x{112D}/g;
- s/\x{F7C4}/\x{112E}/g;
- s/\x{F7C5}/\x{112F}/g;
- s/\x{F7C6}/\x{1130}/g;
- s/\x{F7C7}/\x{1131}/g;
- s/\x{F7C8}/\x{1132}/g;
- s/\x{F7C9}/\x{1133}/g;
- s/\x{F7CA}/\x{110A}/g;
- s/\x{F7CB}/\x{A975}/g;
- s/\x{F7CC}/\x{1134}/g;
- s/\x{F7CD}/\x{1135}/g;
- s/\x{F7CE}/\x{1136}/g;
- s/\x{F7CF}/\x{1137}/g;
- s/\x{F7D0}/\x{1138}/g;
- s/\x{F7D1}/\x{1139}/g;
- s/\x{F7D2}/\x{113A}/g;
- s/\x{F7D3}/\x{113B}/g;
- s/\x{F7D4}/\x{113C}/g;
- s/\x{F7D5}/\x{113D}/g;
- s/\x{F7D6}/\x{113E}/g;
- s/\x{F7D7}/\x{113F}/g;
- s/\x{F7D8}/\x{1140}/g;
- s/\x{F7D9}/\x{110B}/g;
- s/\x{F7DA}/\x{1141}/g;
- s/\x{F7DB}/\x{1142}/g;
- s/\x{F7DC}/\x{A976}/g;
- s/\x{F7DD}/\x{1143}/g;
- s/\x{F7DE}/\x{1144}/g;
- s/\x{F7DF}/\x{1145}/g;
- s/\x{F7E0}/\x{1146}/g;
- s/\x{F7E1}/\x{1147}/g;
- s/\x{F7E2}/\x{1148}/g;
- s/\x{F7E3}/\x{1149}/g;
- s/\x{F7E4}/\x{114A}/g;
- s/\x{F7E5}/\x{114B}/g;
- s/\x{F7E6}/\x{A977}/g;
- s/\x{F7E7}/\x{114C}/g;
- s/\x{F7E8}/\x{110C}/g;
- s/\x{F7E9}/\x{114D}/g;
- s/\x{F7EA}/\x{110D}/g;
- s/\x{F7EB}/\x{A978}/g;
- s/\x{F7EC}/\x{114E}/g;
- s/\x{F7ED}/\x{114F}/g;
- s/\x{F7EE}/\x{1150}/g;
- s/\x{F7EF}/\x{1151}/g;
- s/\x{F7F0}/\x{110E}/g;
- s/\x{F7F1}/\x{1152}/g;
- s/\x{F7F2}/\x{1153}/g;
- s/\x{F7F3}/\x{1154}/g;
- s/\x{F7F4}/\x{1155}/g;
- s/\x{F7F5}/\x{110F}/g;
- s/\x{F7F6}/\x{1110}/g;
- s/\x{F7F7}/\x{A979}/g;
- s/\x{F7F8}/\x{1111}/g;
- s/\x{F7F9}/\x{1156}/g;
- s/\x{F7FA}/\x{A97A}/g;
- s/\x{F7FB}/\x{1157}/g;
- s/\x{F7FC}/\x{1112}/g;
- s/\x{F7FD}/\x{A97B}/g;
- s/\x{F7FE}/\x{1158}/g;
- s/\x{F7FF}/\x{1159}/g;
- s/\x{F800}/\x{A97C}/g;
- s/\x{F806}/\x{1160}/g;
- s/\x{F807}/\x{1161}/g;
- s/\x{F808}/\x{1176}/g;
- s/\x{F809}/\x{1177}/g;
- s/\x{F80A}/\x{11A3}/g;
- s/\x{F80B}/\x{1162}/g;
- s/\x{F80C}/\x{1163}/g;
- s/\x{F80D}/\x{1178}/g;
- s/\x{F80E}/\x{1179}/g;
- s/\x{F80F}/\x{11A4}/g;
- s/\x{F810}/\x{1164}/g;
- s/\x{F811}/\x{1165}/g;
- s/\x{F812}/\x{117A}/g;
- s/\x{F813}/\x{117B}/g;
- s/\x{F814}/\x{117C}/g;
- s/\x{F815}/\x{1166}/g;
- s/\x{F816}/\x{1167}/g;
- s/\x{F817}/\x{11A5}/g;
- s/\x{F818}/\x{117D}/g;
- s/\x{F819}/\x{117E}/g;
- s/\x{F81A}/\x{1168}/g;
- s/\x{F81B}/\x{1169}/g;
- s/\x{F81C}/\x{116A}/g;
- s/\x{F81D}/\x{116B}/g;
- s/\x{F81E}/\x{11A6}/g;
- s/\x{F81F}/\x{11A7}/g;
- s/\x{F820}/\x{117F}/g;
- s/\x{F821}/\x{1180}/g;
- s/\x{F822}/\x{D7B0}/g;
- s/\x{F823}/\x{1181}/g;
- s/\x{F824}/\x{1182}/g;
- s/\x{F825}/\x{D7B1}/g;
- s/\x{F826}/\x{1183}/g;
- s/\x{F827}/\x{116C}/g;
- s/\x{F828}/\x{116D}/g;
- s/\x{F829}/\x{D7B2}/g;
- s/\x{F82A}/\x{D7B3}/g;
- s/\x{F82B}/\x{1184}/g;
- s/\x{F82C}/\x{1185}/g;
- s/\x{F82D}/\x{D7B4}/g;
- s/\x{F82E}/\x{1186}/g;
- s/\x{F82F}/\x{1187}/g;
- s/\x{F830}/\x{1188}/g;
- s/\x{F831}/\x{116E}/g;
- s/\x{F832}/\x{1189}/g;
- s/\x{F833}/\x{118A}/g;
- s/\x{F834}/\x{116F}/g;
- s/\x{F835}/\x{118B}/g;
- s/\x{F836}/\x{1170}/g;
- s/\x{F837}/\x{D7B5}/g;
- s/\x{F838}/\x{118C}/g;
- s/\x{F839}/\x{118D}/g;
- s/\x{F83A}/\x{1171}/g;
- s/\x{F83B}/\x{D7B6}/g;
- s/\x{F83C}/\x{1172}/g;
- s/\x{F83D}/\x{118E}/g;
- s/\x{F83E}/\x{D7B7}/g;
- s/\x{F83F}/\x{118F}/g;
- s/\x{F840}/\x{1190}/g;
- s/\x{F841}/\x{1191}/g;
- s/\x{F842}/\x{1192}/g;
- s/\x{F843}/\x{D7B8}/g;
- s/\x{F844}/\x{1193}/g;
- s/\x{F845}/\x{1194}/g;
- s/\x{F846}/\x{1173}/g;
- s/\x{F847}/\x{D7B9}/g;
- s/\x{F848}/\x{D7BA}/g;
- s/\x{F849}/\x{D7BB}/g;
- s/\x{F84A}/\x{D7BC}/g;
- s/\x{F84B}/\x{1195}/g;
- s/\x{F84C}/\x{1196}/g;
- s/\x{F84D}/\x{1174}/g;
- s/\x{F84E}/\x{1197}/g;
- s/\x{F84F}/\x{1175}/g;
- s/\x{F850}/\x{1198}/g;
- s/\x{F851}/\x{1199}/g;
- s/\x{F852}/\x{D7BD}/g;
- s/\x{F853}/\x{D7BE}/g;
- s/\x{F854}/\x{D7BF}/g;
- s/\x{F855}/\x{D7C0}/g;
- s/\x{F856}/\x{119A}/g;
- s/\x{F857}/\x{D7C1}/g;
- s/\x{F858}/\x{D7C2}/g;
- s/\x{F859}/\x{119B}/g;
- s/\x{F85A}/\x{D7C3}/g;
- s/\x{F85B}/\x{119C}/g;
- s/\x{F85C}/\x{D7C4}/g;
- s/\x{F85D}/\x{119D}/g;
- s/\x{F85E}/\x{119E}/g;
- s/\x{F85F}/\x{D7C5}/g;
- s/\x{F860}/\x{119F}/g;
- s/\x{F861}/\x{D7C6}/g;
- s/\x{F862}/\x{11A0}/g;
- s/\x{F863}/\x{11A1}/g;
- s/\x{F864}/\x{11A2}/g;
- s/\x{F86A}//g;
- s/\x{F86B}/\x{11A8}/g;
- s/\x{F86C}/\x{11A9}/g;
- s/\x{F86D}/\x{11FA}/g;
- s/\x{F86E}/\x{11C3}/g;
- s/\x{F86F}/\x{11FB}/g;
- s/\x{F870}/\x{11AA}/g;
- s/\x{F871}/\x{11C4}/g;
- s/\x{F872}/\x{11FC}/g;
- s/\x{F873}/\x{11FD}/g;
- s/\x{F874}/\x{11FE}/g;
- s/\x{F875}/\x{11AB}/g;
- s/\x{F876}/\x{11C5}/g;
- s/\x{F877}/\x{11FF}/g;
- s/\x{F878}/\x{11C6}/g;
- s/\x{F879}/\x{D7CB}/g;
- s/\x{F87A}/\x{11C7}/g;
- s/\x{F87B}/\x{11C8}/g;
- s/\x{F87C}/\x{11AC}/g;
- s/\x{F87D}/\x{D7CC}/g;
- s/\x{F87E}/\x{11C9}/g;
- s/\x{F87F}/\x{11AD}/g;
- s/\x{F880}/\x{11AE}/g;
- s/\x{F881}/\x{11CA}/g;
- s/\x{F882}/\x{D7CD}/g;
- s/\x{F883}/\x{D7CE}/g;
- s/\x{F884}/\x{11CB}/g;
- s/\x{F885}/\x{D7CF}/g;
- s/\x{F886}/\x{D7D0}/g;
- s/\x{F887}/\x{D7D1}/g;
- s/\x{F888}/\x{D7D2}/g;
- s/\x{F889}/\x{D7D3}/g;
- s/\x{F88A}/\x{D7D4}/g;
- s/\x{F88B}/\x{11AF}/g;
- s/\x{F88C}/\x{11B0}/g;
- s/\x{F88D}/\x{D7D5}/g;
- s/\x{F88E}/\x{11CC}/g;
- s/\x{F88F}/\x{D7D6}/g;
- s/\x{F890}/\x{11CD}/g;
- s/\x{F891}/\x{11CE}/g;
- s/\x{F892}/\x{11CF}/g;
- s/\x{F893}/\x{11D0}/g;
- s/\x{F894}/\x{D7D7}/g;
- s/\x{F895}/\x{11B1}/g;
- s/\x{F896}/\x{11D1}/g;
- s/\x{F897}/\x{11D2}/g;
- s/\x{F898}/\x{D7D8}/g;
- s/\x{F899}/\x{11B2}/g;
- s/\x{F89A}/\x{D7D9}/g;
- s/\x{F89B}/\x{11D3}/g;
- s/\x{F89C}/\x{D7DA}/g;
- s/\x{F89D}/\x{11D4}/g;
- s/\x{F89E}/\x{11D5}/g;
- s/\x{F89F}/\x{11B3}/g;
- s/\x{F8A0}/\x{11D6}/g;
- s/\x{F8A1}/\x{11D7}/g;
- s/\x{F8A2}/\x{D7DB}/g;
- s/\x{F8A3}/\x{11D8}/g;
- s/\x{F8A4}/\x{11B4}/g;
- s/\x{F8A5}/\x{11B5}/g;
- s/\x{F8A6}/\x{11B6}/g;
- s/\x{F8A7}/\x{11D9}/g;
- s/\x{F8A8}/\x{D7DC}/g;
- s/\x{F8A9}/\x{D7DD}/g;
- s/\x{F8AA}/\x{11B7}/g;
- s/\x{F8AB}/\x{11DA}/g;
- s/\x{F8AC}/\x{D7DE}/g;
- s/\x{F8AD}/\x{D7DF}/g;
- s/\x{F8AE}/\x{11DB}/g;
- s/\x{F8AF}/\x{D7E0}/g;
- s/\x{F8B0}/\x{11DC}/g;
- s/\x{F8B1}/\x{D7E1}/g;
- s/\x{F8B2}/\x{11DD}/g;
- s/\x{F8B3}/\x{11DE}/g;
- s/\x{F8B4}/\x{11DF}/g;
- s/\x{F8B5}/\x{D7E2}/g;
- s/\x{F8B6}/\x{11E0}/g;
- s/\x{F8B7}/\x{11E1}/g;
- s/\x{F8B8}/\x{11E2}/g;
- s/\x{F8B9}/\x{11B8}/g;
- s/\x{F8BA}/\x{D7E3}/g;
- s/\x{F8BB}/\x{11E3}/g;
- s/\x{F8BC}/\x{D7E4}/g;
- s/\x{F8BD}/\x{D7E5}/g;
- s/\x{F8BE}/\x{D7E6}/g;
- s/\x{F8BF}/\x{11B9}/g;
- s/\x{F8C0}/\x{D7E7}/g;
- s/\x{F8C1}/\x{D7E8}/g;
- s/\x{F8C2}/\x{D7E9}/g;
- s/\x{F8C3}/\x{11E4}/g;
- s/\x{F8C4}/\x{11E5}/g;
- s/\x{F8C5}/\x{11E6}/g;
- s/\x{F8C6}/\x{11BA}/g;
- s/\x{F8C7}/\x{11E7}/g;
- s/\x{F8C8}/\x{11E8}/g;
- s/\x{F8C9}/\x{11E9}/g;
- s/\x{F8CA}/\x{D7EA}/g;
- s/\x{F8CB}/\x{11EA}/g;
- s/\x{F8CC}/\x{D7EB}/g;
- s/\x{F8CD}/\x{11BB}/g;
- s/\x{F8CE}/\x{D7EC}/g;
- s/\x{F8CF}/\x{D7ED}/g;
- s/\x{F8D0}/\x{D7EE}/g;
- s/\x{F8D1}/\x{D7EF}/g;
- s/\x{F8D2}/\x{D7F0}/g;
- s/\x{F8D3}/\x{D7F1}/g;
- s/\x{F8D4}/\x{D7F2}/g;
- s/\x{F8D5}/\x{11EB}/g;
- s/\x{F8D6}/\x{D7F3}/g;
- s/\x{F8D7}/\x{D7F4}/g;
- s/\x{F8D8}/\x{11BC}/g;
- s/\x{F8D9}/\x{11EC}/g;
- s/\x{F8DA}/\x{11ED}/g;
- s/\x{F8DB}/\x{D7F5}/g;
- s/\x{F8DC}/\x{11F1}/g;
- s/\x{F8DD}/\x{11EE}/g;
- s/\x{F8DE}/\x{11EF}/g;
- s/\x{F8DF}/\x{D7F6}/g;
- s/\x{F8E0}/\x{11F0}/g;
- s/\x{F8E1}/\x{11EC}/g;
- s/\x{F8E2}/\x{11F1}/g;
- s/\x{F8E3}/\x{11F2}/g;
- s/\x{F8E4}/\x{11EF}/g;
- s/\x{F8E5}/\x{D7F6}/g;
- s/\x{F8E6}/\x{11BD}/g;
- s/\x{F8E7}/\x{D7F7}/g;
- s/\x{F8E8}/\x{D7F8}/g;
- s/\x{F8E9}/\x{D7F9}/g;
- s/\x{F8EA}/\x{11BE}/g;
- s/\x{F8EB}/\x{11BF}/g;
- s/\x{F8EC}/\x{11C0}/g;
- s/\x{F8ED}/\x{11C1}/g;
- s/\x{F8EE}/\x{11F3}/g;
- s/\x{F8EF}/\x{D7FA}/g;
- s/\x{F8F0}/\x{D7FB}/g;
- s/\x{F8F1}/\x{11F4}/g;
- s/\x{F8F2}/\x{11C2}/g;
- s/\x{F8F3}/\x{11F5}/g;
- s/\x{F8F4}/\x{11F6}/g;
- s/\x{F8F5}/\x{11F7}/g;
- s/\x{F8F6}/\x{11F8}/g;
- s/\x{F8F7}/\x{11F9}/g;
-}
-
-sub arr_hypua2jamo {
- return (
- [ 0xE0BC, 0x115F,0x1161,0x11AE ],
- [ 0xE0BD, 0x115F,0x1161,0xD7CD ],
- [ 0xE0BE, 0x115F,0x1161,0x11AF ],
- [ 0xE0BF, 0x115F,0x1161,0x11B0 ],
- [ 0xE0C0, 0x115F,0x1161,0x11B1 ],
- [ 0xE0C1, 0x115F,0x1161,0x11B2 ],
- [ 0xE0C2, 0x115F,0x1161,0x11BA ],
- [ 0xE0C3, 0x115F,0x1161,0x11BB ],
- [ 0xE0C4, 0x115F,0x1161,0x11BD ],
- [ 0xE0C5, 0x115F,0x1161,0xD7F9 ],
- [ 0xE0C7, 0x115F,0x11A3,0x11AE ],
- [ 0xE0C8, 0x115F,0x1163,0x11AB ],
- [ 0xE0C9, 0x115F,0x1165,0x11AF ],
- [ 0xE0CA, 0x115F,0x1165,0x11B8 ],
- [ 0xE0CB, 0x115F,0x116E,0x11AB ],
- [ 0xE0CC, 0x115F,0x1175,0x11A8 ],
- [ 0xE0CD, 0x115F,0x1175,0x11AB ],
- [ 0xE0CE, 0x115F,0x1175,0x11AF ],
- [ 0xE0CF, 0x115F,0x1175,0x11BA ],
- [ 0xE0D0, 0x115F,0x1175,0x11BC ],
- [ 0xE0D1, 0x115F,0x119E,0x11AF ],
- [ 0xE0D2, 0x1100,0x1161,0x11FF ],
- [ 0xE0D3, 0x1100,0x1161,0x11C7 ],
- [ 0xE0D4, 0x1100,0x1161,0x11CA ],
- [ 0xE0D5, 0x1100,0x1161,0x11CD ],
- [ 0xE0D6, 0x1100,0x1161,0x11CE ],
- [ 0xE0D7, 0x1100,0x1161,0x11D0 ],
- [ 0xE0D8, 0x1100,0x1161,0xD7DB ],
- [ 0xE0D9, 0x1100,0x1161,0x11D9 ],
- [ 0xE0DA, 0x1100,0x1161,0x11DD ],
- [ 0xE0DB, 0x1100,0x1161,0x11E1 ],
- [ 0xE0DC, 0x1100,0x1161,0x11E2 ],
- [ 0xE0DD, 0x1100,0x1161,0x11E4 ],
- [ 0xE0DE, 0x1100,0x1161,0x11E5 ],
- [ 0xE0DF, 0x1100,0x1161,0x11E6 ],
- [ 0xE0E0, 0x1100,0x1161,0x11E7 ],
- [ 0xE0E1, 0x1100,0x1161,0x11EA ],
- [ 0xE0E2, 0x1100,0x1161,0xD7F0 ],
- [ 0xE0E3, 0x1100,0x1161,0xD7F1 ],
- [ 0xE0E4, 0x1100,0x1161,0x11EB ],
- [ 0xE0E5, 0x1100,0x1161,0x11F1 ],
- [ 0xE0E6, 0x1100,0x1161,0x11F0 ],
- [ 0xE0E7, 0x1100,0x1161,0x11F1 ],
- [ 0xE0E8, 0x1100,0x1161,0x11F9 ],
- [ 0xE0EB, 0x1100,0x1162,0x11CD ],
- [ 0xE0EC, 0x1100,0x1162,0xD7DB ],
- [ 0xE0ED, 0x1100,0x1162,0x11F0 ],
- [ 0xE0EE, 0x1100,0x1163,0x11E2 ],
- [ 0xE0EF, 0x1100,0x1163,0x11E6 ],
- [ 0xE0F0, 0x1100,0x1163,0x11F0 ],
- [ 0xE0F1, 0x1100,0x1163,0x11F9 ],
- [ 0xE0F3, 0x1100,0x1165,0x11C7 ],
- [ 0xE0F4, 0x1100,0x1165,0x11D0 ],
- [ 0xE0F5, 0x1100,0x1165,0x11D9 ],
- [ 0xE0F6, 0x1100,0x1165,0x11DD ],
- [ 0xE0F7, 0x1100,0x1165,0x11E2 ],
- [ 0xE0F8, 0x1100,0x1165,0x11E3 ],
- [ 0xE0F9, 0x1100,0x1165,0x11E6 ],
- [ 0xE0FA, 0x1100,0x1165,0x11E7 ],
- [ 0xE0FB, 0x1100,0x1165,0xD7F0 ],
- [ 0xE0FC, 0x1100,0x1165,0xD7F2 ],
- [ 0xE0FD, 0x1100,0x1165,0x11EB ],
- [ 0xE0FE, 0x1100,0x1165,0x11F0 ],
- [ 0xE0FF, 0x1100,0x1165,0x11F9 ],
- [ 0xE101, 0x1100,0x117C,0x11AB ],
- [ 0xE102, 0x1100,0x117C,0x11AF ],
- [ 0xE103, 0x1100,0x117C,0x11B7 ],
- [ 0xE104, 0x1100,0x1166,0x11F0 ],
- [ 0xE105, 0x1100,0x1167,0xD7D4 ],
- [ 0xE106, 0x1100,0x1167,0x11D9 ],
- [ 0xE107, 0x1100,0x1167,0x11E2 ],
- [ 0xE108, 0x1100,0x1167,0xD7E9 ],
- [ 0xE109, 0x1100,0x1167,0x11E7 ],
- [ 0xE10A, 0x1100,0x1167,0xD7F0 ],
- [ 0xE10B, 0x1100,0x1167,0xD7F1 ],
- [ 0xE10C, 0x1100,0x1167,0xD7F2 ],
- [ 0xE10D, 0x1100,0x1167,0x11EB ],
- [ 0xE10E, 0x1100,0x1167,0x11F0 ],
- [ 0xE10F, 0x1100,0x1167,0x11F1 ],
- [ 0xE110, 0x1100,0x1167,0x11F9 ],
- [ 0xE111, 0x1100,0x1168,0x11F0 ],
- [ 0xE112, 0x1100,0x1169,0x11D0 ],
- [ 0xE113, 0x1100,0x1169,0xD7DA ],
- [ 0xE114, 0x1100,0x1169,0x11D6 ],
- [ 0xE115, 0x1100,0x1169,0x11D9 ],
- [ 0xE116, 0x1100,0x1169,0x11DA ],
- [ 0xE117, 0x1100,0x1169,0x11DD ],
- [ 0xE118, 0x1100,0x1169,0x11E2 ],
- [ 0xE119, 0x1100,0x1169,0x11E6 ],
- [ 0xE11A, 0x1100,0x1169,0xD7F0 ],
- [ 0xE11B, 0x1100,0x1169,0x11EB ],
- [ 0xE11C, 0x1100,0x1169,0x11F0 ],
- [ 0xE11D, 0x1100,0x1169,0x11F1 ],
- [ 0xE11E, 0x1100,0x1169,0x11F7 ],
- [ 0xE11F, 0x1100,0x1169,0x11F8 ],
- [ 0xE120, 0x1100,0x116A,0x11C7 ],
- [ 0xE121, 0x1100,0x116A,0x11D9 ],
- [ 0xE122, 0x1100,0x116A,0x11F0 ],
- [ 0xE123, 0x1100,0x116A,0x11F9 ],
- [ 0xE125, 0x1100,0x11A6,0x11BC ],
- [ 0xE127, 0x1100,0x117F,0x11AB ],
- [ 0xE128, 0x1100,0x117F,0x11AF ],
- [ 0xE12A, 0x1100,0x1182,0x11AF ],
- [ 0xE12B, 0x1100,0x116C,0x11F0 ],
- [ 0xE12C, 0x1100,0x116D,0x11D9 ],
- [ 0xE12D, 0x1100,0x116D,0x11E2 ],
- [ 0xE12E, 0x1100,0x116D,0x11F0 ],
- [ 0xE131, 0x1100,0xD7B3,0x11AF ],
- [ 0xE134, 0x1100,0x1185,0x11AF ],
- [ 0xE135, 0x1100,0x1185,0x11B0 ],
- [ 0xE137, 0x1100,0x1188,0x11AB ],
- [ 0xE138, 0x1100,0x116E,0x11FD ],
- [ 0xE139, 0x1100,0x116E,0x11C7 ],
- [ 0xE13A, 0x1100,0x116E,0x11CD ],
- [ 0xE13B, 0x1100,0x116E,0x11D0 ],
- [ 0xE13C, 0x1100,0x116E,0x11D9 ],
- [ 0xE13D, 0x1100,0x116E,0x11DA ],
- [ 0xE13E, 0x1100,0x116E,0x11DD ],
- [ 0xE13F, 0x1100,0x116E,0x11E2 ],
- [ 0xE140, 0x1100,0x116E,0x11E6 ],
- [ 0xE141, 0x1100,0x116E,0x11EC ],
- [ 0xE142, 0x1100,0x116E,0x11F0 ],
- [ 0xE143, 0x1100,0x116E,0x11EC ],
- [ 0xE144, 0x1100,0x116E,0x11F6 ],
- [ 0xE145, 0x1100,0x116E,0x11F9 ],
- [ 0xE147, 0x1100,0x1189,0x11AB ],
- [ 0xE148, 0x1100,0x1189,0x11B7 ],
- [ 0xE149, 0x1100,0x1189,0x11BC ],
- [ 0xE14B, 0x1100,0x116F,0x11C7 ],
- [ 0xE14C, 0x1100,0x116F,0x11D9 ],
- [ 0xE14D, 0x1100,0x116F,0x11F9 ],
- [ 0xE14F, 0x1100,0x118B,0x11AB ],
- [ 0xE153, 0x1100,0x118D,0x11AF ],
- [ 0xE154, 0x1100,0x1171,0x11F0 ],
- [ 0xE155, 0x1100,0x1171,0x11F9 ],
- [ 0xE156, 0x1100,0x1172,0x11D9 ],
- [ 0xE157, 0x1100,0x1172,0x11E2 ],
- [ 0xE158, 0x1100,0x1172,0x11F0 ],
- [ 0xE159, 0x1100,0x1172,0x11F9 ],
- [ 0xE15B, 0x1100,0x118E,0x11AB ],
- [ 0xE15D, 0x1100,0x118F,0x11AB ],
- [ 0xE15F, 0x1100,0x1191,0x11A8 ],
- [ 0xE160, 0x1100,0x1191,0x11AB ],
- [ 0xE161, 0x1100,0x1191,0x11AF ],
- [ 0xE162, 0x1100,0x1191,0x11D9 ],
- [ 0xE163, 0x1100,0x1191,0x11BC ],
- [ 0xE164, 0x1100,0x1191,0x11F0 ],
- [ 0xE165, 0x1100,0x1191,0x11F9 ],
- [ 0xE167, 0x1100,0x1192,0x11AF ],
- [ 0xE168, 0x1100,0x1192,0x11B0 ],
- [ 0xE169, 0x1100,0x1192,0x11BC ],
- [ 0xE16B, 0x1100,0x1194,0x11A8 ],
- [ 0xE16C, 0x1100,0x1194,0x11AF ],
- [ 0xE16D, 0x1100,0x1194,0x11D9 ],
- [ 0xE16E, 0x1100,0x1194,0x11BC ],
- [ 0xE16F, 0x1100,0x1194,0x11F0 ],
- [ 0xE170, 0x1100,0x1173,0x11C7 ],
- [ 0xE171, 0x1100,0x1173,0xD7CC ],
- [ 0xE172, 0x1100,0x1173,0x11C9 ],
- [ 0xE173, 0x1100,0x1173,0xD7D3 ],
- [ 0xE174, 0x1100,0x1173,0xD7D4 ],
- [ 0xE175, 0x1100,0x1173,0x11CD ],
- [ 0xE176, 0x1100,0x1173,0x11D0 ],
- [ 0xE177, 0x1100,0x1173,0x11D9 ],
- [ 0xE178, 0x1100,0x1173,0x11DA ],
- [ 0xE179, 0x1100,0x1173,0x11DD ],
- [ 0xE17A, 0x1100,0x1173,0x11DF ],
- [ 0xE17B, 0x1100,0x1173,0x11E1 ],
- [ 0xE17C, 0x1100,0x1173,0x11E2 ],
- [ 0xE17D, 0x1100,0x1173,0xD7F0 ],
- [ 0xE17E, 0x1100,0x1173,0x11EB ],
- [ 0xE17F, 0x1100,0x1173,0x11F0 ],
- [ 0xE180, 0x1100,0x1173,0x11F9 ],
- [ 0xE185, 0x1100,0x1174,0x11D9 ],
- [ 0xE186, 0x1100,0x1174,0x11F9 ],
- [ 0xE187, 0x1100,0x1175,0x11CA ],
- [ 0xE188, 0x1100,0x1175,0xD7CD ],
- [ 0xE189, 0x1100,0x1175,0x11CD ],
- [ 0xE18A, 0x1100,0x1175,0x11D0 ],
- [ 0xE18B, 0x1100,0x1175,0x11D9 ],
- [ 0xE18C, 0x1100,0x1175,0xD7DC ],
- [ 0xE18D, 0x1100,0x1175,0x11E0 ],
- [ 0xE18E, 0x1100,0x1175,0x11E2 ],
- [ 0xE18F, 0x1100,0x1175,0xD7E6 ],
- [ 0xE190, 0x1100,0x1175,0xD7E8 ],
- [ 0xE191, 0x1100,0x1175,0x11E4 ],
- [ 0xE192, 0x1100,0x1175,0x11E5 ],
- [ 0xE193, 0x1100,0x1175,0x11E6 ],
- [ 0xE194, 0x1100,0x1175,0x11E7 ],
- [ 0xE195, 0x1100,0x1175,0xD7EC ],
- [ 0xE196, 0x1100,0x1175,0xD7F0 ],
- [ 0xE197, 0x1100,0x1175,0x11EB ],
- [ 0xE198, 0x1100,0x1175,0x11F0 ],
- [ 0xE199, 0x1100,0x1175,0x11F9 ],
- [ 0xE19C, 0x1100,0x1199,0x11AB ],
- [ 0xE19D, 0x1100,0x1199,0x11BC ],
- [ 0xE1A3, 0x1100,0xD7C3,0x11AB ],
- [ 0xE1A8, 0x1100,0x119E,0x11A8 ],
- [ 0xE1A9, 0x1100,0x119E,0x11A9 ],
- [ 0xE1AA, 0x1100,0x119E,0x11AB ],
- [ 0xE1AB, 0x1100,0x119E,0x11AE ],
- [ 0xE1AC, 0x1100,0x119E,0xD7CF ],
- [ 0xE1AD, 0x1100,0x119E,0x11AF ],
- [ 0xE1AE, 0x1100,0x119E,0x11B0 ],
- [ 0xE1AF, 0x1100,0x119E,0x11CD ],
- [ 0xE1B0, 0x1100,0x119E,0x11D0 ],
- [ 0xE1B1, 0x1100,0x119E,0x11B1 ],
- [ 0xE1B2, 0x1100,0x119E,0x11B2 ],
- [ 0xE1B3, 0x1100,0x119E,0x11D3 ],
- [ 0xE1B4, 0x1100,0x119E,0xD7DA ],
- [ 0xE1B5, 0x1100,0x119E,0x11D5 ],
- [ 0xE1B6, 0x1100,0x119E,0x11B3 ],
- [ 0xE1B7, 0x1100,0x119E,0x11B5 ],
- [ 0xE1B8, 0x1100,0x119E,0x11B6 ],
- [ 0xE1B9, 0x1100,0x119E,0x11D9 ],
- [ 0xE1BA, 0x1100,0x119E,0x11B7 ],
- [ 0xE1BB, 0x1100,0x119E,0x11E2 ],
- [ 0xE1BC, 0x1100,0x119E,0x11B8 ],
- [ 0xE1BD, 0x1100,0x119E,0x11E3 ],
- [ 0xE1BE, 0x1100,0x119E,0x11E6 ],
- [ 0xE1BF, 0x1100,0x119E,0x11BA ],
- [ 0xE1C0, 0x1100,0x119E,0x11E7 ],
- [ 0xE1C1, 0x1100,0x119E,0x11EA ],
- [ 0xE1C2, 0x1100,0x119E,0x11EB ],
- [ 0xE1C3, 0x1100,0x119E,0x11BC ],
- [ 0xE1C4, 0x1100,0x119E,0x11F0 ],
- [ 0xE1C5, 0x1100,0x119E,0x11F1 ],
- [ 0xE1C6, 0x1100,0x119E,0x11BD ],
- [ 0xE1C7, 0x1100,0x119E,0x11BE ],
- [ 0xE1C8, 0x1100,0x119E,0x11C0 ],
- [ 0xE1C9, 0x1100,0x119E,0x11C2 ],
- [ 0xE1CB, 0x1100,0x119F,0x11AB ],
- [ 0xE1CC, 0x1100,0x119F,0x11BC ],
- [ 0xE1CE, 0x1100,0x11A1,0x11A8 ],
- [ 0xE1CF, 0x1100,0x11A1,0x11AB ],
- [ 0xE1D0, 0x1100,0x11A1,0x11AF ],
- [ 0xE1D1, 0x1100,0x11A1,0x11B7 ],
- [ 0xE1D2, 0x1100,0x11A1,0x11B8 ],
- [ 0xE1D3, 0x1100,0x11A1,0x11BA ],
- [ 0xE1D4, 0x1100,0x11A1,0x11BC ],
- [ 0xE1D5, 0x1100,0x11A1,0x11F0 ],
- [ 0xE1D6, 0x1100,0x11A1,0x11F1 ],
- [ 0xE1D7, 0x1101,0x1161,0x11F0 ],
- [ 0xE1D9, 0x1101,0x1163,0x11E2 ],
- [ 0xE1DA, 0x1101,0x1165,0x11D9 ],
- [ 0xE1DB, 0x1101,0x1165,0x11E2 ],
- [ 0xE1DC, 0x1101,0x1165,0x11E6 ],
- [ 0xE1DD, 0x1101,0x1165,0x11EC ],
- [ 0xE1DE, 0x1101,0x1165,0x11ED ],
- [ 0xE1E0, 0x1101,0x1167,0x11F0 ],
- [ 0xE1E1, 0x1101,0x1169,0x11E2 ],
- [ 0xE1E2, 0x1101,0x1169,0x11F0 ],
- [ 0xE1E3, 0x1101,0x116A,0x11F0 ],
- [ 0xE1E4, 0x1101,0x116D,0x11E2 ],
- [ 0xE1E5, 0x1101,0x116D,0x11F0 ],
- [ 0xE1E7, 0x1101,0x116E,0x11D9 ],
- [ 0xE1E8, 0x1101,0x116E,0x11DA ],
- [ 0xE1E9, 0x1101,0x116E,0x11E2 ],
- [ 0xE1EA, 0x1101,0x116E,0x11F0 ],
- [ 0xE1EC, 0x1101,0x116F,0x11D9 ],
- [ 0xE1ED, 0x1101,0x116F,0x11F0 ],
- [ 0xE1F0, 0x1101,0x1172,0x11D9 ],
- [ 0xE1F1, 0x1101,0x1172,0x11E2 ],
- [ 0xE1F2, 0x1101,0x1172,0x11F0 ],
- [ 0xE1F4, 0x1101,0x1191,0x11AB ],
- [ 0xE1F5, 0x1101,0x1191,0x11BC ],
- [ 0xE1F6, 0x1101,0x1191,0x11F0 ],
- [ 0xE1F7, 0x1101,0x1191,0x11F9 ],
- [ 0xE1F9, 0x1101,0x1194,0x11BC ],
- [ 0xE1FA, 0x1101,0x1173,0x11D9 ],
- [ 0xE1FB, 0x1101,0x1173,0x11F0 ],
- [ 0xE1FC, 0x1101,0x1173,0x11F6 ],
- [ 0xE1FD, 0x1101,0x1174,0x11F0 ],
- [ 0xE1FE, 0x1101,0x1175,0x11E2 ],
- [ 0xE1FF, 0x1101,0x1175,0x11F0 ],
- [ 0xE200, 0x1101,0x1175,0x11F9 ],
- [ 0xE206, 0x1102,0x1161,0x11C4 ],
- [ 0xE207, 0x1102,0x1161,0x11C7 ],
- [ 0xE208, 0x1102,0x1161,0xD7CF ],
- [ 0xE209, 0x1102,0x1161,0x11CD ],
- [ 0xE20A, 0x1102,0x1161,0x11D0 ],
- [ 0xE20B, 0x1102,0x1161,0x11D9 ],
- [ 0xE20C, 0x1102,0x1161,0x11DA ],
- [ 0xE20D, 0x1102,0x1161,0x11DC ],
- [ 0xE20E, 0x1102,0x1161,0x11DD ],
- [ 0xE20F, 0x1102,0x1161,0x11E2 ],
- [ 0xE210, 0x1102,0x1161,0x11E6 ],
- [ 0xE211, 0x1102,0x1161,0x11E7 ],
- [ 0xE212, 0x1102,0x1161,0x11EA ],
- [ 0xE213, 0x1102,0x1161,0xD7EF ],
- [ 0xE214, 0x1102,0x1161,0xD7F2 ],
- [ 0xE215, 0x1102,0x1161,0x11EB ],
- [ 0xE216, 0x1102,0x1161,0x11EC ],
- [ 0xE217, 0x1102,0x1161,0x11F0 ],
- [ 0xE218, 0x1102,0x1161,0xD7F7 ],
- [ 0xE219, 0x1102,0x1161,0xD7F8 ],
- [ 0xE21A, 0x1102,0x1161,0x11F5 ],
- [ 0xE21B, 0x1102,0x1161,0x11F9 ],
- [ 0xE21E, 0x1102,0x1162,0xD7CF ],
- [ 0xE21F, 0x1102,0x1162,0x11D9 ],
- [ 0xE220, 0x1102,0x1162,0xD7E3 ],
- [ 0xE221, 0x1102,0x1162,0x11E3 ],
- [ 0xE222, 0x1102,0x1163,0x11E2 ],
- [ 0xE223, 0x1102,0x1163,0x11F0 ],
- [ 0xE225, 0x1102,0x1165,0x11D0 ],
- [ 0xE226, 0x1102,0x1165,0x11DA ],
- [ 0xE227, 0x1102,0x1165,0x11DB ],
- [ 0xE228, 0x1102,0x1165,0x11DD ],
- [ 0xE229, 0x1102,0x1165,0x11E3 ],
- [ 0xE22A, 0x1102,0x1165,0x11E5 ],
- [ 0xE22B, 0x1102,0x1165,0x11E9 ],
- [ 0xE22C, 0x1102,0x1165,0xD7F2 ],
- [ 0xE22D, 0x1102,0x1165,0x11F0 ],
- [ 0xE22F, 0x1102,0x117B,0x11B7 ],
- [ 0xE231, 0x1102,0x117A,0x11A8 ],
- [ 0xE231, 0x1102,0x117C,0x11A8 ],
- [ 0xE232, 0x1102,0x117A,0x11C2 ],
- [ 0xE232, 0x1102,0x117C,0x11C2 ],
- [ 0xE233, 0x1102,0x1167,0x11FD ],
- [ 0xE234, 0x1102,0x1167,0x11FE ],
- [ 0xE235, 0x1102,0x1167,0x11C5 ],
- [ 0xE236, 0x1102,0x1167,0x11FF ],
- [ 0xE237, 0x1102,0x1167,0x11C7 ],
- [ 0xE238, 0x1102,0x1167,0x11D9 ],
- [ 0xE239, 0x1102,0x1167,0x11E7 ],
- [ 0xE23A, 0x1102,0x1167,0xD7F2 ],
- [ 0xE23B, 0x1102,0x1167,0x11F0 ],
- [ 0xE23C, 0x1102,0x1167,0x11F9 ],
- [ 0xE23D, 0x1102,0x1169,0x11CD ],
- [ 0xE23E, 0x1102,0x1169,0x11D0 ],
- [ 0xE23F, 0x1102,0x1169,0x11D9 ],
- [ 0xE240, 0x1102,0x1169,0x11E2 ],
- [ 0xE241, 0x1102,0x1169,0x11E4 ],
- [ 0xE242, 0x1102,0x1169,0x11E5 ],
- [ 0xE243, 0x1102,0x1169,0x11E6 ],
- [ 0xE244, 0x1102,0x1169,0xD7F2 ],
- [ 0xE245, 0x1102,0x1169,0x11EB ],
- [ 0xE246, 0x1102,0x1169,0x11F0 ],
- [ 0xE247, 0x1102,0x1169,0xD7F6 ],
- [ 0xE248, 0x1102,0x1169,0x11F3 ],
- [ 0xE249, 0x1102,0x116A,0x11D9 ],
- [ 0xE24B, 0x1102,0x116C,0x11F0 ],
- [ 0xE24C, 0x1102,0x116D,0x11D9 ],
- [ 0xE24D, 0x1102,0x116D,0x11E2 ],
- [ 0xE24E, 0x1102,0x116D,0x11F0 ],
- [ 0xE250, 0x1102,0xD7B2,0x11BC ],
- [ 0xE252, 0x1102,0x116E,0x11C6 ],
- [ 0xE253, 0x1102,0x116E,0x11C7 ],
- [ 0xE254, 0x1102,0x116E,0x11C8 ],
- [ 0xE255, 0x1102,0x116E,0x11D0 ],
- [ 0xE256, 0x1102,0x116E,0x11DD ],
- [ 0xE257, 0x1102,0x116E,0x11E2 ],
- [ 0xE258, 0x1102,0x116E,0x11E6 ],
- [ 0xE259, 0x1102,0x116E,0x11F5 ],
- [ 0xE25B, 0x1102,0x1189,0x11AB ],
- [ 0xE25E, 0x1102,0x1171,0x11EB ],
- [ 0xE260, 0x1102,0x1172,0x11D9 ],
- [ 0xE261, 0x1102,0x1172,0x11E2 ],
- [ 0xE262, 0x1102,0x1172,0x11F0 ],
- [ 0xE265, 0x1102,0x1194,0x11AB ],
- [ 0xE266, 0x1102,0x1194,0x11BC ],
- [ 0xE267, 0x1102,0x1173,0x11C3 ],
- [ 0xE268, 0x1102,0x1173,0x11CD ],
- [ 0xE269, 0x1102,0x1173,0x11D9 ],
- [ 0xE26A, 0x1102,0x1173,0x11F0 ],
- [ 0xE26B, 0x1102,0x1173,0xD7F6 ],
- [ 0xE26D, 0x1102,0x1174,0x11F0 ],
- [ 0xE26F, 0x1102,0x1175,0x11C3 ],
- [ 0xE270, 0x1102,0x1175,0x11CE ],
- [ 0xE271, 0x1102,0x1175,0x11D0 ],
- [ 0xE272, 0x1102,0x1175,0xD7D9 ],
- [ 0xE273, 0x1102,0x1175,0x11D9 ],
- [ 0xE274, 0x1102,0x1175,0x11DD ],
- [ 0xE275, 0x1102,0x1175,0x11E2 ],
- [ 0xE276, 0x1102,0x1175,0x11E4 ],
- [ 0xE277, 0x1102,0x1175,0x11E5 ],
- [ 0xE278, 0x1102,0x1175,0x11E6 ],
- [ 0xE279, 0x1102,0x1175,0x11EB ],
- [ 0xE27A, 0x1102,0x1175,0x11F0 ],
- [ 0xE27B, 0x1102,0x1175,0x11F9 ],
- [ 0xE27E, 0x1102,0x1199,0x11AB ],
- [ 0xE27F, 0x1102,0x1199,0x11BC ],
- [ 0xE284, 0x1102,0x119E,0x11A8 ],
- [ 0xE285, 0x1102,0x119E,0x11AB ],
- [ 0xE286, 0x1102,0x119E,0x11AE ],
- [ 0xE287, 0x1102,0x119E,0xD7D3 ],
- [ 0xE288, 0x1102,0x119E,0x11AF ],
- [ 0xE289, 0x1102,0x119E,0x11B0 ],
- [ 0xE28A, 0x1102,0x119E,0x11B1 ],
- [ 0xE28B, 0x1102,0x119E,0x11B2 ],
- [ 0xE28C, 0x1102,0x119E,0x11B3 ],
- [ 0xE28D, 0x1102,0x119E,0x11D7 ],
- [ 0xE28E, 0x1102,0x119E,0x11B6 ],
- [ 0xE28F, 0x1102,0x119E,0x11D9 ],
- [ 0xE290, 0x1102,0x119E,0x11B7 ],
- [ 0xE291, 0x1102,0x119E,0x11B8 ],
- [ 0xE292, 0x1102,0x119E,0x11BA ],
- [ 0xE293, 0x1102,0x119E,0xD7F0 ],
- [ 0xE294, 0x1102,0x119E,0x11EB ],
- [ 0xE295, 0x1102,0x119E,0x11BC ],
- [ 0xE296, 0x1102,0x119E,0x11F0 ],
- [ 0xE297, 0x1102,0x119E,0x11BD ],
- [ 0xE298, 0x1102,0x119E,0x11BE ],
- [ 0xE29A, 0x1102,0x11A1,0x11A8 ],
- [ 0xE29B, 0x1102,0x11A1,0x11AB ],
- [ 0xE29C, 0x1102,0x11A1,0x11AE ],
- [ 0xE29D, 0x1102,0x11A1,0x11AF ],
- [ 0xE29E, 0x1102,0x11A1,0x11B7 ],
- [ 0xE29F, 0x1102,0x11A1,0x11B8 ],
- [ 0xE2A0, 0x1102,0x11A1,0x11BA ],
- [ 0xE2A1, 0x1102,0x11A1,0x11E8 ],
- [ 0xE2A2, 0x1102,0x11A1,0x11BC ],
- [ 0xE2A3, 0x1102,0x11A1,0x11F0 ],
- [ 0xE2A4, 0x1102,0x11A1,0x11C2 ],
- [ 0xE2AC, 0x1113,0x1168,0x11AB ],
- [ 0xE2C2, 0x1114,0x1163,0x11BC ],
- [ 0xE2C8, 0x1114,0x1173,0x11AB ],
- [ 0xE2CA, 0x1114,0x119E,0x11AB ],
- [ 0xE2CC, 0x1115,0x1161,0x11AB ],
- [ 0xE2D1, 0x1115,0x1166,0x11AB ],
- [ 0xE2D5, 0x1115,0x1169,0x11AB ],
- [ 0xE307, 0x115D,0x1163,0x11BC ],
- [ 0xE30A, 0x115D,0x1172,0x11AB ],
- [ 0xE30C, 0x115D,0x1175,0x11BC ],
- [ 0xE30D, 0x1103,0x1161,0x11C7 ],
- [ 0xE30E, 0x1103,0x1161,0x11CA ],
- [ 0xE30F, 0x1103,0x1161,0xD7CD ],
- [ 0xE310, 0x1103,0x1161,0x11CD ],
- [ 0xE311, 0x1103,0x1161,0x11D0 ],
- [ 0xE312, 0x1103,0x1161,0x11D9 ],
- [ 0xE313, 0x1103,0x1161,0x11DB ],
- [ 0xE314, 0x1103,0x1161,0x11DD ],
- [ 0xE315, 0x1103,0x1161,0x11E2 ],
- [ 0xE316, 0x1103,0x1161,0x11E5 ],
- [ 0xE317, 0x1103,0x1161,0x11E6 ],
- [ 0xE318, 0x1103,0x1161,0x11E7 ],
- [ 0xE319, 0x1103,0x1161,0xD7F2 ],
- [ 0xE31A, 0x1103,0x1161,0x11EB ],
- [ 0xE31B, 0x1103,0x1161,0x11F0 ],
- [ 0xE31C, 0x1103,0x1161,0x11F1 ],
- [ 0xE31D, 0x1103,0x1161,0xD7F6 ],
- [ 0xE31E, 0x1103,0x1161,0x11F9 ],
- [ 0xE320, 0x1103,0x1176,0x11AF ],
- [ 0xE321, 0x1103,0x1162,0x11F0 ],
- [ 0xE322, 0x1103,0x1163,0x11E2 ],
- [ 0xE323, 0x1103,0x1163,0x11F0 ],
- [ 0xE324, 0x1103,0x1163,0x11F1 ],
- [ 0xE326, 0x1103,0x1165,0x11DD ],
- [ 0xE327, 0x1103,0x1165,0x11E4 ],
- [ 0xE328, 0x1103,0x1165,0x11E6 ],
- [ 0xE329, 0x1103,0x1165,0x11EB ],
- [ 0xE32A, 0x1103,0x1165,0x11F0 ],
- [ 0xE32D, 0x1103,0x117B,0x11AF ],
- [ 0xE32F, 0x1103,0x117C,0x11AF ],
- [ 0xE330, 0x1103,0x117C,0x11B7 ],
- [ 0xE331, 0x1103,0x1166,0x11C6 ],
- [ 0xE332, 0x1103,0x1166,0xD7E3 ],
- [ 0xE333, 0x1103,0x1167,0x11D9 ],
- [ 0xE334, 0x1103,0x1167,0x11E2 ],
- [ 0xE335, 0x1103,0x1167,0x11F0 ],
- [ 0xE336, 0x1103,0x1167,0x11F9 ],
- [ 0xE337, 0x1103,0x1169,0x11C6 ],
- [ 0xE338, 0x1103,0x1169,0x11CA ],
- [ 0xE339, 0x1103,0x1169,0xD7D4 ],
- [ 0xE33A, 0x1103,0x1169,0x11D0 ],
- [ 0xE33B, 0x1103,0x1169,0x11D6 ],
- [ 0xE33C, 0x1103,0x1169,0x11D8 ],
- [ 0xE33D, 0x1103,0x1169,0x11D9 ],
- [ 0xE33E, 0x1103,0x1169,0x11E2 ],
- [ 0xE33F, 0x1103,0x1169,0x11E6 ],
- [ 0xE340, 0x1103,0x1169,0x11E7 ],
- [ 0xE341, 0x1103,0x1169,0xD7EC ],
- [ 0xE342, 0x1103,0x1169,0xD7F2 ],
- [ 0xE343, 0x1103,0x1169,0x11EB ],
- [ 0xE344, 0x1103,0x1169,0x11F0 ],
- [ 0xE345, 0x1103,0x1169,0x11F1 ],
- [ 0xE346, 0x1103,0x116A,0x11D9 ],
- [ 0xE347, 0x1103,0x116A,0x11F0 ],
- [ 0xE349, 0x1103,0x1182,0x11B7 ],
- [ 0xE34A, 0x1103,0x116D,0x11E2 ],
- [ 0xE34B, 0x1103,0x116D,0xD7F5 ],
- [ 0xE34C, 0x1103,0x116D,0x11F0 ],
- [ 0xE34E, 0x1103,0x1188,0x11AB ],
- [ 0xE34F, 0x1103,0x1188,0x11AF ],
- [ 0xE350, 0x1103,0x116E,0x11CE ],
- [ 0xE351, 0x1103,0x116E,0x11D0 ],
- [ 0xE352, 0x1103,0x116E,0x11D9 ],
- [ 0xE353, 0x1103,0x116E,0x11DA ],
- [ 0xE354, 0x1103,0x116E,0x11E2 ],
- [ 0xE355, 0x1103,0x116E,0x11F0 ],
- [ 0xE357, 0x1103,0x1189,0x11AB ],
- [ 0xE358, 0x1103,0x116F,0x11F9 ],
- [ 0xE35B, 0x1103,0x1171,0x11E6 ],
- [ 0xE35C, 0x1103,0x1171,0x11F9 ],
- [ 0xE35D, 0x1103,0x1172,0x11D9 ],
- [ 0xE35E, 0x1103,0x1172,0x11E2 ],
- [ 0xE35F, 0x1103,0x1172,0x11F0 ],
- [ 0xE360, 0x1103,0x1172,0x11F1 ],
- [ 0xE362, 0x1103,0x1191,0x11AB ],
- [ 0xE363, 0x1103,0x1191,0x11AF ],
- [ 0xE364, 0x1103,0x1191,0x11D9 ],
- [ 0xE365, 0x1103,0x1191,0x11BC ],
- [ 0xE367, 0x1103,0x1192,0x11BC ],
- [ 0xE369, 0x1103,0x1194,0x11AB ],
- [ 0xE36A, 0x1103,0x1194,0x11BC ],
- [ 0xE36B, 0x1103,0x1173,0x11CD ],
- [ 0xE36C, 0x1103,0x1173,0x11CE ],
- [ 0xE36D, 0x1103,0x1173,0x11D0 ],
- [ 0xE36E, 0x1103,0x1173,0x11D9 ],
- [ 0xE36F, 0x1103,0x1173,0x11DA ],
- [ 0xE370, 0x1103,0x1173,0x11E2 ],
- [ 0xE371, 0x1103,0x1173,0x11E3 ],
- [ 0xE372, 0x1103,0x1173,0x11E6 ],
- [ 0xE373, 0x1103,0x1173,0x11EB ],
- [ 0xE374, 0x1103,0x1173,0x11F0 ],
- [ 0xE375, 0x1103,0x1173,0x11F1 ],
- [ 0xE378, 0x1103,0x1174,0x11D9 ],
- [ 0xE379, 0x1103,0x1174,0x11F9 ],
- [ 0xE37A, 0x1103,0x1175,0x11D0 ],
- [ 0xE37B, 0x1103,0x1175,0x11D9 ],
- [ 0xE37C, 0x1103,0x1175,0x11E2 ],
- [ 0xE37D, 0x1103,0x1175,0x11E4 ],
- [ 0xE37E, 0x1103,0x1175,0x11E5 ],
- [ 0xE37F, 0x1103,0x1175,0xD7F1 ],
- [ 0xE380, 0x1103,0x1175,0x11EB ],
- [ 0xE381, 0x1103,0x1175,0x11F0 ],
- [ 0xE382, 0x1103,0x1175,0x11F9 ],
- [ 0xE385, 0x1103,0x1199,0x11AB ],
- [ 0xE386, 0x1103,0x1199,0x11BC ],
- [ 0xE38B, 0x1103,0x119E,0x11A8 ],
- [ 0xE38C, 0x1103,0x119E,0x11C3 ],
- [ 0xE38D, 0x1103,0x119E,0x11AB ],
- [ 0xE38E, 0x1103,0x119E,0x11AE ],
- [ 0xE38F, 0x1103,0x119E,0x11AF ],
- [ 0xE390, 0x1103,0x119E,0x11B0 ],
- [ 0xE391, 0x1103,0x119E,0x11CC ],
- [ 0xE392, 0x1103,0x119E,0x11B1 ],
- [ 0xE393, 0x1103,0x119E,0x11B2 ],
- [ 0xE394, 0x1103,0x119E,0x11B3 ],
- [ 0xE395, 0x1103,0x119E,0x11B6 ],
- [ 0xE396, 0x1103,0x119E,0x11D9 ],
- [ 0xE397, 0x1103,0x119E,0x11B7 ],
- [ 0xE398, 0x1103,0x119E,0x11DA ],
- [ 0xE399, 0x1103,0x119E,0xD7DE ],
- [ 0xE39A, 0x1103,0x119E,0xD7DF ],
- [ 0xE39B, 0x1103,0x119E,0x11B8 ],
- [ 0xE39C, 0x1103,0x119E,0x11E3 ],
- [ 0xE39D, 0x1103,0x119E,0x11E6 ],
- [ 0xE39E, 0x1103,0x119E,0x11BA ],
- [ 0xE39F, 0x1103,0x119E,0x11E7 ],
- [ 0xE3A0, 0x1103,0x119E,0x11E8 ],
- [ 0xE3A1, 0x1103,0x119E,0x11E9 ],
- [ 0xE3A2, 0x1103,0x119E,0x11EA ],
- [ 0xE3A3, 0x1103,0x119E,0x11EB ],
- [ 0xE3A4, 0x1103,0x119E,0x11BC ],
- [ 0xE3A5, 0x1103,0x119E,0x11F0 ],
- [ 0xE3A6, 0x1103,0x119E,0x11BD ],
- [ 0xE3A7, 0x1103,0x119E,0x11BE ],
- [ 0xE3A9, 0x1103,0x11A1,0x11A8 ],
- [ 0xE3AA, 0x1103,0x11A1,0x11AB ],
- [ 0xE3AB, 0x1103,0x11A1,0x11AE ],
- [ 0xE3AC, 0x1103,0x11A1,0x11AF ],
- [ 0xE3AD, 0x1103,0x11A1,0x11D9 ],
- [ 0xE3AE, 0x1103,0x11A1,0x11B7 ],
- [ 0xE3AF, 0x1103,0x11A1,0x11B8 ],
- [ 0xE3B0, 0x1103,0x11A1,0x11BA ],
- [ 0xE3B1, 0x1103,0x11A1,0x11EB ],
- [ 0xE3B2, 0x1103,0x11A1,0x11BC ],
- [ 0xE3B3, 0x1103,0x11A1,0x11F0 ],
- [ 0xE3B5, 0x1117,0x1173,0x11AF ],
- [ 0xE3B7, 0x1117,0x1175,0x11AF ],
- [ 0xE3B8, 0x1104,0x1161,0x11D0 ],
- [ 0xE3B9, 0x1104,0x1161,0x11D8 ],
- [ 0xE3BA, 0x1104,0x1161,0x11D9 ],
- [ 0xE3BB, 0x1104,0x1161,0x11E2 ],
- [ 0xE3BC, 0x1104,0x1161,0x11E6 ],
- [ 0xE3BD, 0x1104,0x1161,0x11F0 ],
- [ 0xE3BE, 0x1104,0x1161,0x11F9 ],
- [ 0xE3BF, 0x1104,0x1163,0x11E2 ],
- [ 0xE3C0, 0x1104,0x1163,0x11F0 ],
- [ 0xE3C3, 0x1104,0x117C,0x11AF ],
- [ 0xE3C4, 0x1104,0x117C,0x11B2 ],
- [ 0xE3C5, 0x1104,0x1167,0x11D9 ],
- [ 0xE3C6, 0x1104,0x1167,0x11F0 ],
- [ 0xE3C7, 0x1104,0x1169,0x11D9 ],
- [ 0xE3C8, 0x1104,0x1169,0x11E2 ],
- [ 0xE3C9, 0x1104,0x1169,0x11F0 ],
- [ 0xE3CA, 0x1104,0x1169,0x11F9 ],
- [ 0xE3CB, 0x1104,0x116A,0x11D9 ],
- [ 0xE3CC, 0x1104,0x116A,0x11F0 ],
- [ 0xE3CE, 0x1104,0x116D,0x11E2 ],
- [ 0xE3CF, 0x1104,0x116E,0x11E2 ],
- [ 0xE3D0, 0x1104,0x116E,0x11F0 ],
- [ 0xE3D1, 0x1104,0x116E,0x11F9 ],
- [ 0xE3D4, 0x1104,0x1171,0x11F9 ],
- [ 0xE3D5, 0x1104,0x1172,0x11D9 ],
- [ 0xE3D6, 0x1104,0x1172,0x11E2 ],
- [ 0xE3D7, 0x1104,0x1172,0x11F0 ],
- [ 0xE3D9, 0x1104,0x1191,0x11AB ],
- [ 0xE3DB, 0x1104,0x1194,0x11BC ],
- [ 0xE3DC, 0x1104,0x1173,0xD7CD ],
- [ 0xE3DD, 0x1104,0x1173,0x11E2 ],
- [ 0xE3DE, 0x1104,0x1173,0x11F0 ],
- [ 0xE3DF, 0x1104,0x1173,0x11F9 ],
- [ 0xE3E0, 0x1104,0x1174,0x11F9 ],
- [ 0xE3E1, 0x1104,0x1175,0x11D9 ],
- [ 0xE3E2, 0x1104,0x1175,0x11F0 ],
- [ 0xE3E3, 0x1104,0x1175,0x11F9 ],
- [ 0xE3E6, 0x1104,0x119E,0x11A8 ],
- [ 0xE3E7, 0x1104,0x119E,0x11AB ],
- [ 0xE3E8, 0x1104,0x119E,0x11AF ],
- [ 0xE3E9, 0x1104,0x119E,0x11B7 ],
- [ 0xE3EA, 0x1104,0x119E,0x11BA ],
- [ 0xE3EC, 0x1104,0x11A1,0x11A8 ],
- [ 0xE3ED, 0x1104,0x11A1,0x11AF ],
- [ 0xE3EE, 0x1104,0x11A1,0x11BC ],
- [ 0xE3EF, 0x1104,0x11A1,0x11F0 ],
- [ 0xE3F1, 0x115E,0x1175,0x11BC ],
- [ 0xE3F2, 0x115E,0x1175,0x11EF ],
- [ 0xE3F4, 0xA960,0x1161,0x11AF ],
- [ 0xE3F8, 0xA961,0x116E,0x11AF ],
- [ 0xE3FA, 0xA962,0x1172,0x11AF ],
- [ 0xE3FB, 0xA962,0x1172,0x11BC ],
- [ 0xE3FE, 0xA962,0x1175,0x11A8 ],
- [ 0xE400, 0xA963,0x1163,0x11BC ],
- [ 0xE402, 0x1105,0x1161,0x11D0 ],
- [ 0xE403, 0x1105,0x1161,0x11D9 ],
- [ 0xE404, 0x1105,0x1161,0xD7E0 ],
- [ 0xE405, 0x1105,0x1161,0x11DD ],
- [ 0xE406, 0x1105,0x1161,0x11E2 ],
- [ 0xE407, 0x1105,0x1161,0x11E6 ],
- [ 0xE408, 0x1105,0x1161,0x11E7 ],
- [ 0xE409, 0x1105,0x1161,0xD7EC ],
- [ 0xE40A, 0x1105,0x1161,0x11EB ],
- [ 0xE40B, 0x1105,0x1161,0x11F0 ],
- [ 0xE40C, 0x1105,0x1161,0x11EC ],
- [ 0xE40D, 0x1105,0x1161,0x11F5 ],
- [ 0xE40E, 0x1105,0x1161,0x11F9 ],
- [ 0xE410, 0x1105,0x1176,0x11AF ],
- [ 0xE412, 0x1105,0x1162,0x11F0 ],
- [ 0xE413, 0x1105,0x1163,0x11E2 ],
- [ 0xE414, 0x1105,0x1163,0x11F0 ],
- [ 0xE416, 0x1105,0x1165,0xD7E0 ],
- [ 0xE417, 0x1105,0x1165,0x11E6 ],
- [ 0xE418, 0x1105,0x1165,0xD7F2 ],
- [ 0xE419, 0x1105,0x1165,0x11F0 ],
- [ 0xE41A, 0x1105,0x1165,0x11F5 ],
- [ 0xE41D, 0x1105,0x117B,0x11AF ],
- [ 0xE41E, 0x1105,0x1166,0x11F0 ],
- [ 0xE41F, 0x1105,0x1167,0x11C7 ],
- [ 0xE420, 0x1105,0x1167,0x11D9 ],
- [ 0xE421, 0x1105,0x1167,0x11E2 ],
- [ 0xE422, 0x1105,0x1167,0x11E6 ],
- [ 0xE423, 0x1105,0x1167,0x11F0 ],
- [ 0xE424, 0x1105,0x1167,0x11F9 ],
- [ 0xE425, 0x1105,0x1169,0xD7D0 ],
- [ 0xE426, 0x1105,0x1169,0x11D9 ],
- [ 0xE427, 0x1105,0x1169,0x11DD ],
- [ 0xE428, 0x1105,0x1169,0x11E2 ],
- [ 0xE429, 0x1105,0x1169,0xD7E5 ],
- [ 0xE42A, 0x1105,0x1169,0x11E6 ],
- [ 0xE42B, 0x1105,0x1169,0xD7F0 ],
- [ 0xE42C, 0x1105,0x1169,0x11F0 ],
- [ 0xE42D, 0x1105,0x1169,0x11F1 ],
- [ 0xE42E, 0x1105,0x116A,0x11D9 ],
- [ 0xE42F, 0x1105,0x116A,0x11F0 ],
- [ 0xE431, 0x1105,0x116D,0x11D9 ],
- [ 0xE432, 0x1105,0x116D,0x11DD ],
- [ 0xE433, 0x1105,0x116D,0x11E2 ],
- [ 0xE434, 0x1105,0x116D,0x11F0 ],
- [ 0xE438, 0x1105,0x116E,0x11D9 ],
- [ 0xE439, 0x1105,0x116E,0x11DD ],
- [ 0xE43A, 0x1105,0x116E,0x11E2 ],
- [ 0xE43B, 0x1105,0x116E,0x11E4 ],
- [ 0xE43C, 0x1105,0x116E,0x11F0 ],
- [ 0xE43D, 0x1105,0x116E,0x11F9 ],
- [ 0xE43F, 0x1105,0x1189,0x11AB ],
- [ 0xE443, 0x1105,0x1172,0x11D9 ],
- [ 0xE444, 0x1105,0x1172,0x11E2 ],
- [ 0xE445, 0x1105,0x1172,0x11F0 ],
- [ 0xE446, 0x1105,0x1172,0x11F9 ],
- [ 0xE448, 0x1105,0x1191,0x11AB ],
- [ 0xE449, 0x1105,0x1191,0x11AF ],
- [ 0xE44A, 0x1105,0x1191,0x11D9 ],
- [ 0xE44C, 0x1105,0x1194,0x11BC ],
- [ 0xE44D, 0x1105,0x1173,0xD7D3 ],
- [ 0xE44E, 0x1105,0x1173,0x11D0 ],
- [ 0xE44F, 0x1105,0x1173,0x11D9 ],
- [ 0xE450, 0x1105,0x1173,0xD7E0 ],
- [ 0xE451, 0x1105,0x1173,0x11DD ],
- [ 0xE452, 0x1105,0x1173,0x11E2 ],
- [ 0xE453, 0x1105,0x1173,0x11E6 ],
- [ 0xE454, 0x1105,0x1173,0x11F0 ],
- [ 0xE457, 0x1105,0x1174,0x11F9 ],
- [ 0xE458, 0x1105,0x1175,0x11C7 ],
- [ 0xE459, 0x1105,0x1175,0x11D9 ],
- [ 0xE45A, 0x1105,0x1175,0x11DD ],
- [ 0xE45B, 0x1105,0x1175,0x11E2 ],
- [ 0xE45C, 0x1105,0x1175,0x11E6 ],
- [ 0xE45D, 0x1105,0x1175,0x11F0 ],
- [ 0xE45E, 0x1105,0x1175,0x11F9 ],
- [ 0xE461, 0x1105,0x1199,0x11AB ],
- [ 0xE462, 0x1105,0x1199,0x11BC ],
- [ 0xE467, 0x1105,0x119A,0x11AF ],
- [ 0xE46A, 0x1105,0x119B,0x11AF ],
- [ 0xE46D, 0x1105,0x119E,0x11A8 ],
- [ 0xE46E, 0x1105,0x119E,0x11AB ],
- [ 0xE46F, 0x1105,0x119E,0x11AE ],
- [ 0xE470, 0x1105,0x119E,0x11AF ],
- [ 0xE471, 0x1105,0x119E,0x11B0 ],
- [ 0xE472, 0x1105,0x119E,0x11B1 ],
- [ 0xE473, 0x1105,0x119E,0x11B3 ],
- [ 0xE474, 0x1105,0x119E,0x11D7 ],
- [ 0xE475, 0x1105,0x119E,0x11B6 ],
- [ 0xE476, 0x1105,0x119E,0x11D9 ],
- [ 0xE477, 0x1105,0x119E,0x11B7 ],
- [ 0xE478, 0x1105,0x119E,0xD7E0 ],
- [ 0xE479, 0x1105,0x119E,0x11DC ],
- [ 0xE47A, 0x1105,0x119E,0x11DD ],
- [ 0xE47B, 0x1105,0x119E,0x11B8 ],
- [ 0xE47C, 0x1105,0x119E,0x11B9 ],
- [ 0xE47D, 0x1105,0x119E,0x11E6 ],
- [ 0xE47E, 0x1105,0x119E,0x11BA ],
- [ 0xE47F, 0x1105,0x119E,0x11BB ],
- [ 0xE480, 0x1105,0x119E,0x11EB ],
- [ 0xE481, 0x1105,0x119E,0x11F0 ],
- [ 0xE482, 0x1105,0x119E,0x11BD ],
- [ 0xE483, 0x1105,0x119E,0x11BE ],
- [ 0xE484, 0x1105,0x119E,0x11C0 ],
- [ 0xE485, 0x1105,0x119E,0x11C2 ],
- [ 0xE488, 0x1105,0x11A1,0x11A8 ],
- [ 0xE489, 0x1105,0x11A1,0x11AB ],
- [ 0xE48A, 0x1105,0x11A1,0x11AE ],
- [ 0xE48B, 0x1105,0x11A1,0x11AF ],
- [ 0xE48C, 0x1105,0x11A1,0x11B7 ],
- [ 0xE48D, 0x1105,0x11A1,0x11BA ],
- [ 0xE48E, 0x1105,0x11A1,0x11BC ],
- [ 0xE48F, 0x1105,0x11A1,0x11F0 ],
- [ 0xE492, 0xA964,0x1169,0x11BA ],
- [ 0xE495, 0x1118,0x1161,0x11A8 ],
- [ 0xE496, 0x1118,0x1161,0x11AB ],
- [ 0xE497, 0x1118,0x1161,0x11BC ],
- [ 0xE49A, 0x1118,0x1166,0x11AF ],
- [ 0xE49B, 0x1118,0x1166,0x11B8 ],
- [ 0xE49D, 0x1118,0x1169,0x11A8 ],
- [ 0xE49E, 0x1118,0x1169,0x11AB ],
- [ 0xE49F, 0x1118,0x1169,0x11B7 ],
- [ 0xE4A0, 0x1118,0x1169,0x11BA ],
- [ 0xE4A2, 0x1118,0x116D,0x11AB ],
- [ 0xE4A5, 0x1118,0x1172,0x11A8 ],
- [ 0xE4A8, 0x1118,0x1174,0x11A8 ],
- [ 0xE4A9, 0x1118,0x1174,0x11AB ],
- [ 0xE4AA, 0x1118,0x1174,0x11B8 ],
- [ 0xE4AC, 0x1118,0x119E,0x11AB ],
- [ 0xE4AD, 0x1118,0x119E,0x11BC ],
- [ 0xE4AF, 0x1118,0x11A1,0x11A8 ],
- [ 0xE4B0, 0x1118,0x11A1,0x11B7 ],
- [ 0xE4B3, 0x1119,0x1161,0x11A8 ],
- [ 0xE4B4, 0x1119,0x1161,0x11AB ],
- [ 0xE4B5, 0x1119,0x1161,0x11BC ],
- [ 0xE4B8, 0x1119,0x1162,0x11AB ],
- [ 0xE4BA, 0x1119,0x1163,0x11BC ],
- [ 0xE4BD, 0x1119,0x1165,0x11AB ],
- [ 0xE4BE, 0x1119,0x1165,0x11BC ],
- [ 0xE4C1, 0x1119,0x1166,0x11A8 ],
- [ 0xE4C3, 0x1119,0x1167,0x11A8 ],
- [ 0xE4C5, 0x1119,0x1168,0x11AB ],
- [ 0xE4C7, 0x1119,0x1169,0x11BC ],
- [ 0xE4CA, 0x1119,0x116E,0x11AB ],
- [ 0xE4CB, 0x1119,0x116E,0x11BC ],
- [ 0xE4CD, 0x1119,0x1189,0x11AB ],
- [ 0xE4D5, 0x1119,0x1173,0x11AF ],
- [ 0xE4D6, 0x1119,0x1173,0x11D0 ],
- [ 0xE4D7, 0x1119,0x1173,0x11BC ],
- [ 0xE4D9, 0x1119,0x1175,0x11AB ],
- [ 0xE4DA, 0x1119,0x1175,0x11BC ],
- [ 0xE4DD, 0xA968,0x1161,0x11AB ],
- [ 0xE4E3, 0xA96C,0x1169,0x11A8 ],
- [ 0xE4E8, 0xA96D,0x1172,0x11AF ],
- [ 0xE4EB, 0x111A,0x1161,0x11AB ],
- [ 0xE4ED, 0x111A,0x1163,0x11BC ],
- [ 0xE4F1, 0x1106,0x1161,0x11FE ],
- [ 0xE4F2, 0x1106,0x1161,0x11C6 ],
- [ 0xE4F3, 0x1106,0x1161,0x11C7 ],
- [ 0xE4F4, 0x1106,0x1161,0xD7D4 ],
- [ 0xE4F5, 0x1106,0x1161,0x11CD ],
- [ 0xE4F6, 0x1106,0x1161,0x11D0 ],
- [ 0xE4F7, 0x1106,0x1161,0x11D8 ],
- [ 0xE4F8, 0x1106,0x1161,0x11D9 ],
- [ 0xE4F9, 0x1106,0x1161,0x11E2 ],
- [ 0xE4FA, 0x1106,0x1161,0x11E6 ],
- [ 0xE4FB, 0x1106,0x1161,0x11E8 ],
- [ 0xE4FC, 0x1106,0x1161,0xD7ED ],
- [ 0xE4FD, 0x1106,0x1161,0xD7F0 ],
- [ 0xE4FE, 0x1106,0x1161,0xD7F1 ],
- [ 0xE4FF, 0x1106,0x1161,0x11EB ],
- [ 0xE500, 0x1106,0x1161,0x11F0 ],
- [ 0xE501, 0x1106,0x1161,0x11F9 ],
- [ 0xE504, 0x1106,0x1162,0x11F0 ],
- [ 0xE505, 0x1106,0x1163,0x11E2 ],
- [ 0xE507, 0x1106,0x1165,0x11C6 ],
- [ 0xE508, 0x1106,0x1165,0x11CD ],
- [ 0xE509, 0x1106,0x1165,0x11D0 ],
- [ 0xE50A, 0x1106,0x1165,0x11D9 ],
- [ 0xE50B, 0x1106,0x1165,0x11F0 ],
- [ 0xE50C, 0x1106,0x1165,0x11F9 ],
- [ 0xE50F, 0x1106,0x117C,0x11AF ],
- [ 0xE510, 0x1106,0x1166,0x11D9 ],
- [ 0xE511, 0x1106,0x1167,0x11D9 ],
- [ 0xE512, 0x1106,0x1167,0x11E2 ],
- [ 0xE513, 0x1106,0x1167,0x11EB ],
- [ 0xE514, 0x1106,0x1167,0x11F0 ],
- [ 0xE515, 0x1106,0x1167,0xD7F6 ],
- [ 0xE516, 0x1106,0x1167,0x11F9 ],
- [ 0xE517, 0x1106,0x1169,0x11C6 ],
- [ 0xE518, 0x1106,0x1169,0x11D0 ],
- [ 0xE519, 0x1106,0x1169,0x11D9 ],
- [ 0xE51A, 0x1106,0x1169,0x11DD ],
- [ 0xE51B, 0x1106,0x1169,0x11E2 ],
- [ 0xE51C, 0x1106,0x1169,0xD7F0 ],
- [ 0xE51D, 0x1106,0x1169,0x11EB ],
- [ 0xE51E, 0x1106,0x1169,0x11F0 ],
- [ 0xE520, 0x1106,0x117F,0x11AB ],
- [ 0xE524, 0x1106,0x116D,0x11E2 ],
- [ 0xE527, 0x1106,0x116E,0x11C6 ],
- [ 0xE528, 0x1106,0x116E,0x11C7 ],
- [ 0xE529, 0x1106,0x116E,0x11D0 ],
- [ 0xE52A, 0x1106,0x116E,0x11D9 ],
- [ 0xE52B, 0x1106,0x116E,0x11DD ],
- [ 0xE52C, 0x1106,0x116E,0x11E2 ],
- [ 0xE52D, 0x1106,0x116E,0x11E7 ],
- [ 0xE52E, 0x1106,0x116E,0xD7EC ],
- [ 0xE52F, 0x1106,0x116E,0xD7F1 ],
- [ 0xE530, 0x1106,0x116E,0x11EB ],
- [ 0xE531, 0x1106,0x116E,0x11EC ],
- [ 0xE532, 0x1106,0x116E,0x11ED ],
- [ 0xE533, 0x1106,0x116E,0x11F0 ],
- [ 0xE534, 0x1106,0x116E,0x11F9 ],
- [ 0xE535, 0x1106,0x116F,0x11F9 ],
- [ 0xE539, 0x1106,0x1171,0x11F9 ],
- [ 0xE53A, 0x1106,0x1172,0x11E2 ],
- [ 0xE53C, 0x1106,0x1173,0x11C4 ],
- [ 0xE53D, 0x1106,0x1173,0x11D0 ],
- [ 0xE53E, 0x1106,0x1173,0x11D9 ],
- [ 0xE53F, 0x1106,0x1173,0x11E2 ],
- [ 0xE540, 0x1106,0x1173,0x11E7 ],
- [ 0xE541, 0x1106,0x1173,0xD7F2 ],
- [ 0xE542, 0x1106,0x1173,0x11EB ],
- [ 0xE543, 0x1106,0x1173,0x11F0 ],
- [ 0xE546, 0x1106,0x1196,0x11B7 ],
- [ 0xE547, 0x1106,0x1174,0x11D9 ],
- [ 0xE548, 0x1106,0x1174,0x11E6 ],
- [ 0xE549, 0x1106,0x1174,0x11F9 ],
- [ 0xE54A, 0x1106,0x1175,0xD7CF ],
- [ 0xE54B, 0x1106,0x1175,0xD7D3 ],
- [ 0xE54C, 0x1106,0x1175,0xD7D4 ],
- [ 0xE54D, 0x1106,0x1175,0x11CD ],
- [ 0xE54E, 0x1106,0x1175,0x11D0 ],
- [ 0xE54F, 0x1106,0x1175,0x11D9 ],
- [ 0xE550, 0x1106,0x1175,0x11E6 ],
- [ 0xE551, 0x1106,0x1175,0x11E7 ],
- [ 0xE552, 0x1106,0x1175,0xD7F0 ],
- [ 0xE553, 0x1106,0x1175,0xD7F1 ],
- [ 0xE554, 0x1106,0x1175,0xD7F2 ],
- [ 0xE555, 0x1106,0x1175,0x11EB ],
- [ 0xE556, 0x1106,0x1175,0x11F0 ],
- [ 0xE557, 0x1106,0x1175,0x11F6 ],
- [ 0xE558, 0x1106,0x1175,0x11F9 ],
- [ 0xE55B, 0x1106,0x1199,0x11AB ],
- [ 0xE55F, 0x1106,0x119C,0x11BC ],
- [ 0xE561, 0x1106,0x119E,0x11A8 ],
- [ 0xE562, 0x1106,0x119E,0x11C3 ],
- [ 0xE563, 0x1106,0x119E,0x11AB ],
- [ 0xE564, 0x1106,0x119E,0x11AE ],
- [ 0xE565, 0x1106,0x119E,0xD7D3 ],
- [ 0xE566, 0x1106,0x119E,0x11AF ],
- [ 0xE567, 0x1106,0x119E,0x11B0 ],
- [ 0xE568, 0x1106,0x119E,0x11D0 ],
- [ 0xE569, 0x1106,0x119E,0x11B2 ],
- [ 0xE56A, 0x1106,0x119E,0x11D5 ],
- [ 0xE56B, 0x1106,0x119E,0x11B3 ],
- [ 0xE56C, 0x1106,0x119E,0x11B6 ],
- [ 0xE56D, 0x1106,0x119E,0x11D9 ],
- [ 0xE56E, 0x1106,0x119E,0x11B7 ],
- [ 0xE56F, 0x1106,0x119E,0x11B8 ],
- [ 0xE570, 0x1106,0x119E,0x11BA ],
- [ 0xE571, 0x1106,0x119E,0xD7F0 ],
- [ 0xE572, 0x1106,0x119E,0x11EB ],
- [ 0xE573, 0x1106,0x119E,0x11BC ],
- [ 0xE574, 0x1106,0x119E,0x11F0 ],
- [ 0xE575, 0x1106,0x119E,0x11BD ],
- [ 0xE576, 0x1106,0x119E,0x11BE ],
- [ 0xE577, 0x1106,0x119E,0x11C0 ],
- [ 0xE579, 0x1106,0x119F,0x11AB ],
- [ 0xE57A, 0x1106,0x119F,0x11BC ],
- [ 0xE57C, 0x1106,0x11A1,0x11A8 ],
- [ 0xE57D, 0x1106,0x11A1,0x11A9 ],
- [ 0xE57E, 0x1106,0x11A1,0x11AB ],
- [ 0xE57F, 0x1106,0x11A1,0x11AE ],
- [ 0xE580, 0x1106,0x11A1,0x11AF ],
- [ 0xE581, 0x1106,0x11A1,0x11B3 ],
- [ 0xE582, 0x1106,0x11A1,0x11D9 ],
- [ 0xE583, 0x1106,0x11A1,0x11B7 ],
- [ 0xE584, 0x1106,0x11A1,0x11B8 ],
- [ 0xE585, 0x1106,0x11A1,0x11E6 ],
- [ 0xE586, 0x1106,0x11A1,0x11BA ],
- [ 0xE587, 0x1106,0x11A1,0x11BC ],
- [ 0xE588, 0x1106,0x11A1,0x11F0 ],
- [ 0xE589, 0x1106,0x11A1,0x11BD ],
- [ 0xE58A, 0x1106,0x11A1,0x11BE ],
- [ 0xE58B, 0x1106,0x11A1,0x11C2 ],
- [ 0xE591, 0xA970,0x1167,0x11AF ],
- [ 0xE594, 0x111C,0x1161,0x11AB ],
- [ 0xE595, 0x111C,0x1161,0x11AE ],
- [ 0xE59C, 0x111C,0x1168,0x11AB ],
- [ 0xE59D, 0x111C,0x1168,0x11AE ],
- [ 0xE59F, 0x111C,0x1169,0x11A8 ],
- [ 0xE5A0, 0x111C,0x1169,0x11AB ],
- [ 0xE5A1, 0x111C,0x1169,0x11AE ],
- [ 0xE5A7, 0x111C,0x116E,0x11AB ],
- [ 0xE5A8, 0x111C,0x116E,0x11BC ],
- [ 0xE5B3, 0x111C,0x1175,0x11AB ],
- [ 0xE5B8, 0xA971,0x1169,0x11A8 ],
- [ 0xE5BA, 0x111D,0x1161,0x11AB ],
- [ 0xE5BB, 0x111D,0x1161,0x11BC ],
- [ 0xE5BC, 0x111D,0x1161,0x11F0 ],
- [ 0xE5BF, 0x111D,0x116A,0x11AB ],
- [ 0xE5C0, 0x111D,0x116A,0x11F9 ],
- [ 0xE5C2, 0x111D,0x116E,0x11AB ],
- [ 0xE5C3, 0x111D,0x116E,0x11BC ],
- [ 0xE5C4, 0x111D,0x116E,0x11F9 ],
- [ 0xE5C7, 0x111D,0x1172,0x11AB ],
- [ 0xE5C9, 0x111D,0x1173,0x11AB ],
- [ 0xE5CA, 0x111D,0x1173,0x11F9 ],
- [ 0xE5CB, 0x111D,0xD7B9,0x11AB ],
- [ 0xE5CD, 0x111D,0x1175,0x11BC ],
- [ 0xE5CE, 0x1107,0x1161,0x11C3 ],
- [ 0xE5CF, 0x1107,0x1161,0x11FC ],
- [ 0xE5D0, 0x1107,0x1161,0xD7CB ],
- [ 0xE5D1, 0x1107,0x1161,0x11C7 ],
- [ 0xE5D2, 0x1107,0x1161,0x11C9 ],
- [ 0xE5D3, 0x1107,0x1161,0x11CA ],
- [ 0xE5D4, 0x1107,0x1161,0xD7D0 ],
- [ 0xE5D5, 0x1107,0x1161,0xD7D1 ],
- [ 0xE5D6, 0x1107,0x1161,0xD7D4 ],
- [ 0xE5D7, 0x1107,0x1161,0x11D0 ],
- [ 0xE5D8, 0x1107,0x1161,0x11D9 ],
- [ 0xE5D9, 0x1107,0x1161,0xD7E0 ],
- [ 0xE5DA, 0x1107,0x1161,0x11DC ],
- [ 0xE5DB, 0x1107,0x1161,0x11DD ],
- [ 0xE5DC, 0x1107,0x1161,0x11E2 ],
- [ 0xE5DD, 0x1107,0x1161,0x11E3 ],
- [ 0xE5DE, 0x1107,0x1161,0x11E6 ],
- [ 0xE5DF, 0x1107,0x1161,0x11E7 ],
- [ 0xE5E0, 0x1107,0x1161,0x11E8 ],
- [ 0xE5E1, 0x1107,0x1161,0x11EA ],
- [ 0xE5E2, 0x1107,0x1161,0xD7F0 ],
- [ 0xE5E3, 0x1107,0x1161,0x11EB ],
- [ 0xE5E4, 0x1107,0x1161,0x11F1 ],
- [ 0xE5E5, 0x1107,0x1161,0x11F0 ],
- [ 0xE5E6, 0x1107,0x1161,0x11F1 ],
- [ 0xE5E7, 0x1107,0x1161,0x11F6 ],
- [ 0xE5E8, 0x1107,0x1161,0x11F9 ],
- [ 0xE5EA, 0x1107,0x1176,0x11AF ],
- [ 0xE5EC, 0x1107,0x1177,0x11AF ],
- [ 0xE5ED, 0x1107,0x1162,0x11F0 ],
- [ 0xE5EE, 0x1107,0x1163,0x11E2 ],
- [ 0xE5F0, 0x1107,0x1165,0x11C7 ],
- [ 0xE5F1, 0x1107,0x1165,0x11CD ],
- [ 0xE5F2, 0x1107,0x1165,0x11D9 ],
- [ 0xE5F3, 0x1107,0x1165,0x11EB ],
- [ 0xE5F4, 0x1107,0x1165,0x11F0 ],
- [ 0xE5F6, 0x1107,0x117B,0x11AF ],
- [ 0xE5F8, 0x1107,0x117C,0x11A8 ],
- [ 0xE5F9, 0x1107,0x117C,0x11AF ],
- [ 0xE5FA, 0x1107,0x117C,0x11B7 ],
- [ 0xE5FB, 0x1107,0x117C,0x11BC ],
- [ 0xE5FC, 0x1107,0x1167,0x11D9 ],
- [ 0xE5FD, 0x1107,0x1167,0x11E2 ],
- [ 0xE5FE, 0x1107,0x1167,0xD7F1 ],
- [ 0xE5FF, 0x1107,0x1167,0x11F0 ],
- [ 0xE600, 0x1107,0x1167,0x11F1 ],
- [ 0xE601, 0x1107,0x1167,0x11F9 ],
- [ 0xE602, 0x1107,0x1169,0x11D0 ],
- [ 0xE603, 0x1107,0x1169,0x11D9 ],
- [ 0xE604, 0x1107,0x1169,0xD7E0 ],
- [ 0xE605, 0x1107,0x1169,0x11DC ],
- [ 0xE606, 0x1107,0x1169,0x11DD ],
- [ 0xE607, 0x1107,0x1169,0x11E2 ],
- [ 0xE608, 0x1107,0x1169,0x11E7 ],
- [ 0xE609, 0x1107,0x1169,0xD7EC ],
- [ 0xE60A, 0x1107,0x1169,0x11EB ],
- [ 0xE60B, 0x1107,0x1169,0x11F0 ],
- [ 0xE60E, 0x1107,0x116C,0x11D9 ],
- [ 0xE60F, 0x1107,0x116C,0xD7F0 ],
- [ 0xE610, 0x1107,0x116D,0x11D9 ],
- [ 0xE611, 0x1107,0x116D,0x11E2 ],
- [ 0xE612, 0x1107,0x116D,0x11F0 ],
- [ 0xE615, 0x1107,0x116E,0x11C7 ],
- [ 0xE616, 0x1107,0x116E,0x11D0 ],
- [ 0xE617, 0x1107,0x116E,0x11D1 ],
- [ 0xE618, 0x1107,0x116E,0x11D2 ],
- [ 0xE619, 0x1107,0x116E,0x11D9 ],
- [ 0xE61A, 0x1107,0x116E,0x11E2 ],
- [ 0xE61B, 0x1107,0x116E,0x11E6 ],
- [ 0xE61C, 0x1107,0x116E,0x11E7 ],
- [ 0xE61D, 0x1107,0x116E,0xD7F0 ],
- [ 0xE61E, 0x1107,0x116E,0x11EB ],
- [ 0xE61F, 0x1107,0x116E,0x11EF ],
- [ 0xE620, 0x1107,0x116E,0x11F0 ],
- [ 0xE621, 0x1107,0x116E,0x11F9 ],
- [ 0xE622, 0x1107,0x116F,0x11F9 ],
- [ 0xE626, 0x1107,0x1171,0x11D9 ],
- [ 0xE627, 0x1107,0x1171,0x11F9 ],
- [ 0xE628, 0x1107,0x1172,0x11D9 ],
- [ 0xE629, 0x1107,0x1172,0x11E2 ],
- [ 0xE62B, 0x1107,0x1173,0x11C3 ],
- [ 0xE62C, 0x1107,0x1173,0xD7D4 ],
- [ 0xE62D, 0x1107,0x1173,0x11D0 ],
- [ 0xE62E, 0x1107,0x1173,0x11D9 ],
- [ 0xE62F, 0x1107,0x1173,0x11DD ],
- [ 0xE630, 0x1107,0x1173,0x11E7 ],
- [ 0xE631, 0x1107,0x1173,0xD7F1 ],
- [ 0xE632, 0x1107,0x1173,0x11EB ],
- [ 0xE633, 0x1107,0x1173,0x11F0 ],
- [ 0xE634, 0x1107,0x1173,0x11F9 ],
- [ 0xE636, 0x1107,0x1174,0x11F9 ],
- [ 0xE637, 0x1107,0x1175,0x11CA ],
- [ 0xE638, 0x1107,0x1175,0xD7D0 ],
- [ 0xE639, 0x1107,0x1175,0x11D9 ],
- [ 0xE63A, 0x1107,0x1175,0x11E2 ],
- [ 0xE63B, 0x1107,0x1175,0x11E7 ],
- [ 0xE63C, 0x1107,0x1175,0xD7EE ],
- [ 0xE63D, 0x1107,0x1175,0xD7F0 ],
- [ 0xE63E, 0x1107,0x1175,0xD7F2 ],
- [ 0xE63F, 0x1107,0x1175,0x11EB ],
- [ 0xE640, 0x1107,0x1175,0x11F0 ],
- [ 0xE641, 0x1107,0x1175,0x11F1 ],
- [ 0xE642, 0x1107,0x1175,0x11F9 ],
- [ 0xE645, 0x1107,0x1199,0x11AB ],
- [ 0xE64B, 0x1107,0x119E,0x11A8 ],
- [ 0xE64C, 0x1107,0x119E,0x11C3 ],
- [ 0xE64D, 0x1107,0x119E,0x11AB ],
- [ 0xE64E, 0x1107,0x119E,0x11AE ],
- [ 0xE64F, 0x1107,0x119E,0x11AF ],
- [ 0xE650, 0x1107,0x119E,0x11B0 ],
- [ 0xE651, 0x1107,0x119E,0x11D0 ],
- [ 0xE652, 0x1107,0x119E,0x11B1 ],
- [ 0xE653, 0x1107,0x119E,0x11B2 ],
- [ 0xE654, 0x1107,0x119E,0x11D5 ],
- [ 0xE655, 0x1107,0x119E,0x11B3 ],
- [ 0xE656, 0x1107,0x119E,0x11B4 ],
- [ 0xE657, 0x1107,0x119E,0x11B6 ],
- [ 0xE658, 0x1107,0x119E,0x11D9 ],
- [ 0xE659, 0x1107,0x119E,0x11B7 ],
- [ 0xE65A, 0x1107,0x119E,0x11B8 ],
- [ 0xE65B, 0x1107,0x119E,0x11E3 ],
- [ 0xE65C, 0x1107,0x119E,0x11BA ],
- [ 0xE65D, 0x1107,0x119E,0xD7F1 ],
- [ 0xE65E, 0x1107,0x119E,0x11EB ],
- [ 0xE65F, 0x1107,0x119E,0x11F0 ],
- [ 0xE660, 0x1107,0x119E,0x11BD ],
- [ 0xE661, 0x1107,0x119E,0x11BE ],
- [ 0xE662, 0x1107,0x119E,0x11C0 ],
- [ 0xE664, 0x1107,0x119F,0x11AB ],
- [ 0xE665, 0x1107,0x119F,0x11AF ],
- [ 0xE666, 0x1107,0x119F,0x11BC ],
- [ 0xE669, 0x1107,0x11A1,0x11A8 ],
- [ 0xE66A, 0x1107,0x11A1,0x11AB ],
- [ 0xE66B, 0x1107,0x11A1,0x11AE ],
- [ 0xE66C, 0x1107,0x11A1,0x11AF ],
- [ 0xE66D, 0x1107,0x11A1,0x11B0 ],
- [ 0xE66E, 0x1107,0x11A1,0x11D9 ],
- [ 0xE66F, 0x1107,0x11A1,0x11B7 ],
- [ 0xE670, 0x1107,0x11A1,0x11B8 ],
- [ 0xE671, 0x1107,0x11A1,0x11BA ],
- [ 0xE672, 0x1107,0x11A1,0x11BC ],
- [ 0xE673, 0x1107,0x11A1,0x11F0 ],
- [ 0xE674, 0x1107,0x11A1,0x11F1 ],
- [ 0xE675, 0x1107,0x11A1,0x11BD ],
- [ 0xE676, 0x1107,0x11A1,0x11BE ],
- [ 0xE677, 0x1107,0x11A1,0x11C0 ],
- [ 0xE678, 0x1107,0x11A1,0x11C2 ],
- [ 0xE67A, 0x111E,0x1161,0x11A8 ],
- [ 0xE67B, 0x111E,0x1161,0x11B7 ],
- [ 0xE67D, 0x111E,0x1162,0x11AB ],
- [ 0xE67F, 0x111E,0x1165,0x11BA ],
- [ 0xE681, 0x111E,0x1166,0x11AF ],
- [ 0xE683, 0x111E,0x1167,0x11AB ],
- [ 0xE684, 0x111E,0x1167,0x11BA ],
- [ 0xE686, 0x111E,0x1168,0x11AF ],
- [ 0xE688, 0x111E,0x1169,0x11BA ],
- [ 0xE68A, 0x111E,0x116C,0x11BA ],
- [ 0xE68C, 0x111E,0x116E,0x11AF ],
- [ 0xE68D, 0x111E,0x116E,0x11B7 ],
- [ 0xE68E, 0x111E,0x116E,0x11BA ],
- [ 0xE693, 0x111E,0x1173,0x11AB ],
- [ 0xE694, 0x111E,0x1173,0x11AE ],
- [ 0xE695, 0x111E,0x1173,0x11AF ],
- [ 0xE696, 0x111E,0x1173,0x11BA ],
- [ 0xE698, 0x111E,0x1174,0x11BA ],
- [ 0xE69A, 0x111E,0x1175,0x11AF ],
- [ 0xE69B, 0x111E,0x1175,0x11B7 ],
- [ 0xE69C, 0x111E,0x1175,0x11BA ],
- [ 0xE69E, 0x111E,0x119E,0x11AF ],
- [ 0xE6A0, 0x111E,0x11A1,0x11AB ],
- [ 0xE6A1, 0x111E,0x11A1,0x11BA ],
- [ 0xE6A4, 0x1120,0x1161,0x11A8 ],
- [ 0xE6A5, 0x1120,0x1161,0x11AB ],
- [ 0xE6A6, 0x1120,0x1161,0x11AF ],
- [ 0xE6A7, 0x1120,0x1161,0x11B7 ],
- [ 0xE6A8, 0x1120,0x1161,0x11B8 ],
- [ 0xE6A9, 0x1120,0x1161,0x11BA ],
- [ 0xE6AD, 0x1120,0x1165,0x11A8 ],
- [ 0xE6AE, 0x1120,0x1165,0x11AB ],
- [ 0xE6AF, 0x1120,0x1165,0x11AE ],
- [ 0xE6B0, 0x1120,0x1165,0x11AF ],
- [ 0xE6B1, 0x1120,0x1165,0x11B2 ],
- [ 0xE6B2, 0x1120,0x1165,0x11D5 ],
- [ 0xE6B3, 0x1120,0x1165,0x11B7 ],
- [ 0xE6B4, 0x1120,0x1165,0x11BA ],
- [ 0xE6B6, 0x1120,0x1166,0x11AB ],
- [ 0xE6B7, 0x1120,0x1166,0x11BA ],
- [ 0xE6B9, 0x1120,0x1167,0x11BA ],
- [ 0xE6BB, 0x1120,0x1168,0x11BA ],
- [ 0xE6BD, 0x1120,0x1169,0x11A8 ],
- [ 0xE6BE, 0x1120,0x1169,0x11AF ],
- [ 0xE6BF, 0x1120,0x1169,0x11B7 ],
- [ 0xE6C0, 0x1120,0x1169,0x11BC ],
- [ 0xE6C4, 0x1120,0x116C,0x11BA ],
- [ 0xE6C7, 0x1120,0x116E,0x11A8 ],
- [ 0xE6C8, 0x1120,0x116E,0x11AF ],
- [ 0xE6C9, 0x1120,0x116E,0x11B2 ],
- [ 0xE6CA, 0x1120,0x116E,0x11B7 ],
- [ 0xE6CB, 0x1120,0x116E,0x11BA ],
- [ 0xE6CC, 0x1120,0x116E,0x11BC ],
- [ 0xE6CD, 0x1120,0x116E,0x11F0 ],
- [ 0xE6D3, 0x1120,0x1171,0x11AF ],
- [ 0xE6D4, 0x1120,0x1171,0x11BA ],
- [ 0xE6D8, 0x1120,0x1173,0x11A8 ],
- [ 0xE6D9, 0x1120,0x1173,0x11AB ],
- [ 0xE6DA, 0x1120,0x1173,0x11AE ],
- [ 0xE6DB, 0x1120,0x1173,0x11AF ],
- [ 0xE6DC, 0x1120,0x1173,0x11B0 ],
- [ 0xE6DD, 0x1120,0x1173,0x11B2 ],
- [ 0xE6DE, 0x1120,0x1173,0x11B3 ],
- [ 0xE6DF, 0x1120,0x1173,0x11B6 ],
- [ 0xE6E0, 0x1120,0x1173,0x11B7 ],
- [ 0xE6E1, 0x1120,0x1173,0x11BA ],
- [ 0xE6E2, 0x1120,0x1173,0x11BC ],
- [ 0xE6E3, 0x1120,0x1173,0x11BD ],
- [ 0xE6E5, 0x1120,0x1174,0x11AF ],
- [ 0xE6E6, 0x1120,0x1174,0x11BA ],
- [ 0xE6E8, 0x1120,0x1175,0x11A8 ],
- [ 0xE6E9, 0x1120,0x1175,0x11AB ],
- [ 0xE6EA, 0x1120,0x1175,0x11AF ],
- [ 0xE6EB, 0x1120,0x1175,0x11D0 ],
- [ 0xE6EC, 0x1120,0x1175,0x11B7 ],
- [ 0xE6ED, 0x1120,0x1175,0x11BA ],
- [ 0xE6F0, 0x1120,0x119E,0x11AB ],
- [ 0xE6F1, 0x1120,0x119E,0x11AE ],
- [ 0xE6F2, 0x1120,0x119E,0x11AF ],
- [ 0xE6F3, 0x1120,0x119E,0x11B7 ],
- [ 0xE6F4, 0x1120,0x119E,0x11BA ],
- [ 0xE6F6, 0x1120,0x11A1,0x11AB ],
- [ 0xE6F7, 0x1120,0x11A1,0x11BA ],
- [ 0xE6F8, 0x1108,0x1161,0x11D0 ],
- [ 0xE6F9, 0x1108,0x1161,0x11D9 ],
- [ 0xE6FA, 0x1108,0x1161,0x11E2 ],
- [ 0xE6FB, 0x1108,0x1161,0x11E6 ],
- [ 0xE6FC, 0x1108,0x1161,0x11F0 ],
- [ 0xE6FD, 0x1108,0x1161,0x11F9 ],
- [ 0xE6FE, 0x1108,0x1163,0x11E2 ],
- [ 0xE6FF, 0x1108,0x1163,0x11F0 ],
- [ 0xE700, 0x1108,0x1165,0x11D9 ],
- [ 0xE701, 0x1108,0x1165,0x11F9 ],
- [ 0xE702, 0x1108,0x1167,0x11D9 ],
- [ 0xE703, 0x1108,0x1167,0x11E2 ],
- [ 0xE704, 0x1108,0x1167,0x11F0 ],
- [ 0xE705, 0x1108,0x1167,0x11F9 ],
- [ 0xE706, 0x1108,0x1169,0x11D9 ],
- [ 0xE707, 0x1108,0x1169,0x11E2 ],
- [ 0xE708, 0x1108,0x1169,0x11F0 ],
- [ 0xE709, 0x1108,0x116D,0x11E2 ],
- [ 0xE70A, 0x1108,0x116E,0x11D9 ],
- [ 0xE70B, 0x1108,0x116E,0x11E2 ],
- [ 0xE70C, 0x1108,0x116E,0x11F0 ],
- [ 0xE70D, 0x1108,0x116E,0x11F9 ],
- [ 0xE70E, 0x1108,0x116F,0x11F9 ],
- [ 0xE710, 0x1108,0xD7B5,0x11F9 ],
- [ 0xE711, 0x1108,0x1172,0x11E2 ],
- [ 0xE712, 0x1108,0x1173,0x11D9 ],
- [ 0xE713, 0x1108,0x1173,0x11E2 ],
- [ 0xE714, 0x1108,0x1173,0xD7E6 ],
- [ 0xE715, 0x1108,0x1173,0x11F0 ],
- [ 0xE716, 0x1108,0x1173,0x11F9 ],
- [ 0xE717, 0x1108,0x1174,0x11F0 ],
- [ 0xE718, 0x1108,0x1174,0x11F9 ],
- [ 0xE719, 0x1108,0x1175,0x11D9 ],
- [ 0xE71A, 0x1108,0x1175,0x11E2 ],
- [ 0xE71B, 0x1108,0x1175,0x11F0 ],
- [ 0xE71C, 0x1108,0x1175,0x11F9 ],
- [ 0xE71E, 0x1108,0x119E,0x11AF ],
- [ 0xE71F, 0x1108,0x119E,0x11B3 ],
- [ 0xE720, 0x1108,0x119E,0x11D9 ],
- [ 0xE722, 0x1108,0x11A1,0x11A8 ],
- [ 0xE723, 0x1108,0x11A1,0x11BC ],
- [ 0xE724, 0x1108,0x11A1,0x11F0 ],
- [ 0xE726, 0x1121,0x1161,0x11A8 ],
- [ 0xE727, 0x1121,0x1161,0x11AB ],
- [ 0xE728, 0x1121,0x1161,0x11AE ],
- [ 0xE729, 0x1121,0x1161,0x11AF ],
- [ 0xE72A, 0x1121,0x1161,0x11B2 ],
- [ 0xE72B, 0x1121,0x1161,0x11B7 ],
- [ 0xE72C, 0x1121,0x1161,0x11B8 ],
- [ 0xE72D, 0x1121,0x1161,0x11BA ],
- [ 0xE72E, 0x1121,0x1161,0xD7F1 ],
- [ 0xE72F, 0x1121,0x1161,0xD7F2 ],
- [ 0xE730, 0x1121,0x1161,0x11BC ],
- [ 0xE731, 0x1121,0x1161,0x11F0 ],
- [ 0xE732, 0x1121,0x1161,0x11C2 ],
- [ 0xE734, 0x1121,0x1162,0x11B8 ],
- [ 0xE736, 0x1121,0x1163,0x11BC ],
- [ 0xE737, 0x1121,0x1163,0x11F0 ],
- [ 0xE738, 0x1121,0x1163,0x11C1 ],
- [ 0xE739, 0x1121,0x1163,0x11C2 ],
- [ 0xE73C, 0x1121,0x1165,0x11A8 ],
- [ 0xE73D, 0x1121,0x1165,0x11AB ],
- [ 0xE73E, 0x1121,0x1165,0x11AF ],
- [ 0xE73F, 0x1121,0x1165,0x11B7 ],
- [ 0xE740, 0x1121,0x1165,0x11BA ],
- [ 0xE742, 0x1121,0x1166,0x11AB ],
- [ 0xE743, 0x1121,0x1166,0x11AF ],
- [ 0xE745, 0x1121,0x1167,0x11A8 ],
- [ 0xE746, 0x1121,0x1167,0x11AB ],
- [ 0xE747, 0x1121,0x1167,0x11AF ],
- [ 0xE748, 0x1121,0x1167,0x11B7 ],
- [ 0xE749, 0x1121,0x1167,0x11BA ],
- [ 0xE74B, 0x1121,0x1168,0x11AB ],
- [ 0xE74D, 0x1121,0x1169,0x11A8 ],
- [ 0xE74E, 0x1121,0x1169,0x11AB ],
- [ 0xE74F, 0x1121,0x1169,0x11AE ],
- [ 0xE750, 0x1121,0x1169,0x11AF ],
- [ 0xE751, 0x1121,0x1169,0x11B7 ],
- [ 0xE752, 0x1121,0x1169,0x11BA ],
- [ 0xE753, 0x1121,0x1169,0x11BC ],
- [ 0xE754, 0x1121,0x1169,0x11F0 ],
- [ 0xE756, 0x1121,0x116A,0x11BC ],
- [ 0xE757, 0x1121,0x116A,0x11F0 ],
- [ 0xE758, 0x1121,0x116A,0x11F9 ],
- [ 0xE75A, 0x1121,0x116B,0x11BA ],
- [ 0xE75E, 0x1121,0x116E,0x11A8 ],
- [ 0xE75F, 0x1121,0x116E,0x11AB ],
- [ 0xE760, 0x1121,0x116E,0x11AF ],
- [ 0xE761, 0x1121,0x116E,0x11D9 ],
- [ 0xE762, 0x1121,0x116E,0x11B7 ],
- [ 0xE763, 0x1121,0x116E,0x11BA ],
- [ 0xE764, 0x1121,0x116E,0x11BD ],
- [ 0xE765, 0x1121,0x116E,0x11BE ],
- [ 0xE76C, 0x1121,0x1172,0x11B8 ],
- [ 0xE76D, 0x1121,0x1172,0x11BA ],
- [ 0xE76E, 0x1121,0x1172,0x11BD ],
- [ 0xE771, 0x1121,0x1173,0x11A8 ],
- [ 0xE772, 0x1121,0x1173,0x11AB ],
- [ 0xE773, 0x1121,0x1173,0x11AE ],
- [ 0xE774, 0x1121,0x1173,0x11AF ],
- [ 0xE775, 0x1121,0x1173,0x11B6 ],
- [ 0xE776, 0x1121,0x1173,0x11D9 ],
- [ 0xE777, 0x1121,0x1173,0x11B7 ],
- [ 0xE778, 0x1121,0x1173,0x11BA ],
- [ 0xE779, 0x1121,0x1173,0x11BE ],
- [ 0xE77B, 0x1121,0x1174,0x11A8 ],
- [ 0xE77D, 0x1121,0x1175,0x11A8 ],
- [ 0xE77E, 0x1121,0x1175,0x11AB ],
- [ 0xE77F, 0x1121,0x1175,0x11AF ],
- [ 0xE780, 0x1121,0x1175,0x11B7 ],
- [ 0xE781, 0x1121,0x1175,0x11B8 ],
- [ 0xE782, 0x1121,0x1175,0x11BA ],
- [ 0xE783, 0x1121,0x1175,0x11BC ],
- [ 0xE784, 0x1121,0x1175,0x11F0 ],
- [ 0xE787, 0x1121,0x119E,0x11AB ],
- [ 0xE788, 0x1121,0x119E,0x11AE ],
- [ 0xE789, 0x1121,0x119E,0x11AF ],
- [ 0xE78A, 0x1121,0x119E,0x11B3 ],
- [ 0xE78B, 0x1121,0x119E,0x11D9 ],
- [ 0xE78C, 0x1121,0x119E,0x11B7 ],
- [ 0xE78D, 0x1121,0x119E,0x11B8 ],
- [ 0xE78E, 0x1121,0x119E,0x11BA ],
- [ 0xE78F, 0x1121,0x119E,0xD7F2 ],
- [ 0xE790, 0x1121,0x119E,0x11F0 ],
- [ 0xE791, 0x1121,0x119E,0x11C2 ],
- [ 0xE793, 0x1121,0x11A1,0x11BA ],
- [ 0xE796, 0x1122,0x1162,0x11AB ],
- [ 0xE797, 0x1122,0x1162,0x11BA ],
- [ 0xE799, 0x1122,0x1165,0x11B8 ],
- [ 0xE79A, 0x1122,0x1165,0x11E6 ],
- [ 0xE79B, 0x1122,0x1165,0x11BA ],
- [ 0xE79D, 0x1122,0x1166,0x11AF ],
- [ 0xE79F, 0x1122,0x1167,0x11A8 ],
- [ 0xE7A0, 0x1122,0x1167,0x11BA ],
- [ 0xE7A2, 0x1122,0x1168,0x11BA ],
- [ 0xE7A5, 0x1122,0x116C,0x11BA ],
- [ 0xE7A7, 0x1122,0x116E,0x11AB ],
- [ 0xE7A8, 0x1122,0x116E,0x11AF ],
- [ 0xE7A9, 0x1122,0x116E,0x11B7 ],
- [ 0xE7AA, 0x1122,0x116E,0x11BA ],
- [ 0xE7AE, 0x1122,0x1171,0x11AB ],
- [ 0xE7B0, 0x1122,0x1173,0x11AB ],
- [ 0xE7B1, 0x1122,0x1173,0x11AF ],
- [ 0xE7B2, 0x1122,0x1173,0x11B7 ],
- [ 0xE7B3, 0x1122,0x1173,0x11BA ],
- [ 0xE7B5, 0x1122,0x1174,0x11AB ],
- [ 0xE7B6, 0x1122,0x1174,0x11AF ],
- [ 0xE7B7, 0x1122,0x1174,0x11B7 ],
- [ 0xE7B8, 0x1122,0x1174,0x11BA ],
- [ 0xE7BA, 0x1122,0x1175,0x11AF ],
- [ 0xE7BB, 0x1122,0x1175,0x11B7 ],
- [ 0xE7BD, 0x1122,0x119E,0x11AB ],
- [ 0xE7BF, 0x1123,0x1161,0x11B8 ],
- [ 0xE7C2, 0x1123,0x1165,0x11AF ],
- [ 0xE7C3, 0x1123,0x1165,0x11B2 ],
- [ 0xE7C4, 0x1123,0x1165,0x11BA ],
- [ 0xE7C6, 0x1123,0x1167,0x11BA ],
- [ 0xE7CA, 0x1123,0x116E,0x11AF ],
- [ 0xE7CB, 0x1123,0x116E,0x11B7 ],
- [ 0xE7CD, 0x1123,0x1172,0x11B7 ],
- [ 0xE7CF, 0x1123,0x1173,0x11AB ],
- [ 0xE7D0, 0x1123,0x1173,0x11BA ],
- [ 0xE7D3, 0x1123,0x1175,0x11AF ],
- [ 0xE7D5, 0x1123,0x119E,0x11AF ],
- [ 0xE7DD, 0x1126,0x119E,0x11AB ],
- [ 0xE7E0, 0x1127,0x1161,0x11A8 ],
- [ 0xE7E1, 0x1127,0x1161,0x11AB ],
- [ 0xE7E2, 0x1127,0x1161,0x11B7 ],
- [ 0xE7E3, 0x1127,0x1161,0x11BA ],
- [ 0xE7E4, 0x1127,0x1161,0x11BC ],
- [ 0xE7E5, 0x1127,0x1161,0x11F0 ],
- [ 0xE7E8, 0x1127,0x1163,0x11A8 ],
- [ 0xE7E9, 0x1127,0x1163,0x11BC ],
- [ 0xE7EA, 0x1127,0x1163,0x11F0 ],
- [ 0xE7EC, 0x1127,0x1165,0x11A8 ],
- [ 0xE7F0, 0x1127,0x1169,0x11A8 ],
- [ 0xE7F1, 0x1127,0x1169,0x11AB ],
- [ 0xE7F2, 0x1127,0x1169,0x11B7 ],
- [ 0xE7F3, 0x1127,0x1169,0x11BA ],
- [ 0xE7F4, 0x1127,0x1169,0x11BC ],
- [ 0xE7F5, 0x1127,0x1169,0x11F0 ],
- [ 0xE7F6, 0x1127,0x1169,0x11BD ],
- [ 0xE7F7, 0x1127,0x1169,0x11BE ],
- [ 0xE7F9, 0x1127,0x116A,0x11BC ],
- [ 0xE7FA, 0x1127,0x116A,0x11F0 ],
- [ 0xE7FD, 0x1127,0x116C,0x11AB ],
- [ 0xE7FE, 0x1127,0x116C,0x11AF ],
- [ 0xE801, 0x1127,0x116E,0x11A8 ],
- [ 0xE802, 0x1127,0x116E,0x11AF ],
- [ 0xE803, 0x1127,0x116E,0x11B7 ],
- [ 0xE806, 0x1127,0x1173,0x11A8 ],
- [ 0xE807, 0x1127,0x1173,0x11AB ],
- [ 0xE808, 0x1127,0x1173,0x11AE ],
- [ 0xE809, 0x1127,0x1173,0x11AF ],
- [ 0xE80A, 0x1127,0x1173,0x11B7 ],
- [ 0xE80B, 0x1127,0x1173,0x11BA ],
- [ 0xE80C, 0x1127,0x1173,0x11BD ],
- [ 0xE80E, 0x1127,0x1174,0x11BC ],
- [ 0xE80F, 0x1127,0x1174,0x11F0 ],
- [ 0xE811, 0x1127,0x1175,0x11A8 ],
- [ 0xE812, 0x1127,0x1175,0x11AB ],
- [ 0xE813, 0x1127,0x1175,0x11AE ],
- [ 0xE814, 0x1127,0x1175,0x11AF ],
- [ 0xE815, 0x1127,0x1175,0x11B7 ],
- [ 0xE816, 0x1127,0x1175,0x11BA ],
- [ 0xE817, 0x1127,0x1175,0xD7F2 ],
- [ 0xE818, 0x1127,0x1175,0x11BC ],
- [ 0xE819, 0x1127,0x1175,0x11F0 ],
- [ 0xE81B, 0x1127,0x119E,0x11A8 ],
- [ 0xE81C, 0x1127,0x119E,0x11AB ],
- [ 0xE81D, 0x1127,0x119E,0x11AF ],
- [ 0xE81E, 0x1127,0x119E,0x11B7 ],
- [ 0xE820, 0x1127,0x11A1,0x11AB ],
- [ 0xE821, 0x1127,0x11A1,0x11AF ],
- [ 0xE822, 0x1127,0x11A1,0x11BC ],
- [ 0xE824, 0x1128,0x1169,0x11BC ],
- [ 0xE826, 0x1128,0x119E,0x11AF ],
- [ 0xE82D, 0x1129,0x1165,0x11A8 ],
- [ 0xE82E, 0x1129,0x1165,0x11AF ],
- [ 0xE82F, 0x1129,0x1165,0x11B2 ],
- [ 0xE830, 0x1129,0x1165,0x11D5 ],
- [ 0xE831, 0x1129,0x1165,0x11B7 ],
- [ 0xE832, 0x1129,0x1165,0x11BA ],
- [ 0xE835, 0x1129,0x1169,0x11B7 ],
- [ 0xE836, 0x1129,0x1169,0x11B8 ],
- [ 0xE838, 0x1129,0x116E,0x11A8 ],
- [ 0xE839, 0x1129,0x116E,0x11FB ],
- [ 0xE83B, 0x1129,0x1171,0x11AF ],
- [ 0xE83C, 0x1129,0x1171,0x11B7 ],
- [ 0xE83E, 0x1129,0x1173,0x11AB ],
- [ 0xE83F, 0x1129,0x1173,0x11AE ],
- [ 0xE840, 0x1129,0x1173,0x11BA ],
- [ 0xE842, 0x1129,0x1174,0x11B7 ],
- [ 0xE844, 0x1129,0x1175,0x11AB ],
- [ 0xE845, 0x1129,0x1175,0x11AF ],
- [ 0xE846, 0x1129,0x1175,0x11B7 ],
- [ 0xE848, 0x1129,0x119E,0x11AB ],
- [ 0xE849, 0x1129,0x119E,0x11AF ],
- [ 0xE84C, 0x112A,0x1161,0x11AB ],
- [ 0xE84E, 0x112A,0x1169,0x11AB ],
- [ 0xE851, 0x112A,0x1173,0x11AF ],
- [ 0xE854, 0x112A,0x119E,0x11AF ],
- [ 0xE856, 0xA974,0x1161,0x11AB ],
- [ 0xE858, 0x112B,0x1161,0x11A8 ],
- [ 0xE859, 0x112B,0x1161,0x11AB ],
- [ 0xE85A, 0x112B,0x1161,0x11AE ],
- [ 0xE85B, 0x112B,0x1161,0x11AF ],
- [ 0xE85C, 0x112B,0x1161,0x11B0 ],
- [ 0xE85D, 0x112B,0x1161,0x11D9 ],
- [ 0xE85E, 0x112B,0x1161,0x11B7 ],
- [ 0xE85F, 0x112B,0x1161,0x11BA ],
- [ 0xE860, 0x112B,0x1161,0x11EB ],
- [ 0xE861, 0x112B,0x1161,0x11BC ],
- [ 0xE862, 0x112B,0x1161,0x11F0 ],
- [ 0xE863, 0x112B,0x1161,0x11C0 ],
- [ 0xE864, 0x112B,0x1161,0x11F9 ],
- [ 0xE866, 0x112B,0x1162,0x11AB ],
- [ 0xE867, 0x112B,0x1162,0x11BA ],
- [ 0xE869, 0x112B,0x1165,0x11AB ],
- [ 0xE86A, 0x112B,0x1165,0x11B7 ],
- [ 0xE86B, 0x112B,0x1165,0x11B8 ],
- [ 0xE86C, 0x112B,0x1165,0x11BC ],
- [ 0xE86E, 0x112B,0x1166,0x11BA ],
- [ 0xE870, 0x112B,0x1167,0x11A8 ],
- [ 0xE871, 0x112B,0x1167,0x11AF ],
- [ 0xE872, 0x112B,0x1167,0x11D9 ],
- [ 0xE873, 0x112B,0x1167,0x11BA ],
- [ 0xE875, 0x112B,0x1168,0x11BA ],
- [ 0xE877, 0x112B,0x1169,0x11AB ],
- [ 0xE878, 0x112B,0x1169,0x11AF ],
- [ 0xE879, 0x112B,0x1169,0x11B3 ],
- [ 0xE87A, 0x112B,0x1169,0x11D9 ],
- [ 0xE87B, 0x112B,0x1169,0x11B7 ],
- [ 0xE87C, 0x112B,0x1169,0x11DD ],
- [ 0xE87D, 0x112B,0x1169,0x11B8 ],
- [ 0xE87E, 0x112B,0x1169,0x11BA ],
- [ 0xE87F, 0x112B,0x1169,0x11BC ],
- [ 0xE881, 0x112B,0x116A,0x11AB ],
- [ 0xE886, 0x112B,0x116E,0x11AB ],
- [ 0xE887, 0x112B,0x116E,0x11AF ],
- [ 0xE888, 0x112B,0x116E,0x11B7 ],
- [ 0xE889, 0x112B,0x116E,0x11B8 ],
- [ 0xE88A, 0x112B,0x116E,0x11BA ],
- [ 0xE88B, 0x112B,0x116E,0x11BC ],
- [ 0xE88C, 0x112B,0x116E,0x11F0 ],
- [ 0xE88D, 0x112B,0x116E,0x11C2 ],
- [ 0xE88E, 0x112B,0x116E,0x11F9 ],
- [ 0xE891, 0x112B,0x1171,0x11AF ],
- [ 0xE892, 0x112B,0x1171,0x11D9 ],
- [ 0xE894, 0x112B,0x1172,0x11F9 ],
- [ 0xE896, 0x112B,0x1173,0x11AB ],
- [ 0xE897, 0x112B,0x1173,0x11C7 ],
- [ 0xE898, 0x112B,0x1173,0x11AF ],
- [ 0xE899, 0x112B,0x1173,0x11B3 ],
- [ 0xE89A, 0x112B,0x1173,0x11D9 ],
- [ 0xE89B, 0x112B,0x1173,0x11B7 ],
- [ 0xE89C, 0x112B,0x1173,0x11E2 ],
- [ 0xE89D, 0x112B,0x1173,0x11BA ],
- [ 0xE89E, 0x112B,0x1173,0x11BC ],
- [ 0xE8A2, 0x112B,0x1175,0x11A8 ],
- [ 0xE8A3, 0x112B,0x1175,0x11AB ],
- [ 0xE8A4, 0x112B,0x1175,0x11AF ],
- [ 0xE8A5, 0x112B,0x1175,0x11D9 ],
- [ 0xE8A6, 0x112B,0x1175,0x11BC ],
- [ 0xE8A8, 0x112B,0x119E,0x11A8 ],
- [ 0xE8A9, 0x112B,0x119E,0x11AB ],
- [ 0xE8AA, 0x112B,0x119E,0x11AF ],
- [ 0xE8AB, 0x112B,0x119E,0x11B0 ],
- [ 0xE8AC, 0x112B,0x119E,0x11B2 ],
- [ 0xE8AD, 0x112B,0x119E,0x11B3 ],
- [ 0xE8AE, 0x112B,0x119E,0x11D9 ],
- [ 0xE8AF, 0x112B,0x119E,0x11B7 ],
- [ 0xE8B0, 0x112B,0x119E,0x11EB ],
- [ 0xE8B1, 0x112B,0x119E,0x11BC ],
- [ 0xE8B3, 0x112B,0x11A1,0x11A8 ],
- [ 0xE8B4, 0x112B,0x11A1,0x11AB ],
- [ 0xE8B5, 0x112B,0x11A1,0x11AF ],
- [ 0xE8B7, 0x112C,0x1161,0x11AB ],
- [ 0xE8B8, 0x112C,0x1161,0x11BC ],
- [ 0xE8B9, 0x112C,0x1161,0x11F0 ],
- [ 0xE8BA, 0x112C,0x1161,0x11F9 ],
- [ 0xE8BC, 0x112C,0x1169,0x11AB ],
- [ 0xE8BE, 0x112C,0x116A,0x11AB ],
- [ 0xE8C0, 0x112C,0x116E,0x11AB ],
- [ 0xE8C1, 0x112C,0x116E,0x11BC ],
- [ 0xE8C2, 0x112C,0x116E,0x11F0 ],
- [ 0xE8C3, 0x112C,0x116E,0x11F9 ],
- [ 0xE8C5, 0x112C,0x1172,0x11AB ],
- [ 0xE8C7, 0x112C,0x1173,0x11AB ],
- [ 0xE8C8, 0x112C,0x1173,0x11B7 ],
- [ 0xE8C9, 0x112C,0x1173,0x11E2 ],
- [ 0xE8CA, 0x112C,0x1173,0x11BC ],
- [ 0xE8CD, 0x1109,0x1161,0x11C7 ],
- [ 0xE8CE, 0x1109,0x1161,0x11CA ],
- [ 0xE8CF, 0x1109,0x1161,0xD7D4 ],
- [ 0xE8D0, 0x1109,0x1161,0x11CD ],
- [ 0xE8D1, 0x1109,0x1161,0x11D0 ],
- [ 0xE8D2, 0x1109,0x1161,0x11D9 ],
- [ 0xE8D3, 0x1109,0x1161,0x11DD ],
- [ 0xE8D4, 0x1109,0x1161,0x11E2 ],
- [ 0xE8D5, 0x1109,0x1161,0x11E7 ],
- [ 0xE8D6, 0x1109,0x1161,0x11E8 ],
- [ 0xE8D7, 0x1109,0x1161,0xD7F2 ],
- [ 0xE8D8, 0x1109,0x1161,0x11EB ],
- [ 0xE8D9, 0x1109,0x1161,0x11F1 ],
- [ 0xE8DA, 0x1109,0x1161,0x11F0 ],
- [ 0xE8DB, 0x1109,0x1161,0x11F1 ],
- [ 0xE8DC, 0x1109,0x1161,0x11F9 ],
- [ 0xE8E0, 0x1109,0x11A3,0x11B7 ],
- [ 0xE8E1, 0x1109,0x1162,0x11E6 ],
- [ 0xE8E2, 0x1109,0x1162,0x11F0 ],
- [ 0xE8E3, 0x1109,0x1163,0x11D9 ],
- [ 0xE8E4, 0x1109,0x1163,0x11E2 ],
- [ 0xE8E5, 0x1109,0x1163,0x11EB ],
- [ 0xE8E6, 0x1109,0x1163,0x11F0 ],
- [ 0xE8E7, 0x1109,0x1163,0x11F1 ],
- [ 0xE8E9, 0x1109,0x1165,0x11C3 ],
- [ 0xE8EA, 0x1109,0x1165,0x11D9 ],
- [ 0xE8EB, 0x1109,0x1165,0x11E5 ],
- [ 0xE8EC, 0x1109,0x1165,0x11E7 ],
- [ 0xE8ED, 0x1109,0x1165,0x11EB ],
- [ 0xE8EE, 0x1109,0x1165,0x11EC ],
- [ 0xE8EF, 0x1109,0x1165,0x11ED ],
- [ 0xE8F0, 0x1109,0x1165,0x11F0 ],
- [ 0xE8F1, 0x1109,0x1165,0x11F9 ],
- [ 0xE8F5, 0x1109,0x117C,0x11A8 ],
- [ 0xE8F6, 0x1109,0x117C,0x11AF ],
- [ 0xE8F7, 0x1109,0x117C,0x11B7 ],
- [ 0xE8F8, 0x1109,0x117C,0x11BA ],
- [ 0xE8F9, 0x1109,0x117C,0x11BB ],
- [ 0xE8FA, 0x1109,0x117C,0x11BC ],
- [ 0xE8FB, 0x1109,0x1166,0xD7FB ],
- [ 0xE8FC, 0x1109,0x1167,0x11D5 ],
- [ 0xE8FD, 0x1109,0x1167,0x11D9 ],
- [ 0xE8FE, 0x1109,0x1167,0x11DD ],
- [ 0xE8FF, 0x1109,0x1167,0x11E2 ],
- [ 0xE900, 0x1109,0x1167,0x11E3 ],
- [ 0xE901, 0x1109,0x1167,0x11E4 ],
- [ 0xE902, 0x1109,0x1167,0x11E5 ],
- [ 0xE903, 0x1109,0x1167,0x11E7 ],
- [ 0xE904, 0x1109,0x1167,0x11F0 ],
- [ 0xE905, 0x1109,0x1167,0x11F1 ],
- [ 0xE906, 0x1109,0x1167,0x11F9 ],
- [ 0xE909, 0x1109,0x1168,0x11F0 ],
- [ 0xE90A, 0x1109,0x1169,0x11C7 ],
- [ 0xE90B, 0x1109,0x1169,0x11D9 ],
- [ 0xE90C, 0x1109,0x1169,0x11E2 ],
- [ 0xE90D, 0x1109,0x1169,0xD7E7 ],
- [ 0xE90E, 0x1109,0x1169,0x11E8 ],
- [ 0xE90F, 0x1109,0x1169,0xD7F0 ],
- [ 0xE910, 0x1109,0x1169,0x11EB ],
- [ 0xE911, 0x1109,0x1169,0x11F0 ],
- [ 0xE912, 0x1109,0x116A,0x11D9 ],
- [ 0xE913, 0x1109,0x116A,0x11F0 ],
- [ 0xE914, 0x1109,0x116A,0x11F9 ],
- [ 0xE915, 0x1109,0x116B,0x11F9 ],
- [ 0xE919, 0x1109,0x116C,0x11F0 ],
- [ 0xE91A, 0x1109,0x116D,0x11D9 ],
- [ 0xE91B, 0x1109,0x116D,0x11E2 ],
- [ 0xE91C, 0x1109,0x116D,0x11F0 ],
- [ 0xE91D, 0x1109,0x116D,0x11F1 ],
- [ 0xE91F, 0x1109,0x1187,0x11AF ],
- [ 0xE921, 0x1109,0x1188,0x11AB ],
- [ 0xE922, 0x1109,0x1188,0x11AF ],
- [ 0xE923, 0x1109,0x1188,0x11BA ],
- [ 0xE924, 0x1109,0x116E,0x11D0 ],
- [ 0xE925, 0x1109,0x116E,0x11D9 ],
- [ 0xE926, 0x1109,0x116E,0x11E2 ],
- [ 0xE927, 0x1109,0x116E,0x11E4 ],
- [ 0xE928, 0x1109,0x116E,0x11E6 ],
- [ 0xE929, 0x1109,0x116E,0x11E7 ],
- [ 0xE92A, 0x1109,0x116E,0xD7F0 ],
- [ 0xE92B, 0x1109,0x116E,0x11EB ],
- [ 0xE92C, 0x1109,0x116E,0x11F0 ],
- [ 0xE92D, 0x1109,0x116E,0x11F9 ],
- [ 0xE92F, 0x1109,0x1189,0x11AB ],
- [ 0xE930, 0x1109,0x1189,0x11B7 ],
- [ 0xE932, 0x1109,0xD7B5,0x11AB ],
- [ 0xE934, 0x1109,0x1171,0x11D9 ],
- [ 0xE935, 0x1109,0x1171,0x11E6 ],
- [ 0xE936, 0x1109,0x1171,0x11E7 ],
- [ 0xE937, 0x1109,0x1172,0x11D9 ],
- [ 0xE938, 0x1109,0x1172,0x11E2 ],
- [ 0xE939, 0x1109,0x1172,0x11E6 ],
- [ 0xE93A, 0x1109,0x1172,0x11F0 ],
- [ 0xE93C, 0x1109,0x118E,0x11AB ],
- [ 0xE93D, 0x1109,0x118E,0x11F0 ],
- [ 0xE942, 0x1109,0x1191,0x11AB ],
- [ 0xE943, 0x1109,0x1191,0x11AF ],
- [ 0xE944, 0x1109,0x1191,0x11D9 ],
- [ 0xE945, 0x1109,0x1191,0x11F0 ],
- [ 0xE946, 0x1109,0x1191,0x11F9 ],
- [ 0xE948, 0x1109,0x1192,0x11BC ],
- [ 0xE94A, 0x1109,0xD7B8,0x11AF ],
- [ 0xE94C, 0x1109,0x1193,0x11AF ],
- [ 0xE94E, 0x1109,0x1194,0x11AB ],
- [ 0xE94F, 0x1109,0x1194,0x11AF ],
- [ 0xE950, 0x1109,0x1194,0x11B7 ],
- [ 0xE951, 0x1109,0x1194,0x11B8 ],
- [ 0xE952, 0x1109,0x1194,0x11BC ],
- [ 0xE953, 0x1109,0x1173,0x11D9 ],
- [ 0xE954, 0x1109,0x1173,0x11E2 ],
- [ 0xE955, 0x1109,0x1173,0x11E3 ],
- [ 0xE956, 0x1109,0x1173,0xD7F0 ],
- [ 0xE957, 0x1109,0x1173,0xD7F2 ],
- [ 0xE958, 0x1109,0x1173,0x11EB ],
- [ 0xE959, 0x1109,0x1173,0x11F1 ],
- [ 0xE95A, 0x1109,0x1173,0xD7F6 ],
- [ 0xE95B, 0x1109,0x1173,0x11F0 ],
- [ 0xE95C, 0x1109,0x1173,0x11F2 ],
- [ 0xE95C, 0x1109,0x1173,0x11F1 ],
- [ 0xE95D, 0x1109,0x1173,0x11F9 ],
- [ 0xE960, 0x1109,0x1174,0x11F0 ],
- [ 0xE961, 0x1109,0x1174,0x11F9 ],
- [ 0xE962, 0x1109,0x1175,0x11FA ],
- [ 0xE963, 0x1109,0x1175,0x11FF ],
- [ 0xE964, 0x1109,0x1175,0x11C7 ],
- [ 0xE965, 0x1109,0x1175,0x11CE ],
- [ 0xE966, 0x1109,0x1175,0x11D0 ],
- [ 0xE967, 0x1109,0x1175,0x11D9 ],
- [ 0xE968, 0x1109,0x1175,0x11DA ],
- [ 0xE969, 0x1109,0x1175,0x11E1 ],
- [ 0xE96A, 0x1109,0x1175,0x11E2 ],
- [ 0xE96B, 0x1109,0x1175,0x11E6 ],
- [ 0xE96C, 0x1109,0x1175,0x11EB ],
- [ 0xE96D, 0x1109,0x1175,0x11F0 ],
- [ 0xE96E, 0x1109,0x1175,0x11F9 ],
- [ 0xE971, 0x1109,0x1199,0x11AB ],
- [ 0xE972, 0x1109,0x1199,0x11BC ],
- [ 0xE97C, 0x1109,0xD7C3,0x11AB ],
- [ 0xE97E, 0x1109,0x119E,0x11A8 ],
- [ 0xE97F, 0x1109,0x119E,0x11AB ],
- [ 0xE980, 0x1109,0x119E,0x11AE ],
- [ 0xE981, 0x1109,0x119E,0x11CA ],
- [ 0xE982, 0x1109,0x119E,0x11AF ],
- [ 0xE983, 0x1109,0x119E,0x11B0 ],
- [ 0xE984, 0x1109,0x119E,0x11D0 ],
- [ 0xE985, 0x1109,0x119E,0x11B1 ],
- [ 0xE986, 0x1109,0x119E,0x11B2 ],
- [ 0xE987, 0x1109,0x119E,0x11D5 ],
- [ 0xE988, 0x1109,0x119E,0x11B3 ],
- [ 0xE989, 0x1109,0x119E,0x11B6 ],
- [ 0xE98A, 0x1109,0x119E,0x11D9 ],
- [ 0xE98B, 0x1109,0x119E,0x11B7 ],
- [ 0xE98C, 0x1109,0x119E,0xD7E0 ],
- [ 0xE98D, 0x1109,0x119E,0x11DD ],
- [ 0xE98E, 0x1109,0x119E,0x11B8 ],
- [ 0xE98F, 0x1109,0x119E,0x11E3 ],
- [ 0xE990, 0x1109,0x119E,0x11E6 ],
- [ 0xE991, 0x1109,0x119E,0x11BA ],
- [ 0xE992, 0x1109,0x119E,0xD7F0 ],
- [ 0xE993, 0x1109,0x119E,0x11EB ],
- [ 0xE994, 0x1109,0x119E,0x11BC ],
- [ 0xE995, 0x1109,0x119E,0x11F0 ],
- [ 0xE996, 0x1109,0x119E,0x11BD ],
- [ 0xE997, 0x1109,0x119E,0x11BE ],
- [ 0xE998, 0x1109,0x119E,0x11C0 ],
- [ 0xE99A, 0x1109,0x11A1,0x11A8 ],
- [ 0xE99B, 0x1109,0x11A1,0x11AB ],
- [ 0xE99C, 0x1109,0x11A1,0x11AF ],
- [ 0xE99D, 0x1109,0x11A1,0x11D9 ],
- [ 0xE99E, 0x1109,0x11A1,0x11B7 ],
- [ 0xE99F, 0x1109,0x11A1,0x11DD ],
- [ 0xE9A0, 0x1109,0x11A1,0x11B8 ],
- [ 0xE9A1, 0x1109,0x11A1,0x11BA ],
- [ 0xE9A2, 0x1109,0x11A1,0x11BC ],
- [ 0xE9A3, 0x1109,0x11A1,0x11F0 ],
- [ 0xE9A4, 0x1109,0x11A1,0x11F1 ],
- [ 0xE9A6, 0x112D,0x1161,0x11A8 ],
- [ 0xE9A7, 0x112D,0x1161,0x11A9 ],
- [ 0xE9A8, 0x112D,0x1161,0x11AA ],
- [ 0xE9A9, 0x112D,0x1161,0x11AB ],
- [ 0xE9AA, 0x112D,0x1161,0x11AF ],
- [ 0xE9AB, 0x112D,0x1161,0x11B6 ],
- [ 0xE9AC, 0x112D,0x1161,0x11B7 ],
- [ 0xE9AD, 0x112D,0x1161,0x11B8 ],
- [ 0xE9AE, 0x112D,0x1161,0x11B9 ],
- [ 0xE9AF, 0x112D,0x1161,0x11E6 ],
- [ 0xE9B0, 0x112D,0x1161,0x11BA ],
- [ 0xE9B1, 0x112D,0x1161,0x11E7 ],
- [ 0xE9B2, 0x112D,0x1161,0x11BC ],
- [ 0xE9B3, 0x112D,0x1161,0x11F0 ],
- [ 0xE9B5, 0x112D,0x1162,0x11A8 ],
- [ 0xE9B6, 0x112D,0x1162,0x11AB ],
- [ 0xE9B7, 0x112D,0x1162,0x11AF ],
- [ 0xE9B8, 0x112D,0x1162,0x11B7 ],
- [ 0xE9B9, 0x112D,0x1162,0x11BA ],
- [ 0xE9BA, 0x112D,0x1162,0x11F0 ],
- [ 0xE9BC, 0x112D,0x1163,0x11A8 ],
- [ 0xE9BE, 0x112D,0x1164,0x11BA ],
- [ 0xE9C0, 0x112D,0x1165,0x11A8 ],
- [ 0xE9C1, 0x112D,0x1165,0x11A9 ],
- [ 0xE9C2, 0x112D,0x1165,0x11AB ],
- [ 0xE9C3, 0x112D,0x1165,0x11AF ],
- [ 0xE9C4, 0x112D,0x1165,0x11B2 ],
- [ 0xE9C5, 0x112D,0x1165,0x11D5 ],
- [ 0xE9C6, 0x112D,0x1165,0x11B7 ],
- [ 0xE9C7, 0x112D,0x1165,0x11B8 ],
- [ 0xE9C8, 0x112D,0x1165,0x11E6 ],
- [ 0xE9C9, 0x112D,0x1165,0x11BA ],
- [ 0xE9CA, 0x112D,0x1165,0x11E7 ],
- [ 0xE9CB, 0x112D,0x1165,0x11EB ],
- [ 0xE9CC, 0x112D,0x1165,0x11F0 ],
- [ 0xE9CE, 0x112D,0x1166,0x11A8 ],
- [ 0xE9CF, 0x112D,0x1166,0x11AB ],
- [ 0xE9D0, 0x112D,0x1166,0x11AF ],
- [ 0xE9D1, 0x112D,0x1166,0x11B7 ],
- [ 0xE9D2, 0x112D,0x1166,0x11B8 ],
- [ 0xE9D3, 0x112D,0x1166,0x11BA ],
- [ 0xE9D4, 0x112D,0x1166,0x11F0 ],
- [ 0xE9D6, 0x112D,0x1167,0x11A8 ],
- [ 0xE9D7, 0x112D,0x1167,0x11AB ],
- [ 0xE9D8, 0x112D,0x1167,0x11AE ],
- [ 0xE9D9, 0x112D,0x1167,0x11AF ],
- [ 0xE9DA, 0x112D,0x1167,0x11B7 ],
- [ 0xE9DB, 0x112D,0x1167,0x11B8 ],
- [ 0xE9DC, 0x112D,0x1167,0x11BA ],
- [ 0xE9DD, 0x112D,0x1167,0x11BC ],
- [ 0xE9DE, 0x112D,0x1167,0x11F0 ],
- [ 0xE9DF, 0x112D,0x1167,0x11C0 ],
- [ 0xE9E2, 0x112D,0x1169,0x11A8 ],
- [ 0xE9E3, 0x112D,0x1169,0x11AA ],
- [ 0xE9E4, 0x112D,0x1169,0x11AB ],
- [ 0xE9E5, 0x112D,0x1169,0x11AE ],
- [ 0xE9E6, 0x112D,0x1169,0x11AF ],
- [ 0xE9E7, 0x112D,0x1169,0x11B3 ],
- [ 0xE9E8, 0x112D,0x1169,0x11B7 ],
- [ 0xE9E9, 0x112D,0x1169,0x11B8 ],
- [ 0xE9EA, 0x112D,0x1169,0x11BA ],
- [ 0xE9EB, 0x112D,0x1169,0xD7F0 ],
- [ 0xE9EC, 0x112D,0x1169,0x11BC ],
- [ 0xE9ED, 0x112D,0x1169,0x11F0 ],
- [ 0xE9EE, 0x112D,0x1169,0x11BD ],
- [ 0xE9EF, 0x112D,0x1169,0x11BE ],
- [ 0xE9F1, 0x112D,0x116A,0x11A8 ],
- [ 0xE9F2, 0x112D,0x116A,0x11AB ],
- [ 0xE9F3, 0x112D,0x116A,0x11AF ],
- [ 0xE9F4, 0x112D,0x116A,0x11BC ],
- [ 0xE9F5, 0x112D,0x116A,0x11F0 ],
- [ 0xE9F7, 0x112D,0x116B,0x11AF ],
- [ 0xE9F8, 0x112D,0x116B,0x11B0 ],
- [ 0xE9F9, 0x112D,0x116B,0x11BC ],
- [ 0xE9FB, 0x112D,0x116C,0x11A8 ],
- [ 0xE9FC, 0x112D,0x116C,0x11AB ],
- [ 0xE9FD, 0x112D,0x116C,0x11AF ],
- [ 0xE9FE, 0x112D,0x116C,0x11B7 ],
- [ 0xE9FF, 0x112D,0x116C,0x11BA ],
- [ 0xEA00, 0x112D,0x116C,0x11F0 ],
- [ 0xEA02, 0x112D,0x116D,0x11AB ],
- [ 0xEA03, 0x112D,0x116D,0x11AF ],
- [ 0xEA04, 0x112D,0x116D,0x11B7 ],
- [ 0xEA06, 0x112D,0x116E,0x11A8 ],
- [ 0xEA07, 0x112D,0x116E,0x11AB ],
- [ 0xEA08, 0x112D,0x116E,0x11AE ],
- [ 0xEA09, 0x112D,0x116E,0x11AF ],
- [ 0xEA0A, 0x112D,0x116E,0x11D9 ],
- [ 0xEA0B, 0x112D,0x116E,0x11B7 ],
- [ 0xEA0C, 0x112D,0x116E,0x11DA ],
- [ 0xEA0D, 0x112D,0x116E,0xD7E0 ],
- [ 0xEA0E, 0x112D,0x116E,0x11DD ],
- [ 0xEA0F, 0x112D,0x116E,0x11B8 ],
- [ 0xEA10, 0x112D,0x116E,0x11BA ],
- [ 0xEA11, 0x112D,0x116E,0x11BC ],
- [ 0xEA12, 0x112D,0x116E,0x11EC ],
- [ 0xEA13, 0x112D,0x116E,0x11F0 ],
- [ 0xEA14, 0x112D,0x116E,0x11BD ],
- [ 0xEA15, 0x112D,0x116E,0x11BE ],
- [ 0xEA17, 0x112D,0x116F,0x11A8 ],
- [ 0xEA18, 0x112D,0x116F,0x11AB ],
- [ 0xEA19, 0x112D,0x116F,0x11AF ],
- [ 0xEA1A, 0x112D,0x116F,0x11B7 ],
- [ 0xEA1B, 0x112D,0x116F,0x11BC ],
- [ 0xEA1C, 0x112D,0x116F,0x11F0 ],
- [ 0xEA1E, 0x112D,0x1170,0x11AB ],
- [ 0xEA1F, 0x112D,0x1170,0x11AF ],
- [ 0xEA23, 0x112D,0x1171,0x11AB ],
- [ 0xEA24, 0x112D,0x1171,0x11AF ],
- [ 0xEA25, 0x112D,0x1171,0x11B7 ],
- [ 0xEA26, 0x112D,0x1171,0x11F0 ],
- [ 0xEA28, 0x112D,0x1172,0x11AB ],
- [ 0xEA29, 0x112D,0x1172,0x11AF ],
- [ 0xEA2A, 0x112D,0x1172,0x11B7 ],
- [ 0xEA2C, 0x112D,0x118F,0x11BC ],
- [ 0xEA2F, 0x112D,0x1173,0x11A8 ],
- [ 0xEA30, 0x112D,0x1173,0x11AB ],
- [ 0xEA31, 0x112D,0x1173,0xD7CC ],
- [ 0xEA32, 0x112D,0x1173,0x11AD ],
- [ 0xEA33, 0x112D,0x1173,0x11AE ],
- [ 0xEA34, 0x112D,0x1173,0xD7D3 ],
- [ 0xEA35, 0x112D,0x1173,0x11AF ],
- [ 0xEA36, 0x112D,0x1173,0x11D0 ],
- [ 0xEA37, 0x112D,0x1173,0x11B3 ],
- [ 0xEA38, 0x112D,0x1173,0x11B4 ],
- [ 0xEA39, 0x112D,0x1173,0x11B6 ],
- [ 0xEA3A, 0x112D,0x1173,0x11D9 ],
- [ 0xEA3B, 0x112D,0x1173,0x11B7 ],
- [ 0xEA3C, 0x112D,0x1173,0x11BA ],
- [ 0xEA3D, 0x112D,0x1173,0xD7F0 ],
- [ 0xEA3E, 0x112D,0x1173,0xD7F1 ],
- [ 0xEA3F, 0x112D,0x1173,0xD7F2 ],
- [ 0xEA40, 0x112D,0x1173,0x11EB ],
- [ 0xEA41, 0x112D,0x1173,0x11BC ],
- [ 0xEA42, 0x112D,0x1173,0x11F0 ],
- [ 0xEA43, 0x112D,0x1173,0x11BE ],
- [ 0xEA44, 0x112D,0x1173,0x11C0 ],
- [ 0xEA46, 0x112D,0x1174,0x11AB ],
- [ 0xEA47, 0x112D,0x1174,0x11AF ],
- [ 0xEA48, 0x112D,0x1174,0x11D0 ],
- [ 0xEA49, 0x112D,0x1174,0x11B7 ],
- [ 0xEA4A, 0x112D,0x1174,0x11BA ],
- [ 0xEA4C, 0x112D,0x1175,0x11A8 ],
- [ 0xEA4D, 0x112D,0x1175,0x11AB ],
- [ 0xEA4E, 0x112D,0x1175,0x11AD ],
- [ 0xEA4F, 0x112D,0x1175,0x11AE ],
- [ 0xEA50, 0x112D,0x1175,0x11AF ],
- [ 0xEA51, 0x112D,0x1175,0x11B6 ],
- [ 0xEA52, 0x112D,0x1175,0x11B7 ],
- [ 0xEA53, 0x112D,0x1175,0x11B8 ],
- [ 0xEA54, 0x112D,0x1175,0x11BA ],
- [ 0xEA55, 0x112D,0x1175,0x11BC ],
- [ 0xEA56, 0x112D,0x1175,0x11C2 ],
- [ 0xEA59, 0x112D,0x119E,0x11A8 ],
- [ 0xEA5A, 0x112D,0x119E,0x11AB ],
- [ 0xEA5B, 0x112D,0x119E,0x11AE ],
- [ 0xEA5C, 0x112D,0x119E,0x11AF ],
- [ 0xEA5D, 0x112D,0x119E,0x11B7 ],
- [ 0xEA5E, 0x112D,0x119E,0x11B8 ],
- [ 0xEA5F, 0x112D,0x119E,0x11BA ],
- [ 0xEA60, 0x112D,0x119E,0x11F0 ],
- [ 0xEA62, 0x112D,0x11A1,0x11A8 ],
- [ 0xEA63, 0x112D,0x11A1,0x11AB ],
- [ 0xEA64, 0x112D,0x11A1,0x11AF ],
- [ 0xEA65, 0x112D,0x11A1,0x11D9 ],
- [ 0xEA66, 0x112D,0x11A1,0x11B7 ],
- [ 0xEA67, 0x112D,0x11A1,0x11B8 ],
- [ 0xEA68, 0x112D,0x11A1,0x11BA ],
- [ 0xEA69, 0x112D,0x11A1,0x11BC ],
- [ 0xEA6B, 0x112E,0x1161,0x11AF ],
- [ 0xEA6D, 0x112E,0x1167,0x11A8 ],
- [ 0xEA72, 0x112F,0x1161,0x11A8 ],
- [ 0xEA73, 0x112F,0x1161,0x11AB ],
- [ 0xEA74, 0x112F,0x1161,0x11AE ],
- [ 0xEA75, 0x112F,0x1161,0x11AF ],
- [ 0xEA76, 0x112F,0x1161,0x11B6 ],
- [ 0xEA77, 0x112F,0x1161,0x11B7 ],
- [ 0xEA78, 0x112F,0x1161,0x11B8 ],
- [ 0xEA79, 0x112F,0x1161,0x11BA ],
- [ 0xEA7A, 0x112F,0x1161,0x11BC ],
- [ 0xEA7B, 0x112F,0x1161,0xD7F6 ],
- [ 0xEA7C, 0x112F,0x1161,0x11F0 ],
- [ 0xEA7D, 0x112F,0x1161,0xD7F6 ],
- [ 0xEA7E, 0x112F,0x1161,0x11C2 ],
- [ 0xEA80, 0x112F,0x1162,0x11A8 ],
- [ 0xEA81, 0x112F,0x1162,0x11AB ],
- [ 0xEA82, 0x112F,0x1162,0x11AF ],
- [ 0xEA83, 0x112F,0x1162,0x11B7 ],
- [ 0xEA84, 0x112F,0x1162,0x11B8 ],
- [ 0xEA85, 0x112F,0x1162,0x11BA ],
- [ 0xEA86, 0x112F,0x1162,0x11BC ],
- [ 0xEA87, 0x112F,0x1162,0x11F0 ],
- [ 0xEA89, 0x112F,0x1163,0x11A8 ],
- [ 0xEA8A, 0x112F,0x1163,0x11BC ],
- [ 0xEA8B, 0x112F,0x1163,0x11F0 ],
- [ 0xEA8E, 0x112F,0x1165,0x11A8 ],
- [ 0xEA8F, 0x112F,0x1165,0x11AB ],
- [ 0xEA90, 0x112F,0x1165,0x11AE ],
- [ 0xEA91, 0x112F,0x1165,0x11AF ],
- [ 0xEA92, 0x112F,0x1165,0x11B0 ],
- [ 0xEA93, 0x112F,0x1165,0x11B2 ],
- [ 0xEA94, 0x112F,0x1165,0x11B7 ],
- [ 0xEA95, 0x112F,0x1165,0x11B8 ],
- [ 0xEA96, 0x112F,0x1165,0x11BA ],
- [ 0xEA97, 0x112F,0x1165,0x11BC ],
- [ 0xEA98, 0x112F,0x1165,0x11F0 ],
- [ 0xEA99, 0x112F,0x1165,0x11BF ],
- [ 0xEA9B, 0x112F,0x117C,0x11BA ],
- [ 0xEA9C, 0x112F,0x117C,0x11BB ],
- [ 0xEA9D, 0x112F,0x117C,0x11BF ],
- [ 0xEA9F, 0x112F,0x1166,0x11A8 ],
- [ 0xEAA0, 0x112F,0x1166,0x11AB ],
- [ 0xEAA1, 0x112F,0x1166,0x11AF ],
- [ 0xEAA2, 0x112F,0x1166,0x11B7 ],
- [ 0xEAA3, 0x112F,0x1166,0x11BA ],
- [ 0xEAA4, 0x112F,0x1166,0x11BC ],
- [ 0xEAA6, 0x112F,0x1167,0x11A8 ],
- [ 0xEAA7, 0x112F,0x1167,0x11AB ],
- [ 0xEAA8, 0x112F,0x1167,0x11BA ],
- [ 0xEAA9, 0x112F,0x1167,0x11BC ],
- [ 0xEAAC, 0x112F,0x1169,0x11A8 ],
- [ 0xEAAD, 0x112F,0x1169,0x11AA ],
- [ 0xEAAE, 0x112F,0x1169,0x11AB ],
- [ 0xEAAF, 0x112F,0x1169,0x11AF ],
- [ 0xEAB0, 0x112F,0x1169,0x11B7 ],
- [ 0xEAB1, 0x112F,0x1169,0x11B8 ],
- [ 0xEAB2, 0x112F,0x1169,0x11BA ],
- [ 0xEAB3, 0x112F,0x1169,0x11BC ],
- [ 0xEAB4, 0x112F,0x1169,0x11F0 ],
- [ 0xEAB5, 0x112F,0x1169,0x11F1 ],
- [ 0xEAB9, 0x112F,0x116C,0x11AB ],
- [ 0xEABA, 0x112F,0x116C,0x11AF ],
- [ 0xEABC, 0x112F,0x116D,0x11A8 ],
- [ 0xEABD, 0x112F,0x116D,0x11BA ],
- [ 0xEABE, 0x112F,0x116D,0x11BC ],
- [ 0xEAC0, 0x112F,0x116E,0x11A8 ],
- [ 0xEAC1, 0x112F,0x116E,0x11AB ],
- [ 0xEAC2, 0x112F,0x116E,0x11AF ],
- [ 0xEAC3, 0x112F,0x116E,0x11B0 ],
- [ 0xEAC4, 0x112F,0x116E,0x11B2 ],
- [ 0xEAC5, 0x112F,0x116E,0x11B7 ],
- [ 0xEAC6, 0x112F,0x116E,0x11BA ],
- [ 0xEAC7, 0x112F,0x116E,0x11BC ],
- [ 0xEAC8, 0x112F,0x116E,0x11F0 ],
- [ 0xEACE, 0x112F,0x1171,0x11AB ],
- [ 0xEACF, 0x112F,0x1171,0x11AF ],
- [ 0xEAD0, 0x112F,0x1171,0x11B7 ],
- [ 0xEAD1, 0x112F,0x1171,0x11BA ],
- [ 0xEAD3, 0x112F,0x1172,0x11A8 ],
- [ 0xEAD4, 0x112F,0x1172,0x11AF ],
- [ 0xEAD5, 0x112F,0x1172,0x11B7 ],
- [ 0xEAD6, 0x112F,0x1172,0x11BC ],
- [ 0xEAD7, 0x112F,0x1172,0x11F0 ],
- [ 0xEADA, 0x112F,0x1173,0x11A8 ],
- [ 0xEADB, 0x112F,0x1173,0x11AB ],
- [ 0xEADC, 0x112F,0x1173,0x11AE ],
- [ 0xEADD, 0x112F,0x1173,0x11AF ],
- [ 0xEADE, 0x112F,0x1173,0x11B2 ],
- [ 0xEADF, 0x112F,0x1173,0x11B6 ],
- [ 0xEAE0, 0x112F,0x1173,0x11B7 ],
- [ 0xEAE1, 0x112F,0x1173,0x11B8 ],
- [ 0xEAE2, 0x112F,0x1173,0x11BA ],
- [ 0xEAE3, 0x112F,0x1173,0x11BC ],
- [ 0xEAE4, 0x112F,0x1173,0x11F0 ],
- [ 0xEAE5, 0x112F,0x1173,0x11F1 ],
- [ 0xEAE6, 0x112F,0x1173,0x11BD ],
- [ 0xEAE8, 0x112F,0x1174,0x11AB ],
- [ 0xEAE9, 0x112F,0x1174,0x11AF ],
- [ 0xEAEA, 0x112F,0x1174,0x11BA ],
- [ 0xEAEB, 0x112F,0x1174,0x11EB ],
- [ 0xEAEC, 0x112F,0x1174,0x11BE ],
- [ 0xEAEE, 0x112F,0x1175,0x11A8 ],
- [ 0xEAEF, 0x112F,0x1175,0x11AB ],
- [ 0xEAF0, 0x112F,0x1175,0x11AE ],
- [ 0xEAF1, 0x112F,0x1175,0x11AF ],
- [ 0xEAF2, 0x112F,0x1175,0x11B7 ],
- [ 0xEAF3, 0x112F,0x1175,0x11BA ],
- [ 0xEAF4, 0x112F,0x1175,0xD7F2 ],
- [ 0xEAF5, 0x112F,0x1175,0x11BC ],
- [ 0xEAF6, 0x112F,0x1175,0x11C2 ],
- [ 0xEAF9, 0x112F,0x119E,0x11A8 ],
- [ 0xEAFA, 0x112F,0x119E,0x11AB ],
- [ 0xEAFB, 0x112F,0x119E,0x11AE ],
- [ 0xEAFC, 0x112F,0x119E,0x11AF ],
- [ 0xEAFD, 0x112F,0x119E,0x11B6 ],
- [ 0xEAFE, 0x112F,0x119E,0x11B7 ],
- [ 0xEAFF, 0x112F,0x119E,0x11B8 ],
- [ 0xEB00, 0x112F,0x119E,0x11BA ],
- [ 0xEB01, 0x112F,0x119E,0x11BC ],
- [ 0xEB02, 0x112F,0x119E,0x11F0 ],
- [ 0xEB03, 0x112F,0x119E,0x11C2 ],
- [ 0xEB05, 0x112F,0x11A1,0x11A8 ],
- [ 0xEB06, 0x112F,0x11A1,0x11AB ],
- [ 0xEB07, 0x112F,0x11A1,0x11AF ],
- [ 0xEB08, 0x112F,0x11A1,0x11B7 ],
- [ 0xEB09, 0x112F,0x11A1,0x11B8 ],
- [ 0xEB0A, 0x112F,0x11A1,0x11BA ],
- [ 0xEB0B, 0x112F,0x11A1,0x11BC ],
- [ 0xEB0C, 0x112F,0x11A1,0x11F0 ],
- [ 0xEB0F, 0x1130,0x1162,0x11AB ],
- [ 0xEB12, 0x1130,0x1165,0x11BA ],
- [ 0xEB15, 0x1130,0x1167,0x11BA ],
- [ 0xEB18, 0x1130,0x1172,0x11AB ],
- [ 0xEB19, 0x1130,0x1172,0x11BC ],
- [ 0xEB1B, 0x1130,0x1173,0x11AB ],
- [ 0xEB1C, 0x1130,0x1173,0x11AF ],
- [ 0xEB1D, 0x1130,0x1173,0x11B7 ],
- [ 0xEB1F, 0x1130,0x1175,0x11AB ],
- [ 0xEB21, 0x1131,0x1161,0x11AF ],
- [ 0xEB24, 0x1131,0x1173,0x11AF ],
- [ 0xEB26, 0x1131,0x119E,0x11AF ],
- [ 0xEB28, 0x1132,0x1161,0x11A8 ],
- [ 0xEB29, 0x1132,0x1161,0x11AB ],
- [ 0xEB2A, 0x1132,0x1161,0x11AE ],
- [ 0xEB2B, 0x1132,0x1161,0x11AF ],
- [ 0xEB2C, 0x1132,0x1161,0x11B0 ],
- [ 0xEB2D, 0x1132,0x1161,0x11D0 ],
- [ 0xEB2E, 0x1132,0x1161,0x11B7 ],
- [ 0xEB2F, 0x1132,0x1161,0x11B8 ],
- [ 0xEB30, 0x1132,0x1161,0x11BA ],
- [ 0xEB31, 0x1132,0x1161,0x11BC ],
- [ 0xEB32, 0x1132,0x1161,0x11F0 ],
- [ 0xEB33, 0x1132,0x1161,0x11C2 ],
- [ 0xEB35, 0x1132,0x1162,0x11A8 ],
- [ 0xEB36, 0x1132,0x1162,0x11AB ],
- [ 0xEB37, 0x1132,0x1162,0x11AF ],
- [ 0xEB38, 0x1132,0x1162,0x11B7 ],
- [ 0xEB39, 0x1132,0x1162,0x11BA ],
- [ 0xEB3A, 0x1132,0x1162,0x11F0 ],
- [ 0xEB3C, 0x1132,0x1163,0x11B7 ],
- [ 0xEB3E, 0x1132,0x1165,0x11A8 ],
- [ 0xEB3F, 0x1132,0x1165,0x11AB ],
- [ 0xEB40, 0x1132,0x1165,0x11AE ],
- [ 0xEB41, 0x1132,0x1165,0x11AF ],
- [ 0xEB42, 0x1132,0x1165,0x11B7 ],
- [ 0xEB43, 0x1132,0x1165,0x11B8 ],
- [ 0xEB44, 0x1132,0x1165,0x11BA ],
- [ 0xEB45, 0x1132,0x1165,0x11BC ],
- [ 0xEB46, 0x1132,0x1165,0x11F0 ],
- [ 0xEB48, 0x1132,0x1166,0x11AB ],
- [ 0xEB49, 0x1132,0x1166,0x11AF ],
- [ 0xEB4A, 0x1132,0x1166,0x11B7 ],
- [ 0xEB4B, 0x1132,0x1166,0x11BA ],
- [ 0xEB4D, 0x1132,0x1167,0x11A8 ],
- [ 0xEB4E, 0x1132,0x1167,0x11AB ],
- [ 0xEB4F, 0x1132,0x1167,0x11AF ],
- [ 0xEB50, 0x1132,0x1167,0x11B7 ],
- [ 0xEB51, 0x1132,0x1167,0x11BA ],
- [ 0xEB52, 0x1132,0x1167,0xD7F2 ],
- [ 0xEB53, 0x1132,0x1167,0x11F0 ],
- [ 0xEB54, 0x1132,0x1167,0x11C2 ],
- [ 0xEB57, 0x1132,0x1169,0x11A8 ],
- [ 0xEB58, 0x1132,0x1169,0x11AB ],
- [ 0xEB59, 0x1132,0x1169,0x11AF ],
- [ 0xEB5A, 0x1132,0x1169,0x11B7 ],
- [ 0xEB5B, 0x1132,0x1169,0x11B8 ],
- [ 0xEB5C, 0x1132,0x1169,0x11BA ],
- [ 0xEB5D, 0x1132,0x1169,0x11E7 ],
- [ 0xEB5E, 0x1132,0x1169,0x11BC ],
- [ 0xEB5F, 0x1132,0x1169,0x11F0 ],
- [ 0xEB60, 0x1132,0x1169,0x11F1 ],
- [ 0xEB61, 0x1132,0x1169,0x11C2 ],
- [ 0xEB67, 0x1132,0x116E,0x11A8 ],
- [ 0xEB68, 0x1132,0x116E,0x11AB ],
- [ 0xEB69, 0x1132,0x116E,0x11AE ],
- [ 0xEB6A, 0x1132,0x116E,0x11AF ],
- [ 0xEB6B, 0x1132,0x116E,0x11B1 ],
- [ 0xEB6C, 0x1132,0x116E,0x11B7 ],
- [ 0xEB6D, 0x1132,0x116E,0x11BA ],
- [ 0xEB6E, 0x1132,0x116E,0x11BC ],
- [ 0xEB6F, 0x1132,0x116E,0x11BD ],
- [ 0xEB70, 0x1132,0x116E,0x11BE ],
- [ 0xEB79, 0x1132,0x1173,0x11A8 ],
- [ 0xEB7A, 0x1132,0x1173,0x11AB ],
- [ 0xEB7B, 0x1132,0x1173,0x11AF ],
- [ 0xEB7C, 0x1132,0x1173,0x11B3 ],
- [ 0xEB7D, 0x1132,0x1173,0x11B7 ],
- [ 0xEB7E, 0x1132,0x1173,0x11BA ],
- [ 0xEB7F, 0x1132,0x1173,0x11BC ],
- [ 0xEB81, 0x1132,0x1174,0x11AF ],
- [ 0xEB83, 0x1132,0x1175,0x11A8 ],
- [ 0xEB84, 0x1132,0x1175,0x11AB ],
- [ 0xEB85, 0x1132,0x1175,0x11AF ],
- [ 0xEB86, 0x1132,0x1175,0x11B7 ],
- [ 0xEB87, 0x1132,0x1175,0x11BA ],
- [ 0xEB88, 0x1132,0x1175,0x11E7 ],
- [ 0xEB89, 0x1132,0x1175,0xD7F2 ],
- [ 0xEB8A, 0x1132,0x1175,0x11F0 ],
- [ 0xEB8B, 0x1132,0x1175,0x11BE ],
- [ 0xEB8C, 0x1132,0x1175,0x11C2 ],
- [ 0xEB8F, 0x1132,0x119E,0x11A8 ],
- [ 0xEB90, 0x1132,0x119E,0x11AB ],
- [ 0xEB91, 0x1132,0x119E,0x11AF ],
- [ 0xEB92, 0x1132,0x119E,0x11D0 ],
- [ 0xEB93, 0x1132,0x119E,0x11B7 ],
- [ 0xEB94, 0x1132,0x119E,0x11B8 ],
- [ 0xEB95, 0x1132,0x119E,0x11BA ],
- [ 0xEB96, 0x1132,0x119E,0x11BC ],
- [ 0xEB98, 0x1132,0x11A1,0x11A8 ],
- [ 0xEB99, 0x1132,0x11A1,0x11AB ],
- [ 0xEB9A, 0x1132,0x11A1,0x11AF ],
- [ 0xEB9B, 0x1132,0x11A1,0x11B7 ],
- [ 0xEB9C, 0x1132,0x11A1,0x11BA ],
- [ 0xEB9D, 0x1132,0x11A1,0x11E7 ],
- [ 0xEB9E, 0x1132,0x11A1,0x11BC ],
- [ 0xEB9F, 0x1132,0x11A1,0x11F0 ],
- [ 0xEBA3, 0x1133,0x116E,0x11AF ],
- [ 0xEBA5, 0x1133,0x1173,0x11AF ],
- [ 0xEBA8, 0x110A,0x1161,0x11E2 ],
- [ 0xEBA9, 0x110A,0x1161,0xD7F2 ],
- [ 0xEBAA, 0x110A,0x1161,0x11F0 ],
- [ 0xEBAB, 0x110A,0x1163,0x11E2 ],
- [ 0xEBAC, 0x110A,0x1163,0x11F0 ],
- [ 0xEBAD, 0x110A,0x1165,0x11F0 ],
- [ 0xEBAE, 0x110A,0x1167,0x11D9 ],
- [ 0xEBAF, 0x110A,0x1167,0x11F0 ],
- [ 0xEBB0, 0x110A,0x1167,0x11F9 ],
- [ 0xEBB1, 0x110A,0x1169,0x11E2 ],
- [ 0xEBB2, 0x110A,0x1169,0x11F0 ],
- [ 0xEBB3, 0x110A,0x116D,0x11E2 ],
- [ 0xEBB4, 0x110A,0x116D,0x11F0 ],
- [ 0xEBB6, 0x110A,0x116E,0x11D9 ],
- [ 0xEBB7, 0x110A,0x116E,0x11E2 ],
- [ 0xEBB8, 0x110A,0x116E,0x11F9 ],
- [ 0xEBBA, 0x110A,0x1189,0x11AB ],
- [ 0xEBBB, 0x110A,0x1189,0x11BC ],
- [ 0xEBBD, 0x110A,0xD7B5,0x11AB ],
- [ 0xEBBF, 0x110A,0x1172,0x11D9 ],
- [ 0xEBC0, 0x110A,0x1172,0x11E2 ],
- [ 0xEBC1, 0x110A,0x1172,0x11F0 ],
- [ 0xEBC2, 0x110A,0x1172,0x11F9 ],
- [ 0xEBC4, 0x110A,0x1191,0x11AB ],
- [ 0xEBC5, 0x110A,0x1191,0x11BC ],
- [ 0xEBC7, 0x110A,0x1192,0x11BC ],
- [ 0xEBC9, 0x110A,0x1194,0x11BC ],
- [ 0xEBCA, 0x110A,0x1194,0x11F0 ],
- [ 0xEBCB, 0x110A,0x1173,0x11D9 ],
- [ 0xEBCC, 0x110A,0x1173,0x11EB ],
- [ 0xEBCD, 0x110A,0x1173,0x11F0 ],
- [ 0xEBCE, 0x110A,0x1175,0x11D9 ],
- [ 0xEBCF, 0x110A,0x1175,0x11E2 ],
- [ 0xEBD0, 0x110A,0x1175,0x11EB ],
- [ 0xEBD1, 0x110A,0x1175,0x11F0 ],
- [ 0xEBD2, 0x110A,0x1175,0x11F9 ],
- [ 0xEBD5, 0x110A,0x119E,0x11A8 ],
- [ 0xEBD6, 0x110A,0x119E,0x11AB ],
- [ 0xEBD7, 0x110A,0x119E,0x11AE ],
- [ 0xEBD8, 0x110A,0x119E,0x11AF ],
- [ 0xEBD9, 0x110A,0x119E,0x11B7 ],
- [ 0xEBDA, 0x110A,0x119E,0x11DD ],
- [ 0xEBDB, 0x110A,0x119E,0x11B8 ],
- [ 0xEBDC, 0x110A,0x119E,0x11E6 ],
- [ 0xEBDD, 0x110A,0x119E,0x11BA ],
- [ 0xEBDE, 0x110A,0x119E,0x11BC ],
- [ 0xEBDF, 0x110A,0x119E,0x11F0 ],
- [ 0xEBE0, 0x110A,0x119E,0x11C1 ],
- [ 0xEBE2, 0x110A,0x11A1,0x11AB ],
- [ 0xEBE3, 0x110A,0x11A1,0x11F0 ],
- [ 0xEBE7, 0x1135,0x1173,0x11AF ],
- [ 0xEBE8, 0x1135,0x1173,0x11B7 ],
- [ 0xEBEA, 0x1135,0x1175,0x11AF ],
- [ 0xEBEC, 0x1136,0x1161,0x11A8 ],
- [ 0xEBED, 0x1136,0x1161,0x11AB ],
- [ 0xEBEE, 0x1136,0x1161,0x11AF ],
- [ 0xEBEF, 0x1136,0x1161,0x11B2 ],
- [ 0xEBF0, 0x1136,0x1161,0x11B7 ],
- [ 0xEBF1, 0x1136,0x1161,0x11B8 ],
- [ 0xEBF2, 0x1136,0x1161,0x11BA ],
- [ 0xEBF3, 0x1136,0x1161,0x11E9 ],
- [ 0xEBF4, 0x1136,0x1161,0x11BC ],
- [ 0xEBF5, 0x1136,0x1161,0x11F0 ],
- [ 0xEBF7, 0x1136,0x1162,0x11A8 ],
- [ 0xEBF8, 0x1136,0x1162,0x11AB ],
- [ 0xEBF9, 0x1136,0x1162,0x11AF ],
- [ 0xEBFA, 0x1136,0x1162,0x11BA ],
- [ 0xEBFB, 0x1136,0x1162,0x11BC ],
- [ 0xEBFC, 0x1136,0x1162,0x11F0 ],
- [ 0xEBFE, 0x1136,0x1163,0x11A8 ],
- [ 0xEBFF, 0x1136,0x1163,0x11BC ],
- [ 0xEC00, 0x1136,0x1163,0x11F0 ],
- [ 0xEC02, 0x1136,0x1165,0x11A8 ],
- [ 0xEC03, 0x1136,0x1165,0x11AB ],
- [ 0xEC04, 0x1136,0x1165,0x11AF ],
- [ 0xEC05, 0x1136,0x1165,0x11B7 ],
- [ 0xEC06, 0x1136,0x1165,0x11B8 ],
- [ 0xEC07, 0x1136,0x1165,0x11BA ],
- [ 0xEC08, 0x1136,0x1165,0x11BC ],
- [ 0xEC0A, 0x1136,0x1166,0x11AB ],
- [ 0xEC0B, 0x1136,0x1166,0x11AF ],
- [ 0xEC0C, 0x1136,0x1166,0x11B8 ],
- [ 0xEC0D, 0x1136,0x1166,0x11BA ],
- [ 0xEC0F, 0x1136,0x1167,0x11A8 ],
- [ 0xEC10, 0x1136,0x1167,0x11AB ],
- [ 0xEC11, 0x1136,0x1167,0x11AF ],
- [ 0xEC12, 0x1136,0x1167,0x11BA ],
- [ 0xEC13, 0x1136,0x1167,0x11F0 ],
- [ 0xEC15, 0x1136,0x1168,0x11AB ],
- [ 0xEC17, 0x1136,0x1169,0x11A8 ],
- [ 0xEC18, 0x1136,0x1169,0x11AB ],
- [ 0xEC19, 0x1136,0x1169,0x11AF ],
- [ 0xEC1A, 0x1136,0x1169,0x11B7 ],
- [ 0xEC1B, 0x1136,0x1169,0x11B8 ],
- [ 0xEC1C, 0x1136,0x1169,0x11BA ],
- [ 0xEC1D, 0x1136,0x1169,0x11BC ],
- [ 0xEC1E, 0x1136,0x1169,0x11BD ],
- [ 0xEC1F, 0x1136,0x1169,0x11BE ],
- [ 0xEC21, 0x1136,0x116A,0x11A8 ],
- [ 0xEC23, 0x1136,0x116C,0x11A8 ],
- [ 0xEC24, 0x1136,0x116C,0x11AB ],
- [ 0xEC25, 0x1136,0x116C,0x11AF ],
- [ 0xEC26, 0x1136,0x116C,0x11B7 ],
- [ 0xEC28, 0x1136,0x116D,0x11A8 ],
- [ 0xEC29, 0x1136,0x116D,0x11AE ],
- [ 0xEC2A, 0x1136,0x116D,0x11B7 ],
- [ 0xEC2B, 0x1136,0x116D,0x11BA ],
- [ 0xEC2C, 0x1136,0x116D,0x11BC ],
- [ 0xEC2E, 0x1136,0x116E,0x11A8 ],
- [ 0xEC2F, 0x1136,0x116E,0x11AB ],
- [ 0xEC30, 0x1136,0x116E,0x11AF ],
- [ 0xEC31, 0x1136,0x116E,0x11B7 ],
- [ 0xEC32, 0x1136,0x116E,0x11B8 ],
- [ 0xEC33, 0x1136,0x116E,0x11BC ],
- [ 0xEC37, 0x1136,0x1171,0x11A8 ],
- [ 0xEC39, 0x1136,0x1172,0x11A8 ],
- [ 0xEC3A, 0x1136,0x1172,0x11AF ],
- [ 0xEC3B, 0x1136,0x1172,0x11B7 ],
- [ 0xEC3D, 0x1136,0x1173,0x11A8 ],
- [ 0xEC3E, 0x1136,0x1173,0x11AB ],
- [ 0xEC3F, 0x1136,0x1173,0x11AF ],
- [ 0xEC40, 0x1136,0x1173,0x11B7 ],
- [ 0xEC41, 0x1136,0x1173,0x11BA ],
- [ 0xEC42, 0x1136,0x1173,0x11BC ],
- [ 0xEC44, 0x1136,0x1174,0x11AF ],
- [ 0xEC46, 0x1136,0x1175,0x11A8 ],
- [ 0xEC47, 0x1136,0x1175,0x11AB ],
- [ 0xEC48, 0x1136,0x1175,0x11AF ],
- [ 0xEC49, 0x1136,0x1175,0x11D9 ],
- [ 0xEC4A, 0x1136,0x1175,0x11B7 ],
- [ 0xEC4B, 0x1136,0x1175,0x11B8 ],
- [ 0xEC4C, 0x1136,0x1175,0x11BA ],
- [ 0xEC4D, 0x1136,0x1175,0xD7F2 ],
- [ 0xEC4E, 0x1136,0x1175,0x11BC ],
- [ 0xEC4F, 0x1136,0x1175,0x11F0 ],
- [ 0xEC50, 0x1136,0x1175,0x11C2 ],
- [ 0xEC52, 0x1136,0x119E,0x11A8 ],
- [ 0xEC53, 0x1136,0x119E,0x11AB ],
- [ 0xEC54, 0x1136,0x119E,0x11AF ],
- [ 0xEC55, 0x1136,0x119E,0x11B7 ],
- [ 0xEC56, 0x1136,0x119E,0x11B8 ],
- [ 0xEC57, 0x1136,0x119E,0x11BA ],
- [ 0xEC58, 0x1136,0x119E,0x11BC ],
- [ 0xEC5A, 0x1136,0x11A1,0x11A8 ],
- [ 0xEC5B, 0x1136,0x11A1,0x11AF ],
- [ 0xEC5C, 0x1136,0x11A1,0x11BC ],
- [ 0xEC5D, 0x1136,0x11A1,0x11F0 ],
- [ 0xEC61, 0x1137,0x119E,0x11AF ],
- [ 0xEC62, 0x1137,0x119E,0x11B8 ],
- [ 0xEC64, 0x1138,0x1161,0x11BC ],
- [ 0xEC66, 0x1138,0x1165,0x11AB ],
- [ 0xEC67, 0x1138,0x1165,0x11AF ],
- [ 0xEC6A, 0x1138,0x1169,0x11AB ],
- [ 0xEC6B, 0x1138,0x1169,0x11BA ],
- [ 0xEC6C, 0x1138,0x1169,0x11BC ],
- [ 0xEC6D, 0x1138,0x1169,0x11F0 ],
- [ 0xEC71, 0x1138,0x116C,0x11BC ],
- [ 0xEC72, 0x1138,0x116C,0x11F0 ],
- [ 0xEC76, 0x1138,0x1173,0x11AB ],
- [ 0xEC7B, 0x1139,0x1161,0x11AF ],
- [ 0xEC7D, 0x1139,0x1165,0x11AF ],
- [ 0xEC80, 0x1139,0x1169,0x11B8 ],
- [ 0xEC82, 0x1139,0x116E,0x11A8 ],
- [ 0xEC85, 0x1139,0x1173,0x11AF ],
- [ 0xEC86, 0x1139,0x1173,0x11B7 ],
- [ 0xEC87, 0x1139,0x1173,0x11BA ],
- [ 0xEC89, 0x1139,0x1175,0x11BF ],
- [ 0xEC8B, 0x1139,0x119E,0x11AF ],
- [ 0xEC8C, 0x1139,0x119E,0x11B7 ],
- [ 0xEC8E, 0x113A,0x1167,0x11AB ],
- [ 0xEC90, 0x113A,0x116E,0x11AB ],
- [ 0xEC93, 0x113A,0x119E,0x11AF ],
- [ 0xEC95, 0x113B,0x1165,0x11AF ],
- [ 0xEC98, 0x113B,0x1173,0x11AF ],
- [ 0xEC9A, 0x113C,0x1161,0x11AB ],
- [ 0xEC9B, 0x113C,0x1161,0x11F0 ],
- [ 0xEC9E, 0x113C,0x1163,0x11B7 ],
- [ 0xEC9F, 0x113C,0x1163,0x11E2 ],
- [ 0xECA0, 0x113C,0x1163,0x11F0 ],
- [ 0xECA2, 0x113C,0x1165,0x11AB ],
- [ 0xECA4, 0x113C,0x1167,0x11AB ],
- [ 0xECA7, 0x113C,0x116E,0x11AB ],
- [ 0xECA8, 0x113C,0x116E,0x11BC ],
- [ 0xECAB, 0x113C,0x1172,0x11AB ],
- [ 0xECAD, 0x113C,0x1191,0x11AB ],
- [ 0xECAF, 0x113C,0x1173,0x11AB ],
- [ 0xECB0, 0x113C,0x1173,0x11EB ],
- [ 0xECB2, 0x113C,0x1175,0x11BC ],
- [ 0xECB4, 0x113D,0x1163,0x11BC ],
- [ 0xECB5, 0x113D,0x1163,0x11F0 ],
- [ 0xECB7, 0x113D,0x1167,0x11AB ],
- [ 0xECBB, 0x113D,0x1172,0x11AB ],
- [ 0xECBC, 0x113D,0x1172,0x11F0 ],
- [ 0xECBE, 0x113D,0x1191,0x11AB ],
- [ 0xECC1, 0x113D,0x1173,0x11EB ],
- [ 0xECC3, 0x113D,0x1175,0x11AB ],
- [ 0xECC4, 0x113D,0x1175,0x11EB ],
- [ 0xECC5, 0x113D,0x1175,0x11F9 ],
- [ 0xECC7, 0x113E,0x1161,0x11AB ],
- [ 0xECC8, 0x113E,0x1161,0x11AE ],
- [ 0xECCB, 0x113E,0x1163,0x11B7 ],
- [ 0xECCC, 0x113E,0x1163,0x11E2 ],
- [ 0xECCE, 0x113E,0x1167,0x11AB ],
- [ 0xECD3, 0x113E,0x116E,0x11A8 ],
- [ 0xECD4, 0x113E,0x116E,0x11BC ],
- [ 0xECD7, 0x113E,0x1172,0x11AB ],
- [ 0xECD9, 0x113E,0x1191,0x11AB ],
- [ 0xECDB, 0x113E,0x1173,0x11EB ],
- [ 0xECDC, 0x113E,0x1173,0x11BC ],
- [ 0xECDE, 0x113E,0x1175,0x11AB ],
- [ 0xECDF, 0x113E,0x1175,0x11B7 ],
- [ 0xECE0, 0x113E,0x1175,0x11E2 ],
- [ 0xECE2, 0x113F,0x1163,0x11F0 ],
- [ 0xECE4, 0x113F,0x1167,0x11AB ],
- [ 0xECE8, 0x113F,0x1172,0x11A8 ],
- [ 0xECE9, 0x113F,0x1172,0x11AB ],
- [ 0xECEA, 0x113F,0x1172,0x11F0 ],
- [ 0xECEC, 0x113F,0x1173,0x11EB ],
- [ 0xECEE, 0x113F,0x1175,0x11AB ],
- [ 0xECEF, 0x113F,0x1175,0x11F9 ],
- [ 0xECF1, 0x1140,0x1161,0x11A8 ],
- [ 0xECF2, 0x1140,0x1161,0x11AB ],
- [ 0xECF3, 0x1140,0x1161,0x11AE ],
- [ 0xECF4, 0x1140,0x1161,0x11AF ],
- [ 0xECF5, 0x1140,0x1161,0x11B7 ],
- [ 0xECF6, 0x1140,0x1161,0x11DD ],
- [ 0xECF7, 0x1140,0x1161,0x11B8 ],
- [ 0xECF8, 0x1140,0x1161,0x11BA ],
- [ 0xECF9, 0x1140,0x1161,0x11BC ],
- [ 0xECFA, 0x1140,0x1161,0x11F0 ],
- [ 0xECFC, 0x1140,0x1162,0x11AB ],
- [ 0xECFD, 0x1140,0x1162,0x11BA ],
- [ 0xECFE, 0x1140,0x1162,0x11EB ],
- [ 0xECFF, 0x1140,0x1162,0x11BC ],
- [ 0xED00, 0x1140,0x1162,0x11F0 ],
- [ 0xED02, 0x1140,0x1163,0x11A8 ],
- [ 0xED03, 0x1140,0x1163,0x11AB ],
- [ 0xED04, 0x1140,0x1163,0x11B7 ],
- [ 0xED05, 0x1140,0x1163,0x11E2 ],
- [ 0xED06, 0x1140,0x1163,0x11B8 ],
- [ 0xED07, 0x1140,0x1163,0x11E6 ],
- [ 0xED08, 0x1140,0x1163,0x11BC ],
- [ 0xED09, 0x1140,0x1163,0x11F0 ],
- [ 0xED0A, 0x1140,0x1163,0x11F9 ],
- [ 0xED0D, 0x1140,0x1165,0x11A8 ],
- [ 0xED0E, 0x1140,0x1165,0x11AB ],
- [ 0xED0F, 0x1140,0x1165,0x11AF ],
- [ 0xED10, 0x1140,0x1165,0x11B7 ],
- [ 0xED11, 0x1140,0x1165,0x11DD ],
- [ 0xED12, 0x1140,0x1165,0x11B8 ],
- [ 0xED13, 0x1140,0x1165,0x11BA ],
- [ 0xED14, 0x1140,0x1165,0x11EB ],
- [ 0xED15, 0x1140,0x1165,0x11BC ],
- [ 0xED16, 0x1140,0x1165,0x11F0 ],
- [ 0xED17, 0x1140,0x1165,0x11C2 ],
- [ 0xED1A, 0x1140,0x1166,0x11AB ],
- [ 0xED1B, 0x1140,0x1166,0x11BA ],
- [ 0xED1D, 0x1140,0x1167,0x11A8 ],
- [ 0xED1E, 0x1140,0x1167,0x11AB ],
- [ 0xED1F, 0x1140,0x1167,0x11AF ],
- [ 0xED20, 0x1140,0x1167,0x11B3 ],
- [ 0xED21, 0x1140,0x1167,0x11D9 ],
- [ 0xED22, 0x1140,0x1167,0x11B7 ],
- [ 0xED23, 0x1140,0x1167,0x11B8 ],
- [ 0xED24, 0x1140,0x1167,0x11BC ],
- [ 0xED25, 0x1140,0x1167,0x11F0 ],
- [ 0xED26, 0x1140,0x1167,0x11F9 ],
- [ 0xED28, 0x1140,0x1168,0x11AB ],
- [ 0xED29, 0x1140,0x1168,0x11AE ],
- [ 0xED2A, 0x1140,0x1168,0x11B7 ],
- [ 0xED2B, 0x1140,0x1168,0x11BA ],
- [ 0xED2C, 0x1140,0x1168,0x11BC ],
- [ 0xED2E, 0x1140,0x1169,0x11AB ],
- [ 0xED2F, 0x1140,0x1169,0x11AF ],
- [ 0xED30, 0x1140,0x1169,0x11D9 ],
- [ 0xED31, 0x1140,0x1169,0x11B7 ],
- [ 0xED32, 0x1140,0x1169,0x11B8 ],
- [ 0xED33, 0x1140,0x1169,0x11EB ],
- [ 0xED34, 0x1140,0x1169,0x11BC ],
- [ 0xED35, 0x1140,0x1169,0x11F0 ],
- [ 0xED3A, 0x1140,0x116D,0x11A8 ],
- [ 0xED3B, 0x1140,0x116D,0x11B7 ],
- [ 0xED3C, 0x1140,0x116D,0x11E2 ],
- [ 0xED3D, 0x1140,0x116D,0x11BA ],
- [ 0xED3E, 0x1140,0x116D,0x11BC ],
- [ 0xED3F, 0x1140,0x116D,0x11F0 ],
- [ 0xED40, 0x1140,0x116D,0x11C2 ],
- [ 0xED42, 0x1140,0x116E,0x11A8 ],
- [ 0xED43, 0x1140,0x116E,0x11AB ],
- [ 0xED44, 0x1140,0x116E,0x11AF ],
- [ 0xED45, 0x1140,0x116E,0x11D9 ],
- [ 0xED46, 0x1140,0x116E,0x11B7 ],
- [ 0xED47, 0x1140,0x116E,0x11DD ],
- [ 0xED48, 0x1140,0x116E,0x11B8 ],
- [ 0xED49, 0x1140,0x116E,0x11BA ],
- [ 0xED4A, 0x1140,0x116E,0x11BC ],
- [ 0xED4B, 0x1140,0x116E,0x11F0 ],
- [ 0xED4C, 0x1140,0x116E,0x11BE ],
- [ 0xED4D, 0x1140,0x116E,0x11C2 ],
- [ 0xED4F, 0x1140,0x1189,0x11AB ],
- [ 0xED55, 0x1140,0x1171,0x11AB ],
- [ 0xED57, 0x1140,0x1172,0x11A8 ],
- [ 0xED58, 0x1140,0x1172,0x11AB ],
- [ 0xED59, 0x1140,0x1172,0x11B7 ],
- [ 0xED5A, 0x1140,0x1172,0x11E2 ],
- [ 0xED5B, 0x1140,0x1172,0x11BA ],
- [ 0xED5C, 0x1140,0x1172,0x11BC ],
- [ 0xED5D, 0x1140,0x1172,0x11F0 ],
- [ 0xED5E, 0x1140,0x1172,0x11BD ],
- [ 0xED5F, 0x1140,0x1172,0x11BE ],
- [ 0xED60, 0x1140,0x1172,0x11F9 ],
- [ 0xED62, 0x1140,0x118F,0x11AB ],
- [ 0xED64, 0x1140,0x1191,0x11AB ],
- [ 0xED65, 0x1140,0x1191,0x11AF ],
- [ 0xED66, 0x1140,0x1191,0x11D9 ],
- [ 0xED68, 0x1140,0x1192,0x11BC ],
- [ 0xED6A, 0x1140,0x1194,0x11BC ],
- [ 0xED6C, 0x1140,0x1173,0x11A8 ],
- [ 0xED6D, 0x1140,0x1173,0x11AB ],
- [ 0xED6E, 0x1140,0x1173,0x11AF ],
- [ 0xED6F, 0x1140,0x1173,0x11B1 ],
- [ 0xED70, 0x1140,0x1173,0x11B3 ],
- [ 0xED71, 0x1140,0x1173,0x11B6 ],
- [ 0xED72, 0x1140,0x1173,0x11D9 ],
- [ 0xED73, 0x1140,0x1173,0x11B7 ],
- [ 0xED74, 0x1140,0x1173,0x11DD ],
- [ 0xED75, 0x1140,0x1173,0x11E0 ],
- [ 0xED76, 0x1140,0x1173,0x11B8 ],
- [ 0xED77, 0x1140,0x1173,0x11BA ],
- [ 0xED78, 0x1140,0x1173,0xD7F0 ],
- [ 0xED79, 0x1140,0x1173,0x11EB ],
- [ 0xED7A, 0x1140,0x1173,0x11F0 ],
- [ 0xED7B, 0x1140,0x1173,0x11BE ],
- [ 0xED7D, 0x1140,0x1174,0x11AB ],
- [ 0xED7E, 0x1140,0x1174,0x11BA ],
- [ 0xED80, 0x1140,0x1175,0x11A8 ],
- [ 0xED81, 0x1140,0x1175,0x11AB ],
- [ 0xED82, 0x1140,0x1175,0x11AE ],
- [ 0xED83, 0x1140,0x1175,0x11AF ],
- [ 0xED84, 0x1140,0x1175,0x11B3 ],
- [ 0xED85, 0x1140,0x1175,0x11D9 ],
- [ 0xED86, 0x1140,0x1175,0x11B7 ],
- [ 0xED87, 0x1140,0x1175,0x11B8 ],
- [ 0xED88, 0x1140,0x1175,0x11E6 ],
- [ 0xED89, 0x1140,0x1175,0x11BA ],
- [ 0xED8A, 0x1140,0x1175,0x11EB ],
- [ 0xED8B, 0x1140,0x1175,0x11BC ],
- [ 0xED8C, 0x1140,0x1175,0x11F0 ],
- [ 0xED8D, 0x1140,0x1175,0x11F9 ],
- [ 0xED90, 0x1140,0x119E,0x11A8 ],
- [ 0xED91, 0x1140,0x119E,0x11AB ],
- [ 0xED92, 0x1140,0x119E,0x11AE ],
- [ 0xED93, 0x1140,0x119E,0x11AF ],
- [ 0xED94, 0x1140,0x119E,0x11B0 ],
- [ 0xED95, 0x1140,0x119E,0x11B3 ],
- [ 0xED96, 0x1140,0x119E,0x11B6 ],
- [ 0xED97, 0x1140,0x119E,0x11D9 ],
- [ 0xED98, 0x1140,0x119E,0x11B7 ],
- [ 0xED99, 0x1140,0x119E,0x11DD ],
- [ 0xED9A, 0x1140,0x119E,0x11B8 ],
- [ 0xED9B, 0x1140,0x119E,0x11E6 ],
- [ 0xED9C, 0x1140,0x119E,0x11BA ],
- [ 0xED9D, 0x1140,0x119E,0x11EB ],
- [ 0xED9E, 0x1140,0x119E,0x11BC ],
- [ 0xED9F, 0x1140,0x119E,0x11BD ],
- [ 0xEDA1, 0x1140,0x11A1,0x11AB ],
- [ 0xEDA2, 0x1140,0x11A1,0x11AF ],
- [ 0xEDA3, 0x1140,0x11A1,0x11B8 ],
- [ 0xEDA4, 0x1140,0x11A1,0x11BA ],
- [ 0xEDA5, 0x110B,0x1161,0x11C7 ],
- [ 0xEDA6, 0x110B,0x1161,0x11C9 ],
- [ 0xEDA7, 0x110B,0x1161,0x11CD ],
- [ 0xEDA8, 0x110B,0x1161,0x11D0 ],
- [ 0xEDA9, 0x110B,0x1161,0x11D3 ],
- [ 0xEDAA, 0x110B,0x1161,0xD7DA ],
- [ 0xEDAB, 0x110B,0x1161,0x11D4 ],
- [ 0xEDAC, 0x110B,0x1161,0x11D6 ],
- [ 0xEDAD, 0x110B,0x1161,0x11D9 ],
- [ 0xEDAE, 0x110B,0x1161,0x11DD ],
- [ 0xEDAF, 0x110B,0x1161,0x11E1 ],
- [ 0xEDB0, 0x110B,0x1161,0x11E2 ],
- [ 0xEDB1, 0x110B,0x1161,0x11E3 ],
- [ 0xEDB2, 0x110B,0x1161,0xD7E4 ],
- [ 0xEDB3, 0x110B,0x1161,0x11E4 ],
- [ 0xEDB4, 0x110B,0x1161,0x11E5 ],
- [ 0xEDB5, 0x110B,0x1161,0x11E6 ],
- [ 0xEDB6, 0x110B,0x1161,0x11EA ],
- [ 0xEDB7, 0x110B,0x1161,0x11EB ],
- [ 0xEDB8, 0x110B,0x1161,0x11F0 ],
- [ 0xEDB9, 0x110B,0x1161,0x11F5 ],
- [ 0xEDBB, 0x110B,0x1176,0x11AF ],
- [ 0xEDBC, 0x110B,0x1162,0x11EB ],
- [ 0xEDBD, 0x110B,0x1162,0x11F0 ],
- [ 0xEDBE, 0x110B,0x1163,0x11D9 ],
- [ 0xEDBF, 0x110B,0x1163,0x11DC ],
- [ 0xEDC0, 0x110B,0x1163,0x11DD ],
- [ 0xEDC1, 0x110B,0x1163,0x11E2 ],
- [ 0xEDC2, 0x110B,0x1163,0x11E6 ],
- [ 0xEDC3, 0x110B,0x1163,0x11EA ],
- [ 0xEDC4, 0x110B,0x1163,0x11F1 ],
- [ 0xEDC5, 0x110B,0x1163,0x11F0 ],
- [ 0xEDC6, 0x110B,0x1163,0x11F5 ],
- [ 0xEDC7, 0x110B,0x1163,0x11F9 ],
- [ 0xEDCA, 0x110B,0x1165,0x11C3 ],
- [ 0xEDCB, 0x110B,0x1165,0x11C6 ],
- [ 0xEDCC, 0x110B,0x1165,0x11C7 ],
- [ 0xEDCD, 0x110B,0x1165,0x11CD ],
- [ 0xEDCE, 0x110B,0x1165,0x11D0 ],
- [ 0xEDCF, 0x110B,0x1165,0x11D9 ],
- [ 0xEDD0, 0x110B,0x1165,0x11DD ],
- [ 0xEDD1, 0x110B,0x1165,0x11DE ],
- [ 0xEDD2, 0x110B,0x1165,0x11E4 ],
- [ 0xEDD3, 0x110B,0x1165,0x11E6 ],
- [ 0xEDD4, 0x110B,0x1165,0xD7EF ],
- [ 0xEDD5, 0x110B,0x1165,0x11EB ],
- [ 0xEDD6, 0x110B,0x1165,0x11F0 ],
- [ 0xEDD7, 0x110B,0x1165,0xD7FA ],
- [ 0xEDDA, 0x110B,0x117C,0x11AB ],
- [ 0xEDDB, 0x110B,0x117C,0x11AF ],
- [ 0xEDDC, 0x110B,0x117C,0x11B7 ],
- [ 0xEDDD, 0x110B,0x117C,0x11B8 ],
- [ 0xEDDE, 0x110B,0x117C,0x11B9 ],
- [ 0xEDDF, 0x110B,0x117C,0x11BA ],
- [ 0xEDE0, 0x110B,0x117C,0x11BC ],
- [ 0xEDE1, 0x110B,0x1166,0x11C6 ],
- [ 0xEDE2, 0x110B,0x1166,0x11EB ],
- [ 0xEDE3, 0x110B,0x1166,0x11F0 ],
- [ 0xEDE4, 0x110B,0x1167,0x11C4 ],
- [ 0xEDE5, 0x110B,0x1167,0x11FD ],
- [ 0xEDE6, 0x110B,0x1167,0x11C6 ],
- [ 0xEDE7, 0x110B,0x1167,0x11C7 ],
- [ 0xEDE8, 0x110B,0x1167,0x11C9 ],
- [ 0xEDE9, 0x110B,0x1167,0xD7D4 ],
- [ 0xEDEA, 0x110B,0x1167,0x11D0 ],
- [ 0xEDEB, 0x110B,0x1167,0x11D5 ],
- [ 0xEDEC, 0x110B,0x1167,0x11D9 ],
- [ 0xEDED, 0x110B,0x1167,0x11E2 ],
- [ 0xEDEE, 0x110B,0x1167,0x11E3 ],
- [ 0xEDEF, 0x110B,0x1167,0xD7E6 ],
- [ 0xEDF0, 0x110B,0x1167,0x11E6 ],
- [ 0xEDF1, 0x110B,0x1167,0x11E7 ],
- [ 0xEDF2, 0x110B,0x1167,0x11EA ],
- [ 0xEDF3, 0x110B,0x1167,0xD7F1 ],
- [ 0xEDF4, 0x110B,0x1167,0xD7F2 ],
- [ 0xEDF5, 0x110B,0x1167,0x11EB ],
- [ 0xEDF6, 0x110B,0x1167,0x11EC ],
- [ 0xEDF7, 0x110B,0x1167,0x11ED ],
- [ 0xEDF8, 0x110B,0x1167,0x11F0 ],
- [ 0xEDF9, 0x110B,0x1167,0x11F9 ],
- [ 0xEDFC, 0x110B,0x1169,0x11C7 ],
- [ 0xEDFD, 0x110B,0x1169,0xD7D5 ],
- [ 0xEDFE, 0x110B,0x1169,0xD7D6 ],
- [ 0xEDFF, 0x110B,0x1169,0x11CD ],
- [ 0xEE00, 0x110B,0x1169,0x11D0 ],
- [ 0xEE01, 0x110B,0x1169,0x11D6 ],
- [ 0xEE02, 0x110B,0x1169,0x11D9 ],
- [ 0xEE03, 0x110B,0x1169,0x11DD ],
- [ 0xEE04, 0x110B,0x1169,0x11E2 ],
- [ 0xEE05, 0x110B,0x1169,0xD7F0 ],
- [ 0xEE06, 0x110B,0x1169,0x11EB ],
- [ 0xEE07, 0x110B,0x1169,0x11F0 ],
- [ 0xEE08, 0x110B,0x1169,0x11F1 ],
- [ 0xEE09, 0x110B,0x116A,0xD7CF ],
- [ 0xEE0A, 0x110B,0x116A,0xD7D4 ],
- [ 0xEE0B, 0x110B,0x116A,0x11DD ],
- [ 0xEE0C, 0x110B,0x116A,0x11EA ],
- [ 0xEE0D, 0x110B,0x116A,0x11F0 ],
- [ 0xEE0E, 0x110B,0x116A,0x11F9 ],
- [ 0xEE10, 0x110B,0x117F,0x11AB ],
- [ 0xEE11, 0x110B,0x117F,0x11AF ],
- [ 0xEE13, 0x110B,0x1182,0x11AF ],
- [ 0xEE14, 0x110B,0x116C,0x11D0 ],
- [ 0xEE15, 0x110B,0x116C,0x11D9 ],
- [ 0xEE16, 0x110B,0x116C,0x11F0 ],
- [ 0xEE17, 0x110B,0x116D,0x11D9 ],
- [ 0xEE18, 0x110B,0x116D,0x11E2 ],
- [ 0xEE19, 0x110B,0x116D,0x11F0 ],
- [ 0xEE1C, 0x110B,0xD7B3,0x11AB ],
- [ 0xEE1E, 0x110B,0xD7B4,0x11AB ],
- [ 0xEE21, 0x110B,0x1188,0x11AF ],
- [ 0xEE22, 0x110B,0x116E,0x11C9 ],
- [ 0xEE23, 0x110B,0x116E,0xD7D3 ],
- [ 0xEE24, 0x110B,0x116E,0x11CD ],
- [ 0xEE25, 0x110B,0x116E,0x11D0 ],
- [ 0xEE26, 0x110B,0x116E,0x11D9 ],
- [ 0xEE27, 0x110B,0x116E,0x11DD ],
- [ 0xEE28, 0x110B,0x116E,0x11E0 ],
- [ 0xEE29, 0x110B,0x116E,0x11E1 ],
- [ 0xEE2A, 0x110B,0x116E,0x11E2 ],
- [ 0xEE2B, 0x110B,0x116E,0x11E4 ],
- [ 0xEE2C, 0x110B,0x116E,0x11EA ],
- [ 0xEE2D, 0x110B,0x116E,0xD7EB ],
- [ 0xEE2E, 0x110B,0x116E,0xD7F0 ],
- [ 0xEE2F, 0x110B,0x116E,0x11EB ],
- [ 0xEE30, 0x110B,0x116E,0xD7F3 ],
- [ 0xEE31, 0x110B,0x116E,0xD7F4 ],
- [ 0xEE32, 0x110B,0x116E,0x11F0 ],
- [ 0xEE33, 0x110B,0x116E,0x11F9 ],
- [ 0xEE35, 0x110B,0x1189,0x11AB ],
- [ 0xEE36, 0x110B,0x1189,0x11BC ],
- [ 0xEE37, 0x110B,0x1189,0x11F0 ],
- [ 0xEE39, 0x110B,0x116F,0x11D8 ],
- [ 0xEE3A, 0x110B,0x116F,0x11D9 ],
- [ 0xEE3B, 0x110B,0x116F,0x11EB ],
- [ 0xEE3C, 0x110B,0x116F,0x11F0 ],
- [ 0xEE3D, 0x110B,0x116F,0x11F1 ],
- [ 0xEE3F, 0x110B,0x118B,0x11AB ],
- [ 0xEE42, 0x110B,0x1171,0x11D9 ],
- [ 0xEE43, 0x110B,0x1171,0x11F0 ],
- [ 0xEE44, 0x110B,0x1172,0x11D9 ],
- [ 0xEE45, 0x110B,0x1172,0x11E2 ],
- [ 0xEE46, 0x110B,0x1172,0x11F0 ],
- [ 0xEE47, 0x110B,0x1172,0x11F9 ],
- [ 0xEE49, 0x110B,0x118E,0x11AB ],
- [ 0xEE4A, 0x110B,0x118E,0x11B7 ],
- [ 0xEE4D, 0x110B,0x1190,0x11AB ],
- [ 0xEE4F, 0x110B,0x1191,0x11A8 ],
- [ 0xEE50, 0x110B,0x1191,0x11AB ],
- [ 0xEE51, 0x110B,0x1191,0x11AF ],
- [ 0xEE52, 0x110B,0x1191,0x11D9 ],
- [ 0xEE53, 0x110B,0x1191,0x11F0 ],
- [ 0xEE54, 0x110B,0x1191,0x11F9 ],
- [ 0xEE56, 0x110B,0x1192,0x11BC ],
- [ 0xEE57, 0x110B,0x1192,0x11F0 ],
- [ 0xEE5A, 0x110B,0x1194,0x11AB ],
- [ 0xEE5B, 0x110B,0x1194,0x11BC ],
- [ 0xEE5C, 0x110B,0x1194,0x11F0 ],
- [ 0xEE5D, 0x110B,0x1173,0x11FF ],
- [ 0xEE5E, 0x110B,0x1173,0x11C7 ],
- [ 0xEE5F, 0x110B,0x1173,0xD7CD ],
- [ 0xEE60, 0x110B,0x1173,0x11D0 ],
- [ 0xEE61, 0x110B,0x1173,0xD7DA ],
- [ 0xEE62, 0x110B,0x1173,0x11D4 ],
- [ 0xEE63, 0x110B,0x1173,0x11D9 ],
- [ 0xEE64, 0x110B,0x1173,0x11DD ],
- [ 0xEE65, 0x110B,0x1173,0x11E2 ],
- [ 0xEE66, 0x110B,0x1173,0x11E3 ],
- [ 0xEE67, 0x110B,0x1173,0xD7E6 ],
- [ 0xEE68, 0x110B,0x1173,0x11E4 ],
- [ 0xEE69, 0x110B,0x1173,0xD7F0 ],
- [ 0xEE6A, 0x110B,0x1173,0x11EB ],
- [ 0xEE6B, 0x110B,0x1173,0x11F0 ],
- [ 0xEE6C, 0x110B,0x1173,0xD7F9 ],
- [ 0xEE6D, 0x110B,0x1173,0x11F9 ],
- [ 0xEE70, 0x110B,0x1196,0x11AB ],
- [ 0xEE71, 0x110B,0x1196,0x11BC ],
- [ 0xEE72, 0x110B,0x1196,0x11F0 ],
- [ 0xEE73, 0x110B,0x1196,0x11F9 ],
- [ 0xEE74, 0x110B,0x1174,0x11D9 ],
- [ 0xEE75, 0x110B,0x1174,0x11F9 ],
- [ 0xEE76, 0x110B,0x1175,0x11C7 ],
- [ 0xEE77, 0x110B,0x1175,0x11CD ],
- [ 0xEE78, 0x110B,0x1175,0x11D0 ],
- [ 0xEE79, 0x110B,0x1175,0x11D9 ],
- [ 0xEE7A, 0x110B,0x1175,0x11E2 ],
- [ 0xEE7B, 0x110B,0x1175,0x11E5 ],
- [ 0xEE7C, 0x110B,0x1175,0x11E6 ],
- [ 0xEE7D, 0x110B,0x1175,0x11E7 ],
- [ 0xEE7E, 0x110B,0x1175,0x11E9 ],
- [ 0xEE7F, 0x110B,0x1175,0x11EA ],
- [ 0xEE80, 0x110B,0x1175,0x11F0 ],
- [ 0xEE81, 0x110B,0x1175,0x11F9 ],
- [ 0xEE87, 0x110B,0x119C,0x11AB ],
- [ 0xEE89, 0x110B,0x119E,0x11A8 ],
- [ 0xEE8A, 0x110B,0x119E,0x11AB ],
- [ 0xEE8B, 0x110B,0x119E,0x11AE ],
- [ 0xEE8C, 0x110B,0x119E,0x11AF ],
- [ 0xEE8D, 0x110B,0x119E,0x11B0 ],
- [ 0xEE8E, 0x110B,0x119E,0x11B1 ],
- [ 0xEE8F, 0x110B,0x119E,0x11B2 ],
- [ 0xEE90, 0x110B,0x119E,0x11B3 ],
- [ 0xEE91, 0x110B,0x119E,0x11B6 ],
- [ 0xEE92, 0x110B,0x119E,0x11D9 ],
- [ 0xEE93, 0x110B,0x119E,0x11B7 ],
- [ 0xEE94, 0x110B,0x119E,0x11DD ],
- [ 0xEE95, 0x110B,0x119E,0x11B8 ],
- [ 0xEE96, 0x110B,0x119E,0x11B9 ],
- [ 0xEE97, 0x110B,0x119E,0x11BA ],
- [ 0xEE98, 0x110B,0x119E,0x11EB ],
- [ 0xEE99, 0x110B,0x119E,0x11BC ],
- [ 0xEE9A, 0x110B,0x119E,0x11F0 ],
- [ 0xEE9B, 0x110B,0x119E,0x11BD ],
- [ 0xEE9C, 0x110B,0x119E,0x11BE ],
- [ 0xEE9D, 0x110B,0x119E,0x11C0 ],
- [ 0xEE9F, 0x110B,0x119F,0x11AB ],
- [ 0xEEA0, 0x110B,0x119F,0x11AF ],
- [ 0xEEA1, 0x110B,0x119F,0x11B2 ],
- [ 0xEEA2, 0x110B,0x119F,0x11B7 ],
- [ 0xEEA3, 0x110B,0x119F,0x11BC ],
- [ 0xEEA5, 0x110B,0x11A1,0x11A8 ],
- [ 0xEEA6, 0x110B,0x11A1,0x11AB ],
- [ 0xEEA7, 0x110B,0x11A1,0x11AF ],
- [ 0xEEA8, 0x110B,0x11A1,0x11B7 ],
- [ 0xEEA9, 0x110B,0x11A1,0x11B8 ],
- [ 0xEEAA, 0x110B,0x11A1,0x11BA ],
- [ 0xEEAB, 0x110B,0x11A1,0x11EB ],
- [ 0xEEAC, 0x110B,0x11A1,0x11BC ],
- [ 0xEEAD, 0x110B,0x11A1,0x11F0 ],
- [ 0xEEAF, 0x110B,0x11A2,0x11AF ],
- [ 0xEEB1, 0x1141,0x1161,0x11A8 ],
- [ 0xEEB4, 0x1141,0x1163,0x11AB ],
- [ 0xEEB9, 0x1141,0x1168,0x11AB ],
- [ 0xEEBB, 0x1141,0x1169,0x11A8 ],
- [ 0xEEBC, 0x1141,0x1169,0x11AB ],
- [ 0xEEBE, 0x1141,0x116A,0x11AB ],
- [ 0xEEC3, 0x1141,0x116E,0x11AB ],
- [ 0xEECE, 0x1141,0x1175,0x11AB ],
- [ 0xEED3, 0x1142,0x1161,0x11AB ],
- [ 0xEED5, 0x1142,0x1165,0x11AF ],
- [ 0xEED7, 0x1142,0x1166,0x11AB ],
- [ 0xEED9, 0x1142,0x1169,0x11AB ],
- [ 0xEEDA, 0x1142,0x1169,0x11AF ],
- [ 0xEEDC, 0x1142,0x1173,0x11B7 ],
- [ 0xEEDF, 0x1142,0x1175,0x11BC ],
- [ 0xEEE1, 0x1142,0x119E,0x11B7 ],
- [ 0xEEE9, 0x1144,0x1161,0x11AB ],
- [ 0xEEEA, 0x1144,0x1161,0x11AF ],
- [ 0xEEEB, 0x1144,0x1161,0x11B7 ],
- [ 0xEEED, 0x1144,0x1162,0x11AF ],
- [ 0xEEEE, 0x1144,0x1162,0x11B7 ],
- [ 0xEEF0, 0x1144,0x1165,0x11AF ],
- [ 0xEEF1, 0x1144,0x1165,0x11C0 ],
- [ 0xEEF3, 0x1144,0x1166,0x11AB ],
- [ 0xEEF4, 0x1144,0x1166,0x11AF ],
- [ 0xEEF5, 0x1144,0x1166,0x11C0 ],
- [ 0xEEF8, 0x1144,0x1168,0x11AB ],
- [ 0xEEFA, 0x1144,0x1169,0x11AB ],
- [ 0xEEFB, 0x1144,0x1169,0x11AF ],
- [ 0xEEFC, 0x1144,0x1169,0x11C0 ],
- [ 0xEEFE, 0x1144,0x116A,0x11B7 ],
- [ 0xEF01, 0x1144,0x116E,0x11AB ],
- [ 0xEF02, 0x1144,0x116E,0x11AF ],
- [ 0xEF05, 0x1144,0x1170,0x11AF ],
- [ 0xEF07, 0x1144,0x1171,0x11BC ],
- [ 0xEF0A, 0x1144,0x1173,0x11AB ],
- [ 0xEF0B, 0x1144,0x1173,0x11AF ],
- [ 0xEF0E, 0x1144,0x1175,0x11A8 ],
- [ 0xEF0F, 0x1144,0x1175,0x11AB ],
- [ 0xEF10, 0x1144,0x1175,0x11AF ],
- [ 0xEF11, 0x1144,0x1175,0x11BC ],
- [ 0xEF12, 0x1144,0x1175,0x11BF ],
- [ 0xEF16, 0x1145,0x1161,0x11AB ],
- [ 0xEF17, 0x1145,0x1161,0x11BC ],
- [ 0xEF1B, 0x1145,0x1165,0x11AB ],
- [ 0xEF1C, 0x1145,0x1165,0x11AF ],
- [ 0xEF1D, 0x1145,0x1165,0x11B7 ],
- [ 0xEF1E, 0x1145,0x1165,0x11BC ],
- [ 0xEF23, 0x1145,0x1168,0x11AB ],
- [ 0xEF25, 0x1145,0x1169,0x11AB ],
- [ 0xEF27, 0x1145,0x116E,0x11AB ],
- [ 0xEF29, 0x1145,0x1189,0x11AB ],
- [ 0xEF2A, 0x1145,0x1189,0x11BC ],
- [ 0xEF30, 0x1145,0x118E,0x11AB ],
- [ 0xEF35, 0x1145,0x1173,0x11AB ],
- [ 0xEF37, 0x1145,0x1174,0x11AB ],
- [ 0xEF39, 0x1145,0x1175,0x11AF ],
- [ 0xEF3B, 0x1145,0x119E,0x11AF ],
- [ 0xEF57, 0x1147,0x1163,0x11AB ],
- [ 0xEF59, 0x1147,0x1167,0x11AB ],
- [ 0xEF5A, 0x1147,0x1167,0x11BA ],
- [ 0xEF5C, 0x1147,0x1168,0x11BA ],
- [ 0xEF5E, 0x1147,0x116D,0x11AB ],
- [ 0xEF5F, 0x1147,0x116D,0x11B7 ],
- [ 0xEF60, 0x1147,0x116D,0x11E2 ],
- [ 0xEF61, 0x1147,0x116D,0x11BA ],
- [ 0xEF65, 0x1147,0x1172,0x11AB ],
- [ 0xEF66, 0x1147,0x1172,0x11B7 ],
- [ 0xEF68, 0x1147,0x118E,0x11AB ],
- [ 0xEF6A, 0x1147,0x1175,0x11AB ],
- [ 0xEF6C, 0x1148,0x1161,0x11AB ],
- [ 0xEF6D, 0x1148,0x1161,0x11BC ],
- [ 0xEF71, 0x1148,0x1165,0x11AB ],
- [ 0xEF72, 0x1148,0x1165,0x11B7 ],
- [ 0xEF73, 0x1148,0x1165,0x11BC ],
- [ 0xEF78, 0x1148,0x116E,0x11AB ],
- [ 0xEF79, 0x1148,0x116E,0x11BC ],
- [ 0xEF7B, 0x1148,0x1189,0x11AB ],
- [ 0xEF84, 0x1149,0x1161,0x11AB ],
- [ 0xEF85, 0x1149,0x1161,0x11BC ],
- [ 0xEF88, 0x1149,0x1165,0x11AB ],
- [ 0xEF89, 0x1149,0x1165,0x11BC ],
- [ 0xEF8B, 0x1149,0x116E,0x11AB ],
- [ 0xEF8C, 0x1149,0x116E,0x11BC ],
- [ 0xEF8E, 0x1149,0x1189,0x11AB ],
- [ 0xEF93, 0x1149,0x118E,0x11AB ],
- [ 0xEF98, 0x114B,0x1161,0x11A8 ],
- [ 0xEF99, 0x114B,0x1161,0x11AB ],
- [ 0xEF9A, 0x114B,0x1161,0x11AF ],
- [ 0xEF9B, 0x114B,0x1161,0x11D8 ],
- [ 0xEF9C, 0x114B,0x1161,0x11BF ],
- [ 0xEF9E, 0x114B,0x1162,0x11AB ],
- [ 0xEF9F, 0x114B,0x1162,0x11BF ],
- [ 0xEFA1, 0x114B,0x1165,0x11AB ],
- [ 0xEFA2, 0x114B,0x1165,0x11AF ],
- [ 0xEFA3, 0x114B,0x1165,0x11B7 ],
- [ 0xEFA4, 0x114B,0x1165,0x11BC ],
- [ 0xEFA6, 0x114B,0x1166,0x11A8 ],
- [ 0xEFA7, 0x114B,0x1166,0x11AB ],
- [ 0xEFA8, 0x114B,0x1166,0x11AF ],
- [ 0xEFA9, 0x114B,0x1166,0x11BF ],
- [ 0xEFAB, 0x114B,0x1169,0x11AB ],
- [ 0xEFAC, 0x114B,0x1169,0x11AF ],
- [ 0xEFAD, 0x114B,0x1169,0x11B1 ],
- [ 0xEFAE, 0x114B,0x1169,0x11D8 ],
- [ 0xEFAF, 0x114B,0x1169,0x11B7 ],
- [ 0xEFB0, 0x114B,0x1169,0x11BF ],
- [ 0xEFB3, 0x114B,0x116B,0x11AB ],
- [ 0xEFB5, 0x114B,0x116E,0x11AB ],
- [ 0xEFB6, 0x114B,0x116E,0x11AF ],
- [ 0xEFB7, 0x114B,0x116E,0x11BF ],
- [ 0xEFB8, 0x114B,0x116E,0x11C0 ],
- [ 0xEFBA, 0x114B,0x1189,0x11AB ],
- [ 0xEFBC, 0x114B,0x116F,0x11AB ],
- [ 0xEFBE, 0x114B,0x1170,0x11AB ],
- [ 0xEFC0, 0x114B,0x1171,0x11A8 ],
- [ 0xEFC1, 0x114B,0x1171,0x11AB ],
- [ 0xEFC2, 0x114B,0x1171,0x11AF ],
- [ 0xEFC4, 0x114B,0x1172,0x11B7 ],
- [ 0xEFC6, 0x114B,0x1173,0x11AF ],
- [ 0xEFC8, 0x114B,0x1175,0x11AB ],
- [ 0xEFC9, 0x114B,0x1175,0x11AF ],
- [ 0xEFCA, 0x114B,0x1175,0x11BC ],
- [ 0xEFCB, 0x114B,0x1175,0x11BF ],
- [ 0xEFCC, 0x114B,0x1175,0x11C0 ],
- [ 0xEFCD, 0x114B,0x1175,0x11C1 ],
- [ 0xEFD3, 0x114C,0x1161,0x11A8 ],
- [ 0xEFD4, 0x114C,0x1161,0x11AB ],
- [ 0xEFD5, 0x114C,0x1161,0x11AF ],
- [ 0xEFD6, 0x114C,0x1161,0x11D9 ],
- [ 0xEFD7, 0x114C,0x1161,0x11B7 ],
- [ 0xEFD8, 0x114C,0x1161,0x11B8 ],
- [ 0xEFD9, 0x114C,0x1161,0x11EB ],
- [ 0xEFDA, 0x114C,0x1161,0x11BC ],
- [ 0xEFDB, 0x114C,0x1161,0x11F0 ],
- [ 0xEFDC, 0x114C,0x1161,0x11F9 ],
- [ 0xEFDE, 0x114C,0x1162,0x11BA ],
- [ 0xEFDF, 0x114C,0x1162,0x11BC ],
- [ 0xEFE1, 0x114C,0x1163,0x11A8 ],
- [ 0xEFE2, 0x114C,0x1163,0x11AB ],
- [ 0xEFE3, 0x114C,0x1163,0x11BC ],
- [ 0xEFE4, 0x114C,0x1163,0x11F0 ],
- [ 0xEFE6, 0x114C,0x1164,0x11BA ],
- [ 0xEFE8, 0x114C,0x1165,0x11A8 ],
- [ 0xEFE9, 0x114C,0x1165,0x11AB ],
- [ 0xEFEA, 0x114C,0x1165,0x11AF ],
- [ 0xEFEB, 0x114C,0x1165,0x11D9 ],
- [ 0xEFEC, 0x114C,0x1165,0x11B7 ],
- [ 0xEFED, 0x114C,0x1165,0x11B8 ],
- [ 0xEFEE, 0x114C,0x1165,0x11BA ],
- [ 0xEFEF, 0x114C,0x1165,0x11EB ],
- [ 0xEFF0, 0x114C,0x1165,0x11BC ],
- [ 0xEFF1, 0x114C,0x1165,0x11F0 ],
- [ 0xEFF3, 0x114C,0x1166,0x11AB ],
- [ 0xEFF4, 0x114C,0x1166,0x11BA ],
- [ 0xEFF5, 0x114C,0x1166,0x11EB ],
- [ 0xEFF6, 0x114C,0x1166,0x11BC ],
- [ 0xEFF7, 0x114C,0x1166,0x11F0 ],
- [ 0xEFF9, 0x114C,0x1167,0x11A8 ],
- [ 0xEFFA, 0x114C,0x1167,0x11AB ],
- [ 0xEFFB, 0x114C,0x1167,0x11AF ],
- [ 0xEFFC, 0x114C,0x1167,0x11B7 ],
- [ 0xEFFD, 0x114C,0x1167,0x11E2 ],
- [ 0xEFFE, 0x114C,0x1167,0x11B8 ],
- [ 0xEFFF, 0x114C,0x1167,0x11BA ],
- [ 0xF100, 0x114C,0x1167,0x11BC ],
- [ 0xF101, 0x114C,0x1167,0x11F0 ],
- [ 0xF102, 0x114C,0x1167,0x11C1 ],
- [ 0xF103, 0x114C,0x1167,0x11F4 ],
- [ 0xF105, 0x114C,0x1168,0x11BA ],
- [ 0xF106, 0x114C,0x1168,0x11BC ],
- [ 0xF108, 0x114C,0x1169,0x11A8 ],
- [ 0xF109, 0x114C,0x1169,0x11AB ],
- [ 0xF10A, 0x114C,0x1169,0x11AF ],
- [ 0xF10B, 0x114C,0x1169,0x11B3 ],
- [ 0xF10C, 0x114C,0x1169,0x11D9 ],
- [ 0xF10D, 0x114C,0x1169,0x11B7 ],
- [ 0xF10E, 0x114C,0x1169,0x11E2 ],
- [ 0xF10F, 0x114C,0x1169,0x11BA ],
- [ 0xF110, 0x114C,0x1169,0x11BC ],
- [ 0xF111, 0x114C,0x1169,0x11F0 ],
- [ 0xF113, 0x114C,0x116A,0x11A8 ],
- [ 0xF114, 0x114C,0x116A,0x11AB ],
- [ 0xF115, 0x114C,0x116A,0x11AF ],
- [ 0xF116, 0x114C,0x116A,0x11D9 ],
- [ 0xF117, 0x114C,0x116A,0x11B7 ],
- [ 0xF118, 0x114C,0x116A,0x11DD ],
- [ 0xF119, 0x114C,0x116A,0x11BC ],
- [ 0xF11A, 0x114C,0x116A,0x11F0 ],
- [ 0xF11C, 0x114C,0x116B,0x11BC ],
- [ 0xF11E, 0x114C,0x116C,0x11AB ],
- [ 0xF11F, 0x114C,0x116C,0x11BC ],
- [ 0xF120, 0x114C,0x116C,0x11F0 ],
- [ 0xF122, 0x114C,0x116D,0x11B7 ],
- [ 0xF123, 0x114C,0x116D,0x11E2 ],
- [ 0xF124, 0x114C,0x116D,0x11F0 ],
- [ 0xF127, 0x114C,0x1185,0x11BC ],
- [ 0xF129, 0x114C,0x116E,0x11A8 ],
- [ 0xF12A, 0x114C,0x116E,0x11AB ],
- [ 0xF12B, 0x114C,0x116E,0x11AF ],
- [ 0xF12C, 0x114C,0x116E,0x11D9 ],
- [ 0xF12D, 0x114C,0x116E,0x11B7 ],
- [ 0xF12E, 0x114C,0x116E,0x11E2 ],
- [ 0xF12F, 0x114C,0x116E,0x11BC ],
- [ 0xF131, 0x114C,0x116F,0x11AB ],
- [ 0xF132, 0x114C,0x116F,0x11AF ],
- [ 0xF133, 0x114C,0x116F,0x11D9 ],
- [ 0xF134, 0x114C,0x116F,0x11BC ],
- [ 0xF135, 0x114C,0x116F,0x11F0 ],
- [ 0xF138, 0x114C,0x1171,0x11AF ],
- [ 0xF139, 0x114C,0x1171,0x11D9 ],
- [ 0xF13A, 0x114C,0x1171,0x11BC ],
- [ 0xF13B, 0x114C,0x1171,0x11F0 ],
- [ 0xF13D, 0x114C,0x1172,0x11A8 ],
- [ 0xF13E, 0x114C,0x1172,0x11AB ],
- [ 0xF13F, 0x114C,0x1172,0x11AF ],
- [ 0xF140, 0x114C,0x1172,0x11D9 ],
- [ 0xF141, 0x114C,0x1172,0x11B7 ],
- [ 0xF142, 0x114C,0x1172,0x11E2 ],
- [ 0xF144, 0x114C,0x1191,0x11A8 ],
- [ 0xF145, 0x114C,0x1191,0x11AB ],
- [ 0xF146, 0x114C,0x1191,0x11F0 ],
- [ 0xF147, 0x114C,0x1191,0x11F9 ],
- [ 0xF14A, 0x114C,0x1173,0x11A8 ],
- [ 0xF14B, 0x114C,0x1173,0x11AB ],
- [ 0xF14C, 0x114C,0x1173,0x11AF ],
- [ 0xF14D, 0x114C,0x1173,0x11D9 ],
- [ 0xF14E, 0x114C,0x1173,0x11B7 ],
- [ 0xF14F, 0x114C,0x1173,0x11B8 ],
- [ 0xF150, 0x114C,0x1173,0x11BC ],
- [ 0xF151, 0x114C,0x1173,0x11F0 ],
- [ 0xF153, 0x114C,0x1174,0x11BC ],
- [ 0xF155, 0x114C,0x1175,0x11AB ],
- [ 0xF156, 0x114C,0x1175,0x11AE ],
- [ 0xF157, 0x114C,0x1175,0x11AF ],
- [ 0xF158, 0x114C,0x1175,0x11BA ],
- [ 0xF159, 0x114C,0x1175,0x11EB ],
- [ 0xF15A, 0x114C,0x1175,0x11BC ],
- [ 0xF15B, 0x114C,0x1175,0x11F0 ],
- [ 0xF15D, 0x114C,0x119E,0x11A8 ],
- [ 0xF15E, 0x114C,0x119E,0x11AB ],
- [ 0xF15F, 0x114C,0x119E,0x11AE ],
- [ 0xF160, 0x114C,0x119E,0x11AF ],
- [ 0xF161, 0x114C,0x119E,0x11BA ],
- [ 0xF163, 0x114C,0x11A1,0x11A8 ],
- [ 0xF164, 0x110C,0x1161,0x11C7 ],
- [ 0xF165, 0x110C,0x1161,0x11CD ],
- [ 0xF166, 0x110C,0x1161,0x11D0 ],
- [ 0xF167, 0x110C,0x1161,0x11D9 ],
- [ 0xF168, 0x110C,0x1161,0x11DA ],
- [ 0xF169, 0x110C,0x1161,0x11DD ],
- [ 0xF16A, 0x110C,0x1161,0x11E2 ],
- [ 0xF16B, 0x110C,0x1161,0xD7E6 ],
- [ 0xF16C, 0x110C,0x1161,0x11E6 ],
- [ 0xF16D, 0x110C,0x1161,0x11EB ],
- [ 0xF16E, 0x110C,0x1161,0x11F0 ],
- [ 0xF16F, 0x110C,0x1161,0x11EC ],
- [ 0xF170, 0x110C,0x1161,0x11F1 ],
- [ 0xF171, 0x110C,0x1161,0x11F9 ],
- [ 0xF173, 0x110C,0x1162,0x11F0 ],
- [ 0xF174, 0x110C,0x1163,0x11C7 ],
- [ 0xF175, 0x110C,0x1163,0x11CD ],
- [ 0xF176, 0x110C,0x1163,0x11D0 ],
- [ 0xF177, 0x110C,0x1163,0x11E2 ],
- [ 0xF178, 0x110C,0x1163,0x11EB ],
- [ 0xF179, 0x110C,0x1163,0x11F1 ],
- [ 0xF17A, 0x110C,0x1163,0x11F0 ],
- [ 0xF17B, 0x110C,0x1163,0x11F1 ],
- [ 0xF17E, 0x110C,0x11A4,0x11AF ],
- [ 0xF17F, 0x110C,0x1165,0x11FE ],
- [ 0xF180, 0x110C,0x1165,0x11CD ],
- [ 0xF181, 0x110C,0x1165,0x11D0 ],
- [ 0xF182, 0x110C,0x1165,0x11D9 ],
- [ 0xF183, 0x110C,0x1165,0x11DD ],
- [ 0xF184, 0x110C,0x1165,0x11E4 ],
- [ 0xF185, 0x110C,0x1165,0xD7F2 ],
- [ 0xF186, 0x110C,0x1165,0x11EB ],
- [ 0xF187, 0x110C,0x1165,0x11F0 ],
- [ 0xF188, 0x110C,0x1165,0xD7F6 ],
- [ 0xF189, 0x110C,0x1165,0x11F9 ],
- [ 0xF18C, 0x110C,0x117C,0x11A8 ],
- [ 0xF18D, 0x110C,0x117C,0x11AB ],
- [ 0xF18E, 0x110C,0x117C,0x11BC ],
- [ 0xF18F, 0x110C,0x117C,0x11F9 ],
- [ 0xF190, 0x110C,0x1167,0x11C7 ],
- [ 0xF191, 0x110C,0x1167,0x11CA ],
- [ 0xF192, 0x110C,0x1167,0xD7CD ],
- [ 0xF193, 0x110C,0x1167,0xD7CE ],
- [ 0xF194, 0x110C,0x1167,0xD7D2 ],
- [ 0xF195, 0x110C,0x1167,0x11D0 ],
- [ 0xF196, 0x110C,0x1167,0x11D9 ],
- [ 0xF197, 0x110C,0x1167,0x11E2 ],
- [ 0xF198, 0x110C,0x1167,0x11EB ],
- [ 0xF199, 0x110C,0x1167,0x11F0 ],
- [ 0xF19A, 0x110C,0x1167,0x11F9 ],
- [ 0xF19C, 0x110C,0x11A5,0x11BC ],
- [ 0xF19F, 0x110C,0x1169,0x11C7 ],
- [ 0xF1A0, 0x110C,0x1169,0x11D9 ],
- [ 0xF1A1, 0x110C,0x1169,0x11DD ],
- [ 0xF1A2, 0x110C,0x1169,0x11E2 ],
- [ 0xF1A3, 0x110C,0x1169,0x11EB ],
- [ 0xF1A4, 0x110C,0x1169,0x11F0 ],
- [ 0xF1A5, 0x110C,0x116A,0x11D9 ],
- [ 0xF1A6, 0x110C,0x116A,0x11E2 ],
- [ 0xF1A7, 0x110C,0x116A,0x11F0 ],
- [ 0xF1A8, 0x110C,0x116D,0x11D9 ],
- [ 0xF1A9, 0x110C,0x116D,0x11E2 ],
- [ 0xF1AA, 0x110C,0x116D,0x11E6 ],
- [ 0xF1AB, 0x110C,0x116D,0x11F1 ],
- [ 0xF1AC, 0x110C,0x116D,0x11F0 ],
- [ 0xF1AD, 0x110C,0x116D,0x11F1 ],
- [ 0xF1B0, 0x110C,0x1188,0x11AF ],
- [ 0xF1B1, 0x110C,0x1188,0x11D9 ],
- [ 0xF1B2, 0x110C,0x116E,0x11C7 ],
- [ 0xF1B3, 0x110C,0x116E,0x11CD ],
- [ 0xF1B4, 0x110C,0x116E,0x11D9 ],
- [ 0xF1B5, 0x110C,0x116E,0x11DD ],
- [ 0xF1B6, 0x110C,0x116E,0x11E2 ],
- [ 0xF1B7, 0x110C,0x116E,0x11EB ],
- [ 0xF1B8, 0x110C,0x116E,0x11F0 ],
- [ 0xF1B9, 0x110C,0x116E,0x11F9 ],
- [ 0xF1BB, 0x110C,0x1189,0x11BC ],
- [ 0xF1BE, 0x110C,0xD7B5,0x11AB ],
- [ 0xF1BF, 0x110C,0xD7B5,0x11AF ],
- [ 0xF1C0, 0x110C,0xD7B5,0x11D9 ],
- [ 0xF1C2, 0x110C,0x1172,0x11D9 ],
- [ 0xF1C3, 0x110C,0x1172,0x11E2 ],
- [ 0xF1C4, 0x110C,0x1172,0x11F0 ],
- [ 0xF1C5, 0x110C,0x1172,0x11EC ],
- [ 0xF1C6, 0x110C,0x1172,0x11F9 ],
- [ 0xF1C8, 0x110C,0x118E,0x11AB ],
- [ 0xF1CA, 0x110C,0x118F,0x11AB ],
- [ 0xF1CB, 0x110C,0x118F,0x11AF ],
- [ 0xF1CE, 0x110C,0x1191,0x11AB ],
- [ 0xF1CF, 0x110C,0x1191,0x11AF ],
- [ 0xF1D0, 0x110C,0x1191,0x11D9 ],
- [ 0xF1D1, 0x110C,0x1191,0x11F9 ],
- [ 0xF1D3, 0x110C,0x1192,0x11AB ],
- [ 0xF1D4, 0x110C,0x1192,0x11B8 ],
- [ 0xF1D5, 0x110C,0x1192,0x11BC ],
- [ 0xF1D7, 0x110C,0x1194,0x11A8 ],
- [ 0xF1D8, 0x110C,0x1194,0x11AB ],
- [ 0xF1D9, 0x110C,0x1194,0x11AF ],
- [ 0xF1DA, 0x110C,0x1194,0x11D9 ],
- [ 0xF1DB, 0x110C,0x1194,0x11BA ],
- [ 0xF1DC, 0x110C,0x1194,0x11BC ],
- [ 0xF1DD, 0x110C,0x1173,0x11D0 ],
- [ 0xF1DE, 0x110C,0x1173,0x11D9 ],
- [ 0xF1DF, 0x110C,0x1173,0x11E2 ],
- [ 0xF1E0, 0x110C,0x1173,0x11E6 ],
- [ 0xF1E1, 0x110C,0x1173,0x11EB ],
- [ 0xF1E2, 0x110C,0x1173,0x11F0 ],
- [ 0xF1E5, 0x110C,0x1174,0x11F0 ],
- [ 0xF1E6, 0x110C,0x1174,0x11F9 ],
- [ 0xF1E7, 0x110C,0x1175,0x11FE ],
- [ 0xF1E8, 0x110C,0x1175,0xD7D3 ],
- [ 0xF1E9, 0x110C,0x1175,0x11CD ],
- [ 0xF1EA, 0x110C,0x1175,0x11D9 ],
- [ 0xF1EB, 0x110C,0x1175,0x11DD ],
- [ 0xF1EC, 0x110C,0x1175,0x11E2 ],
- [ 0xF1ED, 0x110C,0x1175,0x11E6 ],
- [ 0xF1EE, 0x110C,0x1175,0xD7F0 ],
- [ 0xF1EF, 0x110C,0x1175,0xD7F1 ],
- [ 0xF1F0, 0x110C,0x1175,0xD7F2 ],
- [ 0xF1F1, 0x110C,0x1175,0x11EB ],
- [ 0xF1F2, 0x110C,0x1175,0x11F0 ],
- [ 0xF1F3, 0x110C,0x1175,0x11F9 ],
- [ 0xF1F6, 0x110C,0x1199,0x11AB ],
- [ 0xF1FA, 0x110C,0x119A,0x11AF ],
- [ 0xF1FD, 0x110C,0x119E,0x11A8 ],
- [ 0xF1FE, 0x110C,0x119E,0x11AB ],
- [ 0xF1FF, 0x110C,0x119E,0x11AE ],
- [ 0xF200, 0x110C,0x119E,0x11AF ],
- [ 0xF201, 0x110C,0x119E,0x11CD ],
- [ 0xF202, 0x110C,0x119E,0x11D0 ],
- [ 0xF203, 0x110C,0x119E,0x11D9 ],
- [ 0xF204, 0x110C,0x119E,0x11B7 ],
- [ 0xF205, 0x110C,0x119E,0x11DA ],
- [ 0xF206, 0x110C,0x119E,0x11DD ],
- [ 0xF207, 0x110C,0x119E,0x11B8 ],
- [ 0xF208, 0x110C,0x119E,0x11E6 ],
- [ 0xF209, 0x110C,0x119E,0x11BA ],
- [ 0xF20A, 0x110C,0x119E,0x11EB ],
- [ 0xF20B, 0x110C,0x119E,0x11BC ],
- [ 0xF20C, 0x110C,0x119E,0x11F0 ],
- [ 0xF20D, 0x110C,0x119E,0x11BD ],
- [ 0xF20E, 0x110C,0x119E,0x11BE ],
- [ 0xF20F, 0x110C,0x119E,0x11C0 ],
- [ 0xF211, 0x110C,0xD7C5,0x11BC ],
- [ 0xF213, 0x110C,0x11A1,0x11A8 ],
- [ 0xF214, 0x110C,0x11A1,0x11AB ],
- [ 0xF215, 0x110C,0x11A1,0x11AE ],
- [ 0xF216, 0x110C,0x11A1,0x11AF ],
- [ 0xF217, 0x110C,0x11A1,0x11B7 ],
- [ 0xF218, 0x110C,0x11A1,0x11B8 ],
- [ 0xF219, 0x110C,0x11A1,0x11BA ],
- [ 0xF21A, 0x110C,0x11A1,0x11BC ],
- [ 0xF21B, 0x110C,0x11A1,0x11F0 ],
- [ 0xF21D, 0x114D,0x1173,0x11AF ],
- [ 0xF21F, 0x114D,0x1175,0x11AF ],
- [ 0xF220, 0x110D,0x1161,0x11D0 ],
- [ 0xF221, 0x110D,0x1161,0x11D9 ],
- [ 0xF222, 0x110D,0x1161,0x11E2 ],
- [ 0xF223, 0x110D,0x1161,0xD7E6 ],
- [ 0xF224, 0x110D,0x1161,0x11F0 ],
- [ 0xF225, 0x110D,0x1161,0x11F9 ],
- [ 0xF226, 0x110D,0x1163,0x11E2 ],
- [ 0xF227, 0x110D,0x1163,0x11E6 ],
- [ 0xF228, 0x110D,0x1163,0x11F0 ],
- [ 0xF229, 0x110D,0x1165,0x11F0 ],
- [ 0xF22A, 0x110D,0x1165,0x11F9 ],
- [ 0xF22B, 0x110D,0x1167,0x11D9 ],
- [ 0xF22C, 0x110D,0x1167,0x11F0 ],
- [ 0xF22D, 0x110D,0x1169,0x11D9 ],
- [ 0xF22E, 0x110D,0x1169,0x11E2 ],
- [ 0xF22F, 0x110D,0x1169,0x11F0 ],
- [ 0xF230, 0x110D,0x1169,0xD7F9 ],
- [ 0xF231, 0x110D,0x1169,0x11F9 ],
- [ 0xF232, 0x110D,0x116A,0x11F0 ],
- [ 0xF234, 0x110D,0x116C,0x11F9 ],
- [ 0xF235, 0x110D,0x116D,0x11E2 ],
- [ 0xF236, 0x110D,0x116D,0x11F0 ],
- [ 0xF237, 0x110D,0x116E,0x11D9 ],
- [ 0xF238, 0x110D,0x116E,0x11E2 ],
- [ 0xF239, 0x110D,0x116E,0x11F0 ],
- [ 0xF23A, 0x110D,0x116E,0x11F9 ],
- [ 0xF23B, 0x110D,0x1171,0x11F9 ],
- [ 0xF23C, 0x110D,0x1172,0x11D9 ],
- [ 0xF23D, 0x110D,0x1172,0x11E2 ],
- [ 0xF23F, 0x110D,0x1191,0x11AB ],
- [ 0xF240, 0x110D,0x1191,0x11AF ],
- [ 0xF241, 0x110D,0x1191,0x11D9 ],
- [ 0xF242, 0x110D,0x1191,0x11F9 ],
- [ 0xF244, 0x110D,0x1194,0x11BC ],
- [ 0xF245, 0x110D,0x1173,0x11E2 ],
- [ 0xF246, 0x110D,0x1173,0x11EB ],
- [ 0xF247, 0x110D,0x1173,0x11F0 ],
- [ 0xF248, 0x110D,0x1173,0xD7F9 ],
- [ 0xF249, 0x110D,0x1174,0x11F0 ],
- [ 0xF24A, 0x110D,0x1174,0x11F9 ],
- [ 0xF24B, 0x110D,0x1175,0x11D9 ],
- [ 0xF24C, 0x110D,0x1175,0x11E2 ],
- [ 0xF24D, 0x110D,0x1175,0x11EB ],
- [ 0xF24E, 0x110D,0x1175,0x11F0 ],
- [ 0xF24F, 0x110D,0x1175,0x11F9 ],
- [ 0xF251, 0x110D,0x119E,0x11A8 ],
- [ 0xF252, 0x110D,0x119E,0x11AB ],
- [ 0xF253, 0x110D,0x119E,0x11AF ],
- [ 0xF254, 0x110D,0x119E,0x11B7 ],
- [ 0xF255, 0x110D,0x119E,0x11B8 ],
- [ 0xF256, 0x110D,0x119E,0x11E6 ],
- [ 0xF257, 0x110D,0x119E,0x11BA ],
- [ 0xF258, 0x110D,0x119E,0x11BC ],
- [ 0xF259, 0x110D,0x119E,0x11F0 ],
- [ 0xF25B, 0x110D,0x11A1,0x11A8 ],
- [ 0xF25C, 0x110D,0x11A1,0x11AB ],
- [ 0xF25D, 0x110D,0x11A1,0x11AF ],
- [ 0xF25E, 0x110D,0x11A1,0x11D9 ],
- [ 0xF25F, 0x110D,0x11A1,0x11B7 ],
- [ 0xF260, 0x110D,0x11A1,0x11BC ],
- [ 0xF261, 0x110D,0x11A1,0x11F0 ],
- [ 0xF262, 0x110D,0x11A1,0x11F9 ],
- [ 0xF265, 0xA978,0x1166,0x11AF ],
- [ 0xF266, 0xA978,0x1166,0x11D0 ],
- [ 0xF267, 0xA978,0x1166,0xD7D7 ],
- [ 0xF269, 0x114E,0x1161,0x11AB ],
- [ 0xF26A, 0x114E,0x1161,0x11B7 ],
- [ 0xF26B, 0x114E,0x1161,0x11E2 ],
- [ 0xF26E, 0x114E,0x1163,0x11BC ],
- [ 0xF270, 0x114E,0x1165,0x11AB ],
- [ 0xF272, 0x114E,0x1167,0x11AB ],
- [ 0xF273, 0x114E,0x1167,0x11F9 ],
- [ 0xF27A, 0x114E,0x116E,0x11AB ],
- [ 0xF27B, 0x114E,0x116E,0x11BC ],
- [ 0xF27E, 0x114E,0x1172,0x11AB ],
- [ 0xF27F, 0x114E,0x1172,0x11BC ],
- [ 0xF281, 0x114E,0x1191,0x11AB ],
- [ 0xF283, 0x114E,0x1173,0x11AB ],
- [ 0xF284, 0x114E,0x1173,0x11BA ],
- [ 0xF285, 0x114E,0x1173,0x11EB ],
- [ 0xF287, 0x114E,0x1175,0x11AB ],
- [ 0xF288, 0x114E,0x1175,0x11B7 ],
- [ 0xF289, 0x114E,0x1175,0x11E2 ],
- [ 0xF28A, 0x114E,0x1175,0x11EB ],
- [ 0xF28C, 0x114F,0x1161,0x11AB ],
- [ 0xF28D, 0x114F,0x1161,0x11B7 ],
- [ 0xF28E, 0x114F,0x1161,0x11E2 ],
- [ 0xF28F, 0x114F,0x1161,0x11F0 ],
- [ 0xF292, 0x114F,0x1163,0x11B7 ],
- [ 0xF293, 0x114F,0x1163,0x11F0 ],
- [ 0xF295, 0x114F,0x1165,0x11AB ],
- [ 0xF297, 0x114F,0x1167,0x11AB ],
- [ 0xF29C, 0x114F,0x1172,0x11F0 ],
- [ 0xF29E, 0x114F,0x1191,0x11AB ],
- [ 0xF2A0, 0x114F,0x1173,0x11EB ],
- [ 0xF2A1, 0x114F,0x1173,0x11F0 ],
- [ 0xF2A3, 0x114F,0x1175,0x11AB ],
- [ 0xF2A7, 0x1150,0x1161,0x11AB ],
- [ 0xF2A8, 0x1150,0x1161,0x11AE ],
- [ 0xF2A9, 0x1150,0x1161,0x11B7 ],
- [ 0xF2AA, 0x1150,0x1161,0x11E2 ],
- [ 0xF2AB, 0x1150,0x1161,0x11B8 ],
- [ 0xF2AE, 0x1150,0x1163,0x11B7 ],
- [ 0xF2AF, 0x1150,0x1163,0x11E2 ],
- [ 0xF2B0, 0x1150,0x1163,0x11F0 ],
- [ 0xF2B2, 0x1150,0x1167,0x11AB ],
- [ 0xF2B5, 0x1150,0x116A,0x11BC ],
- [ 0xF2B7, 0x1150,0x116E,0x11BC ],
- [ 0xF2B8, 0x1150,0x116E,0x11F9 ],
- [ 0xF2BA, 0x1150,0x1172,0x11A8 ],
- [ 0xF2BB, 0x1150,0x1172,0x11AB ],
- [ 0xF2BC, 0x1150,0x1172,0x11F0 ],
- [ 0xF2BE, 0x1150,0x1191,0x11AB ],
- [ 0xF2C0, 0x1150,0x1173,0x11B7 ],
- [ 0xF2C1, 0x1150,0x1173,0x11EB ],
- [ 0xF2C3, 0x1150,0x1175,0x11AB ],
- [ 0xF2C4, 0x1150,0x1175,0x11EB ],
- [ 0xF2C5, 0x1150,0x1175,0x11F0 ],
- [ 0xF2C7, 0x1151,0x1161,0x11AB ],
- [ 0xF2C8, 0x1151,0x1161,0x11C2 ],
- [ 0xF2CB, 0x1151,0x1163,0x11B7 ],
- [ 0xF2CC, 0x1151,0x1163,0x11E2 ],
- [ 0xF2CD, 0x1151,0x1163,0x11B8 ],
- [ 0xF2CE, 0x1151,0x1163,0x11F0 ],
- [ 0xF2D0, 0x1151,0x1167,0x11AB ],
- [ 0xF2D4, 0x1151,0x1172,0x11F0 ],
- [ 0xF2D6, 0x1151,0x1191,0x11AB ],
- [ 0xF2D8, 0x1151,0x1173,0x11B7 ],
- [ 0xF2D9, 0x1151,0x1173,0x11E2 ],
- [ 0xF2DB, 0x1151,0x1175,0x11AB ],
- [ 0xF2DC, 0x1151,0x1175,0x11B7 ],
- [ 0xF2DD, 0x1151,0x1175,0x11EB ],
- [ 0xF2DE, 0x1151,0x1175,0x11F0 ],
- [ 0xF2DF, 0x110E,0x1161,0x11D9 ],
- [ 0xF2E0, 0x110E,0x1161,0x11E2 ],
- [ 0xF2E1, 0x110E,0x1161,0x11E6 ],
- [ 0xF2E2, 0x110E,0x1161,0x11F0 ],
- [ 0xF2E3, 0x110E,0x1161,0x11F9 ],
- [ 0xF2E5, 0x110E,0x1163,0x11D9 ],
- [ 0xF2E6, 0x110E,0x1163,0x11E6 ],
- [ 0xF2E7, 0x110E,0x1163,0x11F0 ],
- [ 0xF2E8, 0x110E,0x1163,0x11F1 ],
- [ 0xF2EA, 0x110E,0x1178,0x11AF ],
- [ 0xF2EC, 0x110E,0x1165,0x11EB ],
- [ 0xF2ED, 0x110E,0x1165,0x11F0 ],
- [ 0xF2EF, 0x110E,0x117C,0x11AB ],
- [ 0xF2F0, 0x110E,0x1167,0xD7CD ],
- [ 0xF2F1, 0x110E,0x1167,0xD7CE ],
- [ 0xF2F2, 0x110E,0x1167,0xD7CF ],
- [ 0xF2F3, 0x110E,0x1167,0x11D9 ],
- [ 0xF2F4, 0x110E,0x1167,0x11E2 ],
- [ 0xF2F5, 0x110E,0x1167,0x11F0 ],
- [ 0xF2F6, 0x110E,0x1167,0x11F1 ],
- [ 0xF2F7, 0x110E,0x1167,0x11F9 ],
- [ 0xF2FA, 0x110E,0x1169,0x11D9 ],
- [ 0xF2FB, 0x110E,0x1169,0x11E2 ],
- [ 0xF2FC, 0x110E,0x1169,0xD7E8 ],
- [ 0xF2FD, 0x110E,0x1169,0x11EB ],
- [ 0xF2FE, 0x110E,0x1169,0x11F0 ],
- [ 0xF2FF, 0x110E,0x116A,0x11D9 ],
- [ 0xF300, 0x110E,0x116A,0x11F0 ],
- [ 0xF302, 0x110E,0x116D,0x11E2 ],
- [ 0xF303, 0x110E,0x116D,0x11F0 ],
- [ 0xF306, 0x110E,0x1188,0x11AB ],
- [ 0xF307, 0x110E,0x116E,0x11D9 ],
- [ 0xF308, 0x110E,0x116E,0x11E0 ],
- [ 0xF309, 0x110E,0x116E,0x11E2 ],
- [ 0xF30A, 0x110E,0x116E,0x11F0 ],
- [ 0xF30B, 0x110E,0x116E,0x11F9 ],
- [ 0xF30D, 0x110E,0x1189,0x11AB ],
- [ 0xF30E, 0x110E,0x1189,0x11BC ],
- [ 0xF310, 0x110E,0x116F,0x11F9 ],
- [ 0xF313, 0x110E,0x1171,0x11D9 ],
- [ 0xF314, 0x110E,0x1171,0x11F9 ],
- [ 0xF315, 0x110E,0x1172,0x11D9 ],
- [ 0xF316, 0x110E,0x1172,0x11E2 ],
- [ 0xF317, 0x110E,0x1172,0x11F0 ],
- [ 0xF318, 0x110E,0x1172,0x11F9 ],
- [ 0xF31A, 0x110E,0x118E,0x11AB ],
- [ 0xF31C, 0x110E,0x118F,0x11B7 ],
- [ 0xF31F, 0x110E,0x1191,0x11AB ],
- [ 0xF320, 0x110E,0x1191,0x11AF ],
- [ 0xF321, 0x110E,0x1191,0x11D9 ],
- [ 0xF322, 0x110E,0x1191,0x11B7 ],
- [ 0xF324, 0x110E,0x1192,0x11BC ],
- [ 0xF326, 0x110E,0x1194,0x11AB ],
- [ 0xF327, 0x110E,0x1194,0x11AF ],
- [ 0xF328, 0x110E,0x1194,0x11BC ],
- [ 0xF329, 0x110E,0x1173,0xD7DB ],
- [ 0xF32A, 0x110E,0x1173,0x11D9 ],
- [ 0xF32B, 0x110E,0x1173,0xD7DD ],
- [ 0xF32C, 0x110E,0x1173,0x11E2 ],
- [ 0xF32D, 0x110E,0x1173,0x11EB ],
- [ 0xF32E, 0x110E,0x1173,0x11F0 ],
- [ 0xF331, 0x110E,0x1174,0x11F9 ],
- [ 0xF332, 0x110E,0x1175,0x11D9 ],
- [ 0xF333, 0x110E,0x1175,0x11E2 ],
- [ 0xF334, 0x110E,0x1175,0xD7E3 ],
- [ 0xF335, 0x110E,0x1175,0x11E6 ],
- [ 0xF336, 0x110E,0x1175,0x11EB ],
- [ 0xF337, 0x110E,0x1175,0x11F0 ],
- [ 0xF338, 0x110E,0x1175,0x11F9 ],
- [ 0xF33B, 0x110E,0x1199,0x11AB ],
- [ 0xF33C, 0x110E,0x1199,0x11BC ],
- [ 0xF342, 0x110E,0x119E,0x11A8 ],
- [ 0xF343, 0x110E,0x119E,0x11AB ],
- [ 0xF344, 0x110E,0x119E,0x11AE ],
- [ 0xF345, 0x110E,0x119E,0x11AF ],
- [ 0xF346, 0x110E,0x119E,0x11CE ],
- [ 0xF347, 0x110E,0x119E,0x11B1 ],
- [ 0xF348, 0x110E,0x119E,0x11B3 ],
- [ 0xF349, 0x110E,0x119E,0x11B6 ],
- [ 0xF34A, 0x110E,0x119E,0x11D9 ],
- [ 0xF34B, 0x110E,0x119E,0x11B7 ],
- [ 0xF34C, 0x110E,0x119E,0x11DD ],
- [ 0xF34D, 0x110E,0x119E,0x11B8 ],
- [ 0xF34E, 0x110E,0x119E,0x11BA ],
- [ 0xF34F, 0x110E,0x119E,0x11BB ],
- [ 0xF350, 0x110E,0x119E,0x11BC ],
- [ 0xF351, 0x110E,0x119E,0x11BD ],
- [ 0xF352, 0x110E,0x119E,0x11BE ],
- [ 0xF354, 0x110E,0x11A1,0x11A8 ],
- [ 0xF355, 0x110E,0x11A1,0x11AB ],
- [ 0xF356, 0x110E,0x11A1,0x11AF ],
- [ 0xF357, 0x110E,0x11A1,0x11B7 ],
- [ 0xF358, 0x110E,0x11A1,0x11BA ],
- [ 0xF359, 0x110E,0x11A1,0x11BC ],
- [ 0xF35A, 0x110E,0x11A1,0x11F0 ],
- [ 0xF35E, 0x1153,0x1175,0x11AF ],
- [ 0xF360, 0x1154,0x1161,0x11AB ],
- [ 0xF364, 0x1154,0x1165,0x11AB ],
- [ 0xF366, 0x1154,0x1167,0x11AB ],
- [ 0xF36D, 0x1154,0x116E,0x11AB ],
- [ 0xF36E, 0x1154,0x116E,0x11BC ],
- [ 0xF371, 0x1154,0x1172,0x11AB ],
- [ 0xF373, 0x1154,0x1191,0x11AB ],
- [ 0xF376, 0x1154,0x1175,0x11AB ],
- [ 0xF377, 0x1154,0x1175,0x11EB ],
- [ 0xF378, 0x1154,0x1175,0x11F0 ],
- [ 0xF379, 0x1154,0x1175,0x11F9 ],
- [ 0xF37B, 0x1155,0x1161,0x11AB ],
- [ 0xF37C, 0x1155,0x1161,0x11B7 ],
- [ 0xF37D, 0x1155,0x1161,0x11E2 ],
- [ 0xF37E, 0x1155,0x1161,0x11F9 ],
- [ 0xF381, 0x1155,0x1163,0x11F0 ],
- [ 0xF383, 0x1155,0x1167,0x11AB ],
- [ 0xF386, 0x1155,0x116A,0x11AB ],
- [ 0xF38B, 0x1155,0x1172,0x11A8 ],
- [ 0xF38C, 0x1155,0x1172,0x11AB ],
- [ 0xF38D, 0x1155,0x1172,0x11BC ],
- [ 0xF38E, 0x1155,0x1172,0x11F0 ],
- [ 0xF390, 0x1155,0x1191,0x11AB ],
- [ 0xF392, 0x1155,0x1173,0x11AB ],
- [ 0xF393, 0x1155,0x1173,0x11EB ],
- [ 0xF395, 0x1155,0x1175,0x11AB ],
- [ 0xF396, 0x1155,0x1175,0x11B7 ],
- [ 0xF397, 0x1155,0x1175,0x11E2 ],
- [ 0xF398, 0x1155,0x1175,0x11EB ],
- [ 0xF399, 0x1155,0x1175,0x11F9 ],
- [ 0xF39B, 0x110F,0x1161,0x11D0 ],
- [ 0xF39C, 0x110F,0x1161,0x11D9 ],
- [ 0xF39D, 0x110F,0x1161,0x11E2 ],
- [ 0xF39E, 0x110F,0x1161,0x11E6 ],
- [ 0xF39F, 0x110F,0x1161,0x11F0 ],
- [ 0xF3A1, 0x110F,0x1163,0x11E2 ],
- [ 0xF3A2, 0x110F,0x1163,0x11F0 ],
- [ 0xF3A3, 0x110F,0x1163,0x11F9 ],
- [ 0xF3A5, 0x110F,0x1165,0x11D9 ],
- [ 0xF3A6, 0x110F,0x1165,0x11F9 ],
- [ 0xF3A9, 0x110F,0x1167,0x11D9 ],
- [ 0xF3AA, 0x110F,0x1167,0x11E2 ],
- [ 0xF3AB, 0x110F,0x1167,0x11F0 ],
- [ 0xF3AC, 0x110F,0x1167,0x11F9 ],
- [ 0xF3AE, 0x110F,0x1169,0x11D9 ],
- [ 0xF3AF, 0x110F,0x1169,0x11E2 ],
- [ 0xF3B0, 0x110F,0x1169,0x11F0 ],
- [ 0xF3B1, 0x110F,0x116A,0x11D9 ],
- [ 0xF3B2, 0x110F,0x116A,0x11F0 ],
- [ 0xF3B4, 0x110F,0x116C,0x11F0 ],
- [ 0xF3B5, 0x110F,0x116D,0x11D9 ],
- [ 0xF3B6, 0x110F,0x116D,0x11E2 ],
- [ 0xF3B8, 0x110F,0x116E,0x11D9 ],
- [ 0xF3B9, 0x110F,0x116E,0x11E2 ],
- [ 0xF3BA, 0x110F,0x116E,0x11F0 ],
- [ 0xF3BB, 0x110F,0x116E,0x11F9 ],
- [ 0xF3BD, 0x110F,0x1189,0x11AB ],
- [ 0xF3BE, 0x110F,0x1189,0x11BC ],
- [ 0xF3C0, 0x110F,0x116F,0x11D9 ],
- [ 0xF3C1, 0x110F,0x116F,0x11F9 ],
- [ 0xF3C3, 0x110F,0xD7B5,0x11AB ],
- [ 0xF3C5, 0x110F,0x1172,0x11F0 ],
- [ 0xF3C6, 0x110F,0x1172,0x11F9 ],
- [ 0xF3CA, 0x110F,0x1191,0x11A8 ],
- [ 0xF3CB, 0x110F,0x1191,0x11AB ],
- [ 0xF3CC, 0x110F,0x1191,0x11AF ],
- [ 0xF3CD, 0x110F,0x1191,0x11D9 ],
- [ 0xF3CE, 0x110F,0x1191,0x11F0 ],
- [ 0xF3CF, 0x110F,0x1191,0x11F9 ],
- [ 0xF3D1, 0x110F,0x1192,0x11BC ],
- [ 0xF3D3, 0x110F,0x1194,0x11BC ],
- [ 0xF3D4, 0x110F,0x1173,0x11D9 ],
- [ 0xF3D5, 0x110F,0x1173,0x11E2 ],
- [ 0xF3D6, 0x110F,0x1173,0x11F0 ],
- [ 0xF3D9, 0x110F,0x1174,0x11F9 ],
- [ 0xF3DA, 0x110F,0x1175,0x11D9 ],
- [ 0xF3DB, 0x110F,0x1175,0x11F0 ],
- [ 0xF3DC, 0x110F,0x1175,0x11F9 ],
- [ 0xF3DF, 0x110F,0x1199,0x11AB ],
- [ 0xF3E0, 0x110F,0x1199,0x11BC ],
- [ 0xF3E7, 0x110F,0x119B,0x11AF ],
- [ 0xF3E9, 0x110F,0xD7C3,0x11AB ],
- [ 0xF3EB, 0x110F,0x119E,0x11A8 ],
- [ 0xF3EC, 0x110F,0x119E,0x11AB ],
- [ 0xF3ED, 0x110F,0x119E,0x11AE ],
- [ 0xF3EE, 0x110F,0x119E,0x11AF ],
- [ 0xF3EF, 0x110F,0x119E,0x11B7 ],
- [ 0xF3F0, 0x110F,0x119E,0x11B8 ],
- [ 0xF3F1, 0x110F,0x119E,0x11BA ],
- [ 0xF3F2, 0x110F,0x119E,0x11C0 ],
- [ 0xF3F4, 0x110F,0x11A1,0x11A8 ],
- [ 0xF3F5, 0x110F,0x11A1,0x11AB ],
- [ 0xF3F6, 0x110F,0x11A1,0x11AF ],
- [ 0xF3F7, 0x110F,0x11A1,0x11B7 ],
- [ 0xF3F8, 0x110F,0x11A1,0x11BA ],
- [ 0xF3F9, 0x110F,0x11A1,0x11BC ],
- [ 0xF3FA, 0x110F,0x11A1,0x11F0 ],
- [ 0xF3FB, 0x1110,0x1161,0x11D9 ],
- [ 0xF3FC, 0x1110,0x1161,0x11E2 ],
- [ 0xF3FD, 0x1110,0x1161,0x11F0 ],
- [ 0xF3FE, 0x1110,0x1161,0x11F9 ],
- [ 0xF401, 0x1110,0x1163,0x11E2 ],
- [ 0xF402, 0x1110,0x1163,0x11F0 ],
- [ 0xF404, 0x1110,0x1165,0x11DD ],
- [ 0xF405, 0x1110,0x1165,0x11E6 ],
- [ 0xF406, 0x1110,0x1165,0x11F0 ],
- [ 0xF407, 0x1110,0x1165,0x11F1 ],
- [ 0xF409, 0x1110,0x117B,0x11AE ],
- [ 0xF40A, 0x1110,0x117B,0x11AF ],
- [ 0xF40B, 0x1110,0x1167,0x11D9 ],
- [ 0xF40C, 0x1110,0x1167,0x11F0 ],
- [ 0xF40D, 0x1110,0x1167,0x11F9 ],
- [ 0xF40E, 0x1110,0x1168,0x11F0 ],
- [ 0xF40F, 0x1110,0x1169,0x11D0 ],
- [ 0xF410, 0x1110,0x1169,0x11D9 ],
- [ 0xF411, 0x1110,0x1169,0x11E2 ],
- [ 0xF412, 0x1110,0x1169,0xD7E5 ],
- [ 0xF413, 0x1110,0x1169,0x11E7 ],
- [ 0xF414, 0x1110,0x1169,0x11F0 ],
- [ 0xF415, 0x1110,0x116A,0x11D9 ],
- [ 0xF416, 0x1110,0x116A,0x11F0 ],
- [ 0xF418, 0x1110,0x1182,0x11AF ],
- [ 0xF419, 0x1110,0x116D,0x11D9 ],
- [ 0xF41A, 0x1110,0x116D,0x11E2 ],
- [ 0xF41B, 0x1110,0x116D,0x11F0 ],
- [ 0xF41D, 0x1110,0x116E,0x11D0 ],
- [ 0xF41E, 0x1110,0x116E,0x11D9 ],
- [ 0xF41F, 0x1110,0x116E,0x11E2 ],
- [ 0xF420, 0x1110,0x116E,0x11F0 ],
- [ 0xF421, 0x1110,0x116E,0x11F9 ],
- [ 0xF423, 0x1110,0x1189,0x11AB ],
- [ 0xF424, 0x1110,0x116F,0x11F9 ],
- [ 0xF428, 0x1110,0x1172,0x11D9 ],
- [ 0xF429, 0x1110,0x1172,0x11E2 ],
- [ 0xF42A, 0x1110,0x1172,0x11F0 ],
- [ 0xF42C, 0x1110,0x1173,0x11D0 ],
- [ 0xF42D, 0x1110,0x1173,0x11D7 ],
- [ 0xF42E, 0x1110,0x1173,0x11D9 ],
- [ 0xF42F, 0x1110,0x1173,0x11E2 ],
- [ 0xF430, 0x1110,0x1173,0x11F0 ],
- [ 0xF433, 0x1110,0x1174,0x11F9 ],
- [ 0xF434, 0x1110,0x1175,0x11D9 ],
- [ 0xF435, 0x1110,0x1175,0x11E6 ],
- [ 0xF436, 0x1110,0x1175,0x11F0 ],
- [ 0xF439, 0x1110,0x1199,0x11AB ],
- [ 0xF43D, 0x1110,0x119E,0x11A8 ],
- [ 0xF43E, 0x1110,0x119E,0x11AB ],
- [ 0xF43F, 0x1110,0x119E,0x11AE ],
- [ 0xF440, 0x1110,0x119E,0x11AF ],
- [ 0xF441, 0x1110,0x119E,0x11B0 ],
- [ 0xF442, 0x1110,0x119E,0x11B3 ],
- [ 0xF443, 0x1110,0x119E,0x11B7 ],
- [ 0xF444, 0x1110,0x119E,0x11B8 ],
- [ 0xF445, 0x1110,0x119E,0x11BA ],
- [ 0xF446, 0x1110,0x119E,0x11BC ],
- [ 0xF447, 0x1110,0x119E,0x11BD ],
- [ 0xF449, 0x1110,0x11A1,0x11A8 ],
- [ 0xF44A, 0x1110,0x11A1,0x11AB ],
- [ 0xF44B, 0x1110,0x11A1,0x11AF ],
- [ 0xF44C, 0x1110,0x11A1,0x11B7 ],
- [ 0xF44D, 0x1110,0x11A1,0x11BA ],
- [ 0xF44E, 0x1110,0x11A1,0x11BC ],
- [ 0xF44F, 0x1110,0x11A1,0x11F0 ],
- [ 0xF450, 0x1110,0x11A1,0x11F9 ],
- [ 0xF453, 0xA979,0x119E,0x11AF ],
- [ 0xF454, 0x1111,0x1161,0x11D0 ],
- [ 0xF455, 0x1111,0x1161,0x11D8 ],
- [ 0xF456, 0x1111,0x1161,0x11D9 ],
- [ 0xF457, 0x1111,0x1161,0x11E2 ],
- [ 0xF458, 0x1111,0x1161,0x11E6 ],
- [ 0xF459, 0x1111,0x1161,0x11E7 ],
- [ 0xF45A, 0x1111,0x1161,0x11F0 ],
- [ 0xF45B, 0x1111,0x1161,0x11F9 ],
- [ 0xF45D, 0x1111,0x1162,0x11F9 ],
- [ 0xF45E, 0x1111,0x1163,0x11E2 ],
- [ 0xF460, 0x1111,0x1165,0x11D0 ],
- [ 0xF461, 0x1111,0x1165,0x11F0 ],
- [ 0xF464, 0x1111,0x117C,0x11AF ],
- [ 0xF465, 0x1111,0x1166,0x11C7 ],
- [ 0xF466, 0x1111,0x1167,0x11C7 ],
- [ 0xF467, 0x1111,0x1167,0x11D9 ],
- [ 0xF468, 0x1111,0x1167,0x11E2 ],
- [ 0xF469, 0x1111,0x1167,0x11F0 ],
- [ 0xF46A, 0x1111,0x1167,0x11F9 ],
- [ 0xF46B, 0x1111,0x1169,0x11D9 ],
- [ 0xF46C, 0x1111,0x1169,0x11E2 ],
- [ 0xF46D, 0x1111,0x1169,0x11F0 ],
- [ 0xF46F, 0x1111,0x116D,0x11E2 ],
- [ 0xF470, 0x1111,0x116D,0x11E6 ],
- [ 0xF472, 0x1111,0x116E,0x11D0 ],
- [ 0xF473, 0x1111,0x116E,0x11D9 ],
- [ 0xF474, 0x1111,0x116E,0x11E2 ],
- [ 0xF475, 0x1111,0x116E,0x11F0 ],
- [ 0xF476, 0x1111,0x116E,0x11F1 ],
- [ 0xF477, 0x1111,0x116F,0x11F9 ],
- [ 0xF47A, 0x1111,0x1171,0x11F9 ],
- [ 0xF47B, 0x1111,0x1172,0x11E2 ],
- [ 0xF47C, 0x1111,0x1172,0x11F0 ],
- [ 0xF47E, 0x1111,0x118E,0x11AB ],
- [ 0xF480, 0x1111,0x1173,0x11D9 ],
- [ 0xF481, 0x1111,0x1173,0x11F0 ],
- [ 0xF483, 0x1111,0x1174,0x11F0 ],
- [ 0xF484, 0x1111,0x1174,0x11F9 ],
- [ 0xF485, 0x1111,0x1175,0x11D9 ],
- [ 0xF486, 0x1111,0x1175,0x11F0 ],
- [ 0xF487, 0x1111,0x1175,0x11F9 ],
- [ 0xF48A, 0x1111,0x1199,0x11AB ],
- [ 0xF48F, 0x1111,0x119E,0x11A8 ],
- [ 0xF490, 0x1111,0x119E,0x11AB ],
- [ 0xF491, 0x1111,0x119E,0x11AE ],
- [ 0xF492, 0x1111,0x119E,0x11AF ],
- [ 0xF493, 0x1111,0x119E,0x11B0 ],
- [ 0xF494, 0x1111,0x119E,0x11B3 ],
- [ 0xF495, 0x1111,0x119E,0x11B6 ],
- [ 0xF496, 0x1111,0x119E,0x11B7 ],
- [ 0xF497, 0x1111,0x119E,0x11B8 ],
- [ 0xF498, 0x1111,0x119E,0x11BA ],
- [ 0xF499, 0x1111,0x119E,0x11E7 ],
- [ 0xF49A, 0x1111,0x119E,0x11BC ],
- [ 0xF49B, 0x1111,0x119E,0x11BD ],
- [ 0xF49C, 0x1111,0x119E,0x11BE ],
- [ 0xF49D, 0x1111,0x119E,0x11C0 ],
- [ 0xF49F, 0x1111,0x119F,0x11AB ],
- [ 0xF4A1, 0x1111,0x11A1,0x11A8 ],
- [ 0xF4A2, 0x1111,0x11A1,0x11AB ],
- [ 0xF4A3, 0x1111,0x11A1,0x11AF ],
- [ 0xF4A4, 0x1111,0x11A1,0x11B7 ],
- [ 0xF4A5, 0x1111,0x11A1,0x11B8 ],
- [ 0xF4A6, 0x1111,0x11A1,0x11BA ],
- [ 0xF4A7, 0x1111,0x11A1,0x11BC ],
- [ 0xF4A8, 0x1111,0x11A1,0x11F0 ],
- [ 0xF4AA, 0x1156,0x1161,0x11AB ],
- [ 0xF4AC, 0xA97A,0x1175,0x11AB ],
- [ 0xF4AE, 0x1157,0x116E,0x11AB ],
- [ 0xF4AF, 0x1112,0x1161,0x11CE ],
- [ 0xF4B0, 0x1112,0x1161,0x11CF ],
- [ 0xF4B1, 0x1112,0x1161,0x11D0 ],
- [ 0xF4B2, 0x1112,0x1161,0xD7D8 ],
- [ 0xF4B3, 0x1112,0x1161,0x11D9 ],
- [ 0xF4B4, 0x1112,0x1161,0xD7E2 ],
- [ 0xF4B5, 0x1112,0x1161,0x11E2 ],
- [ 0xF4B6, 0x1112,0x1161,0x11F0 ],
- [ 0xF4B7, 0x1112,0x1161,0x11F1 ],
- [ 0xF4BA, 0x1112,0x1162,0x11EB ],
- [ 0xF4BB, 0x1112,0x1162,0x11F0 ],
- [ 0xF4BC, 0x1112,0x1162,0xD7F6 ],
- [ 0xF4BD, 0x1112,0x1163,0x11C7 ],
- [ 0xF4BE, 0x1112,0x1163,0x11E2 ],
- [ 0xF4BF, 0x1112,0x1163,0x11F0 ],
- [ 0xF4C0, 0x1112,0x1163,0x11F9 ],
- [ 0xF4C2, 0x1112,0x1164,0x11F0 ],
- [ 0xF4C3, 0x1112,0x1165,0x11D0 ],
- [ 0xF4C4, 0x1112,0x1165,0x11D9 ],
- [ 0xF4C5, 0x1112,0x1165,0x11F0 ],
- [ 0xF4C6, 0x1112,0x1165,0x11F1 ],
- [ 0xF4C7, 0x1112,0x117C,0x11F9 ],
- [ 0xF4C7, 0x1112,0x1165,0x11F9 ],
- [ 0xF4CB, 0x1112,0x117C,0x11AB ],
- [ 0xF4CC, 0x1112,0x117C,0x11B7 ],
- [ 0xF4CD, 0x1112,0x1167,0x11D9 ],
- [ 0xF4CE, 0x1112,0x1167,0x11E2 ],
- [ 0xF4CF, 0x1112,0x1167,0x11F0 ],
- [ 0xF4D0, 0x1112,0x1167,0x11F9 ],
- [ 0xF4D1, 0x1112,0x1168,0x11D9 ],
- [ 0xF4D2, 0x1112,0x1169,0x11C7 ],
- [ 0xF4D3, 0x1112,0x1169,0x11CD ],
- [ 0xF4D4, 0x1112,0x1169,0x11D9 ],
- [ 0xF4D5, 0x1112,0x1169,0x11DA ],
- [ 0xF4D6, 0x1112,0x1169,0x11DD ],
- [ 0xF4D7, 0x1112,0x1169,0x11E2 ],
- [ 0xF4D8, 0x1112,0x1169,0x11EB ],
- [ 0xF4D9, 0x1112,0x1169,0x11F0 ],
- [ 0xF4DA, 0x1112,0x1169,0x11F1 ],
- [ 0xF4DB, 0x1112,0x116A,0x11D9 ],
- [ 0xF4DC, 0x1112,0x116A,0x11F0 ],
- [ 0xF4DD, 0x1112,0x116A,0x11F1 ],
- [ 0xF4DE, 0x1112,0x116B,0x11F9 ],
- [ 0xF4E1, 0x1112,0x117F,0x11AB ],
- [ 0xF4E2, 0x1112,0x117F,0x11F9 ],
- [ 0xF4E5, 0x1112,0x116C,0x11F0 ],
- [ 0xF4E6, 0x1112,0x116C,0x11F9 ],
- [ 0xF4E7, 0x1112,0x116D,0x11D9 ],
- [ 0xF4E8, 0x1112,0x116D,0x11E2 ],
- [ 0xF4EA, 0x1112,0xD7B2,0x11AB ],
- [ 0xF4EC, 0x1112,0x1184,0x11BC ],
- [ 0xF4EF, 0x1112,0x1188,0x11AB ],
- [ 0xF4F0, 0x1112,0x116E,0x11D9 ],
- [ 0xF4F1, 0x1112,0x116E,0x11DD ],
- [ 0xF4F2, 0x1112,0x116E,0x11E2 ],
- [ 0xF4F3, 0x1112,0x116E,0x11EB ],
- [ 0xF4F4, 0x1112,0x116E,0x11F0 ],
- [ 0xF4F5, 0x1112,0x116E,0x11F9 ],
- [ 0xF4F7, 0x1112,0x1189,0x11AB ],
- [ 0xF4F8, 0x1112,0x1189,0x11BC ],
- [ 0xF4FA, 0x1112,0x116F,0x11D9 ],
- [ 0xF4FB, 0x1112,0x116F,0x11F0 ],
- [ 0xF4FC, 0x1112,0x116F,0x11F9 ],
- [ 0xF4FE, 0x1112,0x118B,0x11AB ],
- [ 0xF4FF, 0x1112,0x118B,0x11AF ],
- [ 0xF502, 0x1112,0x1171,0x11F0 ],
- [ 0xF503, 0x1112,0x1171,0x11F9 ],
- [ 0xF504, 0x1112,0x1172,0x11D9 ],
- [ 0xF505, 0x1112,0x1172,0x11E2 ],
- [ 0xF506, 0x1112,0x1172,0x11F0 ],
- [ 0xF508, 0x1112,0x118E,0x11AB ],
- [ 0xF50A, 0x1112,0x1191,0x11A8 ],
- [ 0xF50B, 0x1112,0x1191,0x11AB ],
- [ 0xF50C, 0x1112,0x1191,0x11AF ],
- [ 0xF50D, 0x1112,0x1191,0x11D9 ],
- [ 0xF50E, 0x1112,0x1191,0x11BC ],
- [ 0xF50F, 0x1112,0x1191,0x11F0 ],
- [ 0xF510, 0x1112,0x1191,0x11F9 ],
- [ 0xF512, 0x1112,0x1192,0x11AF ],
- [ 0xF513, 0x1112,0x1192,0x11BC ],
- [ 0xF515, 0x1112,0x1194,0x11BC ],
- [ 0xF516, 0x1112,0x1173,0x11C3 ],
- [ 0xF517, 0x1112,0x1173,0xD7D4 ],
- [ 0xF518, 0x1112,0x1173,0x11D0 ],
- [ 0xF519, 0x1112,0x1173,0x11D9 ],
- [ 0xF51A, 0x1112,0x1173,0x11E2 ],
- [ 0xF51B, 0x1112,0x1173,0x11F0 ],
- [ 0xF520, 0x1112,0x1174,0x11EB ],
- [ 0xF521, 0x1112,0x1174,0x11F0 ],
- [ 0xF522, 0x1112,0x1174,0x11F9 ],
- [ 0xF523, 0x1112,0x1175,0x11FF ],
- [ 0xF524, 0x1112,0x1175,0x11D9 ],
- [ 0xF525, 0x1112,0x1175,0x11DC ],
- [ 0xF526, 0x1112,0x1175,0xD7E1 ],
- [ 0xF527, 0x1112,0x1175,0x11DD ],
- [ 0xF528, 0x1112,0x1175,0x11DE ],
- [ 0xF529, 0x1112,0x1175,0x11E2 ],
- [ 0xF52A, 0x1112,0x1175,0x11EE ],
- [ 0xF52B, 0x1112,0x1175,0x11F0 ],
- [ 0xF52C, 0x1112,0x1175,0x11F1 ],
- [ 0xF52F, 0x1112,0x1199,0x11AB ],
- [ 0xF530, 0x1112,0x1199,0x11BC ],
- [ 0xF536, 0x1112,0xD7C3,0x11AB ],
- [ 0xF538, 0x1112,0x119E,0x11A8 ],
- [ 0xF539, 0x1112,0x119E,0x11C3 ],
- [ 0xF53A, 0x1112,0x119E,0x11AB ],
- [ 0xF53B, 0x1112,0x119E,0x11AE ],
- [ 0xF53C, 0x1112,0x119E,0x11AF ],
- [ 0xF53D, 0x1112,0x119E,0x11B0 ],
- [ 0xF53E, 0x1112,0x119E,0x11CD ],
- [ 0xF53F, 0x1112,0x119E,0x11CE ],
- [ 0xF540, 0x1112,0x119E,0x11D0 ],
- [ 0xF541, 0x1112,0x119E,0x11B1 ],
- [ 0xF542, 0x1112,0x119E,0x11B3 ],
- [ 0xF543, 0x1112,0x119E,0x11B6 ],
- [ 0xF544, 0x1112,0x119E,0x11D9 ],
- [ 0xF545, 0x1112,0x119E,0x11B7 ],
- [ 0xF546, 0x1112,0x119E,0x11B8 ],
- [ 0xF547, 0x1112,0x119E,0x11E6 ],
- [ 0xF548, 0x1112,0x119E,0x11BA ],
- [ 0xF549, 0x1112,0x119E,0x11BC ],
- [ 0xF54A, 0x1112,0x119E,0x11F0 ],
- [ 0xF54B, 0x1112,0x119E,0x11C0 ],
- [ 0xF54C, 0x1112,0x119E,0x11C2 ],
- [ 0xF54D, 0x1112,0x119E,0x11F9 ],
- [ 0xF54F, 0x1112,0x119F,0x11AB ],
- [ 0xF551, 0x1112,0x11A1,0x11A8 ],
- [ 0xF552, 0x1112,0x11A1,0x11AB ],
- [ 0xF553, 0x1112,0x11A1,0x11AE ],
- [ 0xF554, 0x1112,0x11A1,0x11AF ],
- [ 0xF555, 0x1112,0x11A1,0x11B0 ],
- [ 0xF556, 0x1112,0x11A1,0x11D9 ],
- [ 0xF557, 0x1112,0x11A1,0x11B7 ],
- [ 0xF558, 0x1112,0x11A1,0x11B8 ],
- [ 0xF559, 0x1112,0x11A1,0xD7E8 ],
- [ 0xF55A, 0x1112,0x11A1,0x11BA ],
- [ 0xF55B, 0x1112,0x11A1,0x11BC ],
- [ 0xF55C, 0x1112,0x11A1,0x11F0 ],
- [ 0xF55E, 0xA97B,0x1163,0x11BC ],
- [ 0xF561, 0xA97B,0x116A,0x11AB ],
- [ 0xF567, 0xA97B,0x1172,0x11BC ],
- [ 0xF569, 0xA97B,0x118E,0x11AB ],
- [ 0xF56D, 0xA97B,0x1194,0x11AB ],
- [ 0xF56F, 0xA97B,0x1175,0x11AB ],
- [ 0xF570, 0xA97B,0x1175,0x11BC ],
- [ 0xF572, 0x1158,0x1161,0x11A8 ],
- [ 0xF573, 0x1158,0x1161,0x11AB ],
- [ 0xF574, 0x1158,0x1161,0x11AF ],
- [ 0xF575, 0x1158,0x1161,0x11D9 ],
- [ 0xF576, 0x1158,0x1161,0x11B7 ],
- [ 0xF577, 0x1158,0x1161,0x11E2 ],
- [ 0xF578, 0x1158,0x1161,0x11B8 ],
- [ 0xF579, 0x1158,0x1161,0x11E6 ],
- [ 0xF57A, 0x1158,0x1161,0x11BC ],
- [ 0xF57B, 0x1158,0x1161,0x11F0 ],
- [ 0xF57D, 0x1158,0x1162,0x11BC ],
- [ 0xF57E, 0x1158,0x1162,0x11F0 ],
- [ 0xF580, 0x1158,0x1163,0x11AB ],
- [ 0xF581, 0x1158,0x1163,0x11B7 ],
- [ 0xF582, 0x1158,0x1163,0x11E2 ],
- [ 0xF583, 0x1158,0x1163,0x11B8 ],
- [ 0xF584, 0x1158,0x1163,0x11E6 ],
- [ 0xF585, 0x1158,0x1163,0x11F0 ],
- [ 0xF586, 0x1158,0x1163,0x11F9 ],
- [ 0xF589, 0x1158,0x1165,0x11AB ],
- [ 0xF58A, 0x1158,0x1165,0x11AF ],
- [ 0xF58B, 0x1158,0x1165,0x11B7 ],
- [ 0xF58C, 0x1158,0x1165,0x11E2 ],
- [ 0xF58D, 0x1158,0x1165,0x11F9 ],
- [ 0xF58F, 0x1158,0x1166,0x11BC ],
- [ 0xF591, 0x1158,0x1167,0x11A8 ],
- [ 0xF592, 0x1158,0x1167,0x11AB ],
- [ 0xF593, 0x1158,0x1167,0x11AF ],
- [ 0xF594, 0x1158,0x1167,0x11D9 ],
- [ 0xF595, 0x1158,0x1167,0x11B7 ],
- [ 0xF596, 0x1158,0x1167,0x11B8 ],
- [ 0xF597, 0x1158,0x1167,0x11F0 ],
- [ 0xF598, 0x1158,0x1167,0x11F9 ],
- [ 0xF59A, 0x1158,0x1168,0x11BC ],
- [ 0xF59C, 0x1158,0x1169,0x11A8 ],
- [ 0xF59D, 0x1158,0x1169,0x11AB ],
- [ 0xF59E, 0x1158,0x1169,0x11AF ],
- [ 0xF59F, 0x1158,0x1169,0x11D9 ],
- [ 0xF5A0, 0x1158,0x1169,0x11B7 ],
- [ 0xF5A1, 0x1158,0x1169,0x11E2 ],
- [ 0xF5A2, 0x1158,0x1169,0x11BC ],
- [ 0xF5A3, 0x1158,0x1169,0x11F0 ],
- [ 0xF5A5, 0x1158,0x116A,0x11A8 ],
- [ 0xF5A6, 0x1158,0x116A,0x11AB ],
- [ 0xF5A7, 0x1158,0x116A,0x11AF ],
- [ 0xF5A8, 0x1158,0x116A,0x11D9 ],
- [ 0xF5A9, 0x1158,0x116A,0x11BC ],
- [ 0xF5AA, 0x1158,0x116A,0x11F0 ],
- [ 0xF5AB, 0x1158,0x116A,0x11F9 ],
- [ 0xF5AD, 0x1158,0x116B,0x11BC ],
- [ 0xF5AF, 0x1158,0x116C,0x11A8 ],
- [ 0xF5B0, 0x1158,0x116C,0x11BC ],
- [ 0xF5B1, 0x1158,0x116C,0x11F0 ],
- [ 0xF5B3, 0x1158,0x116D,0x11B7 ],
- [ 0xF5B4, 0x1158,0x116D,0x11E2 ],
- [ 0xF5B6, 0x1158,0x116E,0x11AB ],
- [ 0xF5B7, 0x1158,0x116E,0x11B7 ],
- [ 0xF5B8, 0x1158,0x116E,0x11E2 ],
- [ 0xF5B9, 0x1158,0x116E,0x11B8 ],
- [ 0xF5BA, 0x1158,0x116E,0x11E6 ],
- [ 0xF5BB, 0x1158,0x116E,0x11BC ],
- [ 0xF5BC, 0x1158,0x116E,0x11F0 ],
- [ 0xF5BD, 0x1158,0x116E,0x11F9 ],
- [ 0xF5BF, 0x1158,0x116F,0x11AB ],
- [ 0xF5C0, 0x1158,0x116F,0x11F9 ],
- [ 0xF5C2, 0x1158,0x1171,0x11F9 ],
- [ 0xF5C4, 0x1158,0x1172,0x11B7 ],
- [ 0xF5C6, 0x1158,0x118F,0x11AB ],
- [ 0xF5C8, 0x1158,0x1191,0x11AB ],
- [ 0xF5C9, 0x1158,0x1191,0x11AF ],
- [ 0xF5CA, 0x1158,0x1191,0x11D9 ],
- [ 0xF5CB, 0x1158,0x1191,0x11BC ],
- [ 0xF5CC, 0x1158,0x1191,0x11F0 ],
- [ 0xF5CE, 0x1158,0x1192,0x11BC ],
- [ 0xF5D0, 0x1158,0x1173,0x11A8 ],
- [ 0xF5D1, 0x1158,0x1173,0x11AB ],
- [ 0xF5D2, 0x1158,0x1173,0x11B7 ],
- [ 0xF5D3, 0x1158,0x1173,0x11E2 ],
- [ 0xF5D4, 0x1158,0x1173,0x11BC ],
- [ 0xF5D5, 0x1158,0x1173,0x11F0 ],
- [ 0xF5D8, 0x1158,0x1174,0x11A8 ],
- [ 0xF5D9, 0x1158,0x1174,0x11F0 ],
- [ 0xF5DA, 0x1158,0x1174,0x11C2 ],
- [ 0xF5DB, 0x1158,0x1174,0x11F9 ],
- [ 0xF5DD, 0x1158,0x1175,0x11AB ],
- [ 0xF5DE, 0x1158,0x1175,0x11B7 ],
- [ 0xF5DF, 0x1158,0x1175,0x11E2 ],
- [ 0xF5E0, 0x1158,0x1175,0x11F0 ],
- [ 0xF5E1, 0x1158,0x1175,0x11F9 ],
- [ 0xF5E3, 0x1158,0x119E,0x11AB ],
- [ 0xF5E5, 0x1158,0x11A1,0x11A8 ],
- [ 0xF5E6, 0x1158,0x11A1,0x11BC ],
- [ 0xF5E7, 0x1158,0x11A1,0x11F0 ],
- [ 0xF5E9, 0x1159,0x1161,0x11A8 ],
- [ 0xF5EA, 0x1159,0x1161,0x11AB ],
- [ 0xF5EB, 0x1159,0x1161,0x11AF ],
- [ 0xF5EC, 0x1159,0x1161,0x11D9 ],
- [ 0xF5ED, 0x1159,0x1161,0x11B7 ],
- [ 0xF5EE, 0x1159,0x1161,0x11E2 ],
- [ 0xF5EF, 0x1159,0x1161,0x11B8 ],
- [ 0xF5F0, 0x1159,0x1161,0x11E6 ],
- [ 0xF5F1, 0x1159,0x1161,0x11BC ],
- [ 0xF5F2, 0x1159,0x1161,0x11F0 ],
- [ 0xF5F4, 0x1159,0x1162,0x11BC ],
- [ 0xF5F5, 0x1159,0x1162,0x11F0 ],
- [ 0xF5F7, 0x1159,0x1163,0x11A8 ],
- [ 0xF5F8, 0x1159,0x1163,0x11AB ],
- [ 0xF5F9, 0x1159,0x1163,0x11B7 ],
- [ 0xF5FA, 0x1159,0x1163,0x11E2 ],
- [ 0xF5FB, 0x1159,0x1163,0x11B8 ],
- [ 0xF5FC, 0x1159,0x1163,0x11E6 ],
- [ 0xF5FD, 0x1159,0x1163,0x11F0 ],
- [ 0xF5FE, 0x1159,0x1163,0x11F9 ],
- [ 0xF601, 0x1159,0x1165,0x11AB ],
- [ 0xF602, 0x1159,0x1165,0x11AF ],
- [ 0xF603, 0x1159,0x1165,0x11D9 ],
- [ 0xF604, 0x1159,0x1165,0x11B7 ],
- [ 0xF605, 0x1159,0x1165,0x11B8 ],
- [ 0xF606, 0x1159,0x1165,0x11BC ],
- [ 0xF608, 0x1159,0x1166,0x11BC ],
- [ 0xF60A, 0x1159,0x1167,0x11A8 ],
- [ 0xF60B, 0x1159,0x1167,0x11AB ],
- [ 0xF60C, 0x1159,0x1167,0x11AF ],
- [ 0xF60D, 0x1159,0x1167,0x11D9 ],
- [ 0xF60E, 0x1159,0x1167,0x11B7 ],
- [ 0xF60F, 0x1159,0x1167,0x11B8 ],
- [ 0xF610, 0x1159,0x1167,0x11F0 ],
- [ 0xF611, 0x1159,0x1167,0x11C2 ],
- [ 0xF613, 0x1159,0x1168,0x11BC ],
- [ 0xF615, 0x1159,0x1169,0x11A8 ],
- [ 0xF616, 0x1159,0x1169,0x11AB ],
- [ 0xF617, 0x1159,0x1169,0x11B7 ],
- [ 0xF618, 0x1159,0x1169,0x11E2 ],
- [ 0xF619, 0x1159,0x1169,0x11BC ],
- [ 0xF61A, 0x1159,0x1169,0x11F0 ],
- [ 0xF61C, 0x1159,0x116A,0x11A8 ],
- [ 0xF61D, 0x1159,0x116A,0x11AB ],
- [ 0xF61E, 0x1159,0x116A,0x11AF ],
- [ 0xF61F, 0x1159,0x116A,0x11D9 ],
- [ 0xF620, 0x1159,0x116A,0x11B8 ],
- [ 0xF621, 0x1159,0x116A,0x11E6 ],
- [ 0xF622, 0x1159,0x116A,0x11BC ],
- [ 0xF623, 0x1159,0x116A,0x11F0 ],
- [ 0xF624, 0x1159,0x116A,0x11F9 ],
- [ 0xF626, 0x1159,0x116B,0x11BC ],
- [ 0xF628, 0x1159,0x116C,0x11A8 ],
- [ 0xF629, 0x1159,0x116C,0x11BC ],
- [ 0xF62A, 0x1159,0x116C,0x11F0 ],
- [ 0xF62C, 0x1159,0x116D,0x11A8 ],
- [ 0xF62D, 0x1159,0x116D,0x11B7 ],
- [ 0xF62E, 0x1159,0x116D,0x11E2 ],
- [ 0xF62F, 0x1159,0x116D,0x11BC ],
- [ 0xF631, 0x1159,0x116E,0x11A8 ],
- [ 0xF632, 0x1159,0x116E,0x11AB ],
- [ 0xF633, 0x1159,0x116E,0x11AF ],
- [ 0xF634, 0x1159,0x116E,0x11D9 ],
- [ 0xF635, 0x1159,0x116E,0x11B7 ],
- [ 0xF636, 0x1159,0x116E,0x11E2 ],
- [ 0xF637, 0x1159,0x116E,0x11BC ],
- [ 0xF638, 0x1159,0x116E,0x11F0 ],
- [ 0xF639, 0x1159,0x116E,0x11F9 ],
- [ 0xF63B, 0x1159,0x116F,0x11AB ],
- [ 0xF63C, 0x1159,0x116F,0x11AF ],
- [ 0xF63D, 0x1159,0x116F,0x11D9 ],
- [ 0xF63E, 0x1159,0x116F,0x11BC ],
- [ 0xF640, 0x1159,0x1171,0x11BC ],
- [ 0xF642, 0x1159,0x1172,0x11AB ],
- [ 0xF643, 0x1159,0x1172,0x11B7 ],
- [ 0xF644, 0x1159,0x1172,0x11E2 ],
- [ 0xF645, 0x1159,0x1172,0x11F9 ],
- [ 0xF647, 0x1159,0x1191,0x11A8 ],
- [ 0xF648, 0x1159,0x1191,0x11AB ],
- [ 0xF649, 0x1159,0x1191,0x11AF ],
- [ 0xF64A, 0x1159,0x1191,0x11D9 ],
- [ 0xF64B, 0x1159,0x1191,0x11BC ],
- [ 0xF64C, 0x1159,0x1191,0x11F0 ],
- [ 0xF64E, 0x1159,0x1192,0x11BC ],
- [ 0xF650, 0x1159,0x1194,0x11BC ],
- [ 0xF652, 0x1159,0x1173,0x11A8 ],
- [ 0xF653, 0x1159,0x1173,0x11AB ],
- [ 0xF654, 0x1159,0x1173,0x11B7 ],
- [ 0xF655, 0x1159,0x1173,0x11E2 ],
- [ 0xF656, 0x1159,0x1173,0x11B8 ],
- [ 0xF657, 0x1159,0x1173,0x11F0 ],
- [ 0xF658, 0x1159,0x1173,0x11F9 ],
- [ 0xF65A, 0x1159,0x1174,0x11AB ],
- [ 0xF65B, 0x1159,0x1174,0x11BC ],
- [ 0xF65D, 0x1159,0x1175,0x11AB ],
- [ 0xF65E, 0x1159,0x1175,0x11AF ],
- [ 0xF65F, 0x1159,0x1175,0x11D9 ],
- [ 0xF660, 0x1159,0x1175,0x11B7 ],
- [ 0xF661, 0x1159,0x1175,0x11E2 ],
- [ 0xF662, 0x1159,0x1175,0x11BC ],
- [ 0xF663, 0x1159,0x1175,0x11F0 ],
- [ 0xF664, 0x1159,0x1175,0x11F9 ],
- [ 0xF666, 0x1159,0x119E,0x11AB ],
- [ 0xF667, 0x1159,0x119E,0x11B7 ],
- [ 0xF669, 0x1159,0x11A1,0x11A8 ],
- [ 0xF66A, 0x1159,0x11A1,0x11AF ],
- [ 0xF66B, 0x1159,0x11A1,0x11CD ],
- [ 0xF66C, 0x1159,0x11A1,0x11B1 ],
- [ 0xF66D, 0x1159,0x11A1,0x11BC ],
- [ 0xF66E, 0x1159,0x11A1,0x11F0 ],
- [ 0xE0C6, 0x115F,0x11A3 ],
- [ 0xE0E9, 0x1100,0x1176 ],
- [ 0xE0EA, 0x1100,0x1177 ],
- [ 0xE0F2, 0x1100,0x1178 ],
- [ 0xE100, 0x1100,0x117C ],
- [ 0xE124, 0x1100,0x11A6 ],
- [ 0xE126, 0x1100,0x117F ],
- [ 0xE129, 0x1100,0x1182 ],
- [ 0xE12F, 0x1100,0xD7B2 ],
- [ 0xE130, 0x1100,0xD7B3 ],
- [ 0xE132, 0x1100,0x1184 ],
- [ 0xE133, 0x1100,0x1185 ],
- [ 0xE136, 0x1100,0x1188 ],
- [ 0xE146, 0x1100,0x1189 ],
- [ 0xE14A, 0x1100,0x118A ],
- [ 0xE14E, 0x1100,0x118B ],
- [ 0xE150, 0x1100,0xD7B5 ],
- [ 0xE151, 0x1100,0x118C ],
- [ 0xE152, 0x1100,0x118D ],
- [ 0xE15A, 0x1100,0x118E ],
- [ 0xE15C, 0x1100,0x118F ],
- [ 0xE15E, 0x1100,0x1191 ],
- [ 0xE166, 0x1100,0x1192 ],
- [ 0xE16A, 0x1100,0x1194 ],
- [ 0xE181, 0x1100,0xD7BA ],
- [ 0xE182, 0x1100,0xD7BB ],
- [ 0xE183, 0x1100,0x1195 ],
- [ 0xE184, 0x1100,0x1196 ],
- [ 0xE19A, 0x1100,0x1198 ],
- [ 0xE19B, 0x1100,0x1199 ],
- [ 0xE19E, 0x1100,0xD7BF ],
- [ 0xE19F, 0x1100,0xD7C0 ],
- [ 0xE1A0, 0x1100,0xD7C2 ],
- [ 0xE1A1, 0x1100,0x119B ],
- [ 0xE1A2, 0x1100,0xD7C3 ],
- [ 0xE1A4, 0x1100,0x119C ],
- [ 0xE1A5, 0x1100,0xD7C4 ],
- [ 0xE1A6, 0x1100,0x119D ],
- [ 0xE1A7, 0x1100,0x119E ],
- [ 0xE1CA, 0x1100,0x119F ],
- [ 0xE1CD, 0x1100,0x11A1 ],
- [ 0xE1D8, 0x1101,0x1176 ],
- [ 0xE1DF, 0x1101,0x117B ],
- [ 0xE1E6, 0x1101,0x1188 ],
- [ 0xE1EB, 0x1101,0x1189 ],
- [ 0xE1EE, 0x1101,0xD7B5 ],
- [ 0xE1EF, 0x1101,0x118C ],
- [ 0xE1F3, 0x1101,0x1191 ],
- [ 0xE1F8, 0x1101,0x1194 ],
- [ 0xE201, 0x1101,0x1198 ],
- [ 0xE202, 0x1101,0x119E ],
- [ 0xE203, 0x1101,0x11A1 ],
- [ 0xE204, 0x115A,0x1165 ],
- [ 0xE205, 0x115A,0x1173 ],
- [ 0xE21C, 0x1102,0x1176 ],
- [ 0xE21D, 0x1102,0x1177 ],
- [ 0xE224, 0x1102,0x1178 ],
- [ 0xE22E, 0x1102,0x117B ],
- [ 0xE230, 0x1102,0x117A ],
- [ 0xE230, 0x1102,0x117C ],
- [ 0xE24A, 0x1102,0x117F ],
- [ 0xE24F, 0x1102,0xD7B2 ],
- [ 0xE251, 0x1102,0x1188 ],
- [ 0xE25A, 0x1102,0x1189 ],
- [ 0xE25C, 0x1102,0xD7B5 ],
- [ 0xE25D, 0x1102,0x118C ],
- [ 0xE25F, 0x1102,0xD7B6 ],
- [ 0xE263, 0x1102,0x118F ],
- [ 0xE264, 0x1102,0x1194 ],
- [ 0xE26C, 0x1102,0x1196 ],
- [ 0xE26E, 0x1102,0x1197 ],
- [ 0xE27C, 0x1102,0x1198 ],
- [ 0xE27D, 0x1102,0x1199 ],
- [ 0xE280, 0x1102,0xD7BF ],
- [ 0xE281, 0x1102,0xD7C0 ],
- [ 0xE282, 0x1102,0x119B ],
- [ 0xE283, 0x1102,0x119E ],
- [ 0xE299, 0x1102,0x11A1 ],
- [ 0xE2A5, 0x1113,0x1161 ],
- [ 0xE2A6, 0x1113,0x1162 ],
- [ 0xE2A7, 0x1113,0x1163 ],
- [ 0xE2A8, 0x1113,0x1165 ],
- [ 0xE2A9, 0x1113,0x1166 ],
- [ 0xE2AA, 0x1113,0x1167 ],
- [ 0xE2AB, 0x1113,0x1168 ],
- [ 0xE2AD, 0x1113,0x1169 ],
- [ 0xE2AE, 0x1113,0x116A ],
- [ 0xE2AF, 0x1113,0x116B ],
- [ 0xE2B0, 0x1113,0x116C ],
- [ 0xE2B1, 0x1113,0x116D ],
- [ 0xE2B2, 0x1113,0x116E ],
- [ 0xE2B3, 0x1113,0x116F ],
- [ 0xE2B4, 0x1113,0x1170 ],
- [ 0xE2B5, 0x1113,0xD7B5 ],
- [ 0xE2B6, 0x1113,0x118C ],
- [ 0xE2B7, 0x1113,0x1171 ],
- [ 0xE2B8, 0x1113,0x1172 ],
- [ 0xE2B9, 0x1113,0x1194 ],
- [ 0xE2BA, 0x1113,0x1173 ],
- [ 0xE2BB, 0x1113,0x1174 ],
- [ 0xE2BC, 0x1113,0x1175 ],
- [ 0xE2BD, 0x1113,0x1198 ],
- [ 0xE2BE, 0x1113,0x119E ],
- [ 0xE2BF, 0x1113,0x11A1 ],
- [ 0xE2C0, 0x1114,0x1161 ],
- [ 0xE2C1, 0x1114,0x1163 ],
- [ 0xE2C3, 0x1114,0x1165 ],
- [ 0xE2C4, 0x1114,0x1166 ],
- [ 0xE2C5, 0x1114,0x1169 ],
- [ 0xE2C6, 0x1114,0x116E ],
- [ 0xE2C7, 0x1114,0x1173 ],
- [ 0xE2C9, 0x1114,0x119E ],
- [ 0xE2CB, 0x1115,0x1161 ],
- [ 0xE2CD, 0x1115,0x1162 ],
- [ 0xE2CE, 0x1115,0x1163 ],
- [ 0xE2CF, 0x1115,0x1165 ],
- [ 0xE2D0, 0x1115,0x1166 ],
- [ 0xE2D2, 0x1115,0x1167 ],
- [ 0xE2D3, 0x1115,0x1168 ],
- [ 0xE2D4, 0x1115,0x1169 ],
- [ 0xE2D6, 0x1115,0x116A ],
- [ 0xE2D7, 0x1115,0x116B ],
- [ 0xE2D8, 0x1115,0x116C ],
- [ 0xE2D9, 0x1115,0x116D ],
- [ 0xE2DA, 0x1115,0x116E ],
- [ 0xE2DB, 0x1115,0x116F ],
- [ 0xE2DC, 0x1115,0x1170 ],
- [ 0xE2DD, 0x1115,0xD7B5 ],
- [ 0xE2DE, 0x1115,0x118C ],
- [ 0xE2DF, 0x1115,0x1171 ],
- [ 0xE2E0, 0x1115,0x1172 ],
- [ 0xE2E1, 0x1115,0x1194 ],
- [ 0xE2E2, 0x1115,0x1173 ],
- [ 0xE2E3, 0x1115,0x1174 ],
- [ 0xE2E4, 0x1115,0x1175 ],
- [ 0xE2E5, 0x1115,0x1198 ],
- [ 0xE2E6, 0x1115,0x119E ],
- [ 0xE2E7, 0x1115,0x11A1 ],
- [ 0xE2E8, 0x1116,0x1161 ],
- [ 0xE2E9, 0x1116,0x1162 ],
- [ 0xE2EA, 0x1116,0x1163 ],
- [ 0xE2EB, 0x1116,0x1165 ],
- [ 0xE2EC, 0x1116,0x1166 ],
- [ 0xE2ED, 0x1116,0x1167 ],
- [ 0xE2EE, 0x1116,0x1168 ],
- [ 0xE2EF, 0x1116,0x1169 ],
- [ 0xE2F0, 0x1116,0x116A ],
- [ 0xE2F1, 0x1116,0x116B ],
- [ 0xE2F2, 0x1116,0x116C ],
- [ 0xE2F3, 0x1116,0x116D ],
- [ 0xE2F4, 0x1116,0x116E ],
- [ 0xE2F5, 0x1116,0x116F ],
- [ 0xE2F6, 0x1116,0x1170 ],
- [ 0xE2F7, 0x1116,0xD7B5 ],
- [ 0xE2F8, 0x1116,0x118C ],
- [ 0xE2F9, 0x1116,0x1171 ],
- [ 0xE2FA, 0x1116,0x1172 ],
- [ 0xE2FB, 0x1116,0x1194 ],
- [ 0xE2FC, 0x1116,0x1173 ],
- [ 0xE2FD, 0x1116,0x1174 ],
- [ 0xE2FE, 0x1116,0x1175 ],
- [ 0xE2FF, 0x1116,0x1198 ],
- [ 0xE300, 0x1116,0x119E ],
- [ 0xE301, 0x1116,0x11A1 ],
- [ 0xE302, 0x115B,0x1175 ],
- [ 0xE303, 0x115B,0x1198 ],
- [ 0xE304, 0x115C,0x1173 ],
- [ 0xE305, 0x115C,0x1175 ],
- [ 0xE306, 0x115D,0x1163 ],
- [ 0xE308, 0x115D,0x1169 ],
- [ 0xE309, 0x115D,0x1172 ],
- [ 0xE30B, 0x115D,0x1175 ],
- [ 0xE31F, 0x1103,0x1176 ],
- [ 0xE325, 0x1103,0x1178 ],
- [ 0xE32B, 0x1103,0x117A ],
- [ 0xE32C, 0x1103,0x117B ],
- [ 0xE32E, 0x1103,0x117C ],
- [ 0xE348, 0x1103,0x1182 ],
- [ 0xE34D, 0x1103,0x1188 ],
- [ 0xE356, 0x1103,0x1189 ],
- [ 0xE359, 0x1103,0xD7B5 ],
- [ 0xE35A, 0x1103,0x118C ],
- [ 0xE361, 0x1103,0x1191 ],
- [ 0xE366, 0x1103,0x1192 ],
- [ 0xE368, 0x1103,0x1194 ],
- [ 0xE376, 0x1103,0x1195 ],
- [ 0xE377, 0x1103,0x1196 ],
- [ 0xE383, 0x1103,0x1198 ],
- [ 0xE384, 0x1103,0x1199 ],
- [ 0xE387, 0x1103,0xD7BF ],
- [ 0xE388, 0x1103,0xD7C0 ],
- [ 0xE389, 0x1103,0x119B ],
- [ 0xE38A, 0x1103,0x119E ],
- [ 0xE3A8, 0x1103,0x11A1 ],
- [ 0xE3B4, 0x1117,0x1173 ],
- [ 0xE3B6, 0x1117,0x1175 ],
- [ 0xE3C1, 0x1104,0x117B ],
- [ 0xE3C2, 0x1104,0x117C ],
- [ 0xE3CD, 0x1104,0x117F ],
- [ 0xE3D2, 0x1104,0xD7B5 ],
- [ 0xE3D3, 0x1104,0x118C ],
- [ 0xE3D8, 0x1104,0x1191 ],
- [ 0xE3DA, 0x1104,0x1194 ],
- [ 0xE3E4, 0x1104,0x1198 ],
- [ 0xE3E5, 0x1104,0x119E ],
- [ 0xE3EB, 0x1104,0x11A1 ],
- [ 0xE3F0, 0x115E,0x1175 ],
- [ 0xE3F3, 0xA960,0x1161 ],
- [ 0xE3F5, 0xA961,0x1161 ],
- [ 0xE3F6, 0xA961,0x1162 ],
- [ 0xE3F7, 0xA961,0x116E ],
- [ 0xE3F9, 0xA962,0x1172 ],
- [ 0xE3FC, 0xA962,0x1173 ],
- [ 0xE3FD, 0xA962,0x1175 ],
- [ 0xE3FF, 0xA963,0x1163 ],
- [ 0xE401, 0xA963,0x119E ],
- [ 0xE40F, 0x1105,0x1176 ],
- [ 0xE411, 0x1105,0x1177 ],
- [ 0xE415, 0x1105,0x1178 ],
- [ 0xE41B, 0x1105,0x117A ],
- [ 0xE41C, 0x1105,0x117B ],
- [ 0xE430, 0x1105,0x1182 ],
- [ 0xE435, 0x1105,0x1186 ],
- [ 0xE436, 0x1105,0x1187 ],
- [ 0xE437, 0x1105,0x1188 ],
- [ 0xE43E, 0x1105,0x1189 ],
- [ 0xE440, 0x1105,0xD7B5 ],
- [ 0xE441, 0x1105,0x118C ],
- [ 0xE442, 0x1105,0x118D ],
- [ 0xE447, 0x1105,0x1191 ],
- [ 0xE44B, 0x1105,0x1194 ],
- [ 0xE455, 0x1105,0x1195 ],
- [ 0xE456, 0x1105,0x1196 ],
- [ 0xE45F, 0x1105,0x1198 ],
- [ 0xE460, 0x1105,0x1199 ],
- [ 0xE463, 0x1105,0xD7BD ],
- [ 0xE464, 0x1105,0xD7BF ],
- [ 0xE465, 0x1105,0xD7C0 ],
- [ 0xE466, 0x1105,0x119A ],
- [ 0xE468, 0x1105,0xD7C2 ],
- [ 0xE469, 0x1105,0x119B ],
- [ 0xE46B, 0x1105,0xD7C4 ],
- [ 0xE46C, 0x1105,0x119E ],
- [ 0xE486, 0x1105,0xD7C5 ],
- [ 0xE487, 0x1105,0x11A1 ],
- [ 0xE490, 0xA964,0x1161 ],
- [ 0xE491, 0xA964,0x1169 ],
- [ 0xE493, 0xA965,0x1161 ],
- [ 0xE494, 0x1118,0x1161 ],
- [ 0xE498, 0x1118,0x1165 ],
- [ 0xE499, 0x1118,0x1166 ],
- [ 0xE49C, 0x1118,0x1169 ],
- [ 0xE4A1, 0x1118,0x116D ],
- [ 0xE4A3, 0x1118,0x116E ],
- [ 0xE4A4, 0x1118,0x1172 ],
- [ 0xE4A6, 0x1118,0x1173 ],
- [ 0xE4A7, 0x1118,0x1174 ],
- [ 0xE4AB, 0x1118,0x119E ],
- [ 0xE4AE, 0x1118,0x11A1 ],
- [ 0xE4B1, 0xA967,0x1161 ],
- [ 0xE4B2, 0x1119,0x1161 ],
- [ 0xE4B6, 0x1119,0x1176 ],
- [ 0xE4B7, 0x1119,0x1162 ],
- [ 0xE4B9, 0x1119,0x1163 ],
- [ 0xE4BB, 0x1119,0x1178 ],
- [ 0xE4BC, 0x1119,0x1165 ],
- [ 0xE4BF, 0x1119,0x117B ],
- [ 0xE4C0, 0x1119,0x1166 ],
- [ 0xE4C2, 0x1119,0x1167 ],
- [ 0xE4C4, 0x1119,0x1168 ],
- [ 0xE4C6, 0x1119,0x1169 ],
- [ 0xE4C8, 0x1119,0x116D ],
- [ 0xE4C9, 0x1119,0x116E ],
- [ 0xE4CC, 0x1119,0x1189 ],
- [ 0xE4CE, 0x1119,0x116F ],
- [ 0xE4CF, 0x1119,0x1170 ],
- [ 0xE4D0, 0x1119,0x1171 ],
- [ 0xE4D1, 0x1119,0x1172 ],
- [ 0xE4D2, 0x1119,0x118F ],
- [ 0xE4D3, 0x1119,0x1190 ],
- [ 0xE4D4, 0x1119,0x1173 ],
- [ 0xE4D8, 0x1119,0x1175 ],
- [ 0xE4DB, 0x1119,0x119B ],
- [ 0xE4DC, 0xA968,0x1161 ],
- [ 0xE4DE, 0xA969,0x1161 ],
- [ 0xE4DF, 0xA96A,0x1161 ],
- [ 0xE4E0, 0xA96B,0x119E ],
- [ 0xE4E1, 0xA96B,0x11A1 ],
- [ 0xE4E2, 0xA96C,0x1169 ],
- [ 0xE4E4, 0xA96C,0x1173 ],
- [ 0xE4E5, 0xA96D,0x1165 ],
- [ 0xE4E6, 0xA96D,0x1166 ],
- [ 0xE4E7, 0xA96D,0x1172 ],
- [ 0xE4E9, 0xA96E,0x1161 ],
- [ 0xE4EA, 0x111A,0x1161 ],
- [ 0xE4EC, 0x111A,0x1163 ],
- [ 0xE4EE, 0x111A,0x1169 ],
- [ 0xE4EF, 0x111A,0x116A ],
- [ 0xE4F0, 0x111A,0x1175 ],
- [ 0xE502, 0x1106,0x1176 ],
- [ 0xE503, 0x1106,0x1177 ],
- [ 0xE506, 0x1106,0x1178 ],
- [ 0xE50D, 0x1106,0x117A ],
- [ 0xE50E, 0x1106,0x117C ],
- [ 0xE51F, 0x1106,0x117F ],
- [ 0xE521, 0x1106,0x1182 ],
- [ 0xE522, 0x1106,0xD7B1 ],
- [ 0xE523, 0x1106,0x1183 ],
- [ 0xE525, 0x1106,0x1187 ],
- [ 0xE526, 0x1106,0x1188 ],
- [ 0xE536, 0x1106,0xD7B5 ],
- [ 0xE537, 0x1106,0x118C ],
- [ 0xE538, 0x1106,0x118D ],
- [ 0xE53B, 0x1106,0x1194 ],
- [ 0xE544, 0x1106,0x1195 ],
- [ 0xE545, 0x1106,0x1196 ],
- [ 0xE559, 0x1106,0x1198 ],
- [ 0xE55A, 0x1106,0x1199 ],
- [ 0xE55C, 0x1106,0xD7BF ],
- [ 0xE55D, 0x1106,0xD7C0 ],
- [ 0xE55E, 0x1106,0x119C ],
- [ 0xE560, 0x1106,0x119E ],
- [ 0xE578, 0x1106,0x119F ],
- [ 0xE57B, 0x1106,0x11A1 ],
- [ 0xE58C, 0xA96F,0x1163 ],
- [ 0xE58D, 0xA96F,0x1178 ],
- [ 0xE58E, 0xA96F,0x1167 ],
- [ 0xE58F, 0xA96F,0x1168 ],
- [ 0xE590, 0xA970,0x1167 ],
- [ 0xE592, 0xA970,0x1169 ],
- [ 0xE593, 0x111C,0x1161 ],
- [ 0xE596, 0x111C,0x1162 ],
- [ 0xE597, 0x111C,0x1163 ],
- [ 0xE598, 0x111C,0x1165 ],
- [ 0xE599, 0x111C,0x1166 ],
- [ 0xE59A, 0x111C,0x1167 ],
- [ 0xE59B, 0x111C,0x1168 ],
- [ 0xE59E, 0x111C,0x1169 ],
- [ 0xE5A2, 0x111C,0x116A ],
- [ 0xE5A3, 0x111C,0x116B ],
- [ 0xE5A4, 0x111C,0x116C ],
- [ 0xE5A5, 0x111C,0x116D ],
- [ 0xE5A6, 0x111C,0x116E ],
- [ 0xE5A9, 0x111C,0x116F ],
- [ 0xE5AA, 0x111C,0x1170 ],
- [ 0xE5AB, 0x111C,0xD7B5 ],
- [ 0xE5AC, 0x111C,0x118C ],
- [ 0xE5AD, 0x111C,0x1171 ],
- [ 0xE5AE, 0x111C,0x1172 ],
- [ 0xE5AF, 0x111C,0x1194 ],
- [ 0xE5B0, 0x111C,0x1173 ],
- [ 0xE5B1, 0x111C,0x1174 ],
- [ 0xE5B2, 0x111C,0x1175 ],
- [ 0xE5B4, 0x111C,0x1198 ],
- [ 0xE5B5, 0x111C,0x119E ],
- [ 0xE5B6, 0x111C,0x11A1 ],
- [ 0xE5B7, 0xA971,0x1169 ],
- [ 0xE5B9, 0x111D,0x1161 ],
- [ 0xE5BD, 0x111D,0x1169 ],
- [ 0xE5BE, 0x111D,0x116A ],
- [ 0xE5C1, 0x111D,0x116E ],
- [ 0xE5C5, 0x111D,0x1171 ],
- [ 0xE5C6, 0x111D,0x1172 ],
- [ 0xE5C8, 0x111D,0x1173 ],
- [ 0xE5CC, 0x111D,0x1175 ],
- [ 0xE5E9, 0x1107,0x1176 ],
- [ 0xE5EB, 0x1107,0x1177 ],
- [ 0xE5EF, 0x1107,0x1178 ],
- [ 0xE5F5, 0x1107,0x117B ],
- [ 0xE5F7, 0x1107,0x117C ],
- [ 0xE60C, 0x1107,0x1182 ],
- [ 0xE60D, 0x1107,0xD7B1 ],
- [ 0xE613, 0x1107,0x1187 ],
- [ 0xE614, 0x1107,0x1188 ],
- [ 0xE623, 0x1107,0xD7B5 ],
- [ 0xE624, 0x1107,0x118C ],
- [ 0xE625, 0x1107,0x118D ],
- [ 0xE62A, 0x1107,0x1194 ],
- [ 0xE635, 0x1107,0x1196 ],
- [ 0xE643, 0x1107,0x1198 ],
- [ 0xE644, 0x1107,0x1199 ],
- [ 0xE646, 0x1107,0xD7BF ],
- [ 0xE647, 0x1107,0xD7C0 ],
- [ 0xE648, 0x1107,0x119A ],
- [ 0xE649, 0x1107,0x119B ],
- [ 0xE64A, 0x1107,0x119E ],
- [ 0xE663, 0x1107,0x119F ],
- [ 0xE667, 0x1107,0xD7C6 ],
- [ 0xE668, 0x1107,0x11A1 ],
- [ 0xE679, 0x111E,0x1161 ],
- [ 0xE67C, 0x111E,0x1162 ],
- [ 0xE67E, 0x111E,0x1165 ],
- [ 0xE680, 0x111E,0x1166 ],
- [ 0xE682, 0x111E,0x1167 ],
- [ 0xE685, 0x111E,0x1168 ],
- [ 0xE687, 0x111E,0x1169 ],
- [ 0xE689, 0x111E,0x116C ],
- [ 0xE68B, 0x111E,0x116E ],
- [ 0xE68F, 0x111E,0x116F ],
- [ 0xE690, 0x111E,0x1170 ],
- [ 0xE691, 0x111E,0x1171 ],
- [ 0xE692, 0x111E,0x1173 ],
- [ 0xE697, 0x111E,0x1174 ],
- [ 0xE699, 0x111E,0x1175 ],
- [ 0xE69D, 0x111E,0x119E ],
- [ 0xE69F, 0x111E,0x11A1 ],
- [ 0xE6A2, 0x111F,0x1167 ],
- [ 0xE6A3, 0x1120,0x1161 ],
- [ 0xE6AA, 0x1120,0x1162 ],
- [ 0xE6AB, 0x1120,0x1163 ],
- [ 0xE6AC, 0x1120,0x1165 ],
- [ 0xE6B5, 0x1120,0x1166 ],
- [ 0xE6B8, 0x1120,0x1167 ],
- [ 0xE6BA, 0x1120,0x1168 ],
- [ 0xE6BC, 0x1120,0x1169 ],
- [ 0xE6C1, 0x1120,0x116A ],
- [ 0xE6C2, 0x1120,0x116B ],
- [ 0xE6C3, 0x1120,0x116C ],
- [ 0xE6C5, 0x1120,0x116D ],
- [ 0xE6C6, 0x1120,0x116E ],
- [ 0xE6CE, 0x1120,0x116F ],
- [ 0xE6CF, 0x1120,0x1170 ],
- [ 0xE6D0, 0x1120,0xD7B5 ],
- [ 0xE6D1, 0x1120,0x118C ],
- [ 0xE6D2, 0x1120,0x1171 ],
- [ 0xE6D5, 0x1120,0x1172 ],
- [ 0xE6D6, 0x1120,0x1194 ],
- [ 0xE6D7, 0x1120,0x1173 ],
- [ 0xE6E4, 0x1120,0x1174 ],
- [ 0xE6E7, 0x1120,0x1175 ],
- [ 0xE6EE, 0x1120,0x1198 ],
- [ 0xE6EF, 0x1120,0x119E ],
- [ 0xE6F5, 0x1120,0x11A1 ],
- [ 0xE70F, 0x1108,0xD7B5 ],
- [ 0xE71D, 0x1108,0x119E ],
- [ 0xE721, 0x1108,0x11A1 ],
- [ 0xE725, 0x1121,0x1161 ],
- [ 0xE733, 0x1121,0x1162 ],
- [ 0xE735, 0x1121,0x1163 ],
- [ 0xE73A, 0x1121,0x1164 ],
- [ 0xE73B, 0x1121,0x1165 ],
- [ 0xE741, 0x1121,0x1166 ],
- [ 0xE744, 0x1121,0x1167 ],
- [ 0xE74A, 0x1121,0x1168 ],
- [ 0xE74C, 0x1121,0x1169 ],
- [ 0xE755, 0x1121,0x116A ],
- [ 0xE759, 0x1121,0x116B ],
- [ 0xE75B, 0x1121,0x116C ],
- [ 0xE75C, 0x1121,0x116D ],
- [ 0xE75D, 0x1121,0x116E ],
- [ 0xE766, 0x1121,0x116F ],
- [ 0xE767, 0x1121,0x1170 ],
- [ 0xE768, 0x1121,0xD7B5 ],
- [ 0xE769, 0x1121,0x118C ],
- [ 0xE76A, 0x1121,0x1171 ],
- [ 0xE76B, 0x1121,0x1172 ],
- [ 0xE76F, 0x1121,0x1194 ],
- [ 0xE770, 0x1121,0x1173 ],
- [ 0xE77A, 0x1121,0x1174 ],
- [ 0xE77C, 0x1121,0x1175 ],
- [ 0xE785, 0x1121,0x1198 ],
- [ 0xE786, 0x1121,0x119E ],
- [ 0xE792, 0x1121,0x11A1 ],
- [ 0xE794, 0x1122,0x1161 ],
- [ 0xE795, 0x1122,0x1162 ],
- [ 0xE798, 0x1122,0x1165 ],
- [ 0xE79C, 0x1122,0x1166 ],
- [ 0xE79E, 0x1122,0x1167 ],
- [ 0xE7A1, 0x1122,0x1168 ],
- [ 0xE7A3, 0x1122,0x1169 ],
- [ 0xE7A4, 0x1122,0x116C ],
- [ 0xE7A6, 0x1122,0x116E ],
- [ 0xE7AB, 0x1122,0x116F ],
- [ 0xE7AC, 0x1122,0x1170 ],
- [ 0xE7AD, 0x1122,0x1171 ],
- [ 0xE7AF, 0x1122,0x1173 ],
- [ 0xE7B4, 0x1122,0x1174 ],
- [ 0xE7B9, 0x1122,0x1175 ],
- [ 0xE7BC, 0x1122,0x119E ],
- [ 0xE7BE, 0x1123,0x1161 ],
- [ 0xE7C0, 0x1123,0x1162 ],
- [ 0xE7C1, 0x1123,0x1165 ],
- [ 0xE7C5, 0x1123,0x1167 ],
- [ 0xE7C7, 0x1123,0x1169 ],
- [ 0xE7C8, 0x1123,0x116C ],
- [ 0xE7C9, 0x1123,0x116E ],
- [ 0xE7CC, 0x1123,0x1172 ],
- [ 0xE7CE, 0x1123,0x1173 ],
- [ 0xE7D1, 0x1123,0x1174 ],
- [ 0xE7D2, 0x1123,0x1175 ],
- [ 0xE7D4, 0x1123,0x119E ],
- [ 0xE7D6, 0x1123,0x11A1 ],
- [ 0xE7D7, 0x1124,0x1167 ],
- [ 0xE7D8, 0x1124,0x1168 ],
- [ 0xE7D9, 0x1125,0x1165 ],
- [ 0xE7DA, 0x1125,0x1169 ],
- [ 0xE7DB, 0x1125,0x1173 ],
- [ 0xE7DC, 0x1126,0x119E ],
- [ 0xE7DE, 0xA972,0x1161 ],
- [ 0xE7DF, 0x1127,0x1161 ],
- [ 0xE7E6, 0x1127,0x1162 ],
- [ 0xE7E7, 0x1127,0x1163 ],
- [ 0xE7EB, 0x1127,0x1165 ],
- [ 0xE7ED, 0x1127,0x1166 ],
- [ 0xE7EE, 0x1127,0x1167 ],
- [ 0xE7EF, 0x1127,0x1169 ],
- [ 0xE7F8, 0x1127,0x116A ],
- [ 0xE7FB, 0x1127,0x116B ],
- [ 0xE7FC, 0x1127,0x116C ],
- [ 0xE7FF, 0x1127,0x116D ],
- [ 0xE800, 0x1127,0x116E ],
- [ 0xE804, 0x1127,0x1171 ],
- [ 0xE805, 0x1127,0x1173 ],
- [ 0xE80D, 0x1127,0x1174 ],
- [ 0xE810, 0x1127,0x1175 ],
- [ 0xE81A, 0x1127,0x119E ],
- [ 0xE81F, 0x1127,0x11A1 ],
- [ 0xE823, 0x1128,0x1169 ],
- [ 0xE825, 0x1128,0x119E ],
- [ 0xE827, 0xA973,0x1169 ],
- [ 0xE828, 0xA973,0x116A ],
- [ 0xE829, 0xA973,0x116B ],
- [ 0xE82A, 0xA973,0x1173 ],
- [ 0xE82B, 0x1129,0x1161 ],
- [ 0xE82C, 0x1129,0x1165 ],
- [ 0xE833, 0x1129,0x1167 ],
- [ 0xE834, 0x1129,0x1169 ],
- [ 0xE837, 0x1129,0x116E ],
- [ 0xE83A, 0x1129,0x1171 ],
- [ 0xE83D, 0x1129,0x1173 ],
- [ 0xE841, 0x1129,0x1174 ],
- [ 0xE843, 0x1129,0x1175 ],
- [ 0xE847, 0x1129,0x119E ],
- [ 0xE84A, 0x1129,0x11A1 ],
- [ 0xE84B, 0x112A,0x1161 ],
- [ 0xE84D, 0x112A,0x1169 ],
- [ 0xE84F, 0x112A,0x116D ],
- [ 0xE850, 0x112A,0x1173 ],
- [ 0xE852, 0x112A,0x1175 ],
- [ 0xE853, 0x112A,0x119E ],
- [ 0xE855, 0xA974,0x1161 ],
- [ 0xE857, 0x112B,0x1161 ],
- [ 0xE865, 0x112B,0x1162 ],
- [ 0xE868, 0x112B,0x1165 ],
- [ 0xE86D, 0x112B,0x1166 ],
- [ 0xE86F, 0x112B,0x1167 ],
- [ 0xE874, 0x112B,0x1168 ],
- [ 0xE876, 0x112B,0x1169 ],
- [ 0xE880, 0x112B,0x116A ],
- [ 0xE882, 0x112B,0x116D ],
- [ 0xE883, 0x112B,0x1187 ],
- [ 0xE884, 0x112B,0x1188 ],
- [ 0xE885, 0x112B,0x116E ],
- [ 0xE88F, 0x112B,0x116F ],
- [ 0xE890, 0x112B,0x1171 ],
- [ 0xE893, 0x112B,0x1172 ],
- [ 0xE895, 0x112B,0x1173 ],
- [ 0xE89F, 0x112B,0x1195 ],
- [ 0xE8A0, 0x112B,0x1174 ],
- [ 0xE8A1, 0x112B,0x1175 ],
- [ 0xE8A7, 0x112B,0x119E ],
- [ 0xE8B2, 0x112B,0x11A1 ],
- [ 0xE8B6, 0x112C,0x1161 ],
- [ 0xE8BB, 0x112C,0x1169 ],
- [ 0xE8BD, 0x112C,0x116A ],
- [ 0xE8BF, 0x112C,0x116E ],
- [ 0xE8C4, 0x112C,0x1172 ],
- [ 0xE8C6, 0x112C,0x1173 ],
- [ 0xE8CB, 0x112C,0x1174 ],
- [ 0xE8CC, 0x112C,0x1175 ],
- [ 0xE8DD, 0x1109,0x1176 ],
- [ 0xE8DE, 0x1109,0x1177 ],
- [ 0xE8DF, 0x1109,0x11A3 ],
- [ 0xE8E8, 0x1109,0x1178 ],
- [ 0xE8F2, 0x1109,0x117A ],
- [ 0xE8F3, 0x1109,0x117B ],
- [ 0xE8F4, 0x1109,0x117C ],
- [ 0xE907, 0x1109,0x117D ],
- [ 0xE908, 0x1109,0x117E ],
- [ 0xE916, 0x1109,0x11A6 ],
- [ 0xE917, 0x1109,0x11A7 ],
- [ 0xE918, 0x1109,0x1182 ],
- [ 0xE91E, 0x1109,0x1187 ],
- [ 0xE920, 0x1109,0x1188 ],
- [ 0xE92E, 0x1109,0x1189 ],
- [ 0xE931, 0x1109,0xD7B5 ],
- [ 0xE933, 0x1109,0x118C ],
- [ 0xE93B, 0x1109,0x118E ],
- [ 0xE93E, 0x1109,0xD7B7 ],
- [ 0xE93F, 0x1109,0x118F ],
- [ 0xE940, 0x1109,0x1190 ],
- [ 0xE941, 0x1109,0x1191 ],
- [ 0xE947, 0x1109,0x1192 ],
- [ 0xE949, 0x1109,0xD7B8 ],
- [ 0xE94B, 0x1109,0x1193 ],
- [ 0xE94D, 0x1109,0x1194 ],
- [ 0xE95E, 0x1109,0x1195 ],
- [ 0xE95F, 0x1109,0x1196 ],
- [ 0xE96F, 0x1109,0x1198 ],
- [ 0xE970, 0x1109,0x1199 ],
- [ 0xE973, 0x1109,0xD7BD ],
- [ 0xE974, 0x1109,0xD7BE ],
- [ 0xE975, 0x1109,0xD7BF ],
- [ 0xE976, 0x1109,0xD7C0 ],
- [ 0xE977, 0x1109,0x119A ],
- [ 0xE978, 0x1109,0xD7C1 ],
- [ 0xE979, 0x1109,0xD7C2 ],
- [ 0xE97A, 0x1109,0x119B ],
- [ 0xE97B, 0x1109,0xD7C3 ],
- [ 0xE97D, 0x1109,0x119E ],
- [ 0xE999, 0x1109,0x11A1 ],
- [ 0xE9A5, 0x112D,0x1161 ],
- [ 0xE9B4, 0x112D,0x1162 ],
- [ 0xE9BB, 0x112D,0x1163 ],
- [ 0xE9BD, 0x112D,0x1164 ],
- [ 0xE9BF, 0x112D,0x1165 ],
- [ 0xE9CD, 0x112D,0x1166 ],
- [ 0xE9D5, 0x112D,0x1167 ],
- [ 0xE9E0, 0x112D,0x1168 ],
- [ 0xE9E1, 0x112D,0x1169 ],
- [ 0xE9F0, 0x112D,0x116A ],
- [ 0xE9F6, 0x112D,0x116B ],
- [ 0xE9FA, 0x112D,0x116C ],
- [ 0xEA01, 0x112D,0x116D ],
- [ 0xEA05, 0x112D,0x116E ],
- [ 0xEA16, 0x112D,0x116F ],
- [ 0xEA1D, 0x112D,0x1170 ],
- [ 0xEA20, 0x112D,0xD7B5 ],
- [ 0xEA21, 0x112D,0x118C ],
- [ 0xEA22, 0x112D,0x1171 ],
- [ 0xEA27, 0x112D,0x1172 ],
- [ 0xEA2B, 0x112D,0x118F ],
- [ 0xEA2D, 0x112D,0x1194 ],
- [ 0xEA2E, 0x112D,0x1173 ],
- [ 0xEA45, 0x112D,0x1174 ],
- [ 0xEA4B, 0x112D,0x1175 ],
- [ 0xEA57, 0x112D,0x1198 ],
- [ 0xEA58, 0x112D,0x119E ],
- [ 0xEA61, 0x112D,0x11A1 ],
- [ 0xEA6A, 0x112E,0x1161 ],
- [ 0xEA6C, 0x112E,0x1167 ],
- [ 0xEA6E, 0x112E,0x1169 ],
- [ 0xEA6F, 0x112E,0x1175 ],
- [ 0xEA70, 0x112E,0x119E ],
- [ 0xEA71, 0x112F,0x1161 ],
- [ 0xEA7F, 0x112F,0x1162 ],
- [ 0xEA88, 0x112F,0x1163 ],
- [ 0xEA8C, 0x112F,0x1164 ],
- [ 0xEA8D, 0x112F,0x1165 ],
- [ 0xEA9A, 0x112F,0x117C ],
- [ 0xEA9E, 0x112F,0x1166 ],
- [ 0xEAA5, 0x112F,0x1167 ],
- [ 0xEAAA, 0x112F,0x1168 ],
- [ 0xEAAB, 0x112F,0x1169 ],
- [ 0xEAB6, 0x112F,0x116A ],
- [ 0xEAB7, 0x112F,0x116B ],
- [ 0xEAB8, 0x112F,0x116C ],
- [ 0xEABB, 0x112F,0x116D ],
- [ 0xEABF, 0x112F,0x116E ],
- [ 0xEAC9, 0x112F,0x116F ],
- [ 0xEACA, 0x112F,0x1170 ],
- [ 0xEACB, 0x112F,0xD7B5 ],
- [ 0xEACC, 0x112F,0x118C ],
- [ 0xEACD, 0x112F,0x1171 ],
- [ 0xEAD2, 0x112F,0x1172 ],
- [ 0xEAD8, 0x112F,0x1194 ],
- [ 0xEAD9, 0x112F,0x1173 ],
- [ 0xEAE7, 0x112F,0x1174 ],
- [ 0xEAED, 0x112F,0x1175 ],
- [ 0xEAF7, 0x112F,0x1198 ],
- [ 0xEAF8, 0x112F,0x119E ],
- [ 0xEB04, 0x112F,0x11A1 ],
- [ 0xEB0D, 0x1130,0x1161 ],
- [ 0xEB0E, 0x1130,0x1162 ],
- [ 0xEB10, 0x1130,0x1163 ],
- [ 0xEB11, 0x1130,0x1165 ],
- [ 0xEB13, 0x1130,0x1166 ],
- [ 0xEB14, 0x1130,0x1167 ],
- [ 0xEB16, 0x1130,0x116E ],
- [ 0xEB17, 0x1130,0x1172 ],
- [ 0xEB1A, 0x1130,0x1173 ],
- [ 0xEB1E, 0x1130,0x1175 ],
- [ 0xEB20, 0x1131,0x1161 ],
- [ 0xEB22, 0x1131,0x1169 ],
- [ 0xEB23, 0x1131,0x1173 ],
- [ 0xEB25, 0x1131,0x119E ],
- [ 0xEB27, 0x1132,0x1161 ],
- [ 0xEB34, 0x1132,0x1162 ],
- [ 0xEB3B, 0x1132,0x1163 ],
- [ 0xEB3D, 0x1132,0x1165 ],
- [ 0xEB47, 0x1132,0x1166 ],
- [ 0xEB4C, 0x1132,0x1167 ],
- [ 0xEB55, 0x1132,0x1168 ],
- [ 0xEB56, 0x1132,0x1169 ],
- [ 0xEB62, 0x1132,0x116A ],
- [ 0xEB63, 0x1132,0x116B ],
- [ 0xEB64, 0x1132,0x116C ],
- [ 0xEB65, 0x1132,0x116D ],
- [ 0xEB66, 0x1132,0x116E ],
- [ 0xEB71, 0x1132,0x116F ],
- [ 0xEB72, 0x1132,0x1170 ],
- [ 0xEB73, 0x1132,0xD7B5 ],
- [ 0xEB74, 0x1132,0x118C ],
- [ 0xEB75, 0x1132,0x1171 ],
- [ 0xEB76, 0x1132,0x1172 ],
- [ 0xEB77, 0x1132,0x1194 ],
- [ 0xEB78, 0x1132,0x1173 ],
- [ 0xEB80, 0x1132,0x1174 ],
- [ 0xEB82, 0x1132,0x1175 ],
- [ 0xEB8D, 0x1132,0x1198 ],
- [ 0xEB8E, 0x1132,0x119E ],
- [ 0xEB97, 0x1132,0x11A1 ],
- [ 0xEBA0, 0x1133,0x1161 ],
- [ 0xEBA1, 0x1133,0x1162 ],
- [ 0xEBA2, 0x1133,0x116E ],
- [ 0xEBA4, 0x1133,0x1173 ],
- [ 0xEBA6, 0x1133,0x1174 ],
- [ 0xEBA7, 0x1133,0x1175 ],
- [ 0xEBB5, 0x110A,0x1188 ],
- [ 0xEBB9, 0x110A,0x1189 ],
- [ 0xEBBC, 0x110A,0xD7B5 ],
- [ 0xEBBE, 0x110A,0x118C ],
- [ 0xEBC3, 0x110A,0x1191 ],
- [ 0xEBC6, 0x110A,0x1192 ],
- [ 0xEBC8, 0x110A,0x1194 ],
- [ 0xEBD3, 0x110A,0x1198 ],
- [ 0xEBD4, 0x110A,0x119E ],
- [ 0xEBE1, 0x110A,0x11A1 ],
- [ 0xEBE4, 0xA975,0x1169 ],
- [ 0xEBE5, 0x1134,0x1173 ],
- [ 0xEBE6, 0x1135,0x1173 ],
- [ 0xEBE9, 0x1135,0x1175 ],
- [ 0xEBEB, 0x1136,0x1161 ],
- [ 0xEBF6, 0x1136,0x1162 ],
- [ 0xEBFD, 0x1136,0x1163 ],
- [ 0xEC01, 0x1136,0x1165 ],
- [ 0xEC09, 0x1136,0x1166 ],
- [ 0xEC0E, 0x1136,0x1167 ],
- [ 0xEC14, 0x1136,0x1168 ],
- [ 0xEC16, 0x1136,0x1169 ],
- [ 0xEC20, 0x1136,0x116A ],
- [ 0xEC22, 0x1136,0x116C ],
- [ 0xEC27, 0x1136,0x116D ],
- [ 0xEC2D, 0x1136,0x116E ],
- [ 0xEC34, 0x1136,0x116F ],
- [ 0xEC35, 0x1136,0x1170 ],
- [ 0xEC36, 0x1136,0x1171 ],
- [ 0xEC38, 0x1136,0x1172 ],
- [ 0xEC3C, 0x1136,0x1173 ],
- [ 0xEC43, 0x1136,0x1174 ],
- [ 0xEC45, 0x1136,0x1175 ],
- [ 0xEC51, 0x1136,0x119E ],
- [ 0xEC59, 0x1136,0x11A1 ],
- [ 0xEC5E, 0x1137,0x1169 ],
- [ 0xEC5F, 0x1137,0x1175 ],
- [ 0xEC60, 0x1137,0x119E ],
- [ 0xEC63, 0x1138,0x1161 ],
- [ 0xEC65, 0x1138,0x1165 ],
- [ 0xEC68, 0x1138,0x1167 ],
- [ 0xEC69, 0x1138,0x1169 ],
- [ 0xEC6E, 0x1138,0x116A ],
- [ 0xEC6F, 0x1138,0x116B ],
- [ 0xEC70, 0x1138,0x116C ],
- [ 0xEC73, 0x1138,0x116E ],
- [ 0xEC74, 0x1138,0x116F ],
- [ 0xEC75, 0x1138,0x1173 ],
- [ 0xEC77, 0x1138,0x1174 ],
- [ 0xEC78, 0x1138,0x1175 ],
- [ 0xEC79, 0x1138,0x119E ],
- [ 0xEC7A, 0x1139,0x1161 ],
- [ 0xEC7C, 0x1139,0x1165 ],
- [ 0xEC7E, 0x1139,0x1166 ],
- [ 0xEC7F, 0x1139,0x1169 ],
- [ 0xEC81, 0x1139,0x116E ],
- [ 0xEC83, 0x1139,0x1171 ],
- [ 0xEC84, 0x1139,0x1173 ],
- [ 0xEC88, 0x1139,0x1175 ],
- [ 0xEC8A, 0x1139,0x119E ],
- [ 0xEC8D, 0x113A,0x1167 ],
- [ 0xEC8F, 0x113A,0x116E ],
- [ 0xEC91, 0x113A,0x1175 ],
- [ 0xEC92, 0x113A,0x119E ],
- [ 0xEC94, 0x113B,0x1165 ],
- [ 0xEC96, 0x113B,0x1167 ],
- [ 0xEC97, 0x113B,0x1173 ],
- [ 0xEC99, 0x113C,0x1161 ],
- [ 0xEC9C, 0x113C,0x1162 ],
- [ 0xEC9D, 0x113C,0x1163 ],
- [ 0xECA1, 0x113C,0x1165 ],
- [ 0xECA3, 0x113C,0x1167 ],
- [ 0xECA5, 0x113C,0x1168 ],
- [ 0xECA6, 0x113C,0x116E ],
- [ 0xECA9, 0x113C,0x1171 ],
- [ 0xECAA, 0x113C,0x1172 ],
- [ 0xECAC, 0x113C,0x1191 ],
- [ 0xECAE, 0x113C,0x1173 ],
- [ 0xECB1, 0x113C,0x1175 ],
- [ 0xECB3, 0x113D,0x1163 ],
- [ 0xECB6, 0x113D,0x1167 ],
- [ 0xECB8, 0x113D,0x116E ],
- [ 0xECB9, 0x113D,0x1171 ],
- [ 0xECBA, 0x113D,0x1172 ],
- [ 0xECBD, 0x113D,0x1191 ],
- [ 0xECBF, 0x113D,0x1194 ],
- [ 0xECC0, 0x113D,0x1173 ],
- [ 0xECC2, 0x113D,0x1175 ],
- [ 0xECC6, 0x113E,0x1161 ],
- [ 0xECC9, 0x113E,0x1162 ],
- [ 0xECCA, 0x113E,0x1163 ],
- [ 0xECCD, 0x113E,0x1167 ],
- [ 0xECCF, 0x113E,0x1169 ],
- [ 0xECD0, 0x113E,0x116A ],
- [ 0xECD1, 0x113E,0x116B ],
- [ 0xECD2, 0x113E,0x116E ],
- [ 0xECD5, 0x113E,0x1171 ],
- [ 0xECD6, 0x113E,0x1172 ],
- [ 0xECD8, 0x113E,0x1191 ],
- [ 0xECDA, 0x113E,0x1173 ],
- [ 0xECDD, 0x113E,0x1175 ],
- [ 0xECE1, 0x113F,0x1163 ],
- [ 0xECE3, 0x113F,0x1167 ],
- [ 0xECE5, 0x113F,0x116E ],
- [ 0xECE6, 0x113F,0x1171 ],
- [ 0xECE7, 0x113F,0x1172 ],
- [ 0xECEB, 0x113F,0x1173 ],
- [ 0xECED, 0x113F,0x1175 ],
- [ 0xECF0, 0x1140,0x1161 ],
- [ 0xECFB, 0x1140,0x1162 ],
- [ 0xED01, 0x1140,0x1163 ],
- [ 0xED0B, 0x1140,0x1178 ],
- [ 0xED0C, 0x1140,0x1165 ],
- [ 0xED18, 0x1140,0x117B ],
- [ 0xED19, 0x1140,0x1166 ],
- [ 0xED1C, 0x1140,0x1167 ],
- [ 0xED27, 0x1140,0x1168 ],
- [ 0xED2D, 0x1140,0x1169 ],
- [ 0xED36, 0x1140,0x116A ],
- [ 0xED37, 0x1140,0x116B ],
- [ 0xED38, 0x1140,0x116C ],
- [ 0xED39, 0x1140,0x116D ],
- [ 0xED41, 0x1140,0x116E ],
- [ 0xED4E, 0x1140,0x1189 ],
- [ 0xED50, 0x1140,0x116F ],
- [ 0xED51, 0x1140,0x1170 ],
- [ 0xED52, 0x1140,0xD7B5 ],
- [ 0xED53, 0x1140,0x118C ],
- [ 0xED54, 0x1140,0x1171 ],
- [ 0xED56, 0x1140,0x1172 ],
- [ 0xED61, 0x1140,0x118F ],
- [ 0xED63, 0x1140,0x1191 ],
- [ 0xED67, 0x1140,0x1192 ],
- [ 0xED69, 0x1140,0x1194 ],
- [ 0xED6B, 0x1140,0x1173 ],
- [ 0xED7C, 0x1140,0x1174 ],
- [ 0xED7F, 0x1140,0x1175 ],
- [ 0xED8E, 0x1140,0x1198 ],
- [ 0xED8F, 0x1140,0x119E ],
- [ 0xEDA0, 0x1140,0x11A1 ],
- [ 0xEDBA, 0x110B,0x1176 ],
- [ 0xEDC8, 0x110B,0x1178 ],
- [ 0xEDC9, 0x110B,0x11A4 ],
- [ 0xEDD8, 0x110B,0x117A ],
- [ 0xEDD9, 0x110B,0x117C ],
- [ 0xEDFA, 0x110B,0x117D ],
- [ 0xEDFB, 0x110B,0x117E ],
- [ 0xEE0F, 0x110B,0x117F ],
- [ 0xEE12, 0x110B,0x1182 ],
- [ 0xEE1A, 0x110B,0xD7B2 ],
- [ 0xEE1B, 0x110B,0xD7B3 ],
- [ 0xEE1D, 0x110B,0xD7B4 ],
- [ 0xEE1F, 0x110B,0x1187 ],
- [ 0xEE20, 0x110B,0x1188 ],
- [ 0xEE34, 0x110B,0x1189 ],
- [ 0xEE38, 0x110B,0x118A ],
- [ 0xEE3E, 0x110B,0x118B ],
- [ 0xEE40, 0x110B,0xD7B5 ],
- [ 0xEE41, 0x110B,0x118C ],
- [ 0xEE48, 0x110B,0x118E ],
- [ 0xEE4B, 0x110B,0x118F ],
- [ 0xEE4C, 0x110B,0x1190 ],
- [ 0xEE4E, 0x110B,0x1191 ],
- [ 0xEE55, 0x110B,0x1192 ],
- [ 0xEE58, 0x110B,0x1193 ],
- [ 0xEE59, 0x110B,0x1194 ],
- [ 0xEE6E, 0x110B,0x1195 ],
- [ 0xEE6F, 0x110B,0x1196 ],
- [ 0xEE82, 0x110B,0x1198 ],
- [ 0xEE83, 0x110B,0x119A ],
- [ 0xEE84, 0x110B,0xD7C1 ],
- [ 0xEE85, 0x110B,0x119B ],
- [ 0xEE86, 0x110B,0x119C ],
- [ 0xEE88, 0x110B,0x119E ],
- [ 0xEE9E, 0x110B,0x119F ],
- [ 0xEEA4, 0x110B,0x11A1 ],
- [ 0xEEAE, 0x110B,0x11A2 ],
- [ 0xEEB0, 0x1141,0x1161 ],
- [ 0xEEB2, 0x1141,0x1162 ],
- [ 0xEEB3, 0x1141,0x1163 ],
- [ 0xEEB5, 0x1141,0x1165 ],
- [ 0xEEB6, 0x1141,0x1166 ],
- [ 0xEEB7, 0x1141,0x1167 ],
- [ 0xEEB8, 0x1141,0x1168 ],
- [ 0xEEBA, 0x1141,0x1169 ],
- [ 0xEEBD, 0x1141,0x116A ],
- [ 0xEEBF, 0x1141,0x116B ],
- [ 0xEEC0, 0x1141,0x116C ],
- [ 0xEEC1, 0x1141,0x116D ],
- [ 0xEEC2, 0x1141,0x116E ],
- [ 0xEEC4, 0x1141,0x116F ],
- [ 0xEEC5, 0x1141,0x1170 ],
- [ 0xEEC6, 0x1141,0xD7B5 ],
- [ 0xEEC7, 0x1141,0x118C ],
- [ 0xEEC8, 0x1141,0x1171 ],
- [ 0xEEC9, 0x1141,0x1172 ],
- [ 0xEECA, 0x1141,0x1194 ],
- [ 0xEECB, 0x1141,0x1173 ],
- [ 0xEECC, 0x1141,0x1174 ],
- [ 0xEECD, 0x1141,0x1175 ],
- [ 0xEECF, 0x1141,0x1198 ],
- [ 0xEED0, 0x1141,0x119E ],
- [ 0xEED1, 0x1141,0x11A1 ],
- [ 0xEED2, 0x1142,0x1161 ],
- [ 0xEED4, 0x1142,0x1165 ],
- [ 0xEED6, 0x1142,0x1166 ],
- [ 0xEED8, 0x1142,0x1169 ],
- [ 0xEEDB, 0x1142,0x1173 ],
- [ 0xEEDD, 0x1142,0x1174 ],
- [ 0xEEDE, 0x1142,0x1175 ],
- [ 0xEEE0, 0x1142,0x119E ],
- [ 0xEEE2, 0xA976,0x1165 ],
- [ 0xEEE3, 0xA976,0x1169 ],
- [ 0xEEE4, 0xA976,0x1175 ],
- [ 0xEEE5, 0x1143,0x116E ],
- [ 0xEEE6, 0x1143,0x119E ],
- [ 0xEEE7, 0x1143,0x11A1 ],
- [ 0xEEE8, 0x1144,0x1161 ],
- [ 0xEEEC, 0x1144,0x1162 ],
- [ 0xEEEF, 0x1144,0x1165 ],
- [ 0xEEF2, 0x1144,0x1166 ],
- [ 0xEEF6, 0x1144,0x1167 ],
- [ 0xEEF7, 0x1144,0x1168 ],
- [ 0xEEF9, 0x1144,0x1169 ],
- [ 0xEEFD, 0x1144,0x116A ],
- [ 0xEEFF, 0x1144,0x116D ],
- [ 0xEF00, 0x1144,0x116E ],
- [ 0xEF03, 0x1144,0x116F ],
- [ 0xEF04, 0x1144,0x1170 ],
- [ 0xEF06, 0x1144,0x1171 ],
- [ 0xEF08, 0x1144,0x1172 ],
- [ 0xEF09, 0x1144,0x1173 ],
- [ 0xEF0C, 0x1144,0x1174 ],
- [ 0xEF0D, 0x1144,0x1175 ],
- [ 0xEF13, 0x1144,0x119E ],
- [ 0xEF14, 0x1144,0x11A1 ],
- [ 0xEF15, 0x1145,0x1161 ],
- [ 0xEF18, 0x1145,0x1176 ],
- [ 0xEF19, 0x1145,0x1162 ],
- [ 0xEF1A, 0x1145,0x1165 ],
- [ 0xEF1F, 0x1145,0x117B ],
- [ 0xEF20, 0x1145,0x1166 ],
- [ 0xEF21, 0x1145,0x1167 ],
- [ 0xEF22, 0x1145,0x1168 ],
- [ 0xEF24, 0x1145,0x1169 ],
- [ 0xEF26, 0x1145,0x116E ],
- [ 0xEF28, 0x1145,0x1189 ],
- [ 0xEF2B, 0x1145,0x118A ],
- [ 0xEF2C, 0x1145,0x116F ],
- [ 0xEF2D, 0x1145,0x1170 ],
- [ 0xEF2E, 0x1145,0x1172 ],
- [ 0xEF2F, 0x1145,0x118E ],
- [ 0xEF31, 0x1145,0x1191 ],
- [ 0xEF32, 0x1145,0x1192 ],
- [ 0xEF33, 0x1145,0x1194 ],
- [ 0xEF34, 0x1145,0x1173 ],
- [ 0xEF36, 0x1145,0x1174 ],
- [ 0xEF38, 0x1145,0x1175 ],
- [ 0xEF3A, 0x1145,0x119E ],
- [ 0xEF3C, 0x1146,0x1161 ],
- [ 0xEF3D, 0x1146,0x1162 ],
- [ 0xEF3E, 0x1146,0x1163 ],
- [ 0xEF3F, 0x1146,0x1165 ],
- [ 0xEF40, 0x1146,0x1166 ],
- [ 0xEF41, 0x1146,0x1167 ],
- [ 0xEF42, 0x1146,0x1168 ],
- [ 0xEF43, 0x1146,0x1169 ],
- [ 0xEF44, 0x1146,0x116A ],
- [ 0xEF45, 0x1146,0x116B ],
- [ 0xEF46, 0x1146,0x116C ],
- [ 0xEF47, 0x1146,0x116D ],
- [ 0xEF48, 0x1146,0x116E ],
- [ 0xEF49, 0x1146,0x116F ],
- [ 0xEF4A, 0x1146,0x1170 ],
- [ 0xEF4B, 0x1146,0xD7B5 ],
- [ 0xEF4C, 0x1146,0x118C ],
- [ 0xEF4D, 0x1146,0x1171 ],
- [ 0xEF4E, 0x1146,0x1172 ],
- [ 0xEF4F, 0x1146,0x1194 ],
- [ 0xEF50, 0x1146,0x1173 ],
- [ 0xEF51, 0x1146,0x1174 ],
- [ 0xEF52, 0x1146,0x1175 ],
- [ 0xEF53, 0x1146,0x1198 ],
- [ 0xEF54, 0x1146,0x119E ],
- [ 0xEF55, 0x1146,0x11A1 ],
- [ 0xEF56, 0x1147,0x1163 ],
- [ 0xEF58, 0x1147,0x1167 ],
- [ 0xEF5B, 0x1147,0x1168 ],
- [ 0xEF5D, 0x1147,0x116D ],
- [ 0xEF62, 0x1147,0x116E ],
- [ 0xEF63, 0x1147,0x116F ],
- [ 0xEF64, 0x1147,0x1172 ],
- [ 0xEF67, 0x1147,0x118E ],
- [ 0xEF69, 0x1147,0x1175 ],
- [ 0xEF6B, 0x1148,0x1161 ],
- [ 0xEF6E, 0x1148,0x1176 ],
- [ 0xEF6F, 0x1148,0x1162 ],
- [ 0xEF70, 0x1148,0x1165 ],
- [ 0xEF74, 0x1148,0x117B ],
- [ 0xEF75, 0x1148,0x1169 ],
- [ 0xEF76, 0x1148,0x116D ],
- [ 0xEF77, 0x1148,0x116E ],
- [ 0xEF7A, 0x1148,0x1189 ],
- [ 0xEF7C, 0x1148,0x116F ],
- [ 0xEF7D, 0x1148,0x1170 ],
- [ 0xEF7E, 0x1148,0x1171 ],
- [ 0xEF7F, 0x1148,0x1172 ],
- [ 0xEF80, 0x1148,0x1194 ],
- [ 0xEF81, 0x1148,0x1173 ],
- [ 0xEF82, 0x1148,0x1175 ],
- [ 0xEF83, 0x1149,0x1161 ],
- [ 0xEF86, 0x1149,0x1162 ],
- [ 0xEF87, 0x1149,0x1165 ],
- [ 0xEF8A, 0x1149,0x116E ],
- [ 0xEF8D, 0x1149,0x1189 ],
- [ 0xEF8F, 0x1149,0x116F ],
- [ 0xEF90, 0x1149,0x1170 ],
- [ 0xEF91, 0x1149,0x1172 ],
- [ 0xEF92, 0x1149,0x118E ],
- [ 0xEF94, 0x1149,0x1194 ],
- [ 0xEF95, 0x1149,0x1173 ],
- [ 0xEF96, 0x114A,0x1173 ],
- [ 0xEF97, 0x114B,0x1161 ],
- [ 0xEF9D, 0x114B,0x1162 ],
- [ 0xEFA0, 0x114B,0x1165 ],
- [ 0xEFA5, 0x114B,0x1166 ],
- [ 0xEFAA, 0x114B,0x1169 ],
- [ 0xEFB1, 0x114B,0x116A ],
- [ 0xEFB2, 0x114B,0x116B ],
- [ 0xEFB4, 0x114B,0x116E ],
- [ 0xEFB9, 0x114B,0x1189 ],
- [ 0xEFBB, 0x114B,0x116F ],
- [ 0xEFBD, 0x114B,0x1170 ],
- [ 0xEFBF, 0x114B,0x1171 ],
- [ 0xEFC3, 0x114B,0x1172 ],
- [ 0xEFC5, 0x114B,0x1173 ],
- [ 0xEFC7, 0x114B,0x1175 ],
- [ 0xEFCE, 0x114B,0x119E ],
- [ 0xEFCF, 0x114B,0x11A1 ],
- [ 0xEFD0, 0xA977,0x1169 ],
- [ 0xEFD1, 0xA977,0x116E ],
- [ 0xEFD2, 0x114C,0x1161 ],
- [ 0xEFDD, 0x114C,0x1162 ],
- [ 0xEFE0, 0x114C,0x1163 ],
- [ 0xEFE5, 0x114C,0x1164 ],
- [ 0xEFE7, 0x114C,0x1165 ],
- [ 0xEFF2, 0x114C,0x1166 ],
- [ 0xEFF8, 0x114C,0x1167 ],
- [ 0xF104, 0x114C,0x1168 ],
- [ 0xF107, 0x114C,0x1169 ],
- [ 0xF112, 0x114C,0x116A ],
- [ 0xF11B, 0x114C,0x116B ],
- [ 0xF11D, 0x114C,0x116C ],
- [ 0xF121, 0x114C,0x116D ],
- [ 0xF125, 0x114C,0x1184 ],
- [ 0xF126, 0x114C,0x1185 ],
- [ 0xF128, 0x114C,0x116E ],
- [ 0xF130, 0x114C,0x116F ],
- [ 0xF136, 0x114C,0x1170 ],
- [ 0xF137, 0x114C,0x1171 ],
- [ 0xF13C, 0x114C,0x1172 ],
- [ 0xF143, 0x114C,0x1191 ],
- [ 0xF148, 0x114C,0x1194 ],
- [ 0xF149, 0x114C,0x1173 ],
- [ 0xF152, 0x114C,0x1174 ],
- [ 0xF154, 0x114C,0x1175 ],
- [ 0xF15C, 0x114C,0x119E ],
- [ 0xF162, 0x114C,0x11A1 ],
- [ 0xF172, 0x110C,0x1176 ],
- [ 0xF17C, 0x110C,0x1178 ],
- [ 0xF17D, 0x110C,0x11A4 ],
- [ 0xF18A, 0x110C,0x117B ],
- [ 0xF18B, 0x110C,0x117C ],
- [ 0xF19B, 0x110C,0x11A5 ],
- [ 0xF19D, 0x110C,0x117D ],
- [ 0xF19E, 0x110C,0x117E ],
- [ 0xF1AE, 0x110C,0x1187 ],
- [ 0xF1AF, 0x110C,0x1188 ],
- [ 0xF1BA, 0x110C,0x1189 ],
- [ 0xF1BC, 0x110C,0x118A ],
- [ 0xF1BD, 0x110C,0xD7B5 ],
- [ 0xF1C1, 0x110C,0x118C ],
- [ 0xF1C7, 0x110C,0x118E ],
- [ 0xF1C9, 0x110C,0x118F ],
- [ 0xF1CC, 0x110C,0x1190 ],
- [ 0xF1CD, 0x110C,0x1191 ],
- [ 0xF1D2, 0x110C,0x1192 ],
- [ 0xF1D6, 0x110C,0x1194 ],
- [ 0xF1E3, 0x110C,0x1195 ],
- [ 0xF1E4, 0x110C,0x1196 ],
- [ 0xF1F4, 0x110C,0x1198 ],
- [ 0xF1F5, 0x110C,0x1199 ],
- [ 0xF1F7, 0x110C,0xD7BF ],
- [ 0xF1F8, 0x110C,0xD7C0 ],
- [ 0xF1F9, 0x110C,0x119A ],
- [ 0xF1FB, 0x110C,0x119B ],
- [ 0xF1FC, 0x110C,0x119E ],
- [ 0xF210, 0x110C,0xD7C5 ],
- [ 0xF212, 0x110C,0x11A1 ],
- [ 0xF21C, 0x114D,0x1173 ],
- [ 0xF21E, 0x114D,0x1175 ],
- [ 0xF233, 0x110D,0x117F ],
- [ 0xF23E, 0x110D,0x1191 ],
- [ 0xF243, 0x110D,0x1194 ],
- [ 0xF250, 0x110D,0x119E ],
- [ 0xF25A, 0x110D,0x11A1 ],
- [ 0xF263, 0xA978,0x1165 ],
- [ 0xF264, 0xA978,0x1166 ],
- [ 0xF268, 0x114E,0x1161 ],
- [ 0xF26C, 0x114E,0x1162 ],
- [ 0xF26D, 0x114E,0x1163 ],
- [ 0xF26F, 0x114E,0x1165 ],
- [ 0xF271, 0x114E,0x1167 ],
- [ 0xF274, 0x114E,0x1168 ],
- [ 0xF275, 0x114E,0x1169 ],
- [ 0xF276, 0x114E,0x116A ],
- [ 0xF277, 0x114E,0x116D ],
- [ 0xF278, 0x114E,0x1184 ],
- [ 0xF279, 0x114E,0x116E ],
- [ 0xF27C, 0x114E,0x1171 ],
- [ 0xF27D, 0x114E,0x1172 ],
- [ 0xF280, 0x114E,0x1191 ],
- [ 0xF282, 0x114E,0x1173 ],
- [ 0xF286, 0x114E,0x1175 ],
- [ 0xF28B, 0x114F,0x1161 ],
- [ 0xF290, 0x114F,0x1162 ],
- [ 0xF291, 0x114F,0x1163 ],
- [ 0xF294, 0x114F,0x1165 ],
- [ 0xF296, 0x114F,0x1167 ],
- [ 0xF298, 0x114F,0x1168 ],
- [ 0xF299, 0x114F,0x116E ],
- [ 0xF29A, 0x114F,0x1171 ],
- [ 0xF29B, 0x114F,0x1172 ],
- [ 0xF29D, 0x114F,0x1191 ],
- [ 0xF29F, 0x114F,0x1173 ],
- [ 0xF2A2, 0x114F,0x1175 ],
- [ 0xF2A4, 0x114F,0x119E ],
- [ 0xF2A5, 0x114F,0x11A1 ],
- [ 0xF2A6, 0x1150,0x1161 ],
- [ 0xF2AC, 0x1150,0x1162 ],
- [ 0xF2AD, 0x1150,0x1163 ],
- [ 0xF2B1, 0x1150,0x1167 ],
- [ 0xF2B3, 0x1150,0x1169 ],
- [ 0xF2B4, 0x1150,0x116A ],
- [ 0xF2B6, 0x1150,0x116E ],
- [ 0xF2B9, 0x1150,0x1172 ],
- [ 0xF2BD, 0x1150,0x1191 ],
- [ 0xF2BF, 0x1150,0x1173 ],
- [ 0xF2C2, 0x1150,0x1175 ],
- [ 0xF2C6, 0x1151,0x1161 ],
- [ 0xF2C9, 0x1151,0x1162 ],
- [ 0xF2CA, 0x1151,0x1163 ],
- [ 0xF2CF, 0x1151,0x1167 ],
- [ 0xF2D1, 0x1151,0x116E ],
- [ 0xF2D2, 0x1151,0x1171 ],
- [ 0xF2D3, 0x1151,0x1172 ],
- [ 0xF2D5, 0x1151,0x1191 ],
- [ 0xF2D7, 0x1151,0x1173 ],
- [ 0xF2DA, 0x1151,0x1175 ],
- [ 0xF2E4, 0x110E,0x1176 ],
- [ 0xF2E9, 0x110E,0x1178 ],
- [ 0xF2EB, 0x110E,0x11A4 ],
- [ 0xF2EE, 0x110E,0x117C ],
- [ 0xF2F8, 0x110E,0x117D ],
- [ 0xF2F9, 0x110E,0x117E ],
- [ 0xF301, 0x110E,0x1182 ],
- [ 0xF304, 0x110E,0x1187 ],
- [ 0xF305, 0x110E,0x1188 ],
- [ 0xF30C, 0x110E,0x1189 ],
- [ 0xF30F, 0x110E,0x118A ],
- [ 0xF311, 0x110E,0xD7B5 ],
- [ 0xF312, 0x110E,0x118C ],
- [ 0xF319, 0x110E,0x118E ],
- [ 0xF31B, 0x110E,0x118F ],
- [ 0xF31D, 0x110E,0x1190 ],
- [ 0xF31E, 0x110E,0x1191 ],
- [ 0xF323, 0x110E,0x1192 ],
- [ 0xF325, 0x110E,0x1194 ],
- [ 0xF32F, 0x110E,0x1195 ],
- [ 0xF330, 0x110E,0x1196 ],
- [ 0xF339, 0x110E,0x1198 ],
- [ 0xF33A, 0x110E,0x1199 ],
- [ 0xF33D, 0x110E,0xD7BF ],
- [ 0xF33E, 0x110E,0xD7C0 ],
- [ 0xF33F, 0x110E,0xD7C2 ],
- [ 0xF340, 0x110E,0x119B ],
- [ 0xF341, 0x110E,0x119E ],
- [ 0xF353, 0x110E,0x11A1 ],
- [ 0xF35B, 0x1152,0x116E ],
- [ 0xF35C, 0x1152,0x116F ],
- [ 0xF35D, 0x1153,0x1175 ],
- [ 0xF35F, 0x1154,0x1161 ],
- [ 0xF361, 0x1154,0x1176 ],
- [ 0xF362, 0x1154,0x1162 ],
- [ 0xF363, 0x1154,0x1165 ],
- [ 0xF365, 0x1154,0x1167 ],
- [ 0xF367, 0x1154,0x1168 ],
- [ 0xF368, 0x1154,0x1169 ],
- [ 0xF369, 0x1154,0x116D ],
- [ 0xF36A, 0x1154,0xD7B2 ],
- [ 0xF36B, 0x1154,0x1184 ],
- [ 0xF36C, 0x1154,0x116E ],
- [ 0xF36F, 0x1154,0x1171 ],
- [ 0xF370, 0x1154,0x1172 ],
- [ 0xF372, 0x1154,0x1191 ],
- [ 0xF374, 0x1154,0x1173 ],
- [ 0xF375, 0x1154,0x1175 ],
- [ 0xF37A, 0x1155,0x1161 ],
- [ 0xF37F, 0x1155,0x1162 ],
- [ 0xF380, 0x1155,0x1163 ],
- [ 0xF382, 0x1155,0x1167 ],
- [ 0xF384, 0x1155,0x1169 ],
- [ 0xF385, 0x1155,0x116A ],
- [ 0xF387, 0x1155,0x116B ],
- [ 0xF388, 0x1155,0x116E ],
- [ 0xF389, 0x1155,0x1171 ],
- [ 0xF38A, 0x1155,0x1172 ],
- [ 0xF38F, 0x1155,0x1191 ],
- [ 0xF391, 0x1155,0x1173 ],
- [ 0xF394, 0x1155,0x1175 ],
- [ 0xF39A, 0x1155,0x119B ],
- [ 0xF3A0, 0x110F,0x1176 ],
- [ 0xF3A4, 0x110F,0x1178 ],
- [ 0xF3A7, 0x110F,0x117A ],
- [ 0xF3A8, 0x110F,0x117B ],
- [ 0xF3AD, 0x110F,0x117E ],
- [ 0xF3B3, 0x110F,0x1182 ],
- [ 0xF3B7, 0x110F,0x1187 ],
- [ 0xF3BC, 0x110F,0x1189 ],
- [ 0xF3BF, 0x110F,0x118A ],
- [ 0xF3C2, 0x110F,0xD7B5 ],
- [ 0xF3C4, 0x110F,0x118C ],
- [ 0xF3C7, 0x110F,0x118F ],
- [ 0xF3C8, 0x110F,0x1190 ],
- [ 0xF3C9, 0x110F,0x1191 ],
- [ 0xF3D0, 0x110F,0x1192 ],
- [ 0xF3D2, 0x110F,0x1194 ],
- [ 0xF3D7, 0x110F,0x1195 ],
- [ 0xF3D8, 0x110F,0x1196 ],
- [ 0xF3DD, 0x110F,0x1198 ],
- [ 0xF3DE, 0x110F,0x1199 ],
- [ 0xF3E1, 0x110F,0xD7BD ],
- [ 0xF3E2, 0x110F,0xD7BF ],
- [ 0xF3E3, 0x110F,0xD7C0 ],
- [ 0xF3E4, 0x110F,0x119A ],
- [ 0xF3E5, 0x110F,0xD7C2 ],
- [ 0xF3E6, 0x110F,0x119B ],
- [ 0xF3E8, 0x110F,0xD7C3 ],
- [ 0xF3EA, 0x110F,0x119E ],
- [ 0xF3F3, 0x110F,0x11A1 ],
- [ 0xF3FF, 0x1110,0x1176 ],
- [ 0xF400, 0x1110,0x1177 ],
- [ 0xF403, 0x1110,0x1178 ],
- [ 0xF408, 0x1110,0x117B ],
- [ 0xF417, 0x1110,0x1182 ],
- [ 0xF41C, 0x1110,0x1188 ],
- [ 0xF422, 0x1110,0x1189 ],
- [ 0xF425, 0x1110,0xD7B5 ],
- [ 0xF426, 0x1110,0x118C ],
- [ 0xF427, 0x1110,0x118D ],
- [ 0xF42B, 0x1110,0x1194 ],
- [ 0xF431, 0x1110,0x1195 ],
- [ 0xF432, 0x1110,0x1196 ],
- [ 0xF437, 0x1110,0x1198 ],
- [ 0xF438, 0x1110,0x1199 ],
- [ 0xF43A, 0x1110,0xD7BF ],
- [ 0xF43B, 0x1110,0xD7C0 ],
- [ 0xF43C, 0x1110,0x119E ],
- [ 0xF448, 0x1110,0x11A1 ],
- [ 0xF451, 0xA979,0x116E ],
- [ 0xF452, 0xA979,0x119E ],
- [ 0xF45C, 0x1111,0x1176 ],
- [ 0xF45F, 0x1111,0x1178 ],
- [ 0xF462, 0x1111,0x117A ],
- [ 0xF463, 0x1111,0x117C ],
- [ 0xF46E, 0x1111,0x1182 ],
- [ 0xF471, 0x1111,0x1188 ],
- [ 0xF478, 0x1111,0xD7B5 ],
- [ 0xF479, 0x1111,0x118C ],
- [ 0xF47D, 0x1111,0x118E ],
- [ 0xF47F, 0x1111,0x1194 ],
- [ 0xF482, 0x1111,0x1196 ],
- [ 0xF488, 0x1111,0x1198 ],
- [ 0xF489, 0x1111,0x1199 ],
- [ 0xF48B, 0x1111,0xD7BD ],
- [ 0xF48C, 0x1111,0xD7BF ],
- [ 0xF48D, 0x1111,0xD7C0 ],
- [ 0xF48E, 0x1111,0x119E ],
- [ 0xF49E, 0x1111,0x119F ],
- [ 0xF4A0, 0x1111,0x11A1 ],
- [ 0xF4A9, 0x1156,0x1161 ],
- [ 0xF4AB, 0xA97A,0x1175 ],
- [ 0xF4AD, 0x1157,0x116E ],
- [ 0xF4B8, 0x1112,0x1176 ],
- [ 0xF4B9, 0x1112,0x1177 ],
- [ 0xF4C1, 0x1112,0x1178 ],
- [ 0xF4C8, 0x1112,0x117A ],
- [ 0xF4C9, 0x1112,0x117B ],
- [ 0xF4CA, 0x1112,0x117C ],
- [ 0xF4DF, 0x1112,0x11A6 ],
- [ 0xF4E0, 0x1112,0x117F ],
- [ 0xF4E3, 0x1112,0x1180 ],
- [ 0xF4E4, 0x1112,0x1182 ],
- [ 0xF4E9, 0x1112,0xD7B2 ],
- [ 0xF4EB, 0x1112,0x1184 ],
- [ 0xF4ED, 0x1112,0x1187 ],
- [ 0xF4EE, 0x1112,0x1188 ],
- [ 0xF4F6, 0x1112,0x1189 ],
- [ 0xF4F9, 0x1112,0x118A ],
- [ 0xF4FD, 0x1112,0x118B ],
- [ 0xF500, 0x1112,0xD7B5 ],
- [ 0xF501, 0x1112,0x118C ],
- [ 0xF507, 0x1112,0x118E ],
- [ 0xF509, 0x1112,0x1191 ],
- [ 0xF511, 0x1112,0x1192 ],
- [ 0xF514, 0x1112,0x1194 ],
- [ 0xF51C, 0x1112,0xD7B9 ],
- [ 0xF51D, 0x1112,0xD7BC ],
- [ 0xF51E, 0x1112,0x1195 ],
- [ 0xF51F, 0x1112,0x1196 ],
- [ 0xF52D, 0x1112,0x1198 ],
- [ 0xF52E, 0x1112,0x1199 ],
- [ 0xF531, 0x1112,0xD7BF ],
- [ 0xF532, 0x1112,0xD7C0 ],
- [ 0xF533, 0x1112,0xD7C2 ],
- [ 0xF534, 0x1112,0x119B ],
- [ 0xF535, 0x1112,0xD7C3 ],
- [ 0xF537, 0x1112,0x119E ],
- [ 0xF54E, 0x1112,0x119F ],
- [ 0xF550, 0x1112,0x11A1 ],
- [ 0xF55D, 0xA97B,0x1163 ],
- [ 0xF55F, 0xA97B,0x1169 ],
- [ 0xF560, 0xA97B,0x116A ],
- [ 0xF562, 0xA97B,0x116E ],
- [ 0xF563, 0xA97B,0x116F ],
- [ 0xF564, 0xA97B,0x1170 ],
- [ 0xF565, 0xA97B,0x1171 ],
- [ 0xF566, 0xA97B,0x1172 ],
- [ 0xF568, 0xA97B,0x118E ],
- [ 0xF56A, 0xA97B,0x118F ],
- [ 0xF56B, 0xA97B,0x1190 ],
- [ 0xF56C, 0xA97B,0x1194 ],
- [ 0xF56E, 0xA97B,0x1175 ],
- [ 0xF571, 0x1158,0x1161 ],
- [ 0xF57C, 0x1158,0x1162 ],
- [ 0xF57F, 0x1158,0x1163 ],
- [ 0xF587, 0x1158,0x1164 ],
- [ 0xF588, 0x1158,0x1165 ],
- [ 0xF58E, 0x1158,0x1166 ],
- [ 0xF590, 0x1158,0x1167 ],
- [ 0xF599, 0x1158,0x1168 ],
- [ 0xF59B, 0x1158,0x1169 ],
- [ 0xF5A4, 0x1158,0x116A ],
- [ 0xF5AC, 0x1158,0x116B ],
- [ 0xF5AE, 0x1158,0x116C ],
- [ 0xF5B2, 0x1158,0x116D ],
- [ 0xF5B5, 0x1158,0x116E ],
- [ 0xF5BE, 0x1158,0x116F ],
- [ 0xF5C1, 0x1158,0x1171 ],
- [ 0xF5C3, 0x1158,0x1172 ],
- [ 0xF5C5, 0x1158,0x118F ],
- [ 0xF5C7, 0x1158,0x1191 ],
- [ 0xF5CD, 0x1158,0x1192 ],
- [ 0xF5CF, 0x1158,0x1173 ],
- [ 0xF5D6, 0x1158,0x1195 ],
- [ 0xF5D7, 0x1158,0x1174 ],
- [ 0xF5DC, 0x1158,0x1175 ],
- [ 0xF5E2, 0x1158,0x119E ],
- [ 0xF5E4, 0x1158,0x11A1 ],
- [ 0xF5E8, 0x1159,0x1161 ],
- [ 0xF5F3, 0x1159,0x1162 ],
- [ 0xF5F6, 0x1159,0x1163 ],
- [ 0xF5FF, 0x1159,0x1164 ],
- [ 0xF600, 0x1159,0x1165 ],
- [ 0xF607, 0x1159,0x1166 ],
- [ 0xF609, 0x1159,0x1167 ],
- [ 0xF612, 0x1159,0x1168 ],
- [ 0xF614, 0x1159,0x1169 ],
- [ 0xF61B, 0x1159,0x116A ],
- [ 0xF625, 0x1159,0x116B ],
- [ 0xF627, 0x1159,0x116C ],
- [ 0xF62B, 0x1159,0x116D ],
- [ 0xF630, 0x1159,0x116E ],
- [ 0xF63A, 0x1159,0x116F ],
- [ 0xF63F, 0x1159,0x1171 ],
- [ 0xF641, 0x1159,0x1172 ],
- [ 0xF646, 0x1159,0x1191 ],
- [ 0xF64D, 0x1159,0x1192 ],
- [ 0xF64F, 0x1159,0x1194 ],
- [ 0xF651, 0x1159,0x1173 ],
- [ 0xF659, 0x1159,0x1174 ],
- [ 0xF65C, 0x1159,0x1175 ],
- [ 0xF665, 0x1159,0x119E ],
- [ 0xF668, 0x1159,0x11A1 ],
- );
-}
diff --git a/Build/source/texk/texlive/linked_scripts/kotex-utils/komkindex.pl b/Build/source/texk/texlive/linked_scripts/kotex-utils/komkindex.pl
deleted file mode 100755
index b144fb83d51..00000000000
--- a/Build/source/texk/texlive/linked_scripts/kotex-utils/komkindex.pl
+++ /dev/null
@@ -1,917 +0,0 @@
-#!/usr/bin/env perl
-
-
-# komkindex.pl
-#
-# Copyright (c) 2007-2015 Dohyun Kim <nomos at ktug org>
-#
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.3c
-# of this license or (at your option) any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3c or later is part of all distributions of LaTeX
-# version 2006/05/20 or later.
-
-###
-### TODO: how to distinguish malformed utf8 string in IND file?
-###
-
-#use warnings;
-#use strict;
-use 5.8.0;
-use Getopt::Std;
-
-## -euc option
-for (@ARGV) {
- if ( /^\-+euc/ ) {
- $_ = '';
- exec ("hmakeindex @ARGV") or die "couldn't exec hmakeindex: $!";
- }
-}
-
-binmode STDOUT,":utf8";
-
-my $progname = $0;
-$progname =~ s/^.*\///;
-
-print "This is $progname, a makeindex wrapper for ko.TeX package.\n";
-
-@ARGV == 0 and die "\n",
- "Usage: $progname [-euc] [makeindex options] idx_filename[s]\n",
- " -euc: exec hmakeindex, passing other arguments as they are.\n\n",
- " $progname [-k] [makeindex options] idx_filename[s]\n",
- " -k: put hangul index entries before than others.\n\n";
-
-
-###
-### Many thanks to Jinsuk Kim, http://www.jinsuk.pe.kr
-###
-my @hanja_to_hangul = get_hanja_hangul_table("hanja_hangul.tab");
-my @hanjacompat_to_hangul = get_hanja_hangul_table("hanjacom_hangul.tab");
-my @hanjaextA_to_hangul = get_hanja_hangul_table("hanjaexa_hangul.tab");
-
-my @cjamo_jamo =
- qw/
- 1100 1101 11aa 1102 11ac 11ad 1103 1104
- 1105 11b0 11b1 11b2 11b3 11b4 11b5 111a
- 1106 1107 1108 1121 1109 110a 110b 110c
- 110d 110e 110f 1110 1111 1112 1161 1162
- 1163 1164 1165 1166 1167 1168 1169 116a
- 116b 116c 116d 116e 116f 1170 1171 1172
- 1173 1174 1175 1160 1114 1115 11c7 11c8
- 11cc 11ce 11d3 11d7 11d9 111c 11dd 11df
- 111d 111e 1120 1122 1123 1127 1129 112b
- 112c 112d 112e 112f 1132 1136 1140 1147
- 114c 11f1 11f2 1157 1158 1159 1184 1185
- 1188 1191 1192 1194 119e 11a1
- /;
-
-my @hangul_grouping =
- qw/
- F785 F788 F790 F798 F7A8 F7AE F7C2 F7D8
- F7D9 F7E7 F7E8 F7F0 F7F5 F7F6 F7F8 F7FC
- F7FF F807 F80C F811 F816 F81B F828 F831
- F83C F846 F84F F85E F86B
- /;
-# ㄱ ă„´ ă„· ă„ą ă… ă…‚ ă…… ă…ż
-# ă…‡ ă† ă… ă…Š ă…‹ ă…Ś ă…Ť ă…Ž
-# ㆆ ㅏ ㅑ ㅓ ㅕ ㅗ ㅛ ㅜ
-# ㅠ ㅡ ㅣ ㆍ 종성
-
-
-# u+115F => U+F784 => U+F801 # ě´ě„±ě±„움
-my @jamo_puajamo_1100 = qw/
- F785 F786 F788 F790 F792 F798 F7A8 F7AE
- F7B2 F7C2 F7CA F7D9 F7E8 F7EA F7F0 F7F5
- F7F6 F7F8 F7FC F789 F78A F78B F78C F791
- F79B F79E F7A6 F7A7 F7AB F7AD F7AF F7B0
- F7B1 F7B3 F7B4 F7B5 F7B6 F7B7 F7B8 F7BA
- F7BB F7BD F7BE F7C0 F7C1 F7C3 F7C4 F7C5
- F7C6 F7C7 F7C8 F7C9 F7CC F7CD F7CE F7CF
- F7D0 F7D1 F7D2 F7D3 F7D4 F7D5 F7D6 F7D7
- F7D8 F7DA F7DB F7DD F7DE F7DF F7E0 F7E1
- F7E2 F7E3 F7E4 F7E5 F7E7 F7E9 F7EC F7ED
- F7EE F7EF F7F1 F7F2 F7F3 F7F4 F7F9 F7FB
- F7FE F7FF F787 F78D F78E F78F F793 F801
- F806 F807 F80B F80C F810 F811 F815 F816
- F81A F81B F81C F81D F827 F828 F831 F834
- F836 F83A F83C F846 F84D F84F F808 F809
- F80D F80E F812 F813 F814 F818 F819 F820
- F821 F823 F824 F826 F82B F82C F82E F82F
- F830 F832 F833 F835 F838 F839 F83D F83F
- F840 F841 F842 F844 F845 F84B F84C F84E
- F850 F851 F856 F859 F85B F85D F85E F860
- F862 F863 F864 F80A F80F F817 F81E F81F
- F86B F86C F870 F875 F87C F87F F880 F88B
- F88C F895 F899 F89F F8A4 F8A5 F8A6 F8AA
- F8B9 F8BF F8C6 F8CD F8D8 F8E6 F8EA F8EB
- F8EC F8ED F8F2 F86E F871 F876 F878 F87A
- F87B F87E F881 F884 F88E F890 F891 F892
- F893 F896 F897 F89B F89D F89E F8A0 F8A1
- F8A3 F8A7 F8AB F8AE F8B0 F8B2 F8B3 F8B4
- F8B6 F8B7 F8B8 F8BB F8C3 F8C4 F8C5 F8C7
- F8C8 F8C9 F8CB F8D5 F8E1 F8DA F8DD F8E4
- F8E0 F8E2 F8E3 F8EE F8F1 F8F3 F8F4 F8F5
- F8F6 F8F7 F86D F86F F872 F873 F874 F877
- /;
-
-my @jamo_puajamo_A960 = qw/
- F794 F795 F796 F797 F799 F79A F79C F79D
- F79F F7A0 F7A1 F7A2 F7A3 F7A4 F7A5 F7A9
- F7AA F7AC F7B9 F7BC F7BF F7CB F7DC F7E6
- F7EB F7F7 F7FA F7FD F800
- /;
-
-my @jamo_puajamo_D7B0 = qw/
- F822 F825 F829 F82A F82D F837 F83B F83E
- F843 F847 F848 F849 F84A F852 F853 F854
- F855 F857 F858 F85A F85C F85F F861
- /;
-
-my @jamo_puajamo_D7CB = qw/
- F879 F87D F882 F883 F885 F886 F887 F888
- F889 F88A F88D F88F F894 F898 F89A F89C
- F8A2 F8A8 F8A9 F8AC F8AD F8AF F8B1 F8B5
- F8BA F8BC F8BD F8BE F8C0 F8C1 F8C2 F8CA
- F8CC F8CE F8CF F8D0 F8D1 F8D2 F8D3 F8D4
- F8D6 F8D7 F8DB F8E5 F8E7 F8E8 F8E9 F8EF
- F8F0
- /;
-
-###
-### parse options
-###
-my (
- %args,
- @IDXfiles,
- $istfile,
- $indfile,
- $logfile,
- $idx0
- );
-getopts('kcgilo:p:qrs:t:LT',\%args);
-@IDXfiles = @ARGV or die "No .idx file specified!\n";
-
-if ($args{s}) {
- $istfile = $args{s};
- $istfile =~ s/(\.ist)?$/\.ist/;
-}
-
-$idx0 = $IDXfiles[0];
-$idx0 =~ s/\.[A-Za-z]+$//;
-
-$indfile = $args{o} ? $args{o} : $idx0 . ".ind";
-
-$logfile = $args{t} ? $args{t} : $idx0 . ".ilg";
-
-foreach my $file (@IDXfiles) {
- $file =~ /\.[A-Za-z]+$/ or $file .= ".idx";
-}
-
-###
-### read .ist file
-###
-my $ist_heading_flag = 0;
-my $ist_heading_prefix = '';
-my $ist_heading_suffix = '';
-my $ist_group_skip = '\indexspace';
-my $ist_item_0 = '\item ';
-my $ist_delim_0 = ', ';
-my $ist_keyword = '\indexentry';
-my $ist_actual = '@';
-my $ist_encap = '|';
-my $ist_level = '!';
-my $ist_quote = '"';
-my $ist_arg_open = '{';
-my $ist_arg_close = '}';
-my $ist_postamble = '\end{theindex}';
-
-if ($istfile) {
- $istfile = `kpsewhich $istfile`;
- chomp $istfile;
- open IST,"<:utf8",$istfile or die "$args{s} : $!\n";
- while (<IST>) {
- s/\%.*//;
- s/\\n\b//g;
- s/\\\\/\\/g;
- if (/headings_flag\s+(.+)/) {
- $ist_heading_flag = $1;
- } elsif (/heading_prefix\s+"(.*)"/) {
- $ist_heading_prefix = $1;
- } elsif (/heading_suffix\s+"(.*)"/) {
- $ist_heading_suffix = $1;
- } elsif (/group_skip\s+"(.*)"/) {
- $ist_group_skip = $1;
- } elsif (/item_0\s+"(.*)"/) {
- $ist_item_0 = $1;
- } elsif (/delim_0\s+"(.*)"/) {
- $ist_delim_0 = $1;
- } elsif (/keyword\s+"(.*)"/) {
- $ist_keyword = $1;
- } elsif (/actual\s+'(.*)'/) {
- $ist_actual = $1;
- } elsif (/encap\s+'(.*)'/) {
- $ist_encap = $1;
- } elsif (/level\s+'(.*)'/) {
- $ist_level = $1;
- } elsif (/quote\s+'(.*)'/) {
- $ist_quote = $1;
- } elsif (/arg_open\s+'(.*)'/) {
- $ist_arg_open = $1;
- } elsif (/arg_close\s+'(.*)'/) {
- $ist_arg_close = $1;
- } elsif (/postamble\s+"(.*)"/) {
- $ist_postamble = $1;
- }
- }
- close IST;
-}
-
-
-# prepare to run makeindex
-my $makeindexoption = "-i -o $indfile -t $logfile";
-foreach ('c','l','q','r','L','g','T') {
- $makeindexoption .= " -$_" if $args{$_};
-}
-$makeindexoption .= " -s $istfile" if $args{s};
-$makeindexoption .= " -p $args{p}" if $args{p};
-
-###
-### read .idx files
-###
-my ( @idxarr, %idxhash );
-foreach my $file (@IDXfiles) {
- open IDX,"<:utf8",$file or die "$file : $!\n";
- while (<IDX>) {
- s/\^\^([0-9a-f]{2})/pack "U0C", hex $1/ge;
- s/\\unihangulchar\s*\{(\d+)\}/chr $1/ge;
-
- # \indexentry{ ..... }{ .. }
- # -> $pre $body $post
- if (/(\Q$ist_keyword\E\s*\Q$ist_arg_open\E)
- (.*)
- (\Q$ist_arg_close$ist_arg_open\E.+?\Q$ist_arg_close\E)
- $/x) {
- my($pre,$body,$post) = ($1,$2,$3);
-
- # \indexentry{ ..... | .. }{ .. }
- # -> $pre $body $post
- my @xbody = split /(?<!(?<!\\)[\\\Q$ist_quote\E])\Q$ist_encap/,$body;
- for ( my $i=$#xbody; $i>0; $i--) {
- $post = $ist_encap.$xbody[$i].$post;
- }
- $body = $xbody[0];
-
- # !을 경계로 가름.
- @xbody = split /(?<!(?<!\\)[\\\Q$ist_quote\E])\Q$ist_level/, $body;
-
- for (@xbody) {
- # @이 없으면... 넣어준다.
- unless (/(?<!(?<!\\)[\\\Q$ist_quote\E])\Q$ist_actual/) {
- $_ = $_.$ist_actual.$_;
- }
-
- # @을 경계로 가름.
- my @ybody = split /(?<!(?<!\\)[\\\Q$ist_quote\E])\Q$ist_actual\E/, $_;
- $_ = $ybody[0];
-
- s/(?<!\\)\\[A-Za-z]+\s*//g;
- s/(?<!\\)[{}]//g;
-
- &hanja_to_hangul;
- s/([\x{AC00}-\x{D7A3}])/syllable_to_jamo_chr($1)/ge;
- s/([\x{3131}-\x{318E}])/cjamo_to_jamo_chr($1)/ge;
- &insert_fillers;
- &compose_jamo;
- &jamo_to_puajamo;
-
- s/^([\x{80}-\x{F784}\x{F8F8}-\x{FFFF}])/symbolize_first($1)/e;
-
- $ybody[0] = $_;
-
- my $tmpkey = $ybody[1];
- $tmpkey =~ s/(?<!\\)\Q$ist_quote\E(.)/$1/g;
- my @tmp = split "",$ybody[0];
- $idxhash{ $tmpkey } = $tmp[0]; # for grouping routine
- if ( $tmp[0] =~ /^\x{F801}/ ) { # ě´ě„±ě±„움.
- $idxhash{ $tmpkey } = $tmp[1];
- }
- if ( $tmp[0] =~ /^\x{F806}/ ) { # 중성채움.
- $idxhash{ $tmpkey } = $tmp[2];
- }
-
- $_ = join $ist_actual,@ybody;
- }
- $body = join $ist_level,@xbody;
- push @idxarr,"$pre$body$post\n";
- }
- }
- close IDX;
-}
-
-###
-### run makeindex
-###
-open(MAKE,"| makeindex $makeindexoption") or die "Cannot fork: $!\n";
-binmode MAKE,":utf8";
-print MAKE @idxarr;
-close MAKE;
-$? >> 8 and die "\nmakeindex failed!\n";
-
-###
-### read .ind file and group hangul items
-###
-my @indarr;
-my $indgroup = 0;
-# (indgroup) 0 = header;
-# 1 = latin;
-# 2 = hangul;
-# 3 = footer.
-
-my $cho = -1;
-
-open IND,"<:utf8",$indfile or die "$indfile : $!\n";
-while (<IND>) {
- if (/\Q$ist_postamble\E/) {
- $indgroup = 3;
- } elsif ($ist_heading_flag and
- /\Q$ist_heading_prefix\E/) {
- if (/\Q$ist_heading_prefix\E.+?\Q$ist_heading_suffix\E/) {
- ### 깨진 글ěžę°€ index head로 í•ë‚ 들어가는데 이를 ě śę±°í•ę¸° ěś„í•´
- ### 복잡í•ę˛Ś 이중으로 조건검사를 í•ě€ë‹¤. 깨진 글ěžëŠ” ë‘ë˛ě§¸ 조건을
- ### 통과í•ě§€ 못한다.
- $indgroup++ if $indgroup == 0;
- } else {
- next;
- }
- } elsif (/\Q$ist_item_0\E(.+?)(\Q$ist_delim_0\E|$)/ ) {
- my $body = $1;
- if ( $idxhash{$body} =~ /[\x{F785}-\x{F8F7}]/ ) {
- $indgroup++ if $indgroup == 1;
- my $first = get_hindexhead_num($idxhash{$body});
- if ($first != $cho) {
- my $tmp = '';
- $tmp .= "\n$ist_group_skip\n" if $cho >= 0;
- $tmp .= "$ist_heading_prefix\\hindexhead{$first}$ist_heading_suffix\n"
- if ($ist_heading_flag);
- $_ = $tmp.$_;
- $cho = $first;
- }
- } else {
- $indgroup++ if $indgroup == 0;
- }
- }
- push @{$indarr[$indgroup]} , $_;
-}
-close IND;
-
-
-open IND,">:utf8",$indfile or die "$indfile : $!\n";
-if ($args{k}) {
- # latiněť ë§ě§€ë§‰ indexspace를 hangul ë§ě§€ë§‰ěśĽëˇś 이동. (-k ěµě…ě—ě„ś)
- if ( @{ $indarr[1] } and @{ $indarr[2] } ) {
- my $tmp;
- $tmp = pop @{ $indarr[1] }
- until ( $tmp =~ /\Q$ist_group_skip\E/ );
- push @{ $indarr[2] },$tmp;
- }
-
- for my $i (0,2,1,3) {
- for my $j (0 .. $#{$indarr[$i]} ) {
- print IND $indarr[$i][$j];
- }
- }
-} else {
- for my $i (0..3) {
- for my $j (0 .. $#{$indarr[$i]} ) {
- print IND $indarr[$i][$j];
- }
- }
-}
-close IND;
-
-
-########## SUBROUTINES ##########
-
-sub get_hindexhead_num {
- my $fn = ord shift;
-
- for ( my $i=0; $i<@hangul_grouping; $i++ ) {
-
- my $divval = $fn / hex($hangul_grouping[$i]);
- if ( $divval < 1 ) {
- return --$i;
- }
- }
-}
-
-sub symbolize_first {
- my $first = shift;
- my $symfirst = '';
-
- for (unpack("U0C*", $first)) {
- $symfirst .= sprintf "^^%02x",$_;
- }
-
- return $symfirst;
-}
-
-sub syllable_to_jamo_chr {
- my $syl = ord shift;
- my $cho = ($syl - 0xac00) / (21 * 28) + 0x1100;
- my $jung = ($syl - 0xac00) % (21 * 28) / 28 + 0x1161;
- my $jong = ($syl - 0xac00) % 28;
- if ($jong) {
- $jong += 0x11a7;
- return chr($cho).chr($jung).chr($jong);
- }
- return chr($cho).chr($jung);
-}
-
-sub cjamo_to_jamo_chr {
- my $cj = ord shift;
- $cj = hex $cjamo_jamo[$cj - 0x3131];
- if($cj <= 0x115f) { ### choseong: append U+F86A
- return chr($cj).chr(0x1160).chr(0xF86A);
- }
- elsif($cj >= 0x1160 and $cj <= 0x11a2) { ### jungseong: append U+F86A
- return chr(0x115f).chr($cj).chr(0xF86A);
- }
- else { ### jongseong
- return chr(0x115f).chr(0x1160).chr($cj);
- }
-}
-
-sub insert_fillers {
- my $cho = "\x{1100}-\x{115F}\x{A960}-\x{A97C}";
- my $jung = "\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}";
- my $jong = "\x{11A8}-\x{11FF}\x{D7CB}-\x{D7FB}\x{F86A}"; # include Tf
- s/([$cho])([$jong])/$1\x{1160}\x{115F}\x{1160}$2/g;
- s/([$cho])(?![$jung])/$1\x{1160}/g;
- s/(?<![$cho])([$jung])/\x{115F}$1/g;
- s/(?<![$jung])([$jong])/\x{115F}\x{1160}$1/g;
- # \x{F86A} is jongsong filler
- s/([$jung])(?![$jong])/$1\x{F86A}/g;
-}
-
-sub hanja_to_hangul {
- s/([\x{3400}-\x{4DB5}])/chr $hanjaextA_to_hangul[ord($1)-0x3400]/ge;
- s/([\x{4E00}-\x{9FA5}])/chr $hanja_to_hangul[ord($1)-0x4E00]/ge;
- s/([\x{F900}-\x{FA2D}])/chr $hanjacompat_to_hangul[ord($1)-0xF900]/ge;
-}
-
-sub get_hanja_hangul_table {
- my $file = shift;
- my @HJHG;
-
- $file = `kpsewhich $file`;
- chomp $file;
-
- open TAB, $file or die "$file : $!\n";
- @HJHG = <TAB>;
- close TAB;
-
- chomp @HJHG;
- return @HJHG;
-}
-
-sub compose_jamo {
- s/\x{1107}\x{1107}\x{110B}/\x{112C}/g;
- s/\x{1107}\x{1109}\x{1100}/\x{1122}/g;
- s/\x{1107}\x{1109}\x{1103}/\x{1123}/g;
- s/\x{1107}\x{1109}\x{1107}/\x{1124}/g;
- s/\x{1107}\x{1109}\x{1109}/\x{1125}/g;
- s/\x{1107}\x{1109}\x{110C}/\x{1126}/g;
- s/\x{1109}\x{1107}\x{1100}/\x{1133}/g;
- s/\x{1109}\x{1109}\x{1109}/\x{1134}/g;
- s/\x{1105}\x{1100}\x{1100}/\x{A965}/g;
- s/\x{1105}\x{1103}\x{1103}/\x{A967}/g;
- s/\x{1105}\x{1107}\x{1107}/\x{A96A}/g;
- s/\x{1105}\x{1107}\x{110B}/\x{A96B}/g;
- s/\x{1107}\x{1109}\x{1110}/\x{A972}/g;
- s/\x{1109}\x{1109}\x{1107}/\x{A975}/g;
- s/\x{110C}\x{110C}\x{1112}/\x{A978}/g;
- s/\x{1100}\x{1100}/\x{1101}/g;
- s/\x{1102}\x{1100}/\x{1113}/g;
- s/\x{1102}\x{1102}/\x{1114}/g;
- s/\x{1102}\x{1103}/\x{1115}/g;
- s/\x{1102}\x{1107}/\x{1116}/g;
- s/\x{1103}\x{1100}/\x{1117}/g;
- s/\x{1103}\x{1103}/\x{1104}/g;
- s/\x{1105}\x{1102}/\x{1118}/g;
- s/\x{1105}\x{1105}/\x{1119}/g;
- s/\x{1105}\x{110B}/\x{111B}/g;
- s/\x{1105}\x{1112}/\x{111A}/g;
- s/\x{1106}\x{1107}/\x{111C}/g;
- s/\x{1106}\x{110B}/\x{111D}/g;
- s/\x{1107}\x{1100}/\x{111E}/g;
- s/\x{1107}\x{1102}/\x{111F}/g;
- s/\x{1107}\x{1103}/\x{1120}/g;
- s/\x{1107}\x{1107}/\x{1108}/g;
- s/\x{1107}\x{1109}/\x{1121}/g;
- s/\x{1107}\x{110A}/\x{1125}/g;
- s/\x{1107}\x{110B}/\x{112B}/g;
- s/\x{1107}\x{110C}/\x{1127}/g;
- s/\x{1107}\x{110E}/\x{1128}/g;
- s/\x{1107}\x{1110}/\x{1129}/g;
- s/\x{1107}\x{1111}/\x{112A}/g;
- s/\x{1107}\x{112B}/\x{112C}/g;
- s/\x{1107}\x{112D}/\x{1122}/g;
- s/\x{1107}\x{112F}/\x{1123}/g;
- s/\x{1107}\x{1132}/\x{1124}/g;
- s/\x{1107}\x{1136}/\x{1126}/g;
- s/\x{1108}\x{110B}/\x{112C}/g;
- s/\x{1109}\x{1100}/\x{112D}/g;
- s/\x{1109}\x{1102}/\x{112E}/g;
- s/\x{1109}\x{1103}/\x{112F}/g;
- s/\x{1109}\x{1105}/\x{1130}/g;
- s/\x{1109}\x{1106}/\x{1131}/g;
- s/\x{1109}\x{1107}/\x{1132}/g;
- s/\x{1109}\x{1109}/\x{110A}/g;
- s/\x{1109}\x{110A}/\x{1134}/g;
- s/\x{1109}\x{110B}/\x{1135}/g;
- s/\x{1109}\x{110C}/\x{1136}/g;
- s/\x{1109}\x{110E}/\x{1137}/g;
- s/\x{1109}\x{110F}/\x{1138}/g;
- s/\x{1109}\x{1110}/\x{1139}/g;
- s/\x{1109}\x{1111}/\x{113A}/g;
- s/\x{1109}\x{1112}/\x{113B}/g;
- s/\x{1109}\x{111E}/\x{1133}/g;
- s/\x{110A}\x{1109}/\x{1134}/g;
- s/\x{110B}\x{1100}/\x{1141}/g;
- s/\x{110B}\x{1103}/\x{1142}/g;
- s/\x{110B}\x{1106}/\x{1143}/g;
- s/\x{110B}\x{1107}/\x{1144}/g;
- s/\x{110B}\x{1109}/\x{1145}/g;
- s/\x{110B}\x{110B}/\x{1147}/g;
- s/\x{110B}\x{110C}/\x{1148}/g;
- s/\x{110B}\x{110E}/\x{1149}/g;
- s/\x{110B}\x{1110}/\x{114A}/g;
- s/\x{110B}\x{1111}/\x{114B}/g;
- s/\x{110B}\x{1140}/\x{1146}/g;
- s/\x{110C}\x{110B}/\x{114D}/g;
- s/\x{110C}\x{110C}/\x{110D}/g;
- s/\x{110E}\x{110F}/\x{1152}/g;
- s/\x{110E}\x{1112}/\x{1153}/g;
- s/\x{1111}\x{1107}/\x{1156}/g;
- s/\x{1111}\x{110B}/\x{1157}/g;
- s/\x{1112}\x{1112}/\x{1158}/g;
- s/\x{1121}\x{1100}/\x{1122}/g;
- s/\x{1121}\x{1103}/\x{1123}/g;
- s/\x{1121}\x{1107}/\x{1124}/g;
- s/\x{1121}\x{1109}/\x{1125}/g;
- s/\x{1121}\x{110C}/\x{1126}/g;
- s/\x{1132}\x{1100}/\x{1133}/g;
- s/\x{113C}\x{113C}/\x{113D}/g;
- s/\x{113E}\x{113E}/\x{113F}/g;
- s/\x{114E}\x{114E}/\x{114F}/g;
- s/\x{1150}\x{1150}/\x{1151}/g;
- s/\x{1100}\x{1103}/\x{115A}/g;
- s/\x{1102}\x{1109}/\x{115B}/g;
- s/\x{1102}\x{110C}/\x{115C}/g;
- s/\x{1102}\x{1112}/\x{115D}/g;
- s/\x{1103}\x{1105}/\x{115E}/g;
- s/\x{1103}\x{1106}/\x{A960}/g;
- s/\x{1103}\x{1107}/\x{A961}/g;
- s/\x{1103}\x{1109}/\x{A962}/g;
- s/\x{1103}\x{110C}/\x{A963}/g;
- s/\x{1105}\x{1100}/\x{A964}/g;
- s/\x{A964}\x{1100}/\x{A965}/g;
- s/\x{1105}\x{1101}/\x{A965}/g;
- s/\x{1105}\x{1103}/\x{A966}/g;
- s/\x{A966}\x{1103}/\x{A967}/g;
- s/\x{1105}\x{1104}/\x{A967}/g;
- s/\x{1105}\x{1106}/\x{A968}/g;
- s/\x{1105}\x{1107}/\x{A969}/g;
- s/\x{A969}\x{1107}/\x{A96A}/g;
- s/\x{1105}\x{1108}/\x{A96A}/g;
- s/\x{1105}\x{112B}/\x{A96B}/g;
- s/\x{1105}\x{1109}/\x{A96C}/g;
- s/\x{1105}\x{110C}/\x{A96D}/g;
- s/\x{1105}\x{110F}/\x{A96E}/g;
- s/\x{1106}\x{1100}/\x{A96F}/g;
- s/\x{1106}\x{1103}/\x{A970}/g;
- s/\x{1106}\x{1109}/\x{A971}/g;
- s/\x{1121}\x{1110}/\x{A972}/g;
- s/\x{1107}\x{1139}/\x{A972}/g;
- s/\x{1107}\x{110F}/\x{A973}/g;
- s/\x{1107}\x{1112}/\x{A974}/g;
- s/\x{110A}\x{1107}/\x{A975}/g;
- s/\x{1109}\x{1132}/\x{A975}/g;
- s/\x{110B}\x{1105}/\x{A976}/g;
- s/\x{110B}\x{1112}/\x{A977}/g;
- s/\x{110D}\x{1112}/\x{A978}/g;
- s/\x{1110}\x{1110}/\x{A979}/g;
- s/\x{1111}\x{1112}/\x{A97A}/g;
- s/\x{1112}\x{1109}/\x{A97B}/g;
- s/\x{1159}\x{1159}/\x{A97C}/g;
- s/\x{1169}\x{1161}\x{1175}/\x{116B}/g;
- s/\x{1169}\x{1165}\x{1175}/\x{1180}/g;
- s/\x{1169}\x{1167}\x{1175}/\x{1181}/g;
- s/\x{116D}\x{1163}\x{1175}/\x{1185}/g;
- s/\x{116E}\x{1161}\x{1175}/\x{118A}/g;
- s/\x{116E}\x{1165}\x{1173}/\x{118B}/g;
- s/\x{116E}\x{1165}\x{1175}/\x{1170}/g;
- s/\x{116E}\x{1167}\x{1175}/\x{118C}/g;
- s/\x{1172}\x{1165}\x{1175}/\x{1190}/g;
- s/\x{1172}\x{1167}\x{1175}/\x{1192}/g;
- s/\x{1173}\x{1175}\x{116E}/\x{1197}/g;
- s/\x{1169}\x{1163}\x{1175}/\x{11A7}/g;
- s/\x{1169}\x{1169}\x{1175}/\x{D7B1}/g;
- s/\x{116D}\x{1161}\x{1175}/\x{D7B3}/g;
- s/\x{116E}\x{1175}\x{1175}/\x{D7B6}/g;
- s/\x{1172}\x{1161}\x{1175}/\x{D7B7}/g;
- s/\x{1173}\x{1165}\x{1175}/\x{D7BB}/g;
- s/\x{1175}\x{1163}\x{1169}/\x{D7BD}/g;
- s/\x{1175}\x{1163}\x{1175}/\x{D7BE}/g;
- s/\x{1175}\x{1167}\x{1175}/\x{D7C0}/g;
- s/\x{1175}\x{1169}\x{1175}/\x{D7C1}/g;
- s/\x{119E}\x{1165}\x{1175}/\x{D7C6}/g;
- s/\x{1161}\x{1169}/\x{1176}/g;
- s/\x{1161}\x{116E}/\x{1177}/g;
- s/\x{1161}\x{1175}/\x{1162}/g;
- s/\x{1163}\x{1169}/\x{1178}/g;
- s/\x{1163}\x{116D}/\x{1179}/g;
- s/\x{1163}\x{1175}/\x{1164}/g;
- s/\x{1165}\x{1169}/\x{117A}/g;
- s/\x{1165}\x{116E}/\x{117B}/g;
- s/\x{1165}\x{1173}/\x{117C}/g;
- s/\x{1165}\x{1175}/\x{1166}/g;
- s/\x{1167}\x{1169}/\x{117D}/g;
- s/\x{1167}\x{116E}/\x{117E}/g;
- s/\x{1167}\x{1175}/\x{1168}/g;
- s/\x{1169}\x{1161}/\x{116A}/g;
- s/\x{1169}\x{1162}/\x{116B}/g;
- s/\x{1169}\x{1165}/\x{117F}/g;
- s/\x{1169}\x{1166}/\x{1180}/g;
- s/\x{1169}\x{1168}/\x{1181}/g;
- s/\x{1169}\x{1169}/\x{1182}/g;
- s/\x{1169}\x{116E}/\x{1183}/g;
- s/\x{1169}\x{1175}/\x{116C}/g;
- s/\x{116A}\x{1175}/\x{116B}/g;
- s/\x{116D}\x{1163}/\x{1184}/g;
- s/\x{116D}\x{1164}/\x{1185}/g;
- s/\x{116D}\x{1167}/\x{1186}/g;
- s/\x{116D}\x{1169}/\x{1187}/g;
- s/\x{116D}\x{1175}/\x{1188}/g;
- s/\x{116E}\x{1161}/\x{1189}/g;
- s/\x{116E}\x{1162}/\x{118A}/g;
- s/\x{116E}\x{1165}/\x{116F}/g;
- s/\x{116E}\x{1166}/\x{1170}/g;
- s/\x{116E}\x{1168}/\x{118C}/g;
- s/\x{116E}\x{116E}/\x{118D}/g;
- s/\x{116E}\x{1175}/\x{1171}/g;
- s/\x{116E}\x{117C}/\x{118B}/g;
- s/\x{116F}\x{1173}/\x{118B}/g;
- s/\x{116F}\x{1175}/\x{1170}/g;
- s/\x{1172}\x{1161}/\x{118E}/g;
- s/\x{1172}\x{1165}/\x{118F}/g;
- s/\x{1172}\x{1166}/\x{1190}/g;
- s/\x{1172}\x{1167}/\x{1191}/g;
- s/\x{1172}\x{1168}/\x{1192}/g;
- s/\x{1172}\x{116E}/\x{1193}/g;
- s/\x{1172}\x{1175}/\x{1194}/g;
- s/\x{1173}\x{116E}/\x{1195}/g;
- s/\x{1173}\x{1173}/\x{1196}/g;
- s/\x{1173}\x{1175}/\x{1174}/g;
- s/\x{1173}\x{119B}/\x{1197}/g;
- s/\x{1174}\x{116E}/\x{1197}/g;
- s/\x{1175}\x{1161}/\x{1198}/g;
- s/\x{1175}\x{1163}/\x{1199}/g;
- s/\x{1175}\x{1169}/\x{119A}/g;
- s/\x{1175}\x{116E}/\x{119B}/g;
- s/\x{1175}\x{1173}/\x{119C}/g;
- s/\x{1175}\x{119E}/\x{119D}/g;
- s/\x{117F}\x{1175}/\x{1180}/g;
- s/\x{1184}\x{1175}/\x{1185}/g;
- s/\x{1189}\x{1175}/\x{118A}/g;
- s/\x{118F}\x{1175}/\x{1190}/g;
- s/\x{1191}\x{1175}/\x{1192}/g;
- s/\x{119E}\x{1165}/\x{119F}/g;
- s/\x{119E}\x{116E}/\x{11A0}/g;
- s/\x{119E}\x{1175}/\x{11A1}/g;
- s/\x{119E}\x{119E}/\x{11A2}/g;
- s/\x{1161}\x{1173}/\x{11A3}/g;
- s/\x{1163}\x{116E}/\x{11A4}/g;
- s/\x{1167}\x{1163}/\x{11A5}/g;
- s/\x{1169}\x{1163}/\x{11A6}/g;
- s/\x{1169}\x{1164}/\x{11A7}/g;
- s/\x{1169}\x{1167}/\x{D7B0}/g;
- s/\x{1182}\x{1175}/\x{D7B1}/g;
- s/\x{1169}\x{116C}/\x{D7B1}/g;
- s/\x{116D}\x{1161}/\x{D7B2}/g;
- s/\x{116D}\x{1162}/\x{D7B3}/g;
- s/\x{116D}\x{1165}/\x{D7B4}/g;
- s/\x{116E}\x{1167}/\x{D7B5}/g;
- s/\x{1171}\x{1175}/\x{D7B6}/g;
- s/\x{116E}\x{D7C4}/\x{D7B6}/g;
- s/\x{1172}\x{1162}/\x{D7B7}/g;
- s/\x{1172}\x{1169}/\x{D7B8}/g;
- s/\x{1173}\x{1161}/\x{D7B9}/g;
- s/\x{1173}\x{1165}/\x{D7BA}/g;
- s/\x{1173}\x{1166}/\x{D7BB}/g;
- s/\x{1173}\x{1169}/\x{D7BC}/g;
- s/\x{1199}\x{1169}/\x{D7BD}/g;
- s/\x{1175}\x{1178}/\x{D7BD}/g;
- s/\x{1175}\x{1164}/\x{D7BE}/g;
- s/\x{1175}\x{1167}/\x{D7BF}/g;
- s/\x{1175}\x{1168}/\x{D7C0}/g;
- s/\x{119A}\x{1175}/\x{D7C1}/g;
- s/\x{1175}\x{116C}/\x{D7C1}/g;
- s/\x{1175}\x{116D}/\x{D7C2}/g;
- s/\x{1175}\x{1172}/\x{D7C3}/g;
- s/\x{1175}\x{1175}/\x{D7C4}/g;
- s/\x{119E}\x{1161}/\x{D7C5}/g;
- s/\x{119E}\x{1166}/\x{D7C6}/g;
- s/\x{11A8}\x{11BA}\x{11A8}/\x{11C4}/g;
- s/\x{11AF}\x{11A8}\x{11BA}/\x{11CC}/g;
- s/\x{11AF}\x{11AE}\x{11C2}/\x{11CF}/g;
- s/\x{11AF}\x{11B7}\x{11A8}/\x{11D1}/g;
- s/\x{11AF}\x{11B7}\x{11BA}/\x{11D2}/g;
- s/\x{11AF}\x{11B8}\x{11BA}/\x{11D3}/g;
- s/\x{11AF}\x{11B8}\x{11BC}/\x{11D5}/g;
- s/\x{11AF}\x{11B8}\x{11C2}/\x{11D4}/g;
- s/\x{11AF}\x{11BA}\x{11BA}/\x{11D6}/g;
- s/\x{11B7}\x{11BA}\x{11BA}/\x{11DE}/g;
- s/\x{11BC}\x{11A8}\x{11A8}/\x{11ED}/g; # legacy enc
- s/\x{11F0}\x{11A8}\x{11A8}/\x{11ED}/g;
- s/\x{11AE}\x{11AE}\x{11B8}/\x{D7CE}/g;
- s/\x{11AE}\x{11BA}\x{11A8}/\x{D7D1}/g;
- s/\x{11AF}\x{11A8}\x{11A8}/\x{D7D5}/g;
- s/\x{11AF}\x{11A8}\x{11C2}/\x{D7D6}/g;
- s/\x{11AF}\x{11AF}\x{11BF}/\x{D7D7}/g;
- s/\x{11AF}\x{11B7}\x{11C2}/\x{D7D8}/g;
- s/\x{11AF}\x{11B8}\x{11AE}/\x{D7D9}/g;
- s/\x{11AF}\x{11B8}\x{11C1}/\x{D7DA}/g;
- s/\x{11AF}\x{11F9}\x{11C2}/\x{D7DC}/g;
- s/\x{11B7}\x{11AB}\x{11AB}/\x{D7DF}/g;
- s/\x{11B7}\x{11B8}\x{11BA}/\x{D7E1}/g;
- s/\x{11B8}\x{11AF}\x{11C1}/\x{D7E4}/g;
- s/\x{11B8}\x{11BA}\x{11AE}/\x{D7E7}/g;
- s/\x{11BA}\x{11B8}\x{11BC}/\x{D7EB}/g;
- s/\x{11BA}\x{11BA}\x{11A8}/\x{D7EC}/g;
- s/\x{11BA}\x{11BA}\x{11AE}/\x{D7ED}/g;
- s/\x{11EB}\x{11B8}\x{11BC}/\x{D7F4}/g;
- s/\x{11BD}\x{11B8}\x{11B8}/\x{D7F8}/g;
- s/\x{11A8}\x{11A8}/\x{11A9}/g;
- s/\x{11A8}\x{11AF}/\x{11C3}/g;
- s/\x{11A8}\x{11BA}/\x{11AA}/g;
- s/\x{11A8}\x{11E7}/\x{11C4}/g;
- s/\x{11AA}\x{11A8}/\x{11C4}/g;
- s/\x{11AB}\x{11A8}/\x{11C5}/g;
- s/\x{11AB}\x{11AE}/\x{11C6}/g;
- s/\x{11AB}\x{11BA}/\x{11C7}/g;
- s/\x{11AB}\x{11BD}/\x{11AC}/g;
- s/\x{11AB}\x{11C0}/\x{11C9}/g;
- s/\x{11AB}\x{11C2}/\x{11AD}/g;
- s/\x{11AB}\x{11EB}/\x{11C8}/g;
- s/\x{11AE}\x{11A8}/\x{11CA}/g;
- s/\x{11AE}\x{11AF}/\x{11CB}/g;
- s/\x{11AF}\x{11A8}/\x{11B0}/g;
- s/\x{11AF}\x{11AA}/\x{11CC}/g;
- s/\x{11AF}\x{11AB}/\x{11CD}/g;
- s/\x{11AF}\x{11AE}/\x{11CE}/g;
- s/\x{11AF}\x{11AF}/\x{11D0}/g;
- s/\x{11AF}\x{11B7}/\x{11B1}/g;
- s/\x{11AF}\x{11B8}/\x{11B2}/g;
- s/\x{11AF}\x{11B9}/\x{11D3}/g;
- s/\x{11AF}\x{11BA}/\x{11B3}/g;
- s/\x{11AF}\x{11BB}/\x{11D6}/g;
- s/\x{11AF}\x{11BF}/\x{11D8}/g;
- s/\x{11AF}\x{11C0}/\x{11B4}/g;
- s/\x{11AF}\x{11C1}/\x{11B5}/g;
- s/\x{11AF}\x{11C2}/\x{11B6}/g;
- s/\x{11AF}\x{11DA}/\x{11D1}/g;
- s/\x{11AF}\x{11DD}/\x{11D2}/g;
- s/\x{11AF}\x{11E5}/\x{11D4}/g;
- s/\x{11AF}\x{11E6}/\x{11D5}/g;
- s/\x{11AF}\x{11EB}/\x{11D7}/g;
- s/\x{11AF}\x{11F9}/\x{11D9}/g;
- s/\x{11B0}\x{11BA}/\x{11CC}/g;
- s/\x{11B1}\x{11A8}/\x{11D1}/g;
- s/\x{11B1}\x{11BA}/\x{11D2}/g;
- s/\x{11B2}\x{11BA}/\x{11D3}/g;
- s/\x{11B2}\x{11BC}/\x{11D5}/g;
- s/\x{11B2}\x{11C2}/\x{11D4}/g;
- s/\x{11B3}\x{11BA}/\x{11D6}/g;
- s/\x{11B7}\x{11A8}/\x{11DA}/g;
- s/\x{11B7}\x{11AF}/\x{11DB}/g;
- s/\x{11B7}\x{11B8}/\x{11DC}/g;
- s/\x{11B7}\x{11BA}/\x{11DD}/g;
- s/\x{11B7}\x{11BB}/\x{11DE}/g;
- s/\x{11B7}\x{11BC}/\x{11E2}/g;
- s/\x{11B7}\x{11BE}/\x{11E0}/g;
- s/\x{11B7}\x{11C2}/\x{11E1}/g;
- s/\x{11B7}\x{11EB}/\x{11DF}/g;
- s/\x{11B8}\x{11AF}/\x{11E3}/g;
- s/\x{11B8}\x{11BA}/\x{11B9}/g;
- s/\x{11B8}\x{11BC}/\x{11E6}/g;
- s/\x{11B8}\x{11C1}/\x{11E4}/g;
- s/\x{11B8}\x{11C2}/\x{11E5}/g;
- s/\x{11BA}\x{11A8}/\x{11E7}/g;
- s/\x{11BA}\x{11AE}/\x{11E8}/g;
- s/\x{11BA}\x{11AF}/\x{11E9}/g;
- s/\x{11BA}\x{11B8}/\x{11EA}/g;
- s/\x{11BA}\x{11BA}/\x{11BB}/g;
- s/\x{11BC}\x{11A8}/\x{11EC}/g; # legacy enc
- s/\x{11F0}\x{11A8}/\x{11EC}/g;
- s/\x{11BC}\x{11A9}/\x{11ED}/g; # legacy enc
- s/\x{11F0}\x{11A9}/\x{11ED}/g;
- s/\x{11BC}\x{11BC}/\x{11EE}/g; # legacy enc
- s/\x{11F0}\x{11F0}/\x{11EE}/g;
- s/\x{11BC}\x{11BF}/\x{11EF}/g; # legacy enc
- s/\x{11F0}\x{11BF}/\x{11EF}/g;
- s/\x{11C1}\x{11B8}/\x{11F3}/g;
- s/\x{11C1}\x{11BC}/\x{11F4}/g;
- s/\x{11C2}\x{11AB}/\x{11F5}/g;
- s/\x{11C2}\x{11AF}/\x{11F6}/g;
- s/\x{11C2}\x{11B7}/\x{11F7}/g;
- s/\x{11C2}\x{11B8}/\x{11F8}/g;
- s/\x{11CE}\x{11C2}/\x{11CF}/g;
- s/\x{11DD}\x{11BA}/\x{11DE}/g;
- s/\x{11EC}\x{11A8}/\x{11ED}/g;
- s/\x{11F0}\x{11BA}/\x{11F1}/g;
- s/\x{11F0}\x{11EB}/\x{11F2}/g;
- s/\x{11A8}\x{11AB}/\x{11FA}/g;
- s/\x{11A8}\x{11B8}/\x{11FB}/g;
- s/\x{11A8}\x{11BE}/\x{11FC}/g;
- s/\x{11A8}\x{11BF}/\x{11FD}/g;
- s/\x{11A8}\x{11C2}/\x{11FE}/g;
- s/\x{11AB}\x{11AB}/\x{11FF}/g;
- s/\x{11AB}\x{11AF}/\x{D7CB}/g;
- s/\x{11AB}\x{11BE}/\x{D7CC}/g;
- s/\x{11AE}\x{11AE}/\x{D7CD}/g;
- s/\x{D7CD}\x{11B8}/\x{D7CE}/g;
- s/\x{11AE}\x{D7CF}/\x{D7CE}/g;
- s/\x{11AE}\x{11B8}/\x{D7CF}/g;
- s/\x{11AE}\x{11BA}/\x{D7D0}/g;
- s/\x{D7D0}\x{11A8}/\x{D7D1}/g;
- s/\x{11AE}\x{11E7}/\x{D7D1}/g;
- s/\x{11AE}\x{11BD}/\x{D7D2}/g;
- s/\x{11AE}\x{11BE}/\x{D7D3}/g;
- s/\x{11AE}\x{11C0}/\x{D7D4}/g;
- s/\x{11B0}\x{11A8}/\x{D7D5}/g;
- s/\x{11AF}\x{11A9}/\x{D7D5}/g;
- s/\x{11B0}\x{11C2}/\x{D7D6}/g;
- s/\x{11AF}\x{11FE}/\x{D7D6}/g;
- s/\x{11D0}\x{11BF}/\x{D7D7}/g;
- s/\x{11AF}\x{11D8}/\x{D7D7}/g;
- s/\x{11B1}\x{11C2}/\x{D7D8}/g;
- s/\x{11AF}\x{11E1}/\x{D7D8}/g;
- s/\x{11B2}\x{11AE}/\x{D7D9}/g;
- s/\x{11AF}\x{D7E3}/\x{D7D9}/g;
- s/\x{11B2}\x{11C1}/\x{D7DA}/g;
- s/\x{11AF}\x{11E4}/\x{D7DA}/g;
- s/\x{11AF}\x{11F0}/\x{D7DB}/g;
- s/\x{11D9}\x{11C2}/\x{D7DC}/g;
- s/\x{11AF}\x{11BC}/\x{D7DD}/g;
- s/\x{11B7}\x{11AB}/\x{D7DE}/g;
- s/\x{D7DE}\x{11AB}/\x{D7DF}/g;
- s/\x{11B7}\x{11FF}/\x{D7DF}/g;
- s/\x{11B7}\x{11B7}/\x{D7E0}/g;
- s/\x{11DC}\x{11BA}/\x{D7E1}/g;
- s/\x{11B7}\x{11B9}/\x{D7E1}/g;
- s/\x{11B7}\x{11BD}/\x{D7E2}/g;
- s/\x{11B8}\x{11AE}/\x{D7E3}/g;
- s/\x{11E3}\x{11C1}/\x{D7E4}/g;
- s/\x{11B8}\x{11B5}/\x{D7E4}/g;
- s/\x{11B8}\x{11B7}/\x{D7E5}/g;
- s/\x{11B8}\x{11B8}/\x{D7E6}/g;
- s/\x{11B9}\x{11AE}/\x{D7E7}/g;
- s/\x{11B8}\x{11E8}/\x{D7E7}/g;
- s/\x{11B8}\x{11BD}/\x{D7E8}/g;
- s/\x{11B8}\x{11BE}/\x{D7E9}/g;
- s/\x{11BA}\x{11B7}/\x{D7EA}/g;
- s/\x{11EA}\x{11BC}/\x{D7EB}/g;
- s/\x{11BA}\x{11E6}/\x{D7EB}/g;
- s/\x{11BB}\x{11A8}/\x{D7EC}/g;
- s/\x{11BA}\x{11E7}/\x{D7EC}/g;
- s/\x{11BB}\x{11AE}/\x{D7ED}/g;
- s/\x{11BA}\x{11E8}/\x{D7ED}/g;
- s/\x{11BA}\x{11EB}/\x{D7EE}/g;
- s/\x{11BA}\x{11BD}/\x{D7EF}/g;
- s/\x{11BA}\x{11BE}/\x{D7F0}/g;
- s/\x{11BA}\x{11C0}/\x{D7F1}/g;
- s/\x{11BA}\x{11C2}/\x{D7F2}/g;
- s/\x{11EB}\x{11B8}/\x{D7F3}/g;
- s/\x{D7F3}\x{11BC}/\x{D7F4}/g;
- s/\x{11EB}\x{11E6}/\x{D7F4}/g;
- s/\x{11F0}\x{11B7}/\x{D7F5}/g;
- s/\x{11F0}\x{11C2}/\x{D7F6}/g;
- s/\x{11BD}\x{11B8}/\x{D7F7}/g;
- s/\x{D7F7}\x{11B8}/\x{D7F8}/g;
- s/\x{11BD}\x{D7E6}/\x{D7F8}/g;
- s/\x{11BD}\x{11BD}/\x{D7F9}/g;
- s/\x{11C1}\x{11BA}/\x{D7FA}/g;
- s/\x{11C1}\x{11C0}/\x{D7FB}/g;
-}
-
-sub jamo_to_puajamo {
- s/([\x{1100}-\x{11FF}])/chr hex $jamo_puajamo_1100[ord($1)-0x1100]/ge;
- s/([\x{A960}-\x{A97C}])/chr hex $jamo_puajamo_A960[ord($1)-0xa960]/ge;
- s/([\x{D7B0}-\x{D7C6}])/chr hex $jamo_puajamo_D7B0[ord($1)-0xd7b0]/ge;
- s/([\x{D7CB}-\x{D7FB}])/chr hex $jamo_puajamo_D7CB[ord($1)-0xd7cb]/ge;
-}
-
-### EOF
diff --git a/Build/source/texk/texlive/linked_scripts/kotex-utils/ttf2kotexfont.pl b/Build/source/texk/texlive/linked_scripts/kotex-utils/ttf2kotexfont.pl
deleted file mode 100755
index 0dea955460e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/kotex-utils/ttf2kotexfont.pl
+++ /dev/null
@@ -1,818 +0,0 @@
-#!/usr/bin/env perl
-
-# ttf2kotexfont.pl
-#
-# Copyright (c) 2003-2013 Dohyun Kim <nomos at ktug org>
-#
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.3c
-# of this license or (at your option) any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3c or later is part of all distributions of LaTeX
-# version 2006/05/20 or later.
-
-#use strict;
-#use warnings;
-use Getopt::Std;
-use File::Copy;
-use File::Path;
-
-# 저작권 정보 표시
-print "ttf2kotexfont v0.9 2007/07/03 \n",
-"Copyright (c) 2003-2007 Dohyun Kim <nomos at ktug org>\n",
-"Redistribution and use, with or without modification, are permitted\n",
-"provided that this coryright notice is retained. If you redistribute\n",
-"a modified version, please attach a note about what you have modified.\n\n";
-
-# command line option을 읽어들임
-my %args;
-getopts("pc:i:",\%args);
-unless($args{c}) {
- print <<"ENDOFHELP";
-Usage: $0 -c CONFIGFILE
- $0 -c CONFIGFILE -i TEXMFROOT
-
- -c CONFIGFILE
- obtain font-related configuration from CONFIGFILE and
- make TFMs and settings for ko.TeX. needs ttf2tfm 1.5 or higher
- -c CONFIGFILE -i TEXMFROOT
- install generated files to TEXMFROOT directory according to TDS
-
-CONFIGFILE syntax example:
-
- FOUNDRY: xy
- FONTmj: f=bt m=BTmedium.ttf b=BTbold.ttf l=BTlight.ttf
- FONTgt: f=dt m=DTmedium.ttf b=DTbold.ttf
- FONTtz: f=tz m=TZmedium.ttf
- ...
-ENDOFHELP
- exit 1;
-}
-
-# ě‚¬ěš©ěž ě„¤ě •íŚŚěťĽěť„ 읽어 %FONTS(hash of hash)ě— ě €ěžĄ
-my($foundry,%FONTS);
-open FILE,$args{c} or die "$args{c}: $!\n";
-while(<FILE>) {
- s/#.*//;
- if(/FOUNDRY:\s*(\w+)/) {
- $foundry = $1;
- }
- elsif(/FONT(\w+?):\s*(.*)/) {
- foreach my $field ( split /\s+/,$2 ) {
- my($key,$value) = split /=/,$field;
- $FONTS{$1}{$key} = $value;
- }
- }
-}
-close FILE;
-
-# ě‚¬ěš©ěž ě„¤ě •ěť„ 체í¬
-error("FOUNDRY must have 1 or 2 byte length.")
- if(!$foundry or length($foundry) >2);
-
-error("`m' field of FONTmj is not defined in `$args{c}'.")
- unless $FONTS{mj}{'m'}; # \mjdefault는 ë°ë“śě‹ś ěžě–´ě•Ľ 함
-
-foreach my $hlatex (keys %FONTS) {
- # FONTxxěť xx는 ě문 2글ěžë§Ś í—ěš©
- error("`$hlatex' of `FONT$hlatex' must have 2 or 3 byte length.")
- unless(length($hlatex) == 2 or length($hlatex) == 3);
-
- # \textrm 같은 라텍 ęł ěś  명령을 재정ěťí•ëŠ” ę˛ěť„ 방지
- error("`FONT$hlatex' is not a valid name.") if $hlatex =~
- /^(rm|sf|tt|md|bf|up|it|sc|sl|mu|pm|bb|yen|bar|kra|mho|ohm|won|div)$/;
-
- # f í•„ë“śę°€ 지정ë지 ě•Šě•ë‹¤ë©´ FONTxxěť xx를 f 필드값으로 사용
- $FONTS{$hlatex}{f} = $hlatex unless $FONTS{$hlatex}{f};
-}
-
-
-# define global variables
-my $ttf2tfm = 'ttf2tfm';
-##### $ttf2tfm = 'echo';
-my $styname = $foundry.'ttf.sty';
-my $pkmap = $foundry.'ttf2pk.map';
-my $pkcfg = 'ttf2pk.cfg';
-my $cidmap = 'cid-'.$foundry.'ttf.map';
-my $dvipdfmxcfg = 'dvipdfmx.cfg';
-my $pdfmap = $foundry.'ttf-pdftex.map';
-my $pdfcfg = 'pdftex.cfg';
-my %SERIES = (
- 'm'=>['m','c'],
- 'b'=>['b','bc'],
- 'l'=>['l'],
- );
-my $slant = 'o';
-my $cshape = '-e .92';
-my $oshape = '-s .167';
-my $bshape = '-b .15'; # for dvipdfmx fakebold feature
-my @Wsh = qw/w s h/;
-my $sansfonts = 'jgt|jsr|jnv|gt|tz|pg|gr|bm|yt|gl'; # for curemaphangulfamily()
-
-my(@StyMapHangul,@StyOther,@CidMap,@PkMap,@PdfMap);
-
-
-# variables for HLaTeX
-my $prefix = '';
-my $hlatexencoding = 'H';
-my $cmap = 'UniKSCms-UCS2-H';
-my $sfd = 'UKS-HLaTeX';
-my $opt = '-q -L KS-HLaTeX -P 3 -E 1';
-my $wancmap = 'KSCms-UHC-H';
-my $wansfd = 'KS-HLaTeX';
-my $wanopt = '-q -l -P 3 -E 5';
-my $texteststr = '^^b0^^a1^^b2^^e5^^b5^^cb^^b8^^b1^^ba^^f5^^bd^^db'.
-'^^c0^^c1^^c3^^a7^^c5^^eb^^c8^^d1 ^^a8^^b1^^a1^^db^^aa^^a2^^a5^^d2'.
-' ^^ca^^a1^^cc^^e5^^cf^^cb^^d2^^b1^^d4^^f5^^d7^^db^^da^^c1^^dd^^a7'.
-'^^df^^eb^^e2^^d1^^e5^^b7^^e7^^fb^^ea^^e1^^ed^^c7^^f0^^ad^^f2^^f1'.
-'^^f5^^d7^^f8^^bd^^fb^^a3^^fd^^e7';
-my $texstyname = 'hfont';
-my $euctexname = 'testeuc.tex';
-my $eucmjdefault = 'wmj';
-my $eucgtdefault = 'wgt';
-my $euctzdefault = 'wtt';
-my $testtexname = $euctexname;
-my $encoding = $hlatexencoding ;
-
-domainprocess() unless $args{i};
-
-$prefix = 'o';
-my $ucsencoding = 'LUC';
-$cmap = 'unicode'; # dvipdfmx 20040912 up is recommended
-$sfd = 'UCS2';
-$opt = '-q -P 3 -E 1';
-$wancmap = 'KSCms-UHC-H';
-$wansfd = "UKS-UCS2";
-$wanopt = '-q -P 3 -E 5';
-$texteststr = '\\unihangulchar{47924}\\unihangulchar{44417}'.
- '\\unihangulchar{54868} \\unihangulchar{44867}\\unihangulchar{51060} '.
- '\\unihangulchar{54588}\\unihangulchar{50632}\\unihangulchar{49845}'.
- '\\unihangulchar{45768}\\unihangulchar{45796}. \\unihangulchar{12298}'.
- '\\unihangulchar{12593}\\unihangulchar{12800}\\unihangulchar{12896}'.
- '\\unihangulchar{12299} \\unihangulchar{19968}\\unihangulchar{20108}'.
- '\\unihangulchar{19977}\\unihangulchar{22235}';
-$texstyname = 'dhucs';
-my $utftexname = 'testutf.tex';
-my $utfmjdefault = 'unbt';
-my $utfgtdefault = 'ungt';
-my $utftzdefault = 'untz';
-$testtexname = $utftexname ;
-$encoding = $ucsencoding ;
-
-domainprocess() unless $args{i};
-
-doremainderprocess() unless $args{i};
-
-exit 0 unless $args{i};
-
-my $texmf = $args{i};
-my $ttfd = "$texmf/fonts/truetype/kotex/${foundry}ttf";
-my $latexd = "$texmf/tex/latex/kotex/${foundry}ttf/euc";
-my $styd = "$texmf/tex/latex/kotex/${foundry}ttf";
-my $dhucsd = "$texmf/tex/latex/kotex/${foundry}ttf/utf";
-my $euctfmd = "$texmf/fonts/tfm/kotex/${foundry}ttf/euc";
-my $utftfmd = "$texmf/fonts/tfm/kotex/${foundry}ttf/utf";
-my $ttf2pkd = "$texmf/fonts/map/ttf2pk/kotex/${foundry}ttf";
-my $dvipdfmd = "$texmf/fonts/map/dvipdfm/kotex/${foundry}ttf";
-my $pdftexd = "$texmf/fonts/map/pdftex/kotex/${foundry}ttf";
-my $eucpdftexencd = "$texmf/fonts/enc/kotex/${foundry}ttf/euc";
-my $utfpdftexencd = "$texmf/fonts/enc/kotex/${foundry}ttf/utf";
-my $pdfcfgd = "$texmf/pdftex/config";
-my $ttf2pkcfgd = "$texmf/ttf2pk/base";
-my $dvipdfmxcfgd = "$texmf/dvipdfmx";
-
-installfiles();
-
-sub installfiles {
- error("Cannot find $styname, $pkmap or $cidmap in current directory.\n".
- "Run $0 without -i option before installing.")
- unless(-e $styname and -e $pkmap and -e $cidmap);
-
-
- unless(mkpath($texmf)) {
- print
- "Some error occured while making $texmf.\n",
- "It seems that the directory already exists.\n",
- "Installing into an existing directory is very DANGEROUS!\n",
- "Any file of the same name will be overwritten without notice.\n",
- "Do you really want to install files into $texmf? [yes/no]: ";
- my $answer = <STDIN>;
- exit 1 unless $answer =~ /yes/;
- }
-
- mymove($styd,$styname);
- mymove($ttf2pkd,$pkmap);
- mymove($dvipdfmd,$cidmap);
- mymove($pdftexd,$pdfmap) ;
-
- foreach my $hlatex (keys %FONTS) {
- next unless $FONTS{$hlatex}{f};
- my $font = $foundry.$FONTS{$hlatex}{f};
- my $ttcount = 0;
-
- foreach my $mbl (keys %SERIES) {
- my $ttf = $FONTS{$hlatex}{$mbl};
- ($ttf) = parsettf($ttf);
- next unless $ttf;
- ++$ttcount;
-
- mymove("$ttfd",$ttf) if -e $ttf;
-
- if ($args{p}) {
- mymove("$eucpdftexencd/$font",
- glob("$font$SERIES{$mbl}[0]*.enc"));
- mymove("$utfpdftexencd/$font",
- glob("$prefix$font$SERIES{$mbl}[0]*.enc"));
- }
-
- foreach my $ser (@{$SERIES{$mbl}}) {
- mymove("$euctfmd/$font",glob("$font$ser*.tfm"));
- mymove("$utftfmd/$font",glob("$prefix$font$ser*.tfm"));
- }
- } # loop for ttfs ends here
-
- if($ttcount) {
- foreach my $wsh (@Wsh) {
- mymove($latexd,"$hlatexencoding$wsh$font.fd");
- }
- mymove($dhucsd,"$ucsencoding$font.fd")
- if -e "$ucsencoding$font.fd";
- }
- } # loop for families ends here
-
- addtocfg("f $cidmap",$dvipdfmxcfg,$dvipdfmxcfgd) or print
- "Failed!\n Add `f $cidmap' at the end of $dvipdfmxcfg manually.\n";
-
- addtocfg("map +$pkmap",$pkcfg,$ttf2pkcfgd) or print
- "Failed!\n Add `map +$pkmap' at th end of $pkcfg manually.\n";
-
- if($args{p}) {
- addtocfg("map +$pdfmap",$pdfcfg,$pdfcfgd) or print
- "Failed!\n Add `map +$pdfmap' at the end of $pdfcfg manually.\n";
- }
-
- print
- "\nThe followings have to be done manually:\n",
- "1. register `$texmf' as the first TEXMF root directory\n",
- " in texmf.cnf or in MikTeX Options.\n",
- "2. run `mktexlsr'.\n\n",
- "Happy TeX'ing!\a\n";
-}
-
-sub mymove {
- my($dest,@Files) = @_;
-
- mkpath $dest;
- foreach my $file (@Files) {
- print "$dest/$file\n";
- move($file,$dest) or die "$file: $!\n";
- }
-}
-
-
-sub doremainderprocess {
- if(@PdfMap) {
- open MAP,">$pdfmap" or die "$pdfmap: $!\n";
- print MAP @PdfMap;
- close MAP;
- }
-
- open MAP,">$cidmap" or die "$cidmap: $!\n";
- print MAP @CidMap;
- close MAP;
-
- open MAP,">$pkmap" or die "$pkmap: $!\n";
- print MAP @PkMap;
- close MAP;
-
- printstyfile(@StyMapHangul,@StyOther);
-
- unless(addtocfg("f $cidmap",$dvipdfmxcfg,'.')) {
- open CFG,">$dvipdfmxcfg" or die "$dvipdfmxcfg: $!\n";
- print CFG "f $cidmap\n";
- close CFG;
- }
- unless(addtocfg("map +$pkmap",$pkcfg,'.')) {
- open CFG,">$pkcfg" or die "$pkcfg: $!\n";
- print CFG "map +$pkmap\n";
- close CFG;
- }
- if(@PdfMap and $args{p} and !addtocfg("map +$pdfmap",$pdfcfg,'.')) {
- open CFG,">$pdfcfg" or die "$pdfcfg: $!\n";
- print CFG "output_format 1\n",
- "page_width 210 true mm\n",
- "page_height 297 true mm\n",
- "horigin 1 true in\n",
- "vorigin 1 true in\n",
- "map psfonts.map\n",
- "map +$pdfmap\n";
- close CFG;
- }
-
- ### cure maphangul
- @StyMapHangul = curemaphangulfamily(@StyMapHangul);
- print "\nTried to cure MapHangulFamily in $styname.\n",
- "Edit $styname to your taste :\n",
- @StyMapHangul;
- move($styname,"$styname.orig") or
- warn "Couldn't rename $styname to $styname.orig: $!\n";
- printstyfile(@StyMapHangul,@StyOther);
-
- $euctexname =~s/\.tex$//;
- $utftexname =~s/\.tex$//;
- print "\nAll done ...\n",
- "Try `latex $euctexname && dvipdfmx $euctexname' for testing.\n",
- "Try `latex $utftexname && dvipdfmx $utftexname' for testing.\a\n";
-
-}
-
-
-sub domainprocess {
- my @TestTeX;
-
- foreach my $hlatex (keys %FONTS) { # loop for each FONTxx families
- my $family = $FONTS{$hlatex}{f};
- my $font = $prefix.$foundry.$family;
- my(%TeXFd,@UCSFd,$nohangul,$nohanja);
-
- foreach my $mbl (keys %SERIES) { # loop for TTFs
- my($iswan,$isttc,$cidmapcnt,$ttf2pkcnt);
- my $ttf = $FONTS{$hlatex}{$mbl};
- next unless $ttf;
- ++$isttc if $ttf =~ /\.ttc\b/i;
- $args{p} = 0 if $isttc;
-
- ($iswan,$cidmapcnt,$ttf2pkcnt) =
- maketfmandmap($font,$ttf,@{$SERIES{$mbl}});
-
- $mbl eq 'b' and $ttf eq $FONTS{$hlatex}{m} and
- @{$cidmapcnt} = addfakeboldoption(@{$cidmapcnt});
-
- push @CidMap,@{$cidmapcnt};
- push @PkMap,@{$ttf2pkcnt};
- if($args{p}) {
- push @PdfMap,getpdfmapdata($font.$SERIES{$mbl}[0],$ttf)
- unless $isttc;
- }
- else {
- push @PdfMap,$font,$SERIES{$mbl}[0],"\@",
- $iswan ? $wansfd : $sfd,
- "\@\t<$ttf\tPidEid=3,",
- $iswan ? "5" : "1",
- "\n" unless $isttc;
- }
-
- if($prefix) {
- -e "$font${mbl}ac.tfm" or ++$nohangul;
- -e "$font${mbl}4e.tfm" or ++$nohanja;
- push @UCSFd,getucsfd($font,@{$SERIES{$mbl}});
- }
- else {
- foreach my $wsh (@Wsh) { # w/s/h ę° fd ë‚´ěš©ěť„ %TeXFdě— ě €ěžĄ
- push @{$TeXFd{$wsh}},gettexfd($font,$wsh,@{$SERIES{$mbl}});
- }
- }
-
- push @TestTeX,gettexfilecnt($font,$mbl,$ttf,$hlatex);
- } # loop for ttfs ends here
-
- my $fdname = $font; $fdname =~ s/^$prefix//;
-
- if($prefix and @UCSFd) {
- open FD,">$encoding$fdname.fd" or
- die "$encoding$fdname.fd: $!\n";
- print FD "\\DeclareFontFamily{$encoding}{$fdname}",
- "{\\hyphenchar\\font\\m\@ne}\n",@UCSFd;
- close FD;
- }
- else {
- foreach my $wsh (keys %TeXFd) { # %TeXFd를 ę° w/s/h .fdíŚŚěťĽě— ě“°ę¸°
- open FD,">$encoding$wsh$font.fd" or
- die "$encoding$wsh$font.fd: $!\n";
- print FD "\\DeclareFontFamily{$encoding}{$wsh$font}",
- "{\\hyphenchar\\font\\m\@ne}\n", @{$TeXFd{$wsh}};
- close FD;
- }
- }
-
- if(!$prefix and keys %TeXFd) {
- push @StyMapHangul,
- "\\MapHangulFamily{$family}{$font,$font,$font}\n";
- if($hlatex =~ /^(mj|gt|tz)$/) {
- push @StyOther,
- "\\renewcommand\\${hlatex}default{$family}\n";
- }
- else {
- push @StyOther, "\\DeclareRobustCommand\\${hlatex}family",
- "{\\hfontfamily{$family}}\n",
- "\\DeclareTextFontCommand\\text$hlatex",
- "{\\${hlatex}family}\n";
- }
- }
-
- if($prefix) {
- if($hlatex eq 'mj') {
- push @StyOther,
- "\\def\\dhucs\@serifhangulfont\{",
- $nohangul ? $utfmjdefault : $fdname,
- "\}\\def\\dhucs\@serifhanjafont\{",
- $nohanja ? $utfmjdefault : $fdname,
- "\}\n";
- }
- elsif($hlatex eq 'gt') {
- push @StyOther,
- "\\def\\dhucs\@sanshangulfont\{",
- $nohangul ? $utfgtdefault : $fdname,
- "\}\\def\\dhucs\@sanshanjafont\{",
- $nohanja ? $utfgtdefault : $fdname,
- "\}\n";
- }
- elsif($hlatex eq 'tz') {
- push @StyOther,
- "\\def\\dhucs\@monohangulfont\{",
- $nohangul ? $utftzdefault : $fdname,
- "\}\\def\\dhucs\@monohanjafont\{",
- $nohanja ? $utftzdefault : $fdname,
- "\}\n";
- }
- }
- } # loop for families ends here
-
- unless($prefix) {
- push @StyOther,
- "\\DeclareErrorHFont{$encoding}{\\mjdefault}{m}{n}{10}\n",
- "\\DeclareHFontSubstitution{$encoding}{\\mjdefault}{m}{n}\n",
- "\\else\n" ;
- }
-
- printtesttexfile(@TestTeX);
-
-}
-
-sub printtesttexfile {
- my @texcnt = @_;
- open TEX,">$testtexname" or die "$testtexname: $!\n";
- print TEX
- "\\documentclass[a4paper]{article}\n",
- "\\usepackage{",$texstyname,",${foundry}ttf}\n",
- "\\usepackage{ifpdf}\n",
- "\\ifpdf",
- "\\expandafter\\ifx\\csname pdfmapfile\\endcsname\\relax\\else\n",
- $prefix ? "\\pdfmapfile{=unttf-pdftex-dhucs.map}": "",
- "\\pdfmapfile{=$pdfmap}\n",
- "\\fi\\fi\n",
- "\\begin{document}\n",
- @texcnt,
- "\\end{document}\n";
- close TEX;
-}
-
-
-sub printstyfile {
- my(@stydata) = @_;
-
- open STY,">$styname" or die "$styname: $!\n";
- print STY "%%% $styname\n",
- "%%%\n",
- "%%% Automatically created by $0\n",
- "%%% at ",scalar localtime,"\n",
- "%%%\n",
- "\\ProvidesPackage{${foundry}ttf}\n",
- "\\expandafter\\ifx\\csname unihangulchar\\endcsname\\relax\n",
- @stydata,
- "\\fi\n",
- "\\def\\hfontfamilynameprefix{$foundry}\n",
- "\\endinput\n";
- close STY;
-}
-
-
-
-sub maketfmandmap {
- my($font,$ttf,@Series) = @_;
- my($iswan,$findex,@cidmapdata,@ttf2pkdata);
- ($ttf,$findex) = parsettf($ttf);
-
- foreach my $ser (@Series) { # eg. for 'm' and 'c'
- foreach my $sla ('',$slant) { # for null and 'o'
- my $font = $font.$ser.$sla;
- my ($tfmcmd,$myopt,$mysfd);
-
- my $shape = '';
- $shape .= " $cshape" if $ser =~ /c/;
- $shape .= " $oshape" if $sla eq 'o';
-
- unless($iswan) {
- $myopt = "$opt$shape -f $findex";
- $mysfd = $sfd;
- }
- else {
- $myopt = "$wanopt$shape -f $findex";
- $mysfd = $wansfd;
- }
-
- $myopt .= ' -w' if($args{p} and $shape eq '');
-
- $tfmcmd = "$ttf2tfm $ttf $myopt $font\@$mysfd\@";
- print "$tfmcmd\n";
-
- my $ttf2tfmresult = `$tfmcmd`;
- if($? >> 8){ # ttf2tfměť´ 실패í–다면 완성 인코딩 ěµě…으로 재시도
- $myopt = "$wanopt$shape -f $findex";
- $myopt .= ' -w' if($args{p} and $shape eq '');
- $tfmcmd = "$ttf2tfm $ttf $myopt $font\@$wansfd\@";
- print "... trying wansung ttf option ...\n$tfmcmd\n";
- $ttf2tfmresult = `$tfmcmd`;
- $? >> 8 and die; # ěť´ë˛ě—도 실패í•ë©´ 프로그램 종료
- ++$iswan; # 성공í–다면 ě™„ě„±í• TTF
- }
- push @ttf2pkdata,$ttf2tfmresult;
-
- my @tmp = ( "$font\@",
- $iswan ? $wansfd : $sfd,
- "\@\t",
- $iswan ? $wancmap : $cmap,
- "\t",
- $findex ? ":$findex:" : "",
- "$ttf$shape\n");
- push @cidmapdata, join '',@tmp;
- }
- }
-
- return($iswan,\@cidmapdata,\@ttf2pkdata);
-}
-
-
-sub parsettf {
- my($ttf) = @_;
- my $findex = 0;
-
- if($ttf =~ /\((\d)\)/) {
- $findex = $1;
- $ttf =~ s/\($1\)//;
- }
-
- if($ttf =~ /\[([\w\-_\.]+?)\]/) { # old version compatible
- $ttf =~ s/\[$1\]//;
- }
-
- return($ttf,$findex);
-}
-
-
-sub addfakeboldoption {
- my @cidmaplines = @_;
- for(@cidmaplines) {
- s/$/ $bshape/;
- }
- return @cidmaplines;
-}
-
-
-sub getpdfmapdata {
- my($font,$ttf) = @_;
- my(@Data,@PLANES);
- ($ttf) = parsettf($ttf);
-
- if($prefix) {
- for my $i(0 .. 255) {
- $PLANES[$i] = sprintf "%02x",$i;
- }
- }
- else {
- @PLANES = ("04".."07",0 .. 29);
- }
-
- foreach my $plane (@PLANES) {
- push @Data,"$font$plane\t<$font$plane.enc\t<$ttf\n"
- if -e "$font$plane.enc";
- }
-
- return @Data;
-}
-
-
-sub gettexfd {
- my($font,$wsh,@Series) = @_;
- my @texfd;
-
- foreach my $ser (@Series) {
- push @texfd,"\n",
- "\\DeclareFontShape{$encoding}{$wsh$font}{$ser}{n}",
- "{<->$font$ser}{}\n",
- "\\DeclareFontShape{$encoding}{$wsh$font}{$ser}{sl}",
- "{<->$font$ser$slant}{}\n",
- "\\DeclareHFontShape{$encoding}{$wsh$font}{$ser}{it}",
- "{<->hssub*$wsh$font/$ser/sl}{}\n";
- }
-
- return @texfd;
-}
-
-sub getucsfd {
- my($ff,@Series) = @_;
- my $font = $ff;
- $font =~ s/^$prefix//;
- my @ucsfd;
-
- foreach my $ser (@Series) {
- push @ucsfd,"\n",
- "\\DeclareFontShape{$encoding}{$font}{$ser}{n}",
- "{<-> $encoding * $ff$ser}{}\n",
- "\\DeclareFontShape{$encoding}{$font}{$ser}{sl}",
- "{<-> $encoding * $ff$ser$slant}{}\n",
- "\\DeclareFontShape{$encoding}{$font}{$ser}{it}",
- "{<-> $encoding * $ff$ser$slant}{}\n";
- if($ser eq 'b') {
- my $bxser = 'bx';
- push @ucsfd,"\n",
- "\\DeclareFontShape{$encoding}{$font}{$bxser}{n}",
- "{<-> ${encoding}ssub * $font/$ser/n}{}\n",
- "\\DeclareFontShape{$encoding}{$font}{$bxser}{sl}",
- "{<-> ${encoding}ssub * $font/$ser/sl}{}\n",
- "\\DeclareFontShape{$encoding}{$font}{$bxser}{it}",
- "{<-> ${encoding}ssub * $font/$ser/it}{}\n";
- }
- }
- return @ucsfd;
-}
-
-
-sub gettexfilecnt {
- my($font,$mbl,$ttf,$hlatex) = @_;
- my(@texcnt,$findex);
-
- ($ttf,$findex) = parsettf($ttf);
- $ttf =~ s/_/\\_/g;
- $ttf .= "($findex)" if $findex;
-
- push @texcnt,"$font$SERIES{$mbl}[0]($ttf):";
- unless($prefix) {
- push @texcnt,"\\text$hlatex\{";
- push @texcnt,"\\bfseries" if $mbl eq 'b';
- push @texcnt,"\\hfontseries{l}" if $mbl eq 'l';
- }
- else {
- $font=~s/^$prefix//;
- if($hlatex eq 'mj') {
- push @texcnt,"\\textrm\{";
- }
- elsif($hlatex eq 'gt') {
- push @texcnt,"\\textsf\{";
- }
- elsif($hlatex eq 'tz') {
- push @texcnt,"\\texttt\{";
- }
- else {
- push @texcnt,"\{\\SetAdhocFonts{$font}{$font}";
- }
- push @texcnt,"\\bfseries" if $mbl eq 'b';
- push @texcnt,"\\fontseries{l}" if $mbl eq 'l';
- }
- push @texcnt,"\\\\$texteststr\}\n\n";
-
- return @texcnt;
-}
-
-
-sub addtocfg {
- my($line,$cfg,$destdir) = @_;
- print "`$line' -> $destdir/$cfg ... ";
-
- # í„ěž¬ë””ë ‰í† ë¦¬ěť $cfg는 kpsewhichěť ěž‘ě—…ě— ë°©í•´ę°€ ë¨
- if(-e $cfg) {
- move($cfg,"$cfg.exa") or return 0;
- }
-
- # kpsewhichę°€ 성공í•ę¸¸ 기ě›í•ěž
- my $progname = $cfg;
- # $progname =~ s/dvipdfmx/dvipdfm/;
- $progname =~ s/\.cfg//;
- my $kpathcfg =
- `kpsewhich -format="other text files" -progname=$progname $cfg`;
- chomp $kpathcfg;
- return 0 unless $kpathcfg;
-
- # ë°śę˛¬ëś $cfg를 읽어들임
- # 단, 추가í•ë ¤ëŠ” 줄과 같은 줄이 ěžěśĽë©´ 무시
- my @Lines = ();
- open(CFG,$kpathcfg) or return 0;
- while(<CFG>) {
- next if /^\Q$line/;
- next if /^% ${foundry}ttf -- added by/;
- push @Lines,$_;
- }
- close CFG;
-
- # .cfg를 $destdirě— ě“°ęł  맨ëťě— $line 추가
- mkpath $destdir;
- open(CFG,">$destdir/$cfg") or return 0;
- print CFG @Lines,"\n\% ${foundry}ttf -- added by $0\n$line\n";
- close CFG;
-
- # 여기까지 도달í•ë©´ 성공
- print "Success.\n But check out the file.\n";
- return 1;
-}
-
-
-sub curemaphangulfamily {
- my(@maphangul) = @_;
- my $mjfamily = $FONTS{mj}{f};
- my $gtfamily = $FONTS{gt}{f} || $mjfamily;
- my @serifcured = ($mjfamily,$mjfamily,$mjfamily);
- my @sanscured = ($gtfamily,$gtfamily,$gtfamily);
- my $texlog = $euctexname; $texlog =~ s/\.tex/\.log/;
- my(@ERRFNT,%SFONTS);
-
- # latexěť„ 돌려 ě—러난 폰트를 @ERRFNTě— ě €ěžĄ
- system("latex -interaction=batchmode -no-mktex=tfm $euctexname");
- open LOG,$texlog or return @maphangul;
- while(<LOG>) {
- if(/^! Font H\/(\w)(\w+?)\/.* \(TFM\) /) {
- push @{$ERRFNT[0]}, $2 if $1 eq 'w';
- push @{$ERRFNT[1]}, $2 if $1 eq 's';
- push @{$ERRFNT[2]}, $2 if $1 eq 'h';
- }
- }
- close LOG;
-
- # @ERRFNTě—ě„ś 중복항목을 없앰
- foreach my $i (0..2) {
- my %seen = ();
- foreach (@{$ERRFNT[$i]}) {
- $seen{$_}++;
- }
- @{$ERRFNT[$i]} = keys %seen;
- }
-
- # @maphangulě—ě„ś %SFONTS 추출
- foreach (@maphangul) {
- if(/\\MapHangulFamily\{(\w+)\}\{(\w+),(\w+),(\w+)\}/) {
- push @{$SFONTS{$1}},$2,$3,$4;
- }
- }
-
- # FONTmjě— ě—러가 ěžěśĽë©´ uhc ěť´ěš©
- foreach my $i (0..2) {
- foreach my $errfnt (@{$ERRFNT[$i]}) {
- $serifcured[$i] = 'type1uhc' if $errfnt eq "$foundry$mjfamily";
- }
- }
-
- # FONTgtě— ě—러가 ěžěśĽë©´ FONTmj ěť´ěš©
- if($gtfamily ne $mjfamily) {
- foreach my $i (0..2) {
- foreach my $errfnt (@{$ERRFNT[$i]}) {
- $sanscured[$i] = 'type1uhc'
- if $errfnt eq "$foundry$gtfamily";
- }
- }
- }
-
- # %SFONTS와 @ERRFNT를 ëą„ęµí•ě—¬
- # sansęł„ě—´ě— ě—러 ěžěśĽë©´ FONTgtěť´ěš©, serifęł„ě—´ěť´ë©´ FONTmjěť´ěš©
- foreach my $fam (keys %SFONTS) {
- foreach my $i (0..2) {
- foreach my $errfnt (@{$ERRFNT[$i]}) {
- if($SFONTS{$fam}[$i] eq $errfnt) {
- if($fam =~ /^($sansfonts)$/) {
- $SFONTS{$fam}[$i] =
- $sanscured[$i] eq 'type1uhc' ?
- $eucgtdefault :
- $SFONTS{$sanscured[$i]}[$i];
- } else {
- $SFONTS{$fam}[$i] =
- $serifcured[$i] eq 'type1uhc' ?
- $eucmjdefault :
- $SFONTS{$serifcured[$i]}[$i];
- }
- }
- }
- }
- }
-
- # ě로운 @maphangul 리턴
- @maphangul = ();
- foreach my $fam (keys %SFONTS) {
- push @maphangul,"\\MapHangulFamily{$fam}{";
- foreach my $i (0..2) {
- push @maphangul,$SFONTS{$fam}[$i];
- push @maphangul,',' if $i < 2;
- }
- push @maphangul,"}\n";
- }
- return @maphangul;
-}
-
-
-sub error {
- my $message = shift;
-
- print "\n$message\nProgram Aborted!!!\n";
- exit 1;
-}
-
-#####
-# 2008/09/23. touched by Karnes. change dvipdfmx.cfg location
diff --git a/Build/source/texk/texlive/linked_scripts/l3build/l3build.lua b/Build/source/texk/texlive/linked_scripts/l3build/l3build.lua
deleted file mode 100644
index e7acd47fb3b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/l3build/l3build.lua
+++ /dev/null
@@ -1,197 +0,0 @@
-#!/usr/bin/env texlua
-
---[[
-
-File l3build.lua Copyright (C) 2014-2020 The LaTeX3 Project
-
-It may be distributed and/or modified under the conditions of the
-LaTeX Project Public License (LPPL), either version 1.3c of this
-license or (at your option) any later version. The latest version
-of this license is in the file
-
- http://www.latex-project.org/lppl.txt
-
-This file is part of the "l3build bundle" (The Work in LPPL)
-and all files in that bundle must be distributed together.
-
------------------------------------------------------------------------
-
-The development version of the bundle can be found at
-
- https://github.com/latex3/l3build
-
-for those people who are interested.
-
---]]
-
--- Version information
-release_date = "2020-06-04"
-
--- File operations are aided by the LuaFileSystem module
-local lfs = require("lfs")
-
--- Local access to functions
-
-local assert = assert
-local ipairs = ipairs
-local insert = table.insert
-local lookup = kpse.lookup
-local match = string.match
-local gsub = string.gsub
-local next = next
-local print = print
-local select = select
-local tonumber = tonumber
-local exit = os.exit
-
--- l3build setup and functions
-kpse.set_program_name("kpsewhich")
-build_kpse_path = match(lookup("l3build.lua"),"(.*[/])")
-local function build_require(s)
- require(lookup("l3build-"..s..".lua", { path = build_kpse_path } ) )
-end
-
--- Minimal code to do basic checks
-build_require("arguments")
-build_require("help")
-
-build_require("file-functions")
-build_require("typesetting")
-build_require("aux")
-build_require("clean")
-build_require("check")
-build_require("ctan")
-build_require("install")
-build_require("unpack")
-build_require("manifest")
-build_require("manifest-setup")
-build_require("tagging")
-build_require("upload")
-build_require("stdmain")
-
--- This has to come after stdmain(),
--- and that has to come after the functions are defined
-if options["target"] == "help" then
- help()
- exit(0)
-elseif options["target"] == "version" then
- version()
- exit(0)
-end
-
--- Allow main function to be disabled 'higher up'
-main = main or stdmain
-
--- Load configuration file if running as a script
-if match(arg[0], "l3build$") or match(arg[0], "l3build%.lua$") then
- -- Look for some configuration details
- if fileexists("build.lua") then
- dofile("build.lua")
- else
- print("Error: Cannot find configuration build.lua")
- exit(1)
- end
-end
-
--- Load standard settings for variables:
--- comes after any user versions
-build_require("variables")
-
--- Ensure that directories are 'space safe'
-maindir = escapepath(maindir)
-docfiledir = escapepath(docfiledir)
-sourcefiledir = escapepath(sourcefiledir)
-supportdir = escapepath(supportdir)
-testfiledir = escapepath(testfiledir)
-testsuppdir = escapepath(testsuppdir)
-builddir = escapepath(builddir)
-distribdir = escapepath(distribdir)
-localdir = escapepath(localdir)
-resultdir = escapepath(resultdir)
-testdir = escapepath(testdir)
-typesetdir = escapepath(typesetdir)
-unpackdir = escapepath(unpackdir)
-
--- Tidy up the epoch setting
--- Force an epoch if set at the command line
--- Must be done after loading variables, etc.
-if options["epoch"] then
- epoch = options["epoch"]
- forcecheckepoch = true
- forcedocepoch = true
-end
-normalise_epoch()
-
--- Sanity check
-check_engines()
-
---
--- Deal with multiple configs for tests
---
-
--- When we have specific files to deal with, only use explicit configs
--- (or just the std one)
-if options["names"] then
- checkconfigs = options["config"] or {stdconfig}
-else
- checkconfigs = options["config"] or checkconfigs
-end
-
-if options["target"] == "check" then
- if #checkconfigs > 1 then
- local errorlevel = 0
- local opts = options
- local failed = { }
- for i = 1, #checkconfigs do
- opts["config"] = {checkconfigs[i]}
- errorlevel = call({"."}, "check", opts)
- if errorlevel ~= 0 then
- if options["halt-on-error"] then
- exit(1)
- else
- insert(failed,checkconfigs[i])
- end
- end
- end
- if next(failed) then
- for _,config in ipairs(failed) do
- print("Failed tests for configuration " .. config .. ":")
- print("\n Check failed with difference files")
- local testdir = testdir
- if config ~= "build" then
- resultdir = resultdir .. "-" .. config
- testdir = testdir .. "-" .. config
- end
- for _,i in ipairs(filelist(testdir,"*" .. os_diffext)) do
- print(" - " .. testdir .. "/" .. i)
- end
- print("")
- end
- exit(1)
- else
- -- Avoid running the 'main' set of tests twice
- exit(0)
- end
- end
-end
-if #checkconfigs == 1 and
- checkconfigs[1] ~= "build" and
- (options["target"] == "check" or options["target"] == "save" or options["target"] == "clean") then
- local config = "./" .. gsub(checkconfigs[1],".lua$","") .. ".lua"
- if fileexists(config) then
- local savedtestfiledir = testfiledir
- dofile(config)
- testdir = testdir .. "-" .. checkconfigs[1]
- -- Reset testsuppdir if required
- if savedtestfiledir ~= testfiledir and
- testsuppdir == savedtestfiledir .. "/support" then
- testsuppdir = testfiledir .. "/support"
- end
- else
- print("Error: Cannot find configuration " .. checkconfigs[1])
- exit(1)
- end
-end
-
--- Call the main function
-main(options["target"], options["names"])
diff --git a/Build/source/texk/texlive/linked_scripts/latex-git-log/latex-git-log b/Build/source/texk/texlive/linked_scripts/latex-git-log/latex-git-log
deleted file mode 100755
index 35d831b6eb6..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latex-git-log/latex-git-log
+++ /dev/null
@@ -1,370 +0,0 @@
-#!/usr/bin/env perl
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# Modules and pragmas {{{
-use strict;
-use warnings;
-use autodie;
-use feature qw(say);
-use utf8;
-use open qw(:std :utf8);
-binmode STDOUT, ':encoding(UTF-8)';
-use IPC::System::Simple qw(capturex);
-use Getopt::Long;
-use Pod::Usage;
-
-# Get the path where this script is located {{{
-my $dirpath;
-
-BEGIN {
- use File::Basename qw(fileparse);
- use Cwd qw(abs_path);
- $dirpath = ( fileparse( abs_path($0) ) )[1];
-}
-# }}}
-
-use Locale::Maketext::Simple (
- Path => $dirpath . 'po/',
- Decode => 1,
-);
-# }}}
-
-# Optional parameters {{{
-my $print_author = 0;
-my $commit_count = 1;
-my $width = 0;
-my $lang = undef;
-my $version = 0;
-my $help = 0;
-my $man = 0;
-my $revision_range = 0;
-my ( $git_user, $git_repo, $git_commit_address );
-GetOptions(
- 'author' => \$print_author,
- 'startcommit=s' => \$commit_count,
- 'width=s' => \$width,
- 'git-c-add=s' => \$git_commit_address,
- 'user=s' => \$git_user,
- 'repo=s' => \$git_repo,
- 'lang=s' => \$lang,
- 'version' => \$version,
- 'help|?' => \$help,
- 'man' => \$man,
- 'range=s' => \$revision_range,
-);
-pod2usage( -verbose => 99, -sections => [ qw(Synopsis Options) ] ) if $help;
-pod2usage( -verbose => 2, -exitstatus => 0, ) if $man;
-pod2usage( -verbose => 99, -sections => 'Version' ) if $version;
-my $git_remote = ( split /\n/xms, capturex(qw(git remote -v)) )[0];
-
-loc_lang($lang) if ( defined $lang );
-say '%% This file was generated by the script latex-git-log';
-my $git_command_commit_msg = '%s';
-if ( (defined $git_user and defined $git_repo) or $git_commit_address ) {
- unless ( defined $git_commit_address ) {
- $git_commit_address = "https://github.com/$+{user}/$+{repo}/commit";
- }
- $git_command_commit_msg = '%H & %s';
- say '%% Base git commit URL: ' . $git_commit_address;
-}
-if ($width) {
- $width = "p{${width}cm}";
-}
-else {
- $width = 'l';
-}
-# }}}
-
-# LaTeX template {{{
-say '\begin{tabular}{lp{12cm}}
- \label{tabular:legend:git-log}
- \textbf{' . loc('acronym') . '} & \textbf{' . loc('meaning') . '} \\\\
- V & \texttt{' . loc('version') . '} \\\\
- ' . loc('tag') . ' & ' . loc('\texttt{git tag}') . ' \\\\
- ' . loc('MF') . ' & ' . loc('Number of \texttt{modified files}.') . ' \\\\
- ' . loc('AL') . ' & ' . loc('Number of \texttt{added lines}.') . ' \\\\
- ' . loc('DL') . ' & ' . loc('Number of \texttt{deleted lines}.') . ' \\\\
-\end{tabular}
-
-\bigskip
-
-\iflanguage{ngerman}{\shorthandoff{"}}{}';
-
-if ($print_author) {
- say "\\begin{longtable}{|rllllrrr|}";
-}
-else {
- say "\\begin{longtable}{|rll${width}rrr|}";
-}
-say '\hline \multicolumn{1}{|c}{\textbf{' . loc('V') . '}} & \multicolumn{1}{c}{\textbf{' . loc('tag') . '}}';
-say '& \multicolumn{1}{c}{\textbf{' . loc('author') . '}}' if $print_author;
-say '& \multicolumn{1}{c}{\textbf{' . loc('date') . '}}
-& \multicolumn{1}{c}{\textbf{' . loc('commit message') . '}} & \multicolumn{1}{c}{\textbf{' . loc('MF') . '}}
-& \multicolumn{1}{c}{\textbf{' . loc('AL') . '}} & \multicolumn{1}{c|}{\textbf{' . loc('DL') . '}} \\\\ \hline
-\endhead
-';
-if ($print_author) {
- say '\hline \multicolumn{8}{|r|}{\longtableendfoot} \\\\ \hline';
-}
-else {
- say '\hline \multicolumn{7}{|r|}{\longtableendfoot} \\\\ \hline';
-}
-say '\endfoot
-
-\hline% \hline
-\endlastfoot
-';
-# }}}
-
-# Get version history from git log {{{
-# git log --pretty=format:'%ai'
-# git log --date=short --pretty=format:'%ad'
-my @lines;
-my @git_command = qw(git log --date=short --shortstat);
-if ($print_author) {
- push( @git_command, qq(--pretty=format:%H & %an NoTinAuthorFiled& %ad & $git_command_commit_msg) );
-}
-else {
- push( @git_command, qq(--pretty=format:%H %ad & $git_command_commit_msg) );
-}
-if ($revision_range) {
- push( @git_command, qq($revision_range) );
-}
-@lines = reverse capturex(@git_command);
-# }}}
-
-# Get tags {{{
-my @tags_commits = capturex( 'git', 'log', '--tags', '--no-walk', '--pretty=\'%H %d\'' );
-my %commit_tags; # The key will be a SHA1 commit hash and the value a comma separated list of all tags.
-for (@tags_commits) {
- chomp;
- m/\A'([^ ]+)\s*\(([^)]+)\)'\z/xms;
- my $c_hash = $1;
- my $tag = $2;
- $tag =~ s/tag: //g;
- if ( defined $commit_tags{$c_hash} ) {
- $commit_tags{$c_hash} .= ", $tag";
- }
- else {
- $commit_tags{$c_hash} = $tag;
- }
-}
-# }}}
-
-# Helper function {{{
-sub latex_escape {
- # Source: http://ommammatips.blogspot.de/2011/01/perl-function-for-latex-escape.html
- my $paragraph = shift;
-
- # Replace a \ with $\backslash$
- # This is made more complicated because the dollars will be escaped
- # by the subsequent replacement. Easiest to add \backslash
- # now and then add the dollars
- $paragraph =~ s/\\/\\backslash/g;
-
- # Must be done after escape of \ since this command adds latex escapes
- # Replace characters that can be escaped
- $paragraph =~ s/([\$\#&%_{}])/\\$1/g;
-
- # Replace ^ characters with \^{} so that $^F works okay
- $paragraph =~ s/(\^)/\\$1\{\}/g;
-
- # Replace tilde (~) with \texttt{\~{}}
- # $paragraph =~ s/~/\\texttt\{\\~\{\}\}/g;
- $paragraph =~ s/~/\\~\{\}/g;
-
- # Now add the dollars around each \backslash
- $paragraph =~ s/(\\backslash)/\$$1\$/g;
- return $paragraph;
-} ## end sub latex_escape
-# }}}
-
-# Loop over all commits {{{
-my $which_line = 0;
-my @changes;
-for (@lines) {
- next if /\A\Z/xms;
- chomp;
- if ( m/^([0-9a-f]{40})\s/g and !$which_line) {
- $which_line ^= 1; ## additional toggle for merge commits
- @changes = ( "-", "-", "-" );
- }
- if ($which_line) {
- s/\A([0-9a-f]{40})\s//xms or die "Did not match the commit hash\n";
- my $tags = exists $commit_tags{$1} ? $commit_tags{$1} : q();
- my $date_author = '';
- my $c_msg = '';
- if ($print_author) {
- /(?:& )(.*?)NoTinAuthorFiled(& .*? &) (.*)/;
- $date_author = latex_escape($1) . $2;
- $c_msg = $3;
- }
- else {
- /(.*? &) (.*)/;
- $date_author = $1;
- $c_msg = $2;
- }
- if ( defined $git_commit_address ) {
- $c_msg =~ /(.*?) & (.*)/;
- $c_msg = sprintf '\\href{%s/%s}{%s}', $git_commit_address, $1, latex_escape($2);
- }
- else {
- $c_msg = latex_escape($c_msg);
- }
- say "\\hline $commit_count & $tags & $date_author $c_msg & " . join( ' & ', @changes ) . ' \\\\';
- $commit_count++;
- } ## end if ($which_line)
- else {
- @changes = ( 0, 0, 0 );
- /(\d+) files? changed/ and $changes[0] = $1;
- /(\d+) insertions?/ and $changes[1] = $1;
- /(\d+) deletions?/ and $changes[2] = $1;
- }
- $which_line ^= 1; ## toggle bit
-} ## end for (@lines)
-say '\end{longtable}';
-# }}}
-
-__END__
-# Documentation {{{
-
-=encoding UTF-8
-=head1 NAME
-
-latex-git-log - Generates the version history of a git project as LaTeX source code.
-
-=head1 Synopsis
-
-latex-git-log [options]
-
-Options:
-
- --author set this if you want the author included
- --startcommit set the start value of count commit
- --width set the width in cm of the commit message field in the LaTeX table
- --git-c-add set an base URL to link to a commit
- --user set a github user to derive the base URL
- --repo set a github repository to derive the base URL
- --lang language of the legend and all strings in the output
- --version, -v print version of this script
- --help brief help message
- --man full documentation
- --range specify a git revision range
-
-=head1 Options
-
-=over 8
-
-=item B<--width>
-
-Set the width in cm of the commit message field in the LaTeX table. If this
-parameter is not set then the table is not vertically limited. That means that
-if you have a very long commit message then the table will probably not fit on
-the page and you will get a "Overfull" error message from TeX.
-
-In this case you should specify the width of the column containing the commit messages.
-I normally use something like --width=14 for DIN A4 in landscape.
-
-=item B<--git-c-add>
-
-Set an base URL to link to a commit.
-This script will automatically try to use the base URL for github.
-
-=item B<--lang>
-
-Set the language of the legend and all strings in the output. By default the
-language of your system is used but you can overwrite this with this parameter.
-
-Currently this script only supports English and German. If you need a translation
-to another language then you can either create a .po file or I can register
-this project on one of those websites for online translation.
-
-=back
-
-=head1 Example
-
-You can use it like this:
-
- latex-git-log --width=6 --lang=en > example-output.tex
-
-=head1 Dependencies
-
-=head2 Of this script
-
-This module requires these other modules and libraries:
-
- IPC::System::Simple
- Locale::Maketext::Simple
-
-Everything else should already be installed.
-
-=head2 To compile the output
-
-The table is using the B<longtable> package and the links to a web resource for
-each commit use the \href macro from B<hyperref>. So these two packages have to
-be loaded.
-
-Furthermore you need to defined the macro B<\longtableendfoot> which will be
-expanded on the bottom of every page if the table will be continued on the next
-page. You can defined it to a localized message to inform the reader that this
-table is not complete and will be continued.
-
-=head1 Description
-
-B<This program> will output the entire version history as table written in
-LaTeX if it is executed within a git repository.
-
-It is intended that you redirect the standard output of this script to a file
-which can then be included from your main LaTeX document.
-
-Because the table can be very large you might want to put the thing on a
-landscape page.
-
-=head1 Version
-
-1.0.0
-
-=head1 Author
-
-Robin Schneider <ypid@riseup.net>
-
-=head1 Development
-
-CTAN: https://ctan.org/pkg/latex-git-log
-
-Source code repository: https://github.com/ypid/typesetting/tree/master/scripts/latex-git-log
-
-Please report bugs and feature requests at https://github.com/ypid/typesetting/issues
-
-=head1 License and Copyright
-
-Copyright (C) 2012-2013,2017,2019 Robin Schneider <ypid@riseup.net>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Dieses Programm ist Freie Software: Sie können es unter den Bedingungen
-der GNU General Public License, wie von der Free Software Foundation,
-Version 3 der Lizenz oder (nach Ihrer Option) jeder späteren
-veröffentlichten Version, weiterverbreiten und/oder modifizieren.
-
-Dieses Programm wird in der Hoffnung, dass es nĂĽtzlich sein wird, aber
-OHNE JEDE GEWĂ„HRLEISTUNG, bereitgestellt; sogar ohne die implizite
-Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
-Siehe die GNU General Public License fĂĽr weitere Details.
-
-Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
-Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>.
-
-=cut
-# }}}
diff --git a/Build/source/texk/texlive/linked_scripts/latex-papersize/latex-papersize.py b/Build/source/texk/texlive/linked_scripts/latex-papersize/latex-papersize.py
deleted file mode 100755
index a20d746273e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latex-papersize/latex-papersize.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/env python
-r"""
-Calculate LaTeX paper and margin settings for arbitrary magnification
-(C) Silas S. Brown, 2005-2009, 2016, 2019. Version 1.63.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-When producing enlarged material in LaTeX for people with
-low vision, it's often not enough to simply add such
-things as "\Large" because that doesn't enlarge
-_everything_ and it can be difficult to achieve the exact
-desired size, especially if unusual packages are being
-used as well.
-
-It's more effective to change the LaTeX paper size and
-margin settings to simulate SMALL PAPER, and then magnify
-the result up to the desired physical paper size. This
-magnifies everything, and also adds some clarity for
-low-vision users because fonts like CMR have different
-versions at different sizes and the small-sized versions
-are often meant to be clearer.
-
-This is a Python script to calculate the necessary
-settings for arbitrary font and page sizes.
-Works in both Python 2 and Python 3.
-
-BASIC USAGE
-
-In the following instructions, base-size is the point size
-that the TeX file is based on (if the documentclass
-specifies 12pt then \small=11 normal=12 \large=14
-\Large=17 \LARGE=20 \huge=25), and desired-size is the
-point size that you want to produce.
-
-The command-line parameters depend on whether you are
-using latex/dvips or pdflatex.
-
-FOR USE WITH LATEX AND DVIPS:
-
-To print the geometry settings:
-
-python latex-papersize.py base-size desired-size tex
-
-e.g.: python latex-papersize.py 12 26 tex
-
-(If you install latex-papersize.py as /usr/local/bin/latex-papersize,
-then you can say "latex-papersize" instead of "python latex-papersize.py"
-throughout these examples.)
-
-The output of this command should then be placed after
-\documentclass in your .tex file.
-
-Then run latex to make a DVI file, and then do:
-
-python latex-papersize.py base-size desired-size dvi-file
-
-e.g.: python latex-papersize.py 12 26 myfile.dvi
-
-which will print the appropriate dvips command.
-
-FOR USE WITH PDFLATEX:
-
-With pdflatex you need only one command:
-
-python latex-papersize.py base-size desired-size pdftex
-
-the output of this command should go just before \begin{document}.
-NB if using hyperref package, put hyperref AFTER these
-settings (and if also using pinyin package then put pinyin
-package after that again)
-
-PAGE NUMBERS:
-
-When invoking latex-papersize.py with the "tex" or "pdftex"
-options, you can optionally add a fourth parameter to
-specify how many points to leave for page numbers at the
-bottom of each page. Normally 15 is a good idea. Leaving
-this out causes no room to be left for page numbers and
-\pagestyle{empty} to be added. This does not affect the
-dvips command.
-
-PAPER SIZES AND MARGINS:
-
-It is assumed that the final physical printout will be on
-A4 portrait with 10mm margins. You can override this by
-setting the paper_width and paper_height environment
-variables (in millimetres) before running, e.g.:
-paper_width=297 paper_height=210 python latex-papersize.py ...
-You can also set the environment variables margin_left and
-margin_top (the right and bottom margins are assumed to be
-mirrors of these).
-
-If using with non-PDF latex, remember to set the
-environment variables again when asking latex-papersize.py for
-the dvips command. Or "export" them so they remain set.
-
-POSTER PRINTING:
-
-If you want to print on a physical paper size that is
-larger than your printer can handle, you can make up the
-larger size by sticking together smaller pieces of paper.
-Perhaps the best way to do this is to use a separate
-utility that knows about printable areas, cut margins,
-etc, such as Jos van Eijndhoven's "poster" utility (last
-known URL: ftp://ftp.es.ele.tue.nl/pub/users/jos/poster/poster.tar.gz )
-
-In this case you can give latex-papersize.py a margin_left and
-margin_top of 0 (because "poster" will handle the
-margins), set the paper size and desired point size
-appropriate for the final poster, use latex/dvips, and run
-the resulting .ps through "poster" with "-s 1". This is
-better than getting "poster" to scale, because if any of
-your fonts are rendered into bitmaps by Metafont (as some
-CJK fonts are) then you will likely get a better
-resolution if the final size is given to latex-papersize.py
-rather than to "poster".
-
-If you're aiming for a specific number of sheets of paper,
-don't pick a physical size that's an exact multiple of
-your printer's paper size, because "poster" accounts for
-unprintable areas and overlaps slightly. Multiply the
-printer paper's height and width by 0.88 (or 0.86 if you
-want a visual margin added to the finished poster besides
-the cutting margins) and try a multiple of that size.
-
-EXAMPLE USAGE IN A SCRIPT:
-
-To typeset a LaTeX file "file.tex" and magnify from
-12-point to 26-point, type a line such as the following
-(after adjusting the documentclass it specifies, and
-removing or commenting out the documentclass in file.tex):
-
-latex "\\documentclass[12pt]{article}$(python latex-papersize.py 12 26 tex)\\input{file.tex}" && mv article.dvi file.dvi
-
-Or in pdflatex (slightly more complex because we need to
-put the settings just before \begin{document}):
-cat file.tex | awk -- "/^ *\\\\begin *\\{document\\}[^#-~]*\$/ { print \"$(python latex-papersize.py 12 26 pdftex | sed -e 's/\\/\\\\/g')\" } { print }" > /tmp/tmp.tex
-pdflatex "\documentclass[12pt]{article}\\input{/tmp/tmp.tex}" && mv article.pdf file.pdf
-
-To run dvips on the .dvi file (not needed for pdflatex):
-
-$(python latex-papersize.py 12 26 file.dvi)
-"""
-
-import os, sys, math
-try: from commands import getoutput # Python 2
-except: from subprocess import getoutput # Python 3
-def hasKey(a,b):
- try: return a.has_key(b) # old Python 2
- except: return b in a # newer Python 2 + Python 3
-if len(sys.argv)==2 and sys.argv[1]=="--help":
- print(__doc__.strip()); raise SystemExit
-if len(sys.argv)==2 and sys.argv[1]=="--version":
- print(__doc__[:__doc__.find("\n\n")].strip()); raise SystemExit
-
-base_pointsize = float(sys.argv[1])
-desired_pointsize = float(sys.argv[2])
-
-if len(sys.argv)>4:
- extra_bottom_margin_mm = float(sys.argv[4])*25.4/72
- pageStyle = ""
-else:
- extra_bottom_margin_mm = 0
- pageStyle = " \\pagestyle{empty}"
-
-if hasKey(os.environ,"paper_width"): paper_width=float(os.environ["paper_width"])
-else: paper_width=210
-if hasKey(os.environ,"paper_height"): paper_height=float(os.environ["paper_height"])
-else: paper_height=297
-if hasKey(os.environ,"margin_left"): margin_left=float(os.environ["margin_left"])
-else: margin_left=10
-if hasKey(os.environ,"margin_top"): margin_top=float(os.environ["margin_top"])
-else: margin_top=10
-
-paper_magstep = 1.0*desired_pointsize/base_pointsize
-paperwidth = paper_width/paper_magstep
-textwidth = (paper_width-2*margin_left)/paper_magstep
-paperheight = paper_height/paper_magstep
-textheight = (paper_height-2*margin_top)/paper_magstep-extra_bottom_margin_mm # note extra_bottom_margin_mm is NOT divided by paper_magstep because it corresponds to the height of the textual page-number, which will be magnified
-margin_left_setting = margin_left/paper_magstep
-margin_top_setting = margin_top/paper_magstep
-
-if sys.argv[3]=="tex" or sys.argv[3]=="pdftex":
- s="\\textwidth=%.1fmm \\textheight=%.1fmm \\topmargin=%.1fmm \\marginparwidth=0mm \\oddsidemargin=%.1fmm \\evensidemargin=%.1fmm \\columnsep=%.1fmm%s" % (textwidth,textheight,margin_top_setting,margin_left_setting,margin_left_setting,margin_left_setting,pageStyle)
- if sys.argv[3]=="pdftex":
- s += "\\mag=%d \\pdfpagewidth=%d true mm \\pdfpageheight=%d true mm \\pdfhorigin=0 mm \\pdfvorigin=-12.95 mm \\paperwidth=%d true mm \\paperheight=%d true mm" % (1000*paper_magstep,paper_width,paper_height,paper_width,paper_height) # the -12.95mm seems to be a constant regardless of magnification (previous version had -14 but it sems -12.95 is more accurate - at least 12.9 is too small and 13 is too big). Need \paperwidth and \paperheight in there as well in case using hyperref.
- print(s)
-else:
- r = os.system("dvips -T %dmm,%dmm -x %d %s -o bbox_test.ps" % (paper_width*10,paper_height*10,1000*paper_magstep+0.5,sys.argv[3]))
- assert not r, "dvips failed"
- # Now, that would have got the origin wrong. I can't
- # figure out how dvips origin and magstep is supposed to
- # interoperate, so let's work it out on a case-by-case
- # basis from the bounding box.
- # (Note: multiplying paper_width and paper_height by 10 above, because if dealing with very small paper sizes then this may give a reading of 0 if the origin is off the page. Increasing the paper size doesn't seem to affect the origin.)
- bbox=getoutput("echo|gs -sDEVICE=bbox bbox_test.ps 2>&1|grep BoundingBox")
- # (previous version used 'head -1' to take only the first page, but that can cause 'broken pipe' errors if the file contains too many pages, and will give an incorrect result if there is only one line per page and it is indented on the first page, so we'll look at ALL the pages and take the outermost bounds. Will also look at high-resolution bounding boxes only, if available.)
- if "HiResBoundingBox" in bbox: bbox=filter(lambda x:"HiRes" in x,bbox.split("\n"))
- else: bbox=bbox.split("\n")
- bbox = map(lambda x:tuple(map(lambda y:float(y),x.split(" ")[1:])), bbox)
- bbox = filter(lambda x: not x==(0,0,0,0), bbox)
- assert bbox, "Could not get a sensible bounding box from bbox_test.ps. (If you're on Ubuntu, beware of bug #160203 in Ubuntu's ghostscript package.)"
- os.unlink("bbox_test.ps")
- existing_left_margin_mm = min(map(lambda x:x[0],bbox))*25.4/72
- existing_top_margin_mm = paper_height*10-max(map(lambda x:x[3],bbox))*25.4/72
- print("dvips -T %dmm,%dmm -O %.1fmm,%.1fmm -x %d %s" % (paper_width,paper_height,margin_left - existing_left_margin_mm,margin_top - existing_top_margin_mm,1000*paper_magstep+0.5,sys.argv[3]))
diff --git a/Build/source/texk/texlive/linked_scripts/latex2man/latex2man b/Build/source/texk/texlive/linked_scripts/latex2man/latex2man
deleted file mode 100755
index e117d3370be..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latex2man/latex2man
+++ /dev/null
@@ -1,2052 +0,0 @@
-#!/usr/bin/env perl
-#!/usr/bin/perl -w
-# Project: Documentation Tools
-# Descr: Latex --> MAN-page (groff -man), HTML and TexInfo;
-# Language: PERL (>= 5.0)
-# Author: Dr. Jürgen Vollmer, Juergen.Vollmer@informatik-vollmer.de
-# $Id: latex2man,v 1.181 2018/11/25 13:05:37 vollmer Exp $
-#
-# Copyright (C) 1998 Dr. Juergen Vollmer
-# Am Rennbuckel 21, D-76185 Karlsruhe, Germany
-# Juergen.Vollmer@informatik-vollmer.de
-# License:
-# This program can be redistributed and/or modified under the terms
-# of the LaTeX Project Public License Distributed from CTAN
-# archives in directory macros/latex/base/lppl.txt; either
-# version 1 of the License, or any later version.
-#
-# If you find this software useful, please send me a postcard.
-
-require 5.0004_03;
-
-use Getopt::Std;
-use File::Basename;
-no warnings 'once';
-# use strict 'vars';
-
-$CMD = basename ($0);
-$gen_date = localtime(); # date when the output was generated
-
-sub date2str;
-$VERSION = "1.29";
-$DATE = date2str ('$Date: 2018/11/25 13:05:37 $' =~ m|(\d+/\d+/\d+)|);
-
-$tmp = "/tmp/$CMD.$$";
-
-##################################################################
-# check option and arguments
-##################################################################
-
-$opt_D = 0;
-$opt_M = 0;
-getopts('o:t:c:VhMHTLC:D:a:'); # -D1: write each read line -D2: write each word
-
-sub usage
-{
-print <<'END';
-usage: latex2man [-t transfile] [-c cssfile] [-HTML] [-C name] [-h] [-V] infile outfile.
- A tool to translate UNIX manual pages written with LaTeX into a format
- understood by the UNIX man(1)-command.
- Reads infile, writes outfile.
-
- -t transfile: Translation for user defined LaTeX macros.
- -c CSSfile: If -H is given, add a link to the \`CSSfile\' and use those
- CSS definitions.
- -M: Produce output suitable for the man(1) command (default).
- -H: Instead of producing output suitable for the man(1) command,
- HTML code is produced (despite of the name of the command).
- -T: Instead of producing output suitable for the man(1) command,
- TEXINFO code is produced (despite of the name of the command).
- -L: Output the LaTeX source. Useful in conjunctin with the -C
- option.
- -C name: Enable conditional text \`name\'.
- To enable more than one conditional name use quotes:
- -C 'name1 name2 ...'
- The following names are defined automatically:
- -H defines HTML
- -T defines TEXI
- -M defines MAN
- -L defines LATEX
- -a char: Is used only in conjunction with -T.
- Background:
- TEXINFO ignores all blanks before the first word on a
- new line. In order to produce some additional space before
- that word (using \SP) some character has to be printed
- before the additional space. By default this is a . (dot).
- The 'char' specifies an alternative for that first character.
- Giving a blank (-a" ") supresses the indentation of a line.
- Note: only for the first \SP of a series that char is printed.
- -h: Help.
- -V: Version.
-
- Copyright (C) 1998 Dr. Jürgen Vollmer, Am Rennbuckel 21, D-76185 Karlsruhe
- email: Juergen.Vollmer@informatik-vollmer.de
- License:
- This program can be redistributed and/or modified under the terms
- of the LaTeX Project Public License Distributed from CTAN
- archives in directory macros/latex/base/lppl.txt; either
- version 1 of the License, or any later version.
-
- If you find this software useful, please send me a postcard from the place
- where you are living.
-END
- print " Version $VERSION, $DATE.\n";
- exit 1;
-}
-
-($opt_h) && usage;
-($opt_V) && print "Version: $VERSION, $DATE\n";
-
-# check command line arguments
-$opt_cnt = 0;
-$opt_cnt++ if ($opt_H);
-$opt_cnt++ if ($opt_T);
-$opt_cnt++ if ($opt_M);
-$opt_cnt++ if ($opt_L);
-if ($opt_cnt == 0) {
- # if no option -H, -T, -M, -L is given, -M is the default
- $opt_M = 1;
-}
-die "$CMD: you may give only one of the -H -T -M -L options\n" if ($opt_cnt > 1);
-
-(@ARGV == 2) || die "$CMD: Expected two arguments: infile outfile. Try \`$CMD -h'.\n";
-
-my %cond_name;
-if ($opt_C) {
- my $name;
- foreach $name ((split (/\s/, $opt_C))) {
- $cond_name{$name} = 1;
- }
-}
-$cond_name{MAN} = 1 if ($opt_M);
-$cond_name{HTML} = 1 if ($opt_H);
-$cond_name{TEXI} = 1 if ($opt_T);
-$cond_name{LATEX} = 1 if ($opt_L);
-
-$SrcFile = $ARGV[0];
-$DestFile = $ARGV[1];
-
-########################################################################
-
-# global variables
-
-# $Prefix is used to construct procedure and variable names
-$Prefix = "";
-if ($opt_M) {
- $Prefix = "man";
-}
-if ($opt_H) {
- $Prefix = "html";
-}
-if ($opt_T) {
- $Prefix = "texi";
-}
-
-$texiCenterLine = 0; # true, only in TEXI-mode if a line must be centered
-$paragraph = 0; # true, if the last output was a paragraph marker
-$newline = 0; # true, if the last output was a newline char
-
-$first_word = 1; # true, if the next word to be processed is the first
- # of a new paragraph or after a line break.
-
-# handling of itemize/enumerate/description environments:
-$list_nest = 0; # counts nesting of itemize/enumerate/description envrionments
-$cur_list[0] = "";# array, indexed with list_nest, indicates kind of list:
- # values are: 'enum' / 'descr' / 'item'
-$item_nr[0] = 0; # array, indexed with list_nest, counts the number of \item in the
- # list
-$manRS = 0; # true, if for Man a .RS was given after a \item
-
-$inside_verb = 0; # true, if inside a verbatim environment
-$inside_table = 0; # true, if inside a table environment
-$first_column = 0; # true, if this is the first column in a table row
-$columns = 0; # nr of columns in the current table
-# $enum_nr = 0; # current number of an enumeration
-$nesting = 0; # count recursive calls of interpret_word
-$section_cnt = 0; # Index into $sections
-#$sections[0] # Array of all sections
-#$section_kind # Array of section kind (subsection/section)
-
-# translation of LaTeX macros without, with one and with two arguments
-$Macro = \%{$Prefix . "Macro"};
-$Macro1a = \%{$Prefix . "Macro1a"};
-$Macro1b = \%{$Prefix . "Macro1b"};
-$Macro2a = \%{$Prefix . "Macro2a"};
-$Macro2b = \%{$Prefix . "Macro2b"};
-$Macro2c = \%{$Prefix . "Macro2c"};
-
-# translations of special characters
-$LetterCode = \%{$Prefix . "LetterCode"};
-
-########################################################################
-
-sub interpret_word;
-sub interpret_line;
-sub Print;
-sub PrintM;
-sub NL;
-
-########################################################################
-# Translation for LaTeX macros for MAN
-
-# translation of special characters
-$manLetterCode{'ä'} = 'ä';
-$manLetterCode{'ö'} = 'ö';
-$manLetterCode{'ü'} = 'ü';
-$manLetterCode{'Ä'} = 'Ä';
-$manLetterCode{'Ö'} = 'Ö';
-$manLetterCode{'Ü'} = 'Ü';
-$manLetterCode{'ß'} = 'ß';
-
-# LaTeX macros without arguments
-$manMacro{'LaTeX'} = 'LaTeX';
-$manMacro{'LATEX'} = 'LaTeX'; # needed, since \LaTeX is contained in a
- # section name (which are transposed
- # into uppercase
-$manMacro{'itemsep'} = ' ';
-
-# some math
-$manMacro{'rightarrow'} = '-->';
-$manMacro{'Rightarrow'} = '==>';
-$manMacro{'leftarrow'} = '<--';
-$manMacro{'Leftarrow'} = '<==';
-$manMacro{'ge'} = '>=';
-$manMacro{'le'} = '<=';
-
-$manMacro{'Dollar'} = '$';
-$manMacro{'Bar'} = '|';
-$manMacro{'Bs'} = '\\\\';
-$manMacro{'Tilde'} = '~';
-$manMacro{'hline'} = '\n_';
-$manMacro{'noindent'} = '';
-$manMacro{'copyright'} = '(C)';
-$manMacro{'Dots'} = '\&...\n';
-$manMacro{'Circum'} = '^';
-$manMacro{'Lbr'} = '[';
-$manMacro{'Rbr'} = ']';
-$manMacro{'LBr'} = '{';
-$manMacro{'RBr'} = '}';
-$manMacro{'Percent'} = '%';
-$manMacro{'Bullet'} = '*';
-$manMacro{'TEXbr'} = '';
-$manMacro{'MANbr'} = '\n.br\n';
-$manMacro{'TEXIbr'} = '';
-$manMacro{'HTMLbr'} = '';
-$manMacro{'medskip'} = '\n';
-$manMacro{'SP'} = '\fB \fP'; # hack hack this works even on
- # the beginning of a line
-$manMacro{'SPfirst'} = $manMacro{'SP'};
-
-$manMacro{'~'} = ' ';
-$manMacro{'|'} = '|';
-$manMacro{'<'} = '<';
-$manMacro{'>'} = '>';
-$manMacro{'<='} = '<=';
-$manMacro{'>='} = '>=';
-$manMacro{'='} = '=';
-$manMacro{'<>'} = '<>';
-$manMacro{'{'} = '{';
-$manMacro{'}'} = '}';
-$manMacro{'_'} = '_';
-$manMacro{'$'} = '$';
-$manMacro{'#'} = '#';
-$manMacro{'&'} = '&';
-$manMacro{'%'} = '%';
-$manMacro{'-'} = '';
-$manMacro{','} = ' ';
-
-$manMacro{'\\'} = '\n.br'; # line break
-$manMacro{'\\Tab'} = '\nT}'; # end of column in a table environment
-
-# LaTeX macros with one argument
-$manMacro1a{'emph'} = '\fI';
- $manMacro1b{'emph'} = '\fP';
-$manMacro1a{'textbf'} = '\fB';
- $manMacro1b{'textbf'} = '\fP';
-$manMacro1a{'texttt'} = '';
- $manMacro1b{'texttt'} = '';
-$manMacro1a{'verb'} = '';
- $manMacro1b{'verb'} = '';
-$manMacro1a{'underline'} = '\n.ul\n';
- $manMacro1b{'underline'}= '\n';
-$manMacro1a{'section'} = '\n.SH ';
- $manMacro1b{'section'} = '\n';
-$manMacro1a{'subsection'} = '\n.SS ';
- $manMacro1b{'subsection'} = '';
-$manMacro1a{'subsubsection'} = '\n.SS ';
- $manMacro1b{'subsubsection'} = '';
-
-$manMacro1a{'Prog'} = '';
- $manMacro1b{'Prog'} = '';
-$manMacro1a{'File'} = '';
- $manMacro1b{'File'} = '';
-$manMacro1a{'Opt'} = '\fB';
- $manMacro1b{'Opt'} = '\fP';
-$manMacro1a{'oOpt'} = '[\fB';
- $manMacro1b{'oOpt'} = '\fP]';
-$manMacro1a{'Arg'} = '\fI';
- $manMacro1b{'Arg'} = '\fP';
-$manMacro1a{'oArg'} = '[\fI';
- $manMacro1b{'oArg'} = '\fP]';
-$manMacro1a{'Email'} = '\fB';
- $manMacro1b{'Email'} = '\fP';
-$manMacro1a{'URL'} = '\fB';
- $manMacro1b{'URL'} = '\fP';
-
-# LaTeX macros with two arguments
-$manMacro2a{'Cmd'} = '\fI';
- $manMacro2b{'Cmd'} = '\fP(';
- $manMacro2c{'Cmd'} = ')';
-$manMacro2a{'OptArg'} = '\fB';
- $manMacro2b{'OptArg'} = '\fP\fI';
- $manMacro2c{'OptArg'} = '\fP';
-$manMacro2a{'OptoArg'} = '\fB';
- $manMacro2b{'OptoArg'} = '\fP[\fI';
- $manMacro2c{'OptoArg'} = '\fP]';
-$manMacro2a{'oOptArg'} = '[\fB';
- $manMacro2b{'oOptArg'} = '\fP\fI';
- $manMacro2c{'oOptArg'} = '\fP]';
-$manMacro2a{'oOptoArg'} = '[\fB';
- $manMacro2b{'oOptoArg'} = '\fP[\fI';
- $manMacro2c{'oOptoArg'} = '\fP]]';
-$manMacro2a{'setlength'} = '';
- $manMacro2b{'setlength'}= '';
- $manMacro2c{'setlength'}= '';
-
-########################################################################
-# Translation for LaTeX macros for HTML
-
-# translation of special characters
-$htmlLetterCode{'ä'} = '&auml;';
-$htmlLetterCode{'ö'} = '&ouml;';
-$htmlLetterCode{'ü'} = '&uuml;';
-$htmlLetterCode{'Ä'} = '&Auml;';
-$htmlLetterCode{'Ö'} = '&Ouml;';
-$htmlLetterCode{'Ü'} = '&Uuml;';
-$htmlLetterCode{'ß'} = '&szlig;';
-
-# LaTeX macros without arguments
-$htmlMacro{'LaTeX'} = 'LaTeX';
-$htmlMacro{'LATEX'} = 'LaTeX'; # needed, since \LaTeX is contained in a
- # section name (which are transposed
- # into uppercase
-$htmlMacro{'itemsep'} = '';
-
-# some math
-$htmlMacro{'rightarrow'} = '--&gt;';
-$htmlMacro{'Rightarrow'} = '==&gt;';
-$htmlMacro{'leftarrow'} = '&lt;--';
-$htmlMacro{'Leftarrow'} = '&lt;==';
-$htmlMacro{'ge'} = '&gt;';
-$htmlMacro{'le'} = '&lt;=';
-
-$htmlMacro{'Dollar'} = '$';
-$htmlMacro{'Bar'} = '|';
-$htmlMacro{'Bs'} = '\\';
-$htmlMacro{'Tilde'} = '~';
-$htmlMacro{'hline'} = '';
-$htmlMacro{'noindent'} = '';
-$htmlMacro{'copyright'} = '&copy;';
-$htmlMacro{'Dots'} = '...';
-$htmlMacro{'Circum'} = '^';
-$htmlMacro{'Lbr'} = '[';
-$htmlMacro{'Rbr'} = ']';
-$htmlMacro{'LBr'} = '{';
-$htmlMacro{'RBr'} = '}';
-$htmlMacro{'Percent'} = '%';
-$htmlMacro{'Bullet'} = '*';
-$htmlMacro{'TEXbr'} = '';
-$htmlMacro{'MANbr'} = '';
-$htmlMacro{'TEXIbr'} = '';
-$htmlMacro{'HTMLbr'} = '<br>\n';
-$htmlMacro{'medskip'} = '<br>\n';
-$htmlMacro{'SP'} = '&nbsp;&nbsp;';
-$htmlMacro{'SPfirst'} = $htmlMacro{'SP'};
-
-$htmlMacro{'~'} = '&nbsp;';
-$htmlMacro{'|'} = '|';
-$htmlMacro{'<'} = '&lt;';
-$htmlMacro{'>'} = '&gt;';
-$htmlMacro{'<='} = '&lt;=';
-$htmlMacro{'>='} = '&gt;=';
-$htmlMacro{'='} = '=';
-$htmlMacro{'<>'} = '&lt;&gt;';
-$htmlMacro{'{'} = '{';
-$htmlMacro{'}'} = '}';
-$htmlMacro{'_'} = '_';
-$htmlMacro{'$'} = '$';
-$htmlMacro{'#'} = '#';
-$htmlMacro{'&'} = '&amp;';
-$htmlMacro{'%'} = '%';
-$htmlMacro{'-'} = '';
-$htmlMacro{','} = ' ';
-
-$htmlMacro{'\\'} = '<br>\n'; # line break
-$htmlMacro{'\\Tab'} = '</td>\n</tr>\n'; # end of column in a table environment
-
-# LaTeX macros with one argument
-$htmlMacro1a{'emph'} = '<em>';
- $htmlMacro1b{'emph'} = '</em>';
-$htmlMacro1a{'textbf'} = '<strong>';
- $htmlMacro1b{'textbf'} = '</strong>';
-$htmlMacro1a{'texttt'} = '<tt>';
- $htmlMacro1b{'texttt'} = '</tt>';
-$htmlMacro1a{'verb'} = '<tt>';
- $htmlMacro1b{'verb'} = '</tt>';
-$htmlMacro1a{'underline'} = '<u>';
- $htmlMacro1b{'underline'} = '</u>';
- $htmlMacro1a{'section'} = '\n<h2>';
- $htmlMacro1b{'section'} = '</h2>\n';
- $htmlMacro1a{'subsection'} = '\n<h4>';
- $htmlMacro1b{'subsection'} = '</h4>\n';
- $htmlMacro1a{'subsubsection'} = '\n<h5>';
- $htmlMacro1b{'subsubsection'} = '</h5>\n';
-if ($opt_c) {
- # use CSS
- # thanks to Tom Brand <tbrand@manumit-systems.com>
- $htmlMacro1a{'Email'} = '\n<font class="emailstyle">';
- $htmlMacro1b{'Email'} = '</font>';
- $htmlMacro1a{'URL'} = '\n<font class="urlstyle">';
- $htmlMacro1b{'URL'} = '</font>';
-
- $htmlMacro1a{'Prog'} = '<font class="progname">';
- $htmlMacro1b{'Prog'} = '</font>';
- $htmlMacro1a{'File'} = '<font class="filename">';
- $htmlMacro1b{'File'} = '</font>';
- $htmlMacro1a{'Opt'} = '<font class="optstyle">';
- $htmlMacro1b{'Opt'} = '</font>';
- $htmlMacro1a{'oOpt'} = '[<font class="optstyle">';
- $htmlMacro1b{'oOpt'} = '</font>]';
- $htmlMacro1a{'Arg'} = '<font class="argstyle">';
- $htmlMacro1b{'Arg'} = '</font>';
- $htmlMacro1a{'oArg'} = '[<font class="argstyle">';
- $htmlMacro1b{'oArg'} = '</font>]';
-} else {
- # don't use CSS
- $htmlMacro1a{'Email'} = '\n<tt>';
- $htmlMacro1b{'Email'} = '</tt>';
- $htmlMacro1a{'URL'} = '\n<tt>';
- $htmlMacro1b{'URL'} = '</tt>';
-
- $htmlMacro1a{'Prog'} = '<tt>';
- $htmlMacro1b{'Prog'} = '</tt>';
- $htmlMacro1a{'File'} = '<tt>';
- $htmlMacro1b{'File'} = '</tt>';
- $htmlMacro1a{'Opt'} = '<b>';
- $htmlMacro1b{'Opt'} = '</b>';
- $htmlMacro1a{'oOpt'} = '[<b>';
- $htmlMacro1b{'oOpt'} = '</b>]';
- $htmlMacro1a{'Arg'} = '<i>';
- $htmlMacro1b{'Arg'} = '</i>';
- $htmlMacro1a{'oArg'} = '[<i>';
- $htmlMacro1b{'oArg'} = '</i>]';
-}
-
-# LaTeX macros with two arguments
-if (opt_c) {
- $htmlMacro2a{'Cmd'} = '<font class="commandname">';
- $htmlMacro2b{'Cmd'} = '</font>(';
- $htmlMacro2c{'Cmd'} = ')';
- $htmlMacro2a{'OptArg'} = '<font class="optstyle">';
- $htmlMacro2b{'OptArg'} = '</font><font class="argstyle">';
- $htmlMacro2c{'OptArg'} = '</font>';
- $htmlMacro2a{'OptoArg'} = '<font class="optstyle">';
- $htmlMacro2b{'OptoArg'} = '</font>[<font class="argstyle">';
- $htmlMacro2c{'OptoArg'} = '</font>]';
- $htmlMacro2a{'oOptArg'} = '[<font class="optstyle">';
- $htmlMacro2b{'oOptArg'} = '</font><font class="argstyle">';
- $htmlMacro2c{'oOptArg'} = '</font>]';
- $htmlMacro2a{'oOptoArg'} = '[<font class="optstyle">';
- $htmlMacro2b{'oOptoArg'} = '</font>[<font class="argstyle">';
- $htmlMacro2c{'oOptoArg'} = '</font>]]';
-} else {
- $htmlMacro2a{'Cmd'} = '<em>';
- $htmlMacro2b{'Cmd'} = '</em>(';
- $htmlMacro2c{'Cmd'} = ')';
- $htmlMacro2a{'OptArg'} = '<b>';
- $htmlMacro2b{'OptArg'} = '</b><i>';
- $htmlMacro2c{'OptArg'} = '</i>';
- $htmlMacro2a{'OptoArg'} = '<b>';
- $htmlMacro2b{'OptoArg'} = '</b>[<i>';
- $htmlMacro2c{'OptoArg'} = '</i>]';
- $htmlMacro2a{'oOptArg'} = '[<b>';
- $htmlMacro2b{'oOptArg'} = '</b><i>';
- $htmlMacro2c{'oOptArg'} = '</i>]';
- $htmlMacro2a{'oOptoArg'} = '[<b>';
- $htmlMacro2b{'oOptoArg'} = '</b>[<i>';
- $htmlMacro2c{'oOptoArg'} = '</i>]]';
-}
-$htmlMacro2a{'setlength'} = '';
- $htmlMacro2b{'setlength'} = '';
- $htmlMacro2c{'setlength'} = '';
-
-# we handle sections in HTML as having two arguments, 1. the number, 2. the name
-if ($opt_c) {
- # use CSS
- # thanks to Tom Brand <tbrand@manumit-systems.com>
- $htmlMacro2a{'section'} = '\n<h2 class="sectionname"><a name="section_';
- $htmlMacro2b{'section'} = '">';
- $htmlMacro2c{'section'} = '</a></h2>\n';
- $htmlMacro2a{'subsection'} = '\n<h4 class="subsectionname"><a name="section_';
- $htmlMacro2b{'subsection'} = '">';
- $htmlMacro2c{'subsection'} = '</a></h4>\n';
- $htmlMacro2a{'subsubsection'} = '\n<h5 class="subsubsectionname"><a name="section_';
- $htmlMacro2b{'subsubsection'} = '">';
- $htmlMacro2c{'subsubsection'} = '</a></h5>\n';
-
- # we handle Email and URL special in HTML, the LaTeX argument is doubled.
- $htmlMacro2a{'Email'} = '<a class="emailstyle" href ="mailto:';
- $htmlMacro2b{'Email'} = '">';
- $htmlMacro2c{'Email'} = '</a>';
- $htmlMacro2a{'URL'} = '<a class="urlstyle" href ="';
- $htmlMacro2b{'URL'} = '"><tt>';
- $htmlMacro2c{'URL'} = '</tt></a>';
-
-}else{
- # don't use CSS
- $htmlMacro2a{'section'} = '\n<h2><a name="section_';
- $htmlMacro2b{'section'} = '">';
- $htmlMacro2c{'section'} = '</a></h2>\n';
- $htmlMacro2a{'subsection'} = '\n<h4><a name="section_';
- $htmlMacro2b{'subsection'} = '">';
- $htmlMacro2c{'subsection'} = '</a></h4>\n';
- $htmlMacro2a{'subsubsection'} = '\n<h5><a name="section_';
- $htmlMacro2b{'subsubsection'} = '">';
- $htmlMacro2c{'subsubsection'} = '</a></h5>\n';
-
- # we handle Email and URL special in HTML, the LaTeX argument is doubled.
- $htmlMacro2a{'Email'} = '<a href ="mailto:';
- $htmlMacro2b{'Email'} = '"><tt>';
- $htmlMacro2c{'Email'} = '</tt></a>';
- $htmlMacro2a{'URL'} = '<a href ="';
- $htmlMacro2b{'URL'} = '"><tt>';
- $htmlMacro2c{'URL'} = '</tt></a>';
-}
-
-########################################################################
-# Translation for LaTeX macros for TexInfo
-
-# translation of special characters
-$texiLetterCode{'ä'} = '@"a';
-$texiLetterCode{'ö'} = '@"o';
-$texiLetterCode{'ü'} = '@"u';
-$texiLetterCode{'Ä'} = '@"A';
-$texiLetterCode{'Ö'} = '@"O';
-$texiLetterCode{'Ü'} = '@"U';
-$texiLetterCode{'ß'} = '@ss{}';
-
-# LaTeX macros without arguments
-$texiMacro{'LaTeX'} = 'LaTeX';
-$texiMacro{'LATEX'} = 'LaTeX'; # needed, since \LaTeX is contained in a
- # section name (which are transposed
- # into uppercase
-$texiMacro{'itemsep'} = '';
-
-# some math
-$texiMacro{'rightarrow'} = '-->';
-$texiMacro{'Rightarrow'} = '==>';
-$texiMacro{'leftarrow'} = '<--';
-$texiMacro{'Leftarrow'} = '<==';
-$texiMacro{'ge'} = '>=';
-$texiMacro{'le'} = '<=';
-
-$texiMacro{'Dollar'} = '$';
-$texiMacro{'Bar'} = '|';
-$texiMacro{'Bs'} = '\\';
-$texiMacro{'Tilde'} = '~';
-$texiMacro{'hline'} = '';
-$texiMacro{'noindent'} = '\n@noindent\n';
-$texiMacro{'copyright'} = '@copyright{}';
-$texiMacro{'Dots'} = '...';
-$texiMacro{'Circum'} = '^';
-$texiMacro{'Lbr'} = '[';
-$texiMacro{'Rbr'} = ']';
-$texiMacro{'LBr'} = '@{';
-$texiMacro{'RBr'} = '@}';
-$texiMacro{'Percent'} = '%';
-$texiMacro{'Bullet'} = '*';
-$texiMacro{'TEXbr'} = '';
-$texiMacro{'MANbr'} = '';
-$texiMacro{'TEXIbr'} = '@*\n';
-$texiMacro{'HTMLbr'} = '';
-$texiMacro{'medskip'} = '@sp 2\n';
-$texiMacro{'SP'} = '@ @ ';
-
-if ($opt_a) {
- $texiMacro{'SPfirst'} = $opt_a . '@ ';
- } else {
- $texiMacro{'SPfirst'} = '.@ ';
-}
-
-$texiMacro{'~'} = ' ';
-$texiMacro{'|'} = '|';
-$texiMacro{'<'} = '<';
-$texiMacro{'>'} = '>';
-$texiMacro{'<='} = '<=';
-$texiMacro{'>='} = '>=';
-$texiMacro{'='} = '=';
-$texiMacro{'<>'} = '<>';
-$texiMacro{'{'} = '@{';
-$texiMacro{'}'} = '@}';
-$texiMacro{'_'} = '_';
-$texiMacro{'$'} = '$';
-$texiMacro{'#'} = '#';
-$texiMacro{'&'} = '&';
-$texiMacro{'%'} = '%';
-$texiMacro{'-'} = '@-';
-$texiMacro{','} = ' ';
-
-$texiMacro{'\\'} = '@*\n'; # line break
-$texiMacro{'\\Tab'} = '\n'; # end of column in a table environment
-
-# LaTeX macros with one argument
-$texiMacro1a{'emph'} = '@emph{'; $texiMacro1b{'emph'} = '}';
-$texiMacro1a{'textbf'} = '@strong{'; $texiMacro1b{'textbf'} = '}';
-$texiMacro1a{'texttt'} = '@t{'; $texiMacro1b{'texttt'} = '}';
-$texiMacro1a{'verb'} = '@t{'; $texiMacro1b{'verb'} = '}';
-$texiMacro1a{'underline'} = ''; $texiMacro1b{'underline'} = '';
-$texiMacro1a{'section'} = '\n@section '; $texiMacro1b{'section'} = '\n';
-$texiMacro1a{'subsection'} = '\n@subsection '; $texiMacro1b{'subsection'} = '\n';
-$texiMacro1a{'subsubsection'} = '\n@subsubsection '; $texiMacro1b{'subsubsection'} = '\n';
-
-$texiMacro1a{'Prog'} = ''; $texiMacro1b{'Prog'} = '';
-$texiMacro1a{'File'} = '@file{'; $texiMacro1b{'File'} = '}';
-$texiMacro1a{'Opt'} = ''; $texiMacro1b{'Opt'} = '';
-$texiMacro1a{'oOpt'} = '[ '; $texiMacro1b{'oOpt'} = ' ]';
-$texiMacro1a{'Arg'} = '@var{'; $texiMacro1b{'Arg'} = '}';
-$texiMacro1a{'oArg'} = '[ @var{'; $texiMacro1b{'oArg'} = '} ]';
-$texiMacro1a{'Email'} = '@email{'; $texiMacro1b{'Email'} = '}';
-$texiMacro1a{'URL'} = '@url{'; $texiMacro1b{'URL'} = '}';
-
-# LaTeX macros with two arguments
-$texiMacro2a{'Cmd'} = '';
- $texiMacro2b{'Cmd'} = '(';
- $texiMacro2c{'Cmd'} = ')';
-$texiMacro2a{'OptArg'} = '';
- $texiMacro2b{'OptArg'} = '@var{';
- $texiMacro2c{'OptArg'} = '}';
-$texiMacro2a{'OptoArg'} = '';
- $texiMacro2b{'OptoArg'} = '[@var{';
- $texiMacro2c{'OptoArg'} = '}]';
-$texiMacro2a{'oOptArg'} = '[ ';
- $texiMacro2b{'oOptArg'} = '@var{';
- $texiMacro2c{'oOptArg'} = '} ]';
-$texiMacro2a{'oOptoArg'} = '[ ';
- $texiMacro2b{'oOptoArg'} = '[@var{';
- $texiMacro2c{'oOptoArg'} = '}] ]';
-$texiMacro2a{'setlength'} = '';
- $texiMacro2b{'setlength'} = '';
- $texiMacro2c{'setlength'} = '';
-
-########################################################################
-# processing for MAN
-
-sub manStart
-{
- printf DEST "\'\\\" t\n"; # process with tbl
- printf DEST ".\\\" Manual page created with $CMD on $gen_date\n";
- printf DEST ".\\\" NOTE: This file is generated, DO NOT EDIT.\n";
-
- # Definitionen von Verbatimbegin and Verbatimend
- Print ".de Vb\n.ft CW\n.nf\n..\n.de Ve\n.ft R\n\n.fi\n..\n";
-
- Print ".TH \"$Name\" \"$chapter\" \"". $date ."\" \"";
- interpret_word "$tool";
- Print "\" \""; interpret_word "$tool"; Print "\""; NL;
- # thanks to Andrew Anderson <aja@emulab.ee.mu.oz.au>
-}
-
-sub manEnd
-{
- NL; printf DEST ".\\\" NOTE: This file is generated, DO NOT EDIT.\n";
-}
-
-sub manSection
-{
- my ($cnt, $kind, $section) = @_;
- if ($kind ne "subsubsection"){
- $section = uc $section;
- }
- interpret_line "\\$kind\{$section\}";
-}
-
-sub manParagraph
-{
- if (!$paragraph) {
- if ($manRS == 0 && $list_nest > 1) {
- Print '\n.RS';
- $manRS = 1;
- }
- Print '\n.PP\n';
- $paragraph = 1;
- }
-}
-
-sub manVerb
-{
- my $arg = $_[0];
- if ($arg =~ /^\./) { print DEST '\\&' };
- Print $arg
-}
-
-sub manItemWithArg
-{
- my $arg = $_[0];
- if ($manRS == 1) {
- Print '\n.RE\n';
- }
- $manRS = 0;
- Print '\n.TP\n';
- interpret_word $arg;
- PrintM ' ';
- NL;
-}
-
-sub manItem
-{
- if ($manRS == 1) {
- Print '\n.RE\n';
- }
- $manRS = 0;
- Print '\n.TP\n';
- if ($cur_list[$list_nest] eq 'item') {
- Print '.B *';
- } elsif ($cur_list[$list_nest] eq 'enum') {
- Print $item_nr[$list_nest] . '.';
- }
- NL;
-}
-
-sub manDescriptionStart
-{
- if ($list_nest > 1) {
- Print '\n.RS\n';
- }
-}
-
-sub manDescriptionEnd
-{
- if ($manRS) {
- Print '\n.RE\n';
- $manRS = 0;
- }
- if ($list_nest > 1) {
- Print '\n.RE\n';
- }
- manParagraph;
-}
-
-sub manItemStart
-{
- if ($list_nest > 1) {
- Print '\n.RS\n';
- }
-}
-
-sub manItemEnd
-{
- if ($manRS) {
- Print '\n.RE\n';
- $manRS = 0;
- }
- if ($list_nest > 1) {
- Print '\n.RE\n';
- }
- manParagraph;
-}
-
-sub manEnumEnd
-{
- if ($manRS) {
- Print '\n.RE\n';
- $manRS = 0;
- }
- if ($list_nest > 1) {
- Print '\n.RE\n';
- }
- manParagraph;
-}
-
-sub manEnumStart
-{
- if ($list_nest > 1) {
- Print '\n.RS\n';
- }
-}
-
-sub manCenterStart
-{
- PrintM '\n.ce 100\n';
-}
-
-sub manCenterEnd
-{
- PrintM '\n.ce 0\n';
-}
-
-sub manNameStart
-{
- interpret_line "\\section\{NAME\}$rest";
-}
-
-sub manNameEnd
-{
- # nothing
-}
-
-sub manTableStart
-{
- my $columns = $_[0];
- my $width = $_[1];
- my $i;
- manParagraph;
- Print '.TS\n';
- Print 'tab(&);\n';
- for ($i = 1; $i <= $columns; $i++) {
- Print " l";
- }
- Print "w($width)" if ($width);
- Print '.\n';
-}
-
-sub manTableSep
-{
- Print '\nT}&T{\n';
-}
-
-sub manTableEnd
-{
- Print '\n.TE\n';
- manParagraph;
-}
-
-sub manVerbatimStart
-{
- Print '\n.Vb\n';
-}
-
-sub manVerbatimEnd
-{
- Print '.Ve\n';
-}
-
-sub manVerbatimLine
-{
- s/\\/\\\\/g;
- s/-/\\-/g;
- print DEST "$_";
-}
-
-###########################################################################
-# processing for HTML
-
-sub htmlStart
-{
- Print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">"; NL;
- Print "<!-- Manual page created with $CMD on $gen_date"; NL;
- Print " ** Author of $CMD: Juergen.Vollmer\@informatik-vollmer.de";NL;
- Print " ** NOTE: This file is generated, DO NOT EDIT. -->"; NL;
- Print "<html>"; NL;
- Print "<head><title>$Name</title>"; NL;
-
- if ($opt_c) {
- Print '<link href="'.$opt_c.'" rel="stylesheet" type="text/css">'; NL;
- Print "</head><body>"; NL;
- Print '<h1 class="titlehead">'; NL;
- interpret_line $title;
- Print '</h1>'; NL;
- Print '<h4 class="authorhead">'; interpret_word $author; Print '</h4>'; NL;
- Print "<h4 class=\"datehead\">$date</h4>"; NL;
- Print "<h4 class=\"versionhead\">Version $version</h4>"; NL;
- } else {
- Print "</head><body bgcolor=\"white\">"; NL;
-
- Print "<h1 align=center>"; NL;
- interpret_line $title;
- Print "</h1>"; NL;
- Print "<h4 align=center>"; interpret_word $author; Print "</h4>"; NL;
- Print "<h4 align=center>$date</h4>"; NL;
- Print "<h4 align=center>Version $version</h4>"; NL;
- }
-}
-
-sub htmlEnd
-{
- Print "</body>"; NL;
- Print "</html>"; NL;
- Print "<!-- NOTE: This file is generated, DO NOT EDIT. -->"; NL;
-}
-
-sub htmlSection
-{
- my ($cnt, $kind, $section) = @_;
- interpret_line "\\$kind\{$cnt\}\{$section\}";
-}
-
-sub htmlCenterStart
-{
- Print '\n<div align=center>\n';
-}
-
-sub htmlCenterEnd
-{
- Print '\n</div>\n';
-}
-
-sub htmlNameStart
-{
- # nothing
-}
-
-sub htmlNameEnd
-{
- Print '\n@@INSERTION-POINT@@-TOC@@\n';
-}
-
-sub htmlParagraph
-{
- if (!$paragraph) {
- NL; Print "<p>"; NL;
- $paragraph = 1;
- }
-}
-
-sub htmlVerb
-{
- $arg = $_[0];
- $arg =~ s/&/&amp;/g;
- $arg =~ s/>/&gt;/g;
- $arg =~ s/</&lt;/g;
- Print $arg;
-}
-
-sub htmlItemWithArg
-{
- my $arg = $_[0];
- NL;
- if ($item_nr[$list_nest] > 1) {
- NL; Print "</dd>"; NL;
- }
- Print "<dt>";
- interpret_word $arg; Print "</dt>"; NL;
- Print "<dd>";
-}
-
-sub htmlItem
-{
- if ($item_nr[$list_nest] > 1) {
- Print '</li>\n';
- }
- if ($cur_list[$list_nest] eq 'item') {
- Print '<li>';
- } elsif ($cur_list[$list_nest] eq 'enum') {
- Print '<li value =' . $item_nr[$list_nest] .'>';
- }
-}
-
-sub htmlDescriptionStart
-{
- NL; Print "<dl compact>"; NL;
-}
-
-sub htmlDescriptionEnd
-{
- NL; Print "</dd>\n</dl>"; NL;
-}
-
-sub htmlItemStart
-{
- NL; Print "<ul compact>"; NL;
-}
-
-sub htmlItemEnd
-{
- NL; Print "</li>\n</ul>"; NL;
-}
-
-sub htmlEnumStart
-{
- NL; Print "<ol compact>"; NL;
-}
-
-sub htmlEnumEnd
-{
- NL; Print "</li>\n</ol>"; NL;
-}
-
-sub htmlTableStart
-{
- my $columns = $_[0];
- my $width = $_[1];
- NL;
- if ($opt_c) {
- Print '<table summary="table" class="tablestyle">';
- } else{
- Print '<table summary="table">';
- }
- NL;
-}
-
-sub htmlTableSep
-{
- if ($first_column == 0) {
- Print '</td>\n';
- }
- if ($opt_c) {
- Print '<td class="cellstyle">';
- } else {
- Print '<td>';
- }
-}
-
-sub htmlTableEnd
-{
- NL; Print "</table>"; NL;
-}
-
-sub htmlVerbatimStart
-{
- NL; Print '<pre>'; NL;
-}
-
-sub htmlVerbatimEnd
-{
- Print '</pre>'; NL;
-}
-
-sub htmlVerbatimLine
-{
- s/&/&amp;/g;
- s/</&lt;/g;
- s/>/&gt;/g;
- print DEST "$_";
-}
-
-###########################################################################
-# processing for TexInfo
-
-sub texiStart
-{
- Print '\input texinfo @c -*-texinfo-*-'; NL;
- Print '@c %**start of header'; NL;
- Print '@setfilename ' . "$name.info"; NL;
- Print '@settitle ' . "$name"; NL;
- Print '@c %**end of header'; NL;
- Print '@c Manual page created with' ." $CMD on $gen_date>"; NL;
- Print '@c NOTE: This file is generated, DO NOT EDIT.'; NL;
-}
-
-sub texiEnd
-{
- Print '@bye'; NL;
- Print '@c NOTE: This file is generated, DO NOT EDIT.'; NL;
-}
-
-sub texiSection
-{
- my ($cnt, $kind, $section) = @_;
- if (uc $sections[$cnt-1] eq "SYNOPSIS") {
- Print '\n@@INSERTION-POINT@@-TOC@@\n';
- $sections[$cnt-1] = "Top"; # The predecessor node is Top and not SYNOPSIS
- }
- if (uc $sections[$cnt] eq "SYNOPSIS") {
- $cnt == 1 ||
- die "$CMD: The Synopsis section must be the first section after\n" .
- "\t the Name environment\n";
- } else {
- Print '\n@@INSERTION-POINT@@-TEXI-SEC@@' . " $kind $cnt" . '\n';
- }
- interpret_line "\\$kind\{$section\}";
-}
-
-sub texiNameStart
-{
- my ($name, $chapter, $author, $tool) = @_;
- $sections[0] = "Top";
- # Print '@dircategory ' .$tool; NL;
- Print '@dircategory Man-pages'; NL;
- Print '@direntry'; NL;
- Print "* " . (ucfirst $name) . ": ($name). Its Man-Page "; NL;
- Print '@end direntry'; NL;
- Print '@titlepage'; NL;
- Print '@title ' . "$name"; NL;
- Print '@subtitle ' . "$tool"; NL;
- Print '@author ' . "$author"; NL;
- Print '@end titlepage'; NL;
- Print '\n@@INSERTION-POINT@@-TEXI-TOP@@'; NL;
- Print '@top ' . "$name"; NL;
-}
-
-sub texiNameEnd
-{
- # nothing
-}
-
-sub texiParagraph
-{
- if (!$paragraph) {
- NL; print DEST "\n";
- $paragraph = 1;
- }
-}
-
-sub texiVerb
-{
- $arg = $_[0];
- $arg =~ s/([{]|})/\@$1/g;
- Print $arg;
-}
-
-sub texiItemWithArg
-{
- my $arg = $_[0];
- Print '\n@item ';
- interpret_word $arg;
- NL;
-}
-
-sub texiItem
-{
- Print '\n@item\n';
-}
-
-sub texiDescriptionStart
-{
- Print '\n@table @samp\n';
-}
-
-sub texiDescriptionEnd
-{
- Print '\n@end table\n';
-}
-
-sub texiItemStart
-{
- Print '\n@itemize @bullet\n';
-}
-
-sub texiItemEnd
-{
- Print '\n@end itemize\n';
-}
-
-sub texiCenterStart
-{
- $texiCenterLine = 1;
- $newline = 0;
- $texiMacro{'\\'} = '@*'; # line break
- $texiMacro{'TEXIbr'} = '@*';
- NL;
-}
-
-sub texiCenterEnd
-{
- $texiCenterLine = 0;
- $newline = 0;
- $texiMacro{'\\'} = '@*\n'; # line break
- $texiMacro{'TEXIbr'} = '@*\n';
- NL;
-}
-
-sub texiEnumStart
-{
- Print '\n@enumerate\n';
-}
-
-sub texiEnumEnd
-{
- Print '\n@end enumerate\n';
-}
-
-sub texiTableStart
-{
- my $columns = $_[0];
- my $width = $_[1];
- my $i;
- Print '\n@multitable @columnfractions ';
- for ($i = 1; $i <= $columns; $i++) {
- Print " " .0.9/$columns ;
- }
- Print '\n';
-}
-
-sub texiTableSep
-{
- Print '@tab ';
-}
-
-sub texiTableEnd
-{
- Print '\n@end multitable\n';
-}
-
-sub texiVerbatimStart
-{
- NL;
- Print '@*'; NL
-}
-
-sub texiVerbatimEnd
-{
- NL;
-}
-
-sub texiVerbatimLine
-{
- s/(\{|\}|@| )/\@$1/g;
- chop;
- print DEST ".$_\@*\n";
-}
-
-###########################################################################
-###########################################################################
-# general processing
-
-# emit an error message is the given macro does not exists.
-sub check_Macro
-{
- exists $Macro->{$_[0]} ||
- die "Error in line $.: no such macro: \\$_[0]\n";
-}
-
-sub check_Macro1
-{
- (exists $Macro1a->{$_[0]} && exists $Macro1b->{$_[0]}) ||
- die "$CMD: Error in line $.: no such macro: \\$_[0]\n";
-}
-
-sub check_Macro2
-{
- (exists $Macro2a->{$_[0]} && exists $Macro2b->{$_[0]} && exists $Macro2c->{$_[0]}) ||
- die "$CMD: Error in line $.: no such macro: \\$_[0]\n";
-}
-
-sub NL
-{
- if (!$newline) {
- printf DEST "\n";
- if ($texiCenterLine) {
- print DEST "\@center ";
- }
- $newline = 1;
- }
-}
-
-sub interpret_word
-{
- if (@_ <= 0) {
- return;
- }
- $_ = join " ", @_;
- my ($s,$m,$a1,$a2,$r); # start, match/macro, argument1, argument2
- my $add_blank = 1; # if true, add a blank after the word
- if ($opt_D == 2) {
- if ($nesting == 0) {
- print "**** ";
- } else {
- print " ";
- }
- print "\`$_'\n";
- }
-
- if ($opt_H) {
- # handling of HTML table rows
- if ($inside_table == 1) {
- if ($first_column == 1) {
- if (/^$/) {
- return;
- }
- if (/^\\hline/) {
- if ($opt_c) {
- Print '\n<tr class="rowstyle"><td class="cellstyle" colspan=' . $columns . '><hr></td></tr>\n';
- } else {
- Print '\n<tr><td colspan=' . $columns . '><hr></td></tr>\n';
- }
- }
- if ($opt_c) {
- Print '\n<tr class="rowstyle">\n<td class="cellstyle">';
- } else {
- Print '\n<tr>\n<td>';
- }
- }
- $first_column = 0;
- }
- } elsif ($opt_M) {
- # handling of troff table rows
- if ($inside_table == 1) {
- if ($first_column == 1) {
- if (/^$/) {
- return;
- }
- Print 'T{\n';
- }
- $first_column = 0;
- }
- } elsif ($opt_T) {
- # handling of TexInfo specific stuff
- if ($nesting == 0) {
- s'@'@@'g; #'
- }
- if ($inside_table == 1) {
- if ($first_column == 1) {
- Print '\n@item ';
- }
- $first_column = 0;
- }
- }
-
- $nesting ++;
-
- SWITCH: {
- /^$/ && do {$add_blank = 0;
- last SWITCH;
- };
- /\\verb\+([^+]*)\+/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- PrintM $Macro1a->{'verb'};
- &{$Prefix . "Verb"} ($m);
- PrintM $Macro1b->{'verb'};
- interpret_word $r;
- last SWITCH;
- };
- /\\(".|ss)/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- check_Macro $m;
- PrintM $Macro->{$m};
- interpret_word $r;
- last SWITCH;
- };
- /\\item\s*\[([^]]*)\]/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- $item_nr[$list_nest] ++;
- &{$Prefix . "ItemWithArg"} ($m);
- interpret_word $r;
- last SWITCH;
- };
- /\\item\s*/ && do {$s=$`;$r=$'; #'
- interpret_word $s;
- $item_nr[$list_nest] ++;
- &{$Prefix . "Item"};
- interpret_word $r;
- last SWITCH;
- };
- # LaTeX macros with two arguments
- /\\([a-zA-Z]+)\{([^}]*)\}\{([^}]*)\}/
- && do {$s=$`;$m=$1;$a1=$2;$a2=$3;$r=$'; #'
- check_Macro2 $m;
- interpret_word $s;
- PrintM $Macro2a->{$m};
- interpret_word $a1;
- PrintM $Macro2b->{$m};
- interpret_word $a2;
- PrintM $Macro2c->{$m};
- interpret_word $r;
- NL;
- last SWITCH;
- };
- # Special Handling of Email and URL LaTeX macros with one argument
- /\\(URL|Email)\{([^}]*)\}/ && ($opt_H)
- && do {$s=$`;$m=$1;$a1=$2;$r=$'; #'
- interpret_word $s;
- PrintM $Macro2a->{$m};
- interpret_word $a1;
- PrintM $Macro2b->{$m};
- interpret_word $a1;
- PrintM $Macro2c->{$m};
- interpret_word $r;
- NL;
- last SWITCH;
- };
- # LaTeX macros with one argument
- /\\([a-zA-Z]+)\{([^}]*)\}/ && do {$s=$`;$m=$1;$a1=$2;$r=$'; #'
- check_Macro1 $m;
- interpret_word $s;
- PrintM $Macro1a->{$m};
- interpret_word $a1;
- PrintM $Macro1b->{$m};
- interpret_word $r;
- NL;
- last SWITCH;
- };
- # Special handling of some LaTeX macros without an argument
- /\\SP\s*/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- if ($first_word) {
- PrintM $Macro->{"SPfirst"};
- } else {
- PrintM $Macro->{"SP"};
- }
- interpret_word $r;
- $add_blank = 0;
- last SWITCH;
- };
- /\\(MANbr|TEXIbr|HTMLbr)\s*/ && do {$s=$`;$m=$1;$r=$'; #'
- # set $first_word to true
- check_Macro $m;
- interpret_word $s;
- PrintM $Macro->{$m};
- $first_word = 1;
- interpret_word $r;
- $add_blank = 0;
- last SWITCH;
- };
- # LaTeX macros without an argument:
- /\\([a-zA-Z]+)\s*/ && do {$s=$`;$m=$1;$r=$'; #'
- check_Macro $m;
- interpret_word $s;
- PrintM $Macro->{$m};
- interpret_word $r;
- $add_blank = 0;
- last SWITCH;
- };
- /\\([{]|}|\$|_|#|&|-|%|,|\.|;)/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- PrintM $Macro->{$m};
- interpret_word $r;
- last SWITCH;
- };
- # LaTeX Math
- /\$(<|>|<=|>=|=|<>)\$/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- PrintM $Macro->{$m};
- interpret_word $r;
- last SWITCH;
- };
- /\$([^\$]*)\$/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- interpret_word $m;
- interpret_word $r;
- last SWITCH;
- };
- /&/ && do {$s=$`;$r=$'; #'
- interpret_word $s;
- &{$Prefix . "TableSep"};
- $first_column = 0;
- interpret_word $r;
- last SWITCH;
- };
- /~/ && do {$s=$`;$r=$'; #'
- interpret_word $s;
- PrintM $Macro->{'~'};
- interpret_word $r;
- last SWITCH;
- };
- /\\\\/ && do {$s=$`;$r=$'; #'
- interpret_word $s;
- if ($inside_table) {
- PrintM $Macro->{'\\Tab'};
- $first_column = 1;
- if (length ($r) > 0) {
- interpret_word $r;
- }
- } else {
- PrintM $Macro->{'\\'};
- $first_word = 1;
- interpret_word $r;
- }
- $add_blank = 0;
- last SWITCH;
- };
- /\\$|\\ / && do {$s=$`;$r=$'; #'
- # LaTeX explicit blank \ will be
- # represented as a single \ at
- # the end of the word
- interpret_word $s;
- Print " ";
- interpret_word $r;
- last SWITCH;
- };
- /\\/ && do {$s=$`;$r=$'; #'
- interpret_word $s;
- interpret_word "\\$r";
- last SWITCH;
- };
- ($opt_M == 1) && /((^\.|')+)/ && do {$s=$`;$m=$1;$r=$'; #'
- interpret_word $s;
- print DEST "\\&$m";
- $newline = 0;
- interpret_word $r;
- last SWITCH;
- };
- Print "$_";
- };
- $nesting --;
- Print " " if ($nesting == 0 && $add_blank);
-} # interpret_word()
-
-sub interpret_line
-{
- my $line = $_[0]; chomp $line;
- my @words = split(/\s+/,$line);
- my $max = $#words;
- my $i;
- my $join = 0; # true, if words must be joined
- my $word = ""; # the joined word
- my $kind = 0; # 1: item[ .. ], 2: { .. }, 3: \verb+ .. +
- if ($max < 0) {
- # empty line marks a paragraph
- &{$Prefix . "Paragraph"};
- $first_word = 1;
- return;
- }
- for ($i = 0; $i <= $max; $i++) {
- $_ = $words[$i];
- # printf "\`$words[$i]'";
- if (/^[\s]*$/) { # skip leading blanks
- # nothing
- } elsif ((!$join || ($kind != 3)) && /^%+/) { # skip comments
- last;
- } else {
- # if blanks in a { .. }, \item[ .. ], \verb+ .. + then we have to joind words
- if ($join) {
- # check whether this is the last word to be joined
- if ($kind == 1) { # item
- $join = index ($_, "]") == -1;
- } elsif ($kind == 2) { # braces
- my @x = $_ =~ /[^\\]}/g;
- $join = $#x == -1;
- } elsif ($kind == 3) { # verb
- $join = index ($_, "+") == -1;
- }
- $word .= " " . $words[$i];
- if (!$join) {
- interpret_word $word;
- $word = "";
- }
- } else {
- # check whether we have to join some words
- if (/\\item/) {
- my $cnt1 = tr/[/[/;
- my $cnt2 = tr/]/]/;
- $join = $cnt1 != $cnt2 || $cnt1 == 0;
- $kind = 1;
- } elsif (/\\verb/) {
- my $cnt = tr/+/+/;
- $join = $cnt % 2 != 0;
- $kind = 3;
- } else {
- my @x = $_ =~ /[^\\]\{/g;
- my @y = $_ =~ /[^\\]\}/g;
- $join = $#x != $#y;
- $kind = 2;
- }
- if ($join) {
- $word = $words[$i];
- } else {
- interpret_word $words[$i];
- }
- }
- }
- }
- if ($join) {
- interpret_word $word;
- }
- NL;
-} # interpret_line()
-
-sub PrintM
-# print only for Macro command text
-{
- if (@_ <= 0 || length ($_[0]) == 0) {
- return;
- }
- my $l = shift;
- my $c;
- $l =~ s/\\n/\n/g;
- foreach $c (split ("", $l)) {
- if ($c eq "\n") {
- NL;
- $newline = 0;
- } else {
- print DEST "$c";
- }
- }
-} # PrintM()
-
-sub Print
-{
-
- # printf "\`$_[0]'\n";
- if (@_ <= 0 || length ($_[0]) == 0) {
- return;
- }
- my $x = $_[0];
-
- unless ($x =~ /^\s*$/) {
- # if other chars than blanks are printed:
- $first_word = 0;
- }
-
- if (!$inside_verb) {
- # transform special characters
- $x =~ s/([äöüÄÖÜß])/$LetterCode->{"$1"}/go;
- }
-
- my @parts = split /\\n/, $x, -1;
- # -1: trailing \n generates an empty list element
- my $i;
- for ($i = 0; $i <= $#parts; $i++) {
- if ($newline) {
- # skip leading blanks after a newline
- $parts[$i] =~ s/^\s+//;
- }
- if (length($parts[$i]) > 0) {
- if ($opt_M) {
- $parts[$i] =~ s/\\/\\\\/g;
- $parts[$i] =~ s/-/\\-/g;
- }
- printf DEST "%s", $parts[$i];
- $newline = 0;
- }
- if ($i < $#parts) {
- NL;
- }
- }
- $paragraph = 0;
-} # Print()
-
-#########################################################################
-
-sub date2str
-{
- @EnglishMonthName = ('','January','February','March','April','May','June','July',
- 'August','September','October','November','December');
- # split date
- my ($Year,$Month,$Day) = split (/\//,$_[0]);
- return $Day . " " . $EnglishMonthName[$Month] . " " . $Year;
-}
-
-$rcs_date=`date '+%Y/%m/%d/'`; # date of the man-page, overwritten
- # by \rcsInfo
-$date = date2str ($rcs_date);
-$Macro->{'today'} = $date;
-
-#########################################################################
-
-my @skip; # stack of skip-flags, 1: skip, 0: don't skip
-push @skip, 0; # synthetic "outer most" IF, don't skip
-my $last_cond_clause = "";
-
-sub handle_conditional_text
-{
- $_ = $_[0];
-# printf "skip-stack: %s;\t top = %s\n", join (", ", @skip), $skip[-1];
- if (/^\s*%@%\s+IF\s+([^%]*)\s+%@%\s*$/) {
- # produce a program, which evaluates the condition:
- my $prog_cond = $1;
- $prog_cond =~ s/(\w+)/\$$1/g;
- my $prog = "";
- my $var;
- foreach $var (keys %cond_name) {
- if ($var ne "") {
- $prog .= "my \$$var = 1; " # declare set names,
- # undeclared ones get value 0
- }
- }
- $prog .= "return ($prog_cond) ? 0 : 1;";
-# print "\n**** [$prog]\n";
- my $skip = eval $prog;
- ($@ eq "") || die "$CMD: error in line $.: wrong condition of `%@% IF.. ($@)\n";
-# print "**** skip=$skip\n";
-
- $last_cond_clause = "IF";
- if ($skip[-1] == 1) {
- # skip this text, since outer IF skips
- push @skip, 1;
- } else {
- # outer IF is not skipped, hence consider this IF
- push @skip, $skip;
- }
- } elsif (/^\s*%@%\s+ELSE\s+%@%\s*$/) {
- ($last_cond_clause =~ /IF/ && ($#skip > 0)) ||
- die "$CMD: error in line $.: `%@% ELSE %@%' without an `%@% IF..'\n";
- $last_cond_clause = "ELSE";
- if ($skip[-2] == 0) {
- $skip[-1] = $skip[-1]? 0 : 1;
- }
- } elsif (/^\s*%@%\s+END-IF\s+%@%\s*$/) {
- $last_cond_clause = "END-IF";
- ($#skip == 0) &&
- die "$CMD: error in line $.: `%@% END-IF %@%' without an `%@% IF..'\n";
- pop @skip;
- }
-# print "$last_cond_clause: skip = $skip[-1]\n";
-} # handle_conditional_text()
-
-############################################################################
-# handle LaTeX output
-#########################################################################
-
-sub emit_LaTeX
-{
- my $src = shift(@_); # the source handle to be read
- my $inside_include = shift(@_); # true, if we reading an \input{..}
- while (<$src>) {
- if ($opt_D == 1) {
- my $line = $_; chop $line;
- print "--- \`$line'\n";
- }
- if (/^\s*\\input\{([^}]*)\}\s*/) {
- # handle \input{fn}
- my $fn = $1;
- printf DEST "%%%%%%%%%%%%%%%%%% start of \\input{%s}\n", $fn;
- open (my $inc, "<$fn") || die "$CMD: Can't open file \\input-file \`$fn' for reading.\n";
- emit_LaTeX($inc, 1);
- close ($inc);
- printf DEST "%%%%%%%%%%%%%%%%%% end of \\input{%s}\n", $fn;
- next;
- }
- if (/^\s*%@%\s/) {
- my $skip = $skip[-1];
- handle_conditional_text ("$_");
- # write %@% directive
- print DEST $_;
- next;
- }
- next if ($skip[-1] == 1);
- print DEST $_;
- }
-} # emit_LaTeX()
-
-
-############################################################################
-# handle non-LaTeX output
-############################################################################
-
-sub emit_NonLaTeX
-# read sections
-# Variables: $section name of the section in uppercase letters
-# $chapter chapter of the man page
-# $name name of the man page
-# $Name name of the man page in uppercase
-# $author author of the man page
-# $tool info about the tool set, $name is part of
-# $date date
-# $version version info
-{
- my $src = shift(@_); # the source handle to be read
- my $inside_include = shift(@_); # true, if we reading an \input{..}
-
- if ($inside_include) {
- $started = shift(@_); # given, only if inside_include is true
- } else {
- $started = 0;
- }
-
- while (<$src>) {
- if ($opt_D == 1) {
- my $line = $_; chop $line;
- print "--- \`$line'\n";
- }
- if (/^\s*\\input\{([^}]*)\}\s*/) {
- # handle \input{fn}
- my $fn = $1;
- if ($opt_M) {
- printf DEST ".\\\" *********************************** start of \\input{%s}\n", $fn;
- } elsif ($opt_H) {
- printf DEST "<!-- *********************************** start of \\input{%s} -->\n", $fn;
- } elsif ($opt_T) {
- printf DEST "\@c *********************************** start of \\input{%s}\n", $fn;
- }
- open (my $inc, "<$fn") || die "$CMD: Can't open file \\input-file \`$fn' for reading.\n";
- emit_NonLaTeX($inc, 1, $started);
- close ($inc);
- if ($opt_M) {
- printf DEST ".\\\" *********************************** end of \\input{%s}\n", $fn;
- } elsif ($opt_H) {
- printf DEST "<!-- *********************************** end of \\input{%s} -->\n", $fn;
- } elsif ($opt_T) {
- printf DEST "\@c *********************************** end of \\input{%s}\n", $fn;
- }
- next;
- }
- if ((/^\s*%@%\s/) && ($inside_verb==0)) {
- my $skip = $skip[-1];
- handle_conditional_text ("$_");
- }
- next if ($skip[-1] == 1);
-
- if ($inside_verb) {
- if (/^\s*\\end\{verbatim\}/) {
- if ($started == 1) {
- &{$Prefix . "VerbatimEnd"};
- $inside_verb = 0;
- }
- } else {
- &{$Prefix . "VerbatimLine"} ($_);
- }
- next;
- }
-
- # remove {, } around Umlaute
- s/\{(\\".)\}/$1/g; # "
- s/\{(\\ss)\}/$1/g;
-
- # normalize special characters
- s/\\"a/ä/g;
- s/\\"o/ö/g;
- s/\\"u/ü/g;
- s/\\"A/Ä/g;
- s/\\"O/Ö/g;
- s/\\"U/Ü/g;
- s/\\ss/ß/g;
-
- if (/^\s*\\rcsInfo \$(.*)\$/) {
- my ($rcs_id,$rcs_file,$rcs_revision,
- $rcs_date,$rcs_time,$rcs_owner,$rcs_status,$rcs_locker) = split(/\s/,$1);
- $date = date2str ($rcs_date);
- $Macro->{'today'} = $date;
- } elsif (/^\s*\\setDate\{\\rcsInfoLongDate\}/) {
- $Macro->{'Date'} = $date;
- } elsif (/^\s*\\setDate\{\\today\}/) {
- $Macro->{'Date'} = $date;
- } elsif (/^\s*\\setDate\{([^}]*)\}/) {
- $date = $1;
- $date =~ s/~/$Macro->{'~'}/g;
- $Macro->{'Date'} = $date;
- } elsif (/^\s*\\setVersion\{([^}]*)\}/) {
- $version = $1;
- $version =~ s/~/$Macro->{'~'}/g;
- $Macro->{'Version'} = $version;
- } elsif (/^\s*\\begin\{Name\}\{([^}]*)\}\{([^}]*)\}\{([^}]*)\}\{([^}]*)\}\{([^}]*)\}/) {
- $section = "Name";
- $chapter = $1;
- $name = $2;
- $Name = uc $name;
- $author = $3;
- $tool = $4;
- $title = $5;
- $rest = $'; #'
- $started = 1;
- $sections[0] = $section;
- $section_cnt = 0;
- &{$Prefix . "Start"} ($name, $chapter, $author, $tool, $title);
- &{$Prefix . "NameStart"} ($name, $chapter, $author, $tool, $title);
- } elsif (/^\s*\\end\{Name\}/) {
- &{$Prefix . "NameEnd"} ($name, $chapter, $author, $tool);
- } elsif (/^\s*\\begin\{Table\}(\[([^]]*)\])?\{([^}]*)\}/) {
- # \begin{Table}[width]{columns}
- if ($started == 1) {
- $columns = $3;
- # $column = $_[0];
- $inside_table = 1;
- $first_column = 1;
- &{$Prefix . "TableStart"} ($columns, $2);
- }
- } elsif (/^\s*\\end\{Table\}/) {
- if ($started == 1) {
- $inside_table = 0;
- $first_column = 0;
- &{$Prefix . "TableEnd"} ($columns);
- }
- } elsif (/^\s*\\begin\{Description\}(\[[^]]*\])?/) {
- if ($started == 1) {
- $list_nest++;
- $cur_list[$list_nest] = 'descr';
- $item_nr[$list_nest] = 0;
- &{$Prefix . "DescriptionStart"};
- }
- } elsif (/^\s*\\end\{Description\}/) {
- if ($started == 1) {
- &{$Prefix . "DescriptionEnd"};
- $list_nest--;
- }
- } elsif (/^\s*\\begin\{description\}/) {
- if ($started == 1) {
- $list_nest++;
- $cur_list[$list_nest] = 'descr';
- $item_nr[$list_nest] = 0;
- &{$Prefix . "DescriptionStart"};
- }
- } elsif (/^\s*\\end\{description\}/) {
- if ($started == 1) {
- &{$Prefix . "DescriptionEnd"};
- $list_nest--;
- }
- } elsif (/^\s*\\begin\{center\}/) {
- if ($started == 1) {
- &{$Prefix . "CenterStart"};
- }
- } elsif (/^\s*\\end\{center\}/) {
- if ($started == 1) {
- &{$Prefix . "CenterEnd"};
- }
- } elsif (/^\s*\\begin\{enumerate\}/) {
- if ($started == 1) {
- $list_nest++;
- $cur_list[$list_nest] = 'enum';
- $item_nr[$list_nest] = 0;
- &{$Prefix . "EnumStart"} ;
- }
- } elsif (/^\s*\\end\{enumerate\}/) {
- if ($started == 1) {
- &{$Prefix . "EnumEnd"} ;
- $list_nest--;
- }
- } elsif (/^\s*\\begin\{itemize\}/) {
- if ($started == 1) {
- $list_nest++;
- $cur_list[$list_nest] = 'item';
- $item_nr[$list_nest] = 0;
- &{$Prefix . "ItemStart"} ;
- }
- } elsif (/^\s*\\end\{itemize\}/) {
- if ($started == 1) {
- &{$Prefix . "ItemEnd"} ;
- $list_nest--;
- }
- } elsif (/^\s*\\begin\{verbatim\}/) {
- if ($started == 1) {
- &{$Prefix . "VerbatimStart"};
- $inside_verb = 1;
- }
- } elsif (/^\s*\\(subsubsection|subsection|section)\{([^}]*)\}/) {
- $kind = $1;
- $section = $2;
- $section_cnt ++;
- $sections[$section_cnt] = $section;
- $section_kind[$section_cnt] = $kind;
- if ($started == 1) {
- &{$Prefix . "Section"} ($section_cnt, $kind, $section);
- }
- } elsif (/^\s*\\LatexManEnd/ || /^\s*\\end\{document\}/) {
- last;
- } elsif (/^\s*((\\begin\{Name|Table|Description\})|(\\(sub)?section))/) {
- die "$CMD: in line $.\n " .
- "Arguments of $1 are not contained in a single " .
- "line.\n " .
- "Remember: all arguments of a macro must be on the same line.\n";
- } else {
- if ($started == 1) {
- interpret_line $_;
- }
- }
- }
- if (!$inside_include) {
- &{$Prefix . "End"};
- }
-} # emit_NonLaTeX()
-
-############################################################################
-# Postprocessing TEXI and HTML
-############################################################################
-
-sub postProcessNonLaTeX
-{
- open (TMP, "<$tmp") || die "$CMD: Can't open file \`$tmp' for reading.\n";
- while (<TMP>) {
- if (/^\@\@INSERTION-POINT\@\@-TOC\@\@$/) {
- if ($opt_H) {
- # Table of contents for HTML
- my $nesting = 0; # nesting of section/subsection/subsubsection
- Print '\n<h3>Table of Contents</h3>\n';
- for ($i = 1; $i <= $section_cnt; $i++) {
- my $cur_nesting = 0;
- if ($section_kind[$i] eq "subsubsection") {
- $cur_nesting = 3;
- } elsif ($section_kind[$i] eq "subsection") {
- $cur_nesting = 2;
- } elsif ($section_kind[$i] eq "section") {
- $cur_nesting = 1;
- }
- if ($cur_nesting > $nesting) {
- # open a new list
- Print '\n<ul>\n'
- }
- if ($cur_nesting == $nesting) {
- # same level, close list item
- Print '</li>\n';
- }
- if ($cur_nesting < $nesting) {
- # close list and list item
- for my $i ($cur_nesting .. $nesting-1) {
- Print '</li>\n';
- Print '</ul>\n';
- }
- }
- # print item
- Print "<li><a href=\"#section_$i\">";
- interpret_word $sections[$i];
- Print "</a>";
- $nesting = $cur_nesting;
- }
- # close remaining lists
- for my $i (1 .. $nesting) {
- Print '</li>\n';
- Print '</ul>\n';
- }
- } else {
- # Menu of sections for texi
- Print '@menu\n';
- for ($i = 2; $i <= $section_cnt; $i++) {
- interpret_line "* " . $sections[$i] . "::";
- }
- Print '@end menu\n';
- }
- } elsif (/\@\@INSERTION-POINT\@\@-TEXI-TOP\@\@/) {
- # Texi-top node
- Print '@node Top, ' . $sections[2] . ', (dir), (dir)\n';
- } elsif (/\@\@INSERTION-POINT\@\@-TEXI-SEC\@\@ (\w+) (\d+)/) {
- # print section header for texi
- $kind = $1;
- $cnt = $2;
- $section = $sections[$cnt];
- Print '@node ' ;
- interpret_word "$sections[$cnt], ";
- interpret_word "$sections[$cnt+1], ";
- interpret_word "$sections[$cnt-1], Top ";
- NL;
- } else {
- print DEST $_;
- }
- }
- close TMP;
- unlink $tmp;
-} # postPrecessNonLaTeX()
-
-#########################################################################
-# Do the job
-#########################################################################
-
-if ($opt_t) {
- # reading of translations for user macros
- do $opt_t;
-}
-
-########################################################################
-
-open (my $SRC, "<$SrcFile") || die "$CMD: Can't open file \`$SrcFile' for reading.\n";
-if ($opt_H || $opt_T) {
- # DestFile will be written in the postprocess
- open (DEST, ">$tmp") || die "$CMD: Can't open file \`$tmp' for writing.\n";
-} else {
- open (DEST, ">$DestFile") || die "$CMD: Can't open file \`$DestFile' for writing.\n";
-}
-
-if ($opt_L) {
- # handle LaTeX output
- emit_LaTeX ($SRC);
- close ($SRC);
- close (DEST);
-} else {
- # handle non-LaTeX
- emit_NonLaTeX ($SRC);
- close ($SRC);
- close (DEST);
-
- if ($opt_H || $opt_T) {
- open (DEST, ">$DestFile") || die "$CMD: Can't open file \`$DestFile' for writing.\n";
- postProcessNonLaTeX();
- close (DEST);
- }
-}
-
-############################################################################
-
-
-#########################################################################
-
-## Emacs specific:
-## Local Variables: ***
-## mode: perl ***
-## End: ***
diff --git a/Build/source/texk/texlive/linked_scripts/latex2nemeth/latex2nemeth b/Build/source/texk/texlive/linked_scripts/latex2nemeth/latex2nemeth
deleted file mode 100755
index 3ce409fc29b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latex2nemeth/latex2nemeth
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-jarpath=`kpsewhich --progname=latex2nemeth --format=texmfscripts latex2nemeth-v1.0.2.jar`
-exec java -jar "$jarpath" "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/latexdiff/latexdiff-vc.pl b/Build/source/texk/texlive/linked_scripts/latexdiff/latexdiff-vc.pl
deleted file mode 100755
index b50a52722ff..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latexdiff/latexdiff-vc.pl
+++ /dev/null
@@ -1,824 +0,0 @@
-#!/usr/bin/env perl
-#
-# latexdiff-vc - wrapper script for applying latexdiff to rcs managed files
-# and for automatised creation of postscript or pdf from difference file
-#
-# Copyright (C) 2005-20 F J Tilmann (tilmann@gfz-potsdam.de)
-#
-# Repository: https://github.com/ftilmann/latexdiff
-# CTAN page: http://www.ctan.org/pkg/latexdiff
-#
-#
-# Contributors: S Utcke, H Bruyninckx, C Junghans
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Detailed usage information at the end of the file
-#
-# TODO/IDEAS: - option to call external pre-processing codes
-# version 1.3.0 ((7 October 2018)
-# - option --only-changes with hyperref will suppress hyperrefs (pull request jprotze)_
-# - option --only-changes now moves (rather than copies) file with only changes
-# version 1.2.1 (22 June 2017):
-# - update: use qpdf (instead of pdftk) to select particular pages of output (pull request #102 submitted by Tom Scogland via github). This was necessary because pdftk is being deprecated. pdftk is still used as a fall-back
-# - bug fix: --hg option was not recognised (partially fixes github issue #93 )
-# - wrap passed-through options to latexdiff in quotation marks (fix github issue #58 )
-# - program names for latexdiff, latex, dvips, bibtex configurable (fixes issue #40)
-#
-# version 1.2.0:
-# - deprecation fix: left brace in RegEx now needs to be escaped
-#
-# version 1.1.1:
-# - better detection of RCS system
-# - undocumented option --debug/--nodebug to override default setting for debug mode (Default: 0)#
-# - bug fix: --flatten option combined with --pdf caused confusion of old and new file
-#
-# version 1.1.0:
-#
-# - with option --flatten and version control option, checkout the whole tree into a temporary directory
-# (use svn info + checkout ; git archive )
-# - add option --only-changes to output only changed pages (in combination with --ps or --pdf option)
-# version 1.0.4:
-# - [ Patch #3486 contributed by cbarbu] add additional compilation for styles using chbar + avoid pdf/postscripts repeat in the code
-# version 1.0.3: Bug fix: replace use of system('cp...') with File::Copy::copy (Patch contributed by D. Bremner)
-# Quotes around system call file arguments to allow filenames with spaces (Patch contributed by ssteve)
-# version 1.0.2: - option --so to use latexdiff-so
-# version 1.0.1 (change version numbering to match that of latexdiff)
-# - Option --fast to use latexdiff-fast,
-# - git support (thanks to Bjorn Magnus Mathisen, Santi BĂ©jar, Pietro Battiston and Stefan Alfredson for patches) - UNTESTED
-# version 0.25:
-# - bbl is allowed as alternative extension (instead of .tex)
-# version 0.26a
-# - Bug fix: it copes now correctly with the possibility that there are no changes between current
-# and archived version
-use Getopt::Long ;
-use Pod::Usage qw/pod2usage/ ;
-use File::Temp qw/tempdir/ ;
-use File::Basename qw/dirname/;
-use File::Copy;
-
-use strict ;
-use warnings ;
-
-my $versionstring=<<EOF ;
-This is LATEXDIFF-VC 1.3.1.1
- (c) 2005-2020 F J Tilmann
-EOF
-
-# output debug and intermediate files, set to 0 in final distribution
-my $debug=0;
-
-
-# Option names
-my ($version,$help,$fast,$showconfig,$so,$postscript,$pdf,$onlychanges,$flatten,$force,$dir,$cvs,$rcs,$svn,$git,$hg,
- $run,$rundvi2,$diffcmd,$patchcmd,@revs,@configlist);
-# for passing through config options to latexdiff:
-my ($configlatexdiff,@config,$config,$assign);
-
-# Preset Variables
-#my $latexdiff="latexdiff"; # Program for making the comparison
-#my $latexcmd="latex"; # latex compiler if not further identified
-my $vc="";
-my $tempdir=tempdir(CLEANUP => 1); # generate a temp dir, which will automatically be deleted at program exit
-# Variables
-my ($file1,$file2,$diff,$diffbase,$rootdir,$answer,$options,$infile,$append,$dirname,$cwd);
-my (@files,@ldoptions,@tmpfiles,@ptmpfiles,@difffiles,$extracomp); # ,
-
-
-# keep commands to be used in config hash
-my (%CFG)=(
- LATEX => "latex",
- LATEXDIFF => "latexdiff",
- DVI2 => "dvips",
- BIBTEX => "bibtex"
- );
-
-
-
-Getopt::Long::Configure('pass_through','bundling');
-
-GetOptions('revision|r:s' => \@revs,
- 'cvs' => \$cvs,
- 'rcs' => \$rcs,
- 'svn' => \$svn,
- 'git' => \$git,
- 'hg' => \$hg,
- 'dir|d:s' => \$dir,
- 'run' => \$run,
- 'dvi' => \$rundvi2,
- 'fast' => \$fast,
- 'so' => \$so,
- 'postscript|ps' => \$postscript,
- 'pdf' => \$pdf,
- 'force' => \$force,
- 'only-changes' => \$onlychanges,
- 'flatten:s' => \$flatten,
- 'config|c=s' => \@configlist,
- 'show-config' => \$showconfig,
- 'version' => \$version,
- 'help|h' => \$help,
- 'debug!' => \$debug);
-
-##print STDERR "DEBUG 1:revs($#revs): " . join(":",@revs) . "\n";
-##print STDERR "DEBUG 1:ARGV($#ARGV): " . join(":",@ARGV) . "\n";
-
-$extracomp = join(" ",grep(/BAR/,@ARGV)); # special latexdiff options requiring additional compilation
-
-if ( $help ) {
- pod2usage(1) ;
-}
-
-if ( $version ) {
- die $versionstring ;
-}
-
-if ( $so ) {
- $CFG{LATEXDIFF}='latexdiff-so';
-}
-if ( $fast ) {
- die "Cannot specify more than one of --fast or --so " if ($so);
- $CFG{LATEXDIFF}='latexdiff-fast';
-}
-
-if ( $cvs ) {
- $vc="CVS";
-}
-if ( $rcs ) {
- die "Cannot specify more than one of --cvs, --rcs, --svn --git or --hg." if ($vc);
- $vc="RCS";
-}
-if ( $svn ) {
- die "Cannot specify more than one of --cvs, --rcs, --svn --git or --hg." if ($vc);
- $vc="SVN";
-}
-if ( $git ) {
- die "Cannot specify more than one of --cvs, --rcs, --svn --git or --hg." if ($vc);
- $vc="GIT";
-}
-if ( $hg ) {
- die "Cannot specify more than one of --cvs, --rcs, --svn --git or --hg." if ($vc);
- $vc="HG";
-}
-
-if ( $pdf ) {
- $CFG{LATEX} = "pdflatex";
- $run=1;
-} elsif ( $postscript ) {
- $CFG{LATEX} = "latex";
- $rundvi2=1;
-}
-
-if ( $rundvi2 ) {
- $run=1;
-}
-
-# setting config variables from command line. Explicitly set configuration options take precedence over convenience options,
-# therefore this is executed last
-@config=();
-foreach $config ( @configlist ) {
- if (-f $config || lc $config eq '/dev/null' ) {
- open(FILE,$config) or die ("Couldn't open configuration file $config: $!");
- while (<FILE>) {
- chomp;
- next if /^\s*#/ || /^\s*%/ || /^\s*$/ ;
- push (@config,$_);
- }
- close(FILE);
- }
- else {
-# foreach ( split(",",$config) ) {
-# push @config,$_;
-# }
- push @config,split(",",$config)
- }
-}
-
-$configlatexdiff="";
-foreach $assign ( @config ) {
- $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)";
- if ( defined($CFG{$1})) {
- # known latexdiff-vc option
- $CFG{$1}=$2;
- } else {
- # unknown option, assume it is a latexdiff configuration variable
- $configlatexdiff .= "$1=$2,";
- }
-}
-# delete last comma inv $configlatexdiff if present
-$configlatexdiff =~ s/,$// ;
-
-if ($showconfig) {
- print "# Configuration variables (latexdiff-vc):\n";
- foreach ( keys %CFG ) {
- print "$_=$CFG{$_}\n";
- }
- exit 0;
-}
-
-
-# check whether the first file name or first passed-through option for latexdiff got misinterpreted as an option to an empty -r option
-if ( @revs && ( -f $revs[$#revs] || $revs[$#revs] =~ /^-/ ) ) {
- push @ARGV,$revs[$#revs];
- $revs[$#revs]="";
-}
-# check whether the first file name or first passed-through option for latexdiff got misinterpreted as an option to an empty -d option
-if ( defined($dir) && ( -f $dir || $dir =~ /^-/ ) ) {
- push @ARGV,$dir;
- $dir="";
-}
-# check whether the first file name or first passed-through option for latexdiff got misinterpreted as an option to an empty --flatten option
-
-if ( defined($flatten) && ( -f $flatten || $flatten =~ /^-/ ) ) {
- unshift @ARGV,$flatten;
- $flatten="";
-}
-
-print STDERR "DEBUG: PDF $pdf latexdiff-vc command line: ", join(" ",@ARGV), "\n" if $debug;
-
-$file2=pop @ARGV;
-( defined($file2) && $file2 =~ /\.(tex|bbl|flt)$/ ) or pod2usage("Must specify at least one tex, bbl or flt file");
-
-if (! $vc && scalar(@revs)>0 ) {
- # have to guess $vc
- # check whether we have a special name
- if ( $0 =~ /-cvs$/ ) {
- $vc="CVS";
- } elsif ( $0 =~ /-rcs$/ ) {
- $vc="RCS";
- } elsif ( $0 =~ /-svn$/ ) {
- $vc="SVN";
- } elsif ( $0 =~ /-git$/ ) {
- $vc="GIT";
- } elsif ( $0 =~ /-hg$/ ) {
- $vc="HG";
- } elsif ( -e "$file2,v" || -d "RCS" ) {
- print STDERR "Guess you are using RCS ...\n";
- $vc="RCS";
- } elsif ( -d ".svn" ) {
- print STDERR "Guess you are using SVN ...\n";
- $vc="SVN";
- } elsif ( -d ".git" ) {
- print STDERR "Guess you are using GIT ...\n";
- $vc="GIT";
- } elsif ( -d ".hg" ) {
- print STDERR "Guess you are using HG ...\n";
- $vc="HG";
- } elsif ( -e "CVSROOT" || defined($ENV{"CVSROOT"}) ) {
- print STDERR "Guess you are using CVS ...\n";
- $vc="CVS";
- } else {
- print STDERR "Cannot figure out version control system, so I default to CVS\n";
- $vc="CVS";
- }
-}
-
-if (defined($dir) && $dir=~/^\.\/?/ ) {
- print STDERR "You wrote -dir=. but you do not really like to do that, do you ?\n";
- exit 10
-}
-
-if ( scalar(@revs)>0 ) {
- if ( $vc eq "CVS" ) {
- $diffcmd = "cvs diff -u -r";
- $patchcmd = "patch -R -p0";
- } elsif ( $vc eq "RCS" ) {
- $diffcmd = "rcsdiff -u -r";
- $patchcmd = "patch -R -p0";
- } elsif ( $vc eq "SVN" ) {
- $diffcmd = "svn diff --internal-diff -r ";
- $patchcmd = "patch -R -p0";
- } elsif ( $vc eq "GIT" ) {
- $diffcmd = "git diff -r --relative --no-prefix ";
- $patchcmd = "patch -R -p0";
- # alternatively:
- # $diffcmd = "git diff ";
- # $patchcmd = "patch -R -p1";
- } elsif ( $vc eq "HG" ) {
- $diffcmd = "hg diff --root . -r";
- $patchcmd = "patch -R -p1";
- } else {
- print STDERR "Unknown versioning system $vc \n";
- exit 10;
- }
-}
-
-
-# make file list (last arguments), initial arguments have to be passed to latexdiff
-# We assume an argument is a valid file rather than a latexdiff argument
-# if it has extension .tex, .bbl or .flt (output of flatex), and does not start with a - or --
-
-@files=($file2);
-while( $file1=pop @ARGV ) {
- if ( $file1 =~ /\.(tex|bbl|flt)$/ && $file1 !~ /^-/) {
- # $file1 looks like a valid file name and is prepended to file list
- unshift @files, $file1 ;
- } else {
- # $file1 looks like an option for latexdiff, push it back to argument stack
- unshift @ldoptions, $file1 ;
- }
-}
-
-if ( length $configlatexdiff >0 ) {
- push @ldoptions, "--config=$configlatexdiff";
-}
-
-if ( defined($flatten) ) {
- push @ldoptions, "--flatten" ;
-}
-
-if ( defined($debug) && $debug ) {
- push @ldoptions, "--debug" ;
-}
-
-# impose ZLABEL subtype if --only-changes option
-if ( $onlychanges ) {
- push @ldoptions, "-s", "ZLABEL","-f","IDENTICAL","--no-links" ;
-}
-
-if ( scalar(@revs) == 0 ) {
- pod2usage("When -r option is not used, two .tex files (old and new) must be given on the command line") unless @files==2;
- warn "Option -flatten should normally be combined with -r option (Results will probably not be as expected)" if defined($flatten);
- # compare two files
- $file1=shift @files ;
-} else {
- # revision control
- if ( defined($flatten) ) {
- pod2usage("Only one root file must be given if --flatten option is used with version control") if @files != 1;
- $tempdir='.' if ( $flatten eq "keep-intermediate" );
- print STDERR "flatten tempdir |$tempdir|\n" if $debug;
- if ( $vc eq "SVN" ) {
- my (@infoout)=`svn info`;
- my (@urlline) = grep(/^URL:/, @infoout);
- @urlline ==1 or die "Ambiguous output from svn info command.";
- ( $rootdir = $urlline[0] ) =~ s/URL:\s*// ;
- chomp $rootdir;
- } elsif ( $vc eq "GIT" || $vc eq "HG" ) {
- # do nothing
- } else {
- die "--flatten option with revision control only possible with SVN, HG and GIT modes";
- }
- }
-}
-
-if ( scalar(@revs) == 2 ) {
- $append = "-diff$revs[0]-$revs[1]";
-} elsif ( scalar(@revs) == 1 || $revs[0] ) {
- $append = "-diff$revs[0]";
-} else {
- $append = "-diff";
-}
-
-if ( defined ($dir) && ! $dir ) {
- # bare -d option => choose directory name
- ($dir=$append) =~ s/^-//;
-}
-
-if ( ($vc eq "SVN" || $vc eq "CVS") && scalar(@revs)) {
- length($revs[$#revs]) > 0 or $revs[$#revs]="HEAD";
- length($revs[0]) > 0 or $revs[0]="HEAD";
-}
-
-if ($vc eq "HG" && scalar(@revs)) {
- length($revs[$#revs]) > 0 or $revs[$#revs]="tip";
- length($revs[0]) > 0 or $revs[0]="tip";
-}
-
-print STDERR "DEBUG LDOptions($#ldoptions): " . join(":",@ldoptions) . "\n" if $debug;
-
-
-# cycle through all files
-@difffiles=();
-
-while ( $infile=$file2=shift @files ) {
- print STDERR "Working on $infile \n";
- if ( scalar(@revs) == 1 ) {
- if ( defined($flatten) ) {
- my $olddir=$tempdir . "/latexdiff-vc-$revs[0]";
- print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n";
- checkout_dir($revs[0],$olddir);
- $file1=$olddir ."/".$infile;
- } else {
- ($file1=$infile) =~ s/\.(tex|bbl|flt)/-oldtmp-$$.$1/ ;
- push @tmpfiles,$file1;
- # compare file with previous version ($revs[0]="") or specified version
- ### system("$diffcmd$revs[0] $infile| $patchcmd -o$file1") ;
- if (system("$diffcmd$revs[0] \"$infile\" | $patchcmd -o\"$file1\"")==0 and -z $file1 ) {
- # no differences detected, i.e. file is equal to current version
- copy($infile,$file1) || die "copy($infile,$file1) failed: $!";
- }
- }
- } elsif ( scalar(@revs) == 2 ) {
- if ( defined($flatten) ) {
- my $olddir=$tempdir . "/latexdiff-vc-$revs[0]";
- print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n";
- checkout_dir($revs[0],$olddir);
- $file1=$olddir ."/".$infile;
-
- my $newdir=$tempdir . "/latexdiff-vc-$revs[1]";
- print STDERR "Checking out new dir into: $newdir\n";
- checkout_dir($revs[1],$newdir);
- $file2=$newdir ."/".$infile;
- } else {
- ($file1=$infile) =~ s/\.(tex|bbl|flt)/-oldtmp-$$.$1/ ;
- $file2 =~ s/\.(tex|bbl|flt)/-newtmp-$$.$1/ ;
- push @tmpfiles,$file2;
- if (system("$diffcmd$revs[1] $infile | $patchcmd -o$file2")==0 and -z $file2 ) {
- copy($infile,$file2) || die "copy($infile,$file2) failed: $!";
- }
- if (system("$diffcmd$revs[0] $infile | $patchcmd -o$file1")==0 and -z $file1 ) {
- copy($infile,$file1) || die "copy($infile,$file1) failed: $!";
- };
- }
- }
-
- if ( -z $file1 || -z $file2) {
- print STDERR "One or both of the files to compare are empty. Possibly something went wrong in the retrieval of older versions. Aborting ...\n" ;
- exit(10);
- }
-
- # Get name of difference file
- if ( defined($dir) ) {
- $diff="$dir/$infile" ;
- } else {
- ($diff=$infile) =~ s/\.(tex|bbl|flt)$/$append.$1/ ;
- }
-
- # make directories if needed
- $dirname=dirname($diff) ;
- system("mkdir -p $dirname") unless ( -e $dirname );
-
- # Remaining options are passed to latexdiff
- if (scalar(@ldoptions) > 0 ) {
- $options = "\'" . join("\' \'",@ldoptions) . "\'";
- } else {
- $options = "";
- }
-
- if ( -e $diff && ! $force ) {
- print STDERR "OK to overwrite existing file $diff (y/n)? ";
- $answer = <STDIN> ;
- unless ($answer =~ /^y/i ) {
- unlink @tmpfiles;
- die "Abort ... " ;
- }
- }
- print STDERR "Running: $CFG{LATEXDIFF} $options \"$file1\" \"$file2\" > \"$diff\"\n";
- unless ( system("$CFG{LATEXDIFF} $options \"$file1\" \"$file2\" > \"$diff\"") == 0 ) {
- print STDERR "Something went wrong in $CFG{LATEXDIFF}. Deleting $diff and abort\n" ; unlink $diff ; exit(5)
- };
- print "Generated difference file $diff\n";
-
- if ( $run and !( scalar(@revs) && greptex( qr/\\document(?:class|style)/ , $diff ) ) ) {
- # save filename for later processing if postscript or pdf conversion is requested and either two-file mode was used (scalar(@revs)==0) or the diff file contains documentclass statement (ie. is a root document)
- push @difffiles, $diff ;
- }
-
- unlink @tmpfiles;
-}
-
-foreach $diff ( @difffiles ) {
- chomp($cwd=(`pwd`));
- if (defined($dir)) {
- ( $diff =~ s/$dir\/?// ) ;
- chdir $dir ;
- }
- @ptmpfiles=();
- ( $diffbase=$diff) =~ s/\.(tex)$// ;
-
- # adapt magically changebar styles to [pdftex] display driver if pdf output was selected
- if ( $pdf ) {
- system("sed \"s/Package\\[dvips\\]/Package[pdftex]/\" \"$diff\" > \"$diff.tmp$$\" ; \\mv \"$diff.tmp$$\" \"$diff\"");
- }
-
- if ( $run ) {
- print STDERR "PDF: $pdf Postscript: $postscript cwd $cwd\n" if $debug;
-
- if ( system("grep -q \'^[^%]*\\\\bibliography{\' \"$diff\"") == 0 ) {
- system("$CFG{LATEX} --interaction=batchmode \"$diff\"; $CFG{BIBTEX} \"$diffbase\";");
- push @ptmpfiles, "$diffbase.bbl","$diffbase.bbl" ;
- }
-
- # if special needs, as CHANGEBAR
- if ( $extracomp ) {
- # print "Extracomp\n";
- system("$CFG{LATEX} --interaction=batchmode \"$diff\";");
- }
-
- # final compilation
- system("$CFG{LATEX} --interaction=batchmode \"$diff\";"); # needed if cross-refs
- system("$CFG{LATEX} \"$diff\";"); # final, with possible error messages
-
- if ( $rundvi2 ) {
- my $dvi="$diffbase.dvi";
- #my $ps="$diffbase.ps";
- my $ppoption="";
-
- if ( $onlychanges ) {
- $ppoption="-pp ".join(",",findchangedpages("$diffbase.aux"));
- }
- #system("$CFG{DVI2} $ppoption -o $ps $dvi");
- system("$CFG{DVI2} $ppoption $dvi");
- push @ptmpfiles, "$diffbase.aux","$diffbase.log",$dvi ;
- #print STDERR "Generated postscript file $ps\n";
- } elsif ( $run ) {
- if ( $onlychanges ) {
- my @pages=findchangedpages("$diffbase.aux");
- my $gs = `which gs`;
- $gs =~ s/^\s+|\s+$//g;
- my $qpdf = `which qpdf`;
- $qpdf =~ s/^\s+|\s+$//g;
- my $pdftk = `which pdftk`;
- $pdftk =~ s/^\s+|\s+$//g;
- my $command;
- if (-x $gs && `gs --version` >= 9.20) {
- $command="gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dSAFER -sPageList=" . join(",", @pages) . " -sOutputFile=\"$diffbase-changedpage.pdf\" \"$diffbase.pdf\"";
- } elsif (-x $pdftk) {
- $command="pdftk \"$diffbase.pdf\" cat " . join(" ",@pages) . " output \"$diffbase-changedpage.pdf\"";
- } elsif (-x $qpdf) {
- $command="qpdf --linearize \"$diffbase.pdf\" --pages \"$diffbase.pdf\" " . join(",", @pages) . " -- \"$diffbase-changedpage.pdf\" ";
- } else {
- die ("could not find any of gs, pdftk or qpdf");
- }
- print "Executing ".$command;
- system($command) == 0
- or die("could not execute <".$command."> to strip pages. Return code: $?");
- move("$diffbase-changedpage.pdf","$diffbase.pdf");
- }
- push @ptmpfiles, "$diffbase.aux","$diffbase.log";
- }
- }
- unlink @ptmpfiles;
- chdir $cwd;
-}
-
-# findchangedpages($auxfile)
-# returns a list of the page numbers on which changes were marked with the ZLABEL subtype of latexdiff
-sub findchangedpages {
- my ($auxfile) =@_;
- my $j;
- my (%pages); # note that I use a hash with page numbers as keys and arbitrary values - this way I can use Perl's built-in functions to get rid of duplicates
- my %start;
- open(AUX,$auxfile) or die ("Could open aux file $auxfile . System error: $!");
- while (<AUX>) {
- if (m/\\zref\@newlabel\{DIFchgb(\d*)\}\{.*\\abspage\{(\d*)\}\}/ ) {
- $start{$1}=$2; $pages{$2}=1;
- }
- if (m/\\zref\@newlabel\{DIFchge(\d*)\}\{.*\\abspage\{(\d*)\}\}/) {
- if (defined($start{$1})) {
- for ($j=$start{$1}; $j<=$2; $j++) {
- $pages{$j}=1;
- }
- } else {
- $pages{$2}=1;
- }
- }
- }
- close(AUX);
- # sort pages numerically (they should be sorted already; this is just to make sure
- return(sort {$a <=> $b} keys(%pages));
-}
-
-# checkout_dir(rev,dirname)
-# checks out revision rev and stores it in dirname
-# uses global variables: $vc, $rootdir
-sub checkout_dir {
- my ($rev,$dirname)=@_;
-
- unless (-e $dirname) { mkdir $dirname or die "Cannot mkdir $dirname ." ;}
- if ( $vc eq "SVN" ) {
- system("svn checkout -r $rev $rootdir $dirname")==0 or die "Something went wrong in executing: svn checkout -r $rev $rootdir $dirname";
- } elsif ( $vc eq "GIT" ) {
- $rev="HEAD" if length($rev)==0;
- system("git archive --format=tar $rev | ( cd $dirname ; tar -xf -)")==0 or die "Something went wrong in executing: git archive --format=tar $rev | ( cd $dirname ; tar -xf -)";
- } elsif ( $vc eq "HG" ) {
- system("hg archive --type files -r $rev $dirname")==0 or die "Something went wrong in executing: hg archive --type files -r $rev $dirname";
- } else {
- die "checkout_dir: only works with SVN, HG and GIT VCS system (selected: $vc)";
- }
-}
-
-# greptex returns 1 if regex is not matched in filename
-# only the 25 first non-comment lines are scanned
-# 0 if there is a match
-sub greptex {
- my ($regex,$filename)=@_;
- my ($i)=0;
- open (FH, $filename) or die("Couldn't open $filename: $!");
- while (<FH>) {
- next if /^\s*%/; # skip comment lines
- if ( m/$regex/ ) {
- close(FH);
- return(0);
- }
- # only scan 25 lines
- $i++;
- last if $i>25 ;
- }
- close(FH);
- return(1);
-}
-
-
-=head1 NAME
-
-latexdiff-vc - wrapper script that calls latexdiff for different versions of a file under version management (CVS, RCS or SVN)
-
-=head1 SYNOPSIS
-
-B<latexdiff-vc> [ F<latexdiff-options> ] [ F<latexdiff-vc-options> ] B<-r> [F<rev1>] [B<-r> F<rev2>] F<file1.tex> [ F<file2.tex> ...]
-
- or
-
-B<latexdiff-vc> [ F<latexdiff-options> ] [ F<latexdiff-vc-options> ][ B<--postscript> | B<--pdf> ] F<old.tex> F<new.tex>
-
-=head1 DESCRIPTION
-
-I<latexdiff-vc> is a wrapper script that applies I<latexdiff> to a
-file, or multiple files under version control (git, subversion (SVN), mercurial (hg), CVS, RCS), and optionally runs the
-sequence of C<latex> and C<dvips> or C<pdflatex> commands necessary to
-produce pdf or postscript output of the difference tex file(s). It can
-also be applied to a pair of files to automatise the generation of difference
-file in postscript or pdf format.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<--rcs>, B<--svn>, B<--cvs>, B<--git> or B<--hg>
-
-Set the version control system used.
-If no version system is specified, latexdiff-vc will venture a guess.
-
-latexdiff-cvs, latexdiff-rcs etc are variants of latexdiff-vc which default to
-the respective versioning system. However, this default can still be overridden using the options above.
-
-Note that hg needs to support the C<--root> option (version >= 2.9)
-
-=item B<-r>, B<-r> F<rev> or B<--revision>, B<--revision=>F<rev>
-
-Choose revision (under RCS, CVS, SVN, GIT or HG). One or two B<-r> options can be
-specified, and they result in different behaviour:
-
-=over 4
-
-=item B<latexdiff-vc> -r F<file.tex> ...
-
-compares F<file.tex> with the most recently checked-in version checked.
-
-=item B<latexdiff-vc> -r F<rev1> F<file.tex> ...
-
-compares F<file.tex> with revision F<rev1>.
-
-=item B<latexdiff-vc> -r F<rev1> -r F<rev2> F<file.tex> ...
-
-compares revisions F<rev1> and F<rev2> of F<file.tex>.
-
-Multiple files can be specified for all of the above options. All files must have the
-extensions C<.tex>, C<.bbl>, or C<.flt>, though.
-
-=item B<latexdiff-vc> F<old.tex> F<new.tex>
-
-compares two files.
-
-=back
-
-The name of the difference file is generated automatically and
-reported to stdout.
-
-=item B<-d> or B<--dir> B<-d> F<path> or B<--dir=>F<path>
-
-Rather than appending the string C<diff> and optionally the version
-numbers given to the output-file, this will prepend a directory name C<diff>
-to the
-original filename, creating the directory and sub-directories should they not exist already. This is particularly useful in order to clone a
-complete directory hierarchy. Optionally, a pathname F<path> can be specified, which is prepended instead of C<diff>.
-
-=item B<--flatten,--flatten=keep-intermediate>
-
-If combined with C<--git>, C<--svn> or C<--hg> option or the corresponding modes, check out the revisions to compare in a separate temporary directory, and then pass on option C<--flatten> to latexdiff. The directory in which C<latexdiff-vc> is invoked defines the subtree which will be checked out.
-Note that if additional files are needed which are not included in the flatten procedure (package files, included graphics), they need to be accessible in the current directory. If you use bibtex, it is recommended to include the C<.bbl> file in the version management.
-
-The generic usage of this function is : C<latexdiff-vc --flatten -r rev1 [-r rev2] master.tex> where master.tex is the project file containing the highest level of includes etc.
-
-With C<--flatten=keep-intermediate>, the intermediate revision snapshots are kept in the current directory (Default is to store them in a temporary directory and delete them after generating the diff file.)
-
-
-=item B<--only-changes>
-
-Post-process the output such that only pages with changes on them are displayed. This requires the use of subtype ZLABEL
-in latexdiff, which will be set automatically, but any manually set -s option will be overruled (also requires zref package to
-be installed). (note that this option must be combined with --ps or --pdf to make sense)
-
-=item B<--force>
-
-Overwrite existing diff files without asking for confirmation. Default
-behaviour is to ask for confirmation before overwriting an existing difference
-file.
-
-=item B<--run>
-
-run latex command on diff file after generation of diff file.
-
-=item B<--dvi>
-
-run latex and dvixxx commands after generation of diff file.
-
-=item B<-c configfile>
-=item B<--config var1=val1,var2=val2,...> or B<-c var1=val1,..>
-
-Set configuration variables for latexdiff and latexdiff-vc. The option can be repeated to set different
-variables (as an alternative to the comma-separated list).
-Available variables for latexdiff-vc:
-
-=over 8
-
-=item C<LATEXDIFF> latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the option C<--interaction=batchmode>
-
-=item C<LATEX> latex command (e.g. pdflatex, lualatex)
-
-=item C<DVI2> Command for conversion of dvi file (e.g. dvips, dvipdf)
-
-=item C<BIBTEX> Command replacing bibtex
-
-=back
-
-All other config variables are passed to latexdiff. Explicitly set configuration changes always override implicit
-changes by the following shortcut options B<--fast>, B<--so>, B<--ps> and B<--pdf>.
-
-=item B<--fast> or B<--so>
-
-Use C<latexdiff-fast> or C<latexdiff-so>, respectively (instead of C<latexdiff>).
-
-=item B<--ps> or B<--postscript>
-
-Generate postscript output from difference file. This will run the
-sequence C<latex; latex; dvips> on the difference file (do not use
-this option in the rare cases, where three C<latex> commands are
-required if you care about correct referencing). If the difference
-file contains a C<\bibliography> tag, run the sequence C<latex;
-bibtex; latex; latex; dvips>.
-
-=item B<--pdf>
-
-Generate pdf output from difference file using C<pdflatex>. This will
-run the sequence C<pdflatex; pdflatex> on the difference file, or
-C<pdflatex; bibtex; pdflatex; pdflatex> for files requiring bibtex.
-Note that this is not just a shortcut for setting configuration variable but also triggers
-some special behaviour.
-
-
-=item B<--show-config>
-
-Show values of configuration variables.
-
-=item B<--help> or B<-h>
-
-Show help text
-
-=item B<--version>
-
-Show version number
-
-=back
-
-All other options are passed on to C<latexdiff>.
-
-=head1 SEE ALSO
-
-L<latexdiff>
-
-=head1 PORTABILITY
-
-I<latexdiff-vc> uses external commands and is therefore dependent on the system architecture; it has been
-tested mainly on Unix-like systems. It also requires a version control
-system and latex to be installed on the system to make use of all features. Modules from Perl 5.8
-or higher are required.
-
-=head1 BUG REPORTING
-
-Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>,
-or send them to I<tilmann -- AT -- gfz-potsdam.de>. Include the version number of I<latexdiff-vc>
-(option C<--version>).
-
-=head1 AUTHOR
-
-Version 1.2.1
-Copyright (C) 2005-2017 Frederik Tilmann
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License Version 3
-Contributors: S Utcke, H Bruyninckx; some ideas have been inspired by git-latexdiff bash script.
-C. Junghans: Mercurial Support.
-
-=cut
-
diff --git a/Build/source/texk/texlive/linked_scripts/latexdiff/latexdiff.pl b/Build/source/texk/texlive/linked_scripts/latexdiff/latexdiff.pl
deleted file mode 100755
index 45e5188bcc7..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latexdiff/latexdiff.pl
+++ /dev/null
@@ -1,5643 +0,0 @@
-#!/usr/bin/env perl
-##!/usr/bin/perl -w
-# latexdiff - differences two latex files on the word level
-# and produces a latex file with the differences marked up.
-#
-# Copyright (C) 2004-20 F J Tilmann (tilmann@gfz-potsdam.de)
-#
-# Repository/issue tracker: https://github.com/ftilmann/latexdiff
-# CTAN page: http://www.ctan.org/pkg/latexdiff
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Detailed usage information at the end of the file
-#
-
-# Version 1.3.1.1
-# - remove spurious \n to fix error: Unknown regexp modifier "/n" at .../latexdiff line 1974, near "=~ " (see github issue #201)
-#
-# Version 1.3.1
-# Bug fixes:
-# - remove some uninitialised variable $2 warnings in string substitution in flatten function in case included file is not found
-# - add minimal postprocessing to diff processing of preamble commands (replace \RIGHTBRACE by \} )
-# - pre-processing: replace (contributed) routine take_comments_and_enter_from_frac() with take_comments_and_newline_from_frac(), which does the same thing
-# (remove whitespace characters and comments between the argument of \frac commands) in an easier and more robust way. In addition, it
-# will replace commands like \frac12 with \frac{1}{2} as pre-processing step. Fixes issue #184
-# - add "intertext" to list of unsafe math commands @UNSAFEMATHCMD . Fixes issue #179
-# - provide citation command patterns for biblatex and protect them with mbox'es. Fixes issue #199
-# - hardcode number of parameters for \href and \url commands to allow spaces between commands and arguments even if --allow-spaces option is not used (this
-# is needed because some bibliography styles add such in-command-sequence spaces) Fixes issues: #178 #198
-# - bibitem is now kept even in deleted blocks such that deleted references show up properly (this implies that the actual numbers in numerical referencing schemes will change)
-# (this is implemented by introducing a new class of commands KEEPCMD , which are kept as is in deleted environments (no effect in added environments). Currently
-# \bibitem is hardwired to be the only member of this class (fixes issue #194, #174)
-# Features:
-# - add some special processing for revtex bibliography commands, so that the spaces between bibliography commands \bibfield and \bibinfo and their arguments are ignored.
-# (fixes issue #194, should fix #174)
-#
-# Version 1.3.0 (7 October 2018):
-# - treat options to \documentclass as potential package names (some packages allow implicit loading of or imply selected packages
-# - improved pattern matching: now allows nested angular brackets, and is no longer confused by escaped curly braces
-# - improved pattern matching in COARSE mode: occasionally, the closing bracket or some other elements would be matched in an 'unnatural' way due to another sequence being more minimal in the computational sense, sometimes even causing errors due to tokens moving in or out of the scope of math environments. This is now discouraged by adding internal \DIFANCHOR commands (which are removed again in post-processing) (fixes issues reported via email by li_ruomeng .
-# - verbatim and lstlisting environments are marked-up with line-by-line in a similar style to non-verbatim text (requires the listing package to be installed)
-# (see new configuration variable VERBATIMLINEENV) (several issues and pull requests by jprotze)
-# - --flatten: now supports \verbatiminput and \lstlistinput
-# - --flatten: if file is not found, do not fail, simply warn and leave command unexpanded (inspired by issue #112). Don't warn if file name contains #[0-9] as it is then most likely an argument within a command definition rather than an actual file (applies to \input, \subfile, \include commands)
-# - added to textcmds: \intertext
-# - new config variable CUSTOMDIFCMD to allow defining special versions of commands in added or deleted blocks (Pull request by github user jprotze)
-# - added option -no-links (mostly for use by latexdiff-vc in only-changes modes) (Pull request by github user jprotze)
-# - new option --filter-script to run both input through a pre-processing script (PR jasonmccsmith #167)
-# new option --no-filter-stderr to hide stderr output from filter-script (potentially dangerous, as this might hide malfunctioning of filter scripts)
-# - --flatten now can deal with imports made using the import package {PR jasonmccsmith #173)
-# Bug fixes:
-# - pattern matching of \verb and \lstinline commands had an error which meant they would trigger on commands beginning with \verb.
-# - In description environments, mark up item descriptions by effectively reating the insides of item commannds as text commands (fixes #161)
-#
-#
-# Version 1.2.1 (22 June 2017)
-# - add "DeclareOldFontCommand" to styles using \bf or \sf old style font commands (fixies issue #92 )
-# - improved markup: process lstinline commands in listings package correctly
-# for styles using colour, \verb and \lstinline arguments are marked up with colour (blue for added, red for deleted)
-# - bug fix: protecting inline math expressions for mbox did not work as intended (see stack exchange question: http://tex.stackexchange.com/questions/359412/compiling-the-latexdiff-when-adding-a-subscript-before-a-pmatrix-environment-cau)
-# - bug fix: when deleted \item commands are followed immediately by unsafe commands, they were not restored properly
-# (thanks to J. Protze for pull request) (pull request #89)
-# - treat lstlisting and comment as equivalent to verbatim environment
-# make environments that are treated like verbatim environments configurable (config variable VERBATIMENV)
-# treat lstinlne as equivalent to verb command
-# partially addresses issue #38
-# - refactoring: set default configuration variables in a hash, and those that correspond to lists
-# - feature: option --add-to-config used to amend configuration variables, which are regex pattern lists
-# - bug fix: deleted figures when endfloat package is activated
-# - bug fix: alignat environment now always processed correctly (fix issues #65)
-# - bug fix: avoid processing of commands as potential files in routine init_regex_arr (fix issue #70 )
-# - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be
-# @ a letter if it is part of a command name will usually lead to the correct behaviour (see http://tex.stackexchange.com/questions/346651/latexdiff-and-let)
-# - new feature/bug fix: --flatten option \endinput in included files now respected but only if \endinput stands right at the beginning of the line (issue #77)
-# - bug fix: flatten would incorrectly attempt to process commented out \include commands (from discussion in issue #77 )
-# - introduce an invisible space (\hspace{0pt} after \mbox{..} auxiliary commands (not in math mode), to allow line breaks between added and deleted citations (change should not cause adverse behaviour otherwise)
-#
-# Version 1.2.0:
-# - highlight new and deleted figures
-# - bug fix in title mark-up. Previously deleted commands in title (such as \title, \author or \date) were marked up erroneously
-# - (minor) bug fixes in new 1.1.1 features: disabled label was commented out twice, additional spaces were introduced before list environment begin and end commands
-# - depracation fix: left brace in RegEx now needs to be escaped
-# - add type PDFCOMMENT based on issue #49 submitted by github user peci1 (Martin Pecka)
-# - make utf8 the default encoding
-#
-# Version 1.1.1
-# - patch mhchem: allow ce in equations
-# - flatten now also expands \input etc. in the preamble (but not \usepackage!)
-# - Better support for Japanese ( contributed by github user kshramt )
-# - prevent duplicated verbatim hashes (patch contributed by github user therussianjig, issue #36)
-# - disable deleted label commands (fixes issue #31)
-# - introduce post-processing to reinstate most deleted environments and all needed item commands (fixes issue #1)
-#
-# Version 1.1.0
-# - treat diacritics (\",\', etc) as safe commands
-# - treat \_ and \& correctly as safe commands, even if used without spacing to the next word
-# - Add a BOLD markup type that sets added text in bold face (Contribution by Victor Zabalza via pull request )
-# - add append-mboxsafecmd list option to be able to specify special safe commands which need to be surrounded by mbox to avoid breaking (mostly this is needed with ulem package)
-# - support for siunitx and cleveref packages: protect \SI command in siunitx package and \cref,\Cref{range}{*} in cleveref packages (thanks to Stefan Pinnow for testing)
-# - experimental support for chemformula, mhchem packages: define \ch and \ce in packages as safe (but not \ch,\cee in equation array environments) - these unfortunately will not be marked up (thanks to Stefan Pinnow for testing)
-# - bug fix: packages identified correctly even if \usepackage command options extend over several lines (previously \usepackage command needed to be fully contained in one line)
-# - new subtype ONLYCHANGEDPAGE outputs only changed pages (might not work well for floating material)
-# - new subtype ZLABEL operates similarly to LABEL but uses absolute page numbers (needs zref package)
-# - undocumented option --debug/--nodebug to override default setting for debug mode (Default: 0 for release version, 1: for development version
-#
-# Version 1.0.4
-# - introduce list UNSAFEMATHCMD, which holds list of commands which cannot be marked up with \DIFadd or \DIFdel commands (only relevant for WHOLE and COARSE math markup modes)
-# - new subtype LABEL which gives each change a label. This can later be used to only display pages where changes
-# have been made (instructions for that are put as comments into the diff'ed file) inspired by answer on http://tex.stackexchange.com/questions/166049/invisible-markers-in-pdfs-using-pdflatex
-# - Configuration variables take into accout some commands from additional packages:
-# tikzpicture environment now treated as PICTUREENV, and \smallmatrix in ARRENV (amsmath)
-# - --flatten: support for \subfile command (subfiles package) (in response to http://tex.stackexchange.com/questions/167620/latexdiff-with-subfiles )
-# - --flatten: \bibliography commands expand if corresponding bbl file present
-# - angled bracket optional commands now parsed correctly (patch #3570) submitted by Dave Kleinschmidt (thanks)
-# - \RequirePackage now treated as synonym of \usepackage with respect to setting packages
-# - special rules for apacite package (redefine citation commands)
-# - recognise /dev/null as 'file-like' arguments for --preamble and --config options
-# - fix units package incompatibility with ulem for text maths statements $ ..$ (thanks to Stuart Prescott for reporting this)
-# - amsmath environment cases treated correctly (Bug fix #19029) (thanks to Jalar)
-# - {,} in comments no longer confuse latexdiff (Bug fix #19146)
-# - \% in one-letter sub/Superscripts was not converted correctly
-#
-# Version 1.0.3
-# - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator
-# command in preamble
-# - \(..\) inline math expressions were not parsed correctly, if they contained a linebreak
-# - applied patch contributed by tomflannaghan via Berlios: [ Patch #3431 ] Adds correct handling of \left< and \right>
-# - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug
-# and sketching out the solution)
-# - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript
-# (thanks to Wail Yahyaoui for pointing out this bug)
-#
-# Version 1.0.1 - treat \big,\bigg etc. equivalently to \left and
-# \right - include starred version in MATHENV - apply
-# - flatten recursively and --flatten expansion is now
-# aware of comments (thanks to Tim Connors for patch)
-# - Change to post-processing for more reliability for
-# deleted math environments
-# - On linux systems, recognise and remove DOS style newlines
-# - Provide markup for some special preamble commands (\title,
-# \author,\date,
-# - configurable by setting context2cmd
-# - for styles using ulem package, remove \emph and \text.. from list of
-# safe commands in order to allow linebreaks within the
-# highlighted sections.
-# - for ulem style, now show citations by enclosing them in \mbox commands.
-# This unfortunately implies linebreaks within citations no longer function,
-# so this functionality can be turned off (Option --disable-citation-markup).
-# With --enable-citation-markup, the mbox markup is forced for other styles)
-# - new substyle COLOR. This is particularly useful for marking up citations
-# and some special post-processing is implemented to retain cite
-# commands in deleted blocks.
-# - four different levels of math-markup
-# - Option --driver for choosing driver for modes employing changebar package
-# - accept \\* as valid command (and other commands of form \.*). Also accept
-# \<nl> (backslashed newline)
-# - some typo fixes, include commands defined in preamble as safe commands
-# (Sebastian Gouezel)
-# - include compared filenames as comments as line 2 and 3 of
-# the preamble (can be modified with option --label, and suppressed with
-# --no-label), option --visible-label to show files in generated pdf or dvi
-# at the beginning of main document
-#
-# Version 0.5 A number of minor improvements based on feedback
-# Deleted blocks are now shown before added blocks
-# Package specific processing
-#
-# Version 0.43 unreleased typo in list of styles at the end
-# Add protect to all \cbstart, \cbend commands
-# More robust substitution of deleted math commands
-#
-# Version 0.42 November 06 Bug fixes only
-#
-# Version 0.4 March 06 option for fast differencing using UNIX diff command, several minor bug fixes (\par bug, improved highlighting of textcmds)
-#
-# Version 0.3 August 05 improved parsing of displayed math, --allow-spaces
-# option, several minor bug fixes
-#
-# Version 0.25 October 04 Fix bug with deleted equations, add math mode commands to safecmd, add | to allowed interpunctuation signs
-# Version 0.2 September 04 extension to utf-8 and variable encodings
-# Version 0.1 August 04 First public release
-
-# Inserted block for stand-alone version replaces
-# use Algorithm::Diff qw(traverse_sequences);
-# in standard version
-# The following BEGIN block contains a verbatim copy of
-# Ned Konz' Algorithm::Diff package version 1.15 except
-# that all POD documentation has been stripped out.
-# I encourage you to download and install the Algorithm::Diff
-# package and use the standard latexdiff version instead
-# (current distribution available from http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15
-# the most recent version can be found via http://search.cpan.org/search?module=Algorithm::Diff )
-# Please note the LICENCE for Algorithm::Diff :
-# "Copyright (c) 2000-2002 Ned Konz. All rights reserved.
-# This program is free software;
-# you can redistribute it and/or modify it under the same terms
-# as Perl itself."
-# The stand-alone version of latexdiff is provided as a convenience
-# for latex users with no knowledge of PERL who do not wish to install
-# additional packages to be able to use latexdiff. If you believe
-# the inlining of Algorithm::Diff violates its license please contact
-# me and I will modify the latexdiff distribution accordingly.
-# Frederik Tilmann (tilmann@esc.cam.ac.uk)
-BEGIN {
-package Algorithm::Diff;
-use strict;
-use vars qw($VERSION @EXPORT_OK @ISA @EXPORT);
-use integer; # see below in _replaceNextLargerWith() for mod to make
- # if you don't use this
-require Exporter;
-@ISA = qw(Exporter);
-@EXPORT = qw();
-@EXPORT_OK = qw(LCS diff traverse_sequences traverse_balanced sdiff);
-$VERSION = sprintf('%d.%02d so', (q$Revision: 1.15 $ =~ /\d+/g));
-
-# McIlroy-Hunt diff algorithm
-# Adapted from the Smalltalk code of Mario I. Wolczko, <mario@wolczko.com>
-# by Ned Konz, perl@bike-nomad.com
-
-
-# Create a hash that maps each element of $aCollection to the set of positions
-# it occupies in $aCollection, restricted to the elements within the range of
-# indexes specified by $start and $end.
-# The fourth parameter is a subroutine reference that will be called to
-# generate a string to use as a key.
-# Additional parameters, if any, will be passed to this subroutine.
-#
-# my $hashRef = _withPositionsOfInInterval( \@array, $start, $end, $keyGen );
-
-sub _withPositionsOfInInterval
-{
- my $aCollection = shift; # array ref
- my $start = shift;
- my $end = shift;
- my $keyGen = shift;
- my %d;
- my $index;
- for ( $index = $start ; $index <= $end ; $index++ )
- {
- my $element = $aCollection->[$index];
- my $key = &$keyGen( $element, @_ );
- if ( exists( $d{$key} ) )
- {
- unshift ( @{ $d{$key} }, $index );
- }
- else
- {
- $d{$key} = [$index];
- }
- }
- return wantarray ? %d : \%d;
-}
-
-# Find the place at which aValue would normally be inserted into the array. If
-# that place is already occupied by aValue, do nothing, and return undef. If
-# the place does not exist (i.e., it is off the end of the array), add it to
-# the end, otherwise replace the element at that point with aValue.
-# It is assumed that the array's values are numeric.
-# This is where the bulk (75%) of the time is spent in this module, so try to
-# make it fast!
-
-sub _replaceNextLargerWith
-{
- my ( $array, $aValue, $high ) = @_;
- $high ||= $#$array;
-
- # off the end?
- if ( $high == -1 || $aValue > $array->[-1] )
- {
- push ( @$array, $aValue );
- return $high + 1;
- }
-
- # binary search for insertion point...
- my $low = 0;
- my $index;
- my $found;
- while ( $low <= $high )
- {
- $index = ( $high + $low ) / 2;
-
- # $index = int(( $high + $low ) / 2); # without 'use integer'
- $found = $array->[$index];
-
- if ( $aValue == $found )
- {
- return undef;
- }
- elsif ( $aValue > $found )
- {
- $low = $index + 1;
- }
- else
- {
- $high = $index - 1;
- }
- }
-
- # now insertion point is in $low.
- $array->[$low] = $aValue; # overwrite next larger
- return $low;
-}
-
-# This method computes the longest common subsequence in $a and $b.
-
-# Result is array or ref, whose contents is such that
-# $a->[ $i ] == $b->[ $result[ $i ] ]
-# foreach $i in ( 0 .. $#result ) if $result[ $i ] is defined.
-
-# An additional argument may be passed; this is a hash or key generating
-# function that should return a string that uniquely identifies the given
-# element. It should be the case that if the key is the same, the elements
-# will compare the same. If this parameter is undef or missing, the key
-# will be the element as a string.
-
-# By default, comparisons will use "eq" and elements will be turned into keys
-# using the default stringizing operator '""'.
-
-# Additional parameters, if any, will be passed to the key generation routine.
-
-sub _longestCommonSubsequence
-{
- my $a = shift; # array ref
- my $b = shift; # array ref
- my $keyGen = shift; # code ref
- my $compare; # code ref
-
- # set up code refs
- # Note that these are optimized.
- if ( !defined($keyGen) ) # optimize for strings
- {
- $keyGen = sub { $_[0] };
- $compare = sub { my ( $a, $b ) = @_; $a eq $b };
- }
- else
- {
- $compare = sub {
- my $a = shift;
- my $b = shift;
- &$keyGen( $a, @_ ) eq &$keyGen( $b, @_ );
- };
- }
-
- my ( $aStart, $aFinish, $bStart, $bFinish, $matchVector ) =
- ( 0, $#$a, 0, $#$b, [] );
-
- # First we prune off any common elements at the beginning
- while ( $aStart <= $aFinish
- and $bStart <= $bFinish
- and &$compare( $a->[$aStart], $b->[$bStart], @_ ) )
- {
- $matchVector->[ $aStart++ ] = $bStart++;
- }
-
- # now the end
- while ( $aStart <= $aFinish
- and $bStart <= $bFinish
- and &$compare( $a->[$aFinish], $b->[$bFinish], @_ ) )
- {
- $matchVector->[ $aFinish-- ] = $bFinish--;
- }
-
- # Now compute the equivalence classes of positions of elements
- my $bMatches =
- _withPositionsOfInInterval( $b, $bStart, $bFinish, $keyGen, @_ );
- my $thresh = [];
- my $links = [];
-
- my ( $i, $ai, $j, $k );
- for ( $i = $aStart ; $i <= $aFinish ; $i++ )
- {
- $ai = &$keyGen( $a->[$i], @_ );
- if ( exists( $bMatches->{$ai} ) )
- {
- $k = 0;
- for $j ( @{ $bMatches->{$ai} } )
- {
-
- # optimization: most of the time this will be true
- if ( $k and $thresh->[$k] > $j and $thresh->[ $k - 1 ] < $j )
- {
- $thresh->[$k] = $j;
- }
- else
- {
- $k = _replaceNextLargerWith( $thresh, $j, $k );
- }
-
- # oddly, it's faster to always test this (CPU cache?).
- if ( defined($k) )
- {
- $links->[$k] =
- [ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ];
- }
- }
- }
- }
-
- if (@$thresh)
- {
- for ( my $link = $links->[$#$thresh] ; $link ; $link = $link->[0] )
- {
- $matchVector->[ $link->[1] ] = $link->[2];
- }
- }
-
- return wantarray ? @$matchVector : $matchVector;
-}
-
-sub traverse_sequences
-{
- my $a = shift; # array ref
- my $b = shift; # array ref
- my $callbacks = shift || {};
- my $keyGen = shift;
- my $matchCallback = $callbacks->{'MATCH'} || sub { };
- my $discardACallback = $callbacks->{'DISCARD_A'} || sub { };
- my $finishedACallback = $callbacks->{'A_FINISHED'};
- my $discardBCallback = $callbacks->{'DISCARD_B'} || sub { };
- my $finishedBCallback = $callbacks->{'B_FINISHED'};
- my $matchVector = _longestCommonSubsequence( $a, $b, $keyGen, @_ );
-
- # Process all the lines in @$matchVector
- my $lastA = $#$a;
- my $lastB = $#$b;
- my $bi = 0;
- my $ai;
-
- for ( $ai = 0 ; $ai <= $#$matchVector ; $ai++ )
- {
- my $bLine = $matchVector->[$ai];
- if ( defined($bLine) ) # matched
- {
- &$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine;
- &$matchCallback( $ai, $bi++, @_ );
- }
- else
- {
- &$discardACallback( $ai, $bi, @_ );
- }
- }
-
- # The last entry (if any) processed was a match.
- # $ai and $bi point just past the last matching lines in their sequences.
-
- while ( $ai <= $lastA or $bi <= $lastB )
- {
-
- # last A?
- if ( $ai == $lastA + 1 and $bi <= $lastB )
- {
- if ( defined($finishedACallback) )
- {
- &$finishedACallback( $lastA, @_ );
- $finishedACallback = undef;
- }
- else
- {
- &$discardBCallback( $ai, $bi++, @_ ) while $bi <= $lastB;
- }
- }
-
- # last B?
- if ( $bi == $lastB + 1 and $ai <= $lastA )
- {
- if ( defined($finishedBCallback) )
- {
- &$finishedBCallback( $lastB, @_ );
- $finishedBCallback = undef;
- }
- else
- {
- &$discardACallback( $ai++, $bi, @_ ) while $ai <= $lastA;
- }
- }
-
- &$discardACallback( $ai++, $bi, @_ ) if $ai <= $lastA;
- &$discardBCallback( $ai, $bi++, @_ ) if $bi <= $lastB;
- }
-
- return 1;
-}
-
-sub traverse_balanced
-{
- my $a = shift; # array ref
- my $b = shift; # array ref
- my $callbacks = shift || {};
- my $keyGen = shift;
- my $matchCallback = $callbacks->{'MATCH'} || sub { };
- my $discardACallback = $callbacks->{'DISCARD_A'} || sub { };
- my $discardBCallback = $callbacks->{'DISCARD_B'} || sub { };
- my $changeCallback = $callbacks->{'CHANGE'};
- my $matchVector = _longestCommonSubsequence( $a, $b, $keyGen, @_ );
-
- # Process all the lines in match vector
- my $lastA = $#$a;
- my $lastB = $#$b;
- my $bi = 0;
- my $ai = 0;
- my $ma = -1;
- my $mb;
-
- while (1)
- {
-
- # Find next match indices $ma and $mb
- do { $ma++ } while ( $ma <= $#$matchVector && !defined $matchVector->[$ma] );
-
- last if $ma > $#$matchVector; # end of matchVector?
- $mb = $matchVector->[$ma];
-
- # Proceed with discard a/b or change events until
- # next match
- while ( $ai < $ma || $bi < $mb )
- {
-
- if ( $ai < $ma && $bi < $mb )
- {
-
- # Change
- if ( defined $changeCallback )
- {
- &$changeCallback( $ai++, $bi++, @_ );
- }
- else
- {
- &$discardACallback( $ai++, $bi, @_ );
- &$discardBCallback( $ai, $bi++, @_ );
- }
- }
- elsif ( $ai < $ma )
- {
- &$discardACallback( $ai++, $bi, @_ );
- }
- else
- {
-
- # $bi < $mb
- &$discardBCallback( $ai, $bi++, @_ );
- }
- }
-
- # Match
- &$matchCallback( $ai++, $bi++, @_ );
- }
-
- while ( $ai <= $lastA || $bi <= $lastB )
- {
- if ( $ai <= $lastA && $bi <= $lastB )
- {
-
- # Change
- if ( defined $changeCallback )
- {
- &$changeCallback( $ai++, $bi++, @_ );
- }
- else
- {
- &$discardACallback( $ai++, $bi, @_ );
- &$discardBCallback( $ai, $bi++, @_ );
- }
- }
- elsif ( $ai <= $lastA )
- {
- &$discardACallback( $ai++, $bi, @_ );
- }
- else
- {
-
- # $bi <= $lastB
- &$discardBCallback( $ai, $bi++, @_ );
- }
- }
-
- return 1;
-}
-
-sub LCS
-{
- my $a = shift; # array ref
- my $matchVector = _longestCommonSubsequence( $a, @_ );
- my @retval;
- my $i;
- for ( $i = 0 ; $i <= $#$matchVector ; $i++ )
- {
- if ( defined( $matchVector->[$i] ) )
- {
- push ( @retval, $a->[$i] );
- }
- }
- return wantarray ? @retval : \@retval;
-}
-
-sub diff
-{
- my $a = shift; # array ref
- my $b = shift; # array ref
- my $retval = [];
- my $hunk = [];
- my $discard = sub { push ( @$hunk, [ '-', $_[0], $a->[ $_[0] ] ] ) };
- my $add = sub { push ( @$hunk, [ '+', $_[1], $b->[ $_[1] ] ] ) };
- my $match = sub { push ( @$retval, $hunk ) if scalar(@$hunk); $hunk = [] };
- traverse_sequences( $a, $b,
- { MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add }, @_ );
- &$match();
- return wantarray ? @$retval : $retval;
-}
-
-sub sdiff
-{
- my $a = shift; # array ref
- my $b = shift; # array ref
- my $retval = [];
- my $discard = sub { push ( @$retval, [ '-', $a->[ $_[0] ], "" ] ) };
- my $add = sub { push ( @$retval, [ '+', "", $b->[ $_[1] ] ] ) };
- my $change = sub {
- push ( @$retval, [ 'c', $a->[ $_[0] ], $b->[ $_[1] ] ] );
- };
- my $match = sub {
- push ( @$retval, [ 'u', $a->[ $_[0] ], $b->[ $_[1] ] ] );
- };
- traverse_balanced(
- $a,
- $b,
- {
- MATCH => $match,
- DISCARD_A => $discard,
- DISCARD_B => $add,
- CHANGE => $change,
- },
- @_
- );
- return wantarray ? @$retval : $retval;
-}
-
-1;
-}
-import Algorithm::Diff qw(traverse_sequences);
-# End of inserted block for stand-alone version
-
-use Getopt::Long ;
-use strict ;
-use warnings;
-use utf8 ;
-
-use File::Spec ;
-
-my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION);
-
-
-my ($versionstring)=<<EOF ;
-This is LATEXDIFF 1.3.1.1 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V)
- (c) 2004-2020 F J Tilmann
-EOF
-
-# Hash with defaults for configuration variables. These marked undef have default values constructed from list defined in the DATA block
-# (under tag CONFIG)
-my %CONFIG=(
- MINWORDSBLOCK => 3, # minimum number of tokens to form an independent block
- # shorter identical blocks will be merged to the previous word
- SCALEDELGRAPHICS => 0.5, # factor with which deleted figures will be scaled down (i.e. 0.5 implies they are shown at half linear size)
- # this is only used for --graphics-markup=BOTH option
- FLOATENV => undef , # Environments in which FL variants of defined commands are used
- PICTUREENV => undef , # Environments in which all change markup is removed
- MATHENV => undef , # Environments turning on display math mode (code also knows about \[ and \])
- MATHREPL => 'displaymath', # Environment introducing deleted maths blocks
- MATHARRENV => undef , # Environments turning on eqnarray math mode
- MATHARRREPL => 'eqnarray*', # Environment introducing deleted maths blocks
- ARRENV => undef , # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block
- COUNTERCMD => undef,
- # COUNTERCMD textcmds which are associated with a counter
- # If any of these commands occur in a deleted block
- # they will be followed by an \addtocounter{...}{-1}
- # for the associated counter such that the overall numbers
- # should be the same as in the new file
- LISTENV => undef , # list making environments - they will generally be kept
- VERBATIMENV => undef, # Environments whose content should be treated as verbatim text and not be touched
- VERBATIMLINEENV => undef, # Environments whose content should be treated as verbatim text and processed in line diff mode
- CUSTOMDIFCMD => undef,# Custom dif command. Is defined in the document as a \DELcommand and \ADDcommand version to be replaced by the diff
- ITEMCMD => 'item' # command marking item in a list environment
-);
-# Configuration variables: these have to be visible from the subroutines
-my ($ARRENV,
- $COUNTERCMD,
- $FLOATENV,
- $ITEMCMD,
- $LISTENV,
- $MATHARRENV,
- $MATHARRREPL,
- $MATHENV,
- $MATHREPL,
- $MINWORDSBLOCK,
- $PICTUREENV,
- $SCALEDELGRAPHICS,
- $VERBATIMENV,
- $VERBATIMLINEENV,
- $CUSTOMDIFCMD
- );
-
-# my $MINWORDSBLOCK=3; # minimum number of tokens to form an independent block
-# # shorter identical blocks will be merged to the previous word
-# my $SCALEDELGRAPHICS=0.5; # factor with which deleted figures will be scaled down (i.e. 0.5 implies they are shown at half linear size)
-# # this is only used for --graphics-markup=BOTH option
-# my $FLOATENV='(?:figure|table|plate)[\w\d*@]*' ; # Environments in which FL variants of defined commands are used
-# my $PICTUREENV='(?:picture|tikzpicture|DIFnomarkup)[\w\d*@]*' ; # Environments in which all change markup is removed
-# my $MATHENV='(?:equation[*]?|displaymath|DOLLARDOLLAR)[*]?' ; # Environments turning on display math mode (code also knows about \[ and \])
-# my $MATHREPL='displaymath'; # Environment introducing deleted maths blocks
-# my $MATHARRENV='(?:eqnarray|align|alignat|gather|multline|flalign)[*]?' ; # Environments turning on eqnarray math mode
-# my $MATHARRREPL='eqnarray*'; # Environment introducing deleted maths blocks
-# my $ARRENV='(?:aligned|gathered|array|[pbvBV]?matrix|smallmatrix|cases|split)'; # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block
-# my $COUNTERCMD='(?:footnote|part|chapter|section|subsection|subsubsection|paragraph|subparagraph)'; # textcmds which are associated with a counter
-# # If any of these commands occur in a deleted block
-# # they will be succeeded by an \addtocounter{...}{-1}
-# # for the associated counter such that the overall numbers
-# # should be the same as in the new file
-# my $LISTENV='(?:itemize|description|enumerate)'; # list making environments - they will generally be kept
-# my $ITEMCMD='item'; # command marking item in a list environment
-
-
-
-my $LABELCMD='(?:label)'; # matching commands are disabled within deleted blocks - mostly useful for maths mode, as otherwise it would be fine to just not add those to SAFECMDLIST
-my @UNSAFEMATHCMD=('qedhere','intertext'); # Commands which are definitely unsafe for marking up in math mode (amsmath qedhere only tested to not work with UNDERLINE markup) (only affects WHOLE and COARSE math markup modes). Note that unlike text mode (or FINE math mode0 deleted unsafe commands are not deleted but simply taken outside \DIFdel
-my $MBOXINLINEMATH=0; # if set to 1 then surround marked-up inline maths expression with \mbox ( to get around compatibility
- # problems between some maths packages and ulem package
-
-
-# Markup strings
-# If at all possible, do not change these as parts of the program
-# depend on the actual name (particularly post-processing)
-# At the very least adapt subroutine postprocess to new tokens.
-my $ADDMARKOPEN='\DIFaddbegin '; # Token to mark begin of appended text
-my $ADDMARKCLOSE='\DIFaddend '; # Token to mark end of appended text
-my $ADDOPEN='\DIFadd{'; # To mark begin of added text passage
-my $ADDCLOSE='}'; # To mark end of added text passage
-my $ADDCOMMENT='DIF > '; # To mark added comment line
-my $DELMARKOPEN='\DIFdelbegin '; # Token to mark begin of deleted text
-my $DELMARKCLOSE='\DIFdelend '; # Token to mark end of deleted text
-my $DELOPEN='\DIFdel{'; # To mark begin of deleted text passage
-my $DELCLOSE='}'; # To mark end of deleted text passage
-my $DELCMDOPEN='%DIFDELCMD < '; # To mark begin of deleted commands (must begin with %, i.e., be a comment
-my $DELCMDCLOSE="%%%\n"; # To mark end of deleted commands (must end with a new line)
-my $AUXCMD='%DIFAUXCMD' ; # follows auxiliary commands put in by latexdiff to make difference file legal
- # auxiliary commands must be on a line of their own
- # Note that for verbatim environment openings the %DIFAUXCMD cannot be placed in
- # the same line as this would mean they are shown
- # so the special form "%DIFAUXCMD NEXT" is used to indicate that the next line
- # is an auxiliary command
- # Similarly "%DIFAUXCMD LAST" would indicate the auxiliary command is in previous line (not currently used)
-my $DELCOMMENT='DIF < '; # To mark deleted comment line
-my $VERBCOMMENT='DIFVRB '; # to mark lines which are within a verbatim environment
-
-# main local variables:
-my @TEXTCMDLIST=(); # array containing patterns of commands with text arguments
-my @TEXTCMDEXCL=(); # array containing patterns of commands without text arguments (if a pattern
- # matches both TEXTCMDLIST and TEXTCMDEXCL it is excluded)
-my @CONTEXT1CMDLIST=(); # array containing patterns of commands with text arguments (subset of text commands),
- # but which cause confusion if used out of context (e.g. \caption).
- # In deleted passages, the command will be disabled but its argument is marked up
- # Otherwise they behave exactly like TEXTCMD's
-my @CONTEXT1CMDEXCL=(); # exclude list for above, but always empty
-my @CONTEXT2CMDLIST=(); # array containing patterns of commands with text arguments, but which fail or cause confusion
- # if used out of context (e.g. \title). They and their arguments will be disabled in deleted
- # passages
-my @CONTEXT2CMDEXCL=(); # exclude list for above, but always empty
-my @MATHTEXTCMDLIST=(); # treat like textcmd. If a textcmd is in deleted or added block, just wrap the
- # whole content with \DIFadd or \DIFdel irrespective of content. This functionality
- # is useful for pseudo commands \MATHBLOCK.. into which math environments are being
- # transformed
-my @MATHTEXTCMDEXCL=(); #
-
-# Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these
-our @SAFECMDLIST=(); # array containing patterns of safe commands (which do not break when in the argument of DIFadd or DIFDEL)
-our @SAFECMDEXCL=();
-my @MBOXCMDLIST=(); # patterns for commands which are in principle safe but which need to be surrounded by an \mbox
-my @MBOXCMDEXCL=(); # all the patterns in MBOXCMDLIST will be appended to SAFECMDLIST
-
-my @KEEPCMDLIST=( qr/^bibitem$/ ); # patterns for commands which should not be deleted in nominally delete text passages
-my @KEEPCMDEXCL=();
-
-my ($i,$j,$l);
-my ($old,$new);
-my ($line,$key);
-my (@dumlist);
-my ($newpreamble,$oldpreamble);
-my (@newpreamble,@oldpreamble,@diffpreamble,@diffbody);
-my ($latexdiffpreamble);
-my ($oldbody, $newbody, $diffbo);
-my ($oldpost, $newpost);
-my ($diffall);
-# Option names
-my ($type,$subtype,$floattype,$config,$preamblefile,$encoding,$nolabel,$visiblelabel,
- $filterscript,$ignorefilterstderr,
- $showpreamble,$showsafe,$showtext,$showconfig,$showall,
- $replacesafe,$appendsafe,$excludesafe,
- $replacetext,$appendtext,$excludetext,
- $replacecontext1,$appendcontext1,
- $replacecontext2,$appendcontext2,
- $help,$verbose,$driver,$version,$ignorewarnings,
- $enablecitmark,$disablecitmark,$allowspaces,$flatten,$nolinks,$debug,$earlylatexdiffpreamble); ###$disablemathmark,
-my ($mboxsafe);
-# MNEMNONICS for mathmarkup
-my $mathmarkup;
-use constant {
- OFF => 0,
- WHOLE => 1,
- COARSE => 2,
- FINE => 3
-};
-# MNEMNONICS for graphicsmarkup
-my $graphicsmarkup;
-use constant {
- NONE => 0,
- NEWONLY => 1,
- BOTH => 2
-};
-
-my ($mboxcmd);
-
-my (@configlist,@addtoconfiglist,@labels,
- @appendsafelist,@excludesafelist,
- @appendmboxsafelist,@excludemboxsafelist,
- @appendtextlist,@excludetextlist,
- @appendcontext1list,@appendcontext2list,
- @packagelist);
-my ($assign,@config);
-# Hash where keys corresponds to the names of all included packages (including the documentclass as another package
-# the optional arguments to the package are the values of the hash elements
-my ($pkg,%packages);
-
-# Defaults
-$mathmarkup=COARSE;
-$verbose=0;
-# output debug and intermediate files, set to 0 in final distribution
-$debug=0;
-# insert preamble directly after documentclass - experimental feature, set to 0 in final distribution
-# Note that this failed with mini example (or other files, where packages used in latexdiff preamble
-# are called again with incompatible options in preamble of resulting file)
-$earlylatexdiffpreamble=0;
-
-
-# define character properties
-sub IsNonAsciiPunct { return <<'END' # Unicode punctuation but excluding ASCII punctuation
-+utf8::IsPunct
--utf8::IsASCII
-END
-}
-sub IsNonAsciiS { return <<'END' # Unicode symbol but excluding ASCII
-+utf8::IsS
--utf8::IsASCII
-END
-}
-
-
-my %verbhash;
-
-Getopt::Long::Configure('bundling');
-GetOptions('type|t=s' => \$type,
- 'subtype|s=s' => \$subtype,
- 'floattype|f=s' => \$floattype,
- 'config|c=s' => \@configlist,
- 'add-to-config=s' => \@addtoconfiglist,
- 'preamble|p=s' => \$preamblefile,
- 'encoding|e=s' => \$encoding,
- 'label|L=s' => \@labels,
- 'no-label' => \$nolabel,
- 'visible-label' => \$visiblelabel,
- 'exclude-safecmd|A=s' => \@excludesafelist,
- 'replace-safecmd=s' => \$replacesafe,
- 'append-safecmd|a=s' => \@appendsafelist,
- 'exclude-textcmd|X=s' => \@excludetextlist,
- 'replace-textcmd=s' => \$replacetext,
- 'append-textcmd|x=s' => \@appendtextlist,
- 'replace-context1cmd=s' => \$replacecontext1,
- 'append-context1cmd=s' => \@appendcontext1list,
- 'replace-context2cmd=s' => \$replacecontext2,
- 'append-context2cmd=s' => \@appendcontext2list,
- 'exclude-mboxsafecmd=s' => \@excludemboxsafelist,
- 'append-mboxsafecmd=s' => \@appendmboxsafelist,
- 'show-preamble' => \$showpreamble,
- 'show-safecmd' => \$showsafe,
- 'show-textcmd' => \$showtext,
- 'show-config' => \$showconfig,
- 'show-all' => \$showall,
- 'packages=s' => \@packagelist,
- 'allow-spaces' => \$allowspaces,
- 'math-markup=s' => \$mathmarkup,
- 'graphics-markup=s' => \$graphicsmarkup,
- 'enable-citation-markup|enforce-auto-mbox' => \$enablecitmark,
- 'disable-citation-markup|disable-auto-mbox' => \$disablecitmark,
- 'verbose|V' => \$verbose,
- 'ignore-warnings' => \$ignorewarnings,
- 'driver=s'=> \$driver,
- 'flatten' => \$flatten,
- 'filter-script=s' => \$filterscript,
- 'ignore-filter-stderr' => \$ignorefilterstderr,
- 'no-links' => \$nolinks,
- 'version' => \$version,
- 'help|h' => \$help,
- 'debug!' => \$debug ) or die "Use latexdiff -h to get help.\n" ;
-
-if ( $help ) {
- usage() ;
-}
-
-
-if ( $version ) {
- die $versionstring ;
-}
-
-print STDERR $versionstring if $verbose;
-
-if (defined($showall)){
- $showpreamble=$showsafe=$showtext=$showconfig=1;
-}
-# Default types
-$type='UNDERLINE' unless defined($type);
-$subtype='SAFE' unless defined($subtype);
-# set floattype to IDENTICAL for LABEL and ONLYCHANGEDPAGE subtype, unless it has been set explicitly on the command line
-$floattype=($subtype eq 'LABEL' || $subtype eq 'ONLYCHANGEDPAGE') ? 'IDENTICAL' : 'FLOATSAFE' unless defined($floattype);
-if ( $subtype eq 'LABEL' ) {
- print STDERR "Note that LABEL subtype is deprecated. If possible, use ZLABEL instead (requires zref package)";
-}
-
-if (defined($mathmarkup)) {
- $mathmarkup=~tr/a-z/A-Z/;
- if ( $mathmarkup eq 'OFF' ){
- $mathmarkup=OFF;
- } elsif ( $mathmarkup eq 'WHOLE' ){
- $mathmarkup=WHOLE;
- } elsif ( $mathmarkup eq 'COARSE' ){
- $mathmarkup=COARSE;
- } elsif ( $mathmarkup eq 'FINE' ){
- $mathmarkup=FINE;
- } elsif ( $mathmarkup !~ m/^[0123]$/ ) {
- die "latexdiff Illegal value: ($mathmarkup) for option--math-markup. Possible values: OFF,WHOLE,COARSE,FINE,0-3\n";
- }
- # else use numerical value
-}
-
-# Give filterscript a default empty string
-$filterscript="" unless defined($filterscript);
-
-# setting extra preamble commands
-if (defined($preamblefile)) {
- $latexdiffpreamble=join "\n",(extrapream($preamblefile),"");
-} else {
- $latexdiffpreamble=join "\n",(extrapream($type,$subtype,$floattype),"");
-}
-
-if ( defined($driver) ) {
- # for changebar only
- $latexdiffpreamble=~s/\[dvips\]/[$driver]/sg;
-}
-# setting up @SAFECMDLIST and @SAFECMDEXCL
-if (defined($replacesafe)) {
- init_regex_arr_ext(\@SAFECMDLIST,$replacesafe);
-} else {
- init_regex_arr_data(\@SAFECMDLIST, "SAFE COMMANDS");
-}
-foreach $appendsafe ( @appendsafelist ) {
- init_regex_arr_ext(\@SAFECMDLIST, $appendsafe);
-}
-foreach $excludesafe ( @excludesafelist ) {
- init_regex_arr_ext(\@SAFECMDEXCL, $excludesafe);
-}
-# setting up @MBOXCMDLIST and @MBOXCMDEXCL
-foreach $mboxsafe ( @appendmboxsafelist ) {
- init_regex_arr_ext(\@MBOXCMDLIST, $mboxsafe);
-}
-foreach $mboxsafe ( @excludemboxsafelist ) {
- init_regex_arr_ext(\@MBOXCMDEXCL, $mboxsafe);
-}
-
-
-
-# setting up @TEXTCMDLIST and @TEXTCMDEXCL
-if (defined($replacetext)) {
- init_regex_arr_ext(\@TEXTCMDLIST,$replacetext);
-} else {
- init_regex_arr_data(\@TEXTCMDLIST, "TEXT COMMANDS");
-}
-foreach $appendtext ( @appendtextlist ) {
- init_regex_arr_ext(\@TEXTCMDLIST, $appendtext);
-}
-foreach $excludetext ( @excludetextlist ) {
- init_regex_arr_ext(\@TEXTCMDEXCL, $excludetext);
-}
-
-
-# setting up @CONTEXT1CMDLIST ( @CONTEXT1CMDEXCL exist but is always empty )
-if (defined($replacecontext1)) {
- init_regex_arr_ext(\@CONTEXT1CMDLIST,$replacecontext1);
-} else {
- init_regex_arr_data(\@CONTEXT1CMDLIST, "CONTEXT1 COMMANDS");
-}
-foreach $appendcontext1 ( @appendcontext1list ) {
- init_regex_arr_ext(\@CONTEXT1CMDLIST, $appendcontext1);
-}
-
-
-# setting up @CONTEXT2CMDLIST ( @CONTEXT2CMDEXCL exist but is always empty )
-if (defined($replacecontext2)) {
- init_regex_arr_ext(\@CONTEXT2CMDLIST,$replacecontext2);
-} else {
- init_regex_arr_data(\@CONTEXT2CMDLIST, "CONTEXT2 COMMANDS");
-}
-foreach $appendcontext2 ( @appendcontext2list ) {
- init_regex_arr_ext(\@CONTEXT2CMDLIST, $appendcontext2);
-}
-
-# setting configuration variables
-@config=();
-foreach $config ( @configlist ) {
- if (-f $config || lc $config eq '/dev/null' ) {
- open(FILE,$config) or die ("Couldn't open configuration file $config: $!");
- while (<FILE>) {
- chomp;
- next if /^\s*#/ || /^\s*%/ || /^\s*$/ ;
- push (@config,$_);
- }
- close(FILE);
- }
- else {
-# foreach ( split(",",$config) ) {
-# push @config,$_;
-# }
- push @config,split(",",$config)
- }
-}
-foreach $assign ( @config ) {
- $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)";
- exists $CONFIG{$1} or die "Unknown configuration variable $1.";
- $CONFIG{$1}=$2;
-}
-
-my @addtoconfig=();
-foreach $config ( @addtoconfiglist ) {
- if (-f $config || lc $config eq '/dev/null' ) {
- open(FILE,$config) or die ("Couldn't open addd-to-config file $config: $!");
- while (<FILE>) {
- chomp;
- next if /^\s*#/ || /^\s*%/ || /^\s*$/ ;
- push (@addtoconfig,$_);
- }
- close(FILE);
- }
- else {
-# foreach ( split(",",$config) ) {
-# push @addtoconfig,$_;
-# }
- push @addtoconfig,split(",",$config)
- }
-}
-
-# initialise default lists from DATA
-# for those configuration variables, which have not been set explicitly, initiate from list in document
-foreach $key ( keys(%CONFIG) ) {
- if (!defined $CONFIG{$key}) {
- @dumlist=();
- init_regex_arr_data(\@dumlist,"$key CONFIG");
- $CONFIG{$key}=join(";",@dumlist)
- }
-}
-
-
-foreach $assign ( @addtoconfig ) {
- ###print STDERR "assign:|$assign|\n";
- $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)";
- exists $CONFIG{$1} or die "Unknown configuration variable $1.";
- $CONFIG{$1}.=";$2";
-}
-
-# Map from hash to variables (we do this to have more concise code later, change from comma-separated list)
-foreach ( keys(%CONFIG) ) {
- if ( $_ eq "MINWORDSBLOCK" ) { $MINWORDSBLOCK = $CONFIG{$_}; }
- elsif ( $_ eq "FLOATENV" ) { $FLOATENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "ITEMCMD" ) { $ITEMCMD = $CONFIG{$_} ; }
- elsif ( $_ eq "LISTENV" ) { $LISTENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "PICTUREENV" ) { $PICTUREENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "MATHENV" ) { $MATHENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "MATHREPL" ) { $MATHREPL = $CONFIG{$_} ; }
- elsif ( $_ eq "MATHARRENV" ) { $MATHARRENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; }
- elsif ( $_ eq "ARRENV" ) { $ARRENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "VERBATIMENV" ) { $VERBATIMENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "VERBATIMLINEENV" ) { $VERBATIMLINEENV = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "CUSTOMDIFCMD" ) { $CUSTOMDIFCMD = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "COUNTERCMD" ) { $COUNTERCMD = liststringtoregex($CONFIG{$_}) ; }
- elsif ( $_ eq "SCALEDELGRAPHICS" ) { $SCALEDELGRAPHICS = $CONFIG{$_} ; }
- else { die "Unknown configuration variable $_.";}
-}
-
-if ( $mathmarkup == COARSE || $mathmarkup == WHOLE ) {
- push(@MATHTEXTCMDLIST,qr/^MATHBLOCK(?:$MATHENV|$MATHARRENV|SQUAREBRACKET)$/);
-}
-
-
-
-
-
-foreach $pkg ( @packagelist ) {
- map { $packages{$_}="" } split(/,/,$pkg) ;
-}
-
-
-if ($showconfig || $showtext || $showsafe || $showpreamble) {
-
- show_configuration();
- exit 0;
-}
-
-
-if ( @ARGV != 2 ) {
- print STDERR "2 and only 2 non-option arguments required. Write latexdiff -h to get help\n";
- exit(2);
-}
-
-# Are extra spaces between command arguments permissible?
-my $extraspace;
-if ($allowspaces) {
- $extraspace='\s*';
-} else {
- $extraspace='';
-}
-
-# append context lists to text lists (as text property is implied)
-push @TEXTCMDLIST, @CONTEXT1CMDLIST;
-push @TEXTCMDLIST, @CONTEXT2CMDLIST;
-
-push @TEXTCMDLIST, @MATHTEXTCMDLIST if $mathmarkup==COARSE;
-
-# internal additions to SAFECMDLIST
-push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/);
-
-
-# Patterns. These are used by some of the subroutines, too
-# I can only define them down here because value of extraspace depends on an option
-
- my $pat0 = '(?:[^{}])*';
- my $pat_n = $pat0;
-# if you get "undefined control sequence MATHBLOCKmath" error, increase the maximum value in this loop
- for (my $i_pat = 0; $i_pat < 20; ++$i_pat){
- $pat_n = '(?:[^{}]|\{'.$pat_n.'\}|\\\\\{|\\\\\})*';
- # Actually within the text body, quoted braces are replaced in pre-processing. The only place where
- # the last part of the pattern matters is when processing the arguments of context2cmds in the preamble
- # and these contain a \{ or \} combination, probably rare.
- # It should thus be fine to use the simpler version below.
- ### $pat_n = '(?:[^{}]|\{'.$pat_n.'\})*';
- }
-
- my $brat0 = '(?:[^\[\]]|\\\[|\\\])*';
- my $brat_n = $brat0;
- for (my $i_pat = 0; $i_pat < 4; ++$i_pat){
- $brat_n = '(?:[^\[\]]|\['.$brat_n.'\]|\\\[|\\\])*';
- ### $brat_n = '(?:[^\[\]]|\['.$brat_n.'\])*'; # Version not taking into account escaped \[ and \]
- }
- my $abrat0 = '(?:[^<>])*';
-
- my $quotemarks = '(?:\'\')|(?:\`\`)';
- my $punct='[0.,\/\'\`:;\"\?\(\)\[\]!~\p{IsNonAsciiPunct}\p{IsNonAsciiS}]';
- my $number='-?\d*\.\d*';
- my $mathpunct='[+=<>\-\|]';
- my $and = '&';
- my $coords= '[\-.,\s\d]*';
-# quoted underscore - this needs special treatment as perl treats _ as a letter (\w) but latex does not
-# such that a\_b is interpreted as a{\_}b by latex but a{\_b} by perl
- my $quotedunderscore='\\\\_';
-# word: sequence of letters or accents followed by letter
- my $word_ja='\p{Han}+|\p{InHiragana}+|\p{InKatakana}+';
- my $word='(?:' . $word_ja . '|(?:(?:[-\w\d*]|\\\\[\"\'\`~^][A-Za-z\*])(?!(?:' . $word_ja . ')))+)';
-
- # for selected commands, the number of arguments is known, and we can therefore allow spaces between command and its argument
- # Note that it is still expected that the arguments are blocks marked by parentheses rather than single characters, and that intervening comments will inhibit the association
- my $predefinedcmdoptseq01='\\\\(?:url|BibitemShut)\s*\s*(?:\{'. $pat_n . '\}\s*){1}'; # Commands with one non-optional argument
- my $predefinedcmdoptseq12='\\\\(?:href|bibfield|bibinfo)\s*(?:\['.$brat_n.'\])?\s*(?:\{'. $pat_n . '\}\s*){2}'; # Commands with one optional and two non-optional arguments
-# my $predefinedcmdoptseq11='\\\\(?:bibitem)\s*(?:\['.$brat_n.'\])?\s*(?:\{'. $pat_n . '\}\s*){1}'; # Commands with one optional and one non-optional arguments
-# \bibitem in revtex styles appears to be always followed by \BibItemOpen. We bind \BibItemOpen to the bibitem (if present) in order to prevent the comparison algorithm to interpret the \BibItemOpen as an identical part of the sequence; this interpretation can lead to added and removed entries to the reference list to become mixed.
- my $predefinedbibitem='\\\\(?:bibitem)\s*(?:\['.$brat_n.'\])?\s*(?:\{'. $pat_n . '\})(?:%?\s*\\\\BibitemOpen)?'; # Commands with one optional and one non-optional arguments
-
- my $predefinedcmdoptseq='(?:'.$predefinedcmdoptseq12.'|'.$predefinedcmdoptseq01.'|'.$predefinedbibitem.')';
-
- my $cmdleftright='\\\\(?:left|right|[Bb]igg?[lrm]?|middle)\s*(?:[<>()\[\]|\.]|\\\\(?:[|{}]|\w+))';
- my $cmdoptseq='\\\\[\w\d@\*]+'.$extraspace.'(?:(?:<'.$abrat0.'>|\['.$brat_n.'\]|\{'. $pat_n . '\}|\(' . $coords .'\))'.$extraspace.')*';
- my $defseq='\\\\def\\\\[\w\d@\*]+(?:#\d+|\[#\d+\])+(?:\{'. $pat_n . '\})?';
- my $backslashnl='\\\\\n';
- my $oneletcmd='\\\\.\*?(?:\['.$brat_n.'\]|\{'. $pat_n . '\})*';
- my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]';
-## the current maths command cannot cope with newline within the math expression
- my $comment='%[^\n]*\n';
- my $pat=qr/(?:\A\s*)?(?:${and}|${quotemarks}|${number}|${word}|$quotedunderscore|${defseq}|$cmdleftright|${predefinedcmdoptseq}|${cmdoptseq}|${math}|${backslashnl}|${oneletcmd}|${comment}|${punct}|${mathpunct}|\{|\})\s*/ ;
-
-
-
-
-# now we are done setting up and can start working
-my ($oldfile, $newfile) = @ARGV;
-# check for existence of input files
-if ( ! -e $oldfile ) {
- die "Input file $oldfile does not exist";
-}
-if ( ! -e $newfile ) {
- die "Input file $newfile does not exist";
-}
-
-
-# set the labels to be included into the file
-# first find out which file name is longer for correct alignment
-my ($diff,$oldlabel_n_spaces,$newlabel_n_spaces);
-$oldlabel_n_spaces = 0;
-$newlabel_n_spaces = 0;
-$diff = length($newfile) - length($oldfile);
-if ($diff > 0) {
- $oldlabel_n_spaces = $diff;
-}
-if ($diff < 0) {
- $newlabel_n_spaces = abs($diff);
-}
-
-my ($oldtime,$newtime,$oldlabel,$newlabel);
-if (defined($labels[0])) {
- $oldlabel=$labels[0] ;
-} else {
- $oldtime=localtime((stat($oldfile))[9]);
- $oldlabel="$oldfile " . " "x($oldlabel_n_spaces) . $oldtime;
-}
-if (defined($labels[1])) {
- $newlabel=$labels[1] ;
-} else {
- $newtime=localtime((stat($newfile))[9]);
- $newlabel="$newfile " . " "x($newlabel_n_spaces) . $newtime;
-}
-
-$encoding=guess_encoding($newfile) unless defined($encoding);
-
-$encoding = "utf8" if $encoding =~ m/^utf8/i ;
-if (lc($encoding) eq "utf8" ) {
- binmode(STDOUT, ":utf8");
- binmode(STDERR, ":utf8");
-}
-
-# filter($text)
-# Runs $text through the script provided in $filterscript argument, if set
-# If not set, just returns $text unchanged.
-# If flatten was set, defer filtering to flatten. flatten will run the filter
-# on all incoming text prior to its own processing.
-# If flatten was not set, filter each of old and new once (see just below this def)
-sub filter {
- my ($text)=@_;
- my ($textout,$pid);
- if ($filterscript ne "") {
- print STDERR "Passing " . length($text) . " chars to filter script " . $filterscript . "\n" if $verbose;
-
- if ($ignorefilterstderr) {
- # If we need to capture and bury STDERR, use the Open3 version, and close CHLD_ERR below.
- use IPC::Open3;
- # We consume STDERR from the process, and hide it
- $pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, $filterscript) or die "open3() failed $!";
- }
- else {
- # Capture STDOUT and use as our new $text. Allow STDERR to go to console.
- use IPC::Open2;
- $pid = open2(\*CHLD_OUT, \*CHLD_IN, $filterscript) or die "open2() failed $!";
- }
- # Send in $text
- print CHLD_IN $text."\n"; # Adding a newline just to make sure there is one.
- close CHLD_IN;
- # Wait for output and gather it up
- while (<CHLD_OUT>) {
- $textout = $textout.$_;
- }
- if ($ignorefilterstderr) {
- close CHLD_ERR; # Enable only if Open3 used above
- }
- # On the off chance a very long running and/or frequently called script is used.
- waitpid( $pid, 0 );
- $text = $textout;
- print STDERR "Received " . length($text) . " chars after filtering\n" if $verbose;
- print STDERR $text if $verbose;
- }
- return $text;
-}
-
-$old=read_file_with_encoding($oldfile,$encoding);
-$new=read_file_with_encoding($newfile,$encoding);
-
-if (not defined($flatten)) {
- $old=filter($old);
- $new=filter($new);
-}
-
-
-
-
-# reset time
-exetime(1);
-($oldpreamble,$oldbody,$oldpost)=splitdoc($old,'\\\\begin\{document\}','\\\\end\{document\}');
-
-($newpreamble,$newbody,$newpost)=splitdoc($new,'\\\\begin\{document\}','\\\\end\{document\}');
-
-
-if ($flatten) {
- $oldbody=flatten($oldbody,$oldpreamble,File::Spec->rel2abs($oldfile),$encoding);
- $newbody=flatten($newbody,$newpreamble,File::Spec->rel2abs($newfile),$encoding);
- # flatten preamble
- $oldpreamble=flatten($oldpreamble,$oldpreamble,File::Spec->rel2abs($oldfile),$encoding);
- $newpreamble=flatten($newpreamble,$newpreamble,File::Spec->rel2abs($newfile),$encoding);
-
-}
-
-
-
-
-my @auxlines;
-
-# boolean variab
-my ($ulem)=0;
-
-if ( length $oldpreamble && length $newpreamble ) {
- # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands)
- # and marking up content with latexdiff markup
- @auxlines=preprocess_preamble($oldpreamble,$newpreamble);
-
- @oldpreamble = split /\n/, $oldpreamble;
- @newpreamble = split /\n/, $newpreamble;
-
- # If a command is defined in the preamble of the new file, and only uses safe commands, then it can be considered to be safe) (contribution S. Gouezel)
- # Base this assessment on the new preamble
- add_safe_commands($newpreamble);
-
- # get a list of packages from preamble if not predefined
- %packages=list_packages($newpreamble) unless %packages;
- if ( %packages && $debug ) { my $key ; foreach $key (keys %packages) { print STDERR "DEBUG \\usepackage[",$packages{$key},"]{",$key,"}\n" ;} }
-}
-
-# have to return to all processing to properly add preamble additions based on packages found
-if (defined($graphicsmarkup)) {
- $graphicsmarkup=~tr/a-z/A-Z/;
- if ( $graphicsmarkup eq 'OFF' or $graphicsmarkup eq 'NONE' ) {
- $graphicsmarkup=NONE;
- } elsif ( $graphicsmarkup eq 'NEWONLY' or $graphicsmarkup eq 'NEW-ONLY' ) {
- $graphicsmarkup=NEWONLY;
- } elsif ( $graphicsmarkup eq 'BOTH' ) {
- $graphicsmarkup=BOTH;
- } elsif ( $graphicsmarkup !~ m/^[012]$/ ) {
- die "latexdiff Illegal value: ($graphicsmarkup) for option --highlight-graphics. Possible values: OFF,WHOLE,COARSE,FINE,0-2\n";
- }
- # else use numerical value
-} else {
- # Default: no explicit setting in menu
- if ( defined $packages{"graphicx"} or defined $packages{"graphics"} ) {
- $graphicsmarkup=NEWONLY;
- } else {
- $graphicsmarkup=NONE;
- }
-}
-
-if (defined $packages{"hyperref"} ) {
- # deleted lines should not generate or appear in link names:
- print STDERR "hyperref package detected.\n" if $verbose ;
- $latexdiffpreamble =~ s/\{\\DIFadd\}/{\\DIFaddtex}/g;
- $latexdiffpreamble =~ s/\{\\DIFdel\}/{\\DIFdeltex}/g;
- $latexdiffpreamble .= join "\n",(extrapream("HYPERREF"),"");
- if($nolinks){
- $latexdiffpreamble .= "\n\\hypersetup{bookmarks=false}";
- }
- ### $latexdiffpreamble .= '%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF FOR HYPERREF PACKAGE' . "\n";
- ### $latexdiffpreamble .= '\providecommand{\DIFadd}[1]{\texorpdfstring{\DIFaddtex{#1}}{#1}}' . "\n";
- ### $latexdiffpreamble .= '\providecommand{\DIFdel}[1]{\texorpdfstring{\DIFdeltex{#1}}{}}' . "\n";
- ### $latexdiffpreamble .= '%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF FOR HYPERREF PACKAGE' . "\n";
-}
-
-# add commands for figure highlighting to preamble
-if ($graphicsmarkup != NONE ) {
- my @matches;
- # Check if \DIFaddbeginFL definition calls \DIFaddbegin - if so we will issue an error message that graphics highlighting is
- # is not compatible with this.
- # (A more elegant solution would be to suppress the redefinitions of the \DIFaddbeginFL etc commands, but for this narrow use case
- # I currently don't see this as an efficient use of time)
- ### The foreach loop does not make sense here. I don't know why I put this in - (F Tilmann)
- ###foreach my $cmd ( "DIFaddbegin","DIFaddend","DIFdelbegin","DIFdelend" ) {
- @matches=( $latexdiffpreamble =~ m/command\{\\DIFaddbeginFL}\{($pat_n)}/sg ) ;
- # we look at the last one of the list to take into account possible redefinition but almost always matches should have exactly one element
- if ( $matches[$#matches] =~ m/\\DIFaddbegin/ ) {
- die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style.";
- exit 10;
- }
- ###}
- $latexdiffpreamble .= join "\n",("\\newcommand{\\DIFscaledelfig}{$SCALEDELGRAPHICS}",extrapream("HIGHLIGHTGRAPHICS"),"");
-
- # only change required for highlighting both is to declare \includegraphics safe, as preamble already contains commands for deleted environment
- if ( $graphicsmarkup == BOTH ) {
- init_regex_arr_list(\@SAFECMDLIST,'includegraphics');
- }
-}
-
-$ulem = ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{ulem\}/ || defined $packages{"ulem"});
-
-
-# If listings is being used or can be found in the latexdiff search path, add to the preamble auxiliary code to enable line-by-line markup
-if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) {
- my @listingpreamble=extrapream("LISTINGS");
- my @listingDIFcode=();
- my $replaced;
- # note that in case user supplies preamblefile the type might not reflect well the
- @listingDIFcode=extrapream("-nofail","DIFCODE_" . $type) unless defined($preamblefile);
- if (!(@listingDIFcode)) {
- # if listingDIFcode is empty try to guess a suitable one from the preamble
- if ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ and $ulem ) {
- @listingDIFcode=extrapream("DIFCODE_UNDERLINE");
- } elsif ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) {
- # only colour used
- @listingDIFcode=extrapream("DIFCODE_CFONT");
- } else {
- # fall-back solution
- @listingDIFcode=extrapream("DIFCODE_BOLD");
- }
- }
- # now splice it in
- $replaced=0;
- ###print STDERR "DEBUG: listingDIFcode: ",join("\n",@listingDIFcode),"|||\n" if $debug;
-
- @listingpreamble=grep {
- # only replace if this has not been done already (use short-circuit property of and)
- if (!$replaced and $_ =~ s/^.*%DIFCODE TEMPLATE.*$/join("\n",@listingDIFcode)/e ) {
- ###print STDERR "DEBUG: Replaced text $_\n" if $debug;
- $replaced=1;
- 1;
- } else {
- # return false for those lines matching %DIFCODE TEMPLATE (so that they are not included in output)
- not m/%DIFCODE TEMPLATE/;
- }
- } @listingpreamble;
- ### print STDERR "DEBUG: listingpreamble @listingpreamble\n";
- $latexdiffpreamble .= join "\n",(@listingpreamble,"");
-} else {
- print STDERR "WARNING: listings package not detected. Disabling mark-up in verbatim environments \n" ;
- # if listings does not exist disable line-by-line markup and treat all verbatim environments as opaque
- $VERBATIMENV = liststringtoregex($CONFIG{VERBATIMENV}.";".$CONFIG{VERBATIMLINEENV});
- $VERBATIMLINEENV = "";
-}
-
-# adding begin and end marker lines to preamble
-$latexdiffpreamble = "%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF\n" . $ latexdiffpreamble . "%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF\n";
-
-# and return to preamble specific processing
-if ( length $oldpreamble && length $newpreamble ) {
- print STDERR "Differencing preamble.\n" if $verbose;
-
- # insert dummy first line such that line count begins with line 1 (rather than perl's line 0) - just so that line numbers inserted by linediff are correct
- unshift @newpreamble,'';
- unshift @oldpreamble,'';
- @diffpreamble = linediff(\@oldpreamble, \@newpreamble);
- # remove dummy line again
- shift @diffpreamble;
- # add filenames, modification time and latexdiff mark
- defined($nolabel) or splice @diffpreamble,1,0,
- "%DIF LATEXDIFF DIFFERENCE FILE",
- ,"%DIF DEL $oldlabel",
- "%DIF ADD $newlabel";
- if ( @auxlines ) {
- push @diffpreamble,"%DIF DELETED TITLE COMMANDS FOR MARKUP";
- push @diffpreamble,join("\n",@auxlines);
- }
- if ( $earlylatexdiffpreamble) {
- # insert latexdiff command directly after documentclass at beginning of preamble
- # note that grep is only run for its side effect
- ( grep { s/^([^%]*\\documentclass.*)$/$1$latexdiffpreamble/ } @diffpreamble )==1 or die "Could not find documentclass statement in preamble";
- } else {
- # insert latexdiff commands at the end of preamble (default behaviour)
- push @diffpreamble,$latexdiffpreamble;
- }
- push @diffpreamble,'\begin{document}';
- if (defined $packages{"hyperref"} && $nolinks) {
- push @diffpreamble, '\begin{NoHyper}';
- }
-}
-elsif ( !length $oldpreamble && !length $newpreamble ) {
- @diffpreamble=();
-} else {
- print STDERR "Either both texts must have preamble or neither text must have the preamble.\n";
- exit(2);
-}
-
-# Special: treat all cite commands as safe except in UNDERLINE and FONTSTRIKE mode
-# (there is a conflict between citation and ulem package, see
-# package documentation)
-# Use post-processing
-# and $packages{"apacite"}!~/natbibpapa/
-
-
-if (defined $packages{"units"} && $ulem ) {
- # protect inlined maths environments by surrounding with an \mbox
- # this is done to get around an incompatibility between the ulem and units package
- # where spaces in the argument to underlined or crossed-out \unit commands cause an error message
- print STDERR "units package detected at the same time as style using ulem.\n" if $verbose ;
- $MBOXINLINEMATH=1;
-}
-
-if (defined $packages{"siunitx"} ) {
- # protect SI command by surrounding them with an \mbox
- # this is done to get around an incompatibility between the ulem and siunitx package
- print STDERR "siunitx package detected.\n" if $verbose ;
- my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange';
- init_regex_arr_list(\@SAFECMDLIST,'num,si');
- if ( $enablecitmark || ( $ulem && ! $disablecitmark )) {
- init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds);
- } else {
- init_regex_arr_list(\@SAFECMDLIST,$mboxcmds);
- }
-}
-
-if (defined $packages{"cleveref"} ) {
- # protect selected command by surrounding them with an \mbox
- # this is done to get around an incompatibility between ulem and cleveref package
- print STDERR "cleveref package detected.\n" if $verbose ;
- my $mboxcmds='[Cc]ref(?:range)?\*?,labelcref,(?:lc)?name[cC]refs?' ;
- if ( $enablecitmark || ( $ulem && ! $disablecitmark )) {
- init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds);
- } else {
- init_regex_arr_list(\@SAFECMDLIST,$mboxcmds);
- }
-}
-
-if (defined $packages{"glossaries"} ) {
- # protect selected command by surrounding them with an \mbox
- # this is done to get around an incompatibility between ulem and glossaries package
- print STDERR "glossaries package detected.\n" if $verbose ;
- my $mboxcmds='[gG][lL][sS](?:|pl|disp|link|first|firstplural|desc|user[iv][iv]?[iv]?),[aA][cC][rR](?:long|longpl|full|fullpl),[aA][cC][lfp]?[lfp]?';
- init_regex_arr_list(\@SAFECMDLIST,'[gG][lL][sS](?:(?:entry)?(?:text|plural|name|symbol)|displaynumberlist|entryfirst|entryfirstplural|entrydesc|entrydescplural|entrysymbolplural|entryuser[iv][iv]?[iv]?|entrynumberlist|entrydisplaynumberlist|entrylong|entrylongpl|entryshort|entryshortpl|entryfull|entryfullpl),[gG]lossentry(?:name|desc|symbol),[aA][cC][rR](?:short|shortpl),[aA]csp?');
- if ( $enablecitmark || ( $ulem && ! $disablecitmark )) {
- init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds);
- } else {
- init_regex_arr_list(\@SAFECMDLIST,$mboxcmds);
- }
-}
-
-if (defined $packages{"chemformula"} or defined $packages{"chemmacros"} ) {
- print STDERR "chemformula package detected.\n" if $verbose ;
- init_regex_arr_list(\@SAFECMDLIST,'ch');
- push(@UNSAFEMATHCMD,'ch');
- # The next command would be needed to allow highlighting the interior of \ch commands in math environments
- # but the redefinitions in chemformula are too deep to make this viable
- # push(@MATHTEXTCMDLIST,'ch');
-}
-
-if (defined $packages{"mhchem"} ) {
- print STDERR "mhchem package detected.\n" if $verbose ;
- init_regex_arr_list(\@SAFECMDLIST,'ce');
- push(@UNSAFEMATHCMD,'ce','cee');
- # The next command would be needed to allow highlighting the interior of \cee commands in math environments
- # but the redefinitions in chemformula are too deep to make this viable
- # push(@MATHTEXTCMDLIST,'cee');
-}
-
-
-my ( $citpat);
-
-if ( defined $packages{"apacite"} ) {
- print STDERR "apacite package detected.\n" if $verbose ;
- $citpat='(?:mask)?(?:full|short|no)?cite(?:A|author|year|meta)?(?:NP)?';
-} elsif (defined $packages{"biblatex"}) {
- print STDERR "biblatex package detected.\n" if $verbose ;
- $citpat='(?:[cC]ites?|(?:[pP]aren|foot|[Tt]ext|[sS]mart|super)cites?\*?|footnotecitetex)';
-} else {
- # citation command pattern for all other citation schemes
- $citpat='(?:cite\w*|nocite)';
-};
-
-if ( ! $ulem ) {
- # modes not using ulem: citation is safe
- push (@SAFECMDLIST, $citpat);
-} else {
- ### Experimental: disable text and emph commands
- push(@SAFECMDEXCL, qr/^emph$/, qr/^text..$/);
- # replace \cite{..} by \mbox{\cite{..}} in added or deleted blocks in post-processing
- push(@MBOXCMDLIST,$citpat) unless $disablecitmark;
- if ( uc($subtype) eq "COLOR" or uc($subtype) eq "DVIPSCOL" ) {
- # remove \cite command again from list of safe commands
- pop @MBOXCMDLIST;
- # deleted cite commands
- }
-}
-push(@MBOXCMDLIST,$citpat) if $enablecitmark ;
-
-
-if (defined $packages{"amsmath"} or defined $packages{"amsart"} or defined $packages{"amsbook"} ) {
- print STDERR "amsmath package detected.\n" if $verbose ;
- $MATHARRREPL='align*';
-}
-
-# add commands in MBOXCMDLIST to SAFECMDLIST
-foreach $mboxcmd ( @MBOXCMDLIST ) {
- init_regex_arr_list(\@SAFECMDLIST, $mboxcmd);
-}
-
-# check if \label is in SAFECMDLIST, and if yes replace "label" in $LABELCMD by something that never matches (we hope!)
-if ( iscmd("label",\@SAFECMDLIST,\@SAFECMDEXCL) ) {
- $LABELCMD=~ s/label/NEVERMATCHLABEL/;
-}
-
-
-
-print STDERR "Preprocessing body. " if $verbose;
-preprocess($oldbody,$newbody);
-
-
-# run difference algorithm
-@diffbody=bodydiff($oldbody, $newbody);
-$diffbo=join("",@diffbody);
-writedebugfile($diffbo,"bodydiff");
-
-print STDERR "(",exetime()," s)\n","Postprocessing body. \n" if $verbose;
-postprocess($diffbo);
-$diffall =join("\n",@diffpreamble) ;
-# add visible labels
-if (defined($visiblelabel)) {
- # Give information right after \begin{document} (or at the beginning of the text for files without preamble
- ### if \date command is used, add information to \date argument, otherwise give right after \begin{document}
- ### $diffall=~s/(\\date$extraspace(?:\[$brat0\])?$extraspace)\{($pat_n)\}/$1\{$2 \\ LATEXDIFF comparison \\ Old: $oldlabel \\ New: $newlabel \}/ or
- $diffbo = "\\begin{verbatim}LATEXDIFF comparison\nOld: $oldlabel\nNew: $newlabel\\end{verbatim}\n$diffbo" ;
-}
-
-$diffall .= "$diffbo" ;
-if (defined $packages{"hyperref"} && $nolinks) {
- $diffall .= "\\end{NoHyper}\n";
-}
-$diffall .= "\\end{document}$newpost" if length $newpreamble ;
-if ( lc($encoding) ne "utf8" && lc($encoding) ne "ascii" ) {
- print STDERR "Encoding output file to $encoding\n" if $verbose;
- $diffall=Encode::encode($encoding,$diffall);
- binmode STDOUT;
-}
-print $diffall;
-
-
-print STDERR "(",exetime()," s)\n","Done.\n" if $verbose;
-
-
-# liststringtoregex(liststring)
-# expands string with semi-colon separated list into a regular expression corresponding
-# matching any of the elements
-sub liststringtoregex {
- my ($liststring)=@_;
- my @elements=grep /\S/,split(";",$liststring);
- if ( @elements) {
- return('(?:(?:' . join(')|(?:',@elements) .'))');
- } else {
- return "";
- }
-}
-
-# show_configuration
-# note that this is not encapsulated but uses variables from the main program
-# It is provided for convenience because in the future it is planned to allow output
-# to be modified based on what packages are read etc - this works only if the input files are actually read
-# whether or not additional files are provided
-sub show_configuration {
- if ($showpreamble) {
- print "\nPreamble commands:\n";
- print $latexdiffpreamble ;
- }
-
- if ($showsafe) {
- print "\nsafecmd: Commands safe within scope of $ADDOPEN $ADDCLOSE and $DELOPEN $DELCLOSE (unless excluded):\n";
- print_regex_arr(@SAFECMDLIST);
- print "\nsafecmd-exlude: Commands not safe within scope of $ADDOPEN $ADDCLOSE and $DELOPEN $DELCLOSE :\n";
- print_regex_arr(@SAFECMDEXCL);
- print "\nmboxsafecmd: Commands safe only if they are surrounded by \\mbox command:\n";
- print_regex_arr(@MBOXCMDLIST);
- print "\nnmboxsafecmd: Commands not safe:\n";
- print_regex_arr(@MBOXCMDEXCL);
- }
-
- if ($showtext) {
- print "\nCommands with last argument textual (unless excluded) and safe in every context:\n";
- print_regex_arr(@TEXTCMDLIST);
- print "\nContext1 commands (last argument textual, command will be disabled in deleted passages, last argument will be shown as plain text):\n";
- print_regex_arr(@CONTEXT1CMDLIST);
- print "\nContext2 commands (last argument textual, command and its argument will be disabled in deleted passages):\n";
- print_regex_arr(@CONTEXT2CMDLIST);
- print "\nExclude list of Commands with last argument not textual (overrides patterns above):\n";
- print_regex_arr(@TEXTCMDEXCL);
- }
-
-
- if ($showconfig) {
- print "Configuration variables:\n";
- print "ARRENV=$ARRENV\n";
- print "COUNTERCMD=$COUNTERCMD\n";
- print "FLOATENV=$FLOATENV\n";
- print "ITEMCMD=$ITEMCMD\n";
- print "LISTENV=$LISTENV\n";
- print "MATHARRENV=$MATHARRENV\n";
- print "MATHARRREPL=$MATHARRREPL\n";
- print "MATHENV=$MATHENV\n";
- print "MATHREPL=$MATHREPL\n";
- print "MINWORDSBLOCK=$MINWORDSBLOCK\n";
- print "PICTUREENV=$PICTUREENV\n";
- print "SCALEDELGRAPHICS=$SCALEDELGRAPHICS\n";
- print "VERBATIMENV=$VERBATIMENV\n";
- print "VERBATIMLINEENV=$VERBATIMLINEENV\n";
- print "CUSTOMDIFCMD=$CUSTOMDIFCMD\n";
- }
-}
-
-
-
-## guess_encoding(filename)
-## reads the first 20 lines of filename and looks for call of inputenc package
-## if found, return the option of this package (encoding), otherwise return utf8
-sub guess_encoding {
- my ($filename)=@_;
- my ($i,$enc);
- open (FH, $filename) or die("Couldn't open $filename: $!");
- $i=0;
- while (<FH>) {
- next if /^\s*%/; # skip comment lines
- if (m/\\usepackage\[(\w*?)\]\{inputenc\}/) {
- close(FH);
- return($1);
- }
- last if (++$i > 20 ); # scan at most 20 non-comment lines
- }
- close(FH);
- ### return("ascii");
- return("utf8");
-}
-
-
-sub read_file_with_encoding {
- my ($output);
- my ($filename, $encoding) = @_;
-
- if (lc($encoding) eq "utf8" ) {
- open (FILE, "<:utf8",$filename) or die("Couldn't open $filename: $!");
- local $/ ; # locally set record operator to undefined, ie. enable whole-file mode
- $output=<FILE>;
- } elsif ( lc($encoding) eq "ascii") {
- open (FILE, $filename) or die("Couldn't open $filename: $!");
- local $/ ; # locally set record operator to undefined, ie. enable whole-file mode
- $output=<FILE>;
- } else {
- require Encode;
- open (FILE, "<",$filename) or die("Couldn't open $filename: $!");
- local $/ ; # locally set record operator to undefined, ie. enable whole-file mode
- $output=<FILE>;
- print STDERR "Converting $filename from $encoding to utf8\n" if $verbose;
- $output=Encode::decode($encoding,$output);
- }
- close FILE;
- if ($^O eq "linux" ) {
- $output =~ s/\r\n/\n/g ;
- }
- return $output;
-}
-
-## %packages=list_packages(@preamble)
-## scans the arguments for \documentclass,\RequirePackage and \usepackage statements and constructs a hash
-## whose keys are the included packages, and whose values are the associated optional arguments
-#sub list_packages {
-# my (@preamble)=@_;
-# my %packages=();
-# foreach $line ( @preamble ) {
-# # get rid of comments
-# $line=~s/(?<!\\)%.*$// ;
-# if ( $line =~ m/\\(?:documentclass|usepackage|RequirePackage)(?:\[(.+?)\])?\{(.*?)\}/ ) {
-## print STDERR "Found something: |$line|\n" if $debug;
-# if (defined($1)) {
-# $packages{$2}=$1;
-# } else {
-# $packages{$2}="";
-# }
-# }
-# }
-# return (%packages);
-#}
-
-
-# %packages=list_packages($preamble)
-# scans the arguments for \documentclass,\RequirePackage and \usepackage statements and constructs a hash
-# whose keys are the included packages, and whose values are the associated optional arguments
-# if argument of \usepackage or \RequirePackage is comma separated list, treat as different packages
-sub list_packages {
- my ($preamble)=@_;
- my %packages=();
- my $pkg;
-
- # remove comments
- $preamble=~s/(?<!\\)%.*$//mg ;
-
- while ( $preamble =~ m/\\(?:documentclass|usepackage|RequirePackage)(?:\[($brat_n)\])?\{(.*?)\}/gs ) {
- if (defined($1)) {
- foreach $pkg ( split /,/,$2 ) {
- $packages{$pkg}=$1;
- }
- } else {
- foreach $pkg ( split /,/,$2 ) {
- $packages{$pkg}="";
- }
- }
- }
-
- # sometimes, class options are defined in such a way that they imply the loading and/or presence of a package
- # so we also treat all class options as 'packages.
- if ( $preamble =~ m/\\documentclass\s*\[($brat_n)\]\s*\{.*?\}/s ) {
- foreach $pkg ( split /,/,$1 ) {
- $pkg =~ s/\s//g ; # remove space and newline characters
- $packages{$pkg}="" unless exists($packages{$pkg});
- }
- }
- return (%packages);
-}
-
-# Subroutine add_safe_commands modified from version provided by S. Gouezel
-# add_safe_commands($preamble)
-# scans the argument for \newcommand and \DeclareMathOperator,
-# and adds the created commands which are clearly safe to @SAFECMDLIST
-sub add_safe_commands {
- my ($preamble)=@_;
-
- # get rid of comments
- $preamble=~s/(?<!\\)%.*$//mg ;
-
- my $to_test = "";
- # test for \DeclareMathOperator{\foo}{myoperator}
- while ( $preamble =~ m/\DeclareMathOperator\s*\*?\{\\(\w*?)\}/osg) {
- $to_test=$1;
- if ($to_test ne "" and not iscmd($to_test,\@SAFECMDLIST,\@SAFECMDEXCL) and not iscmd($to_test, \@SAFECMDEXCL, [])) {
- # one should add $to_test to the list of safe commands.
- init_regex_arr_list(\@SAFECMDLIST, $to_test);
- print STDERR "Adding $to_test to the list of safe commands\n" if $verbose;
- }
- }
-
- while ( $preamble =~ m/\\(?:new|renew|provide)command\s*{\\(\w*)\}(?:|\[\d*\])\s*\{(${pat_n})\}/osg ) {
- my $maybe_to_test = $1;
- my $should_be_safe = $2;
- print STDERR "DEBUG Checking new command: maybe_to_test, should_be_safe: $1 $2\n" if $debug;
- my $success = 0;
- # test if all latex commands inside it are safe
- $success = 1;
- if ($should_be_safe =~ m/\\\\/) {
- $success = 0;
- } else {
- while ($should_be_safe =~ m/\\(\w+)/g) {
- ### print STDERR "DEBUG: Testing command $1 " if $debug;
- $success = 0 unless iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL); ### or $1 eq "";
- ### print STDERR " success=$success\n" if $debug;
- }
- }
- ### }
- if ($success) {
- $to_test = $maybe_to_test;
- if ( not iscmd($to_test,\@SAFECMDLIST,\@SAFECMDEXCL) and not iscmd($to_test, \@SAFECMDEXCL, [])) {
- # # one should add $to_test to the list of safe commands.
- init_regex_arr_list(\@SAFECMDLIST, $to_test);
- print STDERR "Adding $to_test to the list of safe commands\n" if $verbose;
- }
- }
- }
-}
-
-
-# helper function for flatten
-# remove \endinput at beginning of line and everything
-# following it, # if \endinput is not at the beginning of
-# the line, nothing will be removed. It is assumed that
-# this case is most common when \endinput is part of a
-# conditional clause. The file will only be processed
-# correctly if the conditional is always false,
-# i.e. \endinput # not actually reached
-sub remove_endinput {
- # s/// operates on default input
- $_[0] =~ s/^\\endinput.*\Z//ms ;
- return($_[0]);
-}
-
-# flatten($text,$preamble,$filename,$encoding)
-# expands \input and \include commands within text
-# expands \bibliography command with corresponding bbl file if available
-# expands \subfile command (from subfiles package - not part of standard text distribution)
-# preamble is scanned for includeonly commands
-# encoding is the encoding
-sub flatten {
- my ($text,$preamble,$filename,$encoding)=@_;
- my ($includeonly,$dirname,$fname,$newpage,$fullfile,$filecontent,$replacement,$begline,$inputcmd,$bblfile,$subfile,$command,$verbenv,$verboptions,$ignore,$fileonly);
- my ($subpreamble,$subbody,$subpost);
- my ($subdir,$subdirfull,$importfilepath);
- require File::Basename ;
- ### require File::Spec ; # now this is needed even if flatten option not given
- $filename = File::Spec->rel2abs( $filename ) ;
- ($ignore, $dirname, $fileonly) = File::Spec->splitpath($filename) ;
- $bblfile = $filename;
- $bblfile=~s/\.tex$//;
- $bblfile.=".bbl";
-
- if ( ($includeonly) = ($preamble =~ m/\\includeonly\{(.*?)\}/ ) ) {
- $includeonly =~ s/,/|/g;
- } else {
- $includeonly = '.*?';
- }
-
- print STDERR "DEBUG: includeonly $includeonly\n" if $debug;
-
-
- # Run through filter, to let filterscript have a pass if it was set
- $text = filter($text);
-
- # Recursively replace \\import and \\subimport files
- $text =~ s/(^(?:[^%\n]|\\%)*)(\\subimport\{(.*?)\}|\\import\{(.*?)\})(?:[\s]*)\{(.*?)\}/{
- # $1 is begline
- # $3 is directory if subimport
- # $4 is directory if import
- # $5 is filename
- $begline = (defined($1)? $1 : "");
- $subdir = $3 if defined($3);
- $subdir = $4 if defined($4);
- $fname = $5;
- $fname .= ".tex" unless $fname =~ m|\.\w{3,4}$|;
- print STDERR "DEBUG begline:", $begline, "\n" if $debug;
- print STDERR "DEBUG", (defined($3)? "subimport_file:" : "import_file:"), $subdir, "\n" if $debug;
- print STDERR "DEBUG file:", $fname, "\n" if $debug;
-
- # subimport appends $subdir to the current $dirname. import replaces it with an absolute path.
- $subdirfull = (defined($3) ? File::Spec->catdir($dirname,$subdir) : $subdir);
-
- $importfilepath = File::Spec->catfile($subdirfull, $fname);
-
- print STDERR "importing importfilepath:", $importfilepath,"\n" if $verbose;
- if ( -f $importfilepath ) {
- # If file exists, replace input or include command with expanded input
- $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding) or die "Could not open file ",$fullfile,": $!";
- } else {
- # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition
- # and is not meant to be expanded directly
- print STDERR "WARNING: Could not find included file ",$importfilepath,". I will continue but not expand |$2|\n";
- $replacement=(defined($3)? "\\subimport" : "\\import");
- $replacement .= "{$subdir}{$fname} % Processed";
- }
- "$begline$replacement";
- }/exgm;
-
- # recursively replace \\input and \\include files
- $text =~ s/(^(?:[^%\n]|\\%)*)(\\input\{(.*?)\}|\\include\{(${includeonly}(?:\.tex)?)\})/{
- $begline=(defined($1)? $1 : "") ;
- $inputcmd=$2;
- $fname = $3 if defined($3) ;
- $fname = $4 if defined($4) ;
- $newpage=(defined($4)? " \\newpage " : "") ;
- # # add tex extension unless there is a three or four letter extension already
- $fname .= ".tex" unless $fname =~ m|\.\w{3,4}$|;
- $fullfile = File::Spec->catfile($dirname,$fname);
- print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ;
- print STDERR "Include file $fname\n" if $verbose;
- print STDERR "DEBUG looking for file ",$fullfile, "\n" if $debug;
- # content of file becomes replacement value (use recursion), add \newpage if the command was include
- if ( -f $fullfile ) {
- # If file exists, replace input or include command with expanded input
- $replacement=flatten(read_file_with_encoding($fullfile, $encoding), $preamble,$filename,$encoding) or die "Could not open file ",$fullfile,": $!";
- $replacement = remove_endinput($replacement);
- # \include always starts a new page; use explicit \newpage command to simulate this
- } else {
- # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition
- # and is not meant to be expanded directly
- print STDERR "WARNING: Could not find included file ",$fullfile,". I will continue but not expand |$inputcmd|\n" unless $fname =~ m(#[0-9]) ;
- $replacement = $inputcmd ; # i.e. just the original command again -> make no change file does not exist
- $newpage="";
- }
- "$begline$newpage$replacement$newpage";
- }/exgm;
-
- # replace bibliography with bbl file if it exists
- $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{
- if ( -f $bblfile ){
- $replacement=read_file_with_encoding(File::Spec->catfile($bblfile), $encoding);
- } else {
- warn "Bibliography file $bblfile cannot be found. No flattening of \\bibliography done. Run bibtex on old and new files first";
- $replacement="\\bibliography{$2}";
- }
- $begline=(defined($1)? $1 : "") ;
- "$begline$replacement";
- }/exgm;
-
- # replace subfile with contents (subfile package)
- $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{
- $begline=(defined($1)? $1 : "") ;
- $fname = $2;
- # # add tex extension unless there is a three or four letter extension already
- $fname .= ".tex" unless $fname =~ m|\.\w{3,4}|;
- print STDERR "Include file as subfile $fname\n" if $verbose;
- # content of file becomes replacement value (use recursion)
- # now strip away everything outside and including \begin{document} and \end{document} pair#
- # # note: no checking for comments is made
- $fullfile=File::Spec->catfile($dirname,$fname);
- if ( -f $fullfile) {
- # if file exists, expand \subfile command by contents of file
- $subfile=read_file_with_encoding($fullfile,$encoding) or die "Could not open included subfile ",$fullfile,": $!";
- ($subpreamble,$subbody,$subpost)=splitdoc($subfile,'\\\\begin\{document\}','\\\\end\{document\}');
- ### $subfile=~s|^.*\\begin{document}||s;
- ### $subfile=~s|\\end{document}.*$||s;
- $replacement=flatten($subbody, $preamble,$filename,$encoding);
- ### $replacement = remove_endinput($replacement);
- } else {
- # if file does not exist, do not expand subfile
- print STDERR "WARNING: Could not find subfile ",$fullfile,". I will continue but not expand |$2|\n" unless $fname =~ m(#[0-9]) ;
- $replacement = "\\subfile\{$2\}" ; # i.e. just the original command again -> make no change file does not exist
- }
-
- "$begline$replacement";
- }/exgm;
-
- # replace \verbatiminput and \lstlistinginput
- $text=~s/(^(?:[^%\n]|\\%)*)\\(verbatiminput\*?|lstinputlisting)$extraspace(\[$brat_n\])?$extraspace\{(.*?)\}/{
- $begline=(defined($1)? $1 : "") ;
- $command = $2 ;
- $fname = $4 ;
- $verboptions = defined($3)? $3 : "" ;
- if ($command eq 'verbatiminput' ) {
- $verbenv = "verbatim" ;
- } elsif ($command eq 'verbatiminput*' ) {
- $verbenv = "verbatim*" ;
- } elsif ($command eq 'lstinputlisting' ) {
- $verbenv = "lstlisting" ;
- } else {
- die "Internal errorL Unexpected verbatim input type $command.\n";
- }
- print STDERR "DEBUG Beg of line match |$begline|\n" if $debug ;
- print STDERR "Include file $fname verbatim\n" if $verbose;
- print STDERR "DEBUG looking for file ",File::Spec->catfile($dirname,$fname), "\n" if $debug;
- # content of file becomes replacement value (do not use recursion), add \newpage if the command was include
- ###$replacement=read_file_with_encoding(File::Spec->catfile($dirname,$fname), $encoding) or die "Couldn't find file ",File::Spec->catfile($dirname,$fname),": $!";
- $replacement=read_file_with_encoding(File::Spec->catfile($dirname,$fname), $encoding) or die "Couldn't find file ",File::Spec->catfile($dirname,$fname),": $!";
- # Add a new line if it not already there (note that the matching operator needs to use different delimiters, as we are still inside an outer scope that takes precedence
- $replacement .= "\n" unless $replacement =~ m(\n$) ;
- "$begline\\begin{$verbenv}$verboptions\n$replacement\\end{$verbenv}\n";
- }/exgm;
-
- return($text);
-}
-
-
-# print_regex_arr(@arr)
-# prints regex array without x-ism expansion put in by pearl to stdout
-sub print_regex_arr {
- my $dumstring;
- $dumstring = join(" ",@_); # PERL generates string (?-xism:^ref$) for quoted refex ^ref$
- $dumstring =~ s/\(\?-xism:\^(.*?)\$\)/$1/g; # remove string and ^,$ marks before output
- print $dumstring,"\n";
-}
-
-
-# @lines=extrapream($type,...)
-# reads line from appendix or external file
-# (end of file after __END__ token)
-# if $type is a filename, it will read the file instead of reading from the appendix
-# otherwise it will screen appendix for line "%DIF $TYPE" and copy everything up to line
-# '%DIF END $TYPE' (where $TYPE is upcased version of $type)
-# extrapream('-nofail',$type) will---instead of failing---simply return nothing if
-# it does not find the matching line in a appendix (do not use -nofail option with multiple types!)
-sub extrapream {
- my @types=@_;
- my ($type,$arg);
- my $nofail=0;
- ###my @retval=("%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF") ;
- my @retval=();
- my ($copy);
-
- foreach $arg ( @types ) {
- if ( $arg eq '-nofail' ) {
- $nofail=1;
- next;
- }
- $type=$arg;
- $copy=0;
- if ( -f $type || lc $type eq '/dev/null' ) {
- open (FILE,$type) or die "Cannot open preamble file $type: $!";
- print STDERR "Reading preamble file $type\n" if $verbose ;
- while (<FILE>) {
- chomp ;
- if ( $_ =~ m/%DIF PREAMBLE/ ) {
- push (@retval,"$_");
- } else {
- push (@retval,"$_ %DIF PREAMBLE");
- }
- }
- } else { # not (-f $type)
- $type=uc($type); # upcase argument
- print STDERR "Preamble Internal Type $type\n" if $verbose;
- # save filehandle position (before first read this points to line after __END__)
- # but seek DATA,0,0 resets it to the beginning of the file
- # see https://stackoverflow.com/questions/4459601/how-can-i-use-data-twice
- my $data_start = tell DATA;
- while (<DATA>) {
- if ( m/^%DIF $type/ ) {
- $copy=1;
- } elsif ( m/^%DIF END $type/ ) {
- last;
- }
- chomp;
- push (@retval,"$_ %DIF PREAMBLE") if $copy;
- }
- if ( $copy == 0 ) {
- unless ($nofail) {
- print STDERR "\nPreamble style $type not implemented.\n";
- print STDERR "Write latexdiff -h to get help with available styles\n";
- exit(2);
- }
- }
- seek DATA,$data_start,0; # rewind DATA handle to beginning of data record
- }
- }
- ###push (@retval,"%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF") ;
- return @retval;
-}
-
-
-# ($part1,$part2,$part3)=splitdoc($text,$word1,$word2)
-# splits $text into 3 parts at $word1 and $word2.
-# if neither $word1 nor $word2 exist, $part1 and $part3 are empty, $part2 is $text
-# If only $word1 or $word2 exist but not the other, output an error message.
-
-# NB this version avoids $` and $' for performance reason although it only makes a tiny difference
-# (in one test gain a tenth of a second for a 30s run)
-sub splitdoc {
- my ($text,$word1,$word2)=@_;
- my ($part1,$part2,$part3)=("","","");
- my ($rest,$pos);
-
- if ( $text =~ m/(^[^%]*)($word1)/mg ) {
- $pos=pos $text;
- $part1=substr($text,0,$pos-length($2));
- $rest=substr($text,$pos);
- if ( $rest =~ m/(^[^%]*)($word2)/mg ) {
- $pos=pos $rest;
- $part2=substr($rest,0,$pos-length($2));
- $part3=substr($rest,$pos);
- }
- else {
- die "$word1 and $word2 not in the correct order or not present as a pair." ;
- }
- } else {
- $part2=$text;
- die "$word2 present but not $word1." if ( $text =~ m/(^[^%]*)$word2/ms );
- }
- return ($part1,$part2,$part3);
-}
-
-
-
-
-
-# bodydiff($old,$new)
-sub bodydiff {
- my ($oldwords, $newwords) = @_;
- my @retwords;
-
- print STDERR "(",exetime()," s)\n","Splitting into latex tokens \n" if $verbose;
- print STDERR "Parsing $oldfile \n" if $verbose;
- my @oldwords = splitlatex($oldwords);
- print STDERR "Parsing $newfile \n" if $verbose;
- my @newwords = splitlatex($newwords);
-
- if ( $debug ) {
- open(TOKENOLD,">","latexdiff.debug.tokenold");
- print TOKENOLD join("***\n",@oldwords);
- close(TOKENOLD);
- open(TOKENNEW,">","latexdiff.debug.tokennew");
- print TOKENNEW join("***\n",@newwords);
- close(TOKENNEW);
- }
-
- print STDERR "(",exetime()," s)\n","Pass 1: Expanding text commands and merging isolated identities with changed blocks " if $verbose;
- pass1(\@oldwords, \@newwords);
-
-
- print STDERR "(",exetime()," s)\n","Pass 2: inserting DIF tokens and mark up. " if $verbose;
- if ( $debug ) {
- open(TOKENOLD,">","latexdiff.debug.tokenold2");
- print TOKENOLD join("***\n",@oldwords);
- close(TOKENOLD);
- open(TOKENNEW,">","latexdiff.debug.tokennew2");
- print TOKENNEW join("***\n",@newwords);
- close(TOKENNEW);
- }
-
- @retwords=pass2(\@oldwords, \@newwords);
-
- return(@retwords);
-}
-
-
-
-
-# @words=splitlatex($string)
-# split string according to latex rules
-# Each element of words is either
-# a word (including trailing spaces and punctuation)
-# a latex command
-# if there is white space in the beginning return that as first token
-sub splitlatex {
- my ($inputstring) = @_ ;
- my $string=$inputstring ;
- # if input is empty, return empty list
- length($string)>0 or return ();
- $string=~s/^(\s*)//s;
- my $leadin=$1;
- length($string)>0 or return ($leadin);
-
- my @retval=($string =~ m/$pat/osg);
-
- if (length($string) != length(join("",@retval))) {
- print STDERR "\nWARNING: Inconsistency in length of input string and parsed string:\n This often indicates faulty or non-standard latex code.\n In many cases you can ignore this and the following warning messages.\n Note that character numbers in the following are counted beginning after \\begin{document} and are only approximate." unless $ignorewarnings;
- print STDERR "DEBUG Original length ",length($string)," Parsed length ",length(join("",@retval)),"\n" if $debug;
- print STDERR "DEBUG Input string: |$string|\n" if (length($string)<500) && $debug;
- print STDERR "DEBUG Token parsing: |",join("+",@retval),"|\n" if (length($string)<500) && $debug ;
- @retval=();
- # slow way only do this if other m//sg method fails
- my $last = 0;
- while ( $string =~ m/$pat/osg ) {
- my $match=$&;
- if ($last + length $& != pos $string ) {
- my $pos=pos($string);
- my $offset=30<$last ? 30 : $last;
- my $dum=substr($string,$last-$offset,$pos-$last+2*$offset);
- my $dum1=$dum;
- my $cnt=$#retval;
- my $i;
- $dum1 =~ s/\n/ /g;
- unless ($ignorewarnings) {
- print STDERR "\n$dum1\n";
- print STDERR " " x 30,"^" x ($pos-$last)," " x 30,"\n";
- print STDERR "Missing characters near word " . (scalar @retval) . " character index: " . $last . "-" . pos($string) . " Length: " . length($match) . " Match: |$match| (expected match marked above).\n";
- }
- # put in missing characters `by hand'
- push (@retval, substr($dum,$offset,$pos-$last-length($match)));
-# Note: there seems to be a bug in substr with utf8 that made the following line output substr which were too long,
-# using dum instead appears to work
-# push (@retval, substr($string,$last, pos($string)-$last-length($match)));
- }
- push (@retval, $match);
- $last=pos $string;
- }
-
- }
-
- unshift(@retval,$leadin) if (length($leadin)>0);
- return @retval;
-}
-
-
-# pass1( \@seq1,\@seq2)
-# Look for differences between seq1 and seq2.
-# Where an common-subsequence block is flanked by deleted or appended blocks,
-# and is shorter than $MINWORDSBLOCK words it is appended
-# to the last deleted or appended word. If the block contains tokens other than words
-# or punctuation it is not merged.
-# Deleted or appended block consisting of words and safe commands only are
-# also merged, to prevent break-up in pass2 (after previous isolated words have been removed)
-# If there are commands with textual arguments (e.g. \caption) both in corresponding
-# appended and deleted blocks split them such that the command and opening bracket
-# are one token, then the rest is split up following standard rules, and the closing
-# bracket is a separate token, ie. turn
-# "\caption{This is a textual argument}" into
-# ("\caption{","This ","is ","a ","textual ","argument","}")
-# No return value. Destructively changes sequences
-sub pass1 {
- my $seq1 = shift ;
- my $seq2 = shift ;
-
- my $len1 = scalar @$seq1;
- my $len2 = scalar @$seq2;
- my $wpat=qr/^(?:[a-zA-Z.,'`:;?()!]*)[\s~]*$/; #'
-
- my ($last1,$last2)=(-1,-1) ;
- my $cnt=0;
- my $block=[];
- my $addblock=[];
- my $delblock=[];
- my $todo=[];
- my $instruction=[];
- my $i;
- my (@delmid,@addmid,@dummy);
-
- my ($addcmds,$delcmds,$matchindex);
- my ($addtextblocks,$deltextblocks);
- my ($addtokcnt,$deltokcnt,$mattokcnt)=(0,0,0);
- my ($addblkcnt,$delblkcnt,$matblkcnt)=(0,0,0);
-
- my $adddiscard = sub {
- if ($cnt > 0 ) {
- $matblkcnt++;
- # just after an unchanged block
-# print STDERR "Unchanged block $cnt, $last1,$last2 \n";
- if ($cnt < $MINWORDSBLOCK
- && $cnt==scalar (
- grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat_n\]|\{$pat_n\})*)/o
- && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL)
- && scalar(@dummy=split(" ",$2))<3 ) }
- @$block) ) {
- # merge identical blocks shorter than $MINWORDSBLOCK
- # and only containing ordinary words
- # with preceding different word
- # We cannot carry out this merging immediately as this
- # would change the index numbers of seq1 and seq2 and confuse
- # the algorithm, instead we store in @$todo where we have to merge
- push(@$todo, [ $last1,$last2,$cnt,@$block ]);
- }
- $block = [];
- $cnt=0; $last1=-1; $last2=-1;
- }
- };
- my $discard=sub { $deltokcnt++;
- &$adddiscard; #($_[0],$_[1]);
- push(@$delblock,[ $seq1->[$_[0]],$_[0] ]);
- $last1=$_[0] };
-
- my $add = sub { $addtokcnt++;
- &$adddiscard; #($_[0],$_[1]);
- push(@$addblock,[ $seq2->[$_[1]],$_[1] ]);
- $last2=$_[1] };
-
- my $match = sub { $mattokcnt++;
- if ($cnt==0) { # first word of matching sequence after changed sequence or at beginning of word sequence
- $deltextblocks = extracttextblocks($delblock);
- $delblkcnt++ if scalar @$delblock;
- $addtextblocks = extracttextblocks($addblock);
- $addblkcnt++ if scalar @$addblock;
-
- # make a list of all TEXTCMDLIST commands in deleted and added blocks
- $delcmds = extractcommands($delblock);
- $addcmds = extractcommands($addblock);
- # now find those text commands, which are found in both deleted and added blocks, and expand them
- # keygen(third argument of _longestCommonSubsequence) implies to sort on command (0th elements of $addcmd elements)
- # the calling format for longestCommonSubsequence has changed between versions of
- # Algorithm::Diff so we need to check which one we are using
- if ( $algodiffversion > 1.15 ) {
- ### Algorithm::Diff 1.19
- $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, 0, sub { $_[0]->[0] } );
- } else {
- ### Algorithm::Diff 1.15
- $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, sub { $_[0]->[0] } );
- }
-
- for ($i=0 ; $i<=$#$matchindex ; $i++) {
- if (defined($matchindex->[$i])){
- $j=$matchindex->[$i];
- @delmid=splitlatex($delcmds->[$i][3]);
- @addmid=splitlatex($addcmds->[$j][3]);
- while (scalar(@$deltextblocks) && $deltextblocks->[0][0]<$delcmds->[$i][1]) {
- my ($index,$block,$cnt)=@{ shift(@$deltextblocks) };
- push(@$todo, [$index,-1,$cnt,@$block]);
- }
- push(@$todo, [ $delcmds->[$i][1],-1,-1,$delcmds->[$i][2],@delmid,$delcmds->[$i][4]]);
-
- while (scalar(@$addtextblocks) && $addtextblocks->[0][0]<$addcmds->[$j][1]) {
- my ($index,$block,$cnt)=@{ shift(@$addtextblocks) };
- push(@$todo, [-1,$index,$cnt,@$block]);
- }
- push(@$todo, [ -1,$addcmds->[$j][1],-1,$addcmds->[$j][2],@addmid,$addcmds->[$j][4]]);
- }
- }
- # mop up remaining textblocks
- while (scalar(@$deltextblocks)) {
- my ($index,$block,$cnt)=@{ shift(@$deltextblocks) } ;
- push(@$todo, [$index,-1,$cnt,@$block]);
- }
- while (scalar(@$addtextblocks)) {
- my ($index,$block,$cnt)=@{ shift(@$addtextblocks) };
- push(@$todo, [-1,$index,$cnt,@$block]);
- }
-
- $addblock=[];
- $delblock=[];
- }
- push(@$block,$seq2->[$_[1]]);
- $cnt++ };
-
- my $keyfunc = sub { join(" ",split(" ",shift())) };
-
- traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc );
-
-
- # now carry out the merging/splitting. Refer to elements relative from
- # the end (with negative indices) as these offsets don't change before the instruction is executed
- # cnt>0: merged small unchanged groups with previous changed blocks
- # cnt==-1: split textual commands into components
- foreach $instruction ( @$todo) {
- ($last1,$last2,$cnt,@$block)=@$instruction ;
- if ($cnt>=0) {
- splice(@$seq1,$last1-$len1,1+$cnt,join("",$seq1->[$last1-$len1],@$block)) if $last1>=0;
- splice(@$seq2,$last2-$len2,1+$cnt,join("",$seq2->[$last2-$len2],@$block)) if $last2>=0;
- } else {
- splice(@$seq1,$last1-$len1,1,@$block) if $last1>=0;
- splice(@$seq2,$last2-$len2,1,@$block) if $last2>=0;
- }
- }
-
- if ($verbose) {
- print STDERR "\n";
- print STDERR " $mattokcnt matching tokens in $matblkcnt blocks.\n";
- print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n";
- print STDERR " $addtokcnt appended tokens in $addblkcnt blocks.\n";
- }
-}
-
-
-# extracttextblocks(\@blockindex)
-# $blockindex has the following format
-# [ [ token1, index1 ], [token2, index2],.. ]
-# where index refers to the index in the original old or new word sequence
-# Returns: reference to an array of the form
-# [[ $index, $textblock, $cnt ], ..
-# where $index index of block to be merged
-# $textblock contains all the words to be merged with the word at $index (but does not contain this word)
-# $cnt is length of block
-#
-# requires: iscmd
-#
-sub extracttextblocks {
- my $block=shift;
- my ($i,$token,$index);
- my $textblock=[];
- my $last=-1;
- my $wpat=qr/^(?:[a-zA-Z.,'`:;?()!]*)[\s~]*$/; #'
- my $retval=[];
-
- # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting
- # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here
- my $extraspace='\s*';
-
- for ($i=0;$i< scalar @$block;$i++) {
- ($token,$index)=@{ $block->[$i] };
- # store pure text blocks
- if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*)/
- && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL)
- && !iscmd($1,\@TEXTCMDLIST,\@TEXTCMDEXCL))) {
- # we have text or a command which can be treated as text
- if ($last<0) {
- # new pure-text block
- $last=$index;
- } else {
- # add to pure-text block
- push(@$textblock, $token);
- }
- } else {
- # it is not text
- if (scalar(@$textblock)) {
- push(@$retval,[ $last, $textblock, scalar(@$textblock) ]);
- }
- $textblock=[];
- $last=-1;
- }
- }
- # finish processing a possibly unfinished block before returning
- if (scalar(@$textblock)) {
- push(@$retval,[ $last, $textblock, scalar(@$textblock) ]);
- }
- return($retval)
-}
-
-
-
-# extractcommands( \@blockindex )
-# $blockindex has the following format
-# [ [ token1, index1 ], [token2, index2],.. ]
-# where index refers to the index in the original old or new word sequence
-# Returns: reference to an array of the form
-# [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],..
-# where index is just taken from input array
-# command must have a textual argument as last argument
-#
-# requires: iscmd
-#
-sub extractcommands {
- my $block=shift;
- my ($i,$token,$index,$cmd,$open,$mid,$closing);
- my $retval=[];
-
- # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting
- # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here
- my $extraspace='\s*';
-
- for ($i=0;$i< scalar @$block;$i++) {
- ($token,$index)=@{ $block->[$i] };
- # check if token is an alphanumeric command sequence with at least one non-optional argument
- # \cmd[...]{...}{last argument}
- # Capturing in the following results in these associations
- # $1: \cmd[...]{...}{
- # $2: \cmd
- # $3: last argument
- # $4: } + trailing spaces
- if ( ( $token =~ m/^(\\([\w\d\*]+)(?:${extraspace}\[$brat_n\]|${extraspace}\{$pat_n\})*${extraspace}\{)($pat_n)(\}\s*)$/so )
- && iscmd($2,\@TEXTCMDLIST,\@TEXTCMDEXCL) ) {
- print STDERR "DEBUG EXTRACTCOMMANDS Match |$1|$2|$3|$4|$index \n" if $debug;
- # push(@$retval,[ $2,$index,$1,$3,$4 ]);
- ($cmd,$open,$mid,$closing) = ($2,$1,$3,$4) ;
- $closing =~ s/\}/\\RIGHTBRACE/ ;
- push(@$retval,[ $cmd,$index,$open,$mid,$closing ]);
- }
- }
- return $retval;
-}
-
-# iscmd($cmd,\@regexarray,\@regexexcl) checks
-# return 1 if $cmd matches any of the patterns in the
-# array $@regexarray, and none of the patterns in \@regexexcl, otherwise return 0
-sub iscmd {
- my ($cmd,$regexar,$regexexcl)=@_;
- my ($ret)=0;
- ### print STDERR "DEBUG: iscmd($cmd)=" if $debug;
- foreach $pat ( @$regexar ) {
- if ( $cmd =~ m/^${pat}$/ ) {
- $ret=1 ;
- last;
- }
- }
- ### print STDERR "0\n" if ($debug && !$ret) ;
- return 0 unless $ret;
- foreach $pat ( @$regexexcl ) {
- ### print STDERR "0\n" if ( $debug && $cmd =~ m/^${pat}$/) ;
- return 0 if ( $cmd =~ m/^${pat}$/ );
- }
- ### print STDERR "1\n" if $debug;
- return 1;
-}
-
-
-# pass2( \@seq1,\@seq2)
-# Look for differences between seq1 and seq2.
-# Mark begin and end of deleted and appended sequences with tags $DELOPEN and $DELCLOSE
-# and $ADDOPEN and $ADDCLOSE, respectively, however exclude { } & and all comands, unless
-# they match an element of the whitelist (SAFECMD)
-# For words in TEXTCMD but not in SAFECMD, enclose interior with $ADDOPEN and $ADDCLOSE brackets
-# Deleted comment lines are marked with %DIF <
-# Added comment lines are marked with %DIF >
-sub pass2 {
- my $seq1 = shift ;
- my $seq2 = shift ;
-
- my ($addtokcnt,$deltokcnt,$mattokcnt)=(0,0,0);
- my ($addblkcnt,$delblkcnt,$matblkcnt)=(0,0,0);
-
- my $retval = [];
- my $delhunk = [];
- my $addhunk = [];
-
- my $discard = sub { $deltokcnt++;
- push ( @$delhunk, $seq1->[$_[0]]) };
-
- my $add = sub { $addtokcnt++;
- push ( @$addhunk, $seq2->[$_[1]]) };
-
- my $match = sub { $mattokcnt++;
- if ( scalar @$delhunk ) {
- $delblkcnt++;
- # mark up changes, but comment out commands
- push @$retval,marktags($DELMARKOPEN,$DELMARKCLOSE,$DELOPEN,$DELCLOSE,$DELCMDOPEN,$DELCMDCLOSE,$DELCOMMENT,$delhunk);
- $delhunk = [];
- }
- if ( scalar @$addhunk ) {
- $addblkcnt++;
- # we mark up changes, but simply quote commands
- push @$retval,marktags($ADDMARKOPEN,$ADDMARKCLOSE,$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,$addhunk);
- $addhunk = [];
- }
- push(@$retval,$seq2->[$_[1]]) };
-
- my $keyfunc = sub { join(" ",split(" ",shift())) };
-
- traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc );
- # clear up unprocessed hunks
- push @$retval,marktags($DELMARKOPEN,$DELMARKCLOSE,$DELOPEN,$DELCLOSE,$DELCMDOPEN,$DELCMDCLOSE,$DELCOMMENT,$delhunk) if scalar @$delhunk;
- push @$retval,marktags($ADDMARKOPEN,$ADDMARKCLOSE,$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,$addhunk) if scalar @$addhunk;
-
-
- if ($verbose) {
- print STDERR "\n";
- print STDERR " $mattokcnt matching tokens. \n";
- print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n";
- print STDERR " $addtokcnt appended tokens in $addblkcnt blocks.\n";
- }
- return(@$retval);
-}
-
-# marktags($openmark,$closemark,$open,$close,$opencmd,$closecmd,$comment,\@block)
-# returns ($openmark,$open,$block,$close,$closemark) if @block contains no commands (except white-listed ones),
-# braces, ampersands, or comments
-# mark comments with $comment
-# exclude all other exceptions from scope of open, close like this
-# ($openmark, $open,...,$close, $opencmd,command, command,$closecmd, $open, ..., $close, $closemark)
-# If $opencmd begins with "%" marktags assumes it is operating on a deleted block, otherwise on an added block
-sub marktags {
- my ($openmark,$closemark,$open,$close,$opencmd,$closecmd,$comment,$block)=@_;
- my $word;
- my (@argtext);
- my $retval=[];
- my $noncomment=0;
- my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word
- # 1: last token written is a command
- # for keeping track whether we are just in a command sequence or in a word sequence
- my $cmdcomment= ($opencmd =~ m/^%/); # Flag to indicate whether opencmd is a comment (i.e. if we intend to simply comment out changed commands)
- my ($command,$commandword,$closingbracket) ; # temporary variables needed below to remember sub-pattern matches
-
-
-
-# split this block to split sequences joined in pass1
- @$block=splitlatex(join "",@$block);
- ### print STDERR "DEBUG: marktags $openmark,$closemark,$open,$close,$opencmd,$closecmd,$comment\n" if $debug;
- ### print STDERR "DEBUG: marktags blocksplit ",join("|",@$block),"\n" if $debug;
-
- # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting
- # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here
- my $extraspace_mt='\s*';
-
-
- foreach (@$block) {
- $word=$_;
- if ( $word =~ s/^%/%$comment/ ) {
- # a comment
- if ($cmd==1) {
- push (@$retval,$closecmd) ;
- $cmd=-1;
- }
- push (@$retval,$word);
- next;
- }
- if ( $word =~ m/^\s*$/ ) {
- ### print STDERR "DEBUG MARKTAGS: whitespace detected |$word| cmdcom |$cmdcomment| |$opencmd|\n" if $debug;
- # a sequence of white-space characters - this should only ever happen for the first element of block.
- # in deleted block, omit, otherwise just copy it in
- if ( ! $cmdcomment) { # ignore in deleted blocks
- push(@$retval,$word);
- }
- next;
- }
- if (! $noncomment) {
- push (@$retval,$openmark);
- $noncomment=1;
- }
- # negative lookahead pattern (?!) in second clause is put in to avoid matching \( .. \) patterns
- # also note that second pattern will match \\
- if ( $word =~ /^[&{}\[\]]/ || ( $word =~ /^\\(?!\()(\\|[`'^"~=.]|[\w*@]+)/ && !iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL)) ) {
- ### if ( $word =~ /^[&{}\[\]]/ || ( $word =~ /^\\([\w*@\\% ]+)/ && !iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL)) ) {
- # word is a command or other significant token (not in SAFECMDLIST)
- ## same conditions as in subroutine extractcommand:
- # check if token is an alphanumeric command sequence with at least one non-optional argument
- # \cmd[...]{...}{last argument}
- # Capturing in the following results in these associations
- # $1: \cmd[...]{...}{
- # $2: cmd
- # $3: last argument
- # $4: } + trailing spaces
- ### pre-0.3 if ( ( $token =~ m/^(\\([\w\d\*]+)(?:\[$brat0\]|\{$pat_n\})*\{)($pat_n)(\}\s*)$/so )
- if ( ( $word =~ m/^(\\([\w\d\*]+)(?:${extraspace_mt}\[$brat_n\]|${extraspace_mt}\{$pat_n\})*${extraspace_mt}\{)($pat_n)(\}\s*)$/so )
- && (iscmd($2,\@TEXTCMDLIST,\@TEXTCMDEXCL)|| iscmd($2,\@MATHTEXTCMDLIST,\@MATHTEXTCMDEXCL))
- && ( !$cmdcomment || !iscmd($2,\@CONTEXT2CMDLIST, \@CONTEXT2CMDEXCL) ) ) {
- # Condition 1: word is a command? - if yes, $1,$2,.. will be set as above
- # Condition 2: word is a text command - we mark up the interior of the word. There is a separate check for MATHTEXTCMDLIST
- # because for $mathmarkup=WHOLE, the commands should not be split in pass1 (ie. math mode commands are not in
- # TEXTCMDLIST, but the interior of MATHTEXT commnds should be highlighted in both deleted and added blocks
- # Condition 3: But if we are in a deleted block ($cmdcomment=1) and
- # $2 (the command) is in context2, just treat it as an ordinary command (i.e. comment it open with $opencmd)
- # Because we do not want to disable this command
- # here we do not use $opencmd and $closecmd($opencmd is empty)
- if ($cmd==1) {
- push (@$retval,$closecmd) ;
- } elsif ($cmd==0) {
- push (@$retval,$close) ;
- }
- $command=$1; $commandword=$2; $closingbracket=$4;
- @argtext=splitlatex($3); # split textual argument into tokens
- # and mark it up (but we do not need openmark and closemark)
- # insert command with initial arguments, marked-up final argument, and closing bracket
- if ( $cmdcomment && iscmd($commandword,\@CONTEXT1CMDLIST, \@CONTEXT1CMDEXCL) ) {
- # context1cmd in a deleted environment; delete command itself but keep last argument, marked up
- push (@$retval,$opencmd);
- $command =~ s/\n/\n${opencmd}/sg ; # repeat opencmd at the beginning of each line
- # argument, note that the additional comment character is included
- # to suppress linebreak after opening parentheses, which is important
- # for latexrevise
- push (@$retval,$command,"%\n{$AUXCMD\n",marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket);
- } elsif ( iscmd($commandword,,\@MATHTEXTCMDLIST, \@MATHTEXTCMDEXCL) ) {
- # MATHBLOCK pseudo command: consider all commands safe, except & and \\
- # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to
- # ""
- local @SAFECMDLIST=(".*");
- local @SAFECMDEXCL=('\\','\\\\',@UNSAFEMATHCMD);
- push(@$retval,$command,marktags("","",$open,$close,"","",$comment,\@argtext)#@argtext
- ,$closingbracket);
- } else {
- # normal textcmd or context1cmd in an added block
- push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket);
- }
- push (@$retval,$AUXCMD,"\n") if $cmdcomment ;
- $cmd=-1 ;
- } elsif ( $cmdcomment &&
- ( $word =~ m/^(\\([\w\d\*]+)(?:${extraspace_mt}\[$brat_n\]|${extraspace_mt}\{$pat_n\})*${extraspace_mt}\{)($pat_n)(\}\s*)/so )
- && iscmd($2,\@KEEPCMDLIST, \@KEEPCMDEXCL) ) {
- # 'keepcmd' in a deleted environment: keep the command as is
- push (@$retval,$close) if $cmd==0 ;
- push (@$retval,$word);
- $cmd=-1; # pretend we are at the beginning of a sequence because we do not want to add an additional $closecmd or $close before the next token, no matter what it is
- } else {
- # ordinary command
- push (@$retval,$opencmd) if $cmd==-1 ;
- push (@$retval,$close,$opencmd) if $cmd==0 ;
- $word =~ s/\n/\n${opencmd}/sg if $cmdcomment ; # if opencmd is a comment, repeat this at the beginning of every line
- ### print STDERR "MARKTAGS: Add command |$word|\n";
- push (@$retval,$word);
- $cmd=1;
- }
- } else {
- ###print STDERR "DEBUG MARKTAGS is an ordinary word or SAFECMD command \n" if $debug;
- # just an ordinary word or command in SAFECMD
- push (@$retval,$open) if $cmd==-1 ;
- push (@$retval,$closecmd,$open) if $cmd==1 ;
- ###TODO: check here if it is a command in MBOXCMD list, and surround it with \mbox{...}
- ### $word =~ /^\\(?!\()(\\|[`'^"~=.]|[\w*@]+)/ && iscmd($1,\@MBOXCMDLIST,\@MBOXCMDEXCL))
- ### but actually this check has been carried out already so can simply check if word begins with backslash
- if ( $word =~ /^\\(?!\()(\\|[`'^"~=.]|[\w*@]+)(.*?)(\s*)$/s && iscmd($1,\@MBOXCMDLIST,\@MBOXCMDEXCL)) {
- # $word is a safe command in MBOXCMDLIST
- ###print STDERR "DEBUG Mboxsafecmd detected:$word:\n" if $debug ;
- push(@$retval,"\\mbox{$AUXCMD\n\\" . $1 . $2 . $3 ."}\\hspace{0pt}$AUXCMD\n" );
- } else {
- # $word is a normal word or a safe command (not in MBOXCMDLIST)
- push (@$retval,$word);
- }
- $cmd=0;
- }
- }
- push (@$retval,$close) if $cmd==0;
- push (@$retval,$closecmd) if $cmd==1;
-
- push (@$retval,$closemark) if ($noncomment);
- return @$retval;
-}
-
-#used in preprocess
-sub take_comments_and_newline_from_frac() {
- # some special magic for common usage of frac, which does not conform to the latexdiff requirements but can be made to fit
- # note that this is a rare exception to the general rule that the new tex can be reconstructed from the diff file
-
- # \frac12 -> \frac{1}{2}
- s/\\frac(\d)(\w)/\\frac\{$1\}\{$2\}/g;
-
- # \frac1{2b} -> \frac{1}{2b}
- s/\\frac(\d)/\\frac\{$1\}/g;
-
- # delete space and comment characters between \frac arguments
-# s/\\frac(?:\s*?%[^\n]*?)*?(\{$pat_n\})\s*(\{$pat_n\})/\\frac$1$2/g;
- s/\\frac(?:\s|%[^\n]*?)*(\{$pat_n\})(?:\s|%[^\n]*?)*(\{$pat_n\})/\\frac$1$2/g;
-}
-
-# preprocess($string, ..)
-# carry out the following pre-processing steps for all arguments:
-# 1. Remove leading white-space
-# Change \{ to \QLEFTBRACE and \} to \QRIGHTBRACE and \& to \AMPERSAND
-# #. Change {,} in comments to \CLEFTBRACE, \CRIGHTBRACE
-# 2. mark all first empty line (in block of several) with \PAR tokens
-# 3. Convert all '\%' into '\PERCENTAGE ' and all '\$' into \DOLLAR to make parsing regular expressions easier
-# 4. Convert all \verb|some verbatim text| commands (where | can be an arbitrary character)
-# into \verb{hash} (also lstinline)
-# 5. Convert \begin{verbatim} some verbatim text \end{verbatim} into \verbatim{hash} (not only verbatim, all patterns matching VERBATIMENV)
-# 6. Convert _n into \SUBSCRIPTNB{n} and _{nnn} into \SUBSCRIPT{nn}
-# 7. Convert ^n into \SUPERSCRIPTNB{n} and ^{nnn} into \SUPERSCRIPT{nn}
-# 8. a. Convert $$ $$ into \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR}
-# b. Convert \[ \] into \begin{SQUAREBRACKET} \end{SQUAREBRACKET}
-# 9. Convert all picture environmentent (\begin{PICTUREENV} .. \end{PICTUREENV} \PICTUREBLOCKenv
-# For math-mode COARSE,WHOLE or NONE option -convert all \begin{MATH} .. \end{MATH}
-# into \MATHBLOCKmath{...} commands, where MATH/math is any valid math environment
-
-# 10. Add final token STOP to the very end. This is put in because the algorithm works better if the last token is identical. This is removed again in postprocessing.
-#
-# NB: step 6 and 7 is likely to convert some "_" inappropriately, e.g. in file
-# names or labels but it does not matter because they are converted back in the postprocessing step
-# Returns: leading white space removed in step 1
-sub preprocess {
- for (@_) {
-
-
- # change in \verb and similar commands - note that I introduce an extra space here so that the
- # already hashed variants do not trigger again
- # transform \lstinline{...}
-# s/\\lstinline(\[$brat0\])?(\{(?:.*?)\})/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg;
-# s/\\lstinline(\[$brat0\])?((\S).*?\2)/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg;
- s/\\lstinline((?:\[$brat_n\])?)(\{(?:.*?)\})/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg;
- s/\\lstinline((?:\[$brat_n\])?)(([^\s\w]).*?\3)/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg;
- s/\\(verb\*?|lstinline)([^\s\w])(.*?)\2/"\\DIF${1}{". tohash(\%verbhash,"${2}${3}${2}") ."}"/esg;
-
- # Change \{ to \QLEFTBRACE, \} to \QRIGHTBRACE, and \& to \AMPERSAND
- s/(?<!\\)\\\{/\\QLEFTBRACE /sg;
- s/(?<!\\)\\\}/\\QRIGHTBRACE /sg;
- s/(?<!\\)\\&/\\AMPERSAND /sg;
-# replace {,} in comments with \\CLEFTBRACE,\\CRIGHTBRACE
- 1 while s/((?<!\\)%.*)\{(.*)$/$1\\CLEFTBRACE $2/mg ;
- 1 while s/((?<!\\)%.*)\}(.*)$/$1\\CRIGHTBRACE $2/mg ;
- s/(?<!\\)\\%/\\PERCENTAGE /g ; # (?<! is negative lookbehind assertion to prevent \\% from being converted
- s/(?<!\\)\\\$/\\DOLLAR /g ; # (?<! is negative lookbehind assertion to prevent \\$ from being converted
- s/\\begin\{($VERBATIMENV)\}(.*?)\\end\{\1\}/"\\${1}{". tohash(\%verbhash,"${2}") . "}"/esg;
- s/\\begin\{($VERBATIMLINEENV)\}(.*?)\\end\{\1\}/"\\begin{$1}". linecomment($2) . "\\end{$1}"/esg;
-
- # mark all first empty line (in block of several) with \PAR tokens
- s/\n(\s*?)\n((?:\s*\n)*)/\n$1\\PAR\n$2/g ;
- # Convert _n or _\cmd into \SUBSCRIPTNB{n} or \SUBSCRIPTNB{\cmd} and _{nnn} into \SUBSCRIPT{nn}
- 1 while s/(?<!\\)_(\s*([^{\\\s]|\\\w+))/\\SUBSCRIPTNB{$1}/g ;
- 1 while s/(?<!\\)_(\s*{($pat_n)})/\\SUBSCRIPT$1/g ;
- # Convert ^n into \SUPERSCRIPTNB{n} and ^{nnn} into \SUPERSCRIPT{nn}
- 1 while s/(?<!\\)\^(\s*([^{\\\s]|\\\w+))/\\SUPERSCRIPTNB{$1}/g ;
- 1 while s/(?<!\\)\^(\s*{($pat_n)})/\\SUPERSCRIPT$1/g ;
- # Convert \sqrt{n} into \SQRT{n} and \sqrt nn into SQRTNB{nn}
- 1 while s/(?<!\\)\\sqrt(\s*([^{\\\s]|\\\w+))/\\SQRTNB{$1}/g ;
- 1 while s/(?<!\\)\\sqrt(\s*{($pat_n)})/\\SQRT$1/g ;
- # Convert $$ $$ into \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR}
- s/\$\$(.*?)\$\$/\\begin{DOLLARDOLLAR}$1\\end{DOLLARDOLLAR}/sg;
- # Convert \[ \] into \begin{SQUAREBRACKET} \end{SQUAREBRACKET}
- s/(?<!\\)\\\[/\\begin{SQUAREBRACKET}/sg;
- s/\\\]/\\end{SQUAREBRACKET}/sg;
- # Convert all picture environmentent (\begin{PICTUREENV} .. \end{PICTUREENV} \PICTUREBLOCKenv
- s/\\begin\{($PICTUREENV)}(.*?)\\end\{\1}/\\PICTUREBLOCK$1\{$2\}/sg;
- # For math-mode COARSE,WHOLE or NONE option -convert all \begin{MATH} .. \end{MATH}
- # into \MATHBLOCKMATH{...} commands, where MATH is any valid math environment
- # Also convert all array environments into ARRAYBLOCK environments
-
- if ( $mathmarkup != FINE ) {
- # DIFANCHORARRB and DIFANCHORARRE, DIFANCHORMATHB and DIFANCHORMATHE markers are inserted here to encourage the matching algorithm
- # to always match up the closing brace. Otherwise sometimes one ends up with a situation where
- # the closing brace is deleted and added at another point. The deleted closing brace is then
- # prevented by a %DIFDELCMD, leading to material leaking in or out of the math environment.
- # The anchors are removed in post-processing again. (note that they are simple text to cause least amount of complications
- # Admittedly, this is something of a hack and will not always work. If it does not, then one needs to
- # resort to WHOLE or FINE, or NONE math mode processing.
- s/\\begin\{($ARRENV)}(.*?)\\end\{\1}/\\ARRAYBLOCK$1\{$2\\DIFANCHORARRB \}\\DIFANCHORARRE /sg;
-
- take_comments_and_newline_from_frac();
-
- s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)\\end\{\1\}/\\MATHBLOCK$1\{$2\\DIFANCHORMATHB \}\\DIFANCHORMATHE /sg;
- }
-
- # add final token " STOP"
- $_ .= " STOP"
- }
-}
-
-
-# $expanded=linecomment($string)
-#preface all lines with verbatim marker (usually DIFVRB)
-sub linecomment {
- my @verbatimlines=split("\n",$_[0]);
- # the first line needs special treatment - we do want to retain optional arguments as is but wrap the remainder also with VERBCOMMENT
- ### print STDERR "DEBUG: before verbatimlines[0] = ",$verbatimlines[0],"\n";
- $verbatimlines[0]=~s/^((?:\s*\[$brat_n\])?\s*)([^\s\[].*)/ defined($2) ? ( "$1\%$VERBCOMMENT$2" ) : ( $1 )/e;
- ### print STDERR "DEBUG: after verbatimlines[0] = ",$verbatimlines[0],"\n";
- return(join("\n%$VERBCOMMENT",@verbatimlines)."\n");
-}
-
-# $simple=reverselinecomment($env $string)
-# remove DIFVRB comments but leave changed lines marked
-sub reverselinecomment {
- my ($environment, $verbatimtext)=@_;
- ###print STDERR "OLD VERBATIMTEXT: |$verbatimtext|\n";
- # remove markup added by latexdiff
- # (this should occur only if the type of verbatim environment was changed)
- # (note that this destroys some information in old file)
- # in theory I could save it by moving it out of the verbatim environment
- # but this requires more bookkeeping and is probably not necessary)
- $verbatimtext =~ s/\\DIFaddbegin //g;
- $verbatimtext =~ s/\\DIFaddend //g;
- $verbatimtext =~ s/\\DIFdelbegin //g;
- $verbatimtext =~ s/\\DIFdelend //g;
- $verbatimtext =~ s/$DELCMDOPEN.*//g;
-
- # remove DIFVRB mark
- $verbatimtext=~ s/%$VERBCOMMENT//g;
-
- # remove part of the markup in changed lines
- # if any of these substitution was made, then there was at least
- # one changed line, and we have to extend the style
- if ( $verbatimtext=~ s/$VERBCOMMENT//g ) {
- # in the next line we add ~alsolanguage~ modifier, but also deletes the rest of the line after the optional argument, as lstlisting commands gets sometimes
- # very confused by what is there (and othertimes seems to ignore this anyway)
- unless ( $verbatimtext =~ s/^(\s*)\[($brat_n)\](.*)\n/$1\[$2,alsolanguage=DIFcode\]\n/ ) {
- if ( $verbatimtext =~ m/^\s*\n/ ) {
- $verbatimtext = "[alsolanguage=DIFcode]" . $verbatimtext;
- } else {
- $verbatimtext = "[alsolanguage=DIFcode]\n" . $verbatimtext;
- }
- }
- # There is a bug in listings package (at least v1.5b) for empty comments where the actual comment command is not made invisible
- # I therefore have to introduce an artificial '-' character at the end of empty added or deleted lines
- $verbatimtext =~ s/($DELCOMMENT\s*)$/$1-/mg;
- $verbatimtext = "\\DIFmodbegin\n\\begin{${environment}}${verbatimtext}\\end{${environment}}\n\\DIFmodend"
- } else {
- $verbatimtext = "\\begin{${environment}}${verbatimtext}\\end{${environment}}"
- }
- ###print STDERR "NEW VERBATIMTEXT: |$verbatimtext|\n";
- return($verbatimtext);
-}
-
-
-#hashstring=tohash(\%hash,$string)
-# creates a hash value based on string and stores in %hash
-sub tohash {
- my ($hash,$string)=@_;
- my (@arr,$val);
- my ($sum,$i)=(0,1);
- my ($hstr);
-
- @arr=unpack('c*',$string);
-
- while (1) {
- foreach $val (@arr) {
- $sum += $i*$val;
- $i++;
- }
- $hstr= "$sum";
- last unless (defined($hash->{$hstr}) && $string ne $hash->{$hstr});
- # else found a duplicate HASH need to repeat for a higher hash value
- }
- $hash->{$hstr}=$string;
- ### print STDERR "Hash:$hstr: Content:$string:\n";
- return($hstr);
-}
-
-#string=fromhash(\%hash,$fromstring)
-# restores string value stored in hash
-#string=fromhash(\%hash,$fromstring,$prependstring)
-# additionally begins each line with prependstring
-sub fromhash {
- my ($hash,$hstr)=($_[0],$_[1]);
- my $retstr=$hash->{$hstr};
- if ( $#_ >= 2) {
- $retstr =~ s/^/$_[2]/mg;
- }
- return $retstr;
-}
-
-# writedebugfile(string, label)
-# if $debug set writes <string> to file latexdiff.debug.<label>
-# otherwise do nothing
-sub writedebugfile {
- my ($string,$label)=@_;
- if ( $debug ) {
- open(RAWDIFF,">","latexdiff.debug." . $label);
- print RAWDIFF $string;
- close(RAWDIFF);
- }
-}
-
-
-# postprocess($string, ..)
-# carry out the following post-processing steps for all arguments:
-# * Remove STOP token from the end
-# * Replace \RIGHTBRACE by }
-# * change citation commands within comments to protect from processing (using marker CITEDIF)
-# 1. Check all deleted blocks:
-# a.where a deleted block contains a matching \begin and
-# \end environment (these will be disabled by a %DIFDELCMD statements), for selected environments enable
-# these commands again (such that for example displayed math in a deleted equation
-# is properly within math mode. For math mode environments replace numbered equation
-# environments with their display only variety (so that equation numbers in new file and
-# diff file are identical). Where the correct type of math environment cannot be determined
-# use a place holder MATHMODE
-# b.where one of the commands matching $COUNTERCMD is used as a DIFAUXCMD, add a statement
-# subtracting one from the respective counter to keep numbering consistent with new file
-# Replace all MATHMODE environment commands by the correct environment to achieve matching
-# pairs
-# c. Convert MATHBLOCKmath commands to their uncounted numbers (e.g. convert equation -> displaymath
-# (environments defined in $MATHENV will be replaced by $MATHREPL, and environments in $MATHARRENV
-# will be replaced by $MATHARRREPL
-# d. If in-line math mode contains array environment, enclose the whole environment in \mbox'es
-# d. place \cite commands in mbox'es (for UNDERLINE style)
-#
-# For added blocks:
-# c. If in-line math mode contains array environment, enclose the whole environment in \mbox'es
-# d. place \cite commands in mbox'es (for UNDERLINE style)
-#
-# 2. If math-mode COARSE,WHOLE or NONE option set: Convert \MATHBLOCKmath{..} commands back to environments
-#
-# Convert all PICTUREblock{..} commands back to the appropriate environments
-# 3. Convert DIFadd, DIFdel, DIFaddbegin , ... into FL varieties
-# within floats (currently recognised float environments: plate,table,figure
-# plus starred varieties).
-# 4. Remove empty %DIFDELCMD < lines
-# 4. Convert \begin{SQUAREBRACKET} \end{SQUAREBRACKET} into \[ \]
-# Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$
-# 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn}
-# 6. Convert \SUBSCRIPTNB{n} into _n and \SUBCRIPT{nn} into _{nnn}
-# 7. Expand hashes of verb and verbatim environments
-# 8. Convert '\PERCENTAGE ' back into '\%' and '\DOLLAR ' into '\$'
-# 9.. remove all \PAR tokens
-# 10. package specific processing: endfloat: make sure \begin{figure} and \end{figure} are always
-# on a line by themselves, similarly for table environment
-# 4, undo renaming of the \begin, \end,{,} in comments
-# Change \QLEFTBRACE, \QRIGHTBRACE,\AMPERSAND to \{,\},\&
-#
-# Note have to manually synchronize substitution commands below and
-# DIF.. command names in the header
-sub postprocess {
- my ($begin,$len,$cnt,$float,$delblock,$addblock);
- # second level blocks
- my ($begin2,$cnt2,$len2,$eqarrayblock,$mathblock);
-
- my (@textparts,@newtextparts,@liststack,$listtype,$listlast);
-
- my (@itemargs, $itemarg);
-
-
- for (@_) {
- # change $'s in comments to something harmless
- 1 while s/(%.*)\$/$1DOLLARDIF/mg ;
-
- # Remove final STOP token
- s/ STOP$//;
- # Replace \RIGHTBRACE in comments by \MBLOCKRIGHTBRACE
- # the only way to get these is as %DIFDELCMD < \RIGHTBRACE construction
- # This essentially marks closing right braces of MATHBLOCK environments, which did not get matched
- # up. This case should be rare, so I just leave this in the diff file output. Not really elegant
- # but can still be dealt with later if it results in problems.
- s/%DIFDELCMD < \\RIGHTBRACE/%DIFDELCMD < \\MBLOCKRIGHTBRACE/g ;
- # Replace \RIGHTBRACE by }
- s/\\RIGHTBRACE/}/g;
-
- # Check all deleted blocks: where a deleted block contains a matching \begin and
- # \end environment (these will be disabled by a %DIFDELCMD statements), enable
- # these commands again (such that for example displayed math in a deleted equation
- # is properly within math mode). For math mode environments replace numbered equation
- # environments with their display only variety (so that equation numbers in new file and
- # diff file are identical)
-
- while ( m/\\DIFdelbegin.*?\\DIFdelend/sg ) {
- ### while ( m/\\DIFdelbegin.*?\\DIFdelend/sg ) {
- ### print STDERR "DEBUG Match delblock \n||||$&||||\n at ",pos,"\n";
- $cnt=0;
- $len=length($&);
- $begin=pos($_) - $len;
- $delblock=$&;
- ### A much simpler method for math replacement might follow this strategy (can recycle part of the commands below for following
- ### this strategy:
- ### 1. a Insert aux commands \begin{MATHMODE} or \end{MATHMODE} for all deleted commands opening or closing displayed math mode
- ### b Insert aux commands \begin{MATHARRMODE} or \end{MATHARRMODE} for all deleted commands opening or closing math array mode
- ### 2 Replace MATHMODE and MATHARRMODE by correct pairing if appropriate partner math command is found in text
- ### 3 a Replace remaining \begin{MATHMODE}...\end{MATHMODE} pairs with \begin{$MATHREPL}..\end{$MATHREPL}
- ### b Replace remaining \begin{MATHARRMODE}...\end{MATHARRMODE} pairs with \begin{$MATHREPL}..\end{$MATHREPL}
- ### 4 Delete all aux command math mode pairs which have simply comments or empty lines between them
- ### As written this won't actually work!
-
-
- ### Most general case: allow all included environments
- ### $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{(\w*\*?)\}\s*?\n)(.*?)(\%DIFDELCMD < \s*\\end\{\2\})/$1\\begin{$2}$AUXCMD\n$3\n\\end{$2}$AUXCMD\n$4/sg;
- ### (.*?[^\n]?)\n? construct is necessary to avoid empty lines in math mode, which result in
- ### an error
- # displayed math environments
- ###0.5: $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(\%DIFDELCMD < \s*\\end\{\2\})/\\begin{$MATHREPL}$AUXCMD\n$1$3\n\\end{$MATHREPL}$AUXCMD\n$4/sg;
- if ($mathmarkup == FINE ) {
- $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{((?:$MATHENV)|SQUAREBRACKET)\}.*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(\%DIFDELCMD < \s*\\end\{\2\})/\\begin{$MATHREPL}$AUXCMD\n$1$3\n\\end{$MATHREPL}$AUXCMD\n$4/sg;
- # also transform the opposite pair \end{displaymath} .. \begin{displaymath} but we have to be careful not to interfere with the results of the transformation in the line directly above
- ### pre-0.42 obsolete version which did not work on eqnarray test $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{($MATHENV)\}\s*?\n)(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/$1\\end{$MATHREPL}$AUXCMD\n$3\n\\begin{$MATHREPL}$AUXCMD\n$4/sg;
- ###0.5: $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg;
- $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}.*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/\\end\{MATHMODE\}$AUXCMD\n$1$3\n\\begin\{MATHMODE\}$AUXCMD\n$4/sg;
-
- # now look for unpaired %DIFDELCMD < \begin{MATHENV}; if found add \begin{$MATHREPL} and insert \end{$MATHREPL}
- # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted
- if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\begin{$MATHREPL}$AUXCMD\n/sg ) {
- $delblock =~ s/(\\DIFdelend$)/\\end{$MATHREPL}$AUXCMD\n$1/s ;
- }
- # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE}
- # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted
- if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end\{MATHMODE\}$AUXCMD\n/sg ) {
- $delblock =~ s/(\\DIFdelend$)/\\begin\{MATHMODE\}$AUXCMD\n$1/s ;
- }
-
-
- ### pre-0.42 # same as above for special case \[.\] (latex abbreviation for displaymath)
- ### pre-0.42 $delblock=~ s/(\%DIFDELCMD < \s*\\\[\s*?\n())(.*?[^\n]?)\n?(\%DIFDELCMD < \s*\\\])/$1\\\[$AUXCMD\n$3\n\\\]$AUXCMD\n$4/sg;
- ### pre-0.42 $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\\]\s*?\n())(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\\[)/$1\\\]$AUXCMD\n$3\n\\\[$AUXCMD\n$4/sg;
- # equation array environment
- ###pre-0.3 $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($MATHARRENV)\}\s*?\n)(.*?)(\%DIFDELCMD < \s*\\end\{\2\})/$1\\begin{$MATHARRREPL}$AUXCMD\n$3\n\\end{$MATHARRREPL}$AUXCMD\n$4/sg;
- ###0.5 $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(\%DIFDELCMD < \s*\\end\{\2\})/\\begin{$MATHARRREPL}$AUXCMD\n$1$3\n\\end{$MATHARRREPL}$AUXCMD\n$4/sg;
- $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($MATHARRENV)\}.*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(\%DIFDELCMD < \s*\\end\{\2\})/\\begin{$MATHARRREPL}$AUXCMD\n$1$3\n\\end{$MATHARRREPL}$AUXCMD\n$4/sg;
- ### pre-0.42 obsolete version which did not work on eqnarray test $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{($MATHARRENV)\}\s*?\n)(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/$1\\end{$MATHARRREPL}$AUXCMD\n$3\n\\begin{$MATHARRREPL}$AUXCMD\n$4/sg;
- $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg;
-
- # now look for unpaired %DIFDELCMD < \begin{MATHARRENV}; if found add \begin{$MATHARRREPL} and insert \end{$MATHARRREPL}
- # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted
- if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\begin{$MATHARRREPL}$AUXCMD\n/sg ) {
- $delblock =~ s/(\\DIFdelend$)/\\end{$MATHARRREPL}$AUXCMD\n$1/s ;
- }
- # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE}
- # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted
- if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end{MATHMODE}$AUXCMD\n/sg ) {
- $delblock =~ s/(\\DIFdelend$)/\\begin{MATHMODE}$AUXCMD\n$1/s ;
- }
-
- # parse $delblock for deleted and reinstated eqnarray* environments - within those reinstate \\ and & commands
- ### while ( $delblock =~ m/\\begin{$MATHARRREPL}$AUXCMD\n.*?\n\\end{$MATHARRREPL}$AUXCMD\n/sg ) {
- while ( $delblock =~ m/\\begin\Q{$MATHARRREPL}$AUXCMD\E\n.*?\n\\end\Q{$MATHARRREPL}$AUXCMD\E\n/sg ) {
- ### print STDERR "DEBUG Match eqarrayblock $& at ",pos,"\n";
- $cnt2=0;
- $len2=length($&);
- $begin2=pos($delblock) - $len2;
- $eqarrayblock=$&;
- # reinstate deleted & and \\ commands
- $eqarrayblock=~ s/(\%DIFDELCMD < \s*(\&|\\\\)\s*?(?:$DELCMDCLOSE|\n))/$1$2$AUXCMD\n/sg ;
-
- substr($delblock,$begin2,$len2)=$eqarrayblock;
- pos($delblock) = $begin2 + length($eqarrayblock);
- }
- } elsif ( $mathmarkup == COARSE || $mathmarkup == WHOLE ) {
- # Convert MATHBLOCKmath commands to their uncounted numbers (e.g. convert equation -> displaymath
- # (environments defined in $MATHENV will be replaced by $MATHREPL, and environments in $MATHARRENV
- # will be replaced by $MATHARRREPL
- $delblock=~ s/\\MATHBLOCK($MATHENV)\{($pat_n)\}/\\MATHBLOCK$MATHREPL\{$2\}/sg;
- $delblock=~ s/\\MATHBLOCK($MATHARRENV)\{($pat_n)\}/\\MATHBLOCK$MATHARRREPL\{$2\}/sg;
- }
- # Reinstate completely deleted list environments. note that items within the
- # environment will still be commented out. They will be restored later
- $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($LISTENV)\}\s*?(?:\n|$DELCMDCLOSE))(.*?)(\%DIFDELCMD < \s*\\end\{\2\})/{
- ### # block within the search; replacement environment
- ### "$1\\begin{$2}$AUXCMD\n". restore_item_commands($3). "\n\\end{$2}$AUXCMD\n$4";
- "$1\\begin{$2}$AUXCMD\n$3\n\\end{$2}$AUXCMD\n$4";
- }/esg;
-
- ### $delblock=~ s/\\begin\{$MATHENV}$AUXCMD/\\begin{$MATHREPL}$AUXCMD/g;
- ### $delblock=~ s/\\end\{$MATHENV}$AUXCMD/\\end{$MATHREPL}$AUXCMD/g;
- ### $delblock=~ s/\\begin\{$MATHARRENV}$AUXCMD/\\begin{$MATHARRREPL}$AUXCMD/g;
- ### $delblock=~ s/\\end\{$MATHARRENV}$AUXCMD/\\end{$MATHARRREPL}$AUXCMD/g;
-
- # b.where one of the commands matching $COUNTERCMD is used as a DIFAUXCMD, add a statement
- # subtracting one from the respective counter to keep numbering consistent with new file
- $delblock=~ s/\\($COUNTERCMD)((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*\s*${AUXCMD}\n)/\\$1$2\\addtocounter{$1}{-1}${AUXCMD}\n/sg ;
-
- # bb. disable active labels within deleted blocks (i.e. those not commented out) (as these are not safe commands, this should normally only
- # happen within deleted maths blocks
- ### $delblock=~ s/(?<!$DELCMDOPEN)(\\$LABELCMD(?:${extraspace})\{(?:[^{}])*\}[\t ]*)\n?/${DELCMDOPEN}$1${DELCMDCLOSE}/smg ;
- ### previous line caused trouble as by issue #90 I might need to modify this
- $delblock=~ s/^([^%]*)(\\$LABELCMD(?:${extraspace})\{(?:[^{}])*\}[\t ]*)\n?/$1${DELCMDOPEN}$2${DELCMDCLOSE}/smg ;
- ### print STDERR "<<<$delblock>>>\n" if $debug;
-
-
- # c. If in-line math mode contains array environment, enclose the whole environment in \mbox'es
- while ( $delblock =~ m/($math)(\s*)/sg ) {
- # print STDERR "DEBUG Delblock Match math $& at ",pos,"\n";
- $cnt2=0;
- $len2=length($&);
- $begin2=pos($delblock) - $len2;
- $mathblock="%\n\\mbox{$AUXCMD\n$1\n}$AUXCMD\n";
- next unless ( $mathblock =~ /ARRAYBLOCK/ or $mathblock =~ m/\{$ARRENV\}/ );
- substr($delblock,$begin2,$len2)=$mathblock;
- pos($delblock) = $begin2 + length($mathblock);
- }
- ### if ($CITE2CMD) {
- ###### ${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})) .*?%%%\n
- ### $delblock=~s/($DELCMDOPEN\s*\\($CITE2CMD)(.*)$DELCMDCLOSE)/
- ### # Replacement code
- ### {my ($aux,$all);
- ### $aux=$all=$1;
- ### $aux=~s#\n?($DELCMDOPEN|$DELCMDCLOSE)##g;
- ### $all."$aux$AUXCMD\n";}/sge;
- ### }
- ### # or protect \cite commands with \mbox
- ### if ($CITECMD) {
- ###### $delblock=~s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ;
- ### $delblock=~s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ;
- ### }
- # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox
- if ( $MBOXINLINEMATH ) {
- # note additional \newline after command is omitted from output if right at the end of deleted block (otherwise a spurious empty line is generated)
- $delblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg;
- }
- ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/)) {
- ### # change included verbatim environments
- ### $delblock =~ s/\\DIFverb\{/\\DIFDIFdelverb\{/g;
- ### $delblock =~ s/\\DIFlstinline/\\DIFDIFdellstinline/g;
- ###}
- # Mark deleted verbose commands
- $delblock =~ s/(${DELCMDOPEN}\\DIF((?:verb\*?|lstinline(?:\[$brat_n\])?)\{([-\d]*?)\}\s*).*)$/%\n\\DIFDIFdel$2${AUXCMD}\n$1/gm;
- if ( $CUSTOMDIFCMD ) {
- $delblock =~ s/(${DELCMDOPEN}.*)\\($CUSTOMDIFCMD)/$1${DELCMDCLOSE}\\DEL$2/gm;
- }
-
- # splice in modified delblock
- substr($_,$begin,$len)=$delblock;
- pos = $begin + length($delblock);
- }
- ###writedebugfile($_,'postprocess');
-
- ### print STDERR "<<<$_>>>\n" if $debug;
-
-
- # make the array modification in added blocks
- while ( m/\\DIFaddbegin.*?\\DIFaddend/sg ) {
- $cnt=0;
- $len=length($&);
- $begin=pos($_) - $len;
- $addblock=$&;
- while ( $addblock =~ m/($math)(\s*)/sg ) {
- $cnt2=0;
- $len2=length($&);
- $begin2=pos($addblock) - $len2;
- $mathblock="%\n\\mbox{$AUXCMD\n$1\n}$AUXCMD\n";
- next unless ( $mathblock =~ /ARRAYBLOCK/ or $mathblock =~ m/\{$ARRENV\}/) ;
- substr($addblock,$begin2,$len2)=$mathblock;
- pos($addblock) = $begin2 + length($mathblock);
- }
- # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox
- if ( $MBOXINLINEMATH ) {
- ##$addblock=~s/($math)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg;
- $addblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg;
- }
- ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) {
- # mark added verbatim commands
- $addblock =~ s/\\DIFverb/\\DIFDIFaddverb/g;
- $addblock =~ s/\\DIFlstinline/\\DIFDIFaddlstinline/g;
- if( $CUSTOMDIFCMD ) {
- $addblock =~ s/\\($CUSTOMDIFCMD)/\\ADD$1/g;
- }
- # markup the optional arguments of \item
- $addblock =~ s/(\\$ITEMCMD$extraspace(?:<$abrat0>)?$extraspace)\[($brat_n)\]/
- @itemargs=splitlatex(substr($2,0,length($2)));
- $itemarg="[".join("",marktags("","",$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,\@itemargs))."]";
- "$1$itemarg"/sge; # old substitution: $1\[$ADDOPEN$2$ADDCLOSE\]
- ###}
-# splice in modified addblock
- substr($_,$begin,$len)=$addblock;
- pos = $begin + length($addblock);
- }
-
- # Go through whole text, and by counting list environment commands, find out when we are within a list environment.
- # Within those restore deleted \item commands
- @textparts=split /(?<!$DELCMDOPEN)(\\(?:begin|end)\{$LISTENV\})/ ;
- @liststack=();
- @newtextparts=map {
- ### print STDERR ":::::::: $_\n";
- if ( ($listtype) = m/^\\begin\{($LISTENV)\}$/ ) {
- print STDERR "DEBUG: postprocess \\begin{$listtype}\n" if $debug;
- push @liststack,$listtype;
- } elsif ( ($listtype) = m/^\\end\{($LISTENV)\}$/ ) {
- print STDERR "DEBUG: postprocess \\end{$listtype}\n" if $debug;
- if (scalar @liststack > 0) {
- $listlast=pop(@liststack);
- ($listtype eq $listlast) or warn "Invalid nesting of list environments: $listlast environment closed by \\end{$listtype}.";
- } else {
- warn "WARNING: Invalid nesting of list environments: \\end{$listtype} encountered without matching \\begin{$listtype}.\n";
- }
- } else {
- print STDERR "DEBUG: postprocess \@liststack=(",join(",",@liststack),")\n" if $debug;
- if (scalar @liststack > 0 ) {
- # we are within a list environment and should replace all item commands
- $_=restore_item_commands($_);
- }
- # else: we are outside a list environment and do not need to do anything
- }
- $_ } @textparts; # end of map command
- # replace the main text with the modified version
- $_= join("",@newtextparts);
-
-
-
-
- # Replace MATHMODE environments from step 1a above by the correct Math environment
-
- # The next line is complicated. The negative look-ahead insertion makes sure that no \end{$MATHENV} (or other mathematical
- # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching
- # is not globally minimal but only 'locally' (matching is beginning from the left side of the string)
- if ( $mathmarkup == FINE ) {
- 1 while s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}((?:.(?!(?:\\end\{(?:(?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}|\\begin\{MATHMODE})))*?)\\end\{MATHMODE}/\\begin{$1}$2\\end{$1}/s;
- 1 while s/\\begin\{MATHMODE}((?:.(?!\\end\{MATHMODE}))*?)\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}/\\begin{$2}$1\\end{$2}/s;
- # convert remaining \begin{MATHMODE} \end{MATHMODE} (and not containing & or \\ )into MATHREPL environments
- s/\\begin\{MATHMODE\}((?:(.(?!(?<!\\)\&|\\\\))*)?)\\end\{MATHMODE\}/\\begin{$MATHREPL}$1\\end{$MATHREPL}/sg;
- # others into MATHARRREPL
- s/\\begin\{MATHMODE\}(.*?)\\end\{MATHMODE\}/\\begin{$MATHARRREPL}$1\\end{$MATHARRREPL}/sg;
-
- # now look for AUXCMD math-mode pairs which have only comments (or empty lines between them), and remove the added commands
- s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\end\{\1\}$AUXCMD\n/$2/sg;
- } else {
- # math modes OFF,WHOLE,COARSE: Convert \MATHBLOCKmath{..} commands back to environments
- s/\\MATHBLOCK($MATHENV|$MATHARRENV|SQUAREBRACKET)\{($pat_n)\}/\\begin{$1}$2\\end{$1}/sg;
- # convert ARRAYBLOCK.. commands back to environments
- s/\\ARRAYBLOCK($ARRENV)\{($pat_n)\}/\\begin{$1}$2\\end{$1}/sg;
- # get rid of the DIFANCHOR markers, first the delete comments, then everywhere
- s/%DIFDELCMD < \\DIFANCHOR(?:MATH|ARR)[BE] (?:\n%DIFDELCMD < )?%%%\n//g ;
- s/\\DIFANCHOR(?:MATH|ARR)[BE] //g;
- }
-
- # Convert all PICTUREblock{..} commands back to the appropriate environments
- s/\\PICTUREBLOCK($PICTUREENV)\{($pat_n)\}/\\begin{$1}$2\\end{$1}/sg;
-#0.5: # Remove all mark up within picture environments
-# while ( m/\\begin\{($PICTUREENV)\}.*?\\end\{\1\}/sg ) {
-# $cnt=0;
-# $len=length($&);
-# $begin=pos($_) - $len;
-# $float=$&;
-# $float =~ s/\\DIFaddbegin //g;
-# $float =~ s/\\DIFaddend //g;
-# $float =~ s/\\DIFadd\{($pat_n)\}/$1/g;
-# $float =~ s/\\DIFdelbegin //g;
-# $float =~ s/\\DIFdelend //g;
-# $float =~ s/\\DIFdel\{($pat_n)\}//g;
-# $float =~ s/$DELCMDOPEN.*//g;
-# substr($_,$begin,$len)=$float;
-# pos = $begin + length($float);
-# }
- # Convert DIFadd, DIFdel, DIFFaddbegin , ... into varieties
- # within floats (currently recognised float environments: plate,table,figure
- # plus starred varieties).
- while ( m/\\begin\{($FLOATENV)\}.*?\\end\{\1\}/sg ) {
- $cnt=0;
- $len=length($&);
- $begin=pos($_) - $len;
- $float=$&;
- $float =~ s/\\DIFaddbegin /\\DIFaddbeginFL /g;
- $float =~ s/\\DIFaddend /\\DIFaddendFL /g;
- $float =~ s/\\DIFadd\{/\\DIFaddFL{/g;
- $float =~ s/\\DIFdelbegin /\\DIFdelbeginFL /g;
- $float =~ s/\\DIFdelend /\\DIFdelendFL /g;
- $float =~ s/\\DIFdel\{/\\DIFdelFL{/g;
- substr($_,$begin,$len)=$float;
- pos = $begin + length($float);
- }
- ### former location of undo renaming of \begin and \end in comments
-
- # remove empty DIFCMD < lines
- s/^\Q${DELCMDOPEN}\E\n//msg;
-
- # Expand hashes of verb and verbatim environments (note negative look behind assertion to not leak out of DIFDELCMD comments
- s/${DELCMDOPEN}\\($VERBATIMENV)\{([-\d]*?)\}/"${DELCMDOPEN}\\begin{${1}}".fromhash(\%verbhash,$2,$DELCMDOPEN)."${DELCMDOPEN}\\end{${1}}"/esg;
- # revert changes to verbatim environments for line diffs (and add code to mark up changes)
- s/(?<!$DELCMDOPEN)\\begin\{($VERBATIMLINEENV)\}(.*?)\\end\{\1\}/"". reverselinecomment($1, $2) .""/esg;
-# # we do the same for deleted environments but additionally reinstate the framing commands
-# s/$DELCMDOPEN\\begin\{($VERBATIMLINEENV)\}$extraspace(?:\[$brat0\])?$DELCMDCLOSE(.*?)$DELCMDOPEN\\end\{\1\}$DELCMDCLOSE/"\\begin{$1}". reverselinecomment($2) . "\\end{$1}"/esg;
-## s/$DELCMDOPEN\\begin\{($VERBATIMLINEENV)\}($extraspace(?:\[$brat0\])?\s*)(?:\n|$DELCMDOPEN)*$DELCMDCLOSE((?:\%$DELCOMMENT$VERBCOMMENT.*?\n)*)($DELCMDOPEN\\end\{\1\}(?:\n|\s|$DELCMDOPEN)*$DELCMDCLOSE)/"SUBSTITUTION: \\begin{$1}$2 INTERIOR: |$3| END: |$4|"/esg;
- s/ # Deleted \begin command of verbatim environment (Captures $1: whole deleted command, $2: environment, $3: optional arguments with white space
- (\Q$DELCMDOPEN\E\\begin\{($VERBATIMLINEENV)\}(\Q$extraspace\E(?:\[$brat_n\])?\s*)(?:\n|\Q$DELCMDOPEN\E)*\Q$DELCMDCLOSE\E)
- # Interior of deleted verbatim environment should consist entirely of delete DIFVRB comments, i.e. match only lines beginning with % DIF < DIFVRB
- # Captures: $4: all lines combined
- ((?:\%\Q$DELCOMMENT$VERBCOMMENT\E[^\n]*?\n)*)
- # Deleted \end command of verbatim environment. Note that the type is forced to match the opening. Captures: $5: Whole deleted environment (previous way this line was written: (\Q$DELCMDOPEN\E\\end\{\2\}(?:\n|\s|\Q$DELCMDOPEN\E)*\Q$DELCMDCLOSE\E)
- (\Q$DELCMDOPEN\E\\end\{\2\})
- / # Substitution part
- $1 # Leave expression as is
- . "$AUXCMD NEXT\n" # Mark the following line as an auxiliary command
- . "" # reinstate the original environment without options
- . reverselinecomment($2, "$3$4") # modify the body to change the markup; reverselinecomment parses for options
- . " $AUXCMD\n" # close the auxiliary environment
- . $5 # and again leave the original deleted closing environment as is
- /esgx; # Modifiers of substitution command
- # where changes have occurred in verbatim environment, change verbatim to DIFverbatim to allow mark-up
- # (I use the presence of optional paramater to verbatim environment as the marker - normal verbatim
- # environment does not take optional arguments)
- s/(?<!$DELCMDOPEN)\\begin\{(verbatim[*]?)\}(\[$brat_n\].*?)\\end\{\1\}/\\begin{DIF$1}$2\\end{DIF$1}/sg;
-
- s/\\($VERBATIMENV)\{([-\d]*?)\}/"\\begin{${1}}".fromhash(\%verbhash,$2)."\\end{${1}}"/esg;
-
-
- # remove all \PAR tokens (taking care to properly keep commented out PAR's
- # from introducing uncommented newlines - next line)
- s/(%DIF < )([^\n]*?)\\PAR\n/$1$2\n$1\n/sg;
- # convert PAR commands which are on a line by themselves
- s/\n(\s*?)\\PAR\n/\n\n/sg;
- # convert remaining PAR commands (which are preceded by non-white space characters, usually "}" ($ADDCLOSE)
- s/\\PAR\n/\n\n/sg;
-
- # package specific processing:
- if ( defined($packages{"endfloat"})) {
- #endfloat: make sure \begin{figure} and \end{figure} are always
- # on a line by themselves, similarly for table environment
- print STDERR "endfloat package detected.\n" if $verbose ;
- # eliminate whitespace before and after
- s/^(\s*)(\\(?:end|begin)\{(?:figure|table)\})(\s*?)$/$2/mg;
- # split lines with remaining characters before float environment conmmand
- s/^([^%]+)(\\(?:begin|end)\{(?:figure|table)\})/$1\n$2/mg;
- # split lines with remaining characters after float environment conmmand
- s/^((?:[^%]+)\\(?:begin|end)\{(?:figure|table)\}(?:\[[a-zA-Z]+\])?)(.+)((?:%.*)?)$/$1\n$2$3/mg;
- }
-
- # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated
- s/\\PERCENTAGE ?/\\%/g;
- # Convert '\DOLLAR ' back into '\$'
- s/\\DOLLAR /\\\$/g;
-
- # undo renaming of the \begin and \end,{,} and dollars in comments
-
- # although we only renamed $ in comments to DOLLARDIFF, we might have lost the % in unchanged verbatim blocks, so rename all
- s/DOLLARDIF/\$/g;
-# Convert \begin{SQUAREBRACKET} \end{SQUAREBRACKET} into \[ \]
- s/\\end\{SQUAREBRACKET\}/\\\]/sg;
- s/\\begin\{SQUAREBRACKET\}/\\\[/sg;
-# 4. Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$
- s/\\begin\{DOLLARDOLLAR\}(.*?)\\end\{DOLLARDOLLAR\}/\$\$$1\$\$/sg;
-# 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn}
- 1 while s/\\SUPERSCRIPT(\s*\{($pat_n)\})/^$1/g ;
- 1 while s/\\SUPERSCRIPTNB\{(\s*$pat0)\}/^$1/g ;
- # Convert \SUBSCRIPNB{n} into _n and \SUBCRIPT{nn} into _{nnn}
- 1 while s/\\SUBSCRIPT(\s*\{($pat_n)\})/_$1/g ;
- 1 while s/\\SUBSCRIPTNB\{(\s*$pat0)\}/_$1/g ;
- # Convert \SQRT{n} into \sqrt{n} and \SQRTNB{nn} into \sqrt nn
- 1 while s/\\SQRT(\s*\{($pat_n)\})/\\sqrt$1/g ;
- 1 while s/\\SQRTNB\{(\s*$pat0)\}/\\sqrt$1/g ;
-
- 1 while s/(%.*)\\CRIGHTBRACE (.*)$/$1\}$2/mg ;
- 1 while s/(%.*)\\CLEFTBRACE (.*)$/$1\{$2/mg ;
-
-
-# Change \QLEFTBRACE, \QRIGHTBRACE to \{,\}
- s/\\QLEFTBRACE /\\\{/sg;
- s/\\QRIGHTBRACE /\\\}/sg;
- s/\\AMPERSAND /\\&/sg;
- # Highligh added inline verbatim commands if possible
- if ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) {
- # wrap added verb commands with color commands
- s/\\DIFDIFadd((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*)/\{\\color{blue}$AUXCMD\n\\DIF$1%\n\}$AUXCMD\n/sg;
- s/\\DIFDIFdel((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*$AUXCMD)/\{\\color{red}${AUXCMD}\n\\DIF$1\n\}${AUXCMD}/sg;
- } else {
- # currently if colour markup is not used just remove the added mark
- s/\\DIFDIFadd(verb\*?|lstinline)/\\DIF$1/sg;
- s/\\DIFDIFdel((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*$AUXCMD\n)//sg;
- }
- # expand \verb and friends inline arguments
- s/\\DIF((?:DIFadd|DIFdel)?(?:verb\*?|lstinline(?:\[$brat_n\])?))\{([-\d]*?)\}/"\\${1}". fromhash(\%verbhash,$2)/esg;
- # add basicstyle color{blue} to added lstinline commands
- # finally add the comment to the ones not having an optional argument before
- ###s/\\DIFaddlstinline(?!\[)/\\lstinline\n[basicstyle=\\color{blue}]$AUXCMD\n/g;
-
- return;
- }
-}
-
-# $out = restore_item_commands($listenviron)
-# short helper function for post-process, which restores deleted \item commands in its argument (as DIFAUXCMDs)
-sub restore_item_commands {
- my ($string)=@_ ;
- my ($itemarg,@itemargs);
- $string =~ s/(\%DIFDELCMD < \s*(\\$ITEMCMD$extraspace)((?:<$abrat0>)?$extraspace)((?:\[$brat_n\])?)\s*((?:${cmdoptseq}\s*?)*)(?:\n|$DELCMDCLOSE))/
- # if \item has an []argument, then mark up the argument as deleted)
- if (length($4)>0) {
- # use substr to exclude square brackets at end points
- @itemargs=splitlatex(substr($4,1,length($4)-2));
- $itemarg="[".join("",marktags("","",$DELOPEN,$DELCLOSE,$DELCMDOPEN,$DELCMDCLOSE,$DELCOMMENT,\@itemargs))."]";
- } else {
- $itemarg="";
- }
- "$1$2$3$itemarg$AUXCMD\n"; ###.((length($5)>0) ? "%DIFDELCMD $5 $DELCMDCLOSE\n" : "")
- /sge;
- return($string);
-}
-
-
-# @auxlines=preprocess_preamble($oldpreamble,$newpreamble);
- # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands)
- # the list of commands is defined in CONTEXT2CMD
- # if found then use a bodydiff to mark up content, and replace the corresponding commands
- # in both preambles by marked up version to 'fool' the linediff (such that only body is marked up).
- # A special case are e.g. author commands being added (or removed)
- # 1. If commands are added, then the entire content is marked up as new, but also the lines are marked as new in the linediff
- # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns
- # with $auxlines a text to be appended at the end of the preamble, which shows the respective fields as deleted
-sub preprocess_preamble {
- my ($oldpreambleref,$newpreambleref)=(\$_[0],\$_[1]) ;
- my @auxlines=();
- # Remember to use $$oldpreambleref to refer to oldpreamble
- my ($titlecmd,$titlecmdpat);
- my (@oldtitlecommands,@newtitlecommands );
- my %oldhash = ();
- my %newhash = ();
- my ($line,$cmd,$optarg,$arg,$optargnew,$optargold,$optargdiff,$argold,$argnew,$argdiff,$auxline);
-
- my $warnmsgdetail = <<EOF ;
- This should not occur for standard styles, but can occur for some specifiy styles, document classes,
- e.g. journal house styles.
- Workaround: Use --replace-context2cmd option to specifically set those commands, which are not repeated.
-EOF
-
- # resuse context2cmdlist to define these commands to look out for in preamble
- $titlecmd = "(?:".join("|",@CONTEXT2CMDLIST).")";
- # as context2cmdlist is stored as regex, e.g. ((?-xism:^title$), we need to remove ^- fo
- # resue in a more complex regex
- $titlecmd =~ s/[\$\^]//g;
- # make sure to not match on comment lines:
- $titlecmdpat=qr/^(?:[^%\n]|\\%)*(\\($titlecmd)$extraspace(?:\[($brat_n)\])?(?:\{($pat_n)\}))/ms;
- ###print STDERR "DEBUG:",$titlecmdpat,"\n";
- @oldtitlecommands= ( $$oldpreambleref =~ m/$titlecmdpat/g );
- @newtitlecommands= ( $$newpreambleref =~ m/$titlecmdpat/g );
-
-
- while ( @oldtitlecommands ) {
- $line=shift @oldtitlecommands;
- $cmd=shift @oldtitlecommands;
- $optarg=shift @oldtitlecommands;
- $arg=shift @oldtitlecommands;
-
- if ( defined($oldhash{$cmd})) {
- warn "WARNING: $cmd is used twice in preamble of old file. Reverting to pure line diff mode for preamble.\n";
- print STDERR $warnmsgdetail;
- return;
- }
- $oldhash{$cmd}=[ $line, $optarg, $arg ];
- }
- while ( @newtitlecommands ) {
- $line=shift @newtitlecommands;
- $cmd=shift @newtitlecommands;
- $optarg=shift @newtitlecommands;
- $arg=shift @newtitlecommands;
-
- if ( defined($newhash{$cmd})) {
- warn "$cmd is used twice in preamble of new file. Reverting to pure line diff mode for preamble.\n";
- print STDERR $warnmsgdetail;
- return;
- }
- $newhash{$cmd}=[ $line, $optarg, $arg ];
- }
- foreach $cmd ( keys %newhash ) {
- if ( defined($newhash{$cmd}->[1])) {
- $optargnew=$newhash{$cmd}->[1];
- } else {
- $optargnew="";
- }
- if ( defined($oldhash{$cmd}->[1])) {
- $optargold=$oldhash{$cmd}->[1];
- } else {
- $optargold="";
- }
-
- if ( defined($oldhash{$cmd}->[2]) ) {
- $argold=$oldhash{$cmd}->[2];
- } else {
- $argold="";
- }
- $argnew=$newhash{$cmd}->[2];
- $argdiff="{" . join("",bodydiff($argold,$argnew)) ."}";
- # Replace \RIGHTBRACE by }
- $argdiff =~ s/\\RIGHTBRACE/}/g;
-
- if ( length $optargnew ) {
- $optargdiff="[".join("",bodydiff($optargold,$optargnew))."]" ;
- $optargdiff =~ s/\\DIFaddbegin /\\DIFaddbeginFL /g;
- $optargdiff =~ s/\\DIFaddend /\\DIFaddendFL /g;
- $optargdiff =~ s/\\DIFadd\{/\\DIFaddFL{/g;
- $optargdiff =~ s/\\DIFdelbegin /\\DIFdelbeginFL /g;
- $optargdiff =~ s/\\DIFdelend /\\DIFdelendFL /g;
- $optargdiff =~ s/\\DIFdel\{/\\DIFdelFL{/g;
- } else {
- $optargdiff="";
- }
- ### print STDERR "DEBUG s/\\Q$newhash{$cmd}->[0]\\E/\\$cmd$optargdiff$argdiff/s\n";
- # Note: \Q and \E force literal interpretation of what it between them but allow
- # variable interpolation, such that e.g. \title matches just that and not TAB-itle
- $$newpreambleref=~s/\Q$newhash{$cmd}->[0]\E/\\$cmd$optargdiff$argdiff/s;
- # replace this in old preamble if necessary
- if ( defined($oldhash{$cmd}->[0])) {
- $$oldpreambleref=~s/\Q$oldhash{$cmd}->[0]\E/\\$cmd$optargdiff$argdiff/s ;
- }
- ### print STDERR "DEBUG NEW PRE ".$$newpreambleref."\n";
- }
-
- foreach $cmd ( keys %oldhash ) {
- # if this has already been dealt with above can just skip
- next if defined($newhash{$cmd}) ;
- $argold=$oldhash{$cmd}->[2];
- $argdiff="{" . join("",bodydiff($argold,"")) ."}";
- if ( defined($oldhash{$cmd}->[1])) {
- $optargold=$oldhash{$cmd}->[1];
- $optargdiff="[".join("",bodydiff($optargold,""))."]" ;
- $optargdiff =~ s/\\DIFdelbegin /\\DIFdelbeginFL /g;
- $optargdiff =~ s/\\DIFdelend /\\DIFdelendFL /g;
- $optargdiff =~ s/\\DIFdel\{/\\DIFdelFL{/g;
- } else {
- $optargdiff="";
- }
- $auxline = "\\$cmd$optargdiff$argdiff";
- $auxline =~s/$/$AUXCMD/sg;
- push @auxlines,$auxline;
- }
- # add auxcmd comment to highlight added lines
- return(@auxlines);
-}
-
-
-
-# @diffs=linediff(\@seq1, \@seq2)
-# mark up lines like this
-#%DIF mm-mmdnn
-#%< old deleted line(s)
-#%DIF -------
-#%DIF mmann-nn
-#new appended line %<
-#%DIF -------
-# Future extension: mark change explicitly
-# Assumes: traverse_sequence traverses deletions before insertions in changed sequences
-# all line numbers relative to line 0 (first line of real file)
-sub linediff {
- my $seq1 = shift ;
- my $seq2 = shift ;
-
- my $block = [];
- my $retseq = [];
- my @begin=('','',''); # dummy initialisation
- my $instring ;
-
- my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ;
- push(@$block, "%DIF < " . $seq1->[$_[0]]) };
- my $add = sub { if (! scalar @$block) {
- @begin=('a',$_[0],$_[1]) ;}
- elsif ( $begin[0] eq 'd' ) {
- $begin[0]='c'; $begin[2]=$_[1];
- push(@$block, "%DIF -------") }
- push(@$block, $seq2->[$_[1]] . " %DIF > " ) };
- my $match = sub { if ( scalar @$block ) {
- if ( $begin[0] eq 'd' && $begin[1]!=$_[0]-1) {
- $instring = sprintf "%%DIF %d-%dd%d",$begin[1],$_[0]-1,$begin[2]; }
- elsif ( $begin[0] eq 'a' && $begin[2]!=$_[1]-1) {
- $instring = sprintf "%%DIF %da%d-%d",$begin[1],$begin[2],$_[1]-1; }
- elsif ( $begin[0] eq 'c' ) {
- $instring = sprintf "%%DIF %sc%s",
- ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) ,
- ($begin[2]==$_[1]-1) ? "$begin[2]" : $begin[2]."-".($_[1]-1) ; }
- else {
- $instring = sprintf "%%DIF %d%s%d",$begin[1],$begin[0],$begin[2]; }
- push @$retseq, $instring,@$block, "%DIF -------" ;
- $block = [];
- }
- push @$retseq, $seq2->[$_[1]]
- };
- # key function: remove multiple spaces (such that insertion or deletion of redundant white space is not reported)
- my $keyfunc = sub { join(" ",split(" ",shift())) };
-
- traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc );
- push @$retseq, @$block if scalar @$block;
-
- return wantarray ? @$retseq : $retseq ;
-}
-
-
-
-# init_regex_arr_data(\@array,"TOKEN INIT")
-# scans DATA file handel for line "%% TOKEN INIT" line
-# then appends each line not beginning with % into array (as a quoted regex)
-# This is used for command lists and configuration variables, but the processing is slightly
-# different:
-# For lists, the regular expression is extended to include beginning (^) and end ($) markers, to require full-string matching
-# For configuration variables (and all others), simply an unadorned list is copied
-sub init_regex_arr_data {
- my ($arr,$token)=@_;
- my $copy=0;
- my ($mode);
- if ($token =~ m/COMMANDS/ ) {
- $mode=0; # Reading command list
- } else {
- $mode=1; # Reading configuration variables
- }
-
- while (<DATA>) {
- if ( m/^%%BEGIN $token\s*$/ ) {
- $copy=1;
- next;
- } elsif ( m/^%%END $token\s*$/ ) {
- last; }
- chomp;
- if ( $mode==0 ) {
-# print STDERR "DEBUG init_regex_arr_data regex >$_<\n" if ($debug && $copy);
- push (@$arr,qr/^$_$/) if ( $copy && !/^%/ ) ;
- } elsif ($mode==1) {
- push (@$arr,"$_") if ( $copy && !/^%/ ) ;
- }
- }
- seek DATA,0,0; # rewind DATA handle to file begin
-}
-
-
-# init_regex_arr_ext(\@array,$arg)
-# appends array with regular expressions.
-# if arg is a file name, then read in list of regular expressions from that file
-# (one expression per line)
-# Otherwise treat arg as a comma separated list of regular expressions
-sub init_regex_arr_ext {
- my ($arr,$arg)=@_;
- if ( -f $arg ) {
- init_regex_arr_file($arr,$arg);
- } else {
- init_regex_arr_list($arr,$arg);
- }
-}
-
-# init_regex_arr_file(\@array,$fname)
-# appends array with regular expressions.
-# Read in list of regular expressions from $fname
-# (one expression per line)
-sub init_regex_arr_file {
- my ($arr,$fname)=@_;
- open(FILE,"$fname") or die ("Couldn't open $fname: $!");
- while (<FILE>) {
- chomp;
- next if /^\s*#/ || /^\s*%/ || /^\s*$/ ;
- push (@$arr,qr/^$_$/);
- }
- close(FILE);
-}
-
-# init_regex_arr_list(\@array,$arg)
-# appends array with regular expressions.
-# read from comma separated list of regular expressions ($arg)
-sub init_regex_arr_list {
- my ($arr,$arg)=@_;
- my $regex;
- ### print STDERR "DEBUG init_regex_arr_list arg >$arg<\n" if $debug;
- foreach $regex (split(qr/(?<!\\),/,$arg)) {
- $regex =~ s/\\,/,/g;
- print STDERR "DEBUG init_regex_arr_list regex >$regex<\n" if $debug;
- push (@$arr,qr/^$regex$/);
- }
-}
-
-
-#exetime() returns time since last execution of this command
-#exetime(1) resets this time
-my $lasttime=-1; # global variable for persistence
-sub exetime {
- my $reset=0;
- my $retval;
- if ((scalar @_) >=1) {
- $reset=shift;
- }
- if ($reset) {
- $lasttime=times();
- }
- else {
- $retval=times()-$lasttime;
- $lasttime=$lasttime+$retval;
- return($retval);
- }
-}
-
-
-sub usage {
- die <<"EOF";
-Usage: $0 [options] old.tex new.tex > diff.tex
-
-Compares two latex files and writes tex code to stdout, which has the same format as new.tex but
-has all changes relative to old.tex marked up or commented. Note that old.tex and new.tex need to
-be real files (not pipes or similar) as they are opened twice.
-
---type=markupstyle
--t markupstyle Add code to preamble for selected markup style
- Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE
- CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT
- [ Default: UNDERLINE ]
-
---subtype=markstyle
--s markstyle Add code to preamble for selected style for bracketing
- commands (e.g. to mark changes in margin)
- Available styles: SAFE MARGIN DVIPSCOL COLOR ZLABEL ONLYCHANGEDPAGE (LABEL)*
- [ Default: SAFE ]
- * LABEL subtype is deprecated
-
---floattype=markstyle
--f markstyle Add code to preamble for selected style which
- replace standard marking and markup commands within floats
- (e.g., marginal remarks cause an error within floats
- so marginal marking can be disabled thus)
- Available styles: FLOATSAFE IDENTICAL
- [ Default: FLOATSAFE ]
-
---encoding=enc
--e enc Specify encoding of old.tex and new.tex. Typical encodings are
- ascii, utf8, latin1, latin9. A list of available encodings can be
- obtained by executing
- perl -MEncode -e 'print join ("\\n",Encode->encodings( ":all" )) ;'
- [Default encoding is utf8 unless the first few lines of the preamble contain
- an invocation "\\usepackage[..]{inputenc} in which case the
- encoding chosen by this command is asssumed. Note that ASCII (standard
- latex) is a subset of utf8]
-
---preamble=file
--p file Insert file at end of preamble instead of auto-generating
- preamble. The preamble must define the following commands
- \\DIFaddbegin,\\DIFaddend,\\DIFadd{..},
- \\DIFdelbegin,\\DIFdelend,\\DIFdel{..},
- and varieties for use within floats
- \\DIFaddbeginFL,\\DIFaddendFL,\\DIFaddFL{..},
- \\DIFdelbeginFL,\\DIFdelendFL,\\DIFdelFL{..}
- (If this option is set -t, -s, and -f options
- are ignored.)
-
---exclude-safecmd=exclude-file
---exclude-safecmd="cmd1,cmd2,..."
--A exclude-file
---replace-safecmd=replace-file
---append-safecmd=append-file
---append-safecmd="cmd1,cmd2,..."
--a append-file Exclude from, replace or append to the list of regex
- matching commands which are safe to use within the
- scope of a \\DIFadd or \\DIFdel command. The file must contain
- one Perl-RegEx per line (Comment lines beginning with # or % are
- ignored). A literal comma within the comma-separated list must be
- escaped thus "\\,", Note that the RegEx needs to match the whole of
- the token, i.e., /^regex\$/ is implied and that the initial
- "\\" of the command is not included. The --exclude-safecmd
- and --append-safecmd options can be combined with the --replace-safecmd
- option and can be used repeatedly to add cumulatively to the lists.
-
---exclude-textcmd=exclude-file
---exclude-textcmd="cmd1,cmd2,..."
--X exclude-file
---replace-textcmd=replace-file
---append-textcmd=append-file
---append-textcmd="cmd1,cmd2,..."
--x append-file Exclude from, replace or append to the list of regex
- matching commands whose last argument is text. See
- entry for --exclude-safecmd directly above for further details.
-
---replace-context1cmd=replace-file
---append-context1cmd=append-file
---append-context1cmd="cmd1,cmd2,..."
- Replace or append to the list of regex matching commands
- whose last argument is text but which require a particular
- context to work, e.g. \\caption will only work within a figure
- or table. These commands behave like text commands, except when
- they occur in a deleted section, when they are disabled, but their
- argument is shown as deleted text.
-
---replace-context2cmd=replace-file
---append-context2cmd=append-file
---append-context2cmd="cmd1,cmd2,..."
- As corresponding commands for context1. The only difference is that
- context2 commands are completely disabled in deleted sections, including
- their arguments.
- context2 commands are also the only commands in the preamble, whose argument will
- be processed in word-by-word mode (which only works, if they occur no more than
- once in the preamble).
-
---exclude-mboxsafecmd=exclude-file
---exclude-mboxsafecmd="cmd1,cmd2,..."
---append-mboxsafecmd=append-file
---append-mboxsafecmd="cmd1,cmd2,..."
- Define safe commands, which additionally need to be protected by encapsulating
- in an \\mbox{..}. This is sometimes needed to get around incompatibilities
- between external packages and the ulem package, which is used for highlighting
- in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE
-
-
-
---config var1=val1,var2=val2,...
--c var1=val1,.. Set configuration variables.
--c configfile Available variables:
- ARRENV (RegEx)
- COUNTERCMD (RegEx)
- FLOATENV (RegEx)
- ITEMCMD (RegEx)
- LISTENV (RegEx)
- MATHARRENV (RegEx)
- MATHARRREPL (String)
- MATHENV (RegEx)
- MATHREPL (String)
- MINWORDSBLOCK (Integer)
- PICTUREENV (RegEx)
- SCALEDELGRAPHICS (Float)
- VERBATIMENV (RegEx)
- VERBATIMLINEENV (RegEx)
- CUSTOMDIFCMD (RegEx)
- This option can be repeated.
-
---add-to-config varenv1=pattern1,varenv2=pattern2
- For configuration variables containing a regular expression (essentially those ending
- in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration
- variables. Instead of setting the complete pattern, with this option it is possible to add an
- alternative pattern. varenv must be one of the variables listed above that take a regular
- expression as argument, and pattern is any regular expression (which might need to be
- protected from the shell by quotation). Several patterns can be added at once by using semi-colons
- to separate them, e.g. --add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote"
-
---packages=pkg1,pkg2,..
- Tell latexdiff that .tex file is processed with the packages in list
- loaded. This is normally not necessary if the .tex file includes the
- preamble, as the preamble is automatically scanned for \\usepackage commands.
- Use of the --packages option disables automatic scanning, so if for any
- reason package specific parsing needs to be switched off, use --packages=none.
- The following packages trigger special behaviour:
- endfloat hyperref amsmath apacite siunitx cleveref glossaries mhchem chemformula/chemmacros
- biblatex
- [ Default: scan the preamble for \\usepackage commands to determine
- loaded packages.]
-
---show-preamble Print generated or included preamble commands to stdout.
-
---show-safecmd Print list of regex matching and excluding safe commands.
-
---show-textcmd Print list of regex matching and excluding commands with text argument.
-
---show-config Show values of configuration variables
-
---show-all Show all of the above
-
- NB For all --show commands, no old.tex or new.tex file needs to be given, and no
- differencing takes place.
-
-Other configuration options:
-
---allow-spaces Allow spaces between bracketed or braced arguments to commands
- [Default requires arguments to directly follow each other without
- intervening spaces]
-
---math-markup=level Determine granularity of markup in displayed math environments:
- Possible values for level are (both numerical and text labels are acceptable):
- off or 0: suppress markup for math environments. Deleted equations will not
- appear in diff file. This mode can be used if all the other modes
- cause invalid latex code.
- whole or 1: Differencing on the level of whole equations. Even trivial changes
- to equations cause the whole equation to be marked changed. This
- mode can be used if processing in coarse or fine mode results in
- invalid latex code.
- coarse or 2: Detect changes within equations marked up with a coarse
- granularity; changes in equation type (e.g.displaymath to equation)
- appear as a change to the complete equation. This mode is recommended
- for situations where the content and order of some equations are still
- being changed. [Default]
- fine or 3: Detect small change in equations and mark up and fine granularity.
- This mode is most suitable, if only minor changes to equations are
- expected, e.g. correction of typos.
-
---graphics-markup=level Change highlight style for graphics embedded with \\includegraphics commands
- Possible values for level:
- none,off or 0: no highlighting for figures
- new-only or 1: surround newly added or changed figures with a blue frame [Default]
- both or 2: highlight new figures with a blue frame and show deleted figures
- at reduced scale, and crossed out with a red diagonal cross. Use configuration
- variable SCALEDELGRAPHICS to set size of deleted figures.
- Note that changes to the optional parameters will make the figure appear as changed
- to latexdiff, and this figure will thus be highlighted.
-
---disable-citation-markup
---disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles
- using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR)
- (the two options are identical and are simply aliases)
-
---enable-citation-markup
---enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections
- with \\mbox command, i.e. use default behaviour for ulem package for other packages
- (the two options are identical and are simply aliases)
-
-Miscelleneous options
-
---label=label
--L label Sets the labels used to describe the old and new files. The first use
- of this option sets the label describing the old file and the second
- use of the option sets the label for the new file.
- [Default: use the filename and modification dates for the label]
-
---no-label Suppress inclusion of old and new file names as comment in output file
-
---visible-label Include old and new filenames (or labels set with --label option) as
- visible output
-
---flatten Replace \\input and \\include commands within body by the content
- of the files in their argument. If \\includeonly is present in the
- preamble, only those files are expanded into the document. However,
- no recursion is done, i.e. \\input and \\include commands within
- included sections are not expanded. The included files are assumed to
- be located in the same directories as the old and new master files,
- respectively, making it possible to organise files into old and new directories.
- --flatten is applied recursively, so inputted files can contain further
- \\input statements. Also handles files included by the import package
- (\\import and \\subimport), and \\subfile command.
-
---filter-script=filterscript Run files through this filterscript (full path preferred) before processing.
- The filterscript must take STDIN input and output to STDOUT.
- When coupled with --flatten, each file will be run through the filter as it is brought in.
-
---ignore-filter-stderr When running with --filter-script, STDERR from the script may cause readability issues.
- Turn this flag on to ignore STDERR from the filter script.
-
-
-
---help
--h Show this help text.
-
---ignore-warnings Suppress warnings about inconsistencies in length between input
- and parsed strings and missing characters.
-
---verbose
--V Output various status information to stderr during processing.
- Default is to work silently.
-
---version Show version number.
-
-Internal options:
-These options are mostly for automated use by latexdiff-vc. They can be used directly, but
-the API should be considered less stable than for the other options.
-
---no-links Suppress generation of hyperreferences, used for minimal diffs
- (option --only-changes of latexdiff-vc).
-EOF
-}
-
-=head1 NAME
-
-latexdiff - determine and markup differences between two latex files
-
-=head1 SYNOPSIS
-
-B<latexdiff> [ B<OPTIONS> ] F<old.tex> F<new.tex> > F<diff.tex>
-
-=head1 DESCRIPTION
-
-Briefly, I<latexdiff> is a utility program to aid in the management of
-revisions of latex documents. It compares two valid latex files, here
-called C<old.tex> and C<new.tex>, finds significant differences
-between them (i.e., ignoring the number of white spaces and position
-of line breaks), and adds special commands to highlight the
-differences. Where visual highlighting is not possible, e.g. for changes
-in the formatting, the differences are
-nevertheless marked up in the source. Note that old.tex and new.tex need to
-be real files (not pipes or similar) as they are opened twice (unless C<--encoding> option is used)
-
-The program treats the preamble differently from the main document.
-Differences between the preambles are found using line-based
-differencing (similarly to the Unix diff command, but ignoring white
-spaces). A comment, "S<C<%DIF E<gt>>>" is appended to each added line, i.e. a
-line present in C<new.tex> but not in C<old.tex>. Discarded lines
- are deactivated by prepending "S<C<%DIF E<lt>>>". Changed blocks are preceded by
-comment lines giving information about line numbers in the original files. Where there are insignificant
-differences, the resulting file C<diff.tex> will be similar to
-C<new.tex>. At the end of the preamble, the definitions for I<latexdiff> markup commands are inserted.
-In differencing the main body of the text, I<latexdiff> attempts to
-satisfy the following guidelines (in order of priority):
-
-=over 3
-
-=item 1
-
-If both C<old.tex> and C<new.tex> are valid LaTeX, then the resulting
-C<diff.tex> should also be valid LateX. (NB If a few plain TeX commands
-are used within C<old.tex> or C<new.tex> then C<diff.tex> is not
-guaranteed to work but usually will).
-
-=item 2
-
-Significant differences are determined on the level of
-individual words. All significant differences, including differences
-between comments should be clearly marked in the resulting source code
-C<diff.tex>.
-
-=item 3
-
-If a changed passage contains text or text-producing commands, then
-running C<diff.tex> through LateX should produce output where added
-and discarded passages are highlighted.
-
-=item 4
-
-Where there are insignificant differences, e.g. in the positioning of
-line breaks, C<diff.tex> should follow the formatting of C<new.tex>
-
-=back
-
-For differencing the same algorithm as I<diff> is used but words
-instead of lines are compared. An attempt is made to recognize
-blocks which are completely changed such that they can be marked up as a unit.
-Comments are differenced line by line
-but the number of spaces within comments is ignored. Commands including
-all their arguments are generally compared as one unit, i.e., no mark-up
-is inserted into the arguments of commands. However, for a selected
-number of commands (for example, C<\caption> and all sectioning
-commands) the last argument is known to be text. This text is
-split into words and differenced just as ordinary text (use options to
-show and change the list of text commands, see below). As the
-algorithm has no detailed knowledge of LaTeX, it assumes all pairs of
-curly braces immediately following a command (i.e. a sequence of
-letters beginning with a backslash) are arguments for that command.
-As a restriction to condition 1 above it is thus necessary to surround
-all arguments with curly braces, and to not insert
-extraneous spaces. For example, write
-
- \section{\textem{This is an emphasized section title}}
-
-and not
-
- \section {\textem{This is an emphasized section title}}
-
-or
-
- \section\textem{This is an emphasized section title}
-
-even though all varieties are the same to LaTeX (but see
-B<--allow-spaces> option which allows the second variety).
-
-For environments whose content does not conform to standard LaTeX or
-where graphical markup does not make sense all markup commands can be
-removed by setting the PICTUREENV configuration variable, set by
-default to C<picture> and C<DIFnomarkup> environments; see B<--config>
-option). The latter environment (C<DIFnomarkup>) can be used to
-protect parts of the latex file where the markup results in illegal
-markup. You have to surround the offending passage in both the old and
-new file by C<\begin{DIFnomarkup}> and C<\end{DIFnomarkup}>. You must
-define the environment in the preambles of both old and new
-documents. I prefer to define it as a null-environment,
-
-C<\newenvironment{DIFnomarkup}{}{}>
-
-but the choice is yours. Any markup within the environment will be
-removed, and generally everything within the environment will just be
-taken from the new file.
-
-It is also possible to difference files which do not have a preamble.
- In this case, the file is processed in the main document
-mode, but the definitions of the markup commands are not inserted.
-
-All markup commands inserted by I<latexdiff> begin with "C<\DIF>". Added
-blocks containing words, commands or comments which are in C<new.tex>
-but not in C<old.tex> are marked by C<\DIFaddbegin> and C<\DIFaddend>.
-Discarded blocks are marked by C<\DIFdelbegin> and C<\DIFdelend>.
-Within added blocks all text is highlighted with C<\DIFadd> like this:
-C<\DIFadd{Added text block}>
-Selected `safe' commands can be contained in these text blocks as well
-(use options to show and change the list of safe commands, see below).
-All other commands as well as braces "{" and "}" are never put within
-the scope of C<\DIFadd>. Added comments are marked by prepending
-"S<C<%DIF E<gt> >>".
-
-Within deleted blocks text is highlighted with C<\DIFdel>. Deleted
-comments are marked by prepending "S<C<%DIF E<lt> >>". Non-safe command
-and curly braces within deleted blocks are commented out with
-"S<C<%DIFDELCMD E<lt> >>".
-
-
-
-=head1 OPTIONS
-
-=head2 Preamble
-
-The following options determine the visual markup style by adding the appropriate
-command definitions to the preamble. See the end of this section for a description of
-available styles.
-
-=over 4
-
-=item B<--type=markupstyle> or
-B<-t markupstyle>
-
-Add code to preamble for selected markup style. This option defines
-C<\DIFadd> and C<\DIFdel> commands.
-Available styles:
-
-C<UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE
-CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT>
-
-[ Default: C<UNDERLINE> ]
-
-=item B<--subtype=markstyle> or
-B<-s markstyle>
-
-Add code to preamble for selected style for bracketing
-commands (e.g. to mark changes in margin). This option defines
-C<\DIFaddbegin>, C<\DIFaddend>, C<\DIFdelbegin> and C<\DIFdelend> commands.
-Available styles: C<SAFE MARGIN COLOR DVIPSCOL ZLABEL ONLYCHANGEDPAGE (LABEL)*>
-
-[ Default: C<SAFE> ]
-* Subtype C<LABEL> is deprecated
-
-=item B<--floattype=markstyle> or
-B<-f markstyle>
-
-Add code to preamble for selected style which
-replace standard marking and markup commands within floats
-(e.g., marginal remarks cause an error within floats
-so marginal marking can be disabled thus). This option defines all
-C<\DIF...FL> commands.
-Available styles: C<FLOATSAFE TRADITIONALSAFE IDENTICAL>
-
-[ Default: C<FLOATSAFE> ]
-
-=item B<--encoding=enc> or
-B<-e enc>
-
-Specify encoding of old.tex and new.tex. Typical encodings are
-C<ascii>, C<utf8>, C<latin1>, C<latin9>. A list of available encodings can be
-obtained by executing
-
-C<perl -MEncode -e 'print join ("\n",Encode->encodings( ":all" )) ;' >
-
-If this option is used, then old.tex, new.tex are only opened once.
-[Default encoding is utf8 unless the first few lines of the preamble contain
-an invocation C<\usepackage[..]{inputenc}> in which case the
-encoding chosen by this command is asssumed. Note that ASCII (standard
-latex) is a subset of utf8]
-
-=item B<--preamble=file> or
-B<-p file>
-
-Insert file at end of preamble instead of generating
-preamble. The preamble must define the following commands
-C<\DIFaddbegin, \DIFaddend, \DIFadd{..},
-\DIFdelbegin,\DIFdelend,\DIFdel{..},>
-and varieties for use within floats
-C<\DIFaddbeginFL, \DIFaddendFL, \DIFaddFL{..},
-\DIFdelbeginFL, \DIFdelendFL, \DIFdelFL{..}>
-(If this option is set B<-t>, B<-s>, and B<-f> options
-are ignored.)
-
-=item B<--packages=pkg1,pkg2,..>
-
-Tell latexdiff that .tex file is processed with the packages in list
-loaded. This is normally not necessary if the .tex file includes the
-preamble, as the preamble is automatically scanned for C<\usepackage> commands.
-Use of the B<--packages> option disables automatic scanning, so if for any
-reason package specific parsing needs to be switched off, use B<--packages=none>.
-The following packages trigger special behaviour:
-
-=over 8
-
-=item C<amsmath>
-
-Configuration variable MATHARRREPL is set to C<align*> (Default: C<eqnarray*>). (Note that many of the
-amsmath array environments are already recognised by default as such)
-
-=item C<endfloat>
-
-Ensure that C<\begin{figure}> and C<\end{figure}> always appear by themselves on a line.
-
-=item C<hyperref>
-
-Change name of C<\DIFadd> and C<\DIFdel> commands to C<\DIFaddtex> and C<\DIFdeltex> and
-define new C<\DIFadd> and C<\DIFdel> commands, which provide a wrapper for these commands,
-using them for the text but not for the link defining command (where any markup would cause
-errors).
-
-=item C<apacite>, C<biblatex>
-
-Redefine the commands recognised as citation commands.
-
-=item C<siunitx>
-
-Treat C<\SI> as equivalent to citation commands (i.e. protect with C<\mbox> if markup style uses ulem package.
-
-=item C<cleveref>
-
-Treat C<\cref,\Cref>, etc as equivalent to citation commands (i.e. protect with C<\mbox> if markup style uses ulem package.
-
-=item C<glossaries>
-
-Define most of the glossaries commands as safe, protecting them with \mbox'es where needed
-
-=item C<mhchem>
-
-Treat C<\ce> as a safe command, i.e. it will be highlighted (note that C<\cee> will not be highlighted in equations as this leads to processing errors)
-
-=item C<chemformula> or C<chemmacros>
-
-Treat C<\ch> as a safe command outside equations, i.e. it will be highlighted (note that C<\ch> will not be highlighted in equations as this leads to processing errors)
-
-
-=back
-
-[ Default: scan the preamble for C<\usepackage> commands to determine
- loaded packages. ]
-
-
-
-=item B<--show-preamble>
-
-Print generated or included preamble commands to stdout.
-
-=back
-
-=head2 Configuration
-
-=over 4
-
-=item B<--exclude-safecmd=exclude-file> or
-B<-A exclude-file> or B<--exclude-safecmd="cmd1,cmd2,...">
-
-=item B<--replace-safecmd=replace-file>
-
-=item B<--append-safecmd=append-file> or
-B<-a append-file> or B<--append-safecmd="cmd1,cmd2,...">
-
-Exclude from, replace or append to the list of regular expressions (RegEx)
-matching commands which are safe to use within the
-scope of a C<\DIFadd> or C<\DIFdel> command. The file must contain
-one Perl-RegEx per line (Comment lines beginning with # or % are
-ignored). Note that the RegEx needs to match the whole of
-the token, i.e., /^regex$/ is implied and that the initial
-"\" of the command is not included.
-The B<--exclude-safecmd> and B<--append-safecmd> options can be combined with the -B<--replace-safecmd>
-option and can be used repeatedly to add cumulatively to the lists.
- B<--exclude-safecmd>
-and B<--append-safecmd> can also take a comma separated list as input. If a
-comma for one of the regex is required, escape it thus "\,". In most cases it
-will be necessary to protect the comma-separated list from the shell by putting
-it in quotation marks.
-
-=item B<--exclude-textcmd=exclude-file> or
-B<-X exclude-file> or B<--exclude-textcmd="cmd1,cmd2,...">
-
-=item B<--replace-textcmd=replace-file>
-
-=item B<--append-textcmd=append-file> or
-B<-x append-file> or B<--append-textcmd="cmd1,cmd2,...">
-
-Exclude from, replace or append to the list of regular expressions
-matching commands whose last argument is text. See
-entry for B<--exclude-safecmd> directly above for further details.
-
-
-=item B<--replace-context1cmd=replace-file>
-
-=item B<--append-context1cmd=append-file> or
-
-=item B<--append-context1cmd="cmd1,cmd2,...">
-
-Replace or append to the list of regex matching commands
-whose last argument is text but which require a particular
-context to work, e.g. C<\caption> will only work within a figure
-or table. These commands behave like text commands, except when
-they occur in a deleted section, when they are disabled, but their
-argument is shown as deleted text.
-
-=item B<--replace-context2cmd=replace-file>
-
-=item B<--append-context2cmd=append-file> or
-
-=item B<--append-context2cmd="cmd1,cmd2,...">
-
-As corresponding commands for context1. The only difference is that
-context2 commands are completely disabled in deleted sections, including
-their arguments.
-
-context2 commands are also the only commands in the preamble, whose argument will be processed in
-word-by-word mode (which only works, if they occur no more than once in the preamble). The algorithm currently cannot cope with repeated context2 commands in the preamble, as they occur e.g. for the C<\author> argument in some journal styles (not in the standard styles, though
-If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use C<--replace-context2cmd> option to just select the commands, which should be processed and are not used repeatedly in the preamble.
-
-
-
-=item B<--exclude-mboxsafecmd=exclude-file> or B<--exclude-mboxsafecmd="cmd1,cmd2,...">
-
-=item B<--append-mboxsafecmd=append-file> or B<--append-mboxsafecmd="cmd1,cmd2,...">
-
-Define safe commands, which additionally need to be protected by encapsulating
-in an C<\mbox{..}>. This is sometimes needed to get around incompatibilities
-between external packages and the ulem package, which is used for highlighting
-in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE
-
-
-
-
-
-=item B<--config var1=val1,var2=val2,...> or B<-c var1=val1,..>
-
-=item B<-c configfile>
-
-Set configuration variables. The option can be repeated to set different
-variables (as an alternative to the comma-separated list).
-Available variables (see below for further explanations):
-
-C<ARRENV> (RegEx)
-
-C<COUNTERCMD> (RegEx)
-
-C<CUSTODIFCMD> (RegEx)
-
-C<FLOATENV> (RegEx)
-
-C<ITEMCMD> (RegEx)
-
-C<LISTENV> (RegEx)
-
-C<MATHARRENV> (RegEx)
-
-C<MATHARRREPL> (String)
-
-C<MATHENV> (RegEx)
-
-C<MATHREPL> (String)
-
-C<MINWORDSBLOCK> (Integer)
-
-C<PICTUREENV> (RegEx)
-
-C<SCALEDELGRAPHICS> (Float)
-
-
-=item B<--add-to-config varenv1=pattern1,varenv2=pattern2,...>
-
-For configuration variables, which are a regular expression (essentially those ending
-in ENV, COUNTERCMD and CUSTOMDIFCMD, see list above) this option provides an alternative way to modify the configuration
-variables. Instead of setting the complete pattern, with this option it is possible to add an
-alternative pattern. C<varenv> must be one of the variables listed above that take a regular
-expression as argument, and pattern is any regular expression (which might need to be
-protected from the shell by quotation). Several patterns can be added at once by using semi-colons
-to separate them, e.g. C<--add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote">
-
-=item B<--show-safecmd>
-
-Print list of RegEx matching and excluding safe commands.
-
-=item B<--show-textcmd>
-
-Print list of RegEx matching and excluding commands with text argument.
-
-=item B<--show-config>
-
-Show values of configuration variables.
-
-=item B<--show-all>
-
-Combine all --show commands.
-
-NB For all --show commands, no C<old.tex> or C<new.tex> file needs to be specified, and no
-differencing takes place.
-
-=back
-
-=head2 Other configuration options:
-
-=over 4
-
-=item B<--allow-spaces>
-
-Allow spaces between bracketed or braced arguments to commands. Note
-that this option might have undesirable side effects (unrelated scope
-might get lumpeded with preceding commands) so should only be used if the
-default produces erroneous results. (Default requires arguments to
-directly follow each other without intervening spaces).
-
-=item B<--math-markup=level>
-
-Determine granularity of markup in displayed math environments:
-Possible values for level are (both numerical and text labels are acceptable):
-
-C<off> or C<0>: suppress markup for math environments. Deleted equations will not
-appear in diff file. This mode can be used if all the other modes
-cause invalid latex code.
-
-C<whole> or C<1>: Differencing on the level of whole equations. Even trivial changes
-to equations cause the whole equation to be marked changed. This
-mode can be used if processing in coarse or fine mode results in
-invalid latex code.
-
-C<coarse> or C<2>: Detect changes within equations marked up with a coarse
-granularity; changes in equation type (e.g.displaymath to equation)
-appear as a change to the complete equation. This mode is recommended
-for situations where the content and order of some equations are still
-being changed. [Default]
-
-C<fine> or C<3>: Detect small change in equations and mark up at fine granularity.
-This mode is most suitable, if only minor changes to equations are
-expected, e.g. correction of typos.
-
-=item B<--graphics-markup=level>
-
- Change highlight style for graphics embedded with C<\includegraphics> commands.
-
-Possible values for level:
-
-C<none>, C<off> or C<0>: no highlighting for figures
-
-C<new-only> or C<1>: surround newly added or changed figures with a blue frame [Default if graphicx package loaded]
-
-C<both> or C<2>: highlight new figures with a blue frame and show deleted figures at reduced
-scale, and crossed out with a red diagonal cross. Use configuration
-variable SCALEDELGRAPHICS to set size of deleted figures.
-
-Note that changes to the optional parameters will make the figure appear as changed
-to latexdiff, and this figure will thus be highlighted
-
-=item B<--disable-citation-markup> or B<--disable-auto-mbox>
-
-Suppress citation markup and markup of other vulnerable commands in styles
-using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR)
-(the two options are identical and are simply aliases)
-
-=item B<--enable-citation-markup> or B<--enforce-auto-mbox>
-
-Protect citation commands and other vulnerable commands in changed sections
-with C<\mbox> command, i.e. use default behaviour for ulem package for other packages
-(the two options are identical and are simply aliases)
-
-=back
-
-=head2 Miscellaneous
-
-=over 4
-
-=item B<--verbose> or B<-V>
-
-Output various status information to stderr during processing.
-Default is to work silently.
-
-=item B<--driver=type>
-
-Choose driver for changebar package (only relevant for styles using
- changebar: CCHANGEBAR CFONTCHBAR CULINECHBAR CHANGEBAR). Possible
-drivers are listed in changebar manual, e.g. pdftex,dvips,dvitops
- [Default: dvips]
-
-=item B<--ignore-warnings>
-
-Suppress warnings about inconsistencies in length between input and
-parsed strings and missing characters. These warning messages are
-often related to non-standard latex or latex constructions with a
-syntax unknown to C<latexdiff> but the resulting difference argument
-is often fully functional anyway, particularly if the non-standard
-latex only occurs in parts of the text which have not changed.
-
-=item B<--label=label> or
-B<-L label>
-
-Sets the labels used to describe the old and new files. The first use
-of this option sets the label describing the old file and the second
-use of the option sets the label for the new file, i.e. set both
-labels like this C<-L labelold -L labelnew>.
-[Default: use the filename and modification dates for the label]
-
-=item B<--no-label>
-
-Suppress inclusion of old and new file names as comment in output file
-
-=item B<--visible-label>
-
-Include old and new filenames (or labels set with C<--label> option) as
-visible output.
-
-=item B<--flatten>
-
-Replace C<\input> and C<\include> commands within body by the content
-of the files in their argument. If C<\includeonly> is present in the
-preamble, only those files are expanded into the document. However,
-no recursion is done, i.e. C<\input> and C<\include> commands within
-included sections are not expanded. The included files are assumed to
- be located in the same directories as the old and new master files,
-respectively, making it possible to organise files into old and new directories.
---flatten is applied recursively, so inputted files can contain further
-C<\input> statements. Also handles files included by the import package
-(C<\import> and C<\subimport>), and C<\subfile> command.
-
-Use of this option might result in prohibitive processing times for
-larger documents, and the resulting difference document
-no longer reflects the structure of the input documents.
-
-=item B<--filter-script=filterscript>
-
-Run files through this filterscript (full path preferred) before processing.
-The filterscript must take STDIN input and output to STDOUT.
-When coupled with --flatten, each file will be run through the filter as it is brought in.
-
-=item B<--ignore-filter-stderr>
-
-When running with --filter-script, STDERR from the script may cause readability issues.
-Turn this flag on to ignore STDERR from the filter script.
-
-
-
-=item B<--help> or
-B<-h>
-
-Show help text
-
-=item B<--version>
-
-Show version number
-
-=back
-
-
-=head2 Internal options
-
-These options are mostly for automated use by latexdiff-vc. They can be used directly, but the API should be considered less stable than for the other options.
-
-=over 4
-
-=item B<--no-links>
-
-Suppress generation of hyperreferences, used for minimal diffs (option --only-changes of latexdiff-vc)
-
-=back
-
-
-=head2 Predefined styles
-
-=head2 Major types
-
-The major type determine the markup of plain text and some selected latex commands outside floats by defining the markup commands C<\DIFadd{...}> and C<\DIFdel{...}> .
-
-=over 10
-
-=item C<UNDERLINE>
-
-Added text is wavy-underlined and blue, discarded text is struck out and red
-(Requires color and ulem packages). Overstriking does not work in displayed math equations such that deleted parts of equation are underlined, not struck out (this is a shortcoming inherent to the ulem package).
-
-=item C<CTRADITIONAL>
-
-Added text is blue and set in sans-serif, and a red footnote is created for each discarded
-piece of text. (Requires color package)
-
-=item C<TRADITIONAL>
-
-Like C<CTRADITIONAL> but without the use of color.
-
-=item C<CFONT>
-
-Added text is blue and set in sans-serif, and discarded text is red and very small size.
-
-=item C<FONTSTRIKE>
-
-Added tex is set in sans-serif, discarded text small and struck out
-
-=item C<CCHANGEBAR>
-
-Added text is blue, and discarded text is red. Additionally, the changed text is marked with a bar in the margin (Requires color and changebar packages).
-
-=item C<CFONTCHBAR>
-
-Like C<CFONT> but with additional changebars (Requires color and changebar packages).
-
-=item C<CULINECHBAR>
-
-Like C<UNDERLINE> but with additional changebars (Requires color, ulem and changebar packages).
-
-=item C<CHANGEBAR>
-
-No mark up of text, but mark margins with changebars (Requires changebar package).
-
-=item C<INVISIBLE>
-
-No visible markup (but generic markup commands will still be inserted.
-
-=item C<BOLD>
-
-Added text is set in bold face, discarded is not shown.
-
-=item C<PDFCOMMENT>
-
-The pdfcomment package is used to underline new text, and mark deletions with a PDF comment. Note that this markup might appear differently or not at all based on the pdf viewer used. The viewer with best support for pdf markup is probably acroread. This style is only recommended if the number of differences is small.
-
-=back
-
-=head2 Subtypes
-
-The subtype defines the commands that are inserted at the begin and end of added or discarded blocks, irrespectively of whether these blocks contain text or commands (Defined commands: C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>)
-
-=over 10
-
-=item C<SAFE>
-
-No additional markup (Recommended choice)
-
-=item C<MARGIN>
-
-Mark beginning and end of changed blocks with symbols in the margin nearby (using
-the standard C<\marginpar> command - note that this sometimes moves somewhat
-from the intended position.
-
-=item C<COLOR>
-
-An alternative way of marking added passages in blue, and deleted ones in red.
-(It is recommeneded to use instead the main types to effect colored markup,
-although in some cases coloring with dvipscol can be more complete, for example
-with citation commands).
-
-=item C<DVIPSCOL>
-
-An alternative way of marking added passages in blue, and deleted ones in red. Note
-that C<DVIPSCOL> only works with the dvips converter, e.g. not pdflatex.
-(it is recommeneded to use instead the main types to effect colored markup,
-although in some cases coloring with dvipscol can be more complete).
-
-
-=item C<ZLABEL>
-
-can be used to highlight only changed pages, but requires post-processing. It is recommend to not call this option manually but use C<latexdiff-vc> with C<--only-changes> option. Alternatively, use the script given within preamble of diff files made using this style.
-
-=item C<ONLYCHANGEDPAGE>
-
-also highlights changed pages, without the need for post-processing, but might not work reliably if
-there is floating material (figures, tables).
-
-=item C<LABEL>
-
-is similar to C<ZLABEL>, but does not need the zref package and works less reliably (deprecated).
-
-=back
-
-=head2 Float Types
-
-Some of the markup used in the main text might cause problems when used within
-floats (e.g. figures or tables). For this reason alternative versions of all
-markup commands are used within floats. The float type defines these alternative commands.
-
-=over 10
-
-=item C<FLOATSAFE>
-
-Use identical markup for text as in the main body, but set all commands marking the begin and end of changed blocks to null-commands. You have to choose this float type if your subtype is C<MARGIN> as C<\marginpar> does not work properly within floats.
-
-=item C<TRADITIONALSAFE>
-
-Mark additions the same way as in the main text. Deleted environments are marked by angular brackets \[ and \] and the deleted text is set in scriptscript size. This float type should always be used with the C<TRADITIONAL> and C<CTRADITIONAL> markup types as the \footnote command does not work properly in floating environments.
-
-=item C<IDENTICAL>
-
-Make no difference between the main text and floats.
-
-=back
-
-
-=head2 Configuration Variables
-
-=over 10
-
-=item C<ARRENV>
-
-If a match to C<ARRENV> is found within an inline math environment within a deleted or added block, then the inlined math
-is surrounded by C<\mbox{>...C<}>. This is necessary as underlining does not work within inlined array environments.
-
-[ Default: C<ARRENV>=S<C<(?:array|[pbvBV]matrix)> >
-
-=item C<COUNTERCMD>
-
-If a command in a deleted block which is also in the textcmd list matches C<COUNTERCMD> then an
-additional command C<\addtocounter{>F<cntcmd>C<}{-1}>, where F<cntcmd> is the matching command, is appended in the diff file such that the numbering in the diff file remains synchronized with the
-numbering in the new file.
-
-[ Default: C<COUNTERCMD>=C<(?:footnote|part|section|subsection> ...
-
-C<|subsubsection|paragraph|subparagraph)> ]
-
-=item C<CUSTOMDIFCMD>
-
-This option is for advanced users and allows definition of special versions of commands, which do not work as safe commands.
-
-Commands in C<CUSTOMDIFCMD> that occur in added or deleted blocks will be given an ADD or DEL prefix.
-The prefixed versions of the command must be defined in the preamble, either by putting them
-in the preamble of at least the new file, or by creating a custom preamble file (Option --preamble).
-For example the command C<\blindtext> (from package blindtext) does not interact well with underlining, so that
-for the standard markup type, it is not satisfactory to define it as a safe command. Instead, a customised versions
-without underlining can be defined in the preamble:
-
-C<\newcommand{\DELblindtext}{{\color{red}\blindtext}}>
-
-C<\newcommand{\ADDblindtext}{{\color{blue}\blindtext}}>
-
-and then latexdiff should be invoked with the option C<-c CUSTOMDIFCMD=blindtext>.
-
-[ Default: none ]
-
-=item C<FLOATENV>
-
-Environments whose name matches the regular expression in C<FLOATENV> are
-considered floats. Within these environments, the I<latexdiff> markup commands
-are replaced by their FL variaties.
-
-[ Default: S<C<(?:figure|table|plate)[\w\d*@]*> >]
-
-=item C<ITEMCMD>
-
-Commands representing new item line with list environments.
-
-[ Default: \C<item> ]
-
-=item C<LISTENV>
-
-Environments whose name matches the regular expression in C<LISTENV> are list environments.
-
-[ Default: S<C<(?:itemize|enumerate|description)> >]
-
-=item C<MATHENV>,C<MATHREPL>
-
-If both \begin and \end for a math environment (environment name matching C<MATHENV> or \[ and \])
-are within the same deleted block, they are replaced by a \begin and \end commands for C<MATHREPL>
-rather than being commented out.
-
-[ Default: C<MATHENV>=S<C<(?:displaymath|equation)> >, C<MATHREPL>=S<C<displaymath> >]
-
-=item C<MATHARRENV>,C<MATHARRREPL>
-
-as C<MATHENV>,C<MATHREPL> but for equation arrays
-
-[ Default: C<MATHARRENV>=S<C<eqnarray\*?> >, C<MATHREPL>=S<C<eqnarray> >]
-
-=item C<MINWORDSBLOCK>
-
-Minimum number of tokens required to form an independent block. This value is
-used in the algorithm to detect changes of complete blocks by merging identical text parts of less than C<MINWORDSBLOCK> to the preceding added and discarded parts.
-
-[ Default: 3 ]
-
-=item C<PICTUREENV>
-
-Within environments whose name matches the regular expression in C<PICTUREENV>
-all latexdiff markup is removed (in pathologic cases this might lead to
-inconsistent markup but this situation should be rare).
-
-[ Default: S<C<(?:picture|DIFnomarkup)[\w\d*@]*> >]
-
-=item C<SCALEDELGRAPHICS>
-
-If C<--graphics-markup=both> is chosen, C<SCALEDELGRAPHICS> is the factor, by which deleted figures will be scaled (i.e. 0.5 implies they are shown at half linear size).
-
-[ Default: 0.5 ]
-
-=item C<VERBATIMENV>
-
-RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way:
-deleted content is commented out, new content is not marked up
-
-[ Default: S<C<comment> > ]
-
-=item C<VERBATIMLINEENV>
-
-RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by VERBATIMLINEENV are compared in
-line mode, and changes are marked up using the listings package. The markup style is set based on the chosen mains markup type (Option -t), or on an analysis
-of the preamble.
-Note that "listings.sty" must be installed. If this file is not found the fallback solution is to
-treat VERBATIMLINEENV environments treated exactly the same way as VERBATIMENV environments.
-
-[ Default: S<C<(?:verbatim[*]?|lstlisting> > ]
-
-=back
-
-=head1 COMMON PROBLEMS AND FAQ
-
-=over 10
-
-=item Citations result in overfull boxes
-
-There is an incompatibility between the C<ulem> package, which C<latexdiff> uses for underlining and striking out in the UNDERLINE style,
-the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an C<\mbox>
-command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have two possibilities.
-
-1. Use C<CFONT> type markup (option C<-t CFONT>): If this markup is chosen, then changed citations are no longer marked up
-with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the C<ulem> package will also work.
-
-2. Choose option C<--disable-citation-markup> which turns off the marking up of citations: deleted citations are no longer shown, and
-added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older)
-
-For custom packages you can define the commands which need to be protected by C<\mbox> with C<--append-mboxsafecmd> and C<--excludemboxsafecmd> options
-(submit your lists of command as feature request at github page to set the default behaviour of future versions, see section 6)
-
-=item Changes in complicated mathematical equations result in latex processing errors
-
-Try options C<--math-markup=whole>. If even that fails, you can turn off mark up for equations with C<--math-markup=off>.
-
-=item How can I just show the pages where changes had been made
-
-Use options -C<-s ZLABEL> (some postprocessing required) or C<-s ONLYCHANGEDPAGE>. C<latexdiff-vc --ps|--pdf> with C<--only-changes> option takes care of
-the post-processing for you (requires zref package to be installed).
-
-=back
-
-=head1 BUGS
-
-=over 10
-
-=item Option allow-spaces not implemented entirely consistently. It breaks
-the rules that number and type of white space does not matter, as
-different numbers of inter-argument spaces are treated as significant.
-
-=back
-
-Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>,
-or send them to I<tilmann -- AT -- gfz-potsdam.de>. Include the version number of I<latexdiff>
-(from comments at the top of the source or use B<--version>). If you come across latex
-files that are error-free and conform to the specifications set out
-above, and whose differencing still does not result in error-free
-latex, please send me those files, ideally edited to only contain the
-offending passage as long as that still reproduces the problem. If your
-file relies on non-standard class files, you must include those. I will not
-look at examples where I have trouble to latex the original files.
-
-=head1 SEE ALSO
-
-L<latexrevise>, L<latexdiff-vc>
-
-=head1 PORTABILITY
-
-I<latexdiff> does not make use of external commands and thus should run
-on any platform supporting Perl 5.6 or higher. If files with encodings
-other than ASCII or UTF-8 are processed, Perl 5.8 or higher is required.
-
-The standard version of I<latexdiff> requires installation of the Perl package
-C<Algorithm::Diff> (available from I<www.cpan.org> -
-I<http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15>) but a stand-alone
-version, I<latexdiff-so>, which has this package inlined, is available, too.
-I<latexdiff-fast> requires the I<diff> command to be present.
-
-=head1 AUTHOR
-
-Version 1.3.0
-Copyright (C) 2004-2018 Frederik Tilmann
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License Version 3
-
-Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner,
-T. Connors, Sebastian Gouezel and many others.
-Thanks to the many people who sent in bug reports, feature suggestions, and other feedback.
-
-=cut
-
-__END__
-%%BEGIN SAFE COMMANDS
-% Regex matching commands which can safely be in the
-% argument of a \DIFadd or \DIFdel command (leave out the \)
-arabic
-dashbox
-emph
-fbox
-framebox
-hspace\*?
-math.*
-makebox
-mbox
-pageref
-ref
-symbol
-raisebox
-rule
-text.*
-shortstack
-usebox
-dag
-ddag
-copyright
-pounds
-S
-P
-oe
-OE
-ae
-AE
-aa
-AA
-o
-O
-l
-L
-frac
-ss
-sqrt
-ldots
-cdots
-vdots
-ddots
-alpha
-beta
-gamma
-delta
-epsilon
-varepsilon
-zeta
-eta
-theta
-vartheta
-iota
-kappa
-lambda
-mu
-nu
-xi
-pi
-varpi
-rho
-varrho
-sigma
-varsigma
-tau
-upsilon
-phi
-varphi
-chi
-psi
-omega
-Gamma
-Delta
-Theta
-Lambda
-Xi
-Pi
-Sigma
-Upsilon
-Phi
-Psi
-Omega
-ps
-mp
-times
-div
-ast
-star
-circ
-bullet
-cdot
-cap
-cup
-uplus
-sqcap
-vee
-wedge
-setminus
-wr
-diamond
-(?:big)?triangle.*
-lhd
-rhd
-unlhd
-unrhd
-oplus
-ominus
-otimes
-oslash
-odot
-bigcirc
-d?dagger
-amalg
-leq
-prec
-preceq
-ll
-(?:sq)?su[bp]set(?:eq)?
-in
-vdash
-geq
-succ(?:eq)?
-gg
-ni
-dashv
-equiv
-sim(?:eq)?
-asymp
-approx
-cong
-neq
-doteq
-propto
-models
-perp
-mid
-parallel
-bowtie
-Join
-smile
-frown
-.*arrow
-(?:long)?mapsto
-.*harpoon.*
-leadsto
-aleph
-hbar
-imath
-jmath
-ell
-wp
-Re
-Im
-mho
-prime
-emptyset
-nabla
-surd
-top
-bot
-angle
-forall
-exists
-neg
-flat
-natural
-sharp
-backslash
-partial
-infty
-Box
-Diamond
-triangle
-clubsuit
-diamondsuit
-heartsuit
-spadesuit
-sum
-prod
-coprod
-int
-oint
-big(?:sq)?c[au]p
-bigvee
-bigwedge
-bigodot
-bigotimes
-bigoplus
-biguplus
-(?:arc)?(?:cos|sin|tan|cot)h?
-csc
-arg
-deg
-det
-dim
-exp
-gcd
-hom
-inf
-ker
-lg
-lim
-liminf
-limsup
-ln
-log
-max
-min
-Pr
-sec
-sup
-bibfield
-bibinfo
-[Hclbkdruvt]
-[`'^"~=.]
-_
-AMPERSAND
-(SUPER|SUB)SCRIPTNB
-(SUPER|SUB)SCRIPT
-SQRT
-SQRTNB
-PERCENTAGE
-DOLLAR
-%%END SAFE COMMANDS
-
-%%BEGIN TEXT COMMANDS
-% Regex matching commands with a text argument (leave out the \)
-addcontents.*
-cc
-closing
-chapter
-dashbox
-emph
-encl
-fbox
-framebox
-footnote
-footnotetext
-framebox
-href
-intertext
-part
-(sub){0,2}section\*?
-(sub)?paragraph\*?
-makebox
-mbox
-opening
-parbox
-raisebox
-savebox
-sbox
-shortintertext
-shortstack
-sidenote
-signature
-text.*
-value
-underline
-sqrt
-(SUPER|SUB)SCRIPT
-%%END TEXT COMMANDS
-
-%%BEGIN CONTEXT1 COMMANDS
-% Regex matching commands with a text argument (leave out the \), which will fail out of context. These commands behave like text commands, except when they occur in a deleted section, where they are disabled, but their argument is shown as deleted text.
-caption
-subcaption
-%%END CONTEXT1 COMMANDS
-
-%%BEGIN CONTEXT2 COMMANDS
-% Regex matching commands with a text argument (leave out the \), which will fail out of context. As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments.
-title
-author
-date
-institute
-%%END CONTEXT2 COMMANDS
-
-%% CONFIGURATION variabe defaults
-%%BEGIN LISTENV CONFIG
-itemize
-description
-enumerate
-%%END LISTENV CONFIG
-
-%%BEGIN FLOATENV CONFIG
-figure[\w\d*@]*
-table[\w\d*@]*
-plate[\w\d*@]*
-%%END FLOATENV CONFIG
-
-%%BEGIN PICTUREENV CONFIG
-picture[\w\d*@]*
-tikzpicture[\w\d*@]*
-DIFnomarkup
-%%END PICTUREENV CONFIG
-
-%%BEGIN MATHENV CONFIG
-equation[*]?
-displaymath
-DOLLARDOLLAR
-%%END MATHENV CONFIG
-
-%%BEGIN MATHARRENV CONFIG
-eqnarray[*]?
-align[*]?
-alignat[*]?
-gather[*]?
-multline[*]?
-flalign[*]?
-%%END MATHARRENV CONFIG
-
-%%BEGIN ARRENV CONFIG
-aligned
-gathered
-array
-[pbvBV]?matrix
-smallmatrix
-cases
-split
-%%END ARRENV CONFIG
-
-%%BEGIN COUNTERCMD CONFIG
-footnote
-part
-chapter
-section
-subsection
-subsubsection
-paragraph
-subparagraph
-%%END COUNTERCMD CONFIG
-
-%%BEGIN VERBATIMENV CONFIG
-comment
-%%END VERBATIMENV CONFIG
-
-%%BEGIN VERBATIMLINEENV CONFIG
-lstlisting
-verbatim[*]?
-%%END VERBATIMLINEENV CONFIG
-
-%%BEGIN CUSTOMDIFCMD CONFIG
-%%END CUSTOMDIFCMD CONFIG
-
-%%% TYPES (Commands for highlighting changed blocks)
-
-%DIF UNDERLINE PREAMBLE
-\RequirePackage[normalem]{ulem}
-\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
-\providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}}
-\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}}
-%DIF END UNDERLINE PREAMBLE
-
-%DIF CTRADITIONAL PREAMBLE
-\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
-\RequirePackage[stable]{footmisc}
-\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
-\providecommand{\DIFadd}[1]{{\protect\color{blue} \sf #1}}
-\providecommand{\DIFdel}[1]{{\protect\color{red} [..\footnote{removed: #1} ]}}
-%DIF END CTRADITIONAL PREAMBLE
-
-%DIF TRADITIONAL PREAMBLE
-\RequirePackage[stable]{footmisc}
-\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
-\providecommand{\DIFadd}[1]{{\sf #1}}
-\providecommand{\DIFdel}[1]{{[..\footnote{removed: #1} ]}}
-%DIF END TRADITIONAL PREAMBLE
-
-%DIF CFONT PREAMBLE
-\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
-\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
-\providecommand{\DIFadd}[1]{{\protect\color{blue} \sf #1}}
-\providecommand{\DIFdel}[1]{{\protect\color{red} \scriptsize #1}}
-%DIF END CFONT PREAMBLE
-
-%DIF FONTSTRIKE PREAMBLE
-\RequirePackage[normalem]{ulem}
-\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
-\providecommand{\DIFadd}[1]{{\sf #1}}
-\providecommand{\DIFdel}[1]{{\footnotesize \sout{#1}}}
-%DIF END FONTSTRIKE PREAMBLE
-
-%DIF CCHANGEBAR PREAMBLE
-\RequirePackage[dvips]{changebar}
-\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
-\providecommand{\DIFadd}[1]{\protect\cbstart{\protect\color{blue}#1}\protect\cbend}
-\providecommand{\DIFdel}[1]{\protect\cbdelete{\protect\color{red}#1}\protect\cbdelete}
-%DIF END CCHANGEBAR PREAMBLE
-
-%DIF CFONTCHBAR PREAMBLE
-\RequirePackage[dvips]{changebar}
-\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
-\providecommand{\DIFadd}[1]{\protect\cbstart{\protect\color{blue}\sf #1}\protect\cbend}
-\providecommand{\DIFdel}[1]{\protect\cbdelete{\protect\color{red}\scriptsize #1}\protect\cbdelete}
-%DIF END CFONTCHBAR PREAMBLE
-
-%DIF CULINECHBAR PREAMBLE
-\RequirePackage[normalem]{ulem}
-\RequirePackage[dvips]{changebar}
-\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
-\providecommand{\DIFadd}[1]{\protect\cbstart{\protect\color{blue}\uwave{#1}}\protect\cbend}
-\providecommand{\DIFdel}[1]{\protect\cbdelete{\protect\color{red}\sout{#1}}\protect\cbdelete}
-%DIF END CULINECHBAR PREAMBLE
-
-%DIF CHANGEBAR PREAMBLE
-\RequirePackage[dvips]{changebar}
-\providecommand{\DIFadd}[1]{\protect\cbstart{#1}\protect\cbend}
-\providecommand{\DIFdel}[1]{\protect\cbdelete}
-%DIF END CHANGEBAR PREAMBLE
-
-%DIF INVISIBLE PREAMBLE
-\providecommand{\DIFadd}[1]{#1}
-\providecommand{\DIFdel}[1]{}
-%DIF END INVISIBLE PREAMBLE
-
-%DIF BOLD PREAMBLE
-\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
-\providecommand{\DIFadd}[1]{{\bf #1}}
-\providecommand{\DIFdel}[1]{}
-%DIF END BOLD PREAMBLE
-
-%DIF PDFCOMMENT PREAMBLE
-\RequirePackage{pdfcomment} %DIF PREAMBLE
-\providecommand{\DIFadd}[1]{\pdfmarkupcomment[author=ADD:,markup=Underline]{#1}{}}
-\providecommand{\DIFdel}[1]{\pdfcomment[icon=Insert,author=DEL:,hspace=12pt]{#1}}
-%DIF END PDFCOMMENT PREAMBLE
-
-%% SUBTYPES (Markers for beginning and end of changed blocks)
-
-%DIF SAFE PREAMBLE
-\providecommand{\DIFaddbegin}{}
-\providecommand{\DIFaddend}{}
-\providecommand{\DIFdelbegin}{}
-\providecommand{\DIFdelend}{}
-\providecommand{\DIFmodbegin}{}
-\providecommand{\DIFmodend}{}
-%DIF END SAFE PREAMBLE
-
-%DIF MARGIN PREAMBLE
-\providecommand{\DIFaddbegin}{\protect\marginpar{a[}}
-\providecommand{\DIFaddend}{\protect\marginpar{]}}
-\providecommand{\DIFdelbegin}{\protect\marginpar{d[}}
-\providecommand{\DIFdelend}{\protect\marginpar{]}}
-\providecommand{\DIFmodbegin}{\protect\marginpar{m[}}
-\providecommand{\DIFmodend}{\protect\marginpar{]}}
-%DIF END MARGIN PREAMBLE
-
-%DIF DVIPSCOL PREAMBLE
-%Note: only works with dvips converter
-\RequirePackage{color}
-\RequirePackage{dvipscol}
-\providecommand{\DIFaddbegin}{\protect\nogroupcolor{blue}}
-\providecommand{\DIFaddend}{\protect\nogroupcolor{black}}
-\providecommand{\DIFdelbegin}{\protect\nogroupcolor{red}}
-\providecommand{\DIFdelend}{\protect\nogroupcolor{black}}
-\providecommand{\DIFmodbegin}{}
-\providecommand{\DIFmodend}{}
-%DIF END DVIPSCOL PREAMBLE
-
-%DIF COLOR PREAMBLE
-\RequirePackage{color}
-\providecommand{\DIFaddbegin}{\protect\color{blue}}
-\providecommand{\DIFaddend}{\protect\color{black}}
-\providecommand{\DIFdelbegin}{\protect\color{red}}
-\providecommand{\DIFdelend}{\protect\color{black}}
-\providecommand{\DIFmodbegin}{}
-\providecommand{\DIFmodend}{}
-%DIF END COLOR PREAMBLE
-
-%DIF LABEL PREAMBLE
-% To show only pages with changes (pdf) (external program pdftk needs to be installed)
-% (only works for simple documents with non-repeated page numbers, otherwise use ZLABEL)
-% pdflatex diff.tex
-% pdflatex diff.tex
-%pdftk diff.pdf cat \
-%`perl -lne '\
-% if (m/\\newlabel{DIFchg[b](\d*)}{{.*}{(.*)}}/) { $start{$1}=$2; print $2}\
-% if (m/\\newlabel{DIFchg[e](\d*)}{{.*}{(.*)}}/) { \
-% if (defined($start{$1})) { \
-% for ($j=$start{$1}; $j<=$2; $j++) {print "$j";}\
-% } else { \
-% print "$2"\
-% }\
-% }' diff.aux \
-% | uniq \
-% | tr \\n ' '` \
-% output diff-changedpages.pdf
-% To show only pages with changes (dvips/dvipdf)
-% dvips -pp `\
-% [ put here the perl script from above]
-% | uniq | tr -s \\n ','`
-\typeout{Check comments in preamble of output for instructions how to show only pages where changes have been made}
-\newcount\DIFcounterb
-\global\DIFcounterb 0\relax
-\newcount\DIFcountere
-\global\DIFcountere 0\relax
-\providecommand{\DIFaddbegin}{\global\advance\DIFcounterb 1\relax\label{DIFchgb\the\DIFcounterb}}
-\providecommand{\DIFaddend}{\global\advance\DIFcountere 1\relax\label{DIFchge\the\DIFcountere}}
-\providecommand{\DIFdelbegin}{\global\advance\DIFcounterb 1\relax\label{DIFchgb\the\DIFcounterb}}
-\providecommand{\DIFdelend}{\global\advance\DIFcountere 1\relax\label{DIFchge\the\DIFcountere}}
-\providecommand{\DIFmodbegin}{\global\advance\DIFcounterb 1\relax\label{DIFchgb\the\DIFcounterb}}
-\providecommand{\DIFmodend}{\global\advance\DIFcountere 1\relax\label{DIFchge\the\DIFcountere}}
-%DIF END LABEL PREAMBLE
-
-%DIF ZLABEL PREAMBLE
-% To show only pages with changes (pdf) (external program pdftk needs to be installed)
-% (uses zref for reference to absolute page numbers)
-% pdflatex diff.tex
-% pdflatex diff.tex
-%pdftk diff.pdf cat \
-%`perl -lne 'if (m/\\zref\@newlabel{DIFchgb(\d*)}{.*\\abspage{(\d*)}}/ ) { $start{$1}=$2; print $2 } \
-% if (m/\\zref\@newlabel{DIFchge(\d*)}{.*\\abspage{(\d*)}}/) { \
-% if (defined($start{$1})) { \
-% for ($j=$start{$1}; $j<=$2; $j++) {print "$j";}\
-% } else { \
-% print "$2"\
-% }\
-% }' diff.aux \
-% | uniq \
-% | tr \\n ' '` \
-% output diff-changedpages.pdf
-% To show only pages with changes (dvips/dvipdf)
-% latex diff.tex
-% latex diff.tex
-% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi
-\typeout{Check comments in preamble of output for instructions how to show only pages where changes have been made}
-\usepackage[user,abspage]{zref}
-\newcount\DIFcounterb
-\global\DIFcounterb 0\relax
-\newcount\DIFcountere
-\global\DIFcountere 0\relax
-\providecommand{\DIFaddbegin}{\global\advance\DIFcounterb 1\relax\zlabel{DIFchgb\the\DIFcounterb}}
-\providecommand{\DIFaddend}{\global\advance\DIFcountere 1\relax\zlabel{DIFchge\the\DIFcountere}}
-\providecommand{\DIFdelbegin}{\global\advance\DIFcounterb 1\relax\zlabel{DIFchgb\the\DIFcounterb}}
-\providecommand{\DIFdelend}{\global\advance\DIFcountere 1\relax\zlabel{DIFchge\the\DIFcountere}}
-\providecommand{\DIFmodbegin}{\global\advance\DIFcounterb 1\relax\zlabel{DIFchgb\the\DIFcounterb}}
-\providecommand{\DIFmodend}{\global\advance\DIFcountere 1\relax\zlabel{DIFchge\the\DIFcountere}}
-%DIF END ZLABEL PREAMBLE
-
-%DIF ONLYCHANGEDPAGE PREAMBLE
-\RequirePackage{atbegshi}
-\RequirePackage{etoolbox}
-\RequirePackage{zref}
-% redefine label command to write immediately to aux file - page references will be lost
-\makeatletter \let\oldlabel\label% Store \label
-\renewcommand{\label}[1]{% Update \label to write to the .aux immediately
-\zref@wrapper@immediate{\oldlabel{#1}}}
-\makeatother
-\newbool{DIFkeeppage}
-\newbool{DIFchange}
-\boolfalse{DIFkeeppage}
-\boolfalse{DIFchange}
-\AtBeginShipout{%
- \ifbool{DIFkeeppage}
- {\global\boolfalse{DIFkeeppage}} % True DIFkeeppage
- {\ifbool{DIFchange}{\global\boolfalse{DIFkeeppage}}{\global\boolfalse{DIFkeeppage}\AtBeginShipoutDiscard}} % False DIFkeeppage
-}
-\providecommand{\DIFaddbegin}{\global\booltrue{DIFkeeppage}\global\booltrue{DIFchange}}
-\providecommand{\DIFaddend}{\global\booltrue{DIFkeeppage}\global\boolfalse{DIFchange}}
-\providecommand{\DIFdelbegin}{\global\booltrue{DIFkeeppage}\global\booltrue{DIFchange}}
-\providecommand{\DIFdelend}{\global\booltrue{DIFkeeppage}\global\boolfalse{DIFchange}}
-\providecommand{\DIFmodbegin}{\global\booltrue{DIFkeeppage}\global\booltrue{DIFchange}}
-\providecommand{\DIFmodend}{\global\booltrue{DIFkeeppage}\global\boolfalse{DIFchange}}
-%DIF END ONLYCHANGEDPAGE PREAMBLE
-
-%% FLOAT TYPES
-
-%DIF FLOATSAFE PREAMBLE
-\providecommand{\DIFaddFL}[1]{\DIFadd{#1}}
-\providecommand{\DIFdelFL}[1]{\DIFdel{#1}}
-\providecommand{\DIFaddbeginFL}{}
-\providecommand{\DIFaddendFL}{}
-\providecommand{\DIFdelbeginFL}{}
-\providecommand{\DIFdelendFL}{}
-%DIF END FLOATSAFE PREAMBLE
-
-%DIF IDENTICAL PREAMBLE
-\providecommand{\DIFaddFL}[1]{\DIFadd{#1}}
-\providecommand{\DIFdelFL}[1]{\DIFdel{#1}}
-\providecommand{\DIFaddbeginFL}{\DIFaddbegin}
-\providecommand{\DIFaddendFL}{\DIFaddend}
-\providecommand{\DIFdelbeginFL}{\DIFdelbegin}
-\providecommand{\DIFdelendFL}{\DIFdelend}
-%DIF END IDENTICAL PREAMBLE
-
-%DIF TRADITIONALSAFE PREAMBLE
-% procidecommand color to make this work for TRADITIONAL and CTRADITIONAL
-\providecommand{\color}[1]{}
-\providecommand{\DIFaddFL}[1]{\DIFadd{#1}}
-\providecommand{\DIFdel}[1]{{\protect\color{red}[..{\scriptsize {removed: #1}} ]}}
-\providecommand{\DIFaddbeginFL}{}
-\providecommand{\DIFaddendFL}{}
-\providecommand{\DIFdelbeginFL}{}
-\providecommand{\DIFdelendFL}{}
-%DIF END TRADITIONALSAFE PREAMBLE
-
-% see:
-% http://tex.stackexchange.com/questions/47351/can-i-redefine-a-command-to-contain-itself
-
-%DIF HIGHLIGHTGRAPHICS PREAMBLE
-\RequirePackage{settobox}
-\RequirePackage{letltxmacro}
-\newsavebox{\DIFdelgraphicsbox}
-\newlength{\DIFdelgraphicswidth}
-\newlength{\DIFdelgraphicsheight}
-% store original definition of \includegraphics
-\LetLtxMacro{\DIFOincludegraphics}{\includegraphics}
-\newcommand{\DIFaddincludegraphics}[2][]{{\color{blue}\fbox{\DIFOincludegraphics[#1]{#2}}}}
-\newcommand{\DIFdelincludegraphics}[2][]{%
-\sbox{\DIFdelgraphicsbox}{\DIFOincludegraphics[#1]{#2}}%
-\settoboxwidth{\DIFdelgraphicswidth}{\DIFdelgraphicsbox}
-\settoboxtotalheight{\DIFdelgraphicsheight}{\DIFdelgraphicsbox}
-\scalebox{\DIFscaledelfig}{%
-\parbox[b]{\DIFdelgraphicswidth}{\usebox{\DIFdelgraphicsbox}\\[-\baselineskip] \rule{\DIFdelgraphicswidth}{0em}}\llap{\resizebox{\DIFdelgraphicswidth}{\DIFdelgraphicsheight}{%
-\setlength{\unitlength}{\DIFdelgraphicswidth}%
-\begin{picture}(1,1)%
-\thicklines\linethickness{2pt}
-{\color[rgb]{1,0,0}\put(0,0){\framebox(1,1){}}}%
-{\color[rgb]{1,0,0}\put(0,0){\line( 1,1){1}}}%
-{\color[rgb]{1,0,0}\put(0,1){\line(1,-1){1}}}%
-\end{picture}%
-}\hspace*{3pt}}}
-}
-\LetLtxMacro{\DIFOaddbegin}{\DIFaddbegin}
-\LetLtxMacro{\DIFOaddend}{\DIFaddend}
-\LetLtxMacro{\DIFOdelbegin}{\DIFdelbegin}
-\LetLtxMacro{\DIFOdelend}{\DIFdelend}
-\DeclareRobustCommand{\DIFaddbegin}{\DIFOaddbegin \let\includegraphics\DIFaddincludegraphics}
-\DeclareRobustCommand{\DIFaddend}{\DIFOaddend \let\includegraphics\DIFOincludegraphics}
-\DeclareRobustCommand{\DIFdelbegin}{\DIFOdelbegin \let\includegraphics\DIFdelincludegraphics}
-\DeclareRobustCommand{\DIFdelend}{\DIFOaddend \let\includegraphics\DIFOincludegraphics}
-\LetLtxMacro{\DIFOaddbeginFL}{\DIFaddbeginFL}
-\LetLtxMacro{\DIFOaddendFL}{\DIFaddendFL}
-\LetLtxMacro{\DIFOdelbeginFL}{\DIFdelbeginFL}
-\LetLtxMacro{\DIFOdelendFL}{\DIFdelendFL}
-\DeclareRobustCommand{\DIFaddbeginFL}{\DIFOaddbeginFL \let\includegraphics\DIFaddincludegraphics}
-\DeclareRobustCommand{\DIFaddendFL}{\DIFOaddendFL \let\includegraphics\DIFOincludegraphics}
-\DeclareRobustCommand{\DIFdelbeginFL}{\DIFOdelbeginFL \let\includegraphics\DIFdelincludegraphics}
-\DeclareRobustCommand{\DIFdelendFL}{\DIFOaddendFL \let\includegraphics\DIFOincludegraphics}
-%DIF END HIGHLIGHTGRAPHICS PREAMBLE
-
-%% SPECIAL PACKAGE PREAMBLE COMMANDS
-
-% Standard \DIFadd and \DIFdel are redefined as \DIFaddtex and \DIFdeltex
-% when hyperref package is included.
-%DIF HYPERREF PREAMBLE
-\providecommand{\DIFadd}[1]{\texorpdfstring{\DIFaddtex{#1}}{#1}}
-\providecommand{\DIFdel}[1]{\texorpdfstring{\DIFdeltex{#1}}{}}
-%DIF END HYPERREF PREAMBLE
-
-%DIF LISTINGS PREAMBLE
-\RequirePackage{listings}
-\RequirePackage{color}
-\lstdefinelanguage{DIFcode}{
- % note that the definitions in the following two lines are overwritten dependent on the markup type selected %DIFCODE TEMPLATE
- morecomment=[il]{\%DIF\ <\ }, %DIFCODE TEMPLATE
- moredelim=[il][\bfseries]{\%DIF\ >\ } %DIFCODE TEMPLATE
-}
-\lstdefinestyle{DIFverbatimstyle}{
- language=DIFcode,
- basicstyle=\ttfamily,
- columns=fullflexible,
- keepspaces=true
-}
-\lstnewenvironment{DIFverbatim}{\lstset{style=DIFverbatimstyle}}{}
-\lstnewenvironment{DIFverbatim*}{\lstset{style=DIFverbatimstyle,showspaces=true}}{}
-%DIF END LISTINGS PREAMBLE
-
-%DIF DIFCODE_UNDERLINE
- moredelim=[il][\color{red}\sout]{\%DIF\ <\ },
- moredelim=[il][\color{blue}\uwave]{\%DIF\ >\ }
-%DIF END DIFCODE_UNDERLINE
-
-%DIF DIFCODE_CTRADITIONAL
- moredelim=[il][\color{red}\scriptsize]{\%DIF\ <\ },
- moredelim=[il][\color{blue}\sffamily]{\%DIF\ >\ }
-%DIF END DIFCODE_CTRADITIONAL
-
-%DIF DIFCODE_TRADITIONAL
- moredelim=[il][\color{white}\tiny]{\%DIF\ <\ },
- moredelim=[il][\sffamily]{\%DIF\ >\ }
-%DIF END DIFCODE_TRADITIONAL
-
-%DIF DIFCODE_CFONT
- moredelim=[il][\color{red}\scriptsize]{\%DIF\ <\ },
- moredelim=[il][\color{blue}\sffamily]{\%DIF\ >\ }
-%DIF END DIFCODE_CFONT
-
-%DIF DIFCODE_FONTSTRIKE
- moredelim=[il][\scriptsize \sout]{\%DIF\ <\ },
- moredelim=[il][\sffamily]{\%DIF\ >\ }
-%DIF END DIFCODE_FONTSTRIKE
-
-%DIF DIFCODE_INVISIBLE
- moredelim=[il][\color{white}\tiny]{\%DIF\ <\ },
- moredelim=[il]{\%DIF\ >\ }
-%DIF END DIFCODE_INVISIBLE
-
-%DIF DIFCODE_CHANGEBAR
- moredelim=[il][\color{white}\tiny]{\%DIF\ <\ },
- moredelim=[il]{\%DIF\ >\ }
-%DIF END DIFCODE_CHANGEBAR
-
-%DIF DIFCODE_CCHANGEBAR
- moredelim=[il][\color{red}]{\%DIF\ <\ },
- moredelim=[il][\color{blue}]{\%DIF\ >\ }
-%DIF END DIFCODE_CCHANGEBAR
-
-%DIF DIFCODE_CULINECHBAR
- moredelim=[il][\color{red}\sout]{\%DIF\ <\ },
- moredelim=[il][\color{blue}\uwave]{\%DIF\ >\ }
-%DIF END DIFCODE_CULINECHBAR
-
-%DIF DIFCODE_CFONTCHBAR
- moredelim=[il][\color{red}\scriptsize]{\%DIF\ <\ },
- moredelim=[il][\color{blue}\sffamily]{\%DIF\ >\ }
-%DIF END DIFCODE_CFONTCHBAR
-
-%DIF DIFCODE_BOLD
- % unfortunately \bfseries cannot be combined with ttfamily without extra packages
- % also morecomment=[il] is broken as of v1.5b of listings at least
- % workaround: plot in white with tiny font
- % morecomment=[il]{\%DIF\ <\ },
- moredelim=[il][\color{white}\tiny]{\%DIF\ <\ },
- moredelim=[il][\sffamily\bfseries]{\%DIF\ >\ }
-%DIF END DIFCODE_BOLD
-
-%DIF DIFCODE_PDFCOMMENT
-
- moredelim=[il][\color{white}\tiny]{\%DIF\ <\ },
- moredelim=[il][\sffamily\bfseries]{\%DIF\ >\ }
-%DIF END DIFCODE_PDFCOMMENT
-
diff --git a/Build/source/texk/texlive/linked_scripts/latexdiff/latexrevise.pl b/Build/source/texk/texlive/linked_scripts/latexdiff/latexrevise.pl
deleted file mode 100755
index 2d809fb156d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latexdiff/latexrevise.pl
+++ /dev/null
@@ -1,556 +0,0 @@
-#!/usr/bin/env perl
-# latexrevise - takes output file of latexdiff and removes either discarded
-# or appended passages, then deletes all other latexdiff markup
-#
-# Copyright (C) 2004 F J Tilmann (tilmann@gfz-potsdam.de)
-#
-# Repository: https://github.com/ftilmann/latexdiff
-# CTAN page: http://www.ctan.org/pkg/latexdiff
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Detailed usage information at the end of the file
-# Note: version number now keeping up with latexdiff
-# Version 1.3.1 (Bug fix) Remove some deprecation warnings due to uncommented left parentheses
-# Version 1.0.2 Option --version
-# Version 1.0.1 no changes to latexrevise
-# Version 0.3 Updated for compatibility with latexdiff 0.3 output (DIFAUXCMD removal)
-# Version 0.1 First public release
-
-use Getopt::Long ;
-use strict;
-use warnings;
-
-my $versionstring=<<EOF ;
-This is LATEXREVISE 1.3.1.1
- (c) 2005-2020 F J Tilmann
-EOF
-
-# Markup strings (make sure that this are set to the same value as in
-# latexdiff)
-# If at all possible, do not change these as parts of the program
-# depend on the actual name.
-# At the very least adapt subroutine postprocess to new tokens.
-
-# note: have to use three backslashes to mean one literal one (reason
-# unknown
-my $ADDMARKOPEN='\\\DIFaddbegin(?:FL)? '; # Token to mark begin of appended text
-my $ADDMARKCLOSE='\\\DIFaddend(?:FL)?(?: |\z)'; # Token to mark end of appended text (|\z only deals with the case of \DIFaddend right before \end{document}
-my $ADDOPEN='\\\DIFadd(?:FL)?{'; # To mark begin of added text passage
-my $ADDCLOSE='}'; # To mark end of added text passage
-my $ADDCOMMENT='DIF > '; # To mark added comment line
-my $DELMARKOPEN='\\\DIFdelbegin(?:FL)? '; # Token to mark begin of deleted text
-my $DELMARKCLOSE='\\\DIFdelend(?:FL)?(?: |\z)'; # Token to mark end of deleted text
-my $DELOPEN='\\\DIFdel(?:FL)?{'; # To mark begin of deleted text passage
-my $DELCLOSE='}'; # To mark end of deleted text passage
-my $ALTEXT='FL'; # string which might be appended to above commands
-my $DELCMDOPEN='%DIFDELCMD < '; # To mark begin of deleted commands (must begin with %, i.e., be a comment
-my $DELCMDCLOSE="%%%\n"; # To mark end of deleted commands (must end with a new line)
-my $AUXCMD='%DIFAUXCMD' ; # follows auxiliary commands put in by latexdiff to make difference file legal
-my $DELCOMMENT='DIF < '; # To mark deleted comment line
-
-my $PREAMBLEXTBEG='^%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF$';
-my $PREAMBLEXTEND='^%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF$';
-
-
-#my $pat0 = '(?:[^{}]|\\\{|\\\})*';
-#my $pat1 = '(?:[^{}]|\\\{|\\\}|\{'.$pat0.'\})*';
-#my $pat2 = '(?:[^{}]|\\\{|\\\}|\{'.$pat1.'\})*';
-#my $pat3 = '(?:[^{}]|\\\{|\\\}|\{'.$pat2.'\})*';
-#my $pat4 = '(?:[^{}]|\\\{|\\\}|\{'.$pat3.'\})*';
-
-my $pat0 = '(?:[^{}])*';
-my $pat_n = $pat0;
-# if you get "undefined control sequence MATHBLOCKmath" error, increase the maximum value in this loop
-for (my $i_pat = 0; $i_pat < 20; ++$i_pat){
- $pat_n = '(?:[^{}]|\{'.$pat_n.'\}|\\\\\{|\\\\\})*';
- # Actually within the text body, quoted braces are replaced in pre-processing. The only place where
- # the last part of the pattern matters is when processing the arguments of context2cmds in the preamble
- # and these contain a \{ or \} combination, probably rare.
- # It should thus be fine to use the simpler version below.
- ### $pat_n = '(?:[^{}]|\{'.$pat_n.'\})*';
-}
-
-
-my $brat0 = '(?:[^\[\]]|\\\[|\\\])*';
-
-
-
-
-my ($input,$preamble,$body,$post);
-my (@matches);
-my ($cnt,$prematch,$postmatch);
-my ($help,$version);
-my ($verbose,$quiet,$accept,$decline,$simplify)=(0,0,0,0,0);
-my ($comment,$comenv,$markup,$markenv);
-
-# A word unlikely ever to be used in a real latex file
-my $someword='gobbledegooksygook';
-
-Getopt::Long::Configure('bundling');
-GetOptions('accept|a' => \$accept,
- 'decline|d'=> \$decline,
- 'simplify|s' => \$simplify,
- 'comment|c=s' => \$comment,
- 'comment-environment|e=s' => \$comenv,
- 'markup|m=s' => \$markup,
- 'markup-environment|n=s' => \$markenv,
- 'no-warnings|q' => \$verbose,
- 'version' => \$version,
- 'verbose|V' => \$verbose,
- 'help|h|H' => \$help);
-
-if ( $help ) {
- usage() ;
-}
-
-if ( $version ) {
- die $versionstring ;
-}
-
-
-if ( ($accept && $decline) || ($accept && $simplify) || ($decline && $simplify) ) {
- die '-a,-d and -s options are mutually exclusive. Type latexrevise -h to get more help.';
-}
-
-
-
-print STDERR "ACCEPT mode\n" if $verbose && $accept;
-print STDERR "DECLINE mode\n" if $verbose && $decline;
-print STDERR "SIMPLIFY mode. WARNING: The output will not normally be valid latex,\n" if $verbose && $simplify;
-
-# Slurp old and new files
-{
- local $/ ; # locally set record operator to undefined, ie. enable whole-file mode
- $input=<>;
-}
-
-# split into parts
-($preamble,$body,$post)=splitdoc($input,'\begin{document}','\end{document}');
-
-if (length $preamble && ( $accept || $decline ) ) {
- #
- # WORK ON PREAMBLE
- #
- # (compare subroutine linediff in latexdiff to make sure correct strings are used)
-
- # remove extra commands added to preamble by latexdiff
- $preamble =~ s/${PREAMBLEXTBEG}.*?${PREAMBLEXTEND}\n{0,1}//smg ;
-
- if ( $accept ) {
- # delete mark up in appended lines
- $preamble =~ s/^(.*) %DIF > $/$1/mg ;
- } elsif ( $decline ) {
- # delete appended lines
- # $preamble =~ s/^(.*) %DIF > $//mg ;
- $preamble =~ s/^(.*) %DIF > \n//mg ;
- # delete markup in deleted lines
- $preamble =~ s/^%DIF < //mg ;
- }
- # remove any remaining DIF markups
- #$preamble =~ s/%DIF.*$//mg ;
- $preamble =~ s/%DIF.*?\n//sg ;
-}
-#print $preamble ;
-
-#
-# WORK ON BODY
-#
-if ($accept) {
- # remove ADDMARKOPEN, ADDMARKCLOSE tokens
- @matches= $body =~ m/${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}/sg;
- checkpure(@matches);
- $body =~ s/${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}/$1/sg;
- # remove text flanked by DELMARKOPEN, DELMARKCLOSE tokens
- @matches= $body =~ m/${DELMARKOPEN}(.*?)${DELMARKCLOSE}/sg;
- checkpure(@matches);
- $body =~ s/${DELMARKOPEN}(.*?)${DELMARKCLOSE}//sg;
- # remove markup of added comments
- $body =~ s/%${ADDCOMMENT}(.*?)$/%$1/mg ;
- # remove deleted comments (full line)
- $body =~ s/^%${DELCOMMENT}.*?\n//mg ;
- # remove deleted comments (part of line)
- $body =~ s/%${DELCOMMENT}.*?$//mg ;
-}
-elsif ( $decline) {
- # remove DELMARKOPEN, DELMARKCLOSE tokens
- @matches= $body =~ m/${DELMARKOPEN}(.*?)${DELMARKCLOSE}/sg;
- checkpure(@matches);
- $body =~ s/${DELMARKOPEN}(.*?)${DELMARKCLOSE}/$1/sg;
- # remove text flanked by ADDMARKOPEN, ADDMARKCLOSE tokens
- # as latexdiff algorithm keeps the formatting and white spaces
- # of the new text, sometimes whitespace might be inserted or
- # removed inappropriately. We try to guess whether this has
- # happened
-
- # Mop up tokens. This must be done already now as otherwise
- # detection of white-space problems does not work
- $cnt = $body =~ s/${DELOPEN}($pat_n)${DELCLOSE}/$1/sg;
- # remove markup of deleted commands
- $cnt += $body =~ s/${DELCMDOPEN}(.*?)${DELCMDCLOSE}/$1/sg ;
- $cnt += $body =~ s/${DELCMDOPEN}//g ;
- # remove aux commands
- $cnt += $body =~ s/^.*${AUXCMD}$/${someword}/mg; $body =~ s/${someword}\n//g;
-
- while ( $body =~ m/${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}/s ) {
- $prematch=$`;
- $postmatch=$';
- checkpure($1);
- if ( $prematch =~ /\w$/s && $postmatch =~ /^\w/ ) {
- # apparently no white-space between word=>Insert white space
- $body =~ s/${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}/ /s ;
- }
- elsif ( $prematch =~ /\s$/s && $postmatch =~ /^[.,;:]/ ) {
- # space immediately before one of ".,:;" => remove this space
- $body =~ s/\s${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}//s ;
- }
- else {
- # do not insert or remove any extras
- $body =~ s/${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}//s;
- }
- }
-# Alternative without special cases treatment
-# @matches= $body =~ m/${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}/sg;
-# checkpure(@matches);
-# $body =~ s/${ADDMARKOPEN}(.*?)${ADDMARKCLOSE}//sg;
- # remove markup of deleted comments
- $body =~ s/%${DELCOMMENT}(.*?)$/%$1/mg ;
- # remove added comments (full line)
- $body =~ s/^%${ADDCOMMENT}.*?\n//mg ;
- # remove added comments (part of line)
- $body =~ s/%${ADDCOMMENT}.*?$//mg ;
-}
-
-# remove any remaining tokens
-if ( $accept || $decline || $simplify ) {
- # first substitution command deals with special case of added paragraph
- $cnt = $body =~ s/${ADDOPEN}($pat_n)\n${ADDCLOSE}\n/$1\n/sg;
- $cnt += $body =~ s/${ADDOPEN}($pat_n)${ADDCLOSE}/$1/sg;
- $cnt==0 || warn 'Remaining $ADDOPEN tokens in DECLINE mode\n' unless ( $quiet || $accept || $simplify );
-}
-if ($accept || $simplify ) {
- # Note: in decline mode these commands have already been removed above
- $cnt = $body =~ s/${DELOPEN}($pat_n)${DELCLOSE}/$1/sg;
- #### remove markup of deleted commands
- $cnt += $body =~ s/${DELCMDOPEN}(.*?)${DELCMDCLOSE}/$1/sg ;
- $cnt += $body =~ s/${DELCMDOPEN}//g ;
- # remove aux commands
- # $cnt +=
- $body =~ s/^.*${AUXCMD}$/${someword}/mg; $body =~ s/${someword}\n//g;
-
- #### remove deleted comments
- ###$cnt += $body =~ s/${DIFDELCMD}.*?$//mg ;
- $cnt==0 || warn 'Remaining $DELOPEN or $DIFDELCMD tokens in ACCEPT mode\n' unless ( $quiet || $simplify );
-}
-
-# Remove comment commands
-if (defined($comment)) {
- print STDERR "Removing \\$comment\{..\} sequences (incl. argument)..." if $verbose;
- # protect $comments in comments by making them look different
- $body =~ s/(%.*)${comment}(.*)$/$1${someword}$2/mg ;
- # carry out the substitution
- $cnt = 0 + $body =~ s/\\${comment}(?:\[${brat0}\])?\{${pat_n}\}//sg ;
- print STDERR "$cnt matches found and removed.\n" if $verbose;
- # and undo the protection substitution
- $body =~ s/(%.*)${someword}(.*)$/$1${comment}$2/mg ;
-}
-if (defined($comenv)) {
- print STDERR "Removing $comenv environments ..." if $verbose;
- $body =~ s/(%.*)${comenv}/$1${someword}/mg ;
-## $cnt = 0 + $body =~ s/\\begin(?:\[${brat0}\])?\{\$comenv\}.*?\\end\{\$comenv\}//sg ;
- $cnt = 0 + $body =~ s/\\begin(?:\[${brat0}\])?\{${comenv}\}.*?\\end\{${comenv}\}\s*?\n//sg ;
- print STDERR "$cnt matches found and removed.\n" if $verbose;
- $body =~ s/(%.*)${someword}/$1${comenv}/mg ;
-}
-
-if (defined($markup)) {
- print STDERR "Removing \\$markup\{..\} commands (leaving argument)..." if $verbose;
- # protect $markups in comments by making them look different
- $body =~ s/(%.*)${markup}(.*)$/$1${someword}$2/mg ;
- # carry out the substitution
- $cnt = 0 + $body =~ s/\\${markup}(?:\[${brat0}\])?\{(${pat_n})\}/$1/sg ;
- print STDERR "$cnt matches found and removed.\n" if $verbose;
- # and undo the protection substitution
- $body =~ s/(%.*)${someword}(.*)$/$1${markup}$2/mg ;
-}
-if (defined($markenv)) {
- print STDERR "Removing $markenv environments ..." if $verbose;
- $body =~ s/(%.*)${markenv}/$1${someword}/mg ;
- $cnt = 0 + $body =~ s/\\begin(?:\[${brat0}\])?\{${markenv}\}\n?//sg;
- $cnt += 0 + $body =~ s/\\end\{${markenv}\}\n?//sg;
- print STDERR $cnt/2, " matches found and removed.\n" if $verbose;
- $body =~ s/(%.*)${someword}/$1${markenv}/mg ;
-}
-
-
-if ( length $preamble ) {
- print "$preamble\\begin{document}${body}\\end{document}$post";
-} else {
- print $body;
-}
-
-# checkpure(@matches)
-# checks whether any of the strings in matches contains
-# $ADDMARKOPEN, $ADDMARKCLOSE,$DELMARKOPEN, or $DELMARKCLOSE
-# If so, die reporting nesting problems, otherwise return to caller
-sub checkpure {
- while (defined($_=shift)) {
- if ( /$ADDMARKOPEN/ || /$ADDMARKCLOSE/
- || /$DELMARKOPEN/ || /$DELMARKCLOSE/ ) {
- die <<EOF ;
-There is a problem with nesting of $ADDMARKOPEN, $ADDMARKCLOSE,
-$DELMARKOPEN, and $DELMARKCLOSE tokens that prevents me from
-processing the file. Exiting ...
-EOF
- }
- }
-}
-
-# ($part1,$part2,$part3)=splitdoc($text,$word1,$word2)
-# splits $text into 3 parts at $word1 and $word2.
-# if neither $word1 nor $word2 exist, $part1 and $part3 are empty, $part2 is $text
-# If only $word1 or $word2 exist but not the other, output an error message.
-#
-# same subroutine as in latexdiff
-sub splitdoc {
- my ($text,$word1,$word2)=@_;
- my $l1 = length $word1 ;
- my $l2 = length $word2 ;
-
- my $i = index($text,$word1);
- my $j = index($text,$word2);
-
- my ($part1,$part2,$part3)=("","","");
-
- if ( $i<0 && $j<0) {
- # no $word1 or $word2
- print STDERR "Old Document not a complete latex file. Assuming it is a tex file with no preamble.\n";
- $part2 = $text;
- } elsif ( $i>=0 && $j>$i ) {
- $part1 = substr($text,0,$i) ;
- $part2 = substr($text,$i+$l1,$j-$i-$l1);
- $part3 = substr($text,$j+$l2) unless $j+$l2 >= length $text;
- } else {
- die "$word1 or $word2 not in the correct order or not present as a pair."
- }
- return ($part1,$part2,$part3);
-}
-
-
-
-sub usage {
- die <<"EOF";
-Usage: $0 [OPTIONS] [diff.tex] > revised.tex
-
-Read a file diff.tex (output of latexdiff), and remove its markup.
-If no filename is given read from standard input. The command can be used
-in ACCEPT, DECLINE, or SIMPLIFY mode, and be used to remove user-defined
-latex commands from the input (see options -c, -e, -m, -n below).
-In ACCEPT mode, all appended text fragments (or preamble lines)
-are kept, and all discarded text fragments (or preamble lines) are
-deleted.
-In DECLINE mode, all discarded text fragments are kept, and all appended
-text fragments are deleted.
-If you wish to keep some changes, edit the diff.tex file in
-advance, and manually remove those tokens which would otherwise be
-deleted. Note that latexrevise only pays attention to the \\DIFaddbegin,
-\\DIFaddend, \\DIFdelbegin, and \\DIFdelend tokens and corresponding FL
-varieties. All \\DIFadd and \\DIFdel commands (but not their content) are
-simply deleted. The commands added by latexdiff to the preamble are also
-removed.
-In SIMPLIFY mode all latexdiff markup is removed from the body of the text (after
-\\begin{document}) except for \\DIFaddbegin, \\DIFaddend, \\DIFdelbegin, \\DIFdelend
-tokens and the corresponding FL varieties of those commands. The result
-will not in general be valid latex-code but might be easier to read and edit in
-preparation for a subsequent run in ACCEPT or DECLINE mode.
-In SIMPLIFY mode the preamble is left unmodified.
-
--a
---accept Run in ACCEPT mode (delete all blocks marked by \\DIFdelbegin
- and \\DIFdelend).
-
--d
---decline Run in DECLINE mode (delete all blocks marked by \\DIFaddbegin
- and \\DIFaddend).
-
--s
---simplify Run in SIMPLIFY mode (Keep all \\DIFaddbegin, \\DIFaddend,
- \\DIFdelbegin, \\DIFdelend tokens, but remove all other latexdiff
- markup from body.
-
-Note that the three mode options are mutually exclusive. If no mode option is given,
-latexrevise simply removes user annotations and markup according to the following four
-options.
-
-
--c cmd
---comment=cmd Remove \\cmd{...}. cmd is supposed to mark some explicit
- annotations which should be removed from the file before
- release.
-
--e envir
---comment-environment=envir
- Remove explicit annotation environments from the text, i.e. remove
- \\begin{envir}
- ...
- \\end{envir}
- blocks.
-
--m cmd
---markup=cmd Remove the markup command cmd but leave its argument, i.e.
- turn \\cmd{abc} into abc.
-
--n envir
---markup-environment=envir
- Similarly, remove \\begin{envir} and \\end{envir} commands,
- but leave content of the environment in the text.
-
--q
---no-warnings Do not warn users about \\DIDadd{..} or \\DIFdel statements
- which should not be there anymore
-
--V
---verbose Verbose output
-
-EOF
-}
-
-=head1 NAME
-
-latexrevise - selectively remove markup and text from latexdiff output
-
-=head1 SYNOPSIS
-
-B<latexrevise> [ B<OPTIONS> ] [ F<diff.tex> ] > F<revised.tex>
-
-=head1 DESCRIPTION
-
-I<latexrevise> reads a file C<diff.tex> (output of I<latexdiff>), and remove the markup commands.
-If no filename is given the input is read from standard input. The command can be used
-in I<ACCEPT>, I<DECLINE>, or I<SIMPLIFY> mode, or can be used to remove user-defined
-latex commands from the input (see B<-c>, B<-e>, B<-m>, and B<-n> below).
-In I<ACCEPT> mode, all appended text fragments (or preamble lines)
-are kept, and all discarded text fragments (or preamble lines) are
-deleted.
-In I<DECLINE> mode, all discarded text fragments are kept, and all appended
-text fragments are deleted.
-If you wish to keep some changes, edit the diff.tex file in
-advance, and manually remove those tokens which would otherwise be
-deleted. Note that I<latexrevise> only pays attention to the C<\DIFaddbegin>,
-C<\DIFaddend>, C<\DIFdelbegin>, and C<\DIFdelend> tokens and corresponding FL
-varieties. All C<\DIFadd> and C<\DIFdel> commands (but not their contents) are
-simply deleted. The commands added by latexdiff to the preamble are also
-removed.
-In I<SIMPLIFY> mode, C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>
-tokens and their corresponding C<FL> varieties are kept but all other markup (e.g. C<DIFadd> and <\DIFdel>) is removed. The result
-will not in general be valid latex-code but it will be easier to read and edit in
-preparation for a subsequent run in I<ACCEPT> or I<DECLINE> mode.
-In I<SIMPLIFY> mode the preamble is left unmodified.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-a> or B<--accept>
-
-Run in I<ACCEPT> mode (delete all blocks marked by C<\DIFdelbegin> and C<\DIFdelend>).
-
-=item B<-d> or B<--decline>
-
-Run in I<DECLINE> mode (delete all blocks marked by C<\DIFaddbegin>
-and C<\DIFaddend>).
-
-=item B<-s> or B<--simplify>
-
-Run in I<SIMPLIFY> mode (Keep all C<\DIFaddbegin>, C<\DIFaddend>,
-C<\DIFdelbegin>, C<\DIFdelend> tokens, but remove all other latexdiff
-markup from body).
-
-=back
-
-Note that the three mode options are mutually exclusive. If no mode option is given,
-I<latexrevise> simply removes user annotations and markup according to the following four
-options.
-
-=over 4
-
-=item B<-c cmd> or B<--comment=cmd>
-
-Remove C<\cmd{...}> sequences. C<cmd> is supposed to mark some explicit
-annotations which should be removed from the file before
-release.
-
-=item B<-e envir> or B<--comment-environment=envir>
-
-Remove explicit annotation environments from the text, i.e. remove
-
- \begin{envir}
- ...
- \end{envir}
-
-blocks.
-
-=item B<-m cmd> or B<--markup=cmd>
-
-Remove the markup command C<\cmd> but leave its argument, i.e.
-turn C<\cmd{abc}> into C<abc>.
-
-=item B<-n envir> or B<--markup-environment=envir>
-
-Similarly, remove C<\begin{envir}> and C<\end{envir}> commands but
-leave content of the environment in the text.
-
-
-=item B<-V> or B<--verbose>
-
-Verbose output
-
-=item B<-q> or B<--no-warnings>
-
-Do not warn users about C<\DIDadd{..}> or C<\DIFdel{..}> statements
-which should have been removed already.
-
-=back
-
-=head1 BUGS
-
-The current version is a beta version which has not yet been
-extensively tested. It has not been actively maintained so might not process output of newer versions of latexdiff entirely correctly.
-Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>,
-or send them to I<tilmann -- AT -- gfz-potsdam.de>. Include the serial number of I<latexrevise>
-(Option --version). If you come across latexdiff
-output which is not processed correctly by I<latexrevise> please include the
-problem file as well as the old and new files on which it is based,
-ideally edited to only contain the offending passage as long as that still
-reproduces the problem.
-
-Note that I<latexrevise> gets confused by commented C<\begin{document}> or
-C<\end{document}> statements
-
-=head1 SEE ALSO
-
-L<latexdiff>
-
-=head1 PORTABILITY
-
-I<latexrevise> does not make use of external commands and thus should run
-on any platform supporting PERL v5 or higher.
-
-=head1 AUTHOR
-
-Copyright (C) 2004 Frederik Tilmann
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License Version 3
-
-=cut
diff --git a/Build/source/texk/texlive/linked_scripts/latexfileversion/latexfileversion b/Build/source/texk/texlive/linked_scripts/latexfileversion/latexfileversion
deleted file mode 100755
index bae05f520aa..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latexfileversion/latexfileversion
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env bash
-## latexfileversion
-##
-## This simple shell script prints the version and date of a LaTeX class or
-## style file.
-##
-## Version 0.3, 2011-12-31, Add support for arbitrary tex input file types
-## Rename from getfileversion to latexfileversion
-## Version 0.2, 2011-12-30, Avoid special characters as guillemots
-## Version 0.1, 2005-04-30, Initial version
-##
-## Copyright 2005, 2011 Harald Harders, harald.harders@gmx.de
-##
-## This programme may be distributed and/or modified under the
-## conditions of the LaTeX Project Public License, either version 1.2
-## of this license or (at your option) any later version.
-## The latest version of this license is in
-## http://www.latex-project.org/lppl.txt
-## and version 1.2 or later is part of all distributions of LaTeX
-## version 1999/12/01 or later.
-##
-## This programme consists of the files
-## latexfileversion, README, and ChangeLog.
-VERSION=0.3
-
-# help screen
-if [ -z "$1" ]
-then
- echo 'latexfileversion v'$VERSION >&2
- echo '' >&2
- echo 'This programme prints the version and date of a LaTeX class or' >&2
- echo 'style file.' >&2
- echo '' >&2
- echo 'Syntax:' >&2
- echo 'latexfileversion <file>' >&2
- echo '' >&2
- echo 'This programme handles style files (extension .sty),' >&2
- echo 'class files (extension .cls), and other tex input files.' >&2
- echo 'The file extension must be given.' >&2
- exit 1
-fi
-
-# make temporary directory
-TMPDIR=`mktemp -d /tmp/latexfileversion.XXXXXX` || exit 1
-cd $TMPDIR
-
-# extract basenames for extensions .cls and .sty
-FILE=$1
-STYLE=${1%%.sty}
-CLASS=${1%%.cls}
-
-# handle .cls files and .sty files seperately
-if [ "$CLASS.cls" == "$FILE" ]
-then
- echo -n "Looking for class file '$CLASS.cls': "
- # generate temporary LaTeX file
-(
-cat << EOM
-\documentclass{$CLASS}
-\nofiles
-\makeatletter
-\def\GetFileInfo#1{%
- \def\filename{#1}%
- \def\@tempb##1 ##2 ##3\relax##4\relax{%
- \def\filedate{##1}%
- \def\fileversion{##2}%
- \def\fileinfo{##3}}%
- \edef\@tempa{\csname ver@#1\endcsname}%
- \expandafter\@tempb\@tempa\relax? ? \relax\relax}
-\makeatother
-\GetFileInfo{$CLASS.cls}
-\typeout{VERSION \fileversion, \filedate}
-\begin{document}
-\end{document}
-EOM
-) > latexfileversion.tex
-else
- if [ "$STYLE.sty" == "$FILE" ]
- then
- echo -n "Looking for style file '$STYLE.sty': "
- # generate temporary LaTeX file
-(
-cat << EOM
-\documentclass{ltxdoc}
-\nofiles
-\usepackage{$STYLE}
-\GetFileInfo{$STYLE.sty}
-\typeout{VERSION \fileversion, \filedate}
-\begin{document}
-\end{document}
-EOM
-) > latexfileversion.tex
- else
- echo -n "Looking for file '$FILE': "
- # generate temporary LaTeX file
-(
-cat << EOM
-\documentclass{ltxdoc}
-\nofiles
-\input{$FILE}
-\GetFileInfo{$FILE}
-\typeout{VERSION \fileversion, \filedate}
-\begin{document}
-\end{document}
-EOM
-) > latexfileversion.tex
- fi
-fi
-
-# run temporary LaTeX file which writes »VERSION ...« into the logfile
-pdflatex -interaction=nonstopmode latexfileversion.tex > /dev/null
-# extract the line containing »VERSION« and remove »VERSION «
-grep -e '^VERSION' latexfileversion.log | sed 's/VERSION //'
-
-# delete temporary directory
-rm -rf $TMPDIR
-
-#EOF
diff --git a/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl b/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl
deleted file mode 100755
index f38d6c3fb53..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env perl
-# latexindent.pl, version 3.8.3, 2020-11-06
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# See http://www.gnu.org/licenses/.
-#
-# Chris Hughes, 2017
-#
-# For all communication, please visit: https://github.com/cmhughes/latexindent.pl
-
-use strict;
-use warnings;
-use FindBin; # help find defaultSettings.yaml
-use Getopt::Long; # to get the switches/options/flags
-
-# use lib to make sure that @INC contains the latexindent directory
-use lib $FindBin::RealBin;
-use LatexIndent::Document;
-
-# get the options
-my %switches = (readLocalSettings=>0);
-
-GetOptions (
- "version|v"=>\$switches{version},
- "silent|s"=>\$switches{silentMode},
- "trace|t"=>\$switches{trace},
- "ttrace|tt"=>\$switches{ttrace},
- "local|l:s"=>\$switches{readLocalSettings},
- "yaml|y=s"=>\$switches{yaml},
- "onlydefault|d"=>\$switches{onlyDefault},
- "overwrite|w"=>\$switches{overwrite},
- "outputfile|o=s"=>\$switches{outputToFile},
- "modifylinebreaks|m"=>\$switches{modifyLineBreaks},
- "logfile|g=s"=>\$switches{logFileName},
- "help|h"=>\$switches{showhelp},
- "cruft|c=s"=>\$switches{cruftDirectory},
- "screenlog|sl"=>\$switches{screenlog},
- "replacement|r"=>\$switches{replacement},
- "onlyreplacement|rr"=>\$switches{onlyreplacement},
- "replacementrespectverb|rv"=>\$switches{replacementRespectVerb},
-);
-
-# check local settings doesn't interfer with reading the file;
-# this can happen if the script is called as follows:
-#
-# latexindent.pl -l myfile.tex
-#
-# in which case, the GetOptions routine mistakes myfile.tex
-# as the optional parameter to the l flag.
-#
-# In such circumstances, we correct the mistake by assuming that
-# the only argument is the file to be indented, and place it in @ARGV
-if($switches{readLocalSettings} and scalar(@ARGV) < 1) {
- push(@ARGV,$switches{readLocalSettings});
- $switches{readLocalSettings} = '';
-}
-
-# default value of readLocalSettings
-#
-# latexindent -l myfile.tex
-#
-# means that we wish to use localSettings.yaml
-if(defined($switches{readLocalSettings}) and ($switches{readLocalSettings} eq '')){
- $switches{readLocalSettings} = 'localSettings.yaml';
-}
-
-# allow STDIN as input, if a filename is not present
-unshift( @ARGV, '-' ) unless @ARGV;
-
-my $document = bless ({name=>"masterDocument",modifyLineBreaksYamlName=>"masterDocument",fileName=>$ARGV[0],switches=>\%switches},"LatexIndent::Document");
-$document->latexindent;
-exit(0);
diff --git a/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl b/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
deleted file mode 100755
index a05e938f912..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
+++ /dev/null
@@ -1,10187 +0,0 @@
-#!/usr/bin/env perl
-
-#!!!!!!!!!!!!!!!!!!!????????? CLEAN UP INITIALIZATION
-#!!! See all FIX items.
-
-# Perhaps add subroutine rdb_change_active( (rules to deactivate), (rules to activate))
-
-# ?? Still need to fix bcf error issue.
-# Don't keep looping after error
-# pvc: Only re-run on USER FILE CHANGE.
-# See # ??????? BCF
-
-
-#!!!!!!!!??? Check @pwd_log
-
-
-# !!!!!!!!!! Don't forget to document $silence_logfile_warnings.!!!
-
-# N.B. !!!!!!!!!!! See 17 July 2012 comments !!!!!!!!!!!!!!!!!!
-
-# On a UNIX-like system, the above enables latexmk to run independently
-# of the location of the perl executable. This line relies on the
-# existence of the program /usr/bin/env
-# If there is a problem for any reason, you can replace the first line of
-# this file by:
-
-#!/usr/bin/perl -w
-
-# with the path of the perl executable adjusted for your system.
-
-use warnings;
-
-# Delete #??!! when working
-
-# See ?? <===============================
-
-## ?? Issues with clean-up
-## List of aux files deleted is those read, not those generated.
-## Other files are generated by *latex; should they be deleted?
-## (I have hooks for this).
-
-
-
-#=======================================
-
-#?? Force mode doesn't appear to do force (if error in latex file)
-#??? Get banner back in.
-#?? CORRECT DIAGNOSTICS ON CHANGED FILES IF THEY DIDN'T EXIST BEFORE
-#?? Further corrections to deal with disappeared source files for custom dependencies.
-# Message repeatedly appears about remake when source file of cusdep doesn't exist.
-#?? logfile w/o fdb file: don't set changed file, perhaps for generated exts.
-# Reconsider
-#?? Do proper run-stuff for bibtex, makeindex, cus-deps. OK I think
-# Parse and correctly find ist files
-
-
-# ATTEMPT TO ALLOW FILENAMES WITH SPACES:
-# (as of 1 Apr 2006, and then 14 Sep. 2007)
-
-# Problems:
-# A. Quoting filenames will not always work.
-# a. Under UNIX, quotes are legal in filenames, so when PERL
-# directly runs a binary, a quoted filename will be treated as
-# as a filename containing a quote character. But when it calls
-# a shell, the quotes are handled by the shell as quotes.
-# b. Under MSWin32, quotes are illegal filename characters, and tend
-# to be handled correctly.
-# c. But under cygwin, results are not so clear (there are many
-# combinations: native v. cygwin perl, native v cygwin programs
-# NT v. unix scripts, which shell is called.
-# B. TeX doesn't always handle filenames with spaces gracefully.
-# a. UNIX/LINUX: The version on gluon2 Mar 31, 2006 to Sep. 2007)
-# doesn't handle them at all. (TeX treats space as separator.)
-# b. At least some later versions actually do (Brad Miller e-mail,
-# Sep. 2007).
-# c. fptex [[e-TeXk, Version 3.141592-2.1 (Web2c 7.5.2)] does, on
-# my MSWin at home. In \input the filename must be in quotes.
-# d. Bibtex [BibTeX (Web2c 7.5.2) 0.99c on my MSWin system at home,
-# Sep. 2007] does not allow names of bibfiles to have spaces.
-# C. =====> Using the shell for command lines is not safe, since special
-# characters can cause lots of mayhem.
-# It will therefore be a good idea to sanitize filenames.
-#
-# I've sanitized all calls out:
-# a. system and exec use a single argument, which forces
-# use of shell, under all circumstances
-# Thus I can safely use quotes on filenames: They will be handled by
-# the shell under UNIX, and simply passed on to the program under MSWin32.
-# b. I reorganized Run, Run_Detached to use single command line
-# c. All calls to Run and Run_Detached have quoted filenames.
-# d. So if a space-free filename with wildcards is given on latexmk's
-# command line, and it globs to space-containing filename(s), that
-# works (fptex on home computer, native NT tex)
-# e. ====> But globbing fails: the glob function takes space as filename
-# separator. ====================
-
-#================= TO DO ================
-#
-# 1. See ?? ESPECIALLY $MSWin_fudge_break
-# 2. Check fudged conditions in looping and make_files
-# 3. Should not completely abort after a run that ends in failure from latex
-# Missing input files (including via custom dependency) should be checked for
-# a change in status
-# If sources for missing files from custom dependency
-# are available, then do a rerun
-# If sources of any kind become available rerun (esp. for pvc)
-# rerun
-# Must parse log_file after unsuccessful run of latex: it may give
-# information about missing files.
-# 4. Check file of bug reports and requests
-# 5. Rationalize bibtex warnings and errors. Two almost identical routines.
-# Should 1. Use single routine
-# 2. Convert errors to failure only in calling routine
-# 3. Save first warning/error.
-
-# ?? Use of generated_exts arrays and hashes needs rationalization
-
-# To do:
-# Rationalize again handling of include files.
-# Now I use kpsewhich to do searches, if file not found
-# (How do I avoid getting slowed down too much?)
-# Document the assumptions at each stage of processing algorithm.
-# Option to restart previewer automatically, if it dies under -pvc
-# Test for already running previewer gets wrong answer if another
-# process has the viewed file in its command line
-
-## Copyright John Collins 1998-2020
-## (username jcc8 at node psu.edu)
-## (and thanks to David Coppit (username david at node coppit.org)
-## for suggestions)
-## Copyright Evan McLean
-## (modifications up to version 2)
-## Copyright 1992 by David J. Musliner and The University of Michigan.
-## (original version)
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-##
-##
-##
-## NEW FEATURES, since v. 2.0:
-## 1. Correct algorithm for deciding how many times to run latex:
-## based on whether source file(s) change between runs
-## 2. Continuous preview works, and can be of ps file or dvi file
-## 3. pdf creation by pdflatex possible
-## 4. Defaults for commands are OS dependent.
-## 5. Parsing of log file instead of source file is used to
-## obtain dependencies, by default.
-##
-## Modification log from 9 Dec 2011 onwards in detail
-##
-## 12 Jan 2012 STILL NEED TO DOCUMENT some items below
-##
-## 29 Sep 2020 John Collins V. 4.70b.
-## Correct switch_output.
-## Try to ensure bibtex isn't given absolute pathname, when aux_dir
-## is under current directory. (Otherwise bibtex isn't allowed
-## to write a bbl file under default TeXLive settings.)
-## Add options -bibfudge, -bibfudge-, -nobibfudge.
-## 13 Sep 2020 John Collins V. 4.70a. Updates in comments about bibtex.
-## 28 Aug 2020 John Collins Correct $biber and $bibtex to use %S not %B
-## 24 Aug 2020 John Collins Make sure bibtex/biber rules when created for
-## missing bbl file have correct path for source
-## and destination when out/aux dir used.
-## 16 Jun 2020 John Collins Warning when bibtex fudge is used.
-## Change default $bibtex_fudge to 0. This is safe with
-## at least bibtex in TeXLive 2019 or later, and in current
-## MiKTeX. This version of latexmk is distributed in TeXLive
-## and MiKTeX with a recent enough version of bibtex.
-## Previously, there was a bug in bibtex that prevented it
-## working correctly when -output-directory is used. Latexmk
-## took special action to evade the bug, but at the expense
-## of problems when a .bib file is specified in a directory
-## relative to the document directory.
-## V. 4.69c
-## 9 Jun 2020 John Collins Fix problems with excess calls to parse_log, and messages
-## about changing rule structure when .fdb_latexmk file
-## does not exist.
-## Making quoting (or not) of output and aux directories
-## for option to *latex obey $quote_filenames.
-## 8 Jun 2020 John Collins Engine detection: note that recent lualatex
-## uses luaHBtex, not luatex. So I modified the one
-## place that the name of the $engine is used.
-## 6 May 2020 John Collins Add diagnostic for changed environment variables
-## 27 Apr 2020 John Collins Put ./ for latexmkrc files in current directory
-## V. 4.69b
-## Current version (4.69a, 17 Apr 2020) to CTAN
-## 16 Apr 2020 John Collins Correct contents of "All targets (...) are up-to-date" message
-## V. 4.69a.
-## 12 Mar 2020 John Collins Version is 4.69
-## 7 Feb 2020 John Collins Report rc files read
-## 6 Feb 2020 John Collins Fix bug when -cd and -outdir are used, and outdir is
-## same as document directory. (Bug is caused by
-## problem in perl module Cwd.)
-## 2,3 Feb 2020 John Collins Correction in find_basename.
-## 31 Jan 2020 John Collins Cleanup sub exit_msg1: incorrect comment etc.
-## Extra @file_not_found entry for message from
-## \input on not-found-file
-## Remove use of $extension_treatment: Too hard to
-## check. Always use what was called 'unix' method.
-## When command-line-specified tex file not found,
-## test for cusdep to make it, then try kpsewhich,
-## and only if all 3 fail report an error.
-## 15 Jan 2020 John Collins Add -MSWinBackSlash -MSWinBackSlash- options to
-## control whether directory separator '\' is
-## used for filenames on command line for
-## called programs under MSWin.
-## 3 Jan 2020 John Collins Add -E option to default command for xdvipdfmx, to
-## match call made by xetex (see XeTeX_ext.c in
-## xetex source). This forces xdvipdfmx to always
-## try to embed fonts, ignoring licensing flags, etc.
-##
-## Current version (4.67, 26 Dec 2019) to CTAN
-## 26 Dec 2019 John Collins Change place of setting of $view_file
-## Make fully consistent set of options for engines:
-## -latex, -latex=...,
-## preserving backward compatibility, and avoiding suprises.
-## 11 Dec 2019 John Collins Change rules for wrapping in log file: This deals
-## with xelatex wrapping at > standard number of
-## bytes in presence of non-ASCII Unicode characters.
-## 4 Dec 2019 John Collins If there were missing subdirectories in output/aux
-## directories, and these were successfully created,
-## then ignore error from *latex, since rerun may
-## succeed.
-## 14 Nov 2019 John Collins Add comment.
-## 12 Nov 2019 John Collins Use $compiling_cmd, $warning_cmd, $success_cmd
-# on normal make, rather than just in -pvc mode.
-## 5 Aug 2019 John Collins The changing of '\' to '/' in filenames is now
-## done for msys as well as MSWin32.
-## 8 Jul 2019 John Collins Allow addition of hook for processing lists of
-## missing source files, used after run of *latex.
-## 2 Jul 2019 John Collins Silence message about disallowing change of output
-## file type.
-## V. 4.66
-## 28 Jun 2019 John Collins Try to deal with log file parsing problems
-## V. 4.65
-## 21 May 2019 John Collins Fix incorrect listings by -rules and by -deps
-## 21 May 2019 John Collins V. 4.64a.
-## 20,21 May 2019 John Collins Fix problem with not always running dvipdf,
-## dvips, xdvpdf because of missing information
-## on source files. Do this by adding a
-## source_rule hash to each rule and adding a
-## pass-based criterion for out-of-dateness
-## 20 May 2019 John Collins V. 4.64.
-## 17 Mar 2019 John Collins V. 4.63c.
-## 18 Mar 2019 John Collins Update copyright date
-## 17 Mar 2019 John Collins Further test for problems when linking rules
-## 17 Mar 2019 John Collins V. 4.63b.
-## 17 Mar 2019 John Collins Fix problem revealed by bibtopic package
-## 15 Mar 2019 John Collins Corrections
-## 14 Mar 2019 John Collins Version to 4.63a
-## 12-14 Mar 2019 John Collins Jobname has placeholder
-## 8-11 Mar 2019 John Collins Correct aux-dir bugs
-## 8 Mar 2019 John Collins Version to 4.63
-## 1 Jan 2019 John Collins Correct bug in output switching code
-## 31 Dec 2018 John Collins Correct bug that with $cleanup_includes_generated
-## -c mode deletes final output files (e.g., .dvi, .pdf).
-## 13 Dec 2018 John Collins Fixes, cleanup
-## 12 Dec 2018 John Collins Fix rdb_read
-## 11 Dec 2018 John Collins For output-switch: Reorganize initialization
-## Remove possibility of more than one primary.
-## 1 Dec 2018 John Collins Clean up some code.
-## 30 Nov 2018 John Collins Allow any characters in directory part of tex
-## filename when cd mode on. (Still standard
-## set of disallowed characters applies basename.)
-## 21 Nov 2018 John Collins Infrastructure finished, I think, for active flag
-## Start on output switch
-## 16 Nov 2018 John Collins Remove in non-diagnostics mode a warning about
-## rule not in use in this session that is given
-## when reading an fdb_latexmk file.
-## 2 Nov 2018 John Collins Start implementing active flag for rules.
-## 1 Nov 2018 John Collins Fix finding of missing files that are relative to aux_dir
-## 29-31 Oct 2018 John Collins Some cleanup.
-## 27,28 Oct 2018 John Collins Fix bug that in -pvc mode, after an error in
-## certain rules, new rounds of compilation
-## are triggered because of changes in generated
-## files, instead of only by later user-generated
-## changes.
-## Improve linking of rules.
-## 25 Oct 2018 John Collins V. 4.62
-## Clean up can remove (empty) directories
-## 25 Oct 2018 John Collins Fix definition of clean up substitution for %R
-## so that something with intermediate %R works,
-## as in 'pythontex-files-%R/*'.
-##
-## 1998-2018, John Collins. Many improvements and fixes.
-## See CHANGE-log.txt for full list, and CHANGES for summary
-##
-## Modified by Evan McLean (no longer available for support)
-## Original script (RCS version 2.3) called "go" written by David J. Musliner
-##
-##-----------------------------------------------------------------------
-
-## Explicit exit codes:
-## 10 = bad command line arguments
-## 11 = file specified on command line not found
-## or other file not found
-## 12 = failure in some part of making files
-## 13 = error in initialization file
-## 20 = probable bug
-## or retcode from called program.
-
-$my_name = 'latexmk';
-$My_name = 'Latexmk';
-$version_num = '4.70b';
-$version_details = "$My_name, John Collins, 29 September 2020";
-
-use Config;
-use File::Basename;
-use File::Copy;
-use File::Spec;
-
-# If possible, use better glob, which does not use space as item separator.
-# It's either File::Glob::bsd_glob or File::Glob::glob
-# The first does not exist in old versions of Perl, while the second
-# is deprecated in more recent versions and will be removed
-$have_bsd_glob = 0;
-sub my_glob {
- if ($have_bsd_glob) { return bsd_glob( $_[0] ); }
- else { return glob( $_[0] ); }
-}
-use File::Glob;
-if ( eval{ File::Glob->import('bsd_glob'); 1; } ) {
- # Success in importing bsd_glob
- $have_bsd_glob = 1;
-}
-elsif ( eval{ File::Glob->import('glob'); 1; } ) {
- warn "$My_name: I could not import File::Glob:bsd_glob, probably because your\n",
- " Perl is too old. I have arranged to use the deprecated File::Glob:glob\n",
- " instead.\n",
- " WARNING: It may malfunction on clean up operation on filenames containing\n",
- " spaces.\n";
- $have_bsd_glob = 0;
-}
-else {
- die "Could not import 'File::Glob:bsd_glob' or 'File::Glob:glob'\n";
-}
-
-use File::Path 2.08 qw( make_path );
-use FileHandle;
-use File::Find;
-use List::Util qw( max );
-use Cwd; # To be able to change cwd
-#use Cwd "chdir"; # Ensure $ENV{PWD} tracks cwd. NO NEED, and it messes up -cd -outdir=
-use Digest::MD5;
-
-#use strict;
-
-# The following variables are assigned once and then used in symbolic
-# references, so we need to avoid warnings 'name used only once':
-use vars qw( $dvi_update_command $ps_update_command $pdf_update_command );
-
-# Translation of signal names to numbers and vv:
-%signo = ();
-@signame = ();
-if ( defined $Config{sig_name} ) {
- $i = 0;
- foreach $name (split('\s+', $Config{sig_name})) {
- $signo{$name} = $i;
- $signame[$i] = $name;
- $i++;
- }
-}
-else {
- warn "Something wrong with the perl configuration: No signals?\n";
-}
-
-
-# Line length in log file that indicates wrapping.
-# This number EXCLUDES line-end characters, and is one-based.
-# It is the parameter max_print_line in the TeX program. (tex.web)
-$log_wrap = 79;
-
-#########################################################################
-## Default parsing and file-handling settings
-
-## Array of reg-exps for patterns in log-file for file-not-found
-## Each item is the string in a regexp, without the enclosing slashes.
-## First parenthesized part is the filename.
-## Note the need to quote slashes and single right quotes to make them
-## appear in the regexp.
-## Add items by push, e.g.,
-## push @file_not_found, '^No data file found `([^\\\']*)\\\'';
-## will give match to line starting "No data file found `filename'"
-@file_not_found = (
- '^No file\\s*(.*)\\.$',
- '^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.',
- '^\\! I can\\\'t find file `([^\\\']*)\\\'\\.',
- '.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.',
- '^LaTeX Warning: File `([^\\\']*)\\\' not found',
- '^Package .* [fF]ile `([^\\\']*)\\\' not found',
- '^Package .* No file `([^\\\']*)\\\'',
- 'Error: pdflatex \(file ([^\)]*)\): cannot find image file',
- ': File (.*) not found:\s*$',
- '! Unable to load picture or PDF file \\\'([^\\\']+)\\\'.',
-);
-
-# Characters that we won't allow in the name of a TeX file.
-# Notes: Some are disallowed by TeX itself.
-# '\' results in TeX macro expansion
-# '$' results in possible variable substitution by kpsewhich called from tex.
-# '"' gets special treatment.
-# See subroutine test_fix_texnames and its call for their use.
-$illegal_in_texname = "\x00\t\f\n\r\$%\\~\x7F";
-
-
-## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp,
-# whose matching by a line in a file with that extension indicates that the
-# line is to be ignored in the calculation of the hash number (md5 checksum)
-# for the file. Typically used for ignoring datestamps in testing whether
-# a file has changed.
-# Add items e.g., by
-# $hash_calc_ignore_pattern{'eps'} = '^%%CreationDate: ';
-# This makes the hash calculation for an eps file ignore lines starting with
-# '%%CreationDate: '
-# ?? Note that a file will be considered changed if
-# (a) its size changes
-# or (b) its hash changes
-# So it is useful to ignore lines in the hash calculation only if they
-# are of a fixed size (as with a date/time stamp).
-%hash_calc_ignore_pattern =();
-
-
-# Specification of templates for extra rules.
-# See subroutine rdb_initialize_rules for examples of rule templates, and
-# how they get used to construct rules.
-# (Documentation obviously needs to be improved!)
-%extra_rule_spec = ();
-
-
-# Hooks for customized extra processing on aux files. The following
-# variable is an array of references to functions. Each function is
-# invoked in turn when a line of an aux file is processed (if none
-# of the built-in actions have been done). On entry to the function,
-# the following variables are set:
-# $_ = current line of aux file
-# $rule = name of rule during the invocation of which, the aux file
-# was supposed to have been generated.
-@aux_hooks = ();
-# Hooks for customized processing on lists of source and missing files.
-# The following variable is an array of references to functions. Each
-# function is invoked in turn after a run of latex (or pdflatex etc) and
-# latexmk has analyzed the .log and .fls files for dependency information.
-# On entry to each called function, the following variables are set:
-# $rule = name of *latex rule
-# %dependents: maps source files and possible source files to a status.
-# See begining of sub parse_log for possible values.
-@latex_file_hooks = ();
-
-#########################################################################
-## Default document processing programs, and related settings,
-## These are mostly the same on all systems.
-## Most of these variables represents the external command needed to
-## perform a certain action. Some represent switches.
-
-
-## Which TeX distribution is being used
-## E.g., "MiKTeX 2.9", "TeX Live 2018"
-## "" means not determined. Obtain from first line of .log file.
-$tex_distribution = '';
-
-&std_tex_cmds;
-
-# Possible code to execute by *latex before inputting source file.
-# Not used by default.
-$pre_tex_code = '';
-
-## Default switches:
-$latex_default_switches = '';
-$pdflatex_default_switches = '';
-$lualatex_default_switches = '';
- # Note that xelatex is used to give xdv file, not pdf file, hence
- # we need the -no-pdf option.
-$xelatex_default_switches = '-no-pdf';
-
-## Switch(es) to make them silent:
-$latex_silent_switch = '-interaction=batchmode';
-$pdflatex_silent_switch = '-interaction=batchmode';
-$lualatex_silent_switch = '-interaction=batchmode';
-$xelatex_silent_switch = '-interaction=batchmode';
-
-%input_extensions = ();
-# %input_extensions maps primary_rule_name to pointer to hash of file extensions
-# used for extensionless files specified in the source file by constructs
-# like \input{file} \includegraphics{file}
-set_input_ext( 'latex', 'tex', 'eps' );
-set_input_ext( 'pdflatex', 'tex', 'jpg', 'pdf', 'png' );
-$input_extensions{lualatex} = $input_extensions{pdflatex};
-$input_extensions{xelatex} = $input_extensions{pdflatex};
-# Save these values as standards to be used when switching output,
-# i.e., when actual primary rule differs from standard.
-%standard_input_extensions = %input_extensions;
-
-%allowed_output_ext = ( ".dvi" => 1, ".xdv" => 1, ".pdf" => 1 );
-# Extensions of files preserved when clean up is by -c rather than -C:
-%small_cleanup_preserved_exts = ();
-foreach ( 'dvi', 'dviF', 'ps', 'psF', 'pdf', 'synctex.gz', 'xdv' ) {
- $small_cleanup_preserved_exts{$_} = 1;
-}
-
-
-# Information about options to latex and pdflatex that latexmk will simply
-# pass through to *latex
-# Option without arg. maps to itself.
-# Option with arg. maps the option part to the full specification
-# e.g., -kpathsea-debug => -kpathsea-debug=NUMBER
-%allowed_latex_options = ();
-%allowed_latex_options_with_arg = ();
-foreach (
- #####
- # TeXLive options
- "-draftmode switch on draft mode (generates no output PDF)",
- "-enc enable encTeX extensions such as \\mubyte",
- "-etex enable e-TeX extensions",
- "-file-line-error enable file:line:error style messages",
- "-no-file-line-error disable file:line:error style messages",
- "-fmt=FMTNAME use FMTNAME instead of program name or a %& line",
- "-halt-on-error stop processing at the first error",
- "-interaction=STRING set interaction mode (STRING=batchmode/nonstopmode/\n".
- " scrollmode/errorstopmode)",
- "-ipc send DVI output to a socket as well as the usual\n".
- " output file",
- "-ipc-start as -ipc, and also start the server at the other end",
- "-kpathsea-debug=NUMBER set path searching debugging flags according to\n".
- " the bits of NUMBER",
- "-mktex=FMT enable mktexFMT generation (FMT=tex/tfm/pk)",
- "-no-mktex=FMT disable mktexFMT generation (FMT=tex/tfm/pk)",
- "-mltex enable MLTeX extensions such as \charsubdef",
- "-output-comment=STRING use STRING for DVI file comment instead of date\n".
- " (no effect for PDF)",
- "-output-format=FORMAT use FORMAT for job output; FORMAT is `dvi\" or `pdf\"",
- "-parse-first-line enable parsing of first line of input file",
- "-no-parse-first-line disable parsing of first line of input file",
- "-progname=STRING set program (and fmt) name to STRING",
- "-shell-escape enable \\write18{SHELL COMMAND}",
- "-no-shell-escape disable \\write18{SHELL COMMAND}",
- "-shell-restricted enable restricted \\write18",
- "-src-specials insert source specials into the DVI file",
- "-src-specials=WHERE insert source specials in certain places of\n".
- " the DVI file. WHERE is a comma-separated value\n".
- " list: cr display hbox math par parend vbox",
- "-synctex=NUMBER generate SyncTeX data for previewers if nonzero",
- "-translate-file=TCXNAME use the TCX file TCXNAME",
- "-8bit make all characters printable by default",
-
- #####
- # MikTeX options not in TeXLive
- "-alias=app pretend to be app",
- "-buf-size=n maximum number of characters simultaneously present\n".
- " in current lines",
- "-c-style-errors C-style error messages",
- "-disable-installer disable automatic installation of missing packages",
- "-disable-pipes disable input (output) from (to) child processes",
- "-disable-write18 disable the \\write18{command} construct",
- "-dont-parse-first-line disable checking whether the first line of the main\n".
- " input file starts with %&",
- "-enable-enctex enable encTeX extensions such as \\mubyte",
- "-enable-installer enable automatic installation of missing packages",
- "-enable-mltex enable MLTeX extensions such as \charsubdef",
- "-enable-pipes enable input (output) from (to) child processes",
- "-enable-write18 fully enable the \\write18{command} construct",
- "-error-line=n set the width of context lines on terminal error\n".
- " messages",
- "-extra-mem-bot=n set the extra size (in memory words) for large data\n".
- " structures",
- "-extra-mem-top=n set the extra size (in memory words) for chars,\n".
- " tokens, et al",
- "-font-max=n set the maximum internal font number",
- "-font-mem-size=n set the size, in TeX memory words, of the font memory",
- "-half-error-line=n set the width of first lines of contexts in terminal\n".
- " error messages",
- "-hash-extra=n set the extra space for the hash table of control\n".
- " sequences",
- "-job-time=file set the time-stamp of all output files equal to\n".
- " file's time-stamp",
- "-main-memory=n change the total size (in memory words) of the main\n".
- " memory array",
- "-max-in-open=n set the maximum number of input files and error\n".
- " insertions that can be going on simultaneously",
- "-max-print-line=n set the width of longest text lines output",
- "-max-strings=n set the maximum number of strings",
- "-nest-size=n set the maximum number of semantic levels\n".
- " simultaneously active",
- "-no-c-style-errors standard error messages",
- "-param-size=n set the the maximum number of simultaneous macro\n".
- " parameters",
- "-pool-size=n set the maximum number of characters in strings",
- "-record-package-usages=file record all package usages and write them into\n".
- " file",
- "-restrict-write18 partially enable the \\write18{command} construct",
- "-save-size=n set the the amount of space for saving values\n".
- " outside of current group",
- "-stack-size=n set the maximum number of simultaneous input sources",
- "-string-vacancies=n set the minimum number of characters that should be\n".
- " available for the user's control sequences and font\n".
- " names",
- "-tcx=name process the TCX table name",
- "-time-statistics show processing time statistics",
- "-trace enable trace messages",
- "-trace=tracestreams enable trace messages. The tracestreams argument is\n".
- " a comma-separated list of trace stream names",
- "-trie-size=n set the amount of space for hyphenation patterns",
- "-undump=name use name as the name of the format to be used,\n".
- " instead of the name by which the program was\n".
- " called or a %& line.",
-
- #####
- # Options passed to *latex that have special processing by latexmk,
- # so they are commented out here.
- #-jobname=STRING set the job name to STRING
- #-aux-directory=dir Set the directory dir to which auxiliary files are written
- #-output-directory=DIR use existing DIR as the directory to write files in
- #-quiet
- #-recorder enable filename recorder
- #
- # Options with different processing by latexmk than *latex
- #-help
- #-version
- #
- # Options NOT used by latexmk
- #-includedirectory=dir prefix dir to the search path
- #-initialize become the INI variant of the compiler
- #-ini be pdfinitex, for dumping formats; this is implicitly
- # true if the program name is `pdfinitex'
-) {
- if ( /^([^\s=]+)=/ ) {
- $allowed_latex_options_with_arg{$1} = $_;
- }
- elsif ( /^([^\s=]+)\s/ ) {
- $allowed_latex_options{$1} = $_;
- }
- else {
- $allowed_latex_options{$_} = $_;
- }
-}
-
-# Arrays of options that will be added to latex and pdflatex.
-# These need to be stored until after the command line parsing is finished,
-# in case the values of $latex and/or $pdflatex change after an option
-# is added.
-@extra_latex_options = ();
-@extra_pdflatex_options = ();
-@extra_lualatex_options = ();
-@extra_xelatex_options = ();
-
-
-## Command to invoke biber & bibtex
-$biber = 'biber %O %S';
-$bibtex = 'bibtex %O %S';
-# Switch(es) to make biber & bibtex silent:
-$bibtex_fudge = 0; # Don't use hack to get bibtex working in old versions that
- # don't handle output-directory. When this version of
- # latexmk is part of a distribution of TeX, the
- # accompanying bibtex should also be recent enough
- # (e.g., TeXLive 2019 or later, current MiKTeX) not to
- # need the hack/fudge.
-$biber_silent_switch = '--onlylog';
-$bibtex_silent_switch = '-terse';
-$bibtex_use = 1; # Whether to actually run bibtex to update bbl files.
- # This variable is also used in deciding whether to
- # delete bbl files in clean up operations.
- # 0: Never run bibtex.
- # Do NOT delete bbl files on clean up.
- # 1: Run bibtex only if the bibfiles exists
- # according to kpsewhich, and the bbl files
- # appear to be out-of-date.
- # Do NOT delete bbl files on clean up.
- # 1.5: Run bibtex only if the bibfiles exists
- # according to kpsewhich, and the bbl files
- # appear to be out-of-date.
- # Only delete bbl files on clean up if bibfiles exist.
- # 2: Run bibtex when the bbl files are out-of-date
- # Delete bbl files on clean up.
- #
- # In any event bibtex is only run if the log file
- # indicates that the document uses bbl files.
-
-## Command to invoke makeindex
-$makeindex = 'makeindex %O -o %D %S';
-# Switch(es) to make makeinex silent:
-$makeindex_silent_switch = '-q';
-
-## Command to convert dvi file to pdf file directly:
-$dvipdf = 'dvipdf %O %S %D';
-# N.B. Standard dvipdf runs dvips and gs with their silent switch, so for
-# standard dvipdf $dvipdf_silent_switch is unneeded, but innocuous.
-# But dvipdfmx can be used instead, and it has a silent switch (-q).
-# So implementing $dvipdf_silent_switch is useful.
-
-$dvipdf_silent_switch = '-q';
-
-## Command to convert dvi file to ps file:
-$dvips = 'dvips %O -o %D %S';
-## Command to convert dvi file to ps file in landscape format:
-$dvips_landscape = 'dvips -tlandscape %O -o %D %S';
-# Switch(es) to get dvips to make ps file suitable for conversion to good pdf:
-# (If this is not used, ps file and hence pdf file contains bitmap fonts
-# (type 3), which look horrible under acroread. An appropriate switch
-# ensures type 1 fonts are generated. You can put this switch in the
-# dvips command if you prefer.)
-$dvips_pdf_switch = '-P pdf';
-# Switch(es) to make dvips silent:
-$dvips_silent_switch = '-q';
-
-## Command to convert ps file to pdf file:
-$ps2pdf = 'ps2pdf %O %S %D';
-
-## Command to convert xdv file to pdf file
-$xdvipdfmx = 'xdvipdfmx -E -o %D %O %S';
-$xdvipdfmx_silent_switch = '-q';
-
-
-## Command to search for tex-related files
-$kpsewhich = 'kpsewhich %S';
-
-## Command to run make:
-$make = 'make';
-
-##Printing:
-$print_type = 'auto'; # When printing, print the postscript file.
- # Possible values: 'dvi', 'ps', 'pdf', 'auto', 'none'
- # 'auto' ==> set print type according to the printable
- # file(s) being made: priority 'ps', 'pdf', 'dvi'
-
-# Viewers. These are system dependent, so default to none:
-$pdf_previewer = $ps_previewer = $ps_previewer_landscape = $dvi_previewer = $dvi_previewer_landscape = "NONE";
-
-$dvi_update_signal = undef;
-$ps_update_signal = undef;
-$pdf_update_signal = undef;
-
-$dvi_update_command = undef;
-$ps_update_command = undef;
-$pdf_update_command = undef;
-
-$allow_subdir_creation = 1;
-
-$new_viewer_always = 0; # If 1, always open a new viewer in pvc mode.
- # If 0, only open a new viewer if no previous
- # viewer for the same file is detected.
-
-# Commands for use in pvc mode for compiling, success, warnings, and failure;
-# they default to empty, i.e., not to use:
-$compiling_cmd = $success_cmd = $warning_cmd = $failure_cmd = "";
-
-# Commands for printing are highly system dependent, so default to NONE:
-$lpr = 'NONE $lpr variable is not configured to allow printing of ps files';
-$lpr_dvi = 'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
-$lpr_pdf = 'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
-
-
-# The $pscmd below holds a **system-dependent** command to list running
-# processes. It is used to find the process ID of the viewer looking at
-# the current output file. The output of the command must include the
-# process number and the command line of the processes, since the
-# relevant process is identified by the name of file to be viewed.
-# Its use is not essential.
-$pscmd = 'NONE $pscmd variable is not configured to detect running processes';
-$pid_position = -1; # offset of PID in output of pscmd.
- # Negative means I cannot use ps
-
-
-$quote_filenames = 1; # Quote filenames in external commands
-
-$del_dir = ''; # Directory into which cleaned up files are to be put.
- # If $del_dir is '', just delete the files
-
-@rc_system_files = ();
-
-#########################################################################
-
-################################################################
-## Special variables for system-dependent fudges, etc.
-$log_file_binary = 0; # Whether to treat log file as binary
- # Normally not, since the log file SHOULD be pure text.
- # But Miktex 2.7 sometimes puts binary characters
- # in it. (Typically in construct \OML ... after
- # overfull box with mathmode.)
- # Sometimes there is ctrl/Z, which is not only non-text,
- # but is end-of-file marker for MS-Win in text mode.
-
-$MSWin_fudge_break = 1; # Give special treatment to ctrl/C and ctrl/break
- # in -pvc mode under MSWin
- # Under MSWin32 (at least with perl 5.8 and WinXP)
- # when latexmk is running another program, and the
- # user gives ctrl/C or ctrl/break, to stop the
- # daughter program, not only does it reach
- # the daughter, but also latexmk/perl, so
- # latexmk is stopped also. In -pvc mode,
- # this is not normally desired. So when the
- # $MSWin_fudge_break variable is set,
- # latexmk arranges to ignore ctrl/C and
- # ctrl/break during processing of files;
- # only the daughter programs receive them.
- # This fudge is not applied in other
- # situations, since then having latexmk also
- # stopping because of the ctrl/C or
- # ctrl/break signal is desirable.
- # The fudge is not needed under UNIX (at least
- # with Perl 5.005 on Solaris 8). Only the
- # daughter programs receive the signal. In
- # fact the inverse would be useful: In
- # normal processing, as opposed to -pvc, if
- # force mode (-f) is set, a ctrl/C is
- # received by a daughter program does not
- # also stop latexmk. Under tcsh, we get
- # back to a command prompt, while latexmk
- # keeps running in the background!
-
-## Substitute backslashes in file and directory names for
-## MSWin command line
-$MSWin_back_slash = 1;
-
-## Separator of elements in search_path. Default is unix value
-$search_path_separator = ':';
-
-
-# Directory for temporary files. Default to current directory.
-$tmpdir = ".";
-
-
-# When the aux_dir is on a network share (or the like), its system
-# time may differ from the system time on which latexmk is running.
-# This complicates the tests of whether particular files have been
-# made in a current run of a program or are left over from a previous
-# run. One test, which is needed under some situations, is that a
-# file was made on a previous run when the files modification time is
-# less than the system time when the program is started. (See
-# subroutine test_gen_file; this is only needed in a couple of
-# situations.) The comparison between file and system times must be
-# corrected if there is an offset between system times on the computer
-# running latexmk and the computer hosting the file system containing
-# aux_dir. The offset is measured in subroutine get_filetime_offset
-# by writing a temporary file; the test only needs to be done once.
-#
-# The following variables are used. Since the system-independent
-# values of system and file time are only accurate to a second (or 2
-# seconds for FAT file systems), the offset is also accurate only to a
-# second or two. So thresholds are needed below which differences
-# are insignificant.
-#
-# Note that the making or not making of a file is controlled by the
-# state of the document being compiled and by latexmk's configuration.
-# So a file that is left over from a previous run and not overwritten
-# on the current run will have a file time at least many seconds less
-# than the current time, corresponding to the time scale for a human
-# run-edit-run cycle.
-#
-$filetime_offset_measured = 0; # Measurement not yet done.
-$filetime_offset = 0; # Filetime relative to system time.
-$filetime_causality_threshold = 5; # Threshold for detection of left-over file.
- # Should be non-negative always, and should
- # be bigger than 2 secs if a remote
- # filesystem or network share is used.
-$filetime_offset_report_threshold = 30; # Threshold beyond which filetime offsets
- # are reported; large offsets indicate
- # incorrect system time on at least one system.
-
-
-################################################################
-
-
-# System-dependent overrides:
-# Currently, the cases I have tests for are: MSWin32, cygwin, linux and
-# darwin, msys, with the main complications being for MSWin32 and cygwin.
-# Further special treatment may also be useful for MSYS (for which $^O reports
-# "msys"). This is another *nix-emulation/system for MSWindows. At
-# present it is treated as unix-like, but the environment variables
-# are those of Windows. (The test for USERNAME as well as USER was
-# to make latexmk work under MSYS's perl.)
-#
-if ( $^O eq "MSWin32" ) {
-# Pure MSWindows configuration
- ## Configuration parameters:
-
- ## Use first existing case for $tmpdir:
- $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
- $log_file_binary = 1; # Protect against ctrl/Z in log file from
- # Miktex 2.7.
-
- ## List of possibilities for the system-wide initialization file.
- ## The first one found (if any) is used.
- @rc_system_files = ( "C:/latexmk/LatexMk", "C:/latexmk/latexmkrc" );
-
- $search_path_separator = ';'; # Separator of elements in search_path
-
- # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
- # pdf files, so no program name is needed:
- $pdf_previewer = 'start %O %S';
- $ps_previewer = 'start %O %S';
- $ps_previewer_landscape = $ps_previewer;
- $dvi_previewer = 'start %O %S';
- $dvi_previewer_landscape = "$dvi_previewer";
- # Viewer update methods:
- # 0 => auto update: viewer watches file (e.g., gv)
- # 1 => manual update: user must do something: e.g., click on window.
- # (e.g., ghostview, MSWIN previewers, acroread under UNIX)
- # 2 => send signal. Number of signal in $dvi_update_signal,
- # $ps_update_signal, $pdf_update_signal
- # 3 => viewer can't update, because it locks the file and the file
- # cannot be updated. (acroread under MSWIN)
- # 4 => run a command to force the update. The commands are
- # specified by the variables $dvi_update_command,
- # $ps_update_command, $pdf_update_command
- $dvi_update_method = 1;
- $ps_update_method = 1;
- $pdf_update_method = 3; # acroread locks the pdf file
-}
-elsif ( $^O eq "cygwin" ) {
- # The problem is a mixed MSWin32 and UNIX environment.
- # Perl decides the OS is cygwin in two situations:
- # 1. When latexmk is run from a cygwin shell under a cygwin
- # environment. Perl behaves in a UNIX way. This is OK, since
- # the user is presumably expecting UNIXy behavior.
- # 2. When CYGWIN exectuables are in the path, but latexmk is run
- # from a native NT shell. Presumably the user is expecting NT
- # behavior. But perl behaves more UNIXy. This causes some
- # clashes.
- # The issues to handle are:
- # 1. Perl sees both MSWin32 and cygwin filenames. This is
- # normally only an advantage.
- # 2. Perl uses a UNIX shell in the system command
- # This is a nasty problem: under native NT, there is a
- # start command that knows about NT file associations, so that
- # we can do, e.g., (under native NT) system("start file.pdf");
- # But this won't work when perl has decided the OS is cygwin,
- # even if it is invoked from a native NT command line. An
- # NT command processor must be used to deal with this.
- # 3. External executables can be native NT (which only know
- # NT-style file names) or cygwin executables (which normally
- # know both cygwin UNIX-style file names and NT file names,
- # but not always; some do not know about drive names, for
- # example).
- # Cygwin executables for tex and latex may only know cygwin
- # filenames.
- # 4. The BIBINPUTS environment variables may be
- # UNIX-style or MSWin-style depending on whether native NT or
- # cygwin executables are used. They are therefore parsed
- # differently. Here is the clash:
- # a. If a user is running under an NT shell, is using a
- # native NT installation of tex (e.g., fptex or miktex),
- # but has the cygwin executables in the path, then perl
- # detects the OS as cygwin, but the user needs NT
- # behavior from latexmk.
- # b. If a user is running under an UNIX shell in a cygwin
- # environment, and is using the cygwin installation of
- # tex, then perl detects the OS as cygwin, and the user
- # needs UNIX behavior from latexmk.
- # Latexmk has no way of detecting the difference. The two
- # situations may even arise for the same user on the same
- # computer simply by changing the order of directories in the
- # path environment variable
-
-
- ## Configuration parameters: We'll assume native NT executables.
- ## The user should override if they are not.
-
- # This may fail: perl converts MSWin temp directory name to cygwin
- # format. Names containing this string cannot be handled by native
- # NT executables.
- $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
-
- # Which rc files did I read?
- @rc_files_read = ();
- ## List of possibilities for the system-wide initialization file.
- ## The first one found (if any) is used.
- ## We could stay with MSWin files here, since cygwin perl understands them
- ## @rc_system_files = ( 'C:/latexmk/LatexMk', 'C:/latexmk/latexmkrc' );
- ## But they are deprecated in v. 1.7. So use the UNIX version, prefixed
- ## with a cygwin equivalent of the MSWin location
- ## In addition, we need to add the same set of possible locations as with
- ## unix, so that the user use a unix-style setup.
- @rc_system_files = ();
- foreach ( 'LatexMk', 'latexmkrc' ) {
- push @rc_system_files,
- ( "/cygdrive/c/latexmk/$_",
- "/opt/local/share/latexmk/$_",
- "/usr/local/share/latexmk/$_",
- "/usr/local/lib/latexmk/$_" );
- }
- $search_path_separator = ';'; # Separator of elements in search_path
- # This is tricky. The search_path_separator depends on the kind
- # of executable: native NT v. cygwin.
- # So the user will have to override this.
-
- # We will assume that files can be viewed by native NT programs.
- # Then we must fix the start command/directive, so that the
- # NT-native start command of a cmd.exe is used.
- # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
- # pdf files, so no program name is needed:
- $start_NT = "cmd /c start \"\"";
- $pdf_previewer = "$start_NT %O %S";
- $ps_previewer = "$start_NT %O %S";
- $ps_previewer_landscape = $ps_previewer;
- $dvi_previewer = "$start_NT %O %S";
- $dvi_previewer_landscape = $dvi_previewer;
- # Viewer update methods:
- # 0 => auto update: viewer watches file (e.g., gv)
- # 1 => manual update: user must do something: e.g., click on window.
- # (e.g., ghostview, MSWIN previewers, acroread under UNIX)
- # 2 => send signal. Number of signal in $dvi_update_signal,
- # $ps_update_signal, $pdf_update_signal
- # 3 => viewer can't update, because it locks the file and the file
- # cannot be updated. (acroread under MSWIN)
- $dvi_update_method = 1;
- $ps_update_method = 1;
- $pdf_update_method = 3; # acroread locks the pdf file
-}
-elsif ( $^O eq "msys" ) {
- $search_path_separator = ';'; # Separator of elements in search_path
- # I think MS-Win value is OK, since
- # msys is running under MS-Win
- $pdf_previewer = q[sh -c 'start %S'];
- $ps_previewer = q[sh -c 'start %S'];
- $dvi_previewer = q[sh -c 'start %S'];
- $ps_previewer_landscape = $ps_previewer;
- $dvi_previewer_landscape = "$dvi_previewer";
-}
-else {
- # Assume anything else is UNIX or clone
- # Do special cases (e.g., linux, darwin (i.e., OS-X)) inside this block.
-
- ## Use first existing case for $tmpdir:
- $tmpdir = $ENV{TMPDIR} || '/tmp';
-
- ## List of possibilities for the system-wide initialization file.
- ## The first one found (if any) is used.
- ## Normally on a UNIX it will be in a subdirectory of /opt/local/share or
- ## /usr/local/share, depending on the local conventions.
- ## But /usr/local/lib/latexmk is put in the list for
- ## compatibility with older versions of latexmk.
- @rc_system_files = ();
- foreach ( 'LatexMk', 'latexmkrc' ) {
- push @rc_system_files,
- ( "/opt/local/share/latexmk/$_",
- "/usr/local/share/latexmk/$_",
- "/usr/local/lib/latexmk/$_" );
- }
- $search_path_separator = ':'; # Separator of elements in search_path
-
- $dvi_update_signal = $signo{USR1}
- if ( defined $signo{USR1} ); # Suitable for xdvi
- $ps_update_signal = $signo{HUP}
- if ( defined $signo{HUP} ); # Suitable for gv
- $pdf_update_signal = $signo{HUP}
- if ( defined $signo{HUP} ); # Suitable for gv
- ## default document processing programs.
- # Viewer update methods:
- # 0 => auto update: viewer watches file (e.g., gv)
- # 1 => manual update: user must do something: e.g., click on window.
- # (e.g., ghostview, MSWIN previewers, acroread under UNIX)
- # 2 => send signal. Number of signal in $dvi_update_signal,
- # $ps_update_signal, $pdf_update_signal
- # 3 => viewer can't update, because it locks the file and the file
- # cannot be updated. (acroread under MSWIN)
- # 4 => Run command to update. Command in $dvi_update_command,
- # $ps_update_command, $pdf_update_command.
- $dvi_previewer = 'start xdvi %O %S';
- $dvi_previewer_landscape = 'start xdvi -paper usr %O %S';
- if ( defined $dvi_update_signal ) {
- $dvi_update_method = 2; # xdvi responds to signal to update
- } else {
- $dvi_update_method = 1;
- }
-# if ( defined $ps_update_signal ) {
-# $ps_update_method = 2; # gv responds to signal to update
-# $ps_previewer = 'start gv -nowatch';
-# $ps_previewer_landscape = 'start gv -swap -nowatch';
-# } else {
-# $ps_update_method = 0; # gv -watch watches the ps file
-# $ps_previewer = 'start gv -watch';
-# $ps_previewer_landscape = 'start gv -swap -watch';
-# }
- # Turn off the fancy options for gv. Regular gv likes -watch etc
- # GNU gv likes --watch etc. User must configure
- $ps_update_method = 0; # gv -watch watches the ps file
- $ps_previewer = 'start gv %O %S';
- $ps_previewer_landscape = 'start gv -swap %O %S';
- $pdf_previewer = 'start acroread %O %S';
- $pdf_update_method = 1; # acroread under unix needs manual update
- $lpr = 'lpr %O %S'; # Assume lpr command prints postscript files correctly
- $lpr_dvi =
- 'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
- $lpr_pdf =
- 'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
- # The $pscmd below holds a command to list running processes. It
- # is used to find the process ID of the viewer looking at the
- # current output file. The output of the command must include the
- # process number and the command line of the processes, since the
- # relevant process is identified by the name of file to be viewed.
- # Uses:
- # 1. In preview_continuous mode, to save running a previewer
- # when one is already running on the relevant file.
- # 2. With xdvi in preview_continuous mode, xdvi must be
- # signalled to make it read a new dvi file.
- #
- # The following works on Solaris, LINUX, HP-UX, IRIX
- # Use -f to get full listing, including command line arguments.
- # Use -u $ENV{USER} to get all processes started by current user (not just
- # those associated with current terminal), but none of other users'
- # processes.
- # However, the USER environment variable may not exist. Windows uses
- # USERNAME instead. (And this propagates to a situation of
- # unix-emulation software running under Windows.)
- if ( exists $ENV{USER} ) {
- $pscmd = "ps -f -u $ENV{USER}";
- }
- elsif ( exists $ENV{USERNAME} ) {
- $pscmd = "ps -f -u $ENV{USERNAME}";
- }
- else {
- $pscmd = "ps -f";
- }
- $pid_position = 1; # offset of PID in output of pscmd; first item is 0.
- if ( $^O eq "linux" ) {
- # Ps on Redhat (at least v. 7.2) appears to truncate its output
- # at 80 cols, so that a long command string is truncated.
- # Fix this with the --width option. This option works under
- # other versions of linux even if not necessary (at least
- # for SUSE 7.2).
- # However the option is not available under other UNIX-type
- # systems, e.g., Solaris 8.
- # But (19 Aug 2010), the truncation doesn't happen on RHEL4 and 5,
- # unless the output is written to a terminal. So the --width
- # option is now unnecessary
- # $pscmd = "ps --width 200 -f -u $ENV{USER}";
- }
- elsif ( $^O eq "darwin" ) {
- # OS-X on Macintosh
- # open starts command associated with a file.
- # For pdf, this is set by default to OS-X's preview, which is suitable.
- # Manual update is simply by clicking on window etc, which is OK.
- # For ps, this is set also to preview. This works, but since it
- # converts the file to pdf and views the pdf file, it doesn't
- # see updates, and a refresh cannot be done. This is far from
- # optimal.
- # For a full installation of MacTeX, which is probably the most common
- # on OS-X, an association is created between dvi files and TeXShop.
- # This also converts the file to pdf, so again while it works, it
- # does not deal with changed dvi files, as far as I can see.
- $pdf_previewer = 'open %S';
- $pdf_update_method = 1; # manual
- $dvi_previewer = $dvi_previewer_landscape = 'NONE';
- $ps_previewer = $ps_previewer_landscape = 'NONE';
- # Others
- $lpr_pdf = 'lpr %O %S';
- $pscmd = "ps -ww -u $ENV{USER}";
- }
-}
-
-## default parameters
-$auto_rc_use = 1; # Whether to read rc files automatically
-$max_repeat = 5; # Maximum times I repeat latex. Normally
- # 3 would be sufficient: 1st run generates aux file,
- # 2nd run picks up aux file, and maybe toc, lof which
- # contain out-of-date information, e.g., wrong page
- # references in toc, lof and index, and unresolved
- # references in the middle of lines. But the
- # formatting is more-or-less correct. On the 3rd
- # run, the page refs etc in toc, lof, etc are about
- # correct, but some slight formatting changes may
- # occur, which mess up page numbers in the toc and lof,
- # Hence a 4th run is conceivably necessary.
- # At least one document class (JHEP.cls) works
- # in such a way that a 4th run is needed.
- # We allow an extra run for safety for a
- # maximum of 5. Needing further runs is
- # usually an indication of a problem; further
- # runs may not resolve the problem, and
- # instead could cause an infinite loop.
-$clean_ext = ""; # space separated extensions of files that are
- # to be deleted when doing cleanup, beyond
- # standard set
-$clean_full_ext = ""; # space separated extensions of files that are
- # to be deleted when doing cleanup_full, beyond
- # standard set and those in $clean_ext
-@cus_dep_list = (); # Custom dependency list
-@default_files = ( '*.tex' ); # Array of LaTeX files to process when
- # no files are specified on the command line.
- # Wildcards allowed
- # Best used for project specific files.
-@default_excluded_files = ( );
- # Array of LaTeX files to exclude when using
- # @default_files, i.e., when no files are specified
- # on the command line.
- # Wildcards allowed
- # Best used for project specific files.
-$texfile_search = ""; # Specification for extra files to search for
- # when no files are specified on the command line
- # and the @default_files variable is empty.
- # Space separated, and wildcards allowed.
- # These files are IN ADDITION to *.tex in current
- # directory.
- # This variable is obsolete, and only in here for
- # backward compatibility.
-
-$fdb_ext = 'fdb_latexmk'; # Extension for the file for latexmk's
- # file-database
- # Make it long to avoid possible collisions.
-$fdb_ver = 3; # Version number for kind of fdb_file.
-
-$jobname = ''; # Jobname: as with current tex, etc indicates
- # basename of generated files. Defined so
- # that --jobname=STRING on latexmk's command
- # line has same effect as with current tex,
- # etc, with the exception listed below. (If
- # $jobname is non-empty, then the
- # --jobname=... option is used on tex.)
- # Extension: $jobname is allowed to contain
- # placeholder(s) (currently only %A),
- # which allows construction of jobnames
- # dependent on name of main TeX file; this is
- # useful when a jobname is used and latexmk is
- # invoked on multiple files.
-$out_dir = ''; # Directory for output files.
- # Cf. --output-directory of current *latex
-$aux_dir = ''; # Directory for aux files (log, aux, etc).
- # Cf. --aux-directory of current *latex in MiKTeX.
-
-
-## default flag settings.
-$recorder = 1; # Whether to use recorder option on latex/pdflatex
-$silent = 0; # Silence latex's messages?
-$warnings_as_errors = 0;# Treat warnings as errors and exit with non-zero exit code
-$silence_logfile_warnings = 0; # Do list warnings in log file
-$kpsewhich_show = 0; # Show calls to and results from kpsewhich
-$landscape_mode = 0; # default to portrait mode
-$analyze_input_log_always = 1; # Always analyze .log for input files in the
- # <...> and (...) constructions. Otherwise, only
- # do the analysis when fls file doesn't exist or is
- # out of date.
- # Under normal circumstances, the data in the fls file
- # is reliable, and the test of the log file gets lots
- # of false positives; usually $analyze_input_log_always
- # is best set to zero. But the test of the log file
- # is needed at least in the following situation:
- # When a user needs to persuade latexmk that a certain
- # file is a source file, and latexmk doesn't otherwise
- # find it. User code causes line with (...) to be
- # written to log file. One important case is for
- # lualatex, which doesn't always generate lines in the
- # .fls file for input lua files. (The situation with
- # lualatex is HIGHLY version dependent, e.g., between
- # 2016 and 2017.)
- # To keep backward compatibility with older versions
- # of latexmk, the default is to set
- # $analyze_input_log_always to 1.
-
-# The following two arrays contain lists of extensions (without
-# period) for files that are read in during a *LaTeX run but that
-# are generated automatically from the previous run, as opposed to
-# being user generated files (directly or indirectly from a custom
-# dependency). These files get two kinds of special treatment:
-# 1. In clean up, where depending on the kind of clean up, some
-# or all of these generated files are deleted.
-# (Note that special treatment is given to aux files.)
-# 2. In analyzing the results of a run of *LaTeX, to
-# determine if another run is needed. With an error free run,
-# a rerun should be provoked by a change in any source file,
-# whether a user file or a generated file. But with a run
-# that ends in an error, only a change in a user file during
-# the run (which might correct the error) should provoke a
-# rerun, but a change in a generated file should not.
-# These arrays can be user-configured.
-
-@generated_exts = ( 'aux', 'bcf', 'fls', 'idx', 'ind', 'lof', 'lot',
- 'out', 'toc' );
- # N.B. 'out' is generated by hyperref package
-
-# Which kinds of file do I have requests to make?
-# If no requests at all are made, then I will make dvi file
-# If particular requests are made then other files may also have to be
-# made. E.g., ps file requires a dvi file
-$dvi_mode = 0; # No dvi file requested
-$postscript_mode = 0; # No postscript file requested
-$pdf_mode = 0; # No pdf file requested to be made by pdflatex
- # Possible values:
- # 0 don't create pdf file
- # 1 to create pdf file by pdflatex
- # 2 to create pdf file by ps2pdf
- # 3 to create pdf file by dvipdf
- # 4 to create pdf file by lualatex
- # 5 to create pdf file by xelatex + xdvipdfmx
-$view = 'default'; # Default preview is of highest of dvi, ps, pdf
-$sleep_time = 2; # time to sleep b/w checks for file changes in -pvc mode
-$banner = 0; # Non-zero if we have a banner to insert
-$banner_scale = 220; # Original default scale
-$banner_intensity = 0.95; # Darkness of the banner message
-$banner_message = 'DRAFT'; # Original default message
-$do_cd = 0; # Do not do cd to directory of source file.
- # Thus behave like latex.
-$dependents_list = 0; # Whether to display list(s) of dependencies
-$dependents_phony = 0; # Whether list(s) of dependencies includes phony targets
- # (as with 'gcc -MP').
-$deps_file = '-'; # File for dependency list output. Default stdout.
-$rules_list = 0; # Whether to display list(s) of dependencies
-@dir_stack = (); # Stack of pushed directories, each of form of
- # pointer to array [ cwd, good_cwd ], where
- # good_cwd differs from cwd by being converted
- # to native MSWin path when cygwin is used.
-$cleanup_mode = 0; # No cleanup of nonessential LaTex-related files.
- # $cleanup_mode = 0: no cleanup
- # $cleanup_mode = 1: full cleanup
- # $cleanup_mode = 2: cleanup except for dvi,
- # dviF, pdf, ps, psF & xdv
-$cleanup_fdb = 0; # No removal of file for latexmk's file-database
-$cleanup_only = 0; # When doing cleanup, do not go on to making files
-$cleanup_includes_generated = 0;
- # Determines whether cleanup deletes files generated by
- # *latex (found from \openout lines in log file).
- # It's more than that. BUG
-$cleanup_includes_cusdep_generated = 0;
- # Determines whether cleanup deletes files generated by
- # custom dependencies
-$diagnostics = 0;
-$dvi_filter = ''; # DVI filter command
-$ps_filter = ''; # Postscript filter command
-
-$force_mode = 0; # =1 to force processing past errors
-$go_mode = 0; # =1 to force processing regardless of time-stamps
- # =2 full clean-up first
-$preview_mode = 0;
-$preview_continuous_mode = 0;
-$printout_mode = 0; # Don't print the file
-
-## Control pvc inactivity timeout:
-$pvc_timeout = 0;
-$pvc_timeout_mins = 30;
-
-$show_time = 0;
-@timings = ();
-$processing_time1 = processing_time();
-
-$use_make_for_missing_files = 0; # Whether to use make to try to make missing files.
-
-# Do we make view file in temporary then move to final destination?
-# (To avoid premature updating by viewer).
-$always_view_file_via_temporary = 0; # Set to 1 if viewed file is always
- # made through a temporary.
-$pvc_view_file_via_temporary = 1; # Set to 1 if only in -pvc mode is viewed
- # file made through a temporary.
-
-# State variables initialized here:
-
-$updated = 0; # Flags when something has been remade
- # Used to allow convenient user message in -pvc mode
-$waiting = 0; # Flags whether we are in loop waiting for an event
- # Used to avoid unnecessary repeated o/p in wait loop
-
-# The following are used for some results of parsing log file
-# Global variables, so results can be reported in main program.
-$reference_changed = 0;
-$mult_defined = 0;
-$bad_reference = 0;
-$bad_character = 0;
-$bad_citation = 0;
-@primary_warning_summary = ();
-
-# Cache of expensive-to-compute state variables, e.g., cwd in form
-# fixed to deal with cygwin issues.
-%cache = ();
-&cache_good_cwd;
-
-# Set search paths for includes.
-# Set them early so that they can be overridden
-$BIBINPUTS = $ENV{'BIBINPUTS'};
-if (!$BIBINPUTS) { $BIBINPUTS = '.'; }
-
-# Convert search paths to arrays:
-# If any of the paths end in '//' then recursively search the
-# directory. After these operations, @BIBINPUTS should
-# have all the directories that need to be searched
-
-@BIBINPUTS = find_dirs1( $BIBINPUTS );
-
-
-######################################################################
-######################################################################
-#
-# ??? UPDATE THE FOLLOWING!!
-#
-# We will need to determine whether source files for runs of various
-# programs are out of date. In a normal situation, this is done by
-# asking whether the times of the source files are later than the
-# destination files. But this won't work for us, since a common
-# situation is that a file is written on one run of latex, for
-# example, and read back in on the next run (e.g., an .aux file).
-# Some situations of this kind are standard in latex generally; others
-# occur with particular macro packages or with particular
-# postprocessors.
-#
-# The correct criterion for whether a source is out-of-date is
-# therefore NOT that its modification time is later than the
-# destination file, but whether the contents of the source file have
-# changed since the last successful run. This also handles the case
-# that the user undoes some changes to a source file by replacing the
-# source file by reverting to an earlier version, which may well have
-# an older time stamp. Since a direct comparison of old and new files
-# would involve storage and access of a large number of backup files,
-# we instead use the md5 signature of the files. (Previous versions
-# of latexmk used the backup file method, but restricted to the case
-# of .aux and .idx files, sufficient for most, but not all,
-# situations.)
-#
-# We will have a database of (time, size, md5) for the relevant
-# files. If the time and size of a file haven't changed, then the file
-# is assumed not to have changed; this saves us from having to
-# determine its md5 signature, which would involve reading the whole
-# file, which is naturally time-consuming, especially if network file
-# access to a server is needed, and many files are involved, when most
-# of them don't change. It is of course possible to change a file
-# without changing its size, but then to adjust its timestamp
-# to what it was previously; this requires a certain amount of
-# perversity. We can safely assume that if the user edits a file or
-# changes its contents, then the file's timestamp changes. The
-# interesting case is that the timestamp does change, because the file
-# has actually been written to, but that the contents do not change;
-# it is for this that we use the md5 signature. However, since
-# computing the md5 signature involves reading the whole file, which
-# may be large, we should avoid computing it more than necessary.
-#
-# So we get the following structure:
-#
-# 1. For each relevant run (latex, pdflatex, each instance of a
-# custom dependency) we have a database of the state of the
-# source files that were last used by the run.
-# 2. On an initial startup, the database for a primary tex file
-# is read that was created by a previous run of latex or
-# pdflatex, if this exists.
-# 3. If the file doesn't exist, then the criterion for
-# out-of-dateness for an initial run is that it goes by file
-# timestamps, as in previous versions of latexmk, with due
-# (dis)regard to those files that are known to be generated by
-# latex and re-read on the next run.
-# 4. Immediately before a run, the database is updated to
-# represent the current conditions of the run's source files.
-# 5. After the run, it is determined whether any of the source
-# files have changed. This covers both files written by the
-# run, which are therefore in a dependency loop, and files that
-# the user may have updated during the run. (The last often
-# happens when latex takes a long time, for a big document,
-# and the user makes edits before latex has finished. This is
-# particularly prevalent when latexmk is used with
-# preview-continuous mode.)
-# 6. In the case of latex or pdflatex, the custom dependencies
-# must also be checked and redone if out-of-date.
-# 7. If any source files have changed, the run is redone,
-# starting at step 1.
-# 8. There is naturally a limit on the number of reruns, to avoid
-# infinite loops from bugs and from pathological or unforeseen
-# conditions.
-# 9. After the run is done, the run's file database is updated.
-# (By hypothesis, the sizes and md5s are correct, if the run
-# is successful.)
-# 10. To allow reuse of data from previous runs, the file database
-# is written to a file after every complete set of passes
-# through latex or pdflatex. (Note that there is separate
-# information for latex and pdflatex; the necessary
-# information won't coincide: Out-of-dateness for the files
-# for each program concerns the properties of the files when
-# the other program was run, and the set of source files could
-# be different, e.g., for graphics files.)
-#
-# We therefore maintain the following data structures.:
-#
-# a. For each run (latex, pdflatex, each custom dependency) a
-# database is maintained. This is a hash from filenames to a
-# reference to an array: [time, size, md5]. The semantics of
-# the database is that it represents the state of the source
-# files used in the run. During a run it represents the state
-# immediately before the run; after a run, with all reruns, it
-# represents the state of the files used, modified by having
-# the latest timestamps for generated files.
-# b. There is a global database for all files, which represents
-# the current state. This saves having to recompute the md5
-# signatures of a changed file used in more than one run
-# (e.g., latex and pdflatex).
-# c. Each of latex and pdflatex has a list of the relevant custom
-# dependencies.
-#
-# In all the following a fdb-hash is a hash of the form:
-# filename -> [time, size, md5]
-# If a file is found to disappear, its entry is removed from the hash.
-# In returns from fdb access routines, a size entry of -1 indicates a
-# non-existent file.
-
-
-# List of known rules. Rule types: primary,
-# external (calls program), internal (calls routine), cusdep.
-
-%possible_primaries = ( 'latex' => 'primary', 'pdflatex' => 'primary',
- 'lualatex' => 'primary', 'xelatex' => 'primary' );
-
-# Hashes, whose keys give names of particular kinds of rule, and targets.
-# We use hashes for ease of lookup.
-%possible_one_time = ( 'view' => 1, 'print' => 1, 'update_view' => 1, );
-%target_files = (); # Hash for target files.
- # The keys are the filenames and the value is
- # currently irrelevant.
-%target_rules = (); # Hash for target rules beyond those corresponding to files.
- # The keys are the rule names and the value is
- # currently irrelevant.
-# The target **files** can only be set inside the FILE loop.
-$current_primary = 'latex'; # Rule to compile .tex file.
- # Subject to document-dependent override if .tex document
- # uses metcommands andobeying them is enabled.
-$pdf_method = ''; # How to make pdf file. '' if not requested,
- # else 'ps2pdf', 'dvipdf', 'pdflatex', 'lualatex' or 'xelatex'
- # Subject to document-dependent override if .tex document
- #uses \pdfoutput or c.
-%requested_filetypes = (); # Hash of requested file types (dvi, dviF, etc)
-%one_time = (); # Hash for requested one-time-only rules, currently
- # possible values 'print' and 'view'.
-
-%actives = (); # Hash of active rules
-
-$allow_switch = 1; # Allow switch of rule structure to accommodate
- # changed output file name of primary. Even if
- # this flag is set on, the switch may be
- # prohibited by other issues.
-
-%rule_db = (); # Database of all rules:
- # Hash: rulename -> [array of rule data]
- # Rule data:
- # 0: [ cmd_type, ext_cmd, int_cmd, test_kind,
- # source, dest, base,
- # out_of_date, out_of_date_user,
- # time_of_last_run, time_of_last_file_check,
- # changed
- # last_result, last_message,
- # default_extra_generated,
- # ]
- # where
- # cmd_type is 'primary', 'external', or 'cusdep'
- # ext_cmd is string for associated external command
- # with substitutions (%D for destination, %S
- # for source, %B for base of current rule,
- # %R for base of primary tex file, %T for
- # texfile name, %O for options,
- # %Y for $aux_dir1, and %Z for $out_dir1
- # int_cmd specifies any internal command to be
- # used to implement the application of the
- # rule. If this is present, it overrides
- # the external command, and it is the
- # responsibility of the perl subroutine
- # specified in intcmd to execute the
- # external command if this is appropriate.
- # This variable intcmd is a reference to an array,
- # $$intcmd[0] = internal routine
- # $$intcmd[1...] = its arguments (if any)
- # test_kind specifies method of determining
- # whether a file is out-of-date:
- # 0 for never
- # 1 for usual: whether there is a source
- # file change
- # 2 for dest earlier than source
- # 3 for method 2 at first run, 1 thereafter
- # (used when don't have file data from
- # previous run).
- # source = name of primary source file, if any
- # dest = name of primary destination file,
- # if any
- # base = base name, if any, of files for
- # this rule
- # out_of_date = 1 if it has been detected that
- # this rule needs to be run
- # (typically because a source
- # file has changed).
- # Other values may be used for special cases.
- # 0 otherwise
- # out_of_date_user is like out_of_date, except
- # that the detection of out-of-dateness
- # has been made from a change of a
- # putative user file, i.e., one that is
- # not a generated file (e.g., aux). This
- # kind of out-of-dateness should provoke a
- # rerun whether or not there was an error
- # during a run of *LaTeX. Normally,
- # if there is an error, one should wait
- # for the user to correct the error. But
- # it is possible the error condition is
- # already corrected during the run, e.g.,
- # by the user changing a source file in
- # response to an error message.
- # time_of_last_run = time that this rule was
- # last applied. (In standard units
- # from perl, to be directly compared
- # with file modification times.)
- # time_of_last_file_check = last time that a check
- # was made for changes in source files.
- # changed flags whether special changes have been made
- # that require file-existence status to be ignored
- # last_result is
- # -1 if no run has been made,
- # 0 if the last run was successful
- # 1 if last run was successful, but
- # failed to create an output file
- # 2 if last run failed
- # 200 if last run gave a warning that is
- # important enough to be reported with
- # the error summary. The warning
- # message is stored in last_message.
- # last_message is error message for last run
- # default_extra_generated is a reference to an array
- # of specifications of extra generated files (beyond
- # the main dest file. Standard place holders are used.
- # 1: {Hash sourcefile -> [source-file data] }
- # Source-file data array:
- # 0: time
- # 1: size
- # 2: md5
- # 3: name of rule to make this file
- # 4: whether the file is of the kind made by epstopdf.sty
- # during a primary run. It will have been read during
- # the run, so that even though the file changes during
- # a primary run, there is no need to trigger another
- # run because of this.
- # Size and md5 correspond to the values at the last run.
- # But time may be updated to correspond to the time
- # for the file, if the file is otherwise unchanged.
- # This saves excessive md5 calculations, which would
- # otherwise be done everytime the file is checked,
- # in the following situation:
- # When the file has been rewritten after a run
- # has started (commonly aux, bbl files etc),
- # but the actual file contents haven't
- # changed. Then because the filetime has
- # changed, on every file-change check latexmk
- # would normally redo the md5 calculation to
- # test for actual changes. Once one such
- # check is done, and the contents are
- # unchanged, later checks are superfluous, and
- # can be avoided by changing the file's time
- # in the source-file list.
- # 2: {Hash generated_file -> 1 }
- # This lists all generated files; the values
- # are currently unused, only the keys
- # 3: {Hash source_rule -> last_pass }
- # This lists rules that are to be considered source
- # rules for the current rule, separately from the
- # from_rules of the source files. It maps the name
- # of each of these rules to the pass number of the
- # current rule when it was last run. The current rule
- # is out-of-date if the last_pass for a source rule
- # is less than the pass number for the rule.
- # The purpose of this is when the source file list
- # is expected to be inaccurate, because the source
- # files are hard to determine. Typical needs are
- # for rules applied to dvi and xdv files, when
- # graphics files are involved. Their names are coded
- # inside the dvi/xdv file, but not the contents.
- # It would need parsing of the contents of the file
- # to determine the actual source files.
- # An implication of using a source_rule is that this
- # rule passes files to the current rule and that the
- # current rule can be considered out-of-date whenever
- # the source_rule has been run. Effectively these
- # files are unconditionallyconsidered changed when
- # the source_rule runs.
-
-%fdb_current = (); # Hash of information for all files used.
- # It maps filename to a reference to an array
- # (time, size, md5_checksum).
-@nofile = (0,-1,0); # What we use for initializing a new entry in fdb
- # or flagging non-existent file.
-
-# The following provide information about the structure of the network of rules
-# and files. They are set by the routine rdb_set_rule_net
-%from_rules = (); # Used to optimize test for whether a file is generated.
- # This maps files to rules that generate them. (Files
- # anywhere in %$PHdest.)
-%from_rules_main = (); # Used to optimize test for whether a file is generated.
- # This maps files to rules that generate them as the
- # MAIN output. (I.e., file $$Pdest only.)
-# Classification of rules, for determining order of application
-%current_primaries = (); # Keys are primary rules (latex, etc) that are currently in use.
-@pre_primary = (); # Array of rules that are thought of as pre-primary
-@post_primary = (); # Array of rules that are thought of as post-primary
-@unusual_one_time = (); # Array of rules that are special cases of one-time rules.
- # Currently not used.
-
-
-# User's home directory
-$HOME = '';
-if (exists $ENV{'HOME'} ) {
- $HOME = $ENV{'HOME'};
-}
-elsif (exists $ENV{'USERPROFILE'} ) {
- $HOME = $ENV{'USERPROFILE'};
-}
-# XDG configuration home
-$XDG_CONFIG_HOME = '';
-if (exists $ENV{'XDG_CONFIG_HOME'} ) {
- $XDG_CONFIG_HOME = $ENV{'XDG_CONFIG_HOME'};
-}
-elsif ($HOME ne '') {
- if ( -d "$HOME/.config") {
- $XDG_CONFIG_HOME = "$HOME/.config";
- }
-}
-
-
-#==================================================
-
-# Options that are to be obeyed before rc files are read:
-
-foreach $_ ( @ARGV )
-{
- if (/^-{1,2}norc$/ ) {
- $auto_rc_use = 0;
- }
-}
-
-#==================================================
-## Read rc files with this subroutine
-
-sub read_first_rc_file_in_list {
- foreach my $rc_file ( @_ ) {
- #print "===Testing for rc file \"$rc_file\" ...\n";
- if ( -d $rc_file ) {
- warn "$My_name: I have found a DIRECTORY named \"$rc_file\".\n",
- " Have you perhaps misunderstood latexmk's documentation?\n",
- " This name is normally used for a latexmk configuration (rc) file,\n",
- " and in that case it should be a regular text file, not a directory.\n";
- }
- elsif ( -e $rc_file ) {
- process_rc_file( $rc_file );
- return;
- }
- }
-}
-
-# Note that each rc file may unset $auto_rc_use to
-# prevent lower-level rc files from being read.
-# So test on $auto_rc_use in each case.
-if ( $auto_rc_use ) {
- # System rc file:
- if (exists $ENV{LATEXMKRCSYS} ) {
- push @rc_system_files, $ENV{LATEXMKRCSYS};
- if ( !-e $ENV{LATEXMKRCSYS} ) {
- warn "$My_name: you've specified a system rc file `$ENV{LATEXMKRCSYS}`\n",
- " in environment variable LATEXMKRCSYS, but the file doesn't exist.\n",
- " I won't read any system rc file.\n";
- }
- else {
- process_rc_file( $ENV{LATEXMKRCSYS} );
- }
- }
- else {
- read_first_rc_file_in_list( @rc_system_files );
- }
-}
-if ( $auto_rc_use && ($HOME ne "" ) ) {
- # User rc file:
- @user_rc = ();
- if ( $XDG_CONFIG_HOME ) {
- push @user_rc, "$XDG_CONFIG_HOME/latexmk/latexmkrc";
- }
- # N.B. $HOME equals "" if latexmk couldn't determine a home directory.
- # In that case, we shouldn't look for an rc file there.
- if ( $HOME ) {
- push @user_rc, "$HOME/.latexmkrc";
- }
- read_first_rc_file_in_list( @user_rc );
-}
-if ( $auto_rc_use ) {
- # Rc file in current directory:
- read_first_rc_file_in_list( "./latexmkrc", "./.latexmkrc" );
-}
-
-## Process command line args.
-@command_line_file_list = ();
-$bad_options = 0;
-
-while ($_ = $ARGV[0])
-{
- # Make -- and - equivalent at beginning of option,
- # but save original for possible use in *latex command line
- $original = $_;
- s/^--/-/;
- shift;
- if ( /^-aux-directory=(.*)$/ || /^-auxdir=(.*)$/ ) {
- $aux_dir = $1;
- }
- elsif (/^-bibfudge$/) { $bibtex_fudge = 1; }
- elsif (/^-bibfudge-$/) { $bibtex_fudge = 0; }
- elsif (/^-bibtex$/) { $bibtex_use = 2; }
- elsif (/^-bibtex-$/) { $bibtex_use = 0; }
- elsif (/^-nobibtex$/) { $bibtex_use = 0; }
- elsif (/^-bibtex-cond$/) { $bibtex_use = 1; }
- elsif (/^-bibtex-cond1$/) { $bibtex_use = 1.5; }
- elsif (/^-c$/) { $cleanup_mode = 2; $cleanup_fdb = 1; $cleanup_only = 1; }
- elsif (/^-C$/ || /^-CA$/ ) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1; }
- elsif (/^-CF$/) { $cleanup_fdb = 1; }
- elsif (/^-cd$/) { $do_cd = 1; }
- elsif (/^-cd-$/) { $do_cd = 0; }
- elsif (/^-commands$/) { &print_commands; exit; }
- elsif (/^-d$/) { $banner = 1; }
- elsif (/^-dependents$/ || /^-deps$/ || /^-M$/ ) { $dependents_list = 1; }
- elsif (/^-nodependents$/ || /^-dependents-$/ || /^-deps-$/) { $dependents_list = 0; }
- elsif (/^-deps-out=(.*)$/) {
- $deps_file = $1;
- $dependents_list = 1;
- }
- elsif (/^-diagnostics/) { $diagnostics = 1; }
- elsif (/^-dvi$/) { $dvi_mode = 1; }
- elsif (/^-dvi-$/) { $dvi_mode = 0; }
- elsif (/^-f$/) { $force_mode = 1; }
- elsif (/^-f-$/) { $force_mode = 0; }
- elsif (/^-g$/) { $go_mode = 1; }
- elsif (/^-g-$/) { $go_mode = 0; }
- elsif (/^-gg$/) {
- $go_mode = 2; $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 0;
- }
- elsif ( /^-h$/ || /^-help$/ ) { &print_help; exit;}
- elsif (/^-jobname=(.*)$/) {
- $jobname = $1;
- }
- elsif (/^-l$/) { $landscape_mode = 1; }
- elsif (/^-l-$/) { $landscape_mode = 0; }
- elsif ( /^-latex$/ ) {
- $pdf_mode = 0;
- $postscript_mode = 0;
- $dvi_mode = 1;
- }
- elsif (/^-latex=(.*)$/) {
- $latex = $1;
- }
- elsif (/^-latexoption=(.*)$/) {
- push @extra_latex_options, $1;
- push @extra_pdflatex_options, $1;
- push @extra_lualatex_options, $1;
- push @extra_xelatex_options, $1;
- }
- elsif ( /^-logfilewarninglist$/ || /^-logfilewarnings$/ )
- { $silence_logfile_warnings = 0; }
- elsif ( /^-logfilewarninglist-$/ || /^-logfilewarnings-$/ )
- { $silence_logfile_warnings = 1; }
- elsif ( /^-lualatex$/ || /^-pdflualatex$/ ) {
- $pdf_mode = 4;
- $dvi_mode = $postscript_mode = 0;
- }
-# See below for -lualatex=...
-# See above for -M
- elsif (/^-MF$/) {
- if ( $ARGV[0] eq '' ) {
- &exit_help( "No file name specified after -MF switch");
- }
- $deps_file = $ARGV[0];
- shift;
- }
- elsif ( /^-MP$/ ) { $dependents_phony = 1; }
- elsif ( /-MSWinBackSlash$/ ) { $MSWin_back_slash = 1; }
- elsif ( /-MSWinBackSlash-$/ ) { $MSWin_back_slash = 0; }
- elsif (/^-new-viewer$/) {
- $new_viewer_always = 1;
- }
- elsif (/^-new-viewer-$/) {
- $new_viewer_always = 0;
- }
- elsif (/^-norc$/ ) {
- $auto_rc_use = 0;
- # N.B. This has already been obeyed.
- }
- elsif (/^-nobibfudge$/) { $bibtex_fudge = 0; }
- elsif ( /^-output-directory=(.*)$/ ||/^-outdir=(.*)$/ ) {
- $out_dir = $1;
- }
- elsif (/^-p$/) { $printout_mode = 1;
- $preview_continuous_mode = 0; # to avoid conflicts
- $preview_mode = 0;
- }
- elsif (/^-p-$/) { $printout_mode = 0; }
- elsif (/^-pdf$/) { $pdf_mode = 1; }
- elsif (/^-pdf-$/) { $pdf_mode = 0; }
- elsif (/^-pdfdvi$/){ $pdf_mode = 3; }
- elsif (/^-pdflua$/){ $pdf_mode = 4; }
- elsif (/^-pdfps$/) { $pdf_mode = 2; }
- elsif (/^-pdfxe$/) { $pdf_mode = 5; }
- elsif (/^-pdflatex$/) {
- $pdflatex = "pdflatex %O %S";
- $pdf_mode = 1;
- $dvi_mode = $postscript_mode = 0;
- }
- elsif (/^-pdflatex=(.*)$/) {
- $pdflatex = $1;
- }
- elsif ( /^-pdflualatex=(.*)$/ || /^-lualatex=(.*)$/ ) {
- $lualatex = $1;
- }
- elsif ( /^-pdfxelatex=(.*)$/ || /^-xelatex=(.*)$/ ) {
- $xelatex = $1;
- }
- elsif (/^-pretex=(.*)$/) {
- $pre_tex_code = $1;
- }
- elsif (/^-print=(.*)$/) {
- $value = $1;
- if ( $value =~ /^dvi$|^ps$|^pdf$|^auto$/ ) {
- $print_type = $value;
- $printout_mode = 1;
- }
- else {
- &exit_help("$My_name: unknown print type '$value' in option '$_'");
- }
- }
- elsif (/^-ps$/) { $postscript_mode = 1; }
- elsif (/^-ps-$/) { $postscript_mode = 0; }
- elsif (/^-pv$/) { $preview_mode = 1;
- $preview_continuous_mode = 0; # to avoid conflicts
- $printout_mode = 0;
- }
- elsif (/^-pv-$/) { $preview_mode = 0; }
- elsif (/^-pvc$/) { $preview_continuous_mode = 1;
- $force_mode = 0; # So that errors do not cause loops
- $preview_mode = 0; # to avoid conflicts
- $printout_mode = 0;
- }
- elsif (/^-pvc-$/) { $preview_continuous_mode = 0; }
- elsif (/^-pvctimeout$/) { $pvc_timeout = 1; }
- elsif (/^-pvctimeout-$/) { $pvc_timeout = 0; }
- elsif (/^-pvctimeoutmins=(.*)$/) { $pvc_timeout_mins = $1; }
- elsif (/^-recorder$/ ){ $recorder = 1; }
- elsif (/^-recorder-$/ ){ $recorder = 0; }
- elsif (/^-rules$/ ) { $rules_list = 1; }
- elsif (/^-norules$/ || /^-rules-$/ ) { $rules_list = 0; }
- elsif (/^-showextraoptions$/) {
- print "List of extra latex and pdflatex options recognized by $my_name.\n",
- "These are passed as is to *latex. They may not be recognized by\n",
- "particular versions of *latex. This list is a combination of those\n",
- "for TeXLive and MikTeX.\n",
- "\n",
- "Note that in addition to the options in this list, there are several\n",
- "options known to the *latex programs that are also recognized by\n",
- "latexmk and trigger special behavior by latexmk. Since these options\n",
- "appear in the main list given by running 'latexmk --help', they do not\n",
- "appear in the following list\n",
- "NOTE ALSO: Not all of these options are supported by all versions of *latex.\n",
- "\n";
- foreach $option ( sort( keys %allowed_latex_options, keys %allowed_latex_options_with_arg ) ) {
- if (exists $allowed_latex_options{$option} ) { print " $allowed_latex_options{$option}\n"; }
- if (exists $allowed_latex_options_with_arg{$option} ) { print " $allowed_latex_options_with_arg{$option}\n"; }
- }
- exit;
- }
- elsif (/^-silent$/ || /^-quiet$/ ){ $silent = 1; }
- elsif (/^-stdtexcmds$/) { &std_tex_cmds; }
- elsif (/^-time$/) { $show_time = 1;}
- elsif (/^-time-$/) { $show_time = 0;}
- elsif (/^-use-make$/) { $use_make_for_missing_files = 1; }
- elsif (/^-use-make-$/) { $use_make_for_missing_files = 0; }
- elsif (/^-usepretex$/) { &alt_tex_cmds; }
- elsif (/^-usepretex=(.*)$/) {
- &alt_tex_cmds;
- $pre_tex_code = $1;
- }
- elsif (/^-v$/ || /^-version$/) {
- print "\n$version_details. Version $version_num\n";
- exit;
- }
- elsif (/^-verbose$/) { $silent = 0; }
- elsif (/^-view=default$/) { $view = "default";}
- elsif (/^-view=dvi$/) { $view = "dvi";}
- elsif (/^-view=none$/) { $view = "none";}
- elsif (/^-view=ps$/) { $view = "ps";}
- elsif (/^-view=pdf$/) { $view = "pdf"; }
- elsif (/^-Werror$/){ $warnings_as_errors = 1; }
- elsif ( /^-xelatex$/ || /^-pdfxelatex$/ ) {
- $pdf_mode = 5;
- $dvi_mode = $postscript_mode = 0;
- }
-# See above for -xelatex=...
- elsif (/^-e$/) {
- if ( $#ARGV < 0 ) {
- &exit_help( "No code to execute specified after -e switch");
- }
- execute_code_string( $ARGV[0] );
- shift;
- }
- elsif (/^-r$/) {
- if ( $ARGV[0] eq '' ) {
- &exit_help( "No RC file specified after -r switch");
- }
- if ( -e $ARGV[0] ) {
- process_rc_file( $ARGV[0] );
- }
- else {
- die "$My_name: RC file [$ARGV[0]] does not exist\n";
- }
- shift;
- }
- elsif (/^-bm$/) {
- if ( $ARGV[0] eq '' ) {
- &exit_help( "No message specified after -bm switch");
- }
- $banner = 1; $banner_message = $ARGV[0];
- shift;
- }
- elsif (/^-bi$/) {
- if ( $ARGV[0] eq '' ) {
- &exit_help( "No intensity specified after -bi switch");
- }
- $banner_intensity = $ARGV[0];
- shift;
- }
- elsif (/^-bs$/) {
- if ( $ARGV[0] eq '' ) {
- &exit_help( "No scale specified after -bs switch");
- }
- $banner_scale = $ARGV[0];
- shift;
- }
- elsif (/^-dF$/) {
- if ( $ARGV[0] eq '' ) {
- &exit_help( "No dvi filter specified after -dF switch");
- }
- $dvi_filter = $ARGV[0];
- shift;
- }
- elsif (/^-pF$/) {
- if ( $ARGV[0] eq '' ) {
- &exit_help( "No ps filter specified after -pF switch");
- }
- $ps_filter = $ARGV[0];
- shift;
- }
- elsif ( ( exists( $allowed_latex_options{$_} ) )
- || ( /^(-.+)=/ && exists( $allowed_latex_options_with_arg{$1} ) )
- )
- {
- push @extra_latex_options, $original;
- push @extra_pdflatex_options, $original;
- push @extra_lualatex_options, $original;
- push @extra_xelatex_options, $original;
- }
- elsif (/^-/) {
- warn "$My_name: $_ bad option\n";
- $bad_options++;
- }
- else {
- push @command_line_file_list, $_ ;
- }
-}
-
-show_array( "Rc files read:", @rc_files_read )
- unless ( $silent && ! $diagnostics );
-
-if ( $bad_options > 0 ) {
- &exit_help( "Bad options specified" );
-}
-
-warn "$My_name: This is $version_details, version: $version_num.\n",
- unless $silent;
-
-
-if ( ($out_dir ne '') && ($aux_dir eq '') ){
- $aux_dir = $out_dir;
-}
-
-# Save original values for use in diagnositics.
-# We may change $aux_dir and $out_dir after a detection
-# of results of misconfiguration.
-$aux_dir_requested = $aux_dir;
-$out_dir_requested = $out_dir;
-# The following reports results of diagnostics on location of .log file
-# after the first run of a latex engine, when actually used aux_dir
-# may not be the expected one, due to a configuration error.
-# Values: -1 uninitialized (before first run)
-# 0 log file not found;
-# 1 log file in aux_dir;
-# 2 log file **not** in aux_dir but in out_dir;
-# 3 log file **not** in aux_dir or out_dir, but in cwd.
-$where_log = -1;
-
-&set_dirs_etc;
-
-if ($bibtex_use > 1) {
- push @generated_exts, 'bbl';
-}
-
-# For backward compatibility, convert $texfile_search to @default_files
-# Since $texfile_search is initialized to "", a nonzero value indicates
-# that an initialization file has set it.
-if ( $texfile_search ne "" ) {
- @default_files = split /\s+/, "*.tex $texfile_search";
-}
-
-#Glob the filenames command line if the script was not invoked under a
-# UNIX-like environment.
-# Cases: (1) MS/MSwin native Glob
-# (OS detected as MSWin32)
-# (2) MS/MSwin cygwin Glob [because we do not know whether
-# the cmd interpreter is UNIXy (and does glob) or is
-# native MS-Win (and does not glob).]
-# (OS detected as cygwin)
-# (3) UNIX Don't glob (cmd interpreter does it)
-# (Currently, I assume this is everything else)
-if ( ($^O eq "MSWin32") || ($^O eq "cygwin") ) {
- # Preserve ordering of files
- @file_list = glob_list1(@command_line_file_list);
-#print "A1:File list:\n";
-#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; }
-}
-else {
- @file_list = @command_line_file_list;
-}
-@file_list = uniq1( @file_list );
-
-
-# Check we haven't selected mutually exclusive modes.
-# Note that -c overrides all other options, but doesn't cause
-# an error if they are selected.
-if (($printout_mode && ( $preview_mode || $preview_continuous_mode ))
- || ( $preview_mode && $preview_continuous_mode ))
-{
- # Each of the options -p, -pv, -pvc turns the other off.
- # So the only reason to arrive here is an incorrect inititalization
- # file, or a bug.
- &exit_help( "Conflicting options (print, preview, preview_continuous) selected");
-}
-
-if ( @command_line_file_list ) {
- # At least one file specified on command line (before possible globbing).
- if ( !@file_list ) {
- &exit_help( "Wildcards in file names didn't match any files");
- }
-}
-else {
- # No files specified on command line, try and find some
- # Evaluate in order specified. The user may have some special
- # for wanting processing in a particular order, especially
- # if there are no wild cards.
- # Preserve ordering of files
- my @file_list1 = uniq1( glob_list1(@default_files) );
- my @excluded_file_list = uniq1( glob_list1(@default_excluded_files) );
- # Make hash of excluded files, for easy checking:
- my %excl = ();
- foreach my $file (@excluded_file_list) {
- $excl{$file} = '';
- }
- foreach my $file (@file_list1) {
- push( @file_list, $file) unless ( exists $excl{$file} );
- }
- if ( !@file_list ) {
- &exit_help( "No file name specified, and I couldn't find any");
- }
-}
-
-$num_files = $#file_list + 1;
-$num_specified = $#command_line_file_list + 1;
-
-#print "Command line file list:\n";
-#for ($i = 0; $i <= $#command_line_file_list; $i++ ) { print "$i: '$command_line_file_list[$i]'\n"; }
-#print "File list:\n";
-#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; }
-
-
-# If selected a preview-continuous mode, make sure exactly one filename was specified
-if ($preview_continuous_mode && ($num_files != 1) ) {
- if ($num_specified > 1) {
- &exit_help(
- "Need to specify exactly one filename for ".
- "preview-continuous mode\n".
- " but $num_specified were specified"
- );
- }
- elsif ($num_specified == 1) {
- &exit_help(
- "Need to specify exactly one filename for ".
- "preview-continuous mode\n".
- " but wildcarding produced $num_files files"
- );
- }
- else {
- &exit_help(
- "Need to specify exactly one filename for ".
- "preview-continuous mode.\n".
- " Since none were specified on the command line, I looked for \n".
- " files in '@default_files'.\n".
- " But I found $num_files files, not 1."
- );
- }
-}
-
-# If selected jobname, can only apply that to one file:
-if ( ($jobname ne '') && ($jobname !~ /%A/) && ($num_files > 1) ) {
- &exit_help(
- "Need to specify at most one filename if ".
- "jobname specified without a %A, \n".
- " but $num_files were found (after defaults and wildcarding)."
- );
-}
-if ( $jobname =~ /%[^A]/ ) {
- &exit_help(
- "Jobname '$jobname' contains placeholder other than %A."
- );
-}
-
-# Normalize the commands, to have place-holders for source, dest etc:
-&fix_cmds;
-
-# Add common options
-add_option( $latex_default_switches, \$latex );
-add_option( $pdflatex_default_switches, \$pdflatex );
-add_option( $lualatex_default_switches, \$lualatex );
-add_option( $xelatex_default_switches, \$xelatex );
-
-foreach (@extra_latex_options) { add_option( $_, \$latex ); }
-foreach (@extra_pdflatex_options) { add_option( $_, \$pdflatex ); }
-foreach (@extra_lualatex_options) { add_option( $_, \$lualatex ); }
-foreach (@extra_xelatex_options) { add_option( $_, \$xelatex ); }
-
-
-# If landscape mode, change dvips processor, and the previewers:
-if ( $landscape_mode )
-{
- $dvips = $dvips_landscape;
- $dvi_previewer = $dvi_previewer_landscape;
- $ps_previewer = $ps_previewer_landscape;
-}
-
-if ( $silent ) {
- add_option( "$latex_silent_switch", \$latex );
- add_option( "$pdflatex_silent_switch", \$pdflatex );
- add_option( "$lualatex_silent_switch", \$lualatex );
- add_option( "$xelatex_silent_switch", \$xelatex );
- add_option( "$biber_silent_switch", \$biber );
- add_option( "$bibtex_silent_switch", \$bibtex );
- add_option( "$makeindex_silent_switch", \$makeindex );
- add_option( "$dvipdf_silent_switch", \$dvipdf );
- add_option( "$dvips_silent_switch", \$dvips );
- add_option( "$xdvipdfmx_silent_switch", \$xdvipdfmx );
-}
-
-if ( $recorder ) {
- add_option( "-recorder", \$latex, \$pdflatex, \$lualatex, \$xelatex );
-}
-
-# If the output and/or aux directories are specified, fix the *latex
-# commands to use them.
-# N.B. We'll ensure that the directories actually exist only after a
-# possible cd to the document directory, since the directories can be
-# relative to the document.
-
-$q = $quote_filenames ? '"' : '';
-if ( $out_dir ) {
- add_option( "-output-directory=$q$out_dir$q",
- \$latex, \$pdflatex, \$lualatex, \$xelatex );
-}
-if ( $aux_dir && ($aux_dir ne $out_dir) ) {
- # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
- # option is sufficient, especially because the -aux-directory exists
- # only in MiKTeX, not in TeXLive.
- add_option( "-aux-directory=$q$aux_dir$q",
- \$latex, \$pdflatex, \$lualatex, \$xelatex );
-}
-
-if ( $jobname ne '' ) {
- # Since $jobname may include placeholder(s), put %R placeholder
- # in option, and let %R be substituted by actual jobname at runtime.
- add_option( "--jobname=%R", \$latex, \$lualatex, \$pdflatex, \$xelatex );
-}
-
-# Which kind of file do we preview?
-if ( $view eq "default" ) {
- # If default viewer requested, use "highest" of dvi, ps and pdf
- # that was requested by user.
- # No explicit request means view dvi.
- $view = "dvi";
- if ( $postscript_mode ) { $view = "ps"; }
- if ( $pdf_mode ) { $view = "pdf"; }
-}
-
-# Make sure we make the kind of file we want to view:
-if ($view eq 'dvi') { $dvi_mode = 1; }
-if ($view eq 'ps') { $postscript_mode = 1; }
-if ( ($view eq 'pdf') && ($pdf_mode == 0) ) {
- $pdf_mode = 1;
-}
-
-# Make sure that we make something if all requests are turned off
-if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) {
- print "No specific requests made, so default to dvi by latex\n";
- $dvi_mode = 1;
-}
-
-# Determine requests.
-if ( $banner ) { $postscript_mode = 1; }
-if ( $dvi_mode ) {
- $current_primary = 'latex';
- $requested_filetypes{'dvi'} = 1;
- if ( length($dvi_filter) != 0 ) { $requested_filetypes{'dviF'} = 1; }
-}
-if ( $postscript_mode ) {
- $current_primary = 'latex';
- $requested_filetypes{'ps'} = 1;
- if ( length($ps_filter) != 0 ) { $requested_filetypes{'psF'} = 1; }
-}
-
-if ($pdf_mode > 5) {
- warn "$My_name: Non-allowed value of \$pdf_mode = $pdf_mode,",
- " replaced by 1.\n";
- $pdf_mode = 1;
-}
-if ( ($dvi_mode || $postscript_mode) && $pdf_mode ) {
- my %disallowed = ();
- foreach (1,4,5) { $disallowed{$_} = 1; }
- if ($disallowed{$pdf_mode}) {
- warn "$My_name: \$pdf_mode = $pdf_mode is incompatible with dvi and postscript modes\n",
- " which are required by other requests.\n";
- if ($postscript_mode) {$pdf_mode = 2;}
- else { $pdf_mode = 3; }
- warn " I replaced it by $pdf_mode.\n";
- }
-}
-if ( $pdf_mode == 0 ) {
- $pdf_method = '';
-}
-elsif ( $pdf_mode == 1 ) {
- $requested_filetypes{'pdf'} = 1;
- $pdf_method = 'pdflatex';
-}
-elsif ( $pdf_mode == 2 ) {
- $requested_filetypes{'pdf'} = 1;
- $pdf_method = 'ps2pdf';
-}
-elsif ( $pdf_mode == 3 ) {
- $requested_filetypes{'pdf'} = 1;
- $pdf_method = 'dvipdf';
-}
-elsif ( $pdf_mode == 4 ) {
- $requested_filetypes{'pdf'} = 1;
- $pdf_method = 'lualatex';
-}
-elsif ( $pdf_mode == 5 ) {
- $requested_filetypes{'pdf'} = 1;
- $pdf_method = 'xelatex';
-}
-
-if ($print_type eq 'auto') {
- if ( $postscript_mode ) { $print_type = 'ps'; }
- elsif ( $pdf_mode ) { $print_type = 'pdf'; }
- elsif ( $dvi_mode ) { $print_type = 'dvi'; }
- else { $print_type = 'none'; }
-}
-if ( $printout_mode ) {
- $one_time{'print'} = 1;
- if ($print_type eq 'none'){
- warn "$My_name: You have requested printout, but \$print_type is set to 'none'\n";
- }
-}
-if ( $preview_continuous_mode || $preview_mode ) { $one_time{'view'} = 1; }
-
-$can_switch = $allow_switch;
-if ( $dvi_mode || $postscript_mode
- || ( $printout_mode && ($print_type eq 'ps') || ($print_type eq 'dvi') )
- || ( ($preview_mode || $preview_continuous_mode) && ( ($view eq 'ps') || ($view eq 'dvi') ) )
- ) {
- # Automatic switching (e.g., pdf<->dvi o/p) requires pdf files to be
- # the only destinations. So if ps or dvi files needed, we cannot
- # allow switching. (There will then be an error condition if a TeX
- # engine fails to produce the correct type of output file.)
- if ($diagnostics) {
- warn "$My_name: Disallowing switch of output file as incompatible\n",
- " with file requests.\n";
- }
- $can_switch = 0;
-}
-
-
-if ( $pdf_mode == 2 ) {
- # We generate pdf from ps. Make sure we have the correct kind of ps.
- add_option( "$dvips_pdf_switch", \$dvips );
-}
-
-# Restrict variables to allowed values:
-
-if ($filetime_causality_threshold < 0) {
- warn "$My_name: Correcting negative value of \$filetime_causality_threshold to zero.\n";
- $filetime_causality_threshold = 0;
-}
-
-# Note sleep has granularity of 1 second.
-# Sleep periods 0 < $sleep_time < 1 give zero delay,
-# which is probably not what the user intended.
-# Sleep periods less than zero give infinite delay
-if ( $sleep_time < 0 ) {
- warn "$My_name: Correcting negative sleep_time to 1 sec.\n";
- $sleep_time = 1;
-}
-elsif ( ($sleep_time < 1) && ( $sleep_time != 0 ) ) {
- warn "$My_name: Correcting nonzero sleep_time of less than 1 sec to 1 sec.\n";
- $sleep_time = 1;
-}
-elsif ( $sleep_time == 0 ) {
- warn "$My_name: sleep_time was configured to zero.\n",
- " Do you really want to do this? It will give 100% CPU usage.\n";
-}
-
-# Make convenient forms for lookup.
-# Extensions always have period.
-
-# Convert @generated_exts to a hash for ease of look up and deletion
-# Keep extension without period!
-%generated_exts_all = ();
-foreach (@generated_exts ) {
- $generated_exts_all{$_} = 1;
-}
-
-$quell_uptodate_msgs = $silent;
- # Whether to quell informational messages when files are uptodate
- # Will turn off in -pvc mode
-
-$failure_count = 0;
-@failed_primaries = ();
-
-if ($deps_file eq '' ) {
- # Standardize name used for stdout
- $deps_file = '-';
-}
-
-# Since deps_file is global (common to all processed files), we must
-# delete it here when doing a clean up, and not in the FILE loop, where
-# per-file processing (including clean-up) is done
-if ( ($cleanup_mode > 0) && $dependents_list && ( $deps_file ne '-' ) ) {
- unlink_or_move( $deps_file );
-}
-
-# In non-pvc mode, the dependency list is global to all processed TeX files,
-# so we open a single file here, and add items to it after processing
-# each file. But in -pvc mode, the dependency list should be written
-# after round of processing the single TeX file (as if each round were
-# a separate run of latexmk).
-# If we are cleaning up ($cleanup_mode != 0) AND NOT continuing to
-# make files (--gg option and $go_mode == 2), deps_file should not be
-# created.
-# I will use definedness of $deps_handle as flag for global deps file having
-# been opened and therefore being available to be written to after
-# compiling a file.
-$deps_handle = undef;
-if ( $dependents_list
- && ! $preview_continuous_mode
- && ( ($cleanup_mode == 0) || ($go_mode == 2) )
- ) {
- $deps_handle = new FileHandle "> $deps_file";
- if (! $deps_handle ) {
- die "Cannot open '$deps_file' for output of dependency information\n";
- }
-}
-
-# Remove leading and trailing space in the following space-separated lists,
-# and collapse multiple spaces to one,
-# to avoid getting incorrect blank items when they are split.
-foreach ($clean_ext, $clean_full_ext) { s/^\s+//; s/\s+$//; s/\s+/ /g; }
-
-# Deal with illegal and problematic characters in filename:
-test_fix_texnames( @file_list );
-
-FILE:
-foreach $filename ( @file_list )
-{
- # Global variables for making of current file:
- $updated = 0;
- $failure = 0; # Set nonzero to indicate failure at some point of
- # a make. Use value as exit code if I exit.
- $failure_msg = ''; # Indicate reason for failure
-
- if ( $do_cd ) {
- ($filename, $path) = fileparse( $filename );
- warn "$My_name: Changing directory to '$path'\n"
- if !$silent;
- pushd( dirname_no_tail( $path ) );
- }
- else {
- $path = '';
- }
-
- # Ensure the output/auxiliary directories exist, if need be
- if ( $out_dir ) {
- if ( ! -e $out_dir ) {
- warn "$My_name: making output directory '$out_dir'\n"
- if ! $silent;
- make_path $out_dir;
- }
- elsif ( ! -d $out_dir ) {
- warn "$My_name: you requested output directory '$out_dir',\n",
- " but an ordinary file of the same name exists, which will\n",
- " probably give an error later\n";
- }
- }
-
- if ( $aux_dir && ($aux_dir ne $out_dir) ) {
- # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
- # option is sufficient, especially because the -aux-directory exists
- # only in MiKTeX, not in TeXLive.
- if ( ! -e $aux_dir ) {
- warn "$My_name: making auxiliary directory '$aux_dir'\n"
- if ! $silent;
- make_path $aux_dir;
- }
- elsif ( ! -d $aux_dir ) {
- warn "$My_name: you requested aux directory '$aux_dir',\n",
- " but an ordinary file of the same name exists, which will\n",
- " probably give an error later\n";
- }
- }
-
- &set_names;
- # For use under error conditions:
- @default_includes = ($texfile_name, $aux_main);
- # N.B. Do **not** apply local %rule_db here. It might appear appropriate,
- # but %rule_db is needed in the continue block, which is not in the
- # scope of a local declaration here.
- &rdb_initialize_rules;
- $view_file = '';
- rdb_one_rule( 'view', sub{ $view_file = $$Psource; } );
-
- if ( $cleanup_mode > 0 ) {
-# ?? MAY NEED TO FIX THE FOLLOWING IF $aux_dir or $out_dir IS SET.
- my %other_generated = ();
- my @index_bibtex_generated = ();
- my @aux_files = ();
- my @missing_bib_files = ();
- my $bibs_all_exist = 0;
- my %final_output_files = ();
- foreach (keys %small_cleanup_preserved_exts) {
- $final_output_files{"$out_dir1$root_filename.$_"} = 1;
- }
- $have_fdb = 0;
- if ( -e $fdb_name ) {
- print "$My_name: Examining fdb file '$fdb_name' for rules ...\n"
- if $diagnostics;
- $have_fdb = ( 0 == rdb_read( $fdb_name ) );
- }
- if ( $have_fdb ) {
- rdb_for_actives(
- sub { # Find generated files at rule level
- my ($base, $path, $ext) = fileparseA( $$Psource );
- $base = $path.$base;
- if ( $rule =~ /^makeindex/ ) {
- push @index_bibtex_generated, $$Psource, $$Pdest, "$base.ilg";
- }
- elsif ( $rule =~ /^(bibtex|biber)/ ) {
- push @index_bibtex_generated, $$Pdest, "$base.blg";
- push @aux_files, $$Psource;
- if ( $bibtex_use == 1.5) {
- foreach ( keys %$PHsource ) {
- if ( ( /\.bib$/ ) && (! -e $_) ) {
- push @missing_bib_files, $_;
- }
- }
- }
- }
- elsif ( exists $other_generated{$$Psource} ) {
-# print "=========== CHECKING: source file of rule '$rule', '$$Psource'\n",
-# " is a generated file.\n";
- ## OLD with apparent bug:
- #$other_generated{$$Pdest};
- }
- foreach my $key (keys %$PHdest) {
- $other_generated{$key} = 1;
- }
- },
- sub { # Find generated files at source file level
- if ( $file =~ /\.aux$/ ) { push @aux_files, $file; }
- }
- );
- if ($#missing_bib_files == -1) { $bibs_all_exist = 1; }
- }
- elsif ( -e $log_name ) {
- # No fdb file, but log file exists, so do inferior job by parse_log
- print "$My_name: Examining log file '$log_name' for generated files...\n"
- if $diagnostics;
- # Variables set by parse_log. Can I remove them?
- local %generated_log = ();
- local %dependents = (); # Maps files to status. Not used here.
- local @bbl_files = (); # Not used here.
- local %idx_files = (); # Maps idx_file to (ind_file, base). Not used here.
- local %conversions = (); # *latex-performed conversions. Not used here.
- # Maps output file created and read by *latex
- # to source file of conversion.
- local $primary_out = ''; # Actual output file (dvi or pdf). Not used here.
- local $fls_file_analyzed = 0;
- &parse_log;
- %other_generated = %generated_log;
- }
- else {
- print "$My_name: No fdb or log file, so clean up default set of files ...\n"
- if $diagnostics;
- }
-
- if ( ($go_mode == 2) && !$silent ) {
- warn "$My_name: Removing all generated files\n" unless $silent;
- }
- my $keep_bbl = 1;
- if ( ($bibtex_use > 1.6)
- ||
- ( ($bibtex_use == 1.5) && ($bibs_all_exist) )
- ) {
- $keep_bbl = 0;
- }
- if ($keep_bbl) {
- delete $generated_exts_all{'bbl'};
- }
- # Convert two arrays to hashes:
- my %index_bibtex_generated = ();
- my %aux_files = ();
- my %aux_files_to_save = ();
- foreach (@index_bibtex_generated) {
- $index_bibtex_generated{$_} = 1
- unless ( /\.bbl$/ && ($keep_bbl) );
- delete( $other_generated{$_} );
- }
- foreach (@aux_files) {
- if (exists $other_generated{$_} ) {
- $aux_files{$_} = 1;
- }
- else {
- $aux_files_to_save{$_} = 1;
- }
- }
-
- foreach (keys %final_output_files) { delete $other_generated{$_}; }
-
- if ($diagnostics) {
- show_array( "For deletion, the following were determined from fdb file or log file:\n"
- ." Generated (from makeindex and bibtex):",
- keys %index_bibtex_generated );
- show_array( " Aux files:", keys %aux_files );
- show_array( " Other generated files:\n"
- ." (only deleted if \$cleanup_includes_generated is set): ",
- keys %other_generated );
- show_array( " Yet other generated files are specified by patterns:\n".
- " Explicit pattern with %R or root-filename.extension:",
- keys %generated_exts_all );
- show_array( " Aux files to SAVE and not delete:", keys %aux_files_to_save );
- }
-
- my @clean_args = ( 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak',
- split('\s+',$clean_ext), keys %generated_exts_all );
- cleanup1( $aux_dir1, @clean_args );
- if ( $out_dir1 ne $aux_dir1 ) { cleanup1( $out_dir1, @clean_args ); }
- if ( $cleanup_mode == 1 ) {
- my @clean_args = ( keys %small_cleanup_preserved_exts, split('\s+', $clean_full_ext) );
- cleanup1( $aux_dir1, @clean_args );
- if ( $out_dir1 ne $aux_dir1 ) { cleanup1( $out_dir1, @clean_args ); }
- }
- unlink_or_move( 'texput.log', "texput.aux", "missfont.log",
- keys %index_bibtex_generated,
- keys %aux_files );
- if ($cleanup_includes_generated) {
- unlink_or_move( keys %other_generated );
- }
- if ( $cleanup_includes_cusdep_generated) {
- &cleanup_cusdep_generated;
- }
- }
- if ($cleanup_fdb) {
- unlink_or_move( $fdb_name );
- # If the fdb file exists, it will have been read, and therefore changed
- # rule database. But deleting the fdb file implies we also want
- # a virgin rule database, so we must reset it:
- &rdb_initialize_rules;
- }
- if ($cleanup_only) { next FILE; }
-
- if ( $diagnostics ) {
- print "$My_name: Rules after start up for '$texfile_name'\n";
- rdb_show();
- }
-
- $have_fdb = 0;
- if (! -e $aux_main ) {
- # No aux file => set up trivial aux file
- # and corresponding fdb_file. Arrange them to provoke one run
- # as minimum, but no more if actual aux file is trivial.
- # (Useful on big files without cross references.)
- # If aux file doesn't exist, then any fdb file is surely
- # wrong.
- # Previously, I had condition for this as being both aux and
- # fdb files failing to exist. But it's not obvious what to
- # do if aux exists and fdb doesn't. So I won't do anything.
- &set_trivial_aux_fdb;
- }
-
- if ( -e $fdb_name ) {
- $rdb_errors = rdb_read( $fdb_name );
- $have_fdb = ($rdb_errors == 0);
- }
- if (!$have_fdb) {
- # We didn't get a valid set of data on files used in
- # previous run. So use filetime criterion for make
- # instead of change from previous run, until we have
- # done our own make.
- rdb_recurse( [keys %possible_primaries],
- sub{ if ( $$Ptest_kind == 1 ) { $$Ptest_kind = 3;} }
- );
- if ( -e $log_name ) {
- rdb_for_some( [keys %current_primaries], \&rdb_set_latex_deps );
- }
- }
- foreach $rule ( &rdb_accessible ) {
- # For all source files of all accessible rules,
- # if the file data are not already set (e.g., from fdb_latexmk
- # file, set them from disk.
- rdb_one_rule ($rule, undef,
- sub{ if ( $$Ptime == 0) { &rdb_update1; } }
- );
- }
-
- if ($go_mode) {
- # Force everything to be remade.
- rdb_recurse( [ &rdb_target_array], sub{$$Pout_of_date=1;} );
- }
-
-
- if ( $diagnostics ) {
- print "$My_name: Rules after initialization\n";
- rdb_show();
- }
-
- #************************************************************
-
- if ( $preview_continuous_mode ) {
- &make_preview_continuous;
- next FILE;
- }
-
-
-## Handling of failures:
-## Variable $failure is set to indicate a failure, with information
-## put in $failure_msg.
-## These variables should be set to 0 and '' at any point at which it
-## should be assumed that no failures have occurred.
-## When after a routine is called it is found that $failure is set, then
-## processing should normally be aborted, e.g., by return.
-## Then there is a cascade of returns back to the outermost level whose
-## responsibility is to handle the error.
-## Exception: An outer level routine may reset $failure and $failure_msg
-## after initial processing, when the error condition may get
-## ameliorated later.
- #Initialize failure flags now.
- $failure = 0;
- $failure_msg = '';
- if ($compiling_cmd) { Run_subst( $compiling_cmd ); }
- $failure = &rdb_make;
- if ( ( $failure <= 0 ) || $force_mode ) {
- rdb_for_some( [keys %one_time], \&rdb_run1 );
- }
- if ($#primary_warning_summary > -1) {
- # N.B. $mult_defined, $bad_reference, $bad_character, $bad_citation also available here.
- if ($warnings_as_errors) {
- $failure = 1;
- $failure_msg = "Warning(s) from latex (or c.) for '$filename'; treated as error";
- }
- }
-
- if ($failure > 0) {
- if ($failure_cmd) { Run_subst( $failure_cmd ); }
- next FILE;
- } else {
- if ($success_cmd) { Run_subst( $success_cmd ); }
- }
-} # end FILE
-continue {
- if ($deps_handle) { deps_list($deps_handle); }
- # If requested, print the list of rules. But don't do this in -pvc
- # mode, since the rules list has already been printed.
- if ($rules_list && ! $preview_continuous_mode) { rdb_list(); }
- # Handle any errors
- $error_message_count = rdb_show_rule_errors();
- if ( ($error_message_count == 0) || ($failure > 0) ) {
- if ( $failure_msg ) {
- #Remove trailing space
- $failure_msg =~ s/\s*$//;
- warn "----------------------\n";
- warn "This message may duplicate earlier message.\n";
- warn "$My_name: Failure in processing file '$filename':\n",
- " $failure_msg\n";
- warn "----------------------\n";
- $failure = 1;
- }
- }
- if ( ($failure > 0) || ($error_message_count > 0) ) {
- $failure_count ++;
- push @failed_primaries, $filename;
- }
- &ifcd_popd;
-}
-close($deps_handle) if ( $deps_handle );
-
-if ($show_time) { show_timing();}
-
-sub show_timing {
- my $processing_time = processing_time() - $processing_time1;
- print @timings, "Accumulated processing time = $processing_time\n";
- @timings = ();
- $processing_time1 = processing_time();
-}
-
-# If we get here without going through the continue section:
-if ( $do_cd && ($#dir_stack > -1) ) {
- # Just in case we did an abnormal exit from the loop
- warn "$My_name: Potential bug: dir_stack not yet unwound, undoing all directory changes now\n";
- &finish_dir_stack;
-}
-
-if ($failure_count > 0) {
- if ( $#file_list > 0 ) {
- # Error occured, but multiple files were processed, so
- # user may not have seen all the error messages
- warn "\n------------\n";
- show_array(
- "$My_name: Some operations failed, for the following tex file(s)",
- @failed_primaries);
- }
- if ( !$force_mode ) {
- warn "$My_name: Use the -f option to force complete processing,\n",
- " unless error was exceeding maximum runs, or warnings treated as errors.\n";
- }
- exit 12;
-}
-
-if ( $where_log == 2 ) {
- warn "$My_name: You requested aux_dir '$aux_dir_requested',\n".
- " but '$aux_dir' was used by the *latex engine.\n".
- " That indicates a configuration error.\n";
- if ( ($tex_distribution !~ /^MiKTeX/i) && ($aux_dir_requested ne $out_dir_requested) ) {
- warn " Probably you set different aux and out directories,\n".
- " but that is not supported by your TeX distribution.\n".
- " The only current distribution supporting this is MiKTeX.\n";
- }
-}
-
-
-# end MAIN PROGRAM
-#############################################################
-#############################################################
-
-sub set_tex_cmds {
- # Usage, e.g., set_tex_cmds( '%O %S' )
- my $args = $_[0];
- foreach my $cmd ('latex', 'lualatex', 'pdflatex', 'xelatex' ) {
- ${$cmd} = "$cmd $args";
- }
- # N.B. See setting of $latex_default_switches, ...,
- # $xelatex_default_switches, etc, for any special options needed.
-}
-
-sub std_tex_cmds { set_tex_cmds( '%O %S' ); }
-
-sub alt_tex_cmds { set_tex_cmds( '%O %P' ); }
-
-#========================
-
-sub test_fix_texnames {
- my $illegal_char = 0;
- my $unbalanced_quote = 0;
- my $balanced_quote = 0;
- foreach (@_) {
- if ( ($^O eq "MSWin32") || ($^O eq "msys") ) {
- # On MS-Win, change directory separator '\' to '/', as needed
- # by the TeX engines, for which '\' introduces a macro name.
- # Remember that '/' is a valid directory separator in MS-Win.
- s[\\][/]g;
- }
- if ($do_cd) {
- my ($filename, $path) = fileparse( $_ );
- if ($filename =~ /[\Q$illegal_in_texname\E]/ ) {
- $illegal_char++;
- warn "$My_name: Filename '$filename' contains character not allowed for TeX file.\n";
- }
- if ($filename =~ /^&/) {
- $illegal_char++;
- warn "$My_name: Filename '$filename' contains initial '&', which is\n",
- " not allowed for TeX file.\n";
- }
- }
- else {
- if ( /[\Q$illegal_in_texname\E]/ ) {
- $illegal_char++;
- warn "$My_name: Filename '$_' contains character not allowed for TeX file.\n";
- }
- if (/^&/ ) {
- $illegal_char++;
- warn "$My_name: Filename '$_' contains initial '&', which is not allowed\n",
- " for TeX file.\n";
- }
- }
- my $count_q = ($_ =~ tr/\"//);
- if ( ($count_q % 2) != 0 ) {
- warn "$My_name: Filename '$_' contains unbalanced quotes, not allowed.\n";
- $unbalanced_quote++;
- }
- elsif ( $count_q > 0 ) {
- warn "$My_name: Removed (balanced quotes) from filename '$_',\n";
- s/\"//g;
- warn " and obtained '$_'.\n";
- $balanced_quote++;
- }
- }
- if ($illegal_char || $unbalanced_quote) {
- die "$My_name: Stopping because of bad filename(s).\n";
- }
-}
-
-#############################################################
-
-sub ensure_path {
- # Usage: ensure_path( $var, values ...)
- # $ENV{$var} is an environment variable (e.g. $ENV{TEXINPUTS}.
- # Ensure the values are in it, prepending them if not, and
- # creating the environment variable if it doesn't already exist.
- my $var = shift;
- my %cmpts = ();
- if ( exists $ENV{$var} ) {
- foreach ( split $search_path_separator, $ENV{$var} ) {
- if ($_ ne '') { $cmpts{$_} = 1; }
- }
- }
- foreach (@_) {
- next if ( ($_ eq '') || (exists $cmpts{$_}) );
- if (exists $ENV{$var}) {
- $ENV{$var} = $_ . $search_path_separator . $ENV{$var};
- }
- else {
- $ENV{$var} = $_ . $search_path_separator;
- }
- if (!$silent) {
- print "Set environment variable $var='$ENV{$var}'\n";
- }
- }
-}
-
-#############################################################
-
-sub set_dirs_etc {
- # Normalize versions terminating in directory/path separator
- # and versions referring to current directory
- # These actions in a subroutine so they can be used elsewhere.
- $out_dir = dirname_no_tail( $out_dir );
- $aux_dir = dirname_no_tail( $aux_dir );
- $out_dir1 = $out_dir;
- $aux_dir1 = $aux_dir;
- foreach ( $aux_dir1, $out_dir1 ) {
- if ( ($_ ne '') && ! m([\\/\:]$) ) {
- $_ .= '/';
- }
- while ( s[^\.\/][] ) {}
- }
- if ($aux_dir) {
- # Ensure $aux_dir is in BIBINPUTS and TEXINPUTS search paths.
- # TEXINPUTS is used by dvips for files generated by mpost.
- # For BIBINPUTS,
- # at least one widely package (revtex4-1) generates a bib file
- # (which is used in revtex4-1 for putting footnotes in the reference
- # list), and bibtex must be run to use it. But latexmk needs to
- # determine the existence of the bib file by use of kpsewhich, otherwise
- # there is an error. So cope with this situation (and any analogous
- # cases by adding the aux_dir to the relevant path search environment
- # variables. BIBINPUTS seems to be the only one currently affected.
- foreach ( 'BIBINPUTS', 'TEXINPUTS' ) {
- ensure_path( $_, $aux_dir );
- }
- }
-}
-
-#############################################################
-
-sub fix_cmds {
- # If commands do not have placeholders for %S etc, put them in
- foreach ($latex, $lualatex, $pdflatex, $xelatex, $lpr, $lpr_dvi, $lpr_pdf,
- $pdf_previewer, $ps_previewer, $ps_previewer_landscape,
- $dvi_previewer, $dvi_previewer_landscape,
- $kpsewhich
- ) {
- # Source only
- if ( $_ && ! /%/ ) { $_ .= " %O %S"; }
- }
- foreach ($pdf_previewer, $ps_previewer, $ps_previewer_landscape,
- $dvi_previewer, $dvi_previewer_landscape,
- ) {
- # Run previewers detached
- if ( $_ && ! /^(nostart|NONE|internal) / ) {
- $_ = "start $_";
- }
- }
- foreach ($biber, $bibtex) {
- # Base only
- if ( $_ && ! /%/ ) { $_ .= " %O %B"; }
- }
- foreach ($dvipdf, $ps2pdf) {
- # Source and dest without flag for destination
- if ( $_ && ! /%/ ) { $_ .= " %O %S %D"; }
- }
- foreach ($dvips, $makeindex) {
- # Source and dest with -o dest before source
- if ( $_ && ! /%/ ) { $_ .= " %O -o %D %S"; }
- }
- foreach ($dvi_filter, $ps_filter) {
- # Source and dest, but as filters
- if ( $_ && ! /%/ ) { $_ .= " %O <%S >%D"; }
- }
-} #END fix_cmds
-
-#############################################################
-
-sub add_option {
- # Call add_option( $opt, \$cmd ... )
- # Add option to one or more commands
- my $option = shift;
- while (@_) {
- if ( ${$_[0]} !~ /%/ ) { &fix_cmds; }
- ${$_[0]} =~ s/%O/$option %O/;
- shift;
- }
-} #END add_option
-
-#############################################################
-
-sub rdb_initialize_rules {
- # Initialize rule database.
- # (The rule database may get overridden/extended after the fdb_latexmk
- # file is read, and after running commands to adjust to dependencies
- # determined from document.
- %rule_db = ();
- %target_rules = ();
- %target_files = ();
-
- local %rule_list = ();
- &rdb_set_rule_templates;
-
- my %rule_template = %rule_list;
- while ( my ($key, $value) = each %extra_rule_spec ) {
- $rule_template{$key} = $value;
- }
- foreach my $rule ( keys %rule_template ) {
- my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind, $PA_extra_gen ) = @{$rule_template{$rule}};
- if ( ! $PA_extra_gen ) { $PA_extra_gen = []; }
- my $needs_making = 0;
- # Substitute in the filename variables, since we will use
- # those for determining filenames. But delay expanding $cmd
- # until run time, in case of changes.
- foreach ($base, $source, $dest, @$PA_extra_gen ) {
- s/%R/$root_filename/g;
- s/%Y/$aux_dir1/;
- s/%Z/$out_dir1/;
- }
- foreach ($source, $dest ) {
- s/%B/$base/;
- s/%T/$texfile_name/;
- }
- rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind,
- $source, $dest, $base,
- $needs_making, undef, undef, 1, $PA_extra_gen );
- } # End rule iteration
-
- # Ensure we only have one way to make pdf file, and that it is appropriate. Remove other incompatibilities
- if ($pdf_mode == 1) { rdb_deactivate( 'dvipdf', 'ps2pdf', 'latex', 'lualatex', 'xdvipdfmx', 'xelatex' ); }
- elsif ($pdf_mode == 2) { rdb_deactivate( 'dvipdf', 'pdflatex', 'lualatex', 'xdvipdfmx', 'xelatex' ); }
- elsif ($pdf_mode == 3) { rdb_deactivate( 'pdflatex', 'ps2pdf', 'lualatex', 'xdvipdfmx', 'xelatex' ); }
- elsif ($pdf_mode == 4) { rdb_deactivate( 'pdflatex', 'ps2pdf', 'dvipdf', 'xdvipdfmx', 'xelatex' ); }
- elsif ($pdf_mode == 5) { rdb_deactivate( 'pdflatex', 'ps2pdf', 'dvipdf', 'lualatex' ); }
- else { rdb_deactivate( 'dvipdf', 'pdflatex', 'ps2pdf', 'lualatex', 'xdvipdfmx', 'xelatex' ); }
-
- if ($dvi_mode == 1) {
- rdb_activate( 'latex' );
- $target_files{$dvi_final} = 1;
- }
- if ($postscript_mode == 1) {
- rdb_activate( 'latex' );
- $target_files{$ps_final} = 1;
- }
- if ($pdf_mode) { $target_files{$pdf_final} = 1; }
- &rdb_set_rule_net;
-} # END rdb_initialize_rules
-
-#************************************************************
-
-sub rdb_set_rule_templates {
-# Set up specifications for standard rules, adjusted to current conditions
-# Substitutions: %S = source, %D = dest, %B = this rule's base
-# %T = texfile, %R = root = base for latex.
-# %Y for $aux_dir1, %Z for $out_dir1
-
-
- my $print_file = '';
- my $print_cmd = 'NONE';
- if ( $print_type eq 'dvi' ) {
- $print_file = $dvi_final;
- $print_cmd = $lpr_dvi;
- }
- elsif ( $print_type eq 'pdf' ) {
- $print_file = $pdf_final;
- $print_cmd = $lpr_pdf;
- }
- elsif ( $print_type eq 'ps' ) {
- $print_file = $ps_final;
- $print_cmd = $lpr;
- }
- elsif ( $print_type eq 'none' ) {
- $print_cmd = 'NONE echo NO PRINTING CONFIGURED';
- }
-
- my $view_file = '';
- my $viewer = '';
- my $viewer_update_method = 0;
- my $viewer_update_signal = undef;
- my $viewer_update_command = undef;
-
- if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
- $view_file = ${$view.'_final'};
- $viewer = ${$view.'_previewer'};
- $viewer_update_method = ${$view.'_update_method'};
- $viewer_update_signal = ${$view.'_update_signal'};
- if (defined ${$view.'_update_command'}) {
- $viewer_update_command = ${$view.'_update_command'};
- }
- }
- # Specification of internal command for viewer update:
- my $PA_update = ['do_update_view', $viewer_update_method, $viewer_update_signal, 0, 1];
-
-# For test_kind: Use file contents for latex and friends, but file time for the others.
-# This is because, especially for dvi file, the contents of the file may contain
-# a pointer to a file to be included, not the contents of the file!
- %rule_list = (
- 'latex' => [ 'primary', "$latex", '', "%T", $dvi_name, "%R", 1, [$log_name] ],
- 'pdflatex' => [ 'primary', "$pdflatex", '', "%T", $pdf_name, "%R", 1, [$log_name] ],
- 'lualatex' => [ 'primary', "$lualatex", '', "%T", $pdf_name, "%R", 1, [$log_name] ],
- 'xelatex' => [ 'primary', "$xelatex", '', "%T", $xdv_name, "%R", 1, [$log_name] ],
- 'dvipdf' => [ 'external', "$dvipdf", 'do_viewfile', $dvi_final, $pdf_name, "%Z%R", 2 ],
- 'xdvipdfmx' => [ 'external', "$xdvipdfmx", 'do_viewfile', $xdv_final, $pdf_name, "%Z%R", 2 ],
- 'dvips' => [ 'external', "$dvips", 'do_viewfile', $dvi_final, $ps_name, "%Z%R", 2 ],
- 'dvifilter' => [ 'external', $dvi_filter, 'do_viewfile', $dvi_name, $dviF_name, "%Z%R", 2 ],
- 'ps2pdf' => [ 'external', "$ps2pdf", 'do_viewfile', $ps_final, $pdf_name, "%Z%R", 2 ],
- 'psfilter' => [ 'external', $ps_filter, 'do_viewfile', $ps_name, $psF_name, "%Z%R", 2 ],
- 'print' => [ 'external', "$print_cmd", 'if_source', $print_file, "", "", 2 ],
- 'update_view' => [ 'external', $viewer_update_command, $PA_update,
- $view_file, "", "", 2 ],
- 'view' => [ 'external', "$viewer", 'if_source', $view_file, "", "", 2 ],
- );
-} # END rdb_set_rule_templates
-
-#************************************************************
-
-sub rdb_set_rule_net {
- # Set network of rules, including links
- &rdb_make_links;
- &rdb_classify_rules;
-}
-
-#************************************************************
-
-sub rdb_make_links {
-# ?? Problem if there are multiple rules for getting a file. Notably pdf.
-# Which one to choose?
-# ?? Problem: what if a rule is inactive,
-# e.g., bibtex because biber is in use,
-# or xelatex when pdflatex is in use
-# or bibtex when $bibtex_use is 0.
-# What if both latex and pdflatex are being used?
-# That has been allowed. But .aux file (also
-# .log file) are made by both.
-
-# Other case: package (like bibtopic) creates bbl or other file when
-# it doesn't exist. Later a rule is created by latexmk to make that
-# file. Then the rule's main destination file should have priority
-# over non-main generated files from other rules.
- local %from_rules_old = %from_rules;
- &rdb_cache_generated;
- rdb_for_actives(
- 0,
- sub{
- if ( exists $from_rules_main{$file} ) {
- $$Pfrom_rule = $from_rules_main{$file};
- }
- elsif ( exists $from_rules{$file} ) {
- $$Pfrom_rule = $from_rules{$file};
- }
- if ( $$Pfrom_rule && (! rdb_rule_exists( $$Pfrom_rule ) ) ) {
- $$Pfrom_rule = '';
- }
- }
- );
- rdb_for_actives( \&rdb_set_source_rules );
-# &rdb_show;
-} # END rdb_make_links
-
-#************************************************************
-
-sub rdb_set_source_rules {
- # This applies to rules whose source file is a dvi or xdv file
- # Uses rule context
- my ($base, $path, $ext) = fileparseA( $$Psource );
- if ( ($ext eq '.dvi') || ($ext eq '.dviF') || ($ext eq '.xdv') ) {
- my $old_rule = $from_rules_old{$$Psource};
- my $new_rule = $from_rules{$$Psource};
- if ( defined $old_rule
- && defined $new_rule
- && ($old_rule eq $new_rule)
- && defined $$PHsource_rules{$new_rule}
- )
- { # Nothing to do: source rule is correct.
- }
- else {
- if ( defined $old_rule ) { delete $$PHsource_rules{$old_rule}; }
- if ( defined $new_rule ) { $$PHsource_rules{$new_rule} = 0; }
- }
- }
-}
-
-#************************************************************
-
-sub rdb_cache_generated {
- # Update %from_rules
- %from_rules = ();
- %from_rules_main = ();
- rdb_for_actives( \&one_from_main_rule_cache );
- rdb_for_actives( \&one_from_rule_cache );
-} # END rdb_cache_generated
-
-#------------
-
-sub one_from_main_rule_cache {
- # Rule context assumed.
- # Set from_rules_main items for one rule
- if (! $$Pdest) { return; }
-# Error message trigger: if ( $$Pdest =~ /pdf$/) { $from_rules_main{$$Pdest} = 'pdflatexA'; }
- if ( exists $from_rules_main{$$Pdest} ) {
- my $old_rule = $from_rules_main{$$Pdest};
- if ( $old_rule eq $rule ) {
- # OK
- }
- else {
- warn "$My_name: Possible bug:\n",
- " In linking rules I already set from_rules_main{$$Pdest} to '$old_rule'\n",
- " But now I want to set it to '$rule'\n";
-# traceback( "================================\nFrom one_from_main_rule_cache" );
- }
- }
- $from_rules_main{$$Pdest} = $rule;
-} # END one_from_main_rule_cache
-
-#------------
-
-sub one_from_rule_cache {
- # Rule context assumed.
- # Set from_rules items for one rule
- foreach ( @$PA_extra_gen, keys %$PHdest ) {
- # Error message trigger: if ( $_ =~ /aux$/) { $from_rules{$_} = 'pdflatexA'; }
- if ( exists $from_rules{$_} ) {
- my $old_rule = $from_rules{$_};
- if ( $old_rule eq $rule ) {
- # OK
- }
- elsif ( exists $from_rules_main{$_} && ( $from_rules_main{$_} ne $rule ) ) {
- warn "$My_name: Possible bug:\n",
- " In linking rules, I already set from_rules_main{$_}\n".
- " to '$from_rules_main{$_}'\n",
- " But now I also have a different rule '$rule' that also made the file.\n";
- }
- elsif ( exists($possible_primaries{$old_rule}) && exists($possible_primaries{$rule}) ) {
- # This could be problematic. But we'll let it go,
- # because it is a common case for .aux and .log files
- # (etc), and these cases do not appear to mess up
- # anything (by experience).
- # Once we allow an active flag for rules and only
- # examine active rules, the only case of this that
- # will appear (in the absence of other problems) will
- # be where two primary rules are active, notably a
- # latex rule to make dvi and a pdflatex (or other
- # rule) to make pdf.
- }
- else {
- warn "$My_name: Possible bug:\n",
- " In linking rules I already set from_rules{$_} to '$old_rule'\n",
- " But now I want to set it to '$rule'\n";
-# traceback( "================================\nFrom one_from__rule_cache" );
- }
- }
- $from_rules{$_} = $rule;
- }
-} #END from_rule_cache
-
-#************************************************************
-
-sub set_trivial_aux_fdb {
- # 1. Write aux file EXACTLY as would be written if the tex file
- # had no cross references, etc. I.e., a minimal .aux file.
- # 2. Write a corresponding fdb file
- # 3. Provoke a run of *latex (actually of all primaries).
-
- local *aux_file;
- open( aux_file, '>', $aux_main )
- or die "Cannot write file '$aux_main'\n";
- print aux_file "\\relax \n";
- close(aux_file);
-
- foreach my $rule (keys %possible_primaries ) {
- rdb_ensure_file( $rule, $texfile_name );
- rdb_ensure_file( $rule, $aux_main );
- rdb_one_rule( $rule,
- sub{ $$Pout_of_date = 1; }
- );
- }
- &rdb_write( $fdb_name );
-} #END set_trivial_aux_fdb
-
-#************************************************************
-#### Particular actions
-#************************************************************
-#************************************************************
-
-sub do_cusdep {
- # Unconditional application of custom-dependency
- # except that rule is not applied if the source file source
- # does not exist, and an error is returned if the dest is not made.
- #
- # Assumes rule context for the custom-dependency, and that my first
- # argument is the name of the subroutine to apply
- my $func_name = $_[0];
- my $return = 0;
- if ( !-e $$Psource ) {
- # Source does not exist. Users of this rule will need to turn
- # it off when custom dependencies are reset
- if ( !$silent ) {
-## ??? Was commented out. 1 Sep. 2008 restored, for cusdep no-file-exists issue
- warn "$My_name: In trying to apply custom-dependency rule\n",
- " to make '$$Pdest' from '$$Psource'\n",
- " the source file has disappeared since the last run\n";
- }
- # Treat as successful
- }
- elsif ( !$func_name ) {
- warn "$My_name: Possible misconfiguration or bug:\n",
- " In trying to apply custom-dependency rule\n",
- " to make '$$Pdest' from '$$Psource'\n",
- " the function name is blank.\n";
- }
- elsif ( ! defined &$func_name ) {
- warn "$My_name: Misconfiguration or bug,",
- " in trying to apply custom-dependency rule\n",
- " to make '$$Pdest' from '$$Psource'\n",
- " function name '$func_name' does not exists.\n";
- }
- else {
- my $cusdep_ret = &$func_name( $$Pbase );
- if ( defined $cusdep_ret && ($cusdep_ret != 0) ) {
- $return = $cusdep_ret;
- if ($return) {
- warn "Rule '$rule', function '$func_name'\n",
- " failed with return code = $return\n";
- }
- }
- elsif ( !-e $$Pdest ) {
- # Destination non-existent, but routine failed to give an error
- warn "$My_name: In running custom-dependency rule\n",
- " to make '$$Pdest' from '$$Psource'\n",
- " function '$func_name' did not make the destination.\n";
- $return = -1;
- }
- }
- return $return;
-} # END do_cusdep
-
-#************************************************************
-
-sub do_viewfile {
- # Unconditionally make file for viewing, going through temporary file if
- # Assumes rule context
-
- my $return = 0;
- my ($base, $path, $ext) = fileparseA( $$Pdest );
- if ( &view_file_via_temporary ) {
- if ( $$Pext_cmd =~ /%D/ ) {
- my $tmpfile = tempfile1( "${root_filename}_tmp", $ext );
- warn "$My_name: Making '$$Pdest' via temporary '$tmpfile'...\n";
- $return = &Run_subst( undef, undef, undef, undef, $tmpfile );
- move( $tmpfile, $$Pdest );
- }
- else {
- warn "$My_name is configured to make '$$Pdest' via a temporary file\n",
- " but the command template '$$Pext_cmd' does not have a slot\n",
- " to set the destination file, so I won't use a temporary file\n";
- $return = &Run_subst();
- }
- }
- else {
- $return = &Run_subst();
- }
- return $return;
-} #END do_viewfile
-
-#************************************************************
-
-sub do_update_view {
- # Update viewer
- # Assumes rule context
- # Arguments: (method, signal, viewer_process)
-
- my $return = 0;
-
- # Although the process is passed as an argument, we'll need to update it.
- # So (FUDGE??) bypass the standard interface for the process.
- # We might as well do this for all the arguments.
- my $viewer_update_method = ${$PAint_cmd}[1];
- my $viewer_update_signal = ${$PAint_cmd}[2];
- my $Pviewer_process = \${$PAint_cmd}[3];
- my $Pneed_to_get_viewer_process = \${$PAint_cmd}[4];
-
- if ($viewer_update_method == 2) {
- if ($$Pneed_to_get_viewer_process) {
- $$Pviewer_process = &find_process_id( $$Psource );
- if ($$Pviewer_process != 0) {
- $$Pneed_to_get_viewer_process = 0;
- }
- }
- if ($$Pviewer_process == 0) {
- print "$My_name: need to signal viewer for file '$$Psource', but didn't get \n",
- " process ID for some reason, e.g., no viewer, bad configuration, bug\n"
- if $diagnostics ;
- }
- elsif ( defined $viewer_update_signal) {
- print "$My_name: signalling viewer, process ID $$Pviewer_process ",
- "with signal $viewer_update_signal\n"
- if $diagnostics ;
- kill $viewer_update_signal, $$Pviewer_process;
- }
- else {
- warn "$My_name: viewer is supposed to be sent a signal\n",
- " but no signal is defined. Misconfiguration or bug?\n";
- $return = 1;
- }
- }
- elsif ($viewer_update_method == 4) {
- if (defined $$Pext_cmd) {
- $return = &Run_subst();
- }
- else {
- warn "$My_name: viewer is supposed to be updated by running a command,\n",
- " but no command is defined. Misconfiguration or bug?\n";
- }
- }
- return $return;
-} #END do_update_view
-
-#************************************************************
-
-sub if_source {
- # Unconditionally apply rule if source file exists.
- # Assumes rule context
- if ( -e $$Psource ) {
- return &Run_subst();
- }
- else {
- warn "Needed source file '$$Psource' does not exist.\n";
- return -1;
- }
-} #END if_source
-
-#************************************************************
-#### Subroutines
-#************************************************************
-#************************************************************
-
-sub find_basename {
- # Finds the basename of the root file
- # Arguments:
- # 1 - Filename to breakdown
- # 2 - Where to place base file
- # 3 - Where to place tex file
- # Returns non-zero if tex file does not exist
-
- my $fail = 0;
- local ( $given_name, $base_name, $ext, $path, $tex_name, $source_name );
- $given_name = $_[0];
- $source_name = '';
- $tex_name = $given_name; # Default name if I don't find the tex file
- ($base_name, $path, $ext) = fileparseB( $given_name );
-
- # Treatment of extensions (in TeXLive 2019), with omission of path search:
- # Exists: always means exists as a file, i.e., not as a directory.
- # A. Finding of tex file:
- # 1. If extension is .tex and given_name.tex exists, use it.
- # 2. Else if given_name.tex exists, use it.
- # 3. Else if givne_name exists, use it.
- # B. The base filename is obtained by deleting the path
- # component and the extension.
- # C. The names of generated files (log, aux) are obtained by appending
- # .log, .aux, etc to the basename. Note that these are all in the
- # CURRENT directory (or the output or aux directory, as appropriate).
- # The drive/path part of the originally given filename is ignored.
-
- # Here we'll do:
- # 1. Find the tex file by the above method, if possible.
- # 2. If not, find a custom dependency with a source file that exists to
- # make the tex file so that after the tex file is made, the above
- # rules find the tex file.
- # 3. If that also fails, use kpsewhich on given_name to find the tex
- # file
- # 4. If that also fails, report non-existent tex file.
-
-
- if ( ($ext eq '.tex') && (-f $given_name) ) {
- $tex_name = "$given_name";
- }
- elsif ( -f "$given_name.tex" ) {
- $tex_name = "$given_name.tex";
- $base_name .= $ext;
- }
- elsif ( -f $given_name ) {
- $tex_name = $given_name;
- }
- elsif ( ($ext eq '.tex') && find_cus_dep( $given_name, $source_name ) ) {
- $tex_name = $given_name;
- }
- elsif ( find_cus_dep( "$given_name.tex", \$source_name ) ) {
- $tex_name = "$given_name.tex";
- $base_name .= $ext;
- }
- elsif ( ($ext =~ /^\..+/) && find_cus_dep( $given_name, $source_name ) ) {
- $tex_name = $given_name;
- }
- else {
- my @kpse_result = kpsewhich( $given_name );
- if ($#kpse_result < 0) {
- $fail = 1;
- }
- else {
- $tex_name = $kpse_result[0];
- ($base_name) = fileparseB( $tex_name );
- }
- }
-
- $_[1] = $base_name;
- $_[2] = $tex_name;
-
- if ($diagnostics) {
- print "Given='$given_name', tex='$tex_name', base='$base_name', ext= $ext, source='$source_name'\n";
- }
- return $fail;
-
-} #END find_basename
-
-#************************************************************
-
-sub make_preview_continuous {
- local @changed = ();
- local %changed_rules = ();
- local @changed_user = ();
- local @disappeared = ();
- local @no_dest = (); # Non-existent destination files
- local @rules_never_run = ();
- local @rules_to_apply = ();
-
- local $failure = 0;
- local %rules_applied = ();
- local $updated = 0;
-
- print "======= Need to update make_preview_continuous for target files\n";
-
- $quell_uptodate_msgs = 1;
-
- if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
- warn "Viewing $view\n";
- }
- elsif ( $view eq 'none' ) {
- warn "Not using a previewer\n";
- $view_file = '';
- }
- else {
- warn "$My_name: BUG: Invalid preview method '$view'\n";
- exit 20;
- }
-
- my $viewer_running = 0; # No viewer known to be running yet
- # Get information from update_view rule
- local $viewer_update_method = 0;
- # Pointers so we can update the following:
- local $Pviewer_process = undef;
- local $Pneed_to_get_viewer_process = undef;
- rdb_one_rule( 'update_view',
- sub{ $viewer_update_method = $$PAint_cmd[1];
- $Pviewer_process = \$$PAint_cmd[3];
- $Pneed_to_get_viewer_process = \$$PAint_cmd[4];
- }
- );
- # Note that we don't get the previewer process number from the program
- # that starts it; that might only be a script to get things set up and the
- # actual previewer could be (and sometimes IS) another process.
-
- if ( ($view_file ne '') && (-e $view_file) && !$new_viewer_always ) {
- # Is a viewer already running?
- # (We'll save starting up another viewer.)
- $$Pviewer_process = &find_process_id( $view_file );
- if ( $$Pviewer_process ) {
- warn "$My_name: Previewer is already running\n"
- if !$silent;
- $viewer_running = 1;
- $$Pneed_to_get_viewer_process = 0;
- }
- }
-
- # Loop forever, rebuilding .dvi and .ps as necessary.
- # Set $first_time to flag first run (to save unnecessary diagnostics)
- my $last_action_time = time();
- my $timed_out = 0;
-CHANGE:
- for (my $first_time = 1; 1; $first_time = 0 ) {
-
- my %rules_to_watch = array_to_hash( &rdb_accessible );
-
- $updated = 0;
- $failure = 0;
- $failure_msg = '';
- if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
- # Fudge under MSWin32 ONLY, to stop perl/latexmk from
- # catching ctrl/C and ctrl/break, and let it only reach
- # downstream programs. See comments at first definition of
- # $MSWin_fudge_break.
- $SIG{BREAK} = $SIG{INT} = 'IGNORE';
- }
- if ($compiling_cmd) {
- Run_subst( $compiling_cmd );
- }
- $failure = &rdb_make;
-
- if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
- $SIG{BREAK} = $SIG{INT} = 'DEFAULT';
- }
- # Start viewer if needed.
- if ( ($failure > 0) && (! $force_mode) ) {
- # No viewer yet
- }
- elsif ( ($view_file ne '') && (-e $view_file) && $updated && $viewer_running ) {
- # A viewer is running. Explicitly get it to update screen if we have to do it:
- rdb_one_rule( 'update_view', \&rdb_run1 );
- }
- elsif ( ($view_file ne '') && (-e $view_file) && !$viewer_running ) {
- # Start the viewer
- if ( !$silent ) {
- if ($new_viewer_always) {
- warn "$My_name: starting previewer for '$view_file'\n",
- "------------\n";
- }
- else {
- warn "$My_name: I have not found a previewer that ",
- "is already running. \n",
- " So I will start it for '$view_file'\n",
- "------------\n";
- }
- }
- local $retcode = 0;
- rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} );
- if ( $retcode != 0 ) {
- if ($force_mode) {
- warn "$My_name: I could not run previewer\n";
- }
- else {
- &exit_msg1( "I could not run previewer", $retcode);
- }
- }
- else {
- $viewer_running = 1;
- $$Pneed_to_get_viewer_process = 1;
- } # end analyze result of trying to run viewer
- } # end start viewer
- if ( $failure > 0 ) {
- if ( !$failure_msg ) {
- $failure_msg = 'Failure to make the files correctly';
- }
- &rdb_set_rule_net;
- %rules_to_watch = array_to_hash( &rdb_accessible );
-
- # There will be files changed during the run that are irrelevant.
- # We need to wait for the user to change the files.
-
- # So set the GENERATED files from *latex as up-to-date:
- rdb_for_some( [keys %current_primaries], \&rdb_update_gen_files );
-
- # And don't watch for changes for post_primary rules (ps and pdf
- # from dvi, etc haven't been run after an error in *latex, so
- # are out-of-date by filetime criterion, but they should not be run
- # until after another *latex run:
- foreach (@post_primary) { delete $rules_to_watch{$_}; }
-
- $failure_msg =~ s/\s*$//; #Remove trailing space
- warn "$My_name: $failure_msg\n",
- " ==> You will need to change a source file before I do another run <==\n";
- if ($failure_cmd) {
- Run_subst( $failure_cmd );
- }
- }
- else {
- if ( ($#primary_warning_summary > -1) && $warning_cmd ) {
- Run_subst( $warning_cmd );
- }
- elsif ( ($#primary_warning_summary > -1) && $warnings_as_errors && $failure_cmd ) {
- Run_subst( $failure_cmd );
- }
- elsif ($success_cmd) {
- Run_subst( $success_cmd );
- }
- }
- rdb_show_rule_errors();
- if ($rules_list) { rdb_list(); }
- if ($show_time && ! $first_time) { show_timing(); }
- if ( $dependents_list && ($updated || $failure) ) {
- my $deps_handle = new FileHandle "> $deps_file";
- if ( defined $deps_handle ) {
- deps_list($deps_handle);
- close($deps_handle);
- }
- else {
- warn "Cannot open '$deps_file' for output of dependency information\n";
- }
- }
-
- # Now wait for a file to change...
- &rdb_cache_generated;
- # During waiting for file changes, handle ctrl/C and ctrl/break here,
- # rather than letting system handle them by terminating script (and
- # code in the following command line to work: any script that calls
- # it). This allows, for example, the command cleanup in the following
- # command line to work:
- # latexmk -pvc foo; cleanup;
- &catch_break;
- $have_break = 0;
- $last_action_time = time();
- $waiting = 1;
- print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
- WAIT: while (1) {
- sleep( $sleep_time );
- if ($have_break) { last WAIT; }
- if ( rdb_user_changes(keys %rules_to_watch) ) {
- if (!$silent) {
- warn "$My_name: Need to remake files.\n";
- &rdb_diagnose_changes( ' ' );
- }
- last WAIT;
- }
- # Don't count waiting time in processing:
- $processing_time1 = processing_time();
- # Does this do this job????
- local $new_files = 0;
- rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_files } );
- if ($new_files > 0) {
- warn "$My_name: New file(s) found.\n";
- last WAIT;
- }
- if ($have_break) { last WAIT; }
- if ($pvc_timeout && ( time() > $last_action_time+60*$pvc_timeout_mins ) ) {
- $timed_out = 1;
- last WAIT;
- }
- } # end WAIT:
- &default_break;
- if ($have_break) {
- print "$My_name: User typed ctrl/C or ctrl/break. I'll finish.\n";
- return;
- }
- if ($timed_out) {
- print "$My_name: More than $pvc_timeout_mins mins of inactivity. I'll finish.\n";
- return;
- }
- $waiting = 0; if ($diagnostics) { warn "NOT WAITING\n"; }
- } #end infinite_loop CHANGE:
-} #END sub make_preview_continuous
-
-#************************************************************
-
-sub process_rc_file {
- # Usage process_rc_file( filename )
- # NEW VERSION
- # Run rc_file whose name is given in first argument
- # Exit with code 0 on success
- # Exit with code 1 if file cannot be read or does not exist.
- # Stop if there is a syntax error or other problem.
- # PREVIOUSLY:
- # Exit with code 2 if is a syntax error or other problem.
- my $rc_file = $_[0];
- my $ret_code = 0;
- push @rc_files_read, $rc_file;
-
- # I could use the do command of perl, but the preceeding -r test
- # to get good diagnostics gets the wrong result under cygwin
- # (e.g., on /cygdrive/c/latexmk/LatexMk)
- my $RCH = new FileHandle;
- if ( !-e $rc_file ) {
- warn "$My_name: The rc-file '$rc_file' does not exist\n";
- return 1;
- }
- elsif ( -d $rc_file ) {
- warn "$My_name: The supposed rc-file '$rc_file' is a directory; but it\n",
- " should be a normal text file\n";
- return 1;
- }
- elsif ( open $RCH, "<$rc_file" ) {
- { local $/; eval <$RCH>; }
- close $RCH;
- }
- else {
- warn "$My_name: I cannot read the rc-file '$rc_file'\n";
- return 1;
- }
- # PREVIOUS VERSION
-# if ( ! -r $rc_file ) {
-# warn "$My_name: I cannot read the rc-file '$rc_file'\n",
-# " or at least that's what Perl (for $^O) reports\n";
-# return 1;
-# }
-# do( $rc_file );
- if ( $@ ) {
- # Indent each line of possibly multiline message:
- my $message = prefix( $@, " " );
- warn "$My_name: Initialization file '$rc_file' gave an error:\n",
- "$message\n";
- die "$My_name: Stopping because of problem with rc file\n";
- # Use the following if want non-fatal error.
- return 2;
- }
- return 0;
-} #END process_rc_file
-
-#************************************************************
-
-sub execute_code_string {
- # Usage execute_code_string( string_of_code )
- # Run the perl code contained in first argument
- # Halt if there is a syntax error or other problem.
- # ???Should I leave the exiting to the caller (perhaps as an option)?
- # But I can always catch it with an eval if necessary.
- # That confuses ctrl/C and ctrl/break handling.
- my $code = $_[0];
- warn "$My_name: Executing initialization code specified by -e:\n",
- " '$code'...\n"
- if $diagnostics;
- eval $code;
- # The return value from the eval is not useful, since it is the value of
- # the last expression evaluated, which could be anything.
- # The correct test of errors is on the value of $@.
-
- if ( $@ ) {
- # Indent each line of possibly multiline message:
- my $message = prefix( $@, " " );
- die "$My_name: ",
- "Stopping because executing following code from command line\n",
- " $code\n",
- "gave an error:\n",
- "$message\n";
- }
-} #END execute_code_string
-
-#************************************************************
-
-sub cleanup1 {
- # Usage: cleanup1( directory, exts_without_period, ... )
- #
- # The directory and the root file name are fixed names, so I must escape
- # any glob metacharacters in them:
- my $dir = fix_pattern( shift );
- my $root_fixed = fix_pattern( $root_filename );
- foreach (@_) {
- my $name = /%R/ ? $_ : "%R.$_";
- $name =~ s/%R/${root_fixed}/;
- $name = $dir.$name;
- unlink_or_move( my_glob( "$name" ) );
- }
-} #END cleanup1
-
-#************************************************************
-
-sub cleanup_cusdep_generated {
- # Remove files generated by custom dependencies
- rdb_for_actives( \&cleanup_one_cusdep_generated );
-} #END cleanup_cusdep_generated
-
-#************************************************************
-
-sub cleanup_one_cusdep_generated {
- # Remove destination file generated by one custom dependency
- # Assume rule context, but not that the rule is a custom dependency.
- # Only delete destination file if source file exists (so destination
- # file can be recreated)
- if ( $$Pcmd_type ne 'cusdep' ) {
- # NOT cusdep
- return;
- }
- if ( ! -e $$Psource ) {
- warn "$My_name: For custom dependency '$rule',\n",
- " I won't delete destination file '$$Pdest'\n",
- " and any other generated files,\n",
- " because the source file '$$Psource' doesn't exist,\n",
- " so the destination file may not be able to be recreated\n";
- return;
- }
- unlink_or_move( $$Pdest, keys %$PHdest );
-} #END cleanup_one_cusdep_generated
-
-#************************************************************
-#************************************************************
-#************************************************************
-
-# Error handling routines, warning routines, help
-
-#************************************************************
-
-sub die_trace {
- # Call: die_trace( message );
- &traceback; # argument(s) passed unchanged
- die "\n";
-} #END die_trace
-
-#************************************************************
-
-sub traceback {
- # Call: traceback()
- # or traceback( message )
- # NOT &traceback!!!
- my $msg = shift;
- if ($msg) { warn "$msg\n"; }
- warn "Traceback:\n";
- my $i=0; # Start with immediate caller
- while ( my ($pack, $file, $line, $func) = caller($i++) ) {
- if ($func eq 'die_trace') { next; }
- warn " $func called from line $line\n";
- }
-} #END traceback
-
-#************************************************************
-
-sub exit_msg1
-{
- # exit_msg1( error_message, retcode )
- # 1. display error message
- # 2. exit with retcode
- warn "\n------------\n";
- warn "$My_name: $_[0].\n";
- warn "-- Use the -f option to force complete processing.\n";
-
- my $retcode = $_[1];
- if ($retcode >= 256) {
- # Retcode is the kind returned by system from an external command
- # which is 256 * command's_retcode
- $retcode /= 256;
- }
- exit $retcode;
-} #END exit_msg1
-
-#************************************************************
-
-sub warn_running {
- # Message about running program:
- if ( $silent ) {
- warn "$My_name: @_\n";
- }
- else {
- warn "------------\n@_\n------------\n";
- }
-} #END warn_running
-
-#************************************************************
-
-sub exit_help
-# Exit giving diagnostic from arguments and how to get help.
-{
- warn "\n$My_name: @_\n",
- "Use\n",
- " $my_name -help\nto get usage information\n";
- exit 10;
-} #END exit_help
-
-
-#************************************************************
-
-sub print_help
-{
- print
- "$My_name $version_num: Automatic LaTeX document generation routine\n\n",
- "Usage: $my_name [latexmk_options] [filename ...]\n\n",
- " Latexmk_options:\n",
- " -aux-directory=dir or -auxdir=dir \n",
- " - set name of directory for auxiliary files (aux, log)\n",
- " - Currently this only works with MiKTeX\n",
- " -bibtex - use bibtex when needed (default)\n",
- " -bibtex- - never use bibtex\n",
- " -bibtex-cond - use bibtex when needed, but only if the bib file exists\n",
- " -bibtex-cond1 - use bibtex when needed, but only if the bib file exists;\n",
- " on cleanup delete bbl file only if bib file exists\n",
- " -bibfudge - use change-directory fudge needed for old bibtexs\n",
- " -bibfudge- - don't use change-directory fudge needed for old bibtexs\n",
- " -bm <message> - Print message across the page when converting to postscript\n",
- " -bi <intensity> - Set contrast or intensity of banner\n",
- " -bs <scale> - Set scale for banner\n",
- " -commands - list commands used by $my_name for processing files\n",
- " -c - clean up (remove) all nonessential files, except\n",
- " dvi, ps and pdf files.\n",
- " This and the other clean-ups are instead of a regular make.\n",
- " -C - clean up (remove) all nonessential files\n",
- " including aux, dep, dvi, postscript and pdf files\n",
- " and file of database of file information\n",
- " -CA - clean up (remove) all nonessential files.\n",
- " Equivalent to -C option.\n",
- " -CF - Remove file of database of file information before doing \n",
- " other actions\n",
- " -cd - Change to directory of source file when processing it\n",
- " -cd- - Do NOT change to directory of source file when processing it\n",
- " -dependents or -deps - Show list of dependent files after processing\n",
- " -dependents- or -deps- - Do not show list of dependent files\n",
- " -deps-out=file - Set name of output file for dependency list,\n",
- " and turn on showing of dependency list\n",
- " -dF <filter> - Filter to apply to dvi file\n",
- " -dvi - generate dvi\n",
- " -dvi- - turn off required dvi\n",
- " -e <code> - Execute specified Perl code (as part of latexmk start-up\n",
- " code)\n",
- " -f - force continued processing past errors\n",
- " -f- - turn off forced continuing processing past errors\n",
- " -gg - Super go mode: clean out generated files (-CA), and then\n",
- " process files regardless of file timestamps\n",
- " -g - process regardless of file timestamps\n",
- " -g- - Turn off -g\n",
- " -h - print help\n",
- " -help - print help\n",
- " -jobname=STRING - set basename of output file(s) to STRING.\n",
- " (Like --jobname=STRING on command line for many current\n",
- " implementations of latex/pdflatex.)\n",
- " -l - force landscape mode\n",
- " -l- - turn off -l\n",
- " -latex=<program> - set program used for latex.\n",
- " (replace '<program>' by the program name)\n",
- " -latexoption=<option> - add the given option to the *latex command\n",
- " -logfilewarninglist or -logfilewarnings \n",
- " give list of warnings after run of *latex\n",
- " -logfilewarninglist- or -logfilewarnings- \n",
- " do not give list of warnings after run of *latex\n",
- " -lualatex - use lualatex for processing files to pdf\n",
- " and turn dvi/ps modes off\n",
- " -M - Show list of dependent files after processing\n",
- " -MF file - Specifies name of file to receives list dependent files\n",
- " -MP - List of dependent files includes phony target for each source file.\n",
- " -MSWinBackSlash under MSWin use backslash (\\) for directory separators\n",
- " for filenames given to called programs\n",
- " -MSWinBackSlash- under MSWin use forward slash (/) for directory separators\n",
- " for filenames given to called programs\n",
- " -new-viewer - in -pvc mode, always start a new viewer\n",
- " -new-viewer- - in -pvc mode, start a new viewer only if needed\n",
- " -nobibtex - never use bibtex\n",
- " -nobibfudge - don't use change-directory fudge needed for old bibtexs\n",
- " -nodependents - Do not show list of dependent files after processing\n",
- " -norc - omit automatic reading of system, user and project rc files\n",
- " -output-directory=dir or -outdir=dir\n",
- " - set name of directory for output files\n",
- " -pdf - generate pdf by pdflatex\n",
- " -pdfdvi - generate pdf by dvipdf\n",
- " -pdflatex=<program> - set program used for pdflatex.\n",
- " (replace '<program>' by the program name)\n",
- " -pdflualatex=<program> - set program used for lualatex.\n",
- " (replace '<program>' by the program name)\n",
- " -pdfps - generate pdf by ps2pdf\n",
- " -pdflua - generate pdf by lualatex\n",
- " -pdfxe - generate pdf by xelatex\n",
- " -pdfxelatex=<program> - set program used for xelatex.\n",
- " (replace '<program>' by the program name)\n",
- " -pdf- - turn off pdf\n",
- " -ps - generate postscript\n",
- " -ps- - turn off postscript\n",
- " -pF <filter> - Filter to apply to postscript file\n",
- " -p - print document after generating postscript.\n",
- " (Can also .dvi or .pdf files -- see documentation)\n",
- " -pretex=<TeX code> - Sets TeX code to be executed before inputting source\n",
- " file, if commands suitable configured\n",
- " -print=dvi - when file is to be printed, print the dvi file\n",
- " -print=ps - when file is to be printed, print the ps file (default)\n",
- " -print=pdf - when file is to be printed, print the pdf file\n",
- " -pv - preview document. (Side effect turn off continuous preview)\n",
- " -pv- - turn off preview mode\n",
- " -pvc - preview document and continuously update. (This also turns\n",
- " on force mode, so errors do not cause $my_name to stop.)\n",
- " (Side effect: turn off ordinary preview mode.)\n",
- " -pvc- - turn off -pvc\n",
- " -pvctimeout - timeout in pvc mode after period of inactivity\n",
- " -pvctimeout- - don't timeout in pvc mode after inactivity\n",
- " -pvctimeoutmins=<time> - set period of inactivity (minutes) for pvc timeout\n",
- " -quiet - silence progress messages from called programs\n",
- " -r <file> - Read custom RC file\n",
- " (N.B. This file could override options specified earlier\n",
- " on the command line.)\n",
- " -recorder - Use -recorder option for *latex\n",
- " (to give list of input and output files)\n",
- " -recorder- - Do not use -recorder option for *latex\n",
- " -rules - Show list of rules after processing\n",
- " -rules- - Do not show list of rules after processing\n",
- " -showextraoptions - Show other allowed options that are simply passed\n",
- " as is to latex and pdflatex\n",
- " -silent - silence progress messages from called programs\n",
- " -stdtexcmds - Sets standard commands for *latex\n",
- " -time - show CPU time used\n",
- " -time- - don't show CPU time used\n",
- " -use-make - use the make program to try to make missing files\n",
- " -use-make- - don't use the make program to try to make missing files\n",
- " -usepretex - Sets commands for *latex to use extra code before inputting\n",
- " source file\n",
- " -usepretex=<TeX code> - Equivalent to -pretex=<TeX code> -usepretex\n",
- " -v - display program version\n",
- " -verbose - display usual progress messages from called programs\n",
- " -version - display program version\n",
- " -view=default - viewer is default (dvi, ps, pdf)\n",
- " -view=dvi - viewer is for dvi\n",
- " -view=none - no viewer is used\n",
- " -view=ps - viewer is for ps\n",
- " -view=pdf - viewer is for pdf\n",
- " -Werror - treat warnings from called programs as errors\n",
- " -xelatex - use xelatex for processing files to pdf\n",
- " and turn dvi/ps modes off\n",
- "\n",
- " filename = the root filename of LaTeX document\n",
- "\n",
- "-p, -pv and -pvc are mutually exclusive\n",
- "-h, -c and -C override all other options.\n",
- "-pv and -pvc require one and only one filename specified\n",
- "All options can be introduced by '-' or '--'. (E.g., --help or -help.)\n",
- " \n",
- "In addition, latexmk recognizes many other options that are passed to\n",
- "latex and/or pdflatex without interpretation by latexmk. Run latexmk\n",
- "with the option -showextraoptions to see a list of these\n",
- "\n",
- "Report bugs etc to John Collins <jcc8 at psu.edu>.\n";
-
-} #END print_help
-
-#************************************************************
-
-sub print_commands {
- warn "Commands used by $my_name:\n",
- " To run latex, I use \"$latex\"\n",
- " To run pdflatex, I use \"$pdflatex\"\n",
- " To run lualatex, I use \"$lualatex\"\n",
- " To run xelatex, I use \"$xelatex\"\n",
- " To run biber, I use \"$biber\"\n",
- " To run bibtex, I use \"$bibtex\"\n",
- " To run makeindex, I use \"$makeindex\"\n",
- " To make a ps file from a dvi file, I use \"$dvips\"\n",
- " To make a ps file from a dvi file with landscape format, ",
- "I use \"$dvips_landscape\"\n",
- " To make a pdf file from a dvi file, I use \"$dvipdf\"\n",
- " To make a pdf file from a ps file, I use \"$ps2pdf\"\n",
- " To make a pdf file from an xdv file, I use \"$xdvipdfmx\"\n",
- " To view a pdf file, I use \"$pdf_previewer\"\n",
- " To view a ps file, I use \"$ps_previewer\"\n",
- " To view a ps file in landscape format, ",
- "I use \"$ps_previewer_landscape\"\n",
- " To view a dvi file, I use \"$dvi_previewer\"\n",
- " To view a dvi file in landscape format, ",
- "I use \"$dvi_previewer_landscape\"\n",
- " To print a ps file, I use \"$lpr\"\n",
- " To print a dvi file, I use \"$lpr_dvi\"\n",
- " To print a pdf file, I use \"$lpr_pdf\"\n",
- " To find running processes, I use \"$pscmd\", \n",
- " and the process number is at position $pid_position\n";
- warn "Notes:\n",
- " Command starting with \"start\" is run detached\n",
- " Command that is just \"start\" without any other command, is\n",
- " used under MS-Windows to run the command the operating system\n",
- " has associated with the relevant file.\n",
- " Command starting with \"NONE\" is not used at all\n";
-} #END print_commands
-
-#************************************************************
-
-sub view_file_via_temporary {
- return $always_view_file_via_temporary
- || ($pvc_view_file_via_temporary && $preview_continuous_mode);
-} #END view_file_via_temporary
-
-#************************************************************
-#### Tex-related utilities
-
-#**************************************************
-
-sub check_biber_log {
- # Check for biber warnings:
- # Usage: check_biber_log( base_of_biber_run, \@biber_source )
- # return 0: OK;
- # 1: biber warnings;
- # 2: biber errors;
- # 3: could not open .blg file;
- # 4: failed to find one or more source files, except for bibfile;
- # 5: failed to find bib file;
- # 6: missing file, one of which is control file
- # 10: only error is missing \citation commands.
- # 11: Malformed bcf file (normally due to error in pdflatex run)
- # Side effect: add source files @biber_source
- my $base = $_[0];
- my $Pbiber_source = $_[1];
- my $blg_name = "$base.blg";
- my $blg_file = new FileHandle;
- open( $blg_file, "<$blg_name" )
- or return 3;
- my $have_warning = 0;
- my $have_error = 0;
- my $missing_citations = 0;
- my $no_citations = 0;
- my $error_count = 0; # From my counting of error messages
- my $warning_count = 0; # From my counting of warning messages
- # The next two occur only from biber
- my $bibers_error_count = 0; # From biber's counting of errors
- my $bibers_warning_count = 0; # From biber's counting of warnings
- my $not_found_count = 0;
- my $control_file_missing = 0;
- my $control_file_malformed = 0;
- my %remote = (); # List of extensions of remote files
- while (<$blg_file>) {
- if (/> WARN /) {
- print "Biber warning: $_";
- $have_warning = 1;
- $warning_count ++;
- }
- elsif (/> (FATAL|ERROR) /) {
- print "Biber error: $_";
- if ( /> (FATAL|ERROR) - Cannot find file '([^']+)'/ #'
- || /> (FATAL|ERROR) - Cannot find '([^']+)'/ ) { #'
- $not_found_count++;
- push @$Pbiber_source, $2;
- }
- elsif ( /> (FATAL|ERROR) - Cannot find control file '([^']+)'/ ) { #'
- $not_found_count++;
- $control_file_missing = 1;
- push @$Pbiber_source, $2;
- }
- elsif ( /> ERROR - .*\.bcf is malformed/ ) {
- # Special treatment: Malformed .bcf file commonly results from error
- # in *latex run. This error must be ignored.
- $control_file_malformed = 1;
- }
- else {
- $have_error = 1;
- $error_count ++;
- if ( /> (FATAL|ERROR) - The file '[^']+' does not contain any citations!/ ) { #'
- $no_citations++;
- }
- }
- }
- elsif ( /> INFO - Data source '([^']*)' is a remote BibTeX data source - fetching/
- ){
- my $spec = $1;
- my ( $base, $path, $ext ) = fileparseA( $spec );
- $remote{$ext} = 1;
- }
- elsif ( /> INFO - Found .* '([^']+)'\s*$/
- || /> INFO - Found '([^']+)'\s*$/
- || /> INFO - Reading '([^']+)'\s*$/
- || /> INFO - Processing .* file '([^']+)' .*$/
- ) {
- my $file = $1;
- my ( $base, $path, $ext ) = fileparseA( $file );
- if ($remote{$ext} && ( $base =~ /^biber_remote_data_source/ ) && 1) {
- # Ignore the file, which appears to be a temporary local copy
- # of a remote file. Treating the file as a source file will
- # be misleading, since it will normally have been deleted by
- # biber itself.
- }
- elsif ( (defined $Pbiber_source) && (-e $file) ) {
- # Note that biber log file gives full path to file. (No search is
- # needed to find it.) The file must have existed when biber was
- # run. If it doesn't exist now, a few moments later, it must
- # have gotten deleted, probably by biber (e.g., because it is a
- # copy of a remote file).
- # So I have included a condition above that the file must
- # exist to be included in the source-file list.
- push @$Pbiber_source, $file;
- }
- }
- elsif ( /> INFO - WARNINGS: ([\d]+)\s*$/ ) {
- $bibers_warning_count = $1;
- }
- elsif ( /> INFO - ERRORS: ([\d]+)\s*$/ ) {
- $bibers_error_count = $1;
- }
- }
- close $blg_file;
- if ($control_file_malformed){return 11;}
-
- my @not_found = &find_file_list1( $Pbiber_source, $Pbiber_source,
- '', \@BIBINPUTS );
- @$Pbiber_source = uniqs( @$Pbiber_source );
-
- if ( ($#not_found < 0) && ($#$Pbiber_source >= 0) ) {
- warn "$My_name: Found biber source file(s) [@$Pbiber_source]\n"
- unless $silent;
- }
- elsif ( ($#not_found == 0) && ($not_found[0] =~ /\.bib$/) ) {
- # Special treatment if sole missing file is bib file
- # I don't want to treat that as an error
- warn "$My_name: Biber did't find bib file [$not_found[0]]\n";
- return 5;
- }
- else {
- warn "$My_name: Failed to find one or more biber source files:\n";
- foreach (@not_found) { warn " '$_'\n"; }
- if ($force_mode) {
- warn "==== Force_mode is on, so I will continue. ",
- "But there may be problems ===\n";
- }
- if ($control_file_missing) {
- return 6;
- }
- return 4;
- }
-# print "$My_name: #Biber errors = $error_count, warning messages = $warning_count,\n ",
-# "missing citation messages = $missing_citations, no_citations = $no_citations\n";
- if ( ! $have_error && $no_citations ) {
- # If the only errors are missing citations, or lack of citations, that should
- # count as a warning.
- # HOWEVER: biber doesn't generate a new bbl. So it is an error condition.
- return 10;
- }
- if ($have_error) {return 2;}
- if ($have_warning) {return 1;}
- return 0;
-} #END check_biber_log
-
-#**************************************************
-
-sub run_bibtex {
- my $return = 999;
- # Prevent changes we make to environment becoming global:
- local %ENV = %ENV;
- my ( $base, $path, $ext ) = fileparseA( $$Psource );
- if ( $path && $bibtex_fudge ) {
- # Up to TeXLive 2018, the following was true; situation has changed since.
- # When an output directory is specified and with a bibtex from 2018 or
- # earlier, running 'bibtex output/main.aux' doesn't find subsidiary .aux
- # files, as from \@include{chap.aux}. To evade the bug, we change
- # directory to the directory of the top-level .aux file to run bibtex.
- # But we have to fix search paths for .bib and .bst, since they may be
- # specified relative to the document directory.
- my $cwd = good_cwd();
- foreach ( 'BIBINPUTS', 'BSTINPUTS' ) {
- if ( exists $ENV{$_} ) {
- $ENV{$_} = $cwd.$search_path_separator.$ENV{$_};
- }
- else {
- $ENV{$_} = $cwd.$search_path_separator;
- }
- }
- pushd( $path );
- if (!$silent) {
- print "$My_name: ==========WARNING:=================\n",
- "I am taking action to evade a bug/feature in older versions of bibtex\n",
- "This may give problems under some situations, symptomized by bibtex not\n",
- "finding a .bib file or an aux file.\n",
- "Provided you have a recent version of bibtex (about 2019 or later) you\n",
- "can avoid the problems by putting '\$bibtex_fudge = 0;' in an\n",
- "initialization file (a latexmrc file for $my_name.\n",
- "\n",
- "Here my bug-evading action:\n",
- "I temporarily changed directory to '$path'\n",
- "Set BIBINPUTS='$ENV{BIBINPUTS}'\n",
- "Set BSTINPUTS='$ENV{BSTINPUTS}'\n";
- }
- $return = &Run_subst( undef, undef, '', $base.$ext, '', $base );
- popd();
- if (!$silent) {
- print "$My_name: changed directory back to '", cwd(), "'\n";
- }
- }
- else {
- $return = Run_subst();
- }
- return $return;
-}
-
-
-#**************************************************
-
-sub check_bibtex_log {
- # Check for bibtex warnings:
- # Usage: check_bibtex_log( base_of_bibtex_run )
- # return 0: OK, 1: bibtex warnings, 2: bibtex errors,
- # 3: could not open .blg file.
- # 10: only error is missing \citation commands or a missing aux file
- # (which would normally be corrected after a later run of
- # *latex).
-
- my $base = $_[0];
- my $blg_name = "$base.blg";
- my $blg_file = new FileHandle;
- open( $blg_file, "<$blg_name" )
- or return 3;
- my $have_warning = 0;
- my $have_error = 0;
- my $missing_citations = 0;
- my @missing_aux = ();
- my $error_count = 0;
- while (<$blg_file>) {
- if (/^Warning--/) {
- #print "Bibtex warning: $_";
- $have_warning = 1;
- }
- elsif ( /^I couldn\'t open auxiliary file (.*\.aux)/ ) {
- push @missing_aux, $1;
- }
- elsif ( /^I found no \\citation commands---while reading file/ ) {
- $missing_citations++;
- }
- elsif (/There (were|was) (\d+) error message/) {
- $error_count = $2;
- #print "Bibtex error: count=$error_count $_";
- $have_error = 1;
- }
- }
- close $blg_file;
- my $missing = $missing_citations + $#missing_aux + 1;
-
- if ( $#missing_aux > -1 ) {
- # Need to make the missing files.
- warn "$My_name: One or more aux files is missing for bibtex. I'll try\n",
- " to get *latex to remake them.\n";
- rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
- }
- #print "Bibtex errors = $error_count, missing aux files and citations = $missing\n";
- if ($have_error && ($error_count <= $missing )
- && ($missing > 0) ) {
- # If the only error is a missing citation line, that should only
- # count as a warning.
- # Also a missing aux file should be innocuous; it will be created on
- # next run of *latex. ?? HAVE I HANDLED THAT CORRECTLY?
- # But have to deal with the problem that bibtex gives a non-zero
- # exit code. So leave things as they are so that the user gets
- # a better diagnostic ??????????????????????????
-# $have_error = 0;
-# $have_warning = 1;
- return 10;
- }
- if ($have_error) {return 2;}
- if ($have_warning) {return 1;}
- return 0;
-} #END check_bibtex_log
-
-#**************************************************
-
-sub normalize_force_directory {
- # Usage, normalize_force_directory( dir, filename )
- # Perform the following operations:
- # Clean filename
- # If filename contains no path component, insert dir in front
- # Normalize filename
- # Return result
- my $default_dir = $_[0];
- my $filename = clean_filename( $_[1] );
- my ($base_name, $path ) = fileparse( $filename );
- if ( $base_name eq $filename ) {
- $filename = "$default_dir$filename";
- }
- return normalize_filename( $filename );
-} #END normalize force_directory
-
-#**************************************************
-
-sub set_names {
- # Set names of standard files. These are global variables.
-
- ## Remove extension from filename if was given.
- if ( find_basename($filename, $root_filename, $texfile_name) ) {
- if ( $force_mode ) {
- warn "$My_name: Could not find file '$texfile_name'\n";
- }
- else {
- &ifcd_popd;
- &exit_msg1( "Could not find file '$texfile_name'",
- 11);
- }
- }
- $tex_basename = $root_filename; # Base name of TeX file itself
- if ($jobname ne '' ) {
- $root_filename = $jobname;
- $root_filename =~ s/%A/$tex_basename/g;
- }
-
- $aux_main = "%Y%R.aux";
- $log_name = "%Y%R.log";
- $fdb_name = "%Y%R.$fdb_ext";
- # Note: Only MiKTeX allows out_dir ne aux_dir. It puts
- # .fls file in out_dir, not aux_dir, which seems
- # not natural.
- $fls_name = "%Z%R.fls";
-
- $dvi_name = "%Z%R.dvi";
- $dviF_name = "%Z%R.dviF";
- $ps_name = "%Z%R.ps";
- $psF_name = "%Z%R.psF";
- $pdf_name = "%Z%R.pdf";
- ## It would be logical for a .xdv file to be put in the out_dir,
- ## just like a .dvi file. But the only program, MiKTeX, that
- ## currently implements aux_dir, and hence allows aux_dir ne out_dir,
- ## puts .xdv file in aux_dir. So we must use %Y not %Z:
- $xdv_name = "%Y%R.xdv";
-
- foreach ( $aux_main, $log_name, $fdb_name, $fls_name,
- $dvi_name, $ps_name, $pdf_name, $xdv_name, $dviF_name, $psF_name ) {
- s/%R/$root_filename/g;
- s/%Y/$aux_dir1/;
- s/%Z/$out_dir1/;
- }
-
- $dvi_final = $dvi_name;
- $ps_final = $ps_name;
- $pdf_final = $pdf_name;
- $xdv_final = $xdv_name;
-
- if ( length($dvi_filter) > 0) {
- $dvi_final = $dviF_name;
- }
- if ( length($ps_filter) > 0) {
- $ps_final = $psF_name;
- }
-}
-
-#**************************************************
-
-sub parse_log {
-# Scan log file for: dependent files
-# reference_changed, bad_reference, bad_citation
-# Return value: 1 if success, 0 if no log file.
-# Put results in UPDATES of global variables (which are normally declared
-# local in calling routine, to be suitably scoped):
-# %dependents: maps definite dependents to code:
-# 0 = from missing-file line
-# May have no extension
-# May be missing path
-# 1 = from 'File: ... Graphic file (type ...)' line
-# no path. Should exist, but may need a search, by kpsewhich.
-# 2 = from regular '(...' coding for input file,
-# Has NO path, which it would do if LaTeX file
-# Highly likely to be mis-parsed line
-# 3 = ditto, but has a path character ('/').
-# Should be LaTeX file that exists.
-# If it doesn't exist, we have probably a mis-parsed line.
-# There's no need to do a search.
-# 4 = definitive, which in this subroutine is only done:
-# for default dependents,
-# and for files that exist and are source of conversion
-# reported by epstopdf et al.
-# 5 = Had a missing file line. Now the file exists.
-# 6 = File was written during run. (Overrides 5)
-# 7 = File was created during run to be read in. (Overrides 5 and 6)
-# (e.g., by epstopdf)
-# Treat the following specially, since they have special rules
-# @bbl_files to list of .bbl files.
-# %idx_files to map from .idx files to .ind files.
-# %generated_log: keys give set of files written by *latex (e.g., aux, idx)
-# as determined by \openout = ... lines in log file.
-# @missing_subdirs = list of needed subdirectories of aux_dir
-# These are needed for writing aux_files when an included file is in
-# a subdirectory relative to the directory of the main TeX file.
-# This variable is only set when the needed subdirectories don't exist,
-# and the aux_dir is non-trivial, which results in an error message in
-# the log file
-# %conversions Internally made conversions from one file to another
-#
-# These may have earlier found information in them, so they should NOT
-# be initialized.
-#
-# Also SET
-# $reference_changed, $bad_reference, $bad_citation
-# $pwd_latex
-#
-# Put in trivial or default values if log file does not exist/cannot be opened
-#
-# Input globals: $primary_out, $fls_file_analyzed
-#
-
-
-# Give a quick way of looking up custom-dependency extensions
- my %cusdep_from = ();
- my %cusdep_to = ();
- foreach ( @cus_dep_list ) {
- my ($fromext, $toext) = split;
- $cusdep_from{$fromext} = $cusdep_from{".$fromext"} = $_;
- $cusdep_to{$toext} = $cusdep_to{".$toext"} = $_;
- }
-# print "==== Cusdep from-exts:"; foreach (keys %cusdep_from) {print " '$_'";} print "\n";
-# print "==== Cusdep to-exts:"; foreach (keys %cusdep_to) {print " '$_'";} print "\n";
-
-
- # Filenames given in log file may be preceded by a pathname
- # denoting current directory. In MiKTeX, this is an absolute
- # pathname; in TeXLive, it is './'. Either way, we'll want to
- # remove this pathname string --- see the comments in sub
- # rdb_set_latex_deps. In order of reliability for use in
- # normalizing filenames from the log file, the following forms
- # of the cwd are used:
- # (a) internally deduced pwd from log file from sequence of lines
- # **file
- # (dir/file
- # if possible. NO THAT'S WRONG if kpsearch is done.
- # (b) from PWD line in fls file (if available), passed as $pwd_latex
- # (c) system-given cwd as interpreted by sub good_cwd.
- # We'll put the first two in @pwd_log
- my @pwd_log = ();
- if ($pwd_latex) { push @pwd_log, $pwd_latex; }
-
- # $primary_out is actual output file (dvi or pdf)
- # It is initialized before the call to this routine, to ensure
- # a sensible default in case of misparsing
-
- $reference_changed = 0;
- $mult_defined = 0;
- $bad_reference = 0;
- $bad_character = 0;
- $bad_citation = 0;
-
- my $log_file = new FileHandle;
- if ( ! open( $log_file, "<$log_name" ) ) {
- return 0;
- }
- print "$My_name: Examining '$log_name'\n"
- if not $silent;
- if ($log_file_binary) { binmode $log_file; }
-# Collect lines of log file
- my @lines = ();
- my $line = 0;
- my $engine = 'pdfTeX'; # Simple default in case of problems
- while(<$log_file>) {
- $line++;
- # Could use chomp here, but that fails if there is a mismatch
- # between the end-of-line sequence used by latex and that
- # used by perl. (Notably a problem with MSWin latex and
- # cygwin perl!)
- s/[\n\r]*$//;
- # Handle wrapped lines:
- # They are lines brutally broken at exactly $log_wrap chars
- # excluding line-end. Sometimes a line $log_wrap chars
- # long is an ordinary line, sometimes it is part of a line
- # that was wrapped. To handle all cases, I keep both
- # options open by putting the line into @lines before
- # and after appending the next line:
- my $len = length($_);
- if ($line == 1) {
- if ( /^This is ([^,]+), / ) {
- $engine = $1;
- print "=== TeX engine is '$engine'\n"
- if (!$silent);
- if ( /^This is ([^,]+), [^\(]*\(([^\)]+)\)/ ) {
- $tex_distribution = $2;
- print "=== TeX distribution is '$tex_distribution'\n"
- if ($diagnostics);
- }
- }
- else {
- warn "$My_name: First line of .log file '$log_name' is not in standard format.\n";
- }
- }
- else {
- # Xetex and luatex sometimes wrap at longer line lengths:
- # LuaTeX sometimes at 80. Xetex 80 or longer with non-ascii characters.
- while ( ( ($len == $log_wrap)
- || ( ($engine eq 'LuaTeX') && ($len == $log_wrap+1) )
- || ( ($engine eq 'LuaHBTeX') && ($len == $log_wrap+1) )
- || ( ($engine eq 'XeTeX') && ($len >= $log_wrap+1) )
- )
- && !eof($log_file) ) {
- push @lines, $_;
- my $extra = <$log_file>;
- $extra =~ s/[\n\r]*$//;
- $len = length($extra);
- $_ .= $extra;
- }
- }
- push @lines, $_;
- }
- close $log_file;
-
- push @lines, ""; # Blank line to terminate. So multiline blocks
- # are always terminated by non-block line, rather than eof.
-
- $line = 0;
- my $state = 0; # 0 => before ** line,
- # 1 => after **filename line, before next line (first file-reading line)
- # 2 => pwd_log determined.
- # For parsing multiple line blocks of info
- my $current_pkg = ""; # non-empty string for package name, if in
- # middle of parsing multi-line block of form:
- # Package name ....
- # (name) ...
- # ...
- my $block_type = ""; # Specify information in such a block
- my $delegated_source = ""; # If it is a file conversion, specify source
- my $delegated_output = ""; # and output file. (Don't put in
- # data structure until block is ended.)
- my %new_conversions = ();
- my @retries = ();
- my $log_silent = ($silent || $silence_logfile_warnings);
- my @warning_list = ();
-LINE:
- while( ($line <= $#lines) || ($#retries > -1) ) {
- if ($#retries > -1) {
- $_ = pop @retries;
- }
- else {
- $_ = $lines[$line];
- $line ++;
- }
- if ( /^! pdfTeX warning/ || /^pdfTeX warning/ ) {
- # This kind of warning is produced by some versions of pdftex
- # or produced by my reparse of warnings from other
- # versions.
- next;
- }
- elsif ( /^(.+)(pdfTeX warning.*)$/ ) {
- # Line contains a pdfTeX warnings that may have been
- # inserted directly after other material without an
- # intervening new line. I think pdfTeX always inserts a
- # newline after the warning. (From examination of source
- # code.)
- push @retries, $1;
- # But continue parsing the original line, in case it was a
- # misparse, e.g., of a filename ending in 'pdfTeX';
- }
- if ( $line == 1 ){
- if ( /^This is / ) {
- # First line OK
- next LINE;
- } else {
- warn "$My_name: Error on first line of '$log_name'.\n".
- "This is apparently not a TeX log file. ",
- "The first line is:\n$_\n";
- $failure = 1;
- $failure_msg = "Log file '$log_name' appears to have wrong format.";
- return 0;
- }
- }
-
- if ( ($state == 0) && /^\*\*(.*)$/ ) {
- # Line containing first line specified to tex
- # It's either a filename or a command starting with \
- my $first = $1;
- $state = 1;
- if ( ! /^\\/ ) {
- $source_log = $first;
- if ( -e "$source_log.tex" ) { $source_log .= '.tex'; }
- }
- else {
- $state = 2;
- }
- next LINE;
- }
- elsif ( $state == 1 ) {
- $state = 2;
- if (-e $source_log) {
- # then the string preceeding $source_log on the line after the
- # ** line is probably the PWD as it appears in filenames in the
- # log file, except if the file appears in two locations.
- if ( m{^\("([^"]*)[/\\]\Q$source_log\E"} ) {
- unshift @pwd_log, $1;
- }
- elsif ( m{^\((.*)[/\\]\Q$source_log\E} ) {
- unshift @pwd_log, $1;
- }
- }
- }
-
- if ( $block_type ) {
- # In middle of parsing block
- if ( /^\($current_pkg\)/ ) {
- # Block continues
- if ( ($block_type eq 'conversion')
- && /^\($current_pkg\)\s+Output file: <([^>]+)>/ )
- {
- $delegated_output = normalize_clean_filename($1, @pwd_log);
- }
- next LINE;
- }
- # Block has ended.
- if ($block_type eq 'conversion') {
-#print "=== $delegated_source -> $delegated_output\n";
- $new_conversions{$delegated_source} = $delegated_output;
- }
- $current_pkg = $block_type
- = $delegated_source = $delegated_output = "";
- # Then process current line
- }
-
- # Check for changed references, bad references and bad citations:
- if (/Rerun to get/) {
- warn "$My_name: References changed.\n" if ! $log_silent;
- $reference_changed = 1;
- }
- if (/^LaTeX Warning: (Reference[^\001]*undefined on input line .*)\./) {
- push @warning_list, $1;
- $bad_reference++;
- }
- elsif (/^LaTeX Warning: (Label [^\001]* multiply defined.*)\./) {
- push @warning_list, $1;
- $mult_defined++;
- }
- elsif (/^LaTeX Warning: (Citation[^\001]*undefined on input line .*)\./) {
- push @warning_list, $1;
- $bad_citation++;
- }
- elsif (/^Package natbib Warning: (Citation[^\001]*undefined on input line .*)\./) {
- push @warning_list, $1;
- $bad_citation++;
- }
- elsif ( /^Missing character: There is no /
- || /^! Package inputenc Error: Unicode character /
- || /^! Bad character code /
- ) {
- $bad_character++;
- }
- elsif ( /^Document Class: / ) {
- # Class sign-on line
- next LINE;
- }
- elsif ( /^\(Font\)/ ) {
- # Font info line
- next LINE;
- }
- elsif (/^No pages of output\./) {
- $primary_out = '';
- warn "$My_name: Log file says no output from latex\n";
- next LINE;
- }
- elsif ( /^Output written on\s+(.*)\s+\(\d+\s+page/ ) {
- $primary_out = normalize_clean_filename($1, @pwd_log);
- warn "$My_name: Log file says output to '$primary_out'\n"
- unless $silent;
- next LINE;
- }
- elsif ( /^Overfull /
- || /^Underfull /
- || /^or enter new name\. \(Default extension: .*\)/
- || /^\*\*\* \(cannot \\read from terminal in nonstop modes\)/
- ) {
- # Latex error/warning, etc.
- next LINE;
- }
- elsif ( /^\\openout\d+\s*=\s*(.*)\s*$/ ) {
- # \openout followed by filename followed by line end.
- # pdflatex and xelatex quote it and wrap,
- # lualatex leaves filename as is, and doesn't wrap.
- my $cand = $1;
- if ( $cand =~ /\`\"([^\'\"]+)\"\'\.$/ ) {
- # One form of quoting by pdflatex, xelatex: `"..."'.
- $cand = $1;
- }
- elsif ( $cand =~ /\`([^\']+)\'\.$/ ) {
- # Another form of quoting by pdflatex, xelatex: `...'.
- $cand = $1;
- }
- if ( $cand =~ /[\`\'\"]/){
- # Bad quotes: e.g., incomplete wrapped line
- next LINE;
- }
- $generated_log{normalize_force_directory( $aux_dir1, $cand )} = 1;
- next LINE;
- }
- # Test for conversion produced by package:
- elsif ( /^Package (\S+) Info: Source file: <([^>]+)>/ ) {
- # Info. produced by epstopdf (and possibly others)
- # about file conversion
- $current_pkg = normalize_clean_filename($1, @pwd_log);
- $delegated_source = normalize_clean_filename($2, @pwd_log);
- $block_type = 'conversion';
- next LINE;
- }
-# Test for writing of index file. The precise format of the message
-# depends on which package (makeidx.sty , multind.sty or index.sty) and
-# which version writes the message.
- elsif ( /Writing index file (.*)$/ ) {
- my $idx_file = '';
- if ( /^Writing index file (.*)$/ ) {
- # From makeidx.sty or multind.sty
- $idx_file = $1;
- }
- elsif ( /^index\.sty> Writing index file (.*)$/ ) {
- # From old versions of index.sty
- $idx_file = $1;
- }
- elsif ( /^Package \S* Info: Writing index file (.*) on input line/ ) {
- # From new versions of index.sty
- $idx_file = $1;
- }
- else {
- warn "$My_name: Message indicates index file was written\n",
- " ==> but I do not know how to understand it: <==\n",
- " '$_'\n";
- next LINE;
- }
- # Typically, there is trailing space, not part of filename:
- $idx_file =~ s/\s*$//;
- # When *latex is run with an -output-directory
- # or an -aux_directory, the file name does not contain
- # the output path; fix this, after removing quotes:
- $idx_file = normalize_force_directory( $aux_dir1, $idx_file );
- my ($idx_base, $idx_path, $idx_ext) = fileparseA( $idx_file );
- $idx_base = $idx_path.$idx_base;
- $idx_file = $idx_base.$idx_ext;
- if ( $idx_ext eq '.idx' ) {
- warn "$My_name: Index file '$idx_file' was written\n"
- unless $silent;
- $idx_files{$idx_file} = [ "$idx_base.ind", $idx_base ];
- }
- elsif ( exists $cusdep_from{$idx_ext} ) {
- if ( !$silent ) {
- warn "$My_name: Index file '$idx_file' was written\n";
- warn " Cusdep '$cusdep_from{$idx_ext}' should be used\n";
- }
- # No action needed here
- }
- else {
- warn "$My_name: Index file '$idx_file' written\n",
- " ==> but it has an extension I do not know how to handle <==\n";
- }
-
- next LINE;
- }
- elsif ( /^No file (.*?\.bbl)./ ) {
- my $bbl_file = normalize_force_directory( $aux_dir1, $1);
- my $aux_file = $bbl_file;
- $aux_file =~ s/\.bbl$/\.aux/;
- warn "$My_name: Non-existent bbl file '$bbl_file in line'\n $_\n";
- $dependents{$bbl_file} = 0;
- push @bbl_files, $bbl_file;
- next LINE;
- }
- foreach my $pattern (@file_not_found) {
- if ( /$pattern/ ) {
- my $file = clean_filename($1);
- warn "$My_name: Missing input file: '$file' from line\n '$_'\n"
- unless $silent;
- $dependents{normalize_filename($file, @pwd_log)} = 0;
- my $file1 = $file;
- if ( $aux_dir ) {
- # Allow for the possibility that latex generated
- # a file in $aux_dir, from which the missing file can
- # be created by a cusdep (or other) rule that puts
- # the result in $out_dir. If the announced missing file
- # has no path, then it would be effectively a missing
- # file in $aux_dir, with a path. So give this alternate
- # location.
- # It is also possible to have a file that is in a directory
- # relative to the aux_dir, so allow for that as well
- my $file1 = normalize_force_directory( $aux_dir1, $file );
- $dependents{$file1} = 0;
- $dependents{$aux_dir1.$file} = 0;
-
- }
- next LINE;
- }
- }
- if ( (! $fls_file_analyzed)
- && /^File: (.+) Graphic file \(type / ) {
- # First line of message from includegraphics/x
- # But this does NOT include full path information
- # (if exact match is not found and a non-trivial
- # kpsearch was done by *latex).
- # But the source-file information is in the fls file,
- # if we are using it.
- $dependents{normalize_clean_filename($1, @pwd_log)} = 1;
- next LINE;
- }
- # Now test for generic lines to ignore, only after special cases!
- if ( /^File: / ) {
- # Package sign-on line. Includegraphics/x also produces a line
- # with this signature, but I've already handled it.
- next LINE;
- }
- if ( /^Package: / ) {
- # Package sign-on line
- next LINE;
- }
- if (/^\! LaTeX Error: / ) {
- next LINE;
- }
- if ( m[^! I can't write on file `(.*)/([^/']*)'.\s*$] ) {
- my $dir = $1;
- my $file = $2;
- my $full_dir = $aux_dir1.$dir;
- if ( ($aux_dir ne '') && (! -e $full_dir) && ( $file =~ /\.aux$/) ) {
- warn "$My_name: === There were problems writing to '$file' in '$full_dir'\n",
- " I'll try to make the subdirectory later.\n"
- if $diagnostics;
- push @missing_subdirs, $full_dir;
- }
- else {
- warn "$My_name: ====== There were problems writing to",
- "----- '$file' in '$full_dir'.\n",
- "----- But this is not the standard situation of\n",
- "----- aux file to subdir of output directory, with\n",
- "----- non-existent subdir\n",
- }
- }
-
- if ( ($fls_file_analyzed) && (! $analyze_input_log_always) ) {
- # Skip the last part, which is all about finding input
- # file names which should all appear more reliably in the
- # fls file.
- next LINE;
- }
-
- my @new_includes = ();
-
- GRAPHICS_INCLUDE_CANDIDATE:
- while ( /<([^>]+)(>|$)/g ) {
- if ( -f $1 ) { push @new_includes, $1; }
- } # GRAPHICS_INCLUDE_CANDIDATE:
-
- INCLUDE_CANDIDATE:
- while ( /\((.*$)/ ) {
- # Filename found by
- # '(', then filename, then terminator.
- # Terminators: obvious candidates: ')': end of reading file
- # '(': beginning of next file
- # ' ': space is an obvious separator
- # ' [': start of page: latex
- # and pdflatex put a
- # space before the '['
- # '[': start of config file
- # in pdflatex, after
- # basefilename.
- # '{': some kind of grouping
- # Problem:
- # All or almost all special characters are allowed in
- # filenames under some OS, notably UNIX. Luckily most cases
- # are rare, if only because the special characters need
- # escaping. BUT 2 important cases are characters that are
- # natural punctuation
- # Under MSWin, spaces are common (e.g., "C:\Program Files")
- # Under VAX/VMS, '[' delimits directory names. This is
- # tricky to handle. But I think few users use this OS
- # anymore.
- #
- # Solution: use ' [', but not '[' as first try at delimiter.
- # Then if candidate filename is of form 'name1[name2]', then
- # try splitting it. If 'name1' and/or 'name2' exists, put
- # it/them in list, else just put 'name1[name2]' in list.
- # So form of filename is now:
- # '(',
- # then any number of characters that are NOT ')', '(', or '{'
- # (these form the filename);
- # then ' [', or ' (', or ')', or end-of-string.
- # That fails for pdflatex
- # In log file:
- # '(' => start of reading of file, followed by filename
- # ')' => end of reading of file
- # '[' => start of page (normally preceeded by space)
- # Remember:
- # filename (on VAX/VMS) may include '[' and ']' (directory
- # separators)
- # filenames (on MS-Win) commonly include space.
- # filenames on UNIX can included space.
- # Miktex quotes filenames
- # But web2c doesn't. Then
- # (string message
- # is ambiguous: is the filename "string" or "string message".
- # Allow both as candidates, since user filenames with spaces
- # are rare. System filenames with spaces are common, but
- # they are normally followed by a newline rather than messages.
-
- # First step: replace $_ by whole of line after the '('
- # Thus $_ is putative filename followed by other stuff.
- $_ = $1;
- # Array of new candidate include files; sometimes more than one.
- my $quoted = 0;
- if ( /^\"([^\"]+)\"/ ) {
- # Quoted file name, as from MikTeX
- $quoted = 1;
- }
- elsif ( /^\"/ ) {
- # Incomplete quoted file, as in wrapped line before appending
- # next line
- next LINE;
- }
- elsif ( /^([^\(^\)]*?)\s+[\[\{\<]/ ) {
- # Terminator: space then '[' or '{' or '<'
- # Use *? in condition: to pick up first ' [' (etc)
- # as terminator
- }
- elsif ( /^([^\(^\)]*)\s+(?=\()/ ) {
- # Terminator is ' (', but '(' isn't in matched string,
- # so we keep the '(' ready for the next match
- }
- elsif ( /^([^\(^\)]*)(\))/ ) {
- # Terminator is ')'
- }
- else {
- #Terminator is end-of-string
- }
- $_ = $'; # Put $_ equal to the unmatched tail of string '
- my $include_candidate = $1;
- $include_candidate =~ s/\s*$//; # Remove trailing space.
- if ($quoted) {
- # Remove quotes around filename.
- $include_candidate =~ s/^\"(.*)\"$/$1/;
- }
- elsif ( !$quoted && ($include_candidate =~ /(\S+)\s/ ) ){
- # Non-space-containing filename-candidate
- # followed by space followed by message
- # (Common)
- push @new_includes, $1;
- }
- if ($include_candidate =~ /[\"\'\`]/) {
- # Quote inside filename. Probably misparse.
- next INCLUDE_CANDIDATE;
- }
- if ( $include_candidate eq "[]" ) {
- # Part of overfull hbox message
- next INCLUDE_CANDIDATE;
- }
- if ( $include_candidate =~ /^\\/ ) {
- # Part of font message
- next INCLUDE_CANDIDATE;
- }
-
- push @new_includes, $include_candidate;
- if ( $include_candidate =~ /^(.+)\[([^\]]+)\]$/ ) {
- # Construct of form 'file1[file2]', as produced by pdflatex
- if ( -e $1 ) {
- # If the first component exists, we probably have the
- # pdflatex form
- push @new_includes, $1, $2;
- }
- else {
- # We have something else.
- # So leave the original candidate in the list
- }
- }
- } # INCLUDE_CANDIDATE
-
- INCLUDE_NAME:
- foreach my $include_name (@new_includes) {
- if ($include_name =~ /[\"\'\`]/) {
- # Quote inside filename. Probably misparse.
- next INCLUDE_NAME;
- }
- $include_name = normalize_filename( $include_name, @pwd_log );
- my ($base, $path, $ext) = fileparseB( $include_name );
- if ( ($path eq './') || ($path eq '.\\') ) {
- $include_name = $base.$ext;
- }
- if ( $include_name !~ m'[/|\\]' ) {
- # Filename does not include a path character
- # High potential for misparsed line
- $dependents{$include_name} = 2;
- } else {
- $dependents{$include_name} = 3;
- }
- if ( $ext eq '.bbl' ) {
- warn "$My_name: Found input bbl file '$include_name'\n"
- unless $silent;
- push @bbl_files, $include_name;
- }
- } # INCLUDE_NAME
- } # LINE
-
- # Default includes are always definitive:
- foreach (@default_includes) { $dependents{$_} = 4; }
-
- ###print "New parse: \n";
- ###foreach (sort keys %dependents) { print " '$_': $dependents{$_}\n"; }
-
- my @misparsed = ();
- my @missing = ();
- my @not_found = ();
-
- my %kpsearch_candidates = ();
-CANDIDATE:
- foreach my $candidate (keys %dependents) {
- my $code = $dependents{$candidate};
- if ( -d $candidate ) {
- # If $candidate is directory, it was presumably found from a
- # mis-parse, so remove it from the list. (Misparse can
- # arise, for example from a mismatch of latexmk's $log_wrap
- # value and texmf.cnf value of max_print_line.)
- delete $dependents{$candidate};
- }
- elsif ( -e $candidate ) {
- if ( exists $generated_log{$candidate} ){
- $dependents{$candidate} = 6;
- }
- elsif ($code == 0) {
- $dependents{$candidate} = 5;
- }
- else {
- $dependents{$candidate} = 4;
- }
- }
- elsif ($code == 1) {
- # Graphics file that is supposed to have been read.
- # Candidate name is as given in source file, not as path
- # to actual file.
- # We have already tested that file doesn't exist, as given.
- # so use kpsewhich.
- # If the file still is not found, assume non-existent;
- $kpsearch_candidates{$candidate} = 1;
- delete $dependents{$candidate};
- }
- elsif ($code == 2) {
- # Candidate is from '(...' construct in log file, for input file
- # which should include pathname if valid input file.
- # Name does not have pathname-characteristic character (hence
- # $code==2.
- # We get here if candidate file does not exist with given name
- # Almost surely result of a misparsed line in log file.
- delete $dependents{$candidate};
- push @misparse, $candidate;
- }
- elsif ($code == 3) {
- # Candidate is from '(...' construct in log file, for input file
- # which should include pathname if valid input file.
- # Name does have pathname-characteristic character (hence
- # $code==3.
- # But we get here only if candidate file does not exist with
- # given name.
- # Almost surely result of a misparsed line in log file.
- # But with lower probability than $code == 2
- delete $dependents{$candidate};
- push @misparse, $candidate;
- }
- elsif ($code == 0) {
- my ($base, $path, $ext) = fileparseA($candidate);
- $ext =~ s/^\.//;
- if ( ($ext eq '') && (-e "$path$base.tex") ) {
- # I don't think the old version was correct.
- # If the missing-file report was of a bare
- # extensionless file, and a corresponding .tex file
- # exists, then the missing file does not correspond
- # to the missing file, unless the .tex file was
- # created during the run.
- # OLD $dependents{"$path$base.tex"} = 4;
- # OLD delete $dependents{$candidate};
- # NEW:
- $dependents{"$path$base.tex"} = 4;
- }
- push @missing, $candidate;
- }
- }
-
- my @kpsearch_candidates = keys %kpsearch_candidates;
- if (@kpsearch_candidates) {
- foreach my $result ( kpsewhich( @kpsearch_candidates ) ) {
- $dependents{$result} = 4;
- }
- }
-
-CANDIDATE_PAIR:
- foreach my $delegated_source (keys %new_conversions) {
- my $delegated_output = $new_conversions{$delegated_source};
- my $rule = "Delegated $delegated_source, $delegated_output";
- # N.B. $delegated_source eq '' means the output file
- # was created without a named input file.
- foreach my $candidate ($delegated_source, $delegated_output) {
- if (! -e $candidate ) {
- # The file might be somewhere that can be found
- # in the search path of kpathsea:
- my @kpse_result = kpsewhich( $candidate,);
- if ($#kpse_result > -1) {
- $candidate = $kpse_result[0];
- }
- }
- }
- if ( ( (-e $delegated_source) || ($delegated_source eq '') )
- && (-e $delegated_output) )
- {
- $conversions{$delegated_output} = $delegated_source;
- $dependents{$delegated_output} = 7;
- if ($delegated_source) {
- $dependents{$delegated_source} = 4;
- }
- }
- elsif (!$silent) {
- print "Logfile claimed conversion from '$delegated_source' ",
- "to '$delegated_output'. But:\n";
- if (! -e $delegated_output) {
- print " Output file does not exist\n";
- }
- if ( ($delegated_source ne '') && (! -e $delegated_source) ) {
- print " Input file does not exist\n";
- }
- }
- }
-
- if ( ($#warning_list >= 0) && !$log_silent ) {
- @warning_list = uniqs( @warning_list );
- show_array( "$My_name: List of undefined refs and citations:",
- @warning_list );
- }
-
- if ( $diagnostics ) {
- @misparse = uniqs( @misparse );
- @missing = uniqs( @missing );
- @not_found = uniqs( @not_found );
- my @dependents = sort( keys %dependents );
-
- my $dependents = $#dependents + 1;
- my $misparse = $#misparse + 1;
- my $missing = $#missing + 1;
- my $not_found = $#not_found + 1;
- my $exist = $dependents - $not_found - $missing;
- my $bbl = $#bbl_files + 1;
-
- print "$dependents dependent files detected, of which ",
- "$exist exist, $not_found were not found,\n",
- " and $missing appear not to exist.\n";
- print "Dependents:\n";
- foreach (@dependents) {
- print " '$_' ";
- if ( $dependents{$_} == 6 ) { print " written by *latex";}
- if ( $dependents{$_} == 7 ) { print " converted by *latex";}
- print "\n";
- }
- if ($not_found > 0) {
- print "Not found:\n";
- foreach (@not_found) { print " $_\n"; }
- }
- if ($missing > 0) {
- print "Not existent:\n";
- foreach (@missing) { print " $_\n"; }
- }
- if ( $bbl > 0 ) {
- print "Input bbl files:\n";
- foreach (@bbl_files) { print " $_\n"; }
- }
-
- if ( $misparse > 0 ) {
- print "Possible input files, perhaps from misunderstood lines in .log file:\n";
- foreach ( @misparse ) { print " $_\n"; }
- }
- }
- return 1;
-} #END parse_log
-
-#************************************************************
-
-sub find_set_log {
- # Locate the log file, if possible. This allows for possible configuration
- # errors, e.g., because the command for (*)latex was such that it did not
- # do the setting of -output-directory or -aux-directory that the user intended,
- # or because the version used did not support one or other of these options.
- # Put result in $where_log (see its initial declaration/definition for details).
- # Change $aux_dir and/or $out_dir as appropriate, and make consequent changes.
- #
- # Probably further attention to location of output file (.dvi, .pdf, or .xdv)
- # could be done, to get $out_dir and $$Pdest more accurately set.
- #
- # Typical configuration errors that lead to the need for this subroutine:
- # %O not used in command definition, so directory options don't getpassed
- # to (*)latex.
- # Use of $aux_dir different to $out_dir, when (*)latex doesn't support
- # the -aux-directory option (notably with TeXLive distribution).
- if ($where_log >= 0) {
- # .log file was found on previous run. No need to repeat search, since
- # if the location were to change from run to run, we'd have other
- # serious difficulties that are to hard to deal with.
- return;
- }
- if ( test_gen_file( "$aux_dir1$root_filename.log" ) ) {
- # .log file is in expected place.
- $where_log = 1;
- }
- elsif ( test_gen_file( "$out_dir1$root_filename.log" ) ) {
- # .log file is in out_dir not in aux_dir.
- # Presumably there is a configuration error
- # that prevents aux_dir from being used by latex.
- # So change $aux_dir to the actually used value.
- $where_log = 2;
- $aux_dir = $out_dir;
- }
- elsif ( test_gen_file( "$root_filename.log" ) ) {
- # .log file is not in out_dir nor in aux_dir, but is in cwd.
- # Presumably there is a configuration error
- # that prevents the directories from being used by latex.
- # So change $aux_dir to the actually used value.
- $where_log = 3;
- $aux_dir = "";
- }
- else {
- # No .log file found
- $failure = 1;
- $$Plast_result = 2;
- $where_log = 0;
- $failure_msg
- = "*LaTeX didn't generate the expected log file '$log_name'\n";
- }
- if ($where_log > 1) {
- warn "$My_name: Changed aux_dir from '$aux_dir_requested' to '$aux_dir'\n".
- " to allow for probable configuration error\n";
- # Allow for the changes associated with change of $aux_dir:
- &set_dirs_etc;
- &set_names;
- warn "$My_name: Actual .log file is\n",
- " '$log_name'\n",
- " instead of the value\n",
- " '$aux_dir_requested/$root_filename.log'\n",
- " that seemed to be intended.\n";
- }
-}
-
-#************************************************************
-
-sub parse_fls {
- my ($fls_name, $Pinputs, $Poutputs, $Pfirst_read_after_write, $Ppwd_latex ) = @_;
- %$Pinputs = %$Poutputs = %$Pfirst_read_after_write = ();
- my $fls_file = new FileHandle;
- # Make a note of current working directory
- # I'll update it from the fls file later
- # Currently I don't use this, but it would be useful to use
- # this when testing prefix for cwd in a filename, by
- # giving *latex's best view of the cwd. Note that the
- # value given by the cwd() function may be mangled, e.g., by cygwin
- # compared with native MSWin32.
- #
- # Two relevant forms of cwd exist: The system one, which we can find, and
- # the one reported by *latex in the fls file. It will be
- # useful to remove leading part of cwd in filenames --- see the
- # comments in sub rdb_set_latex_deps. Given the possible multiplicity
- # of representations of cwd, the one reported in the fls file should
- # be definitive in the fls file.
-
- my $cwd = good_cwd();
- if ( ! open ($fls_file, "<$fls_name") ) {
- return 1;
- }
- foreach $_ ( <$fls_file> ) {
- # Remove trailing CR and LF. Thus we get correct behavior when an fls file
- # is produced by MS-Windows program (e.g., in MiKTeX) with CRLF line ends,
- # but is read by Unix Perl (which treats LF as line end, and preserves CRLF
- # in read-in lines):
- $_ =~ s/[\n\r]*$//;
- if (/^\s*PWD\s+(.*)$/) {
- $cwd = $1;
- $$Ppwd_latex = $cwd;
- if ( $cwd =~ /\"/ ) {
- warn "$My_name: The working directory has a '\"' character in its name:\n",
- " '$cwd'\n This can cause me trouble. Beware!\n";
- }
- }
- elsif (/^\s*INPUT\s+(.*)$/) {
- # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
- my $file = $1;
- # Remove exactly pwd reported in this file, and following separator.
- # MiKTeX reports absolute pathnames, and this way of removing PWD insulates
- # us from coding issues if the PWD contains non-ASCII characters. What
- # coding scheme (UTF-8, code page, etc) is used depends on OS, TeX
- # implementation, ...
- if ( defined $$Ppwd_latex ) {
- $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
- }
- $file = normalize_filename( $file );
- if ( (exists $$Poutputs{$file}) && (! exists $$Pinputs{$file}) ) {
- $$Pfirst_read_after_write{$file} = 1;
- }
- $$Pinputs{$file} = 1;
- }
- elsif (/^\s*OUTPUT\s+(.*)$/) {
- # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
- my $file = $1;
- $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
- $file = normalize_filename( $file );
- $$Poutputs{$file} = 1;
- }
- }
- close( $fls_file );
- return 0;
-} #END parse_fls
-
-#************************************************************
-
-sub dirname_no_tail {
- my $dirname = $_[0];
-# print "DNT1 = '$dirname'\n";
- foreach ($dirname) {
- # Normalize name to use / to separate directory components:
- # (Note both / and \ are allowed under MSWin.)
- s(\\)(/)g;
- # Change multiple trailing / to single /
- # (Note internal // or \\ can have special meaning on MSWin)
- s(/+$)(/);
- # Remove trailing /,
- # BUT **not** if that changes the semantics, i.e., if name is "/" or "C:/".
- if ( m(/$) ) {
- if ( ( ! m(^/+$) ) && ( ! m(:/+$) ) ) {
- s(/$)();
- }
- }
- }
-# print "DNT2 = '$dirname'\n";
- return $dirname;
-}
-
-#************************************************************
-
-sub clean_filename {
- # Convert quoted filename as found in log file to filename without quotes
- # Allows arbitrarily embedded double-quoted substrings, includes the
- # cases
- # 1. `"string".ext', which arises e.g., from \jobname.bbl:
- # when the base filename contains spaces, \jobname has quotes.
- # and from \includegraphics with basename specified.
- # Also deals with filenames written by asymptote.sty
- # 2. Or "string.ext" from \includegraphcs with basename and ext specified.
- # and from MiKTeX logfile for input files with spaces.
- # Doubled quotes (e.g., A""B) don't get converted.
- # Neither do unmatched quotes.
- my $filename = $_[0];
- while ( $filename =~ s/^([^\"]*)\"([^\"]+)\"(.*)$/$1$2$3/ ) {}
- return $filename;
-}
-
-# ------------------------------
-
-sub normalize_filename {
- # Usage: normalize_filename( filename [, extra forms of name of cwd] )
- # Returns filename with removal of various forms for cwd, and
- # with conversion of directory separator to '/' only
- #
- my ( $file, @dirs ) = @_;
- my $file1 = $file; # Saved original value
- my $cwd = good_cwd();
- # Normalize files to use / to separate directory components:
- # (Note both / and \ are allowed under MSWin.)
- foreach ($cwd, $file, @dirs) {
- s(\\)(/)g;
- $_ = dirname_no_tail( $_ );
- }
- # Remove initial component equal to current working directory.
- # Use \Q and \E round directory name in regex to avoid interpretation
- # of metacharacters in directory name:
- foreach my $dir ( @dirs, '.', $cwd ) {
- if ( $dir =~ /^\s*$/ ) {
- next;
- }
- if ( $file =~ s(^\Q$dir\E/)() ) {
- last;
- }
- }
- return $file;
-}
-
-# ------------------------------
-
-sub normalize_clean_filename {
- # Usage: normalize_clean_filename( filename [, extra forms of name of cwd] )
- # Same as normalize_filename, but first remove any double quotes, as
- # done by clean_filename, which is appropriate for filenames from log file.
- my ($file, @dirs) = @_;
- return normalize_filename( clean_filename( $file ) , @dirs );
-}
-
-#************************************************************
-
-sub fix_pattern {
- # Escape the characters [ and {, to give a pattern for use in glob
- # with these characters taken literally.
- my $pattern = shift;
- $pattern =~ s/\[/\\\[/g;
- $pattern =~ s/\{/\\\{/g;
- return $pattern;
-}
-
-#************************************************************
-
-sub parse_aux {
- #Usage: parse_aux( $aux_file, \@new_bib_files, \@new_aux_files, \@new_bst_files )
- # Parse aux_file (recursively) for bib files, and bst files.
- # If can't open aux file, then
- # Return 0 and leave @new_bib_files empty
- # Else set @new_bib_files from information in the aux files
- # And:
- # Return 1 if no problems
- # Return 2 with @new_bib_files empty if there are no \bibdata
- # lines.
- # Return 3 if I couldn't locate all the bib_files
- # Set @new_aux_files to aux files parsed
-
- my $aux_file = $_[0];
- local $Pbib_files = $_[1];
- local $Paux_files = $_[2];
- local $Pbst_files = $_[3];
-
- @$Pbib_files = ();
- @$Pbst_files = ();
- @$Paux_files = ();
-
- parse_aux1( $aux_file );
- if ($#{$Paux_files} < 0) {
- return 0;
- }
- @$Pbib_files = uniqs( @$Pbib_files );
- @$Pbst_files = uniqs( @$Pbst_files );
-
- if ( $#{$Pbib_files} == -1 ) {
- warn "$My_name: No .bib files listed in .aux file '$aux_file' \n",
- return 2;
- }
- my @not_found = &find_file_list1( $Pbib_files, $Pbib_files,
- '.bib', \@BIBINPUTS );
- @$Pbib_files = uniqs( @$Pbib_files );
- &find_file_list1( $Pbst_files, $Pbst_files, '.bst' );
- @$Pbst_files = uniqs( @$Pbst_files );
- my @bad_bib = ();
- foreach ( @$Pbib_files ) {
- if ( /\s/ ) { push @bad_bib, $_; }
- }
- if ($#bad_bib >= 0) {
- warn "$My_name: White space in an argument list for \\bibliography.\n",
- " which is not allowed by bibtex. Bad arguments:\n";
- foreach (@bad_bib ) { warn " '$_'\n"; }
- return 3;
- }
- if ( $#not_found < 0) {
- warn "$My_name: Found bibliography file(s) [@$Pbib_files]\n"
- unless $silent;
- }
- else {
- warn "$My_name: Failed to find one or more bibliography files:\n";
- foreach (@not_found) { warn " '$_'\n"; }
- if ($force_mode) {
- warn "==== Force_mode is on, so I will continue. ",
- "But there may be problems ===\n";
- }
- return 3;
- }
- return 1;
-} #END parse_aux
-
-#************************************************************
-
-sub parse_aux1
-# Parse single aux file for bib files.
-# Usage: &parse_aux1( aux_file_name )
-# Append newly found bib_filenames in @$Pbib_files, already
-# initialized/in use.
-# Append aux_file_name to @$Paux_files if aux file opened
-# Recursively check \@input aux files
-# Return 1 if success in opening $aux_file_name and parsing it
-# Return 0 if fail to open it
-{
- my $aux_file = $_[0];
- my $aux_fh = new FileHandle;
- if (! open($aux_fh, $aux_file) ) {
- warn "$My_name: Couldn't find aux file '$aux_file'\n";
- return 0;
- }
- push @$Paux_files, $aux_file;
-AUX_LINE:
- while (<$aux_fh>) {
- if ( /^\\bibdata\{(.*)\}/ ) {
- # \\bibdata{comma_separated_list_of_bib_file_names}
- # These are normally without the '.bib' extension.
- push @$Pbib_files, split /,/, $1;
- }
- elsif ( /^\\bibstyle\{(.*)\}/ ) {
- # \\bibstyle{bst_file_name}
- # Normally without the '.bst' extension.
- push @$Pbst_files, split /,/, $1;
- }
- elsif ( /^\\\@input\{(.*)\}/ ) {
- # \\@input{next_aux_file_name}
- &parse_aux1( $aux_dir1.$1 );
- }
- else {
- foreach my $Psub (@aux_hooks) {
- &$Psub;
- }
- }
- }
- close($aux_fh);
- return 1;
-} #END parse_aux1
-
-#************************************************************
-
-#************************************************************
-#************************************************************
-#************************************************************
-
-# Manipulations of main file database:
-
-#************************************************************
-
-sub fdb_get {
- # Call: fdb_get(filename [, check_time])
- # Returns an array (time, size, md5) for the current state of the
- # named file.
- # The optional argument check_time is either the run_time of some command
- # that may have changed the file or the last time the file was checked
- # for changes --- see below.
- # For non-existent file, deletes its entry in fdb_current,
- # and returns (0,-1,0) (whatever is in @nofile).
- # As an optimization, the md5 value is taken from the cache in
- # fdb_current, if the time and size stamp indicate that the
- # file has not changed.
- # The md5 value is recalculated if
- # the current filetime differs from the cached value:
- # file has been written
- # the current filesize differs from the cached value:
- # file has definitely changed
- # But the file can also be rewritten without change in filetime when
- # file processing happens within the 1-second granularity of the
- # timestamp (notably for aux files from latex on a short source file).
- # The only case that concerns us is when the file is an input to a program
- # at some runtime t, the file is rewritten later by the same or another
- # program, with timestamp t, and when the initial file also has
- # timestamp t.
- # A test is applied for this situation if the check_time argument is
- # supplied and is nonzero.
-
- my ($file, $check_time) = @_;
- if ( ! defined $check_time ) { $check_time = 0;}
- my ($new_time, $new_size) = get_time_size($file);
- if ( $new_size < 0 ) {
- delete $fdb_current{$file};
- return @nofile;
- }
- my $recalculate_md5 = 0;
- if ( ! exists $fdb_current{$file} ) {
- # Ensure we have a record.
- $fdb_current{$file} = [@nofile];
- $recalculate_md5 = 1;
- }
- my $file_data = $fdb_current{$file};
- my ( $time, $size, $md5 ) = @$file_data;
-
- if ( ($new_time != $time) || ($new_size != $size)
- || ( $check_time && ($check_time == $time ) )
- ) {
- # Only force recalculation of md5 if time or size changed.
- # However, the physical file time may have changed without
- # affecting the value of the time coded in $time, because
- # times are computed with a 1-second granularity.
- # The only case to treat specially is where the file was created,
- # then used by the current rule, and then rewritten, all within
- # the granularity size, otherwise the value of the reported file
- # time changed, and we've handled it. But we may have already
- # checked this at an earlier time than the current check. So the
- # only dangerous case is where the file time equals a check_time,
- # which is either the run_time of the command or the time of a
- # previous check.
- # Else we assume file is really unchanged.
- $recalculate_md5 = 1;
- }
- if ($recalculate_md5) {
- @$file_data = ( $new_time, $new_size, get_checksum_md5( $file ) );
- }
- return @$file_data;;
-} #END fdb_get
-
-#************************************************************
-
-sub fdb_set {
- # Call: fdb_set(filename, $time, $size, $md5 )
- # Set data in file data cache, i.e., %fdb_current
- my ($file, $time, $size, $md5 ) = @_;
- if ( ! exists $fdb_current{$file} ) {
- $fdb_current{$file} = [@nofile];
- }
- @{$fdb_current{$file}} = ( $time, $size, $md5 );
-} #END fdb_set
-
-#************************************************************
-
-sub fdb_show {
- # Displays contents of fdb
- foreach my $file ( sort keys %fdb_current ) {
- print "'$file': @{$fdb_current{$file}}\n";
- }
-} #END fdb_show
-
-#************************************************************
-#************************************************************
-#************************************************************
-
-# Routines for manipulating rule database
-
-#************************************************************
-
-sub rdb_read {
- # Call: rdb_read( $in_name )
- # Sets rule database from saved file, in format written by rdb_write.
- # Returns -1 if file could not be read else number of errors.
- # Thus return value on success is 0
- # Requires: Rule database initialized with standard rules, with
- # conditions corresponding to requests determined by
- # initialization and command line options.
- # Asssumption: Normally the fdb_latexmk file contains state of
- # rules and files corresponding to end of last
- # compilation, and the rules in the file were
- # active on that run.
- # Complications arise when that state does not correspond to current
- # rule set:
- # (a) Configuration etc may have changed: e.g., different out_dir,
- # different target rules and files, including different tex engine.
- # (b) Output extension of primary rule may be different from current
- # initialized one, because of document properties (use of
- # \pdfoutput etc).
- # (c) The same may arise because of misconfigured rules, a situation
- # that may or may not have changed in current run.
- # (d) The primary engine requested may not be the one used in
- # the previous run, possibly because (i) request has
- # changed, or (ii) document metacommand was obeyed to change
- # engine. (The last is not currently implemented, but
- # may/should be in the future.)
- # (e) Something else, e.g., copying/editing of fdb_latexmk file.
- #
- local $in_name = $_[0];
- my $in_handle = new FileHandle;
- $in_handle->open( $in_name, '<' )
- or return ();
- my $errors = 0;
- my $state = -1; # Values: -1: before start; 0: outside rule;
- # 1: in source section;
- # 2: in generated file section;
- # 10: ignored rule.
- my $rule = '';
- local $run_time = 0;
- local $source = '';
- local $dest = '';
- my $base = '';
- my %old_actives = (); # Hash: keys are rules in fdb_latexmk file
- local %new_sources = (); # Hash: rule => { file=>[ time, size, md5, fromrule ] }
- my $new_source = undef; # Reference to hash of sources for current rule
-LINE:
- while ( <$in_handle> ) {
- # Remove leading and trailing white space.
- s/^\s*//;
- s/\s*$//;
- if ($state == -1) {
- if ( ! /^# Fdb version ([\d]+)$/ ) {
- warn "$My_name: File-database '$in_name' is not of correct format\n";
- return 1;
- }
- if ( $1 > $fdb_ver) {
- warn "$My_name: File-database '$in_name' is of too new version, $1 > $fdb_ver\n";
- return 1;
- }
- $state = 0;
- }
- # Ignore blank lines and comments
- if ( /^$/ || /^#/ || /^%/ ) { next LINE;}
- if ( /^\[\"([^\"]+)\"\]/ ) {
- # Start of section
- $rule = $1;
- my $tail = $'; #' Single quote in comment tricks the parser in
- # emacs from misparsing an isolated single quote
- $run_time = $check_time = 0;
- $source = $dest = $base = '';
- $old_actives{$rule} = 1;
- if ( $tail =~ /^\s*(\S+)\s*$/ ) {
- $run_time = $1;
- }
- elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s*$/ ) {
- $run_time = $1;
- $source = $2;
- $dest = $3;
- $base = $4;
- }
- elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+(\S+)\s*$/ ) {
- $run_time = $1;
- $source = $2;
- $dest = $3;
- $base = $4;
- $check_time = $5;
- }
- if ( rdb_rule_exists( $rule ) ) {
- rdb_one_rule( $rule, \&rdb_read_set_rule );
- }
- elsif ($rule =~ /^cusdep\s+(\S+)\s+(\S+)\s+(.+)$/ ) {
- # Create custom dependency
- my $fromext = $1;
- my $toext = $2;
- my $base = $3;
- $source = "$base.$fromext";
-# $dest = "$base.$toext";
- my $func_name = '';
- foreach my $dep ( @cus_dep_list ) {
- my ($tryfromext,$trytoext,$must,$try_func_name) = split('\s+',$dep);
- if ( ($tryfromext eq $fromext) && ($trytoext eq $toext) ) {
- $func_name = $try_func_name;
- }
- }
- if ($func_name) {
- my $PAnew_cmd = ['do_cusdep', $func_name];
- # Set source file as non-existent.
- # If it existed on last run, it will be in later
- # lines of the fdb file
- rdb_create_rule( $rule, 'cusdep', '', $PAnew_cmd, 1,
- $source, $dest, $base, 0, $run_time, $check_time, 1 );
- }
- else {
- warn "$My_name: In file-database '$in_name', the custom-dependency rule\n",
- " '$rule' is not available in this session.\n",
- " Presumably it's no longer in your configuration for latexmk.\n";
- $state = 10;
- next LINE;
- }
- }
- elsif ( $rule =~ /^(makeindex|bibtex|biber)\s*(.*)$/ ) {
- my $PA_extra_gen = [];
- my $rule_generic = $1;
- my $int_cmd = '';
- if ( ! $source ) {
- # If fdb_file was old-style (v. 1)
- $source = $2;
- my $path = '';
- my $ext = '';
- ($base, $path, $ext) = fileparseA( $source );
- $base = $path.$base;
- if ($rule_generic eq 'makeindex') {
- $dest = "$base.ind";
- }
- elsif ($rule_generic eq 'bibtex') {
- $dest = "$base.bbl";
- $source = "$base.aux";
- }
- elsif ($rule_generic eq 'biber') {
- $dest = "$base.bbl";
- $source = "$base.bcf";
- }
- }
- if ($rule =~ /^makeindex/) { $PA_extra_gen = [ "$base.ilg" ]; }
- if ($rule =~ /^(bibtex|biber)/) { $PA_extra_gen = [ "$base.blg" ]; }
- if ($rule =~ /^bibtex/) { $int_cmd = "run_bibtex"; }
- warn "$My_name: File-database '$in_name': setting rule '$rule'\n"
- if $diagnostics;
- my $cmd_type = 'external';
- my $ext_cmd = ${$rule_generic};
- warn " Rule kind = '$rule_generic'; ext_cmd = '$ext_cmd';\n",
- " int_cmd = '$int_cmd';\n",
- " source = '$source'; dest = '$dest'; base = '$base';\n"
- if $diagnostics;
- # Set source file as non-existent.
- # If it existed on last run, it will be in later
- # lines of the fdb file
- rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, 1,
- $source, $dest, $base, 0, $run_time, $check_time, 1, $PA_extra_gen );
- }
- else {
- if ($diagnostics) {
- warn "$My_name: In file-database '$in_name' rule '$rule'\n",
- " is not in use in this session\n";
- }
- $new_source = undef;
- $state = 10;
- next LINE;
- }
- $new_source = $new_sources{$rule} = {};
- $state = 1; #Reading a section, source part
- }
- elsif ( ($state <=0) || ($state >= 3) ) {
- next LINE;
- }
- elsif ( /^\(source\)/ ) { $state = 1; next LINE; }
- elsif ( /^\(generated\)/ ) { $state = 2; next LINE; }
- elsif ( ($state == 1) && /^\"([^\"]*)\"\s+(\S+)\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"/ ) {
- # Source file line
- my $file = $1;
- my $time = $2;
- my $size = $3;
- my $md5 = $4;
- my $from_rule = $5;
-#?? print " --- File '$file'\n";
- if ($state != 1) {
- warn "$My_name: In file-database '$in_name' ",
- "line $. is outside a section:\n '$_'\n";
- $errors++;
- next LINE;
- }
- # Set file in database. But ensure we don't do an unnecessary
- # fdb_get, which can trigger a new MD5 calculation, which is
- # lengthy for a big file. Ininitially flagging the file
- # as non-existent solves the problem:
- rdb_ensure_file( $rule, $file, undef, 1 );
- rdb_set_file1( $rule, $file, $time, $size, $md5 );
- fdb_set( $file, $time, $size, $md5 );
- # Save the rest of the data, especially the from_rule until we know all
- # the rules, otherwise the from_rule may not exist.
- # Also we'll have a better chance of looping through files.
- ${$new_source}{$file} = [ $time, $size, $md5, $from_rule ];
- }
- elsif ( ($state == 2) && /^\"([^\"]*)\"/ ) {
- my $file = $1;
- rdb_one_rule( $rule, sub{ rdb_add_generated($file); } );
- }
- else {
- warn "$My_name: In file-database '$in_name' ",
- "line $. is of wrong format:\n '$_'\n";
- $errors++;
- next LINE;
- }
- }
- undef $in_handle;
- # Set cus dependencies.
- &rdb_set_dependents( keys %rule_db );
- &rdb_set_rule_net;
-
- return $errors;
-} # END rdb_read
-
-#************************************************************
-
-sub rdb_read_set_rule {
- # Rule context assumed. Implicit passing of $dest, $run_time, $check_time,
- # $in_name used as local variables in calling routine rdb_read;
- if ($$Ptest_kind == 3) { $$Ptest_kind = 1; }
- $$Prun_time = $run_time;
- $$Pcheck_time = $check_time;
- # Deal with possibility that destination in fdb_latexmk has different name
- # than the default one. The only case that concerns us is where
- # the extension is changed (by \pdfoutput, e.g., in tex file). But
- # it is possible out and aux directories have been chosen differently,
- # and the user choice there MUST OVERRIDE the value in the fdb_latexmk file.
- if ($dest ne $$Pdest) {
- if (! $possible_primaries{$rule} ) {
- warn "$My_name: In reading rule '$rule' in '$in_name',\n",
- " name of destination file is not current one; I'll flag rule as out of date.\n";
- $$Pout_of_date = 10;
- }
- elsif ( ! rdb_is_active($rule) ) {
- warn "$My_name: In reading rule '$rule' in '$in_name',\n",
- " rule is not currently active.\n";
- # No fixup now. Causes to be analyzed:
- # Change of requested files: no action needed.
- # Obeying of metacommand: not implemented yet.
- }
- else {
- # Get here if rule is active and primary and destination is different
- warn "$My_name: In reading rule '$rule' in '$in_name',\n",
- " destination has different name than configured...\n";
- my ($oldbase, $oldpath, $oldext) = fileparseA( $dest );
- my ($newbase, $newpath, $newext) = fileparseA( $$Pdest );
- if ($oldext ne $newext) {
- if ( ! exists $allowed_output_ext{$oldext} ) {
- warn " Old extension '$oldext' not allowed.\n";
- $$Pout_of_date = 10;
- }
- else {
- warn " ===== CHANGING output type from '$newext' to '$oldext' in '$rule'\n";
- my $switch_error = switch_output( $rule, $oldext, $newext );
- if ($switch_error) {
- warn " I could not accommodate the changed output extension.\n",
- " That is either because the configuration does not allow it\n",
- " or because there is a conflict with implicit or explicit requested filetypes.\n",
- " (Typically that is about .dvi and/or .ps filetypes.)\n",
- "===> There may be subsequent warnings, which may or may not be ignorable.\n",
- "===> If necessary, clean out generated files and try again\n";
- }
- }
- }
- if ( ($oldbase ne $newbase) || ($oldpath ne $newpath) ) {
- # There are further issues (e.g., change of out_dir).
- # Need rerun to correct:
- $$Pout_of_date = 10;
- }
- }
- }
-} #END rdb_read_set_rule
-
-#************************************************************
-
-sub rdb_write {
- # Call: rdb_write( $out_name )
- # Writes to the given file name the database of file and rule data
- # for all rules needed to make final output
- # Returns 1 on success, 0 if file couldn't be opened.
- local $out_name = $_[0];
- local $out_handle = new FileHandle;
- if ( ($out_name eq "") || ($out_name eq "-") ) {
- # Open STDOUT
- $out_handle->open( '>-' );
- }
- else {
- $out_handle->open( $out_name, '>' );
- }
- if (!$out_handle) { return 0; }
-
- &rdb_set_rule_net;
-
- print $out_handle "# Fdb version $fdb_ver\n";
- my @rules = sort &rdb_accessible;
- rdb_for_some(
- \@rules,
- sub {
- # Omit data on a unused and never-run primary rule:
- if ( ($$Prun_time == 0)
- && exists( $possible_primaries{$rule} )
- && ! exists( $current_primaries{$rule} )
- )
- {
- return;
- }
- print $out_handle "[\"$rule\"] $$Prun_time \"$$Psource\" \"$$Pdest\" \"$$Pbase\" $$Pcheck_time\n";
- rdb_do_files(
- sub { print $out_handle " \"$file\" $$Ptime $$Psize $$Pmd5 \"$$Pfrom_rule\"\n"; }
- );
- print $out_handle " (generated)\n";
- foreach (keys %$PHdest) {
- print $out_handle " \"$_\"\n";
- }
- }
- );
- undef $out_handle;
- return 1;
-} #END rdb_write
-
-#************************************************************
-
-sub rdb_set_latex_deps {
- # Assume primary rule context.
- # This is intended to be applied only for a primary (LaTeX-like) rule.
- # Set its dependents etc, using information from log, aux, and fls files.
- # Use fls file only if $recorder is set, and the fls file was generated
- # on this run.
-
- # N.B. A complication which we try and handle in determining
- # dependent files is that there may be aliasing of file names,
- # especially when characters are used in file and directory
- # names that are not pure 7-bit-ASCII. Here is a list of some
- # of the difficulties that do arise, between, on the one hand,
- # the filenames specified on latexmk's and the cwd found by
- # latexmk from the system, and, on the other hand, the filenames
- # and their components reported by *latex in the fls and log
- # files:
- # 1. Whether the separator of path components is / or \ in
- # MSWin.
- # 2. Whether the LFN or the SFN is provided.
- # 3. Whether the filenames include the cwd or whether they
- # are relative to the current directory.
- # 4. Under cygwin, whether the absolute filenames are
- # specified by UNIX or native MSWin conventions.
- # (With cygin, the programs used, including the Perl that
- # executes latexmk, can be any combination of native MSWin
- # programs and cygwin programs with their UNIX-like
- # behavior.)
- # 5. Whether UTF-8 or some other coding is used, and under
- # which circumstances: e.g., in calls to the OS to access
- # files, in files output by programs, on latexmk's command
- # line, on other programs' command lines, by the command
- # interpreterS.
- # 6. If UTF-8 is used, what kind of canonicalization is used,
- # if any. (This is a particular bugbear when files are
- # transferred between different OSes.)
- # 7. Whether the name of a file in the current directory is
- # reported as the simple filename or whether it is
- # preceeded by ".\" or "./".
- # 8. How is it determined whether a pathname is absolute or
- # relative? An absolute pathname in MSWin may start with
- # a drive letter and a colon, but under UNIX-type systems,
- # the colon is an ordinary character.
- # 9. Whether a filename reported in an fls or log file can be
- # used as is by perl to access a file, or on the command
- # line to invoke another program, and whether the use on a
- # command line depends on whether the command line is
- # executed by a CLI, and by which CLI. (E.g., cmd.exe,
- # v. sh v. tcsh, etc.)
- # 10. Whether such a filename for the filename on *latex's
- # file agrees with the one on the command line.
- # The above questions have arisen from actual experiences and
- # tests.
- #
- # In any case, when determining dependent files, we will try to
- # remove an initial directory string from filenames found in the
- # fls and log files, whenever it denotes the current
- # directory. The directory string may be an absolute pathname,
- # such as MiKTeX writes in both fls and log files, or it may be
- # simply "./" as given by TeXLive in its log file. There are
- # several reasons for removing a directory string when possible:
- #
- # 1. To avoid having multiple names referring to the same
- # file in the list of dependents.
- # 2. Because the name may be in a different coding. Thus
- # under MSWin 7, cmd.exe and perl (by default) work in an
- # "ANSI" coding with some code page, but the filenames
- # written by MiKTeX are UTF-8 coded (and if they are non-ASCII
- # can't be used for file-processing by Perl without some
- # trouble). This is a particular problem if the pathname
- # contains non-ASCII characters; the directory names may not
- # even be under the user's control, unlike typical filenames.
- # 3. When it comes to filenames that are then used in calls to
- # bibtex and makeindex, it is bad to use absolute pathnames
- # instead of clearly relative pathnames, because the default
- # security settings are to prohibit writing files to the
- # corresponding directories, which makes the calls to these
- # programs unnecessarily fail.
- #
- # In removing unnecessary directory-specifying strings, to
- # convert a filename to a simple specification relative to the
- # current directory, it will be important to preferentially use
- # a determination of the current directory from the file being
- # processed. In the fls file, there is normally a PWD line. In
- # the log file, if *latex is started with a filename instead
- # of a command-executing first line, then this can be determined
- # from the first few lines of the log file -- see parse_log.
- # This gives a more reliable determination of the relevant path
- # string; this is especially important in cases where there is a
- # mismatch of coding of the current directory, particularly
- # notable in the above-mentioned case of non-ASCII characters
- # under MSWin. Other inconsistencies happen when there is a
- # mixure of cygwin and native MSWin software. There can also be
- # inconsistencies between whether the separator of pathname
- # components is "/" or "\". So we will allow for this. The
- # necessary normalizations of filenames are handled by the
- # subroutines normalize_filename and normalize_clean_filename.
- #
- # I have not tried to handle the (currently rare) cases that the
- # OS is neither UNIX-like nor MSWin-like.
- #
- # Assumption: the list of generated files in %PHdest was already initialized earlier.
- # In principle, I should do it here, but useful possibilities (e.g.,
- # see pythontex-latexmk) for subroutine called to process a .tex to add items to
- # %PHdest. So initializing here is too late.
-
- # Rules should only be primary
- if ( $$Pcmd_type ne 'primary' ) {
- warn "\n$My_name: ==========$My_name: Probable BUG======= \n ",
- " rdb_set_latex_deps called to set files ",
- "for non-primary rule '$rule'\n\n";
- return;
- }
-
-#?? # We'll prune this by all files determined to be needed for source files.
-#?? my %unneeded_source = %$PHsource;
-
- # Parse fls and log files to find relevant filenames
- # Result in the following variables:
- local %dependents = (); # Maps files to status
- local @bbl_files = ();
- local %idx_files = (); # Maps idx_file to (ind_file, base)
- local %generated_log = (); # Lists generated files found in log file
- local %generated_fls = (); # Lists generated files found in fls file
- local %source_fls = (); # Lists source files found in fls file
- local %first_read_after_write = (); # Lists source files that are only read
- # after being written (so are not true
- # source files.
- local $primary_out = $$Pdest; # output file (dvi or pdf)
- local %conversions = (); # *latex-performed conversions.
- # Maps output file created and read by *latex
- # to source file of conversion.
- local @missing_subdirs = (); # Missing subdirectories in aux_dir
-
- local $pwd_latex = undef; # Cwd as reported in fls file by *latex
-
- local %created_rules = (); # Maps files to rules existing or created to
- # make them. Use to avoid misunderstood
- # dependencies when a package creates a
- # missing file during *latex compliation
- # instead of just allowing to be made later
- # by another rule.
-
- # The following are also returned by parsing routines, but are global,
- # to be used by caller:
- # $reference_changed, $bad_reference, $bad_character, $bad_citation, $mult_defined
-
- # Do I have my own eps-to-pdf conversion?
- my $epspdf_cusdep = 0;
- foreach (@cus_dep_list) {
- if ( /^eps pdf / ) { $epspdf_cusdep = 1; last; }
- }
-
- # Analyze fls file first. It tells us the working directory as seen by *latex
- # But we'll use the results later, so that they take priority over the findings
- # from the log file.
- local $fls_file_analyzed = 0;
- if ($recorder && test_gen_file($fls_name) ) {
- $fls_file_analyzed =
- (0== parse_fls( $fls_name, \%source_fls, \%generated_fls, \%first_read_after_write, \$pwd_latex ));
- if (! $fls_file_analyzed ) {
- warn "$My_name: fls file '$fls_name' appears to have been made but it couldn't be opened.\n";
- }
- }
-
- &parse_log;
-
- my $missing_dirs = 'none'; # Status of missing directories
- if (@missing_subdirs) {
- $missing_dirs = 'success';
- if ($allow_subdir_creation) {
- foreach my $dir ( uniqs( @missing_subdirs ) ) {
- if ( -d $dir ) {
- $missing_dirs = 'failure';
- warn "$My_name: ==== Directory '$dir' is said to be missing\n",
- " But it exists!\n";
- }
- elsif ( (-e $dir) && (!-d $dir) ) {
- $missing_dirs = 'failure';
- warn "$My_name: ==== Directory '$dir' is said to be missing\n",
- " But a non-directory file of this name exists!\n";
- }
- else {
- if (mkdir $dir) {
- warn "$My_name: Directory '$dir' created\n";
- }
- else {
- $missing_dirs = 'failure';
- warn "$My_name: Couldn't create directory '$dir'.\n",
- " System error: '$!'\n";
- }
- }
- }
- }
- else {
- $missing_dirs = 'not allowed';
- warn "$My_name: There are missing subdirectories, but their creation\n",
- " is not allowed. The subdirectories are:\n";
- foreach my $dir ( uniqs( @missing_subdirs ) ) {
- warn " '$dir'\n";
- }
- }
- }
- # Use results from fls file. (N.B. The hashes will be empty if the fls file
- # wasn't used/analyzed, so we don't need a test as to whether the fls file was
- # used.
- foreach (keys %source_fls) {
- if (! -e ) {
- # File is listed in .fls file as read, but doesn't exist now.
- # Therefore it is not a true source file, surely.
- # Sometimes this is caused by a bug (e.g., lualatex in TeXLive 2016,
- # 2017) when there is an incorrect line in .fls file. (This
- # would deserve a warning.)
- # But sometimes (e.g., with minted package), the file could be
- # created during a run, read, and then deleted.
- next;
- }
- $dependents{$_} = 4;
- if ( /\.bbl$/ ) { push @bbl_files, $_; }
- }
- foreach (keys %generated_fls) {
- if (! -e ) {
- # File is listed in .fls file as written, but doesn't exist now.
- # Therefore it is not a true externally visible generated file.
- # (Typically, e.g., with the minted package, it is a temporary
- # file created during a run and then deleted during the run.)
- next;
- }
- rdb_add_generated( $_ );
- if ( exists($dependents{$_}) ) {
- $dependents{$_} = 6;
- }
- }
-
- for my $conv (sort keys %conversions) {
- my $conv_source = $conversions{$conv};
- if ( $conv =~ /^(.*)-eps-converted-to\.pdf$/ ) {
- # Check all the conditions for pdflatex's conversion eps to pdf
- # are valid; if they are, treat the converted file as not a
- # source file.
- my $base = $1;
- if ( (-e $conv_source) && (-e $conv) && ( $conv_source eq "$base.eps" ) ) {
- # $conv isn't a real source of *latex
- rdb_remove_files( $rule, $conv );
- delete $dependents{$conv};
- if ($epspdf_cusdep) {
- $dependents{"$base.pdf"} = ((-e "$base.pdf") ? 4 : 0 );
- }
- }
- }
- }
-
-
-
-# ?? !! Should also deal with .run.xml file
-
- # Handle result on output file:
- # 1. Non-existent output file, which is because of no content.
- # This could either be because the source file has genuinely
- # no content, or because of a missing input file. Since a
- # missing input file might be correctable by a run of some
- # other program whose running is provoked AFTER a run of
- # *latex, we'll set a diagnostic and leave it to the
- # rdb_make to handle after all circular dependencies are
- # resolved.
- # 2. The output file might be of a different kind than expected
- # (i.e., dvi instead of pdf, or vv). This could
- # legitimately occur when the source file (or an invoked
- # package or class) sets \pdfoutput.
- $missing_dvi_pdf = '';
- if ($primary_out eq '') {
- warn "$My_name: For rule '$rule', no output was made\n";
- $missing_dvi_pdf = $$Pdest;
- }
- elsif ($primary_out ne normalize_filename($$Pdest) ) {
- my ($actual_base, $actual_path, $actual_ext) = fileparseA( $primary_out );
- my ($intended_base, $intended_path, $intended_ext) = fileparseA( $$Pdest );
- if ( $actual_ext ne $intended_ext ) {
- warn "$My_name: ===For rule '$rule', the extensions differ between the\n",
- " actual output file '$primary_out',\n",
- " and the expected output '$$Pdest'.\n";
- if ( ! exists $allowed_output_ext{$actual_ext} ) {
- warn " Actual output file has an extension '$actual_ext' that\n",
- " is not one I know about. I cannot handle this\n";
- }
- else {
- my $switch_error = switch_output( $rule, $actual_ext, $intended_ext );
- if ( $switch_error ) {
- warn " I could not accommodate the changed output extension\n",
- " (either because the configuration does not allow it\n",
- " or because there is a conflict with requested filetypes).\n";
- $failure = 1;
- $failure_msg = 'Could not handle change of output extension';
- }
- else {
- warn " Rule structure will be changed suitably.\n";
- }
- }
- }
- }
-
- IDX_FILE:
- foreach my $idx_file ( keys %idx_files ) {
- my ($ind_file, $ind_base) = @{$idx_files{$idx_file}};
- my $from_rule = "makeindex $idx_file";
- if ( ! rdb_rule_exists( $from_rule ) ){
- print "!!!===Creating rule '$from_rule': '$ind_file' from '$idx_file'\n"
- if ($diagnostics);
- rdb_create_rule( $from_rule, 'external', $makeindex, '', 1,
- $idx_file, $ind_file, $ind_base, 1, 0, 0, 1, [ "$ind_base.ilg" ] );
- print " ===Source file '$ind_file' for '$rule'\n"
- if ($diagnostics);
- rdb_ensure_file( $rule, $ind_file, $from_rule );
- }
- # Make sure the .ind file is treated as a detected source file;
- # otherwise if the log file has it under a different name (as
- # with MiKTeX which gives full directory information), there
- # will be problems with the clean-up of the rule concerning
- # no-longer-in-use source files:
- $dependents{$ind_file} = 4;
- if ( ! -e $ind_file ) {
- # Failure was non-existence of makable file
- # Leave failure issue to other rules.
- $failure = 0;
- }
- $created_rules{$ind_file} = $from_rule;
- }
-
- local %processed_aux_files = ();
- BBL_FILE:
- foreach my $bbl_file ( uniqs( @bbl_files ) ) {
- my ($bbl_base, $bbl_path, $bbl_ext) = fileparseA( $bbl_file );
- $bbl_base = $bbl_path.$bbl_base;
- my @new_bib_files = ();
- my @new_aux_files = ();
- my @new_bst_files = ();
- my @biber_source = ( "$bbl_base.bcf" );
- my $bib_program = 'bibtex';
- if ( test_gen_file( "$bbl_base.bcf" ) ) {
- $bib_program = 'biber';
- }
- my $from_rule = "$bib_program $bbl_base";
- print "======= Dealing with '$from_rule'\n" if ($diagnostics);
- # Don't change to use activation and deactivation here, rather than
- # creation and removal of rules. This is because rules are to be
- # created on the fly here with details corresponding to current. So
- # activating a previously inactive rule, which is out-of-date, may
- # cause trouble.
- if ($bib_program eq 'biber') {
- check_biber_log( $bbl_base, \@biber_source );
- # Remove OPPOSITE kind of bbl generation:
- rdb_remove_rule( "bibtex $bbl_base" );
- }
- else {
- parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files, \@new_bst_files );
- # Remove OPPOSITE kind of bbl generation:
- rdb_remove_rule( "biber $bbl_base" );
- }
- if ( ! rdb_rule_exists( $from_rule ) ){
- print " ===Creating rule '$from_rule'\n" if ($diagnostics);
- if ( $bib_program eq 'biber' ) {
- rdb_create_rule( $from_rule, 'external', $biber, '', 1,
- "$bbl_base.bcf", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ] );
- }
- else {
- rdb_create_rule( $from_rule, 'external', $bibtex, 'run_bibtex', 1,
- "$bbl_base.aux", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ] );
- }
- }
- $created_rules{$bbl_file} = $from_rule;
- local %old_sources = ();
- rdb_one_rule( $from_rule, sub { %old_sources = %$PHsource; } );
- my @new_sources = ( @new_bib_files, @new_aux_files, @new_bst_files );
- if ( $bib_program eq 'biber' ) {
- push @new_sources, @biber_source;
- }
- foreach my $source ( @new_sources ) {
- print " ===Source file '$source' for '$from_rule'\n"
- if ($diagnostics);
- rdb_ensure_file( $from_rule, $source );
- delete $old_sources{$source};
- }
- foreach my $source ( @new_aux_files ) {
- $processed_aux_files{$source} = 1;
- }
- if ($diagnostics) {
- foreach ( keys %old_sources ) {
- print "Removing no-longer-needed dependent '$_' from rule '$from_rule'\n";
- }
- }
- rdb_remove_files( $from_rule, keys %old_sources );
- print " ===Source file '$bbl_file' for '$rule'\n"
- if ($diagnostics);
- rdb_ensure_file( $rule, $bbl_file, $from_rule );
- if ( ! -e $bbl_file ) {
- # Failure was non-existence of makable file
- # Leave failure issue to other rules.
- $failure = 0;
- }
- }
-
- if ( ($#aux_hooks > -1) && ! exists $processed_aux_files{$aux_main} ) {
- my @new_bib_files = ();
- my @new_aux_files = ();
- my @new_bst_files = ();
- parse_aux( $aux_main, \@new_bib_files, \@new_aux_files, \@new_bst_files );
- foreach my $source ( @new_aux_files ) {
- $processed_aux_files{$source} = 1;
- }
- }
-
-NEW_SOURCE:
- foreach my $new_source (keys %dependents) {
- print " ===Source file for rule '$rule': '$new_source'\n"
- if ($diagnostics);
- if ( exists $first_read_after_write{$new_source} ) {
- if ( dep_at_start($new_source) ) {
- #warn "--- READ ONLY AFTER WRITE OF '$new_source'\n";
- $dependents{$new_source} = 7;
- }
- else {
- #warn "--- READ ONLY AFTER CREATE OF '$new_source'\n";
- $dependents{$new_source} = 6;
- }
- }
- if ( ($dependents{$new_source} == 5)
- || ($dependents{$new_source} == 6)
- ) {
- # (a) File was detected in "No file..." line in log file.
- # Typically file was searched for early in run of
- # latex/pdflatex, was not found, and then was written
- # later in run.
- # or (b) File was written during run.
- # In both cases, if file doesn't already exist in database, we
- # don't know its previous status. Therefore we tell
- # rdb_ensure_file that if it needs to add the file to its
- # database, then the previous version of the file should be
- # treated as non-existent, to ensure another run is forced.
- rdb_ensure_file( $rule, $new_source, undef, 1 );
- }
- elsif ( $dependents{$new_source} == 7 ) {
- # File was result of conversion by *latex.
- my $cnv_source = $conversions{$new_source};
- rdb_ensure_file( $rule, $new_source );
-# if ($cnv_source && ($cnv_source !~ /\"/ ) ) {
- if ($cnv_source ) {
- # Conversion from $cnv_source to $new_source
- # implies that effectively $cnv_source is a source
- # of the *latex run.
- rdb_ensure_file( $rule, $cnv_source );
- }
- # Flag that changes of the generated file during a run
- # do not require a rerun:
- rdb_one_file( $new_source, sub{ $$Pcorrect_after_primary = 1; } );
- }
- else {
- # But we don't need special precautions for ordinary user files
- # (or for files that are generated outside of latex/pdflatex).
- rdb_ensure_file( $rule, $new_source );
- }
- if ( ($dependents{$new_source} == 6)
- || ($dependents{$new_source} == 7)
- ) {
- rdb_add_generated($new_source);
- }
- }
-
- foreach my $Psub (@latex_file_hooks) {
- &$Psub;
- }
-
- # Some packages (e.g., bibtopic) generate a dummy error-message-providing
- # bbl file when a bbl file does not exist. Then the fls and log files
- # show the bbl file as created by the primary run and hence as a
- # generated file. Since we now have a rule to create a real bbl file,
- # the information in the fls and log files no longer represents a
- # correct dependency, so the bbl file is to be removed from the
- # generated files.
- foreach (keys %created_rules) { rdb_remove_generated( $_ ); }
-
- my @more_sources = &rdb_set_dependents( $rule );
- my $num_new = $#more_sources + 1;
- foreach (@more_sources) {
- $dependents{$_} = 4;
- if ( ! -e $_ ) {
- # Failure was non-existence of makable file
- # Leave failure issue to other rules.
- $failure = 0;
- $$Pchanged = 1; # New files can be made. Ignore error.
- }
- }
- if ($diagnostics) {
- if ($num_new > 0 ) {
- print "$num_new new source files for rule '$rule':\n";
- foreach (@more_sources) { print " '$_'\n"; }
- }
- else {
- print "No new source files for rule '$rule':\n";
- }
- my @first_read_after_write = sort keys %first_read_after_write;
- if ($#first_read_after_write >= 0) {
- print "The following files were only read after being written:\n";
- foreach (@first_read_after_write) {
- print " '$_'\n";
- }
- }
- }
- my @files_not_needed = ();
- foreach (keys %$PHsource) {
- if ( ! exists $dependents{$_} ) {
- print "Removing no-longer-needed dependent '$_' from rule '$rule'\n"
- if $diagnostics;
- push @files_not_needed, $_;
- }
- }
- rdb_remove_files( $rule, @files_not_needed );
-
- return ($missing_dirs, [@missing_subdirs] );
-
-} # END rdb_set_latex_deps
-
-#************************************************************
-
-sub switch_output {
- # Usage: switch_output( primary_rule, actual_ext, intended_ext )
- # Rearrange rules to deal with changed extension of output file of
- # the specified primary rule (one of *latex).
- # Return 0 on success, non-zero error code on failure
-
- my ( $rule, $actual_ext, $intended_ext ) = @_;
- if ( $actual_ext eq $intended_ext ) { return 0; }
- if ( ! $can_switch ) { return 1; }
-
- if (! defined $possible_primaries{$rule} ) {
- warn "$My_name: BUG: subroutine switch_output called with non-primary rule '$rule'\n";
- return 1;
- }
-
- rdb_deactivate_derequest( 'dvipdf', 'pspdf', 'xdvipdfmx', keys %possible_primaries );
-
- rdb_activate_request( $rule );
-
- if ( $actual_ext eq '.dvi' ) {
- rdb_activate_request( 'dvipdf' );
- $input_extensions{$rule} = $standard_input_extensions{latex};
- }
- elsif ( $actual_ext eq '.xdv' ) {
- rdb_activate_request( 'xdvipdfmx' );
- $input_extensions{$rule} = $standard_input_extensions{xelatex};
- }
- else {
- $input_extensions{$rule} = $standard_input_extensions{pdflatex};
- }
-
- my $old_dest = $$Pdest;
- my $new_dest = $$Pdest;
- $new_dest =~ s/$intended_ext$/$actual_ext/;
- # Compensate for MiKTeX's behavior: dvi and pdf are put in out_dir, but xdv is put in aux_dir:
- if ( ($actual_ext eq '.xdv') && ($out_dir ne $aux_dir) ){ $new_dest =~ s/^$out_dir1/$aux_dir1/; }
- if ( ($intended_ext eq '.xdv') && ($out_dir ne $aux_dir) ){ $new_dest =~ s/^$aux_dir1/$out_dir1/; }
-
- rdb_change_dest( $new_dest );
-
- # Some fixes to avoid spurious error conditions:
- $switched_primary_output = 1;
- if (-e $$Pdest) {
- $missing_dvi_pdf = '';
- if ($$Plast_result == 1 ) { $$Plast_result = 0; }
- }
- else { $missing_dvi_pdf = $$Pdest; }
-
- return 0;
-} #END switch_output
-
-#************************************************************
-
-sub test_gen_file {
- # Usage: test_gen_file( filename )
- # Tests whether the file was generated during a run of *latex.
- # Assumes context for primary rule.
- # Two kinds of test are used:
- # a. From %generated_log, which works after the log file has been parsed,
- # but only for certain files and for those TeX engines (not MiKTeX)
- # that put \openout lines in log file.
- # b. By the file existing and being at least as new as the system
- # time at the start of the run. But we allow for a measured
- # offset between filetime and system time, which could be
- # nonzero if the file is on a different, remote system than the
- # one running latexmk. We must also allow a threshold in the
- # comparisons of filetimes to allow for the inaccuracy of the
- # offset measurement.
- my $file = shift;
- return exists $generated_log{$file}
- || ( -e $file && ( get_mtime( $file ) >= $$Prun_time + $filetime_offset - $filetime_causality_threshold));
-}
-
-#************************************************************
-
-sub dep_at_start {
- # Usage: dep_at_start( filename )
- # Tests whether the file was source file and existed at start of run.
- # Assumes context for primary rule.
- my $time = undef;
- rdb_one_file( shift, sub{ $time = $$Ptime; } );
- return (defined $time) && ($time != 0);
-}
-
-#************************************************************
-
-sub rdb_find_new_files {
- # Call: rdb_find_new_files
- # Assumes rule context for primary rule.
- # Deal with files which were missing and for which a method
- # of finding them has become available:
- # (a) A newly available source file for a custom dependency.
- # (b) When there was no extension, a file with appropriate
- # extension
- # (c) When there was no extension, and a newly available source
- # file for a custom dependency can make it.
-
- my %new_includes = ();
-
-MISSING_FILE:
- foreach my $missing ( keys %$PHsource ) {
- next if ( $$PHsource{$missing} != 0 );
- my ($base, $path, $ext) = fileparseA( $missing );
- $ext =~ s/^\.//;
- if ( -e "$missing.tex" ) {
- $new_includes{"$missing.tex"} = 1;
- }
- elsif ( -e $missing ) {
- $new_includes{$missing} = 1;
- }
- elsif ( $ext ne "" ) {
- foreach my $dep (@cus_dep_list){
- my ($fromext,$toext) = split('\s+',$dep);
- if ( ( "$ext" eq "$toext" )
- && ( -f "$path$base.$fromext" )
- ) {
- # Source file for the missing file exists
- # So we have a real include file, and it will be made
- # next time by rdb_set_dependents
- $new_includes{$missing} = 1;
- }
- else {
- # no point testing the $toext if the file doesn't exist.
- }
- next MISSING_FILE;
- }
- }
- else {
- # $_ doesn't exist, $_.tex doesn't exist,
- # and $_ doesn't have an extension
- foreach my $dep (@cus_dep_list){
- my ($fromext,$toext) = split('\s+',$dep);
- if ( -f "$path$base.$fromext" ) {
- # Source file for the missing file exists
- # So we have a real include file, and it will be made
- # next time by &rdb__dependents
- $new_includes{"$path$base.$toext"} = 1;
-# next MISSING_FILE;
- }
- if ( -f "$path$base.$toext" ) {
- # We've found the extension for the missing file,
- # and the file exists
- $new_includes{"$path$base.$toext"} = 1;
-# next MISSING_FILE;
- }
- }
- }
- } # end MISSING_FILES
-
- # Sometimes bad line-breaks in log file (etc) create the
- # impression of a missing file e.g., ./file, but with an incorrect
- # extension. The above tests find the file with an extension,
- # e.g., ./file.tex, but it is already in the list. So now I will
- # remove files in the new_include list that are already in the
- # include list. Also handle aliasing of file.tex and ./file.tex.
- # For example, I once found:
-# (./qcdbook.aux (./to-do.aux) (./ideas.aux) (./intro.aux) (./why.aux) (./basics
-#.aux) (./classics.aux)
-
- my $found = 0;
- foreach my $file (keys %new_includes) {
-# if ( $file =~ /\"/ ) {next; }
- my $stripped = $file;
- $stripped =~ s{^\./}{};
- if ( exists $PHsource{$file} ) {
- delete $new_includes{$file};
- }
- else {
- $found ++;
- rdb_ensure_file( $rule, $file );
- }
- }
-
- if ( $diagnostics && ( $found > 0 ) ) {
- warn "$My_name: Detected previously missing files:\n";
- foreach ( sort keys %new_includes ) {
- warn " '$_'\n";
- }
- }
- return $found;
-} # END rdb_find_new_files
-
-#************************************************************
-
-sub rdb_set_dependents {
- # Call rdb_set_dependents( rules ...)
- # Returns array (sorted), of new source files.
- local @new_sources = ();
- local @deletions = ();
-
-# Shouldn't recurse. The definite rules to be examined are given.
- rdb_for_some( [@_], 0, \&rdb_one_dep );
-# OLD rdb_recurse( [@_], 0, \&rdb_one_dep );
- foreach (@deletions) {
- my ($rule, $file) = @$_;
- rdb_remove_files( $rule, $file );
- }
- &rdb_make_links;
- return uniqs( @new_sources );
-} #END rdb_set_dependents
-
-#************************************************************
-
-sub rdb_find_source_file {
- # Helper for searching dependencies in all paths inside the TEXINPUTS
- # environment variable.
- my $test = "$_[0].$_[1]";
- if ( -e $test ) {
- return $_[0];
- }
- if ( exists $ENV{TEXINPUTS} ) {
- foreach my $searchpath (split $search_path_separator, $ENV{TEXINPUTS}) {
- my $file = File::Spec->catfile($searchpath,$_[0]);
- my $test = "$file.$_[1]";
- if ( -e $test ) {
- return $file;
- }
- }
- }
- return "$_[0]";
-}
-
-#************************************************************
-
-sub rdb_one_dep {
- # Helper for finding dependencies. One case, $rule and $file given
- # Assume file (and rule) context for DESTINATION file.
-
- # Only look for dependency if $rule is primary rule (i.e., latex
- # or pdflatex) or is a custom dependency:
- if ( (! exists $possible_primaries{$rule}) && ($rule !~ /^cusdep/) ) {
- return;
- }
-#print "=============ONE_DEP: '$rule' '$file'\n";
- local $new_dest = $file;
- my ($base_name, $path, $toext) = fileparseA( $new_dest );
- $base_name = $path.$base_name;
- $toext =~ s/^\.//;
- my $Pinput_extensions = $input_extensions{$rule};
-DEP:
- foreach my $dep ( @cus_dep_list ) {
- my ($fromext,$proptoext,$must,$func_name) = split('\s+',$dep);
- if ( $toext eq $proptoext ) {
- $base_name = rdb_find_source_file($base_name, $fromext);
- my $source = "$base_name.$fromext";
- # Found match of rule
- if ($diagnostics) {
- print "Found cusdep: $source to make $rule:$new_dest ====\n";
- }
- if ( -e $source ) {
- $$Pfrom_rule = "cusdep $fromext $toext $base_name";
- my $new_new_dest = "$base_name.$toext";
- if ($new_new_dest ne $new_dest) {
- rdb_ensure_file( $rule, $new_new_dest );
- $new_dest = $new_new_dest;
- }
- local @PAnew_cmd = ( 'do_cusdep', $func_name );
- if ( !-e $new_dest ) {
- push @new_sources, $new_dest;
- }
- if (! rdb_rule_exists( $$Pfrom_rule ) ) {
- print "$My_name: === Creating rule '$$Pfrom_rule'\n" if $diagnostics;
- rdb_create_rule( $$Pfrom_rule, 'cusdep', '', \@PAnew_cmd, 3,
- $source, $new_dest, $base_name, 0 );
- }
- return;
- }
- else {
- # Source file does not exist
- if ( !$force_mode && ( $must != 0 ) ) {
- # But it is required that the source exist ($must !=0)
- $failure = 1;
- $failure_msg = "File '$base_name.$fromext' does not exist ".
- "to build '$base_name.$toext'";
- return;
- }
- elsif ( $$Pfrom_rule =~ /^cusdep $fromext $toext / ) {
- # Source file does not exist, destination has the rule set.
- # So turn the from_rule off
- $$Pfrom_rule = '';
- }
- else {
- }
- }
- }
- elsif ( ($toext eq '')
- && (! -e $file )
- && (! -e "$base_name.$proptoext" )
- && exists $$Pinput_extensions{$proptoext}
- ) {
- # Empty extension and non-existent destination
- # This normally results from \includegraphics{A}
- # without graphics extension for file, when file does
- # not exist. So we will try to find something to make it.
- $base_name = rdb_find_source_file($base_name, $fromext);
- my $source = "$base_name.$fromext";
- if ( -e $source ) {
- $new_dest = "$base_name.$proptoext";
- my $from_rule = "cusdep $fromext $proptoext $base_name";
- push @new_sources, $new_dest;
- print "Ensuring rule for '$from_rule', to make '$new_dest'\n"
- if $diagnostics > -1;
- local @PAnew_cmd = ( 'do_cusdep', $func_name );
- if (! rdb_rule_exists( $from_rule ) ) {
- print "$My_name: === Creating rule '$$Pfrom_rule'\n" if $diagnostics;
- rdb_create_rule( $from_rule, 'cusdep', '', \@PAnew_cmd, 3,
- $source, $new_dest, $base_name, 0 );
- }
- rdb_ensure_file( $rule, $new_dest, $from_rule );
- # We've now got a spurious file in our rule. But don't mess
- # with deleting an item we are in the middle of!
- push @deletions, [$rule, $file];
- return;
- }
- } # End of Rule found
- } # End DEP
- if ( (! -e $file) && $use_make_for_missing_files ) {
- # Try to make the missing file
- #Set character to surround filenames in commands:
- my $q = $quote_filenames ? '"' : '';
- if ( $toext ne '' ) {
- print "$My_name: '$rule': source file '$file' doesn't exist. I'll try making it...\n";
- &Run_subst( "$make $q$file$q" );
- if ( -e $file ) {
- return;
- }
- }
- else {
- print "$My_name: '$rule': source '$file' doesn't exist.\n",
- " I'll try making it with allowed extensions \n";
- foreach my $try_ext ( keys %$Pinput_extensions ) {
- my $new_dest = "$file.$try_ext";
- &Run_subst( "$make $q$new_dest$q" );
- if ( -e $new_dest ) {
- print "SUCCESS in making '$new_dest'\n";
- # Put file in rule, without a from_rule, but
- # set its state as non-existent, to correspond
- # to file's state before the file was made
- # This ensures a rerun of *latex is provoked.
- rdb_ensure_file( $rule, $new_dest, undef, 1 );
- push @new_sources, $new_dest;
- push @deletions, [$rule, $file];
- # Flag need for a new run of *latex despite
- # the error due to a missing file.
- $$Pout_of_date_user = 1;
- return;
- }
- }
- }
- }
-} #END rdb_one_dep
-
-#************************************************************
-
-sub rdb_list {
- # Call: rdb_list()
- # List rules and their source files
- print "===Rules:\n";
- local $count_rules = 0;
- my @accessible_all = &rdb_accessible;
- rdb_for_some(
- \@accessible_all,
- sub{ $count_rules++;
- print "Rule '$rule' depends on:\n";
- },
- sub{ print " '$file'\n"; },
- sub{ print " and generates:\n";
- foreach (keys %$PHdest) { print " '$_'\n"; }
-# print " default_extra_generated:\n";
-# foreach (@$PA_extra_gen) { print " '$_'\n"; }
- },
- );
- if ($count_rules <= 0) {
- print " ---No rules defined\n";
- }
-} #END rdb_list
-
-#************************************************************
-
-sub deps_list {
- # Call: deps_list(fh)
- # List dependent files to file open on fh
- my $fh = $_[0];
- print $fh "#===Dependents, and related info, for $filename:\n";
- my @dest_exts = ();
- if ($pdf_mode) {push @dest_exts, '.pdf';}
- if ($dvi_mode) {push @dest_exts, '.dvi';}
- if ($postscript_mode) {push @dest_exts, '.ps';}
- my %source = ( $texfile_name => 1 );
- my @generated = ();
- my @accessible_all = &rdb_accessible;
- rdb_for_some(
- \@accessible_all,
- sub{ push @generated, keys %$PHdest; },
- sub{ $source{$file} = 1; }
- );
- foreach (keys %generated_exts_all) {
- (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/${aux_dir1}${root_filename}/;
- push @generated, $name;
- }
- show_array( "Generated:", @generated ) if $diagnostics;
- foreach (@generated) {
- delete $source{$_};
- }
- show_array( "Sources:", keys %source ) if $diagnostics;
- foreach my $ext (@dest_exts) {
- # Don't insert name of deps file in targets.
- # The previous behavior of inserting the name of the deps file
- # matched the method recommended by GNU make for automatically
- # generated prerequisites -- see Sec. "Generating Prerequisites
- # Automatically" of GNU make manual (v. 4.2). But this can
- # cause problems in complicated cases, and as far as I can see,
- # it doesn't actually help, despite the reasoning given.
- # The only purpose of the deps file is to to determine source
- # files for a particular rule. The files whose changes make the
- # deps file out-of-date are the same as those that make the real
- # target file (e.g., .pdf) out-of-date. So the GNU method seems
- # completely unnecessary.
- print $fh "${out_dir1}${root_filename}${ext} :";
- foreach (sort keys %source) {
- print $fh "\\\n $_";
- }
- print $fh "\n";
- }
- print $fh "#===End dependents for $filename:\n";
- if ($dependents_phony) {
- print $fh "\n#===Phony rules for $filename:\n\n";
- foreach (sort keys %source) {
- print $fh "$_ :\n\n";
- }
- print $fh "#===End phony rules for $filename:\n";
- }
-} #END deps_list
-
-#************************************************************
-
-sub rdb_show {
- # Call: rdb_show()
- # Displays contents of rule data base.
- # Side effect: Exercises access routines!
- print "===Rules:\n";
- local $count_rules = 0;
- rdb_for_actives(
- sub{ $count_rules++;
- my @int_cmd = @$PAint_cmd;
- foreach (@int_cmd) {
- if ( !defined($_) ) { $_='undef';}
- }
- print " [$rule]: '$$Pcmd_type' '$$Pext_cmd' '@int_cmd' $$Ptest_kind ",
- "'$$Psource' '$$Pdest' '$$Pbase' $$Pout_of_date $$Pout_of_date_user\n"; },
- sub{ print " '$file': $$Ptime $$Psize $$Pmd5 '$$Pfrom_rule'\n"; }
- );
- if ($count_rules <= 0) {
- print " ---No rules defined\n";
- }
-} #END rdb_show
-
-#************************************************************
-
-sub rdb_target_array {
- # Returns array of all rules implicated by %target_rules and %target_files
- my %rules = &rdb_target_hash;
- return keys %rules;
-} # End rdb_target_array
-
-#************************************************************
-
-sub rdb_target_hash {
- # Returns hash mapping to 1 all rules implicated by %target_rules and %target_files
- my %rules = %target_rules;
- foreach (keys %target_files) {
- if (exists $from_rules{$_}) { $rules{$from_rules{$_}} = 1; }
- }
- return %rules;
-} # End rdb_target_hash
-
-#************************************************************
-
-sub rdb_accessible {
- # Call: &rdb_accessible
- # Returns array of rules accessible from target rules and rules to make target files
-
- local %accessible_rules = &rdb_target_hash;
- rdb_recurse( [keys %accessible_rules], sub{ $accessible_rules{$rule} = 1; } );
- return keys %accessible_rules;
-} #END rdb_accessible
-
-#************************************************************
-#************************************************************
-#************************************************************
-
-sub rdb_make {
- # Call: &rdb_make
- # Makes the targets and prerequisites.
- # Leaves one-time rules to last.
- # Does appropriate repeated makes to resolve dependency loops
-
- # Returns 0 on success, nonzero on failure.
-
- # General method: Find all accessible rules, then repeatedly make
- # them until all accessible rules are up-to-date and the source
- # files are unchanged between runs. On termination, all
- # accessible rules have stable source files.
- #
- # One-time rules are view and print rules that should not be
- # repeated in an algorithm that repeats rules until the source
- # files are stable. It is the calling routine's responsibility to
- # arrange to call them, or to use them here with caution.
- #
- # Note that an update-viewer rule need not be considered
- # one-time. It can be legitimately applied everytime the viewed
- # file changes.
- #
- # Note also that the criterion of stability is to be applied to
- # source files, not to output files. Repeated application of a
- # rule to IDENTICALLY CONSTANT source files may produce different
- # output files. This may be for a trivial reason (e.g., the
- # output file contains a time stamp, as in the header comments for
- # a typical postscript file), or for a non-trivial reason (e.g., a
- # stochastic algorithm, as in abcm2ps).
- #
- # This caused me some actual trouble. In general, circular
- # dependencies produce non-termination, and the the following
- # situation is an example of a generic situation where certain
- # rules must be obeyed in order to obtain proper results:
- # 1. A/the latex source file contains specifications for
- # certain postprocessing operations. Standard *latex
- # already has this, for indexing and bibliography.
- # 2. In the case in point that caused me trouble, the
- # specification was for musical tunes that were contained
- # in external source files not directly input to
- # *latex. But in the original version, there was a
- # style file (abc.sty) that caused latex itself to call
- # abcm2ps to make .eps files for each tune that were to be
- # read in on the next run of latex.
- # 3. Thus the specification can cause a non-terminating loop
- # for latexmk, because the output files of abcm2ps changed
- # even with identical input.
- # 4. The solution was to
- # a. Use a style file abc_get.sty that simply wrote the
- # specification on the tunes to the .aux file in a
- # completely deterministic fashion.
- # b. Instead of latex, use a script abclatex.pl that runs
- # latex and then extracts the abc contents for each tune
- # from the source abc file. This is also
- # deterministic.
- # c. Use a cusdep rule in latexmk to convert the tune abc
- # files to eps. This is non-deterministic, but only
- # gets called when the (deterministic) source file
- # changes.
- # This solves the problem. Latexmk works. Also, it is no
- # longer necessary to enable write18 in latex, and multiple
- # unnecessary runs of abcm2ps are no longer used.
- #
- # The order of testing and applying rules is chosen by the
- # following heuristics:
- # 1. Both latex and pdflatex may be used, but the resulting
- # aux files etc may not be completely identical. Define
- # latex and pdflatex as primary rules. Apply the general
- # method of repeated circulating through all rules until
- # the source files are stable for each primary rule
- # separately. Naturally the rules are all accessible
- # rules, but excluding primary rules except for the current
- # primary.
- # 2. Assume that the primary rules are relatively
- # time-consuming, so that unnecessary passes through them
- # to check stability of the source files should be avoided.
- # 3. Assume that although circular dependencies exist, the
- # rules can nevertheless be thought of as basically
- # non-circular, and that many rules are strictly or
- # normally non-circular. In particular cusdep rules are
- # typically non-circular (e.g., fig2eps), as are normal
- # output processing rules like dvi2ps.
- # 4. The order for the non-circular approximation is
- # determined by applying the assumption that an output file
- # from one rule that is read in for an earlier stage is
- # unchanged.
- # HOWEVER, at a first attempt, the ordering is not needed. It
- # only gives an optimization
- # 5. (Note that these assumptions could be violated, e.g., if
- # $dvips is arranged not only to do the basic dvips
- # command, but also to extract information from the ps file
- # and feed it back to an input file for *latex.)
- # 6. Nevertheless, the overall algorithm should allow
- # circularities. Then the general criterion of stability
- # of source files covers the general case, and also
- # robustly handles the case that the USER changes source
- # files during a run. This is particularly important in
- # -pvc mode, given that a full make on a large document can
- # be quite lengthy in time, and moreover that a user
- # naturally wishes to make corrections in response to
- # errors, particularly latex errors, and have them apply
- # right away.
- # This leads to the following approach:
- # 1. Classify accessible rules as: primary, pre-primary
- # (typically cusdep, bibtex, makeindex, etc), post-primary
- # (typically dvips, etc), and one-time
- # 2. Then stratify the rules into an order of application that
- # corresponds to the basic feedforward structure, with the
- # exclusion of one-time rules.
- # 3. Always require that one-time rules are among the
- # explicitly requested rules, i.e., the last to be applied,
- # were we to apply them. Anything else would not match the
- # idea of a one-time rule.
- # 4. Then work as follows:
- # a. Loop over primaries
- # b. For each primary, examine each pre-primary rule and
- # apply if needed, then the primary rule and then each
- # post-primary rule. The ordering of the pre-primary
- # and post-primary rules was found in step 2.
- # BUT applying the ordering is not essential
- # c. Any time that a pre-primary or primary rule is
- # applied, loop back to the beginning of step b. This
- # ensures that bibtex etc are applied before rerunning
- # *latex, and also covers changing source files, and
- # gives priority to quick pre-primary rules for changing
- # source files against slow reruns of latex.
- # d. Then apply post-primary rules in order, but not
- # looping back after each rule. This non-looping back
- # is because the rules are normally feed-forward only.
- # BUT applying the ordering is not essential
- # e. But after completing post-primary rules do loop back
- # to b if any rules were applied. This covers exotic
- # circular dependence (and as a byproduct, changing
- # source files).
- # f. On each case of looping back to b, re-evaluate the
- # dependence setup to allow for the effect of changing
- # source files.
- #
-
-
- &rdb_set_rule_net;
-
- local %pass = ();
- local $failure = 0; # General accumulated error flag
- local $missing_dvi_pdf = ''; # Did primary run fail to make its output file?
- local $runs = 0;
- local $too_many_passes = 0;
- local %rules_applied = ();
- local $switched_primary_output = 0;
- my $retry_msg = 0; # Did I earlier say I was going to attempt
- # another pass after a failure?
- rdb_for_some ( [keys %rule_db],
- sub{ $pass{$rule} = 0;
- foreach (keys %$PHsource_rules) {
- $$PHsource_rules{$_} = 0;
- }
- }
- );
- PASS:
- while (1==1) {
- # Exit condition at end of body of loop.
- $runs = 0;
- $switched_primary_output = 0;
- my $previous_failure = $failure;
- $failure = 0;
- local $newrule_nofile = 0; # Flags whether rule created for
- # making currently non-existent file, which
- # could become a needed source file for a run
- # and therefore undo an error condition
- foreach my $rule (keys %rule_db) {
- # Update %pass in case new rules have been created
- if (! exists $pass{$rule} ) { $pass{$rule} = 0; }
- }
- if ($diagnostics) {
- print "Make: doing pre_primary and primary...\n";
- }
- # Do the primary run if it is needed. On return $runs == 0
- # signals that nothing was run (and hence no output
- # files changed), either because no input files
- # changed and no run was needed, or because the
- # number of passes through the rule exceeded the
- # limit. In the second case $too_many_runs is set.
- rdb_for_some( [@pre_primary, $current_primary], \&rdb_make1 );
- if ($switched_primary_output) {
- print "=========SWITCH OF OUTPUT WAS DONE.\n";
- next PASS;
- }
- if ( ($runs > 0) && ! $too_many_passes ) {
- $retry_msg = 0;
- if ( $force_mode || (! $failure) || $switched_primary_output ) {
- next PASS;
- }
- # Get here on failure, without being in force_mode
- if ( $newrule_nofile ) {
- $retry_msg = 1;
- print "$My_name: Error on run, but found possibility to ",
- "make new source files\n";
- next PASS;
- }
- else { last PASS; }
- }
- if ($runs == 0) {
- # $failure not set on this pass, so use value from previous pass:
- $failure = $previous_failure;
- if ($retry_msg) {
- print "But in fact no new files made\n";
- }
- if ($failure && !$force_mode ) { last PASS; }
- }
- if ( $missing_dvi_pdf ) {
- # No output from primary, after completing circular dependence
- warn "Failure to make '$missing_dvi_pdf'\n";
- $failure = 1;
- last PASS;
- }
- if ($diagnostics) {
- print "Make: doing post_primary...\n";
- }
- rdb_for_some( [@post_primary], \&rdb_make1 );
- if ( ($runs == 0) || $too_many_passes ) {
- # If $too_many_passes is set, it should also be that
- # $runs == 0; but for safety, I also checked
- # $too_many_passes.
- last PASS;
- }
- }
- continue {
- # Re-evaluate rule classification and accessibility,
- # but do not change primaries.
- # Problem is that %current_primaries gets altered
- &rdb_set_rule_net;
- } #End PASS
-
- rdb_for_some( [@unusual_one_time], \&rdb_make1 );
- rdb_write( $fdb_name );
-
- if ($#primary_warning_summary > -1) {
- # N.B. $mult_defined, $bad_reference, $bad_character, $bad_citation also available here.
- show_array( "$My_name: Summary of warnings from last run of *latex:",
- @primary_warning_summary );
- }
- if (! $silent) {
- if ($failure && $force_mode) {
- print "$My_name: Errors, in force_mode: so I tried finishing targets\n";
- }
- elsif ($failure) {
- print "$My_name: Errors, so I did not complete making targets\n";
- }
- else {
-# local @dests = ( keys %current_primaries, @pre_primary, @post_primary, @unusual_one_time );
- local @rules = ( keys %current_primaries, @post_primary, @unusual_one_time );
- local @dests = ();
- rdb_for_some( [@rules], sub{ push @dests, $$Pdest if ($$Pdest); } );
- print "$My_name: All targets (@dests) are up-to-date\n";
- }
- }
- rdb_for_some ( [keys %rule_db],
- sub{
- foreach my $s_rule (keys %$PHsource_rules) {
- $$PHsource_rules{$s_rule} = $pass{$s_rule};
- }
- }
- );
- return $failure;
-} #END rdb_make
-
-#-------------------
-
-sub rdb_show_rule_errors {
- local @errors = ();
- local @warnings = ();
- rdb_for_actives(
- sub{
- if ($$Plast_message ne '') {
- if ($$Plast_result == 200) {
- push @warnings, "$rule: $$Plast_message";
- }
- else {
- push @errors, "$rule: $$Plast_message";
- }
- }
- elsif ($$Plast_result == 1) {
- push @errors, "$rule: failed to create output file";
- }
- elsif ($$Plast_result == 2) {
- push @errors, "$rule: gave an error";
- }
- elsif ($$Prun_time == 0) {
- # This can have innocuous causes. So don't report
- }
- }
- );
- if ($#warnings > -1) {
- warn "Collected warning summary (may duplicate other messages):\n";
- foreach (@warnings){
- warn " $_\n";
- }
- }
- if ($#errors > -1) {
- warn "Collected error summary (may duplicate other messages):\n";
- foreach (@errors){
- warn " $_\n";
- }
- }
- return $#errors+1;
-}
-
-#-------------------
-
-sub rdb_make1 {
- # Call: rdb_make1
- # Helper routine for rdb_make.
- # Carries out make at level of given rule (all data available).
- # Assumes contexts for recursion, make, and rule, and
- # assumes that source files for the rule are to be considered
- # up-to-date.
- if ($diagnostics) { print " Make1 $rule\n"; }
- if ($failure & ! $force_mode) {return;}
- if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
-
- # Special fix up for bibtex:
- my $bibtex_not_run = -1; # Flags status as to whether this is a
- # bibtex rule and if it is, whether out-of-date condition is to
- # be ignored.
- # -1 => not a bibtex rule
- # 0 => no special treatment
- # 1 => don't run bibtex because of non-existent bibfiles
- # (and setting to do this test)
- # 2 => don't run bibtex because of setting
- my @missing_bib_files = ();
- if ( $rule =~ /^(bibtex|biber)/ ) {
- $bibtex_not_run = 0;
- if ($bibtex_use == 0) {
- $bibtex_not_run = 2;
- }
- elsif ( ($bibtex_use == 1) || ($bibtex_use == 1.5) ) {
- foreach ( keys %$PHsource ) {
- if ( ( /\.bib$/ ) && (! -e $_) ) {
- push @missing_bib_files, $_;
- $bibtex_not_run = 1;
- }
- }
- }
- }
-
- if ( ($$Prun_time == 0) && exists($possible_primaries{$rule}) ) {
- push @rules_never_run, $rule;
- $$Pout_of_date = 1;
- $$Plast_result = -1;
- }
- else {
- if ( $$Pdest && (! -e $$Pdest) ) {
- # With a non-existent destination, if we haven't made any passes
- # through a rule, rerunning the rule is good, because the file
- # may fail to exist because of being deleted by the user (for ex.)
- # rather than because of a failure on a previous run.
- # (We could do better with a flag in fdb file.)
- # But after the first pass, the situation is different.
- # For a primary rule *latex, the lack of a destination file
- # could result from there being zero content due to a missing
- # essential input file. The input file could be generated
- # by a program to be run later (e.g., a cusdep or bibtex),
- # so we should wait until all passes are completed before
- # deciding a non-existent destination file is an error.
- # For a custom dependency, the rule may be obsolete, and
- # if the source file does not exist also, we should simply
- # not run the rule, but not set an error condition.
- # Any error will arise at the *latex level due to a
- # missing source file at that level.
- if ( $$Psource && (! -e $$Psource)
- && ( ( $$Pcmd_type ne 'primary') )
- ) {
- # Main source file doesn't exist, and rule is NOT primary.
- # No action, since a run is pointless. Primary is different:
- # file might be found elsewhere (by kpsearch from *latex),
- # while non-existence of main source file is a clear error.
- }
- elsif ( $$Pcmd_type eq 'delegated' ) {
- # Delegate to destination rule
- }
- elsif ( $pass{$rule}==0) {
- push @no_dest, $$Pdest;
- $$Pout_of_date = 1;
- }
- if ( $$Pcmd_type eq 'primary' ) {
- $missing_dvi_pdf = $$Pdest;
- }
- }
- }
-
- &rdb_clear_change_record;
- &rdb_flag_changes_here(0);
-
- if (!$$Pout_of_date) {
- return;
- }
- if ($diagnostics) { print " remake\n"; }
- if (!$silent) {
- print "$My_name: applying rule '$rule'...\n";
- &rdb_diagnose_changes( "Rule '$rule': " );
- }
-
- # We are applying the rule, so its source file state for when it
- # was last made is as of now:
- # ??IS IT CORRECT TO DO NOTHING IN CURRENT VERSION?
-
- # The actual run
- my $return = 0; # Return code from called routine
- # Rule may have been created since last run:
- if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
- if ( $pass{$rule} >= $max_repeat ) {
- # Avoid infinite loop by having a maximum repeat count
- # Getting here represents some kind of weird error.
- warn "$My_name: Maximum runs of $rule reached ",
- "without getting stable files\n";
- $too_many_passes = 1;
- # Treat rule as completed, else in -pvc mode get infinite reruns:
- $$Pout_of_date = 0;
- $failure = 1;
- $failure_msg = "'$rule' needed too many passes";
- return;
- }
-
- $rules_applied{$rule} = 1;
- $runs++;
-
- $pass{$rule}++;
- if ($bibtex_not_run > 0) {
- if ($bibtex_not_run == 1 ) {
- show_array ("$My_name: I WON'T RUN '$rule' because I don't find the following files:",
- @missing_bib_files);
- }
- elsif ($bibtex_not_run == 2 ) {
- warn "$My_name: I AM CONFIGURED/INVOKED NOT TO RUN '$rule'\n";
- }
- $return = &rdb_dummy_run0;
- }
- else {
- warn_running( "Run number $pass{$rule} of rule '$rule'" );
- if ($$Pcmd_type eq 'primary' ) {
- $return = &rdb_primary_run;
- }
- else { $return = &rdb_run1; }
- }
- if ($$Pchanged) {
- $newrule_nofile = 1;
- $return = 0;
- }
- elsif ( $$Pdest && ( !-e $$Pdest ) && (! $failure) ){
- # If there is a destination to make, but for some reason
- # it did not get made, and no other error was reported,
- # then a priori there appears to be an error condition:
- # the run failed. But there are some important cases in
- # which this is a wrong diagnosis.
- if ( ( $$Pcmd_type eq 'cusdep') && $$Psource && (! -e $$Psource) ) {
- # However, if the rule is a custom dependency, this is not by
- # itself an error, if also the source file does not exist. In
- # that case, we may have the situation that (1) the dest file is no
- # longer needed by the tex file, and (2) therefore the user
- # has deleted the source and dest files. After the next
- # latex run and the consequent analysis of the log file, the
- # cusdep rule will no longer be needed, and will be removed.
-
- # So in this case, do NOT report an error
- $$Pout_of_date = 0;
- }
- elsif ($$Pcmd_type eq 'primary' ) {
- # For a primary rule, i.e., *latex, not to produce the
- # expected output file may not be an error condition.
- # Diagnostics were handled in parsing the log file.
- # Special action in main loop in rdb_make
- $missing_dvi_pdf = $$Pdest;
- }
- elsif ($return == -2) {
- # Missing output file was reported to be NOT an error
- $$Pout_of_date = 0;
- }
- elsif ( ($bibtex_use <= 1.5) && ($bibtex_not_run > 0) ) {
- # Lack of destination file is not to be treated as an error
- # for a bibtex rule when latexmk is configured not to treat
- # this as an error, and the lack of a destination file is the
- # only error.
- $$Pout_of_date = 0;
- }
- else {
- $failure = 1;
- }
- }
- if ( ($return != 0) && ($return != -2) ) {
- $failure = 1;
- $$Plast_result = 2;
- if ( !$$Plast_message ) {
- $$Plast_message = "Run of rule '$rule' gave a non-zero error code";
- }
-# !!?? $failure_msg = $$Plast_message;
-
- }
- foreach ( keys %$PHsource_rules ) {
- $$PHsource_rules{$_} = $pass{$_};
- }
-} #END rdb_make1
-
-#************************************************************
-
-sub rdb_classify_rules {
- # Usage: &rdb_classify_rules
- # Assume the following variables are available (global or local):
- # Input:
- # %target_rules # Set to target rules
- # %target_files # Set to target files
- # %possible_primaries
-
- # Output:
- # %current_primaries # Keys are actual primaries
- # @pre_primary # Array of rules
- # @post_primary # Array of rules
- # @unusual_one_time # Array of rules
- # @pre_primary and @post_primary are in natural order of application.
-
- local @requested_targets = &rdb_target_array;
- local $state = 0; # Post-primary
- local @classify_stack = ();
-
- %current_primaries = ();
- @pre_primary = ();
- @post_primary = ();
- @unusual_one_time = ();
-
- rdb_recurse( \@requested_targets, \&rdb_classify1, 0,0, \&rdb_classify2 );
-
- # Reverse, as tendency is to find last rules first.
- @pre_primary = reverse @pre_primary;
- @post_primary = reverse @post_primary;
-
- my @current_primaries = keys %current_primaries;
- if ($#current_primaries < 0) {
- die "$My_name: No active primary rules found. I have to stop.\n";
- }
- elsif ($#current_primaries > 0) {
- die "$My_name: More than one active primary rule found. I have to stop.\n",
- " Primary rules: @current_primaries\n";
- }
- $current_primary = $current_primaries[0];
-
- if ($diagnostics) {
- print "Rule classification: \n";
- if ($#requested_targets < 0) {
- print " No requested rules\n";
- }
- else {
- print " Requested rules:\n";
- foreach ( @requested_targets ) { print " $_\n"; }
- }
- if ($#pre_primary < 0) {
- print " No pre-primaries\n";
- }
- else {
- print " Pre-primaries:\n";
- foreach (@pre_primary) { print " $_\n"; }
- }
- print " Primaries:\n";
- foreach (keys %current_primaries) { print " $_\n"; }
- if ($#post_primary < 0) {
- print " No post-primaries\n";
- }
- else {
- print " Post-primaries:\n";
- foreach (@post_primary) { print " $_\n"; }
- }
- if ($#unusual_one_time < 0) {
- print " No inner-level one_time rules, as expected\n";
- }
- else {
- print " Inner-level one_time rules:\n";
- foreach ( @unusual_one_time ) { print " $_\n"; }
- }
- my @normal_one_time = keys %one_time;
- if ($#normal_one_time < 0) {
- print " No outer-level one_time rules\n";
- }
- else {
- print " Outer-level one_time rules:\n";
- foreach ( @normal_one_time ) { print " $_\n"; }
- }
- } #end diagnostics
-
-} #END rdb_classify_rules
-
-#-------------------
-
-sub rdb_classify1 {
- # Helper routine for rdb_classify_rules
- # Applied as rule_act1 in recursion over rules
- # Assumes rule context, and local variables from rdb_classify_rules
- push @classify_stack, [$state];
- if ( exists $possible_one_time{$rule} ) {
- # Normally, we will have already extracted the one_time rules,
- # and they will never be accessed here. But just in case of
- # problems or generalizations, we will cover all possibilities:
- if ($depth > 1) {
- warn "ONE TIME rule not at outer level '$rule'\n";
- }
- push @unusual_one_time, $rule;
- }
- elsif ($state == 0) {
- if ( exists $possible_primaries{$rule} ) {
- $state = 1; # In primary rule
- $current_primaries{ $rule } = 1;
- }
- else {
- push @post_primary, $rule;
- }
- }
- else {
- $state = 2; # in post-primary rule
- push @pre_primary, $rule;
- }
-} #END rdb_classify1
-
-#-------------------
-
-sub rdb_classify2 {
- # Helper routine for rdb_classify_rules
- # Applied as rule_act2 in recursion over rules
- # Assumes rule context
- ($state) = @{ pop @classify_stack };
-} #END rdb_classify2
-
-#************************************************************
-
-
-sub rdb_run1 {
- # Assumes contexts for: rule.
- # Unconditionally apply the rule
- # Returns return code from applying the rule.
- # Otherwise: 0 on other kind of success,
- # -1 on error,
- # -2 when missing dest_file is to be ignored
-
- # Source file data, by definition, correspond to the file state just
- # before the latest run, and the run_time to the time just before the run:
- &rdb_update_files;
- $$Prun_time = time();
- $$Pchanged = 0; # No special changes in files
- $$Plast_result = 0;
- $$Plast_message = '';
-
- # Return values for external command:
- my $return = 0;
-
- # Find any internal command
- my @int_args = @$PAint_cmd;
-
- my $int_cmd = shift @int_args;
- my @int_args_for_printing = @int_args;
- foreach (@int_args_for_printing) {
- if ( ! defined $_ ) { $_ = 'undef'; }
- }
- if ($int_cmd) {
- print "For rule '$rule', running '\&$int_cmd( @int_args_for_printing )' ...\n";
- $return = &$int_cmd( @int_args );
- }
- elsif ($$Pext_cmd) {
- $return = &Run_subst() / 256;
- }
- else {
- warn "$My_name: Either a bug OR a configuration error:\n",
- " No command provided for '$rule'\n";
- traceback();
- $return = -1;
- $$Plast_result = 2;
- $$Plast_message = "Bug or configuration error; incorrect command type";
- }
- if ( $rule =~ /^biber/ ) {
- my @biber_source = ( );
- my $retcode = check_biber_log( $$Pbase, \@biber_source );
- foreach my $source ( @biber_source ) {
-# if ( $source =~ /\"/ ) {next; }
- print " ===Source file '$source' for '$rule'\n"
- if ($diagnostics);
- rdb_ensure_file( $rule, $source );
- }
- if ($retcode == 5) {
- # Special treatment if sole missing file is bib file
- # I don't want to treat that as an error
- $return = 0;
- $$Plast_result = 200;
- $$Plast_message = "Could not find bib file for '$$Pbase'";
- push @warnings, "Bib file not found for '$$Pbase'";
- }
- elsif ($retcode == 6) {
- # Missing control file. Need to remake it (if possible)
- # Don't treat missing bbl file as error.
- warn "$My_name: bibtex control file missing. Since that can\n",
- " be recreated, I'll try to do so.\n";
- $return = -2;
- rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
- }
- elsif ($retcode == 4) {
- $$Plast_result = 2;
- $$Plast_message = "Could not find all biber source files for '$$Pbase'";
- push @warnings, "Not all biber source files found for '$$Pbase'";
- }
- elsif ($retcode == 3) {
- $$Plast_result = 2;
- $$Plast_message = "Could not open biber log file for '$$Pbase'";
- push @warnings, $$Plast_message;
- }
- elsif ($retcode == 2) {
- $$Plast_message = "Biber errors: See file '$$Pbase.blg'";
- push @warnings, $$Plast_message;
- }
- elsif ($retcode == 1) {
- push @warnings, "Biber warnings for '$$Pbase'";
- }
- elsif ($retcode == 10) {
- push @warnings, "Biber found no citations for '$$Pbase'";
- # Biber doesn't generate a bbl file in this situation.
- $return = -2;
- }
- elsif ($retcode == 11) {
- push @warnings, "Biber: malformed bcf file for '$$Pbase'. IGNORE";
- if (!$silent) {
- warn "$My_name: biber found malformed bcf file for '$$Pbase'.\n",
- " I'll ignore error, and delete any bbl file.\n";
- }
- # Malformed bcf file is a downstream consequence, normally,
- # of an error in *latex run. So this is not an error
- # condition in biber itself.
- # Current version of biber deletes bbl file.
- # Older versions (pre-2016) made an incorrect bbl file, which
- # tended to cause latex errors, and give a self-perpetuating error.
- # To be safe, ensure the bbl file doesn't exist.
- unlink $$Pdest;
- # The missing bbl file is now not an error:
- $return = -2;
-# ??????? BCF
-# Following is intended to work, but creates infinite loop
-# in malformed bcf file situation under -pvc.
-# since on each check for change in ANY file, pvc finds changed file
-# Need to restrict pvc reruns to case of changed USER files
-# # To give good properties for *latex rule, it is best
-# # to have a valid bbl file that exists:
-# create_empty_file( $$Pdest );
-# $return = 0;
-
- }
- }
- if ( $rule =~ /^bibtex/ ) {
- my $retcode = check_bibtex_log($$Pbase);
- if ( ! -e $$Psource ) {
- $retcode = 10;
- rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
- }
- if ($retcode == 3) {
- $$Plast_result = 2;
- $$Plast_message = "Could not open bibtex log file for '$$Pbase'";
- push @warnings, $$Plast_message;
- }
- elsif ($retcode == 2) {
- $$Plast_message = "Bibtex errors: See file '$$Pbase.blg'";
- $failure = 1;
- push @warnings, $$Plast_message;
- }
- elsif ($retcode == 1) {
- push @warnings, "Bibtex warnings for '$$Pbase'";
- }
- elsif ($retcode == 10) {
- push @warnings, "Bibtex found no citations for '$$Pbase',\n",
- " or bibtex found a missing aux file\n";
- if (! -e $$Pdest ) {
- warn "$My_name: Bibtex did not produce '$$Pdest'. But that\n",
- " was because of missing files, so I will continue.\n";
- $return = -2;
- }
- else {
- $return = 0;
- }
- }
- }
-
- $updated = 1;
- if ($$Ptest_kind == 3) {
- # We are time-criterion first time only. Now switch to
- # file-change criterion
- $$Ptest_kind = 1;
- }
- $$Pout_of_date = $$Pout_of_date_user = 0;
-
- if ( ($$Plast_result == 0) && ($return != 0) && ($return != -2) ) {
- $$Plast_result = 2;
- if ($$Plast_message eq '') {
- $$Plast_message = "Command for '$rule' gave return code $return";
- if ($rule =~ /^(pdf|lua|xe|)latex/) {
- $$Plast_message .= "\n Refer to '$log_name' for details";
- }
- elsif ($rule =~ /^makeindex/) {
- $$Plast_message .= "\n Refer to '${aux_dir1}${root_filename}.ilg' for details";
- }
- }
- }
- elsif ( $$Pdest && (! -e $$Pdest) && ($return != -2) ) {
- $$Plast_result = 1;
- }
- return $return;
-} # END rdb_run1
-
-#-----------------
-
-sub rdb_dummy_run0 {
- # Assumes contexts for: rule.
- # Update rule state as if the rule ran successfully,
- # but don't run the rule.
- # Returns 0 (success code)
-
- # Source file data, by definition, correspond to the file state just before
- # the latest run, and the run_time to the time just before the run:
- &rdb_update_files;
- $$Prun_time = time();
- $$Pchanged = 0; # No special changes in files
- $$Plast_result = 0;
- $$Plast_message = '';
-
- if ($$Ptest_kind == 3) {
- # We are time-criterion first time only. Now switch to
- # file-change criterion
- $$Ptest_kind = 1;
- }
- $$Pout_of_date = $$Pout_of_date_user = 0;
-
- return 0;
-} # END rdb_dummy_run0
-
-#-----------------
-
-sub Run_subst {
- # Call: Run_subst( cmd, msg, options, source, dest, base )
- # Runs command with substitutions.
- # If an argument is omitted or undefined, it is replaced by a default:
- # cmd is the command to execute
- # msg is whether to print a message:
- # 0 for not, 1 according to $silent setting, 2 always
- # options, source, dest, base: correspond to placeholders.
- # Substitutions:
- # %S=source, %D=dest, %B=base, %R=root=base for latex, %O=options,
- # %T=texfile, %Y=$aux_dir1, %Z=$out_dir1
- # This is a globally usable subroutine, and works in a rule context,
- # and outside.
- # Defaults:
- # cmd: $PPext_cmd if defined, else '';
- # msg: 1
- # options: ''
- # source: $$Psource if defined, else $texfile_name;
- # dest: $$Pdest if defined, else $view_file, else '';
- # base: $$Pbase if defined, else $root_filename;
-
- my ($ext_cmd, $msg, $options, $source, $dest, $base ) = @_;
-
- $ext_cmd ||= ( $Pext_cmd ? $$Pext_cmd : '' );
- $msg = ( defined $msg ? $msg : 1 );
- $options ||= '';
- $source ||= ( $Psource ? $$Psource : $texfile_name );
- $dest ||= ( $Pdest ? $$Pdest : ( $view_file || '' ) );
- $base ||= ( $Pbase ? $$Pbase : $root_filename );
-
- if ( $ext_cmd eq '' ) {
- return 0;
- }
-
- #Set character to surround filenames:
- my $q = $quote_filenames ? '"' : '';
-
- my %subst = (
- '%A' => $q.$tex_basename.$q,
- '%B' => $q.$base.$q,
- '%D' => $q.$dest.$q,
- '%O' => $options,
- '%S' => $q.$source.$q,
- '%R' => $q.$root_filename.$q,
- '%S' => $q.$source.$q,
- '%T' => $q.$texfile_name.$q,
- '%Y' => $q.$aux_dir1.$q,
- '%Z' => $q.$out_dir1.$q,
- '%%' => '%' # To allow literal %B, %R, etc, by %%B.
- );
- if ($pre_tex_code) {
- $subst{'%U'} = $q.$pre_tex_code.$q;
- $subst{'%P'} = "$q$pre_tex_code\\input{$source}$q";
- }
- else {
- $subst{'%U'} = '';
- $subst{'%P'} = $subst{'%S'};
- }
- if ( ($^O eq "MSWin32" ) && $MSWin_back_slash ) {
- foreach ( '%R', '%B', '%T', '%S', '%D', '%Y', '%Z' ) {
- $subst{$_} =~ s(/)(\\)g;
- }
- }
-
- my @tokens = split /(%.)/, $ext_cmd;
- foreach (@tokens) {
- if (exists($subst{$_})) { $_ = $subst{$_}; }
- }
- $ext_cmd = join '', @tokens;
-
- my ($pid, $return) =
- ( ($msg == 0) || ( ($msg == 1) && $silent ) )
- ? &Run($ext_cmd)
- : &Run_msg($ext_cmd);
- return $return;
-} #END Run_subst
-
-#-----------------
-
-sub rdb_primary_run {
-#?? See multipass_run in previous version Aug 2007 for issues
- # Call: rdb_primary_run
- # Assumes contexts for: recursion, make, & rule.
- # Assumes (a) the rule is a primary,
- # (b) a run has to be made,
- # (c) source files have been made.
- # This routine carries out the run of the rule unconditionally,
- # and then parses log file etc.
- my $return = 0;
-
- if ( ! $filetime_offset_measured ) {
- $filetime_offset = get_filetime_offset( $aux_dir1."tmp" );
- if ( (abs($filetime_offset) > $filetime_offset_report_threshold)
- && ($diagnostics || ! $silent) )
- {
- warn "$My_name: I am working around an offset relative to my system time by\n",
- " $filetime_offset secs for file times in directory '$aux_dir1'.\n";
- }
- $filetime_offset_measured = 1;
- }
-
- # Need to reset the list of generated files. If we don't it can contain
- # out-of-date items from previous run. (Think bibtopic, which writes
- # bbl files!)
- &rdb_initialize_generated;
- my $return_latex = &rdb_run1;
-
- # Need to worry about changed directory, changed output extension
- # Where else is $missing_dvi_pdf set? Was it initialized?
- if (-e $$Pdest) { $missing_dvi_pdf = '';}
-
- # Handle case that log file is caused to be in an unexpected place,
- # from a configuration error:
- &find_set_log;
-
- if ($recorder) {
- # Handle problem that some version of *latex give fls files
- # of name latex.fls or pdflatex.fls instead of $root_filename.fls.
- # Also that setting of -output-directory -aux-directory is not
- # respected by *latex, at least in some versions.
- my $std_fls_file = $fls_name;
- my @other_fls_names = ( );
- if ( $rule =~ /^pdflatex/ ) {
- push @other_fls_names, "pdflatex.fls";
- }
- else {
- push @other_fls_names, "latex.fls";
- }
- if ( $aux_dir1 ne '' ) {
- push @other_fls_names, "$root_filename.fls";
- # MiKTeX uses out_dir for .fls. However, it seems logical to
- # me for .fls to be in aux_dir. So I'll allow for this
- # Possibility, although I don't know if it has been used.
- push @other_fls_names, "$aux_dir1$root_filename.fls";
- }
- # Find the first non-standard fls file and copy it to the standard
- # place. But only do this if the file time is compatible with being
- # generated in the current run, and if the standard fls file hasn't
- # been made in the current run, as tested by the use of
- # test_gen_file; that avoids problems with fls files leftover from
- # earlier runs with other versions of latex.
- if ( ! test_gen_file( $std_fls_file ) ) {
- foreach my $cand (@other_fls_names) {
- if ( test_gen_file( $cand ) ) {
- copy $cand, $std_fls_file;
- last;
- }
- }
- }
- if ( ! test_gen_file( $std_fls_file ) ) {
- warn "$My_name: fls file doesn't appear to have been made.\n";
- }
- }
-
- # Find current set of source files:
- my ($missing_dirs, $PA_missing_subdirs) = &rdb_set_latex_deps;
-
- # For each file of the kind made by epstopdf.sty during a run,
- # if the file has changed during a run, then the new version of
- # the file will have been read during the run. Unlike the usual
- # case, we will NOT need to redo the primary run because of the
- # change of this file during the run. Therefore set the file as
- # up-to-date:
- rdb_do_files( sub { if ($$Pcorrect_after_primary) {&rdb_update1;} } );
-
- $updated = 1; # Flag that some dependent file has been remade
-
-#?? # Fix the state of the files as of now: this will solve the
-#?? # problem of latex and pdflatex interfering with each other,
-#?? # at the expense of some non-optimality
-#?? #?? Check this is correct:
-#?? &rdb_update_files;
-
- if ( $diagnostics ) {
- print "$My_name: Rules after run: \n";
- rdb_show();
- }
-
- $return = $return_latex;
-
-# ???? Is the following needed?
- if ($return_latex && $$Pout_of_date_user) {
- print "Error in *LaTeX, but change of user file(s), ",
- "so ignore error & provoke rerun\n"
- if (! $silent);
- $return = 0;
- }
- if ($return_latex && ($missing_dirs ne 'none') ) {
- print "Error in *LaTeX, but needed subdirectories in output directory\n",
- " were missing and successfully created, so try again.\n"
- if (! $silent);
- $return = 0;
- }
- # Summarize issues that may have escaped notice:
- @primary_warning_summary = ();
- if ($bad_reference) {
- push @primary_warning_summary,
- "Latex failed to resolve $bad_reference reference(s)";
- }
- if ($mult_defined) {
- push @primary_warning_summary,
- "Latex found $mult_defined multiply defined reference(s)";
- }
- if ($bad_character) {
- push @primary_warning_summary,
- "=====Latex reported missing or unavailable character(s).\n".
- "=====See log file for details.";
- }
- if ($bad_citation) {
- push @primary_warning_summary,
- "Latex failed to resolve $bad_citation citation(s)";
- }
- if ( $diagnostics && ($#primary_warning_summary > -1) ) {
- show_array( "$My_name: Summary of warnings:", @primary_warning_summary );
- }
- return $return;
-} #END rdb_primary_run
-
-#************************************************************
-
-sub rdb_clear_change_record {
- # Initialize diagnostics for reasons for running rule.
- @changed = ();
- %changed_rules = ();
- @changed_user = ();
- @disappeared = ();
- @no_dest = (); # We are not now using this
- @rules_never_run = ();
- @rules_to_apply = (); # This is used in recursive application
- # of rdb_flag_changes_here, to list
- # rules that were out-of-date for some reason.
-} #END rdb_clear_change_record
-
-#************************************************************
-
-sub rdb_flag_changes_here {
- # Flag changes in current rule.
- # Assumes rule context.
- # Usage: rdb_flag_changes_here( ignore_run_time )
- # Argument: if true then fdb_get shouldn't do runtime test
- # for recalculation of md5
- local $ignore_run_time = $_[0];
- if ( ! defined $ignore_run_time ) { $ignore_run_time = 0; }
-
- $$Pcheck_time = time();
-
- local $dest_mtime = 0;
- $dest_mtime = get_mtime($$Pdest) if ($$Pdest);
- rdb_do_files( \&rdb_file_change1);
- while ( my ($s_rule, $l_pass) = each %$PHsource_rules ) {
- if ( defined $pass{$s_rule}
- && ($pass{$s_rule} > $l_pass)
- )
- {
- $changed_rules{$s_rule} = $rule;
- $$Pout_of_date = 1;
- }
- }
- if ($$Pout_of_date) {
- push @rules_to_apply, $rule;
- }
-#?? print "======== flag: $rule $$Pout_of_date ==========\n";
-} #END rdb_flag_changes_here
-
-#************************************************************
-
-sub rdb_file_change1 {
- # Call: &rdb_file_change1
- # Assumes rule and file context. Assumes $dest_mtime set.
- # Flag whether $file in $rule has changed or disappeared.
- # Set rule's make flag if there's a change.
-
- my $check_time_argument = 0;
- if (! $ignore_run_time ) {
- $check_time_argument = max( $$Pcheck_time, $$Prun_time );
- }
- my ($new_time, $new_size, $new_md5) = fdb_get($file, $check_time_argument );
- my $ext_no_period = ext_no_period( $file );
- my $generated = exists $from_rules{$file};
- if ( ($new_size < 0) && ($$Psize >= 0) ) {
- # print "Disappeared '$file' in '$rule'\n";
- push @disappeared, $file;
- # No reaction is good.
- #$$Pout_of_date = 1;
- # ??? 1 Sep. 2008: I do NOT think so, for cusdep no-file-exists issue
- # ??? 30 Sep 2008: I think I have this fixed. There were other changes
- # needed. No-change-flagged is correct. The array @disappeared flags
- # files that have disappeared, if I need to know. But having a source
- # file disappear is not a reason for a remake unless I know how to
- # make the file. If the file is a destination of a rule, that rule
- # will be rerun. It may be that the user is changing another source
- # in such a way that the disappeared file won't be needed. Before the
- # change is applied we get a superfluous infinite loop.
- return;
- }
- if ( ($new_size < 0) && ($$Psize < 0) ) {
- return;
- }
- # Primarily use md5 signature to determine whether file contents have
- # changed.
- # Backup by file size change, but only in the case where there is
- # no pattern of lines to ignore in testing for a change
- if ( ($new_md5 ne $$Pmd5)
- || (
- (! exists $hash_calc_ignore_pattern{$ext_no_period})
- && ($new_size != $$Psize)
- )
- ) {
- push @changed, $file;
- $$Pout_of_date = 1;
- if ( ! $generated ) {
- push @changed_user, $file;
- $$Pout_of_date_user = 1;
- }
- }
- elsif ( $new_time != $$Ptime ) {
- $$Ptime = $new_time;
- }
- if ( ( ($$Ptest_kind == 2) || ($$Ptest_kind == 3) )
- && (! $generated)
- && ( $new_time > $dest_mtime )
- ) {
- push @changed, $file;
- $$Pout_of_date = $$Pout_of_date_user = 1;
- }
-} #END rdb_file_change1
-
-#************************************************************
-
-sub rdb_user_changes {
- # Argument(s): a set of top level rules.
- # Aim: Find any changed user files for those rules and all ancestors.
- # Assumption: List of from_rules for files is up-to-date.
- &rdb_clear_change_record;
- rdb_recurse( [@_], sub{ &rdb_flag_changes_here(1); } );
- if ($#changed_user >=0) { show_array( 'User changed files', @changed_user ); }
- return ($#changed_user >= 0);
-} #END rdb_user_changes
-
-#************************************************************
-
-sub rdb_diagnose_changes {
- # Call: rdb_diagnose_changes or rdb_diagnose_changes( heading )
- # List changes on STDERR
- # Precede the message by the optional heading, else by "$My_name: "
- my $heading = defined($_[0]) ? $_[0] : "$My_name: ";
-
- if ($#rules_never_run >= 0) {
- warn "${heading}Rules & subrules not known to be previously run:\n";
- foreach (@rules_never_run) { warn " $_\n"; }
- }
- if ( ($#changed >= 0) || (keys %changed_rules > 0) || ($#disappeared >= 0) || ($#no_dest >= 0) ) {
- warn "${heading}File changes, etc:\n";
- if ( $#changed >= 0 ) {
- warn " Changed files, or newly in use since previous run(s):\n";
- foreach (uniqs(@changed)) { warn " '$_'\n"; }
- }
- if ( $#disappeared >= 0 ) {
- warn " No-longer-existing files:\n";
- foreach (uniqs(@disappeared)) { warn " '$_'\n"; }
- }
- if ( $#no_dest >= 0 ) {
- warn " Non-existent destination files:\n";
- foreach (uniqs(@no_dest)) { warn " '$_'\n"; }
- }
- if ( keys %changed_rules > 0 ) {
- warn " Rule(s) that have been run and require run of dependent rule:\n";
- while (my ($s_rule, $d_rule) = each %changed_rules) {
- warn " '$s_rule' which requires run of '$d_rule'\n";
- }
- }
- }
- elsif ($#rules_to_apply >=0) {
- warn "${heading}The following rules & subrules became out-of-date:\n";
- foreach (@rules_to_apply) { warn " '$_'\n"; }
- }
- else {
- warn "${heading}No file changes\n";
- }
-} #END rdb_diagnose_changes
-
-
-#************************************************************
-#************************************************************
-#************************************************************
-#************************************************************
-
-#************************************************************
-#************************************************************
-#************************************************************
-#************************************************************
-
-# Routines for convenient looping and recursion through rule database
-# ================= NEW VERSION ================
-
-# There are several places where we need to loop through or recurse
-# through rules and files. This tends to involve repeated, tedious
-# and error-prone coding of much book-keeping detail. In particular,
-# working on files and rules needs access to the variables involved,
-# which either involves direct access to the elements of the database,
-# and consequent fragility against changes and upgrades in the
-# database structure, or involves lots of routines for reading and
-# writing data in the database, then with lots of repetitious
-# house-keeping code.
-#
-# The routines below provide a solution. Looping and recursion
-# through the database are provided by a set of basic routines where
-# each necessary kind of looping and iteration is coded once. The
-# actual actions are provided as references to action subroutines.
-# (These can be either actual references, as in \&routine, or
-# anonymous subroutines, as in sub{...}, or aas a zero value 0 or an
-# omitted argument, to indicate that no action is to be performed.)
-#
-# When the action subroutine(s) are actually called, a context for the
-# rule and/or file (as appropriate) is given by setting named
-## NEW ??
-# variables to REFERENCES to the relevant data values. These can be
-# used to retrieve and set the data values. As a convention,
-# references to scalars are given by variables named start with "$P",
-# as in "$Pdest", while references to arrays start with "$PA", as in
-# "$PAint_cmd", and references to hashes with "$PH", as in "$PHsource".
-# After the action subroutine has finished, checks for data
-# consistency may be made.
-## ??? OLD
-# variables to the relevant data values. After the action subroutine
-# has finished, the database is updated with the values of these named
-# variables, with any necessary consistency checks. Thus the action
-# subroutines can act on sensibly named variables without needed to
-# know the database structure.
-#
-# The only routines that actually use the database structure and need
-# to be changed if that is changed are: (a) the routines rdb_one_rule
-# and rdb_one_file that implement the calling of the action subroutines,
-# (b) routines for creation of single rules and file items, and (c) to
-# a lesser extent, the routine for destroying a file item.
-#
-# Note that no routine is provided for destroying a rule. During a
-# run, a rule, with its source files, may become inaccessible or
-# unused. This happens dynamically, depending on the dependencies
-# caused by changes in the source file or by error conditions that
-# cause the computation of dependencies, particular of latex files, to
-# become wrong. In that situation the files certainly come and go in
-# the database, but subsidiary rules, with their content information
-# on their source files, need to be retained so that their use can be
-# reinstated later depending on dynamic changes in other files.
-#
-# However, there is a potential memory leak unless some pruning is
-# done in what is written to the fdb file. (Probably only accessible
-# rules and those for which source files exist. Other cases have no
-# relevant information that needs to be preserved between runs.)
-
-#
-#
-
-
-#************************************************************
-
-# First the top level routines for recursion and iteration
-
-#************************************************************
-
-sub rdb_recurse {
- # Call: rdb_recurse( rule | [ rules],
- # \&rule_act1, \&file_act1, \&file_act2,
- # \&rule_act2 )
- # The actions are pointers to subroutines, and may be null (0, or
- # undefined) to indicate no action to be applied.
- # Recursively acts on the given rules and all ancestors:
- # foreach rule found:
- # apply rule_act1
- # loop through its files:
- # apply file_act1
- # act on its ancestor rule, if any
- # apply file_act2
- # apply rule_act2
- # Guards against loops.
- # Access to the rule and file data by local variables, only
- # for getting and setting.
-
- # This routine sets a context for anything recursive, with @heads,
- # %visited and $depth being set as local variables.
-
- local @heads = ();
- my $rules = shift;
-
- # Distinguish between single rule (a string) and a reference to an
- # array of rules:
- if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
- else { @heads = ( $rules ); }
-
- # Keep a list of visited rules, used to block loops in recursion:
- local %visited = ();
- local $depth = 0;
-
- foreach $rule ( @heads ) {
- if ( rdb_is_active($rule) ) { rdb_recurse_rule( $rule, @_ ); }
- }
-
-} #END rdb_recurse
-
-#************************************************************
-
-sub rdb_for_actives {
- # Call: rdb_for_actives( \&rule_act1, \&file_act, \&rule_act2 )
- # Loops through all rules and their source files, using the
- # specified set of actions, which are pointers to subroutines.
- # Sorts rules alphabetically.
- # See rdb_for_some for details.
-# rdb_for_some( [ sort keys %rule_db ], @_);
- rdb_for_some( [ sort &rdb_actives ], @_);
-} #END rdb_for_actives
-
-#************************************************************
-
-sub rdb_for_some {
- # Call: rdb_for_some( rule | [ rules],
- # \&rule_act1, \&file_act, \&rule_act2)
- # Actions can be zero, and rules at tail of argument list can be
- # omitted. E.g. rdb_for_some( rule, 0, \&file_act ).
- # Anonymous subroutines can be used, e.g., rdb_for_some( rule, sub{...} ).
- #
- # Loops through rules and their source files, using the
- # specified set of rules:
- # foreach rule:
- # apply rule_act1
- # loop through its files:
- # apply file_act
- # apply rule_act2
- #
- # Rule data and file data are made available in local variables
- # for access by the subroutines.
-
- local @heads = ();
- my $rules = shift;
- # Distinguish between single rule (a string) and a reference to an
- # array of rules:
- if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
- else { @heads = ( $rules ); }
-
- foreach $rule ( @heads ) {
- # $rule is implicitly local
- &rdb_one_rule( $rule, @_ );
- }
-} #END rdb_for_some
-
-#************************************************************
-
-sub rdb_for_one_file {
- my $rule = shift;
- # Avoid name collisions with general recursion and iteraction routines:
- local $file1 = shift;
- local $action1 = shift;
- rdb_for_some( $rule, sub{rdb_one_file($file1,$action1)} );
-} #END rdb_for_one_file
-
-
-#************************************************************
-
-# Routines for inner part of recursion and iterations
-
-#************************************************************
-
-sub rdb_recurse_rule {
- # Call: rdb_recurse_rule($rule, \&rule_act1, \&file_act1, \&file_act2,
- # \&rule_act2 )
- # to do the work for one rule, recurisvely called from_rules for
- # the sources of the rules.
- # Assumes recursion context, i.e. that %visited, @heads, $depth.
- # We are overriding actions:
- my ($rule, $rule_act1, $new_file_act1, $new_file_act2, $rule_act2)
- = @_;
- if (! rdb_is_active($rule)) { return; }
- # and must propagate the file actions:
- local $file_act1 = $new_file_act1;
- local $file_act2 = $new_file_act2;
- # Prevent loops:
- if ( (! $rule) || exists $visited{$rule} ) { return; }
- $visited{$rule} = 1;
- # Recursion depth
- $depth++;
- # We may need to repeat actions on dependent rules, without being
- # blocked by the test on visited files. So save %visited:
- # NOT CURRENTLY USED!! local %visited_at_rule_start = %visited;
- # At end, the last value set for %visited wins.
- rdb_one_rule( $rule, $rule_act1, \&rdb_recurse_file, $rule_act2 );
- $depth--;
- } #END rdb_recurse_rule
-
-#************************************************************
-
-sub rdb_recurse_file {
- # Call: rdb_recurse_file to do the work for one file.
- # This has no arguments, since it is used as an action subroutine,
- # passed as a reference in calls in higher-level subroutine.
- # Assumes contexts set for: Recursion, rule, and file
- &$file_act1 if $file_act1;
- rdb_recurse_rule( $$Pfrom_rule, $rule_act1, $file_act1, $file_act2,
- $rule_act2 )
- if $$Pfrom_rule;
- &$file_act2 if $file_act2;
-} #END rdb_recurse_file
-
-#************************************************************
-
-sub rdb_do_files {
- # Assumes rule context, including $PHsource.
- # Applies an action to all the source files of the rule.
- local $file_act = shift;
- my @file_list = sort keys %$PHsource;
- foreach my $file ( @file_list ){
- rdb_one_file( $file, $file_act );
- }
-} #END rdb_do_files
-
-#************************************************************
-
-# Routines for action on one rule and one file. These are the main
-# places (in addition to creation and destruction routines for rules
-# and files) where the database structure is accessed.
-
-#************************************************************
-
-sub rdb_one_rule {
- # Call: rdb_one_rule( $rule, $rule_act1, $file_act, $rule_act2 )
- # Sets context for rule and carries out the actions.
-#===== Accesses rule part of database structure =======
-
- local ( $rule, $rule_act1, $file_act, $rule_act2 ) = @_;
-#?? &R1;
- if ( (! $rule) || ! rdb_rule_exists($rule) ) { return; }
-
- local ( $PArule_data, $PHsource, $PHdest, $PHsource_rules ) = @{$rule_db{$rule}};
- local ($Pcmd_type, $Pext_cmd, $PAint_cmd, $Ptest_kind,
- $Psource, $Pdest, $Pbase,
- $Pout_of_date, $Pout_of_date_user, $Prun_time, $Pcheck_time,
- $Pchanged,
- $Plast_result, $Plast_message, $PA_extra_gen )
- = Parray( $PArule_data );
-
- &$rule_act1 if $rule_act1;
- &rdb_do_files( $file_act ) if $file_act;
- &$rule_act2 if $rule_act2;
-#?? &R2;
-} #END rdb_one_rule
-
-#************************************************************
-
-sub rdb_activate {
- # Usage rdb_activate( rule_names )
- # Turns on active flag for the rules
- foreach ( @_ ) {
- if ( rdb_rule_exists($_) ) { $actives{$_} = 1; }
- }
-}
-
-#--------------------------------------------------
-
-sub rdb_deactivate {
- # Usage rdb_deactivate( rule_names )
- # Turns off active flag for the rules
- foreach ( @_ ) { delete $actives{$_}; }
-}
-
-#--------------------------------------------------
-
-sub rdb_activate_request {
- # Usage rdb_activate_request( rule_names )
- # Turns on active flag for the rules.
- # Adds rules to target_rules list
- foreach ( @_ ) {
- if ( rdb_rule_exists($_) ) { $actives{$_} = 1; $target_rules{$_} = 1; }
- }
-}
-
-#--------------------------------------------------
-
-sub rdb_deactivate_derequest {
- # Usage rdb_deactivate_derequest( rule_names )
- # Turns off active flag for the rules
- # Removes rules from target_rules list
- foreach ( @_ ) { delete $actives{$_}; delete $target_rules{$_}; }
-}
-
-#--------------------------------------------------
-sub rdb_is_active {
- # Usage rdb_is_active( rule_name )
- if ( (exists $actives{$_[0]}) && rdb_rule_exists($_[0]) ) { return 1; }
- else { return 0; }
-}
-
-#--------------------------------------------------
-
-sub rdb_actives {
- # Returns array of active rules
- return keys %actives;
-}
-
-#************************************************************
-
-sub rdb_one_file {
- # Call: rdb_one_file($file, $file_act)
- # Sets context for file and carries out the action.
- # Assumes $rule context set.
-#===== Accesses file part of database structure =======
- local ($file, $file_act) = @_;
-#?? &F1;
- if ( (!$file) ||(!exists ${$PHsource}{$file}) ) { return; }
- local $PAfile_data = ${$PHsource}{$file};
- local ($Ptime, $Psize, $Pmd5, $Pfrom_rule, $Pcorrect_after_primary )
- = Parray( $PAfile_data );
- &$file_act() if $file_act;
- if ( ! rdb_rule_exists( $$Pfrom_rule ) ) {
- $$Pfrom_rule = '';
- }
-#?? &F2;
-} #END rdb_one_file
-
-#************************************************************
-
-# Routines for creation of rules and file items, and for removing file
-# items.
-
-#************************************************************
-
-sub rdb_remove_rule {
- # rdb_remove_rule( rule, ... )
- foreach my $key (@_) {
- delete $rule_db{$key};
- delete $actives{$key};
- }
-}
-
-#************************************************************
-
-sub rdb_create_rule {
- # rdb_create_rule( rule, command_type, ext_cmd, int_cmd, test_kind,
- # source, dest, base,
- # needs_making, run_time, check_time, set_file_not_exists,
- # ref_to_array_of_specs_of_extra_generated_files )
- # int_cmd is either a string naming a perl subroutine or it is a
- # reference to an array containing the subroutine name and its
- # arguments.
- # Makes rule. Update rule if it already exists.
- # Omitted arguments: replaced by 0 or '' as needed.
- # Rule is made active
-# ==== Sets rule data ====
- my ( $rule, $cmd_type, $ext_cmd, $PAint_cmd, $test_kind,
- $source, $dest, $base,
- $needs_making, $run_time, $check_time, $set_file_not_exists, $extra_gen ) = @_;
- my $active = 1;
- my $changed = 0;
-
- # Set defaults, and normalize parameters:
- foreach ( $cmd_type, $ext_cmd, $PAint_cmd, $source, $dest, $base,
- $set_file_not_exists ) {
- if (! defined $_) { $_ = ''; }
- }
- if ( ($source =~ /\"/) || ($dest =~ /\"/) || ($base =~ /\"/) ) {
- die "$My_name: Error. In rdb_create_rule to create rule\n",
- " '$rule',\n",
- " there is a double quote in one of source, destination or base parameters:\n",
- " '$source'\n",
- " '$dest'\n",
- " '$base'\n",
- " I cannot handle this. Cause is probably a latexmk bug. Please report it.\n";
- }
- foreach ( $needs_making, $run_time, $check_time, $test_kind ) {
- if (! defined $_) { $_ = 0; }
- }
- if (!defined $test_kind) {
- # Default to test on file change
- $test_kind = 1;
- }
- if ( ref( $PAint_cmd ) eq '' ) {
- # It is a single command. Convert to array reference:
- $PAint_cmd = [ $PAint_cmd ];
- }
- else {
- # COPY the referenced array:
- $PAint_cmd = [ @$PAint_cmd ];
- }
- my $PA_extra_gen = [];
- if ($extra_gen) {
- @$PA_extra_gen = @$extra_gen;
- }
- $rule_db{$rule} =
- [ [$cmd_type, $ext_cmd, $PAint_cmd, $test_kind,
- $source, $dest, $base,
- $needs_making, 0, $run_time, $check_time, $changed,
- -1, '', $PA_extra_gen ],
- {},
- {},
- {}
- ];
- if ($source) {
- rdb_ensure_file( $rule, $source, undef, $set_file_not_exists );
- }
- rdb_one_rule( $rule, \&rdb_initialize_generated );
- if ($active) { rdb_activate($rule); }
- else { rdb_deactivate($rule); }
-} #END rdb_create_rule
-
-#************************************************************
-
-sub rdb_initialize_generated {
-# Assume rule context.
-# Initialize hash of generated files
- %$PHdest = ();
- if ($$Pdest) { rdb_add_generated($$Pdest); }
- rdb_add_generated(@$PA_extra_gen);
-} #END rdb_initialize_generated
-
-#************************************************************
-
-sub rdb_add_generated {
-# Assume rule context.
-# Add arguments to hash of generated files, and to global cache
- foreach (@_) {
- $$PHdest{$_} = 1;
- $from_rules{$_} = $rule;
- }
-} #END rdb_add_generated
-
-#************************************************************
-
-sub rdb_remove_generated {
-# Assume rule context.
-# Remove arguments from hash of generated files
- foreach (@_) { delete $$PHdest{$_}; }
-} #END rdb_remove_generated
-
-#************************************************************
-
-sub rdb_ensure_file {
- # rdb_ensure_file( rule, file[, fromrule[, set_not_exists]] )
- # Ensures the source file item exists in the given rule.
- # Then if the fromrule is specified, set it for the file item.
- # If the item is created, then:
- # (a) by default initialize it to current file state.
- # (b) but if the fourth argument, set_not_exists, is true,
- # initialize the item as if the file does not exist.
- # This case is typically used when the log file for a run
- # of latex/pdflatex claims that the file was non-existent
- # at the beginning of a run.
-#============ rule and file data set here ======================================
- my $rule = shift;
- local ( $new_file, $new_from_rule, $set_not_exists ) = @_;
- if ( ! rdb_rule_exists( $rule ) ) {
- die_trace( "$My_name: BUG in call to rdb_ensure_file: non-existent rule '$rule'" );
- }
- if ( ! defined $new_file ) {
- die_trace( "$My_name: BUG in call to rdb_ensure_file: undefined file for '$rule'" );
- }
- if ( $new_file =~ /\"/ ) {
- warn "$My_name: in rdb_ensure_file for rule '$rule', there is a double quote in\n",
- " the filename: '$new_file'.\n",
- " I cannot handle this, will ignore this file.\n";
- return;
- }
- if ( ! defined $set_not_exists ) { $set_not_exists = 0; }
- rdb_one_rule( $rule,
- sub{
- if (! exists ${$PHsource}{$new_file} ) {
- if ( $set_not_exists ) {
- ${$PHsource}{$new_file} = [@nofile, '', 0];
- }
- else {
- ${$PHsource}{$new_file}
- = [fdb_get($new_file, $$Prun_time), '', 0];
- }
- }
- }
- );
- if (defined $new_from_rule ) {
- rdb_for_one_file( $rule, $new_file, sub{ $$Pfrom_rule = $new_from_rule; });
- }
-} #END rdb_ensure_file
-
-#************************************************************
-
-sub rdb_remove_files {
- # rdb_remove_file( rule, file, ... )
- # Removes file(s) for the rule.
- my $rule = shift;
- if (!$rule) { return; }
- local @files = @_;
- rdb_one_rule( $rule,
- sub{ foreach (@files) { delete ${$PHsource}{$_}; } }
- );
-} #END rdb_remove_files
-
-#************************************************************
-
-sub rdb_list_source {
- # rdb_list_source( rule )
- # Return array of source files for rule.
- my $rule = shift;
- my @files = ();
- rdb_one_rule( $rule,
- sub{ @files = keys %$PHsource; }
- );
- return @files;
-} #END rdb_list_source
-
-#************************************************************
-
-sub rdb_set_source {
- # rdb_set_source( rule, file, ... )
- my $rule = shift;
- if (!$rule) { return; }
- my %files = ();
- foreach (@_) {
-# if ( /\"/ ) {next; }
- rdb_ensure_file( $rule, $_ );
- $files{$_} = 1;
- }
- foreach ( rdb_list_source($rule) ) {
- if ( ! exists $files{$_} ) { rdb_remove_files( $rule, $_ ); }
- }
- return;
-} #END rdb_list_source
-
-#************************************************************
-
-sub rdb_change_dest {
- # Assumes rule context.
- # Usage change_dest( new_dest [, flag] )
- # Changes destination for this rule. Fixes from_rule links.
- # If flag set, make the new_dest a source file in any rule
- # for which the old destination is already set.
- # No action if there's no change of destination.
- local ($new_dest, $flag) = @_;
- local $old_dest = $$Pdest;
- if ($old_dest eq $new_dest) { return; }
-# if ( $new_dest =~ /\"/ ) { return; }
- rdb_remove_generated( $old_dest );
- rdb_add_generated( $new_dest );
- if ($flag) {
- print "rdb_change_dest: fixing dependencies\n";
- rdb_for_actives( sub{ if ( rdb_file_exists( $rule, $old_dest ) ) {
- rdb_ensure_file( $rule, $new_dest );
- rdb_remove_files( $rule, $old_dest );
- }
- }
- );
- }
- $$Pdest = $new_dest;
- # ??? Do I need to fix from_rule setting?
- #&rdb_make_links;
- return;
-} #END rdb_change_dest
-
-#************************************************************
-
-sub rdb_rule_exists {
- # Call rdb_rule_exists($rule): Returns whether rule exists.
- my $rule = shift;
- if (! $rule ) { return 0; }
- return exists $rule_db{$rule};
-} #END rdb_rule_exists
-
-#************************************************************
-
-sub rdb_file_exists {
- # Call rdb_file_exists($rule, $file):
- # Returns whether source file item in rule exists.
- local ( $rule, $file ) = @_;
- local $exists = 0;
- rdb_one_rule( $rule,
- sub{ $exists = exists( ${$PHsource}{$file} ) ? 1:0; }
- );
- return $exists;
-} #END rdb_file_exists
-
-#************************************************************
-
-sub rdb_update_gen_files {
- # Assumes rule context. Update source files of rule to current state.
- rdb_do_files(
- sub{
- if ( exists $generated_exts_all{ ext_no_period($file) }
- || exists $$PHdest{$file}
- ) {
- &rdb_update1;
- }
- }
- );
-} #END rdb_update_gen_files
-
-#************************************************************
-
-sub rdb_update_files {
- # Call: rdb_update_files
- # Assumes rule context. Update source files of rule to current state.
- rdb_do_files( \&rdb_update1 );
-}
-
-#************************************************************
-
-sub rdb_update1 {
- # Call: rdb_update1.
- # Assumes file context. Updates file data to correspond to
- # current file state on disk
- ($$Ptime, $$Psize, $$Pmd5) = fdb_get($file);
-}
-
-#************************************************************
-
-sub rdb_set_file1 {
- # Call: fdb_file1(rule, file, new_time, new_size, new_md5)
- # Sets file time, size and md5.
- my $rule = shift;
- my $file = shift;
- local @new_file_data = @_;
- rdb_for_one_file( $rule, $file, sub{ ($$Ptime,$$Psize,$$Pmd5)=@new_file_data; } );
-}
-
-#************************************************************
-
-sub rdb_dummy_file {
- # Returns file data for non-existent file
-# ==== Uses rule_db structure ====
- return (0, -1, 0, '');
-}
-
-#************************************************************
-#************************************************************
-
-# Predefined subroutines for custom dependency
-
-sub cus_dep_delete_dest {
- # This subroutine is used for situations like epstopdf.sty, when
- # the destination (target) of the custom dependency invoking
- # this subroutine will be made by the primary run provided the
- # file (destination of the custom dependency, source of the
- # primary run) doesn't exist.
- # It is assumed that the resulting file will be read by the
- # primary run.
-
- # Remove the destination file, to indicate it needs to be remade:
- unlink_or_move( $$Pdest );
- # Arrange that the non-existent destination file is not treated as
- # an error. The variable changed here is a bit misnamed.
- $$Pchanged = 1;
- # Ensure a primary run is done
- &cus_dep_require_primary_run;
- # Return success:
- return 0;
-}
-
-#************************************************************
-
-sub cus_dep_require_primary_run {
- # This subroutine is used for situations like epstopdf.sty, when
- # the destination (target) of the custom dependency invoking
- # this subroutine will be made by the primary run provided the
- # file (destination of the custom dependency, source of the
- # primary run) doesn't exist.
- # It is assumed that the resulting file will be read by the
- # primary run.
-
- local $cus_dep_target = $$Pdest;
- # Loop over all rules and source files:
- rdb_for_actives( 0,
- sub { if ($file eq $cus_dep_target) {
- $$Pout_of_date = 1;
- $$Pcorrect_after_primary = 1;
- }
- }
- );
- # Return success:
- return 0;
-}
-
-
-#************************************************************
-#************************************************************
-#************************************************************
-#
-# UTILITIES:
-#
-
-#************************************************************
-# Miscellaneous
-
-sub show_array {
-# For use in diagnostics and debugging.
-# On stderr, print line with $_[0] = label.
-# Then print rest of @_, one item per line preceeded by some space
- warn "$_[0]\n";
- shift;
- if ($#_ >= 0) {
- foreach (@_){
- if (defined $_ ) { warn " $_\n"; }
- else { warn " undef\n"; }
- }
- }
- else { warn " NONE\n"; }
-}
-
-
-#************************************************************
-
-sub array_to_hash {
- # Call: array_to_hash( items )
- # Returns: hash mapping items to 1
- my %hash = ();
- foreach (@_) {$hash{$_} = 1; }
- return %hash;
-}
-
-#************************************************************
-
-sub Parray {
- # Call: Parray( \@A )
- # Returns array of references to the elements of @A
- # But if an element of @A is already a reference, the
- # reference will be returned in the output array, not a
- # reference to the reference.
- my $PA = shift;
- my @P = (undef) x (1+$#$PA);
- foreach my $i (0..$#$PA) {
- $P[$i] = (ref $$PA[$i]) ? ($$PA[$i]) : (\$$PA[$i]);
- }
- return @P;
-}
-
-#************************************************************
-
-sub glob_list1 {
- # Glob a collection of filenames.
- # But no sorting or elimination of duplicates
- # Usage: e.g., @globbed = glob_list1(string, ...);
- # Since perl's glob appears to use space as separator, I'll do a special check
- # for existence of non-globbed file (assumed to be tex like)
-
- my @globbed = ();
- foreach my $file_spec (@_) {
- # Problem, when the PATTERN contains spaces, the space(s) are
- # treated as pattern separaters.
- # Solution: I now the glob from use File::Glob.
- # The following hack avoids issues with glob in the case that a file exists
- # with the specified name (possibly with extension .tex):
- if ( -e $file_spec || -e "$file_spec.tex" ) {
- # Non-globbed file exists, return the file_spec.
- # Return $file_spec only because this is not a file-finding subroutine, but
- # only a globber
- push @globbed, $file_spec;
- }
- else {
- push @globbed, my_glob( "$file_spec" );
- }
- }
- return @globbed;
-} #END glob_list1
-
-#************************************************************
-# Miscellaneous
-
-sub prefix {
- #Usage: prefix( string, prefix );
- #Return string with prefix inserted at the front of each line
- my @line = split( /\n/, $_[0] );
- my $prefix = $_[1];
- for (my $i = 0; $i <= $#line; $i++ ) {
- $line[$i] = $prefix.$line[$i]."\n";
- }
- return join( "", @line );
-} #END prefix
-
-
-#===============================
-
-sub parse_quotes {
- # Split string into words.
- # Words are delimited by space, except that strings
- # quoted all stay inside a word. E.g.,
- # 'asdf B" df "d "jkl"'
- # is split to ( 'asdf', 'B df d', 'jkl').
- # An array is returned.
- my @results = ();
- my $item = '';
- local $_ = shift;
- pos($_) = 0;
- ITEM:
- while() {
- /\G\s*/gc;
- if ( /\G$/ ) {
- last ITEM;
- }
- # Now pos (and \G) is at start of item:
- PART:
- while () {
- if (/\G([^\s\"]*)/gc) {
- $item .= $1;
- }
- if ( /\G\"([^\"]*)\"/gc ) {
- # Match balanced quotes
- $item .= $1;
- next PART;
- }
- elsif ( /\G\"(.*)$/gc ) {
- # Match unbalanced quote
- $item .= $1;
- warn "====Non-matching quotes in\n '$_'\n";
- }
- push @results, $item;
- $item = '';
- last PART;
- }
- }
- return @results;
-} #END parse_quotes
-
-#************************************************************
-#************************************************************
-# File handling utilities:
-
-
-#************************************************************
-
-sub get_latest_mtime
-# - arguments: each is a filename.
-# - returns most recent modify time.
-{
- my $return_mtime = 0;
- foreach my $include (@_)
- {
- my $include_mtime = &get_mtime($include);
- # The file $include may not exist. If so ignore it, otherwise
- # we'll get an undefined variable warning.
- if ( ($include_mtime) && ($include_mtime > $return_mtime) )
- {
- $return_mtime = $include_mtime;
- }
- }
- return $return_mtime;
-}
-
-#************************************************************
-
-sub get_mtime_raw
-{
- my $mtime = (stat($_[0]))[9];
- return $mtime;
-}
-
-#************************************************************
-
-sub get_mtime {
- return get_mtime0($_[0]);
-}
-
-#************************************************************
-
-sub get_mtime0 {
- # Return time of file named in argument
- # If file does not exist, return 0;
- if ( -e $_[0] ) {
- return get_mtime_raw($_[0]);
- }
- else {
- return 0;
- }
-}
-
-#************************************************************
-
-sub get_size {
- # Return time of file named in argument
- # If file does not exist, return 0;
- if ( -e $_[0] ) {
- return get_size_raw($_[0]);
- }
- else {
- return 0;
- }
-}
-
-#************************************************************
-
-sub get_size_raw
-{
- my $size = (stat($_[0]))[7];
- return $size;
-}
-
-#************************************************************
-
-sub get_time_size {
- # Return time and size of file named in argument
- # If file does not exist, return (0,-1);
- if ( -e $_[0] ) {
- return get_time_size_raw($_[0]);
- }
- else {
- return (0,-1);
- }
-}
-
-#************************************************************
-
-sub get_time_size_raw
-{
- my $mtime = (stat($_[0]))[9];
- my $size = (stat($_[0]))[7];
- return ($mtime, $size);
-}
-
-#************************************************************
-
-sub processing_time
-{ my ($user, $system, $cuser, $csystem) = times();
- return $user + $system + $cuser + $csystem;
-}
-
-#************************************************************
-
-sub get_checksum_md5 {
- my $source = shift;
- my $input = new FileHandle;
- my $md5 = Digest::MD5->new;
- my $ignore_pattern = undef;
-
-#warn "======= GETTING MD5: $source\n";
- if ( -d $source ) {
- # We won't use checksum for directory
- return 0;
- }
- else {
- open( $input, '<:bytes', $source )
- or return 0;
- my ($base, $path, $ext) = fileparseA( $source );
- $ext =~ s/^\.//;
- if ( exists $hash_calc_ignore_pattern{$ext} ) {
- $ignore_pattern = $hash_calc_ignore_pattern{$ext};
- }
- }
- if ( defined $ignore_pattern ) {
- while (<$input>) {
- if ( ! /$ignore_pattern/ ){
- $md5->add($_);
- }
- }
- }
- else {
- $md5->addfile($input);
- }
- close $input;
- return $md5->hexdigest();
-}
-
-#************************************************************
-#************************************************************
-
-sub create_empty_file {
- my $name = shift;
- my $h = new FileHandle ">$name"
- or return 1;
- close ($h);
- return 0;
-}
-
-#************************************************************
-#************************************************************
-
-sub find_file1 {
- # Usage: find_file1(name, ref_to_array_search_path)
- # Modified find_file, which doesn't die.
- # Given filename and path, return array of:
- # full name
- # retcode
- # On success: full_name = full name with path, retcode = 0
- # On failure: full_name = given name, retcode = 1
-
- my $name = $_[0];
- # Make local copy of path, since we may rewrite it!
- my @path = ();
- if ($_[1]) {
- @path = @{$_[1]};
- }
- if ( $name =~ /^\// ) {
- # Absolute path (if under UNIX)
- # This needs fixing, in general
- if (-e $name) { return( $name, 0 );}
- else { return( $name, 1 );}
- }
- foreach my $dir ( @path ) {
- #??print "-------------dir='$dir', ";
- # Make $dir concatenatable, and empty for current dir:
- if ( $dir eq '.' ) {
- $dir = '';
- }
- elsif ( $dir =~ /[\/\\:]$/ ) {
- #OK if dir ends in / or \ or :
- }
- elsif ( $dir ne '' ) {
- #Append directory separator only to non-empty dir
- $dir = "$dir/";
- }
- #?? print " newdir='$dir'\n";
- if (-e "$dir$name") {
- return("$dir$name", 0);
- }
- }
- my @kpse_result = kpsewhich( $name );
- if ($#kpse_result > -1) {
- return( $kpse_result[0], 0);
- }
- return("$name" , 1);
-} #END find_file1
-
-#************************************************************
-
-sub find_file_list1 {
- # Modified version of find_file_list that doesn't die.
- # Given output and input arrays of filenames, a file suffix, and a path,
- # fill the output array with full filenames
- # Return array of not-found files.
- # Usage: find_file_list1( ref_to_output_file_array,
- # ref_to_input_file_array,
- # suffix,
- # ref_to_array_search_path
- # )
- # SPECIAL TREATMENT TO .bib extension, because of behavior of bibtex
- # OTHER SPECIAL TREATMENT IF EXTENSION IS GIVEN.
-
- my $ref_output = $_[0];
- my $ref_input = $_[1];
- my $suffix = $_[2];
- my $ref_search = $_[3];
- my @not_found = ();
-
-#?? show_array( "=====find_file_list1. Suffix: '$suffix'\n Source:", @$ref_input );
-#?? show_array( " Bibinputs:", @$ref_search );
-
- my @return_list = (); # Generate list in local array, since input
- # and output arrays may be same
- my $retcode = 0;
- foreach my $file1 (@$ref_input) {
- my $file = $file1;
- if ($suffix eq '.bib') { $file =~ s/\.bib$//; }
- my ($tmp_file, $find_retcode) = &find_file1( "$file$suffix", $ref_search );
- if ($tmp_file) {
- push @return_list, $tmp_file;
- }
- if ( $find_retcode != 0 ) {
- push @not_found, $file.$suffix;
- }
- }
- @$ref_output = @return_list;
-#?? show_array( " Output", @$ref_output );
-#?? foreach (@$ref_output) { if ( /\/\// ) { print " ====== double slash in '$_'\n"; } }
- return @not_found;
-} #END find_file_list1
-
-#************************************************************
-
-sub unlink_or_move {
- if ( $del_dir eq '' ) {
- foreach (@_) {
- if (!-e) {next;}
- if (-d) {
- if (!rmdir) {
- warn "$My_name: Cannot remove directory '$_'\n";
- }
- }
- else {
- if (!unlink) {
- warn "$My_name: Cannot remove file '$_'\n";
- }
- }
- }
- }
- else {
- foreach (@_) {
- if (-e $_ && ! move $_, "$del_dir/$_" ) {
- warn "$My_name: Cannot move '$_' to '$del_dir/$_'\n";
- }
- }
- }
-}
-
-#************************************************************
-
-sub kpsewhich {
-# Usage: kpsewhich( filespec, ...)
-# Returns array of files with paths as found by kpsewhich
-# kpsewhich( 'try.sty', 'jcc.bib' );
-# With standard use of kpsewhich (i.e., without -all option), the array
-# has either 0 or 1 element.
-# Can also do, e.g.,
-# kpsewhich( '-format=bib', 'trial.bib', 'file with spaces');
- my $cmd = $kpsewhich;
- my @args = @_;
- if ( ($cmd eq '') || ( $cmd =~ /^NONE($| )/ ) ) {
- # Kpsewhich not set up.
- warn "$My_name: Kpsewhich command needed but not set up\n";
- return ();
- }
- foreach (@args) {
- if ( ! /^-/ ) {
- $_ = "\"$_\"";
- }
- }
- $cmd =~ s/%[RBTDO]//g;
- $cmd =~ s/%S/@args/g;
- my @found = ();
- local $fh;
- if ( $kpsewhich_show || $diagnostics ) {
- print "$My_name.kpsewhich: Running '$cmd'...\n";
- }
- open $fh, "$cmd|"
- or die "Cannot open pipe for \"$cmd\"\n";
- while ( <$fh> ) {
- s/[\r\n]*$//;
- push @found, $_;
- }
- close $fh;
- if ( $kpsewhich_show || $diagnostics ) {
- show_array( "$My_name.kpsewhich: '$cmd' ==>", @found );
- }
- return @found;
-}
-
-####################################################
-
-sub add_cus_dep {
- # Usage: add_cus_dep( from_ext, to_ext, flag, sub_name )
- # Add cus_dep after removing old versions
- my ($from_ext, $to_ext, $must, $sub_name) = @_;
- remove_cus_dep( $from_ext, $to_ext );
- push @cus_dep_list, "$from_ext $to_ext $must $sub_name";
-}
-
-####################################################
-
-sub remove_cus_dep {
- # Usage: remove_cus_dep( from_ext, to_ext )
- my ($from_ext, $to_ext) = @_;
- my $i = 0;
- while ($i <= $#cus_dep_list) {
- # Use \Q and \E round directory name in regex to avoid interpretation
- # of metacharacters in directory name:
- if ( $cus_dep_list[$i] =~ /^\Q$from_ext $to_ext \E/ ) {
- splice @cus_dep_list, $i, 1;
- }
- else {
- $i++;
- }
- }
-}
-
-####################################################
-
-sub show_cus_dep {
- show_array( "Custom dependency list:", @cus_dep_list );
-}
-
-####################################################
-
-sub find_cus_dep {
- # Usage find_cus_dep( dest, source )
- # Given dest, if a cus_dep to make it is found, set source.
- # Return 1 or 0 on success or failure.
- #
- my $dest = $_[0];
- my ($base, $path, $ext) = fileparseB( $dest );
- $ext =~ s/^\.//;
- if (! $ext ) { return 0; }
- foreach my $dep ( @cus_dep_list ) {
- my ($fromext, $toext) = split( '\s+', $dep );
- if ( ( "$ext" eq "$toext" ) && ( -f "$path$base.$fromext" ) ) {
- # We have a way of making $dest
- $_[1] = "$path$base.$fromext";
- return 1
- }
- }
- return 0;
-}
-
-####################################################
-####################################################
-
-sub add_aux_hook {
- # Usage: add_aux_hook( sub_name )
- # Add the name subroutine to the array of hooks for
- # processing lines of aux files.
- # The argument is either a string naming the subroutine, e.g.
- # add_aux_hook( 'subname' );
- # or a Perl reference to the subroutine, e.g.,
- # add_aux_hook( \&subname );
- # It is also possible to use an anonymous subroutine, e.g.,
- # add_aux_hook( sub{ code of subroutine... } );
- my ($sub_name) = @_;
- push @aux_hooks, $sub_name;
-}
-
-####################################################
-
-sub add_latex_file_hook {
- # Usage: add_latex_file_hook( sub_name )
- # Add the name subroutine to the array of hooks for
- # processing list of possible dependency files after a run of *latex.
- # The argument is either a string naming the subroutine, e.g.
- # add_latex_file_hook( 'subname' );
- # or a Perl reference to the subroutine, e.g.,
- # add_latex_file_hook( \&subname );
- # It is also possible to use an anonymous subroutine, e.g.,
- # add_latex_file_hook( sub{ code of subroutine... } );
- my ($sub_name) = @_;
- push @latex_file_hooks, $sub_name;
-}
-
-####################################################
-
-sub set_input_ext {
- # Usage: set_input_ext( rule, ext, ... )
- # Set list of extension(s) (specified without a leading period)
- # for the given rule ('latex', 'pdflatex', etc).
- # These extensions are used when an input
- # file without an extension is found by *latex, as in
- # \input{file} or \includegraphics{figure}. When latexmk searches
- # custom dependencies to make the missing file, it will assume that
- # the file has one of the specified extensions.
- my $rule = shift;
- $input_extensions{$rule} = {};
- my $Prule = $input_extensions{$rule};
- foreach (@_) { $$Prule{$_} = 1; }
-}
-
-####################################################
-
-sub show_input_ext {
- # Usage: show_input_ext( rule )
- my $rule = shift;
- show_array ("Input extensions for rule '$rule': ",
- keys %{$input_extensions{$rule}} );
-}
-
-####################################################
-
-sub find_dirs1 {
- # Same as find_dirs, but argument is single string with directories
- # separated by $search_path_separator
- find_dirs( &split_search_path( $search_path_separator, ".", $_[0] ) );
-}
-
-
-#************************************************************
-
-sub find_dirs {
-# @_ is list of directories
-# return: same list of directories, except that for each directory
-# name ending in //, a list of all subdirectories (recursive)
-# is added to the list.
-# Non-existent directories and non-directories are removed from the list
-# Trailing "/"s and "\"s are removed
- local @result = ();
- my $find_action
- = sub
- { ## Subroutine for use in File::find
- ## Check to see if we have a directory
- if (-d) { push @result, $File::Find::name; }
- };
- foreach my $directory (@_) {
- my $recurse = ( $directory =~ m[//$] );
- # Remove all trailing /s, since directory name with trailing /
- # is not always allowed:
- $directory =~ s[/+$][];
- # Similarly for MSWin reverse slash
- $directory =~ s[\\+$][];
- if ( ! -e $directory ){
- next;
- }
- elsif ( $recurse ){
- # Recursively search directory
- find( $find_action, $directory );
- }
- else {
- push @result, $directory;
- }
- }
- return @result;
-}
-
-#************************************************************
-
-sub uniq
-# Read arguments, delete neighboring items that are identical,
-# return array of results
-{
- my @sort = ();
- my ($current, $prev);
- my $first = 1;
- while (@_)
- {
- $current = shift;
- if ($first || ($current ne $prev) )
- {
- push @sort, $current;
- $prev = $current;
- $first = 0;
- }
- }
- return @sort;
-}
-
-#==================================================
-
-sub uniq1 {
- # Usage: uniq1( strings )
- # Returns array of strings with duplicates later in list than
- # first occurence deleted. Otherwise preserves order.
-
- my @strings = ();
- my %string_hash = ();
-
- foreach my $string (@_) {
- if (!exists( $string_hash{$string} )) {
- $string_hash{$string} = 1;
- push @strings, $string;
- }
- }
- return @strings;
-}
-
-#************************************************************
-
-sub uniqs {
- # Usage: uniq2( strings )
- # Returns array of strings sorted and with duplicates deleted
- return uniq( sort @_ );
-}
-
-#************************************************************
-
-sub ext {
- # Return extension of filename. Extension includes the period
- my $file_name = $_[0];
- my ($base_name, $path, $ext) = fileparseA( $file_name );
- return $ext;
- }
-
-#************************************************************
-
-sub ext_no_period {
- # Return extension of filename. Extension excludes the period
- my $file_name = $_[0];
- my ($base_name, $path, $ext) = fileparseA( $file_name );
- $ext =~ s/^\.//;
- return $ext;
- }
-
-#************************************************************
-
-sub fileparseA {
- # Like fileparse but replace $path for current dir ('./' or '.\') by ''
- # Also default second argument to get normal extension.
- my $given = $_[0];
- my $pattern = '\.[^\.]*';
- if ($#_ > 0 ) { $pattern = $_[1]; }
- my ($base_name, $path, $ext) = fileparse( $given, $pattern );
- if ( ($path eq './') || ($path eq '.\\') ) {
- $path = '';
- }
- return ($base_name, $path, $ext);
-}
-
-#************************************************************
-
-sub fileparseB {
- # Like fileparse but with default second argument for normal extension
- my $given = $_[0];
- my $pattern = '\.[^\.]*';
- if ($#_ > 0 ) { $pattern = $_[1]; }
- my ($base_name, $path, $ext) = fileparse( $given, $pattern );
- return ($base_name, $path, $ext);
-}
-
-#************************************************************
-
-sub split_search_path
-{
-# Usage: &split_search_path( separator, default, string )
-# Splits string by separator and returns array of the elements
-# Allow empty last component.
-# Replace empty terms by the default.
- my $separator = $_[0];
- my $default = $_[1];
- my $search_path = $_[2];
- my @list = split( /$separator/, $search_path);
- if ( $search_path =~ /$separator$/ ) {
- # If search path ends in a blank item, the split subroutine
- # won't have picked it up.
- # So add it to the list by hand:
- push @list, "";
- }
- # Replace each blank argument (default) by current directory:
- for ($i = 0; $i <= $#list ; $i++ ) {
- if ($list[$i] eq "") {$list[$i] = $default;}
- }
- return @list;
-}
-
-#################################
-
-sub get_filetime_offset {
- # Usage: get_filetime_offset( prefix, [suffix] )
- # Measures offset between filetime in a directory and system time
- # Makes a temporary file of a unique name, and deletes in.
- # Filename is of form concatenation of prefix, an integer, suffix.
- # Prefix is normally of form dir/ or dir/tmp.
- # Default default suffix ".tmp".
- my $prefix = $_[0];
- my $suffix = $_[1] || '.tmp';
- my $tmp_file_count = 0;
- while (1==1) {
- # Find a new temporary file, and make it.
- $tmp_file_count++;
- my $tmp_file = "${prefix}${tmp_file_count}${suffix}";
- if ( ! -e $tmp_file ) {
- open( TMP, ">$tmp_file" )
- or die "$My_name.get_filetime_offset: In measuring filetime offset, couldn't write to\n",
- " temporary file '$tmp_file'\n";
- my $time = time();
- close(TMP);
- my $offset = get_mtime($tmp_file) - $time;
- unlink $tmp_file;
- return $offset;
- }
- }
- die "$My_name.get_filetime_offset: BUG TO ARRIVE HERE\n";
-}
-
-#################################
-
-sub tempfile1 {
- # Makes a temporary file of a unique name. I could use file::temp,
- # but it is not present in all versions of perl.
- # Filename is of form $tmpdir/$_[0]nnn$suffix, where nnn is an integer
- my $tmp_file_count = 0;
- my $prefix = $_[0];
- my $suffix = $_[1];
- while (1==1) {
- # Find a new temporary file, and make it.
- $tmp_file_count++;
- my $tmp_file = "${tmpdir}/${prefix}${tmp_file_count}${suffix}";
- if ( ! -e $tmp_file ) {
- open( TMP, ">$tmp_file" )
- or next;
- close(TMP);
- return $tmp_file;
- }
- }
- die "$My_name.tempfile1: BUG TO ARRIVE HERE\n";
-}
-
-#################################
-
-#************************************************************
-#************************************************************
-# Process/subprocess routines
-
-sub Run_msg {
- # Same as Run, but give message about my running
- warn_running( "Running '$_[0]'" );
- return Run($_[0]);
-} #END Run_msg
-
-#==================
-
-sub Run {
- # This is wrapper around Run_no_time to capture timing information
- my $time1 = processing_time();
- my ($pid, $return) = Run_no_time($_[0]);
- my $time = processing_time() - $time1;
- push @timings, "'$_[0]': time = $time\n";
- return ($pid, $return);
-} #END Run_msg
-
-#==================
-
-sub Run_no_time {
-# Usage: Run_no_time ("command string");
-# or Run_no_time ("one-or-more keywords command string");
-# Possible keywords: internal, NONE, start, nostart.
-#
-# A command string not started by keywords just gives a call to system with
-# the specified string, I return after that has finished executing.
-# Exceptions to this behavior are triggered by keywords.
-# The general form of the string is
-# Zero or more occurences of the start keyword,
-# followed by at most one of the other key words (internal, nostart, NONE),
-# followed by (a) a command string to be executed by the systerm
-# or (b) if the command string is specified to be internal, then
-# it is of the form
-#
-# routine arguments
-#
-# which implies invocation of the named Perl subroutine
-# with the given arguments, which are obtained by splitting
-# the string into words, delimited by spaces, but with
-# allowance for double quotes.
-#
-# The meaning of the keywords is:
-#
-# start: The command line is to be running detached, as appropriate for
-# a previewer. The method is appropriate for the operating system
-# (and the keyword is inspired by the action of the start command
-# that implements in under MSWin).
-# HOWEVER: the start keyword is countermanded by the nostart,
-# internal, and NONE keywords. This allows rules that do
-# previewing to insert a start keyword to create a presumption
-# of detached running unless otherwise.
-# nostart: Countermands a previous start keyword; the following command
-# string is then to be obeyed by the system, and any necessary
-# detaching (as of a previewer) is done by the executed command(s).
-# internal: The following command string, of the form 'routine arguments'
-# specifies a call to the named Perl subroutine.
-# NONE: This does not run anything, but causes an error message to be
-# printed. This is provided to allow program names defined in the
-# configuration to flag themselves as unimplemented.
-# Note that if the word "start" is duplicated at the beginning, that is
-# equivalent to a single "start".
-#
-# Return value is a list (pid, exitcode):
-# If a process is spawned sucessfully, and I know the PID,
-# return (pid, 0),
-# else if process is spawned sucessfully, but I do not know the PID,
-# return (0, 0),
-# else if process is run,
-# return (0, exitcode of process)
-# else if I fail to run the requested process
-# return (0, suitable return code)
-# where return code is 1 if cmdline is null or begins with "NONE" (for
-# an unimplemented command)
-# or the return value of the Perl subroutine.
- my $cmd_line = $_[0];
- if ( $cmd_line eq '' ) {
- traceback( "$My_name: Bug OR configuration error\n".
- " In run of '$rule', attempt to run a null program" );
- return (0, 1);
- }
- # Deal with latexmk-defined pseudocommands 'start' and 'NONE'
- # at front of command line:
- my $detach = 0;
- while ( $cmd_line =~ s/^start +// ) {
- # But first remove extra starts (which may have been inserted
- # to force a command to be run detached, when the command
- # already contained a "start").
- $detach = 1;
- }
- if ( $cmd_line =~ s/^nostart +// ) {
- $detach = 0;
- }
- if ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s+(.*)$/ ) {
- my $routine = $1;
- my @args = parse_quotes( $2 );
- warn "$My_name: calling $routine( $2 )\n"
- if (! $silent);
- return ( 0, &$routine( @args ) );
- }
- elsif ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s*$/ ) {
- my $routine = $1;
- warn "$My_name: calling $routine()\n"
- if (! $silent);
- return ( 0, &$routine() );
- }
- elsif ( $cmd_line =~ /^NONE/ ) {
- warn "$My_name: ",
- "Program not implemented for this version. Command line:\n";
- warn " '$cmd_line'\n";
- return (0, 1);
- }
- elsif ($detach) {
- # Run detached. How to do this depends on the OS
- return &Run_Detached( $cmd_line );
- }
- else {
- # The command is given to system as a single argument, to force shell
- # metacharacters to be interpreted:
- return( 0, system( $cmd_line ) );
- }
-} #END Run
-
-#************************************************************
-
-sub Run_Detached {
-# Usage: Run_Detached ("program arguments ");
-# Runs program detached. Returns 0 on success, 1 on failure.
-# Under UNIX use a trick to avoid the program being killed when the
-# parent process, i.e., me, gets a ctrl/C, which is undesirable for pvc
-# mode. (The simplest method, system("program arguments &"), makes the
-# child process respond to the ctrl/C.)
-# Return value is a list (pid, exitcode):
-# If process is spawned sucessfully, and I know the PID,
-# return (pid, 0),
-# else if process is spawned sucessfully, but I do not know the PID,
-# return (0, 0),
-# else if I fail to spawn a process
-# return (0, 1)
-
- my $cmd_line = $_[0];
-
-## warn "Running '$cmd_line' detached...\n";
- if ( $cmd_line =~ /^NONE / ) {
- warn "$My_name: ",
- "Program not implemented for this version. Command line:\n";
- warn " '$cmd_line'\n";
- return (0, 1);
- }
-
- if ( "$^O" eq "MSWin32" ){
- # Win95, WinNT, etc: Use MS's start command:
- # Need extra double quotes to deal with quoted filenames:
- # MSWin start takes first quoted argument to be a Window title.
- return( 0, system( "start \"\" $cmd_line" ) );
- } else {
- # Assume anything else is UNIX or clone
- # For this purpose cygwin behaves like UNIX.
- ## warn "Run_Detached.UNIX: A\n";
- my $pid = fork();
- ## warn "Run_Detached.UNIX: B pid=$pid\n";
- if ( ! defined $pid ) {
- ## warn "Run_Detached.UNIX: C\n";
- warn "$My_name: Could not fork to run the following command:\n";
- warn " '$cmd_line'\n";
- return (0, 1);
- }
- elsif( $pid == 0 ){
- ## warn "Run_Detached.UNIX: D\n";
- # Forked child process arrives here
- # Insulate child process from interruption by ctrl/C to kill parent:
- # setpgrp(0,0);
- # Perhaps this works if setpgrp doesn't exist
- # (and therefore gives fatal error):
- eval{ setpgrp(0,0);};
- exec( $cmd_line );
- # Exec never returns; it replaces current process by new process
- die "$My_name forked process: could not run the command\n",
- " '$cmd_line'\n";
- }
- ##warn "Run_Detached.UNIX: E\n";
- # Original process arrives here
- return ($pid, 0);
- }
- # NEVER GET HERE.
- ##warn "Run_Detached.UNIX: F\n";
-} #END Run_Detached
-
-#************************************************************
-
-sub find_process_id {
-# find_process_id(string) finds id of process containing string and
-# being run by the present user. Typically the string will be the
-# name of the process or part of its command line.
-# On success, this subroutine returns the process ID.
-# On failure, it returns 0.
-# This subroutine only works on UNIX systems at the moment.
-
- if ( $pid_position < 0 ) {
- # I cannot do a ps on this system
- return (0);
- }
-
- my $looking_for = $_[0];
- my @ps_output = `$pscmd`;
- my @ps_lines = ();
-
-# There may be multiple processes. Find only latest,
-# almost surely the one with the highest process number
-# This will deal with cases like xdvi where a script is used to
-# run the viewer and both the script and the actual viewer binary
-# have running processes.
- my @found = ();
-
- shift(@ps_output); # Discard the header line from ps
- foreach (@ps_output) {
- next unless ( /$looking_for/ ) ;
- s/^\s*//;
- my @ps_line = split ('\s+');
- push @found, $ps_line[$pid_position];
- push @ps_lines, $_;
- }
-
- if ($#found < 0) {
- # No luck in finding the specified process.
- return(0);
- }
- @found = reverse sort @found;
- if ($diagnostics) {
- print "Found the following processes concerning '$looking_for'\n",
- " @found\n",
- " I will use $found[0]\n";
- print " The relevant lines from '$pscmd' were:\n";
- foreach (@ps_lines) { print " $_"; }
- }
- return $found[0];
-}
-
-#************************************************************
-#************************************************************
-#************************************************************
-
-#============================================
-
-sub cache_good_cwd {
- # Set cached value of cwd to current cwd.
- # Under cygwin, the cached value is converted to a native MSWin path so
- # that the result can be used for input to MSWin programs as well
- # as cygwin programs.
- # Similarly for msys.
- my $cwd = cwd();
- if ( $^O eq "cygwin" ) {
- my $cmd = "cygpath -w \"$cwd\"";
- my $Win_cwd = `$cmd`;
- chomp $Win_cwd;
- if ( $Win_cwd ) {
- $cwd = $Win_cwd;
- }
- else {
- warn "$My_name: Could not correctly run command\n",
- " '$cmd'\n",
- " to get MSWin version of cygwin path\n",
- " '$cwd'\n",
- " The result was\n",
- " '$Win_cwd'\n";
- }
- }
- elsif ( $^O eq "msys" ) {
- $cwd =~ s[^/([a-z])/][\u$1:/];
- }
- $cache{cwd} = $cwd;
-} # END cache_good_cwd
-
-#============================================
-
-sub good_cwd {
- # Return cwd, but under cygwin (or ...), convert to MSWin path.
- # Use cached result, to save a possible expensive computation (running
- # of extenal program under cygwin).
- return $cache{cwd};
-} # END good_cwd
-
-#============================================
-
-# Directory stack routines
-
-sub pushd {
- push @dir_stack, [cwd(), $cache{cwd}];
- if ( $#_ > -1) {
- chdir dirname_no_tail( $_[0] );
- &cache_good_cwd;
- }
-}
-
-#************************************************************
-
-sub popd {
- if ($#dir_stack > -1 ) {
- my $Parr = pop @dir_stack;
- chdir $$Parr[0];
- $cache{cwd} = $$Parr[1];
- }
-}
-
-#************************************************************
-
-sub ifcd_popd {
- if ( $do_cd ) {
- warn "$My_name: Undoing directory change\n"
- if !$silent;
- &popd;
- }
-}
-
-#************************************************************
-
-sub finish_dir_stack {
- while ($#dir_stack > -1 ) { &popd; }
-}
-
-#************************************************************
-#************************************************************
-# Break handling routines (for wait-loop in preview continuous)
-
-sub end_wait {
- # Handler for break: Set global variable $have_break to 1.
- # Some systems (e.g., MSWin reset) appear to reset the handler.
- # So I'll re-enable it
- &catch_break;
- $have_break = 1;
-}
-
-#========================
-
-sub catch_break {
-# Capture ctrl/C and ctrl/break.
-# $SIG{INT} corresponds to ctrl/C on LINUX/?UNIX and MSWin
-# $SIG{BREAK} corresponds to ctrl/break on MSWin, doesn't exist on LINUX
- $SIG{INT} = \&end_wait;
- if ( exists $SIG{BREAK} ) {
- $SIG{BREAK} = \&end_wait;
- }
-}
-
-#========================
-
-sub default_break {
-# Arrange for ctrl/C and ctrl/break to give default behavior
- $SIG{INT} = 'DEFAULT';
- if ( exists $SIG{BREAK} ) {
- $SIG{BREAK} = 'DEFAULT';
- }
-}
-
-#************************************************************
-#************************************************************
diff --git a/Build/source/texk/texlive/linked_scripts/latexpand/latexpand b/Build/source/texk/texlive/linked_scripts/latexpand/latexpand
deleted file mode 100755
index e7de1965f1c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/latexpand/latexpand
+++ /dev/null
@@ -1,665 +0,0 @@
-#!/usr/bin/perl
-# Inspired by latexpand by D. Musliner, University of Michigan
-# 2012-2019: Matthieu Moy <git@matthieu-moy.fr>
-# BSD License
-
-use strict;
-use Cwd;
-use Getopt::Long;
-use IO::Handle;
-use File::Spec;
-
-my $TEXINPUTS = $ENV{'TEXINPUTS'};
-# By default, search in current directory. We use '.' and not getcwd()
-# to avoid issues if the working directory contains a ':' character.
-if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
-
-my $verbose;
-my $keep_comments;
-my $keep_includes;
-my $empty_comments;
-my $help;
-my $long_help;
-my $output;
-my $explain;
-my $show_graphics;
-my $graphics_extensions = ":.pdf:.png:.jpg:.eps";
-my $expand_usepackage;
-my $expand_bbl;
-my $biber;
-my $fatal;
-my $version;
-my $makeatletter;
-my $inside_import;
-my $in_enc = "bytes";
-my $out_enc = "bytes";
-
-GetOptions (
- 'h' => \$help,
- 'help' => \$long_help,
- 'verbose|v' => \$verbose,
- 'keep-comments' => \$keep_comments,
- 'keep-includes' => \$keep_includes,
- 'empty-comments' => \$empty_comments,
- 'output|o=s' => \$output,
- 'explain' => \$explain,
- 'show-graphics' => \$show_graphics,
- 'graphics-extensions' => \$graphics_extensions,
- 'expand-usepackage' => \$expand_usepackage,
- 'expand-bbl=s' => \$expand_bbl,
- 'biber=s' => \$biber,
- 'fatal' => \$fatal,
- 'version' => \$version,
- 'makeatletter' => \$makeatletter,
- 'in-encoding=s' => \$in_enc,
- 'out-encoding=s' => \$out_enc,
-) or pod2usage_wrapper(2);
-version() if $version;
-pod2usage_wrapper(0) if $help;
-pod2usage_wrapper(-exitstatus => 0, -output => \*STDOUT, -verbose => 2) if $long_help;
-
-sub pod2usage_wrapper
-{
- # Like pod2usage, but fall back to a simpler implem in case
- # pod2usage can't be found.
- if (eval {require Pod::Usage;1;} ne 1) {
- print "Please install perldoc and Pod::Usage to get proper help.\n";
- my $started = 0;
- open (my $in, '<', "$0") or die $!;
- while (<$in>) {
- if ($started) {
- print;
- }
- if (/^__END__$/) {
- $started = 1;
- }
- }
- } else {
- Pod::Usage->import();
- pod2usage(@_);
- }
-}
-
-sub get_version
-{
- # $VERSION's value will be substituted by 'make dist', but the
- # next line won't (the string has to be broken to avoid it).
- my $VERSION = 'v1.6';
- if ($VERSION eq '@LATEXPAND' . '_VERSION@') {
- my($vol,$dir,$file) = File::Spec->splitpath($0);
- chdir($dir);
- $VERSION = `git describe --tags HEAD 2>/dev/null`;
- }
- if ($VERSION eq '') {
- $VERSION = '<unknown version>';
- }
- $VERSION =~ s/^\s+|\s+$//g;
- return $VERSION;
-}
-
-sub version
-{
- print "latexpand version ". get_version() .".\n";
- exit(0);
-}
-
-my $nl = "";
-if ($empty_comments) {
- $nl = "%\n";
-}
-
-if ($output && $output ne "-") {
- open (my $OUTPUT, '>', "$output") or die $!;
- STDOUT->fdopen(\*$OUTPUT, 'w') or die $!;
-}
-
-sub say
-{
- if ($verbose) {
- print STDERR "$_[0]";
- }
-}
-
-my $makeatletter_found;
-my $in_preamble;
-
-use open IN => ":$in_enc", OUT => ":$out_enc";
-
-foreach my $file (@ARGV)
-{
- say "processing $file\n";
- $makeatletter_found = 0;
- $in_preamble = 1;
- $inside_import = "";
- process_file($file, " ");
-}
-
-sub cat_file
-{
- my $file = shift;
- open (my $INFILE, "<", $file) || die "could not open input file '$file'\n";
- while (<$INFILE>) {
- print;
- }
- close ($INFILE);
-}
-
-sub process_file
-{
- my $file = shift;
- my $prefix = (shift || "");
- my $in_comment = 0;
- open(my $FILE, "<", $file) or die "could not open input file '$file'\n";
- my $commented_newline = 0;
- while (my $line = <$FILE>) {
- if ($line =~ /^[ \t]*\\endinput/) {
- $line =~ s/(\\endinput.*)\n/% $1/;
- $in_comment = 1;
- process_line($line, $prefix, \$commented_newline);
- last;
- }
- process_line($line, $prefix, \$commented_newline, $file);
- if ($line =~ /^%.*[^\n]\z/ || $line =~ /[^\\]%.*[^\n]\z/) {
- # file ends with a comment not ending with a newline
- print "\n";
- }
- # Garbage at end of line after \end{document} is
- # ignored by LaTeX, but we don't allow anything before
- # to avoid e.g. \verb|\end{document}| from terminating
- # the file.
- if (!$keep_comments && $line =~ /^[ \t]*\\end\{document\}/) {
- last;
- }
- }
- close($FILE);
- return $in_comment;
-}
-
-sub process_line
-{
- my ($line, $prefix, $commented_newline, $file) = @_;
- $_ = $line;
- if ($$commented_newline) {
- # Leading whitespaces after a comment is ignored.
- # There's no space in:
- # Line 1%
- # Line 2.
- # Match just space and tabs (\s would match \n)
- s/^[ \t]*//;
- if (/^$/) {
- # Deal with:
- #
- # Line 1 % comment
- #
- # Line 2
- #
- # The newline after Line 1 is commented, but we still
- # want a new paragraph. We strip the comment together
- # with its newline, but re-add a newline to chnge
- # paragraph here if needed:
- print "\n";
- }
- }
- $$commented_newline = 0;
- # Consider \makeatletter only in preamble, because we do want
- # to warn on \someCommand{\makeatletter\command@with@arobase}.
- if ($in_preamble && /^[^%]*\\makeatletter/) {
- $makeatletter_found = 1;
- }
- if ($in_preamble && /^[^%]*\\makeatother/) {
- $makeatletter_found = 0;
- }
- my $command;
- if (!$makeatletter && !$makeatletter_found
- && (($command) = /^[^%]*(\\[[:alpha:]]*@[[:alpha:]]*)/)
- && ($command ne '\@')) {
- print STDERR "Warning: command $command containing @ found in\n";
- print STDERR "Warning: $file.\n";
- print STDERR "Warning: consider using --makeatletter if the result is not compilable.\n";
- }
-
- # non-comment is a sequence of:
- # - escaped character (\\.), including \% and \\
- # - neither '%' nor '\'.
- my $NON_COMMENT = '([^\\\\%]|\\\\.)*';
-
- unless ($keep_comments) {
- if (!$empty_comments) {
- # Include \n in pattern to avoid matching
- # comments at end of files
-
- # remove comments + whitespace-only lines completely
- if (s/^\s*%.*\n//) {
- $$commented_newline = 1;
- }
-
- # Special-case commands at end of line. We
- # don't want "\\foo%\nbar" to become
- # "\\foobar"
- if (s/^($NON_COMMENT\\[[:alpha:]@]+)%.*\n/$1 /) {
- $$commented_newline = 1;
- } elsif (s/^($NON_COMMENT)%.*\n/$1/) {
- # remove only the comment if the line has actual content
- $$commented_newline = 1;
- }
- }
- # Apply the "empty comments" treatment unconditionally
- # for comments not matched above (it doesn't harm to
- # keep an empty comment sometimes, but it may harm to
- # leave a real comment if the goal was to strip them).
- s/^(([^\\%]|\\.)*)%.*$/$1%/;
- }
-
- unless ($keep_includes) {
- # \input{foo.tex}
- my $ARGBRACES = '\{\\s*([^"}\\s][^}]*)(\\s*)\}';
- # \input{"foo bar.tex"}
- my $ARGQUOTED = '\{\\s*"([^"]*)"(\\s*)\}';
- # \input foo.tex
- my $ARGSPACES = '\\s([^\{\\s][^\\s]+?)\\s()';
- my $ARGUMENT = "\\s*?(?|$ARGBRACES|$ARGQUOTED|$ARGSPACES)";
-
- if (my ($before, $ignored, $full_filename, $trailing, $after)
- = /^($NON_COMMENT)\\include$ARGUMENT(.*)$/) {
- $full_filename = find_tex_file($full_filename . ".tex");
- if ($full_filename) {
- say $prefix . "Found include for file: $full_filename\n";
- print $before . $nl;
- print '\clearpage{}' . $nl;
- print "% start include $full_filename\n" if ($explain);
- my $in_comment = process_file($full_filename, $prefix . " ");
- if ($explain) {
- print " % end include $full_filename\n";
- } elsif ($in_comment) {
- print "\n";
- }
- print '\clearpage{}' . $nl;
- print $nl . $after . "\n";
- $_ = "";
- }
- } elsif (my ($before, $ignored, $full_filename, $trailing, $after)
- = /^($NON_COMMENT)\\input$ARGUMENT(.*)$/) {
- if ($inside_import) {
- $full_filename = $inside_import . $full_filename;
- }
- $full_filename = find_tex_file($full_filename, ":.tex");
- if ($full_filename) {
- say $prefix . "Found input for file: $full_filename\n";
- # Surprisingly, space after filename
- # in \input{foo.tex } is inserted
- # _before_ the inclusion. Apply this
- # rule in latexpand.
- print $before . $trailing . $nl;
- print "% start input $full_filename\n" if ($explain);
- my $in_comment = process_file($full_filename, $prefix . " ");
- if ($explain) {
- print " % end input $full_filename\n";
- } elsif ($in_comment) {
- print "\n";
- }
- if ($after =~ /[^\s]/) {
- # LaTeX produces this space, so let's do it also
- print " " . $nl . $after . "\n";
- } else {
- print " ";
- }
- $_ = "";
- }
- } elsif (my ($before, $ignored, $dir, $ignored, $full_filename, $ignored, $after)
- = /^($NON_COMMENT)\\(?:sub)?import$ARGUMENT$ARGUMENT(.*)$/) {
- if ($explain) {
- print "% dir " . $dir ."\n";
- print "% full_filename " . $full_filename ."\n";
- print "% after " . $after ."\n";
- print "% inside_import $inside_import\n";
- }
- $full_filename = $dir . $full_filename;
- if ($inside_import) {
- $full_filename = $inside_import . $full_filename;
- }
- print "% cat(inside_import,dir,full_filename) " . $full_filename ."\n" if ($explain);
- $full_filename = find_tex_file($full_filename, ":.tex");
- if ($full_filename) {
- say $prefix . "Found input for file: $full_filename\n";
- print $before . $nl;
- print "% start input $full_filename\n" if ($explain);
- my $previous_import_dir = $inside_import;
- $inside_import = $inside_import . $dir;
- my $in_comment = process_file($full_filename, $prefix . " ");
- $inside_import = $previous_import_dir;
- if ($explain) {
- print " % end input $full_filename\n";
- } elsif ($in_comment) {
- print "\n";
- }
- if ($after =~ /[^\s]/) {
- # LaTeX produces this space, so let's do it also
- print " " . $nl . $after . "\n";
- } else {
- print " ";
- }
- $_ = "";
- }
- } elsif (my ($before, $ignored, $args, $full_filename, $ignored, $after)
- = /^($NON_COMMENT)\\includegraphics[\[\s]+(.*?)[\s\]]$ARGUMENT(.*)$/) {
- if ($explain) {
- print "% inside_import " . $inside_import ."\n";
- print "% before " . $before ."\n";
- print "% ignored " . $ignored ."\n";
- print "% args " . $args ."\n";
- print "% full_filename " . $full_filename ."\n";
- print "% after " . $after ."\n";
- }
- if ($inside_import) {
- $full_filename = $inside_import . $full_filename;
- print "$before\\includegraphics[$args]{$full_filename}$after\n";
- $_ = "";
- }
- } elsif (my ($before, $ignored, $args, $full_filename, $ignored, $after)
- = /^($NON_COMMENT)\\lstinputlisting[\[\s]+(.*?)[\s\]]$ARGUMENT(.*)$/) {
- if ($explain) {
- print "% inside_import " . $inside_import ."\n";
- print "% before " . $before ."\n";
- print "% ignored " . $ignored ."\n";
- print "% args " . $args ."\n";
- print "% full_filename " . $full_filename ."\n";
- print "% after " . $after ."\n";
- }
- if ($inside_import) {
- $full_filename = $inside_import . $full_filename;
- print "$before\\lstinputlisting[$args]{$full_filename}$after\n";
- $_ = "";
- }
- }
- }
- if ($expand_usepackage) {
- # Don't bother with before and after text, we just require the
- # usepackage to be alone on its line.
- if (my ($package_name) = /^\s*\\usepackage\{([^\}]*)\}\s*(%.*)?$/) {
- my $full = find_file($package_name . ".sty", $TEXINPUTS);
- if ($full) {
- say $prefix . "Found package file: $full\n";
- process_file($full, $prefix . " ");
- $_ = "";
- # Forget about any commented newline
- # before the \usepackage:
- $$commented_newline = 0;
- } else {
- say $prefix . "Not including external package $package_name\n";
- }
- }
- }
- if ($expand_bbl) {
- if (my ($before, $bib_name, $after)
- = /^(.*)\\(?:bibliography|bibselect)\{([^\}]*)\}(.*)$/) {
- # The BBL file is not necessarily $bib_name.
- # Take it from the command-line.
- print $before . $nl;
- say $prefix . "Expanding BBL file: $expand_bbl\n";
- process_file($expand_bbl, $prefix . " ");
- print " " . $nl . $after . "\n";
- $_ = "";
- }
- }
- if ($biber) {
- if (my ($before, $after)
- = /^(.*)\\(?:addbibresource)\{[^\}]*\}(.*)$/) {
- # See https://tex.stackexchange.com/questions/166518/biblatex-include-bbl-problem-with-verb-field/166526#166526
- my $biber_noext = $biber;
- $biber_noext =~ s/.bbl//;
- print $before . $nl;
- say $prefix . "Expanding Biber BBL file: $biber\n";
- print '\begin{filecontents*}{' . $biber . '}' . "\n";
- cat_file($biber);
- print "\n";
- print '\end{filecontents*}
-
-\usepackage{xpatch}
-
-%Patch the biblatex input command.
-%replace "testinput-bbl" if you change the name above.
-%disable if you want to run biblatex/biber normally
-\makeatletter
-\patchcmd\blx@bblinput{\blx@blxinit}
- {\blx@blxinit
- \def\jobname{' . $biber_noext . '}%new jobname
- }{}{\fail}
-\makeatother
- ';
- say $prefix . "End expansion of Biber BBL file: $biber\n";
- print " " . $nl . $after . "\n";
- $_ = "";
- }
- }
- if ($show_graphics) {
- if (/\\includegraphics(\[[^\]]*\])?{([^}]*)}/) {
- my $full_filename = $2;
- if ($inside_import) {
- $full_filename = $inside_import . $full_filename;
- }
- my $full = find_tex_file($full_filename, $graphics_extensions);
- say $prefix . "needs graphics file: ";
- print STDERR "$full\n";
- }
- }
- if (/^[ \t]*\\begin\{document\}/) {
- $in_preamble = 0;
- if ($makeatletter) {
- print '\makeatletter' . $nl;
- }
- }
- print;
-}
-
-sub unquote
-{
- my $str = shift;
- my $x = substr($str, 0, 1);
- my $y = substr($str, -1, 1);
- if ($x eq $y && ($x eq '"' || $x eq "'")) {
- $str = substr($str, 1, -1);
- }
- # There's a weird LaTeX syntax: \include{"file\space
- # with\space spaces"}, so remove these \space when unquoting.
- $str =~ s/\\space / /g;
- return $str;
-}
-
-# search $1 in $TEXINPUTS, with possible extensions in $2
-sub find_tex_file
-{
- my $file = unquote(shift);
- my $extensions = (shift || ":");
- foreach my $ext (split(':', $extensions, -1)) {
- my $full = find_file_global($file . $ext);
- if ($full) {
- return $full;
- }
- }
- if ($fatal) {
- die "ERROR: Could not find file [$file]\n";
- } else {
- print STDERR "Warning: Could not find file [$file]\n";
- return;
- }
-}
-
-sub find_file_global
-{
- my $file = shift;
- if (open(my $fh, "-|", "kpsewhich", $file)) {
- my $full = <$fh>;
- $full =~ s/\s+$//;
- close($fh);
- if ($full) {
- return $full;
- }
- }
- # Should be useless, but fall-back in case kpsewhich fails (or is not installed, or ...):
- return find_file($file, $TEXINPUTS);
-}
-
-# Find files, not searching for global files (to allow not expanding global .sty packages)
-sub find_file
-{
- my ($file, $path) = @_;
- if (File::Spec->file_name_is_absolute($file)) {
- if (-e "$file" && ! -d "$file") {
- return $file;
- } else {
- return;
- }
- }
-
- # TEXINPUTS=...: (trailing :) means "append default search
- # directories". We don't want global directories here, but
- # still add . that may be needed.
- if (substr($path, -1) eq ':') {
- $path .= '.';
- }
- foreach my $dir (split(':', $path)) {
- if (-e "$dir/$file" && ! -d "$dir/$file") {
- return("$dir/$file");
- }
- }
- return;
-}
-
-
-__END__
-
-=head1 NAME
-
-latexpand - Flatten LaTeX file by expanding \include and \input, ... and remove comments
-
-=head1 SYNOPSIS
-
-latexpand [options] FILE...
-
-=head2 Options:
-
- --verbose show what's going on
- --keep-comments don't strip comments (comments are lines
- starting with %, and anything below
- \end{document})
- --empty-comments keep empty comments (i.e. % at end of lines) for clarity
- --keep-includes don't expand \input and \include directives
- --expand-usepackage
- Expand \usepackage{...} directives if the
- corresponding .sty file is found in
- $TEXINPUTS (or the current directory if
- $TEXINPUTS is not set)
- --expand-bbl FILE
- Expand the bibliography by inlining FILE
- (should be a *.bbl file)
- --biber FILE Include \bibliography{} with FILE's content,
- as needed by biblatex with the biber backend.
- (similar to --expand-bbl FILE, but for
- biber+biblatex).
- --help this help message
- --output <file>, -o <file>
- generate output in <file>
- --explain generate explanatory comments in output
- --show-graphics show included graphics
- --graphics_extensions
- colon-separated list of possible graphics extensions
- (used by --show-graphics to find the actual graphics files)
- --fatal Die in case a file can't be found.
- --makeatletter Insert a \makeatletter in the preamble. In some
- rare cases it may break your document, but it
- may help fixing bad interactions between
- @-commands and inclusion (see BUGS section).
- --in-encoding FMT, --out-encoding FMT
- File encoding used by input and output files.
- This uses the same syntax as PerlIO's layers.
- Example:
- --in-encoding 'encoding(UTF-8)'
- The default is 'bytes' and should always work.
-
-=head1 USES
-
-The most common use of latexpand is to simplify distribution of source
-LaTeX files, typically to satisfy the requirement of editors and
-archival sites (springer, arXiv.org, ...) who force the authors to
-submit sources. One does not necessarily want to submit sources with
-comments, and uploading a document made of several files including
-each other is a bit painful. By default, latexpand answers both
-problems by outputing a single LaTeX file that contain no comment.
-
-=head1 GETTING LATEXPAND
-
-The latest version of latexpand is available here:
-
- https://gitlab.com/latexpand/latexpand
-
-Versions are uploaded to ctan.org from time to time:
-
- http://www.ctan.org/pkg/latexpand
-
-=head1 BUGS
-
-Please, report bugs on the issue tracker on the project site:
-
- https://gitlab.com/latexpand/latexpand/issues
-
-=head2 Known bugs
-
-=head3 Verbatim
-
-latexpand currently ignores \begin{verbatim} ... \end{verbatim}, and
-will therefore process any \include, \input, ... directives that
-appear within verbatim environments (while it shouldn't).
-
-LaTeX comments inside verbatim environments are also incorrectly
-stripped. You can use --keep-comments as a workaround to avoid this.
-
-=head3 Comment environment
-
-It would be nice to remove code between \begin{comment} and
-\end{comment} too if \usepackage{comment} is used.
-
-Code like
-
- foo%
- \begin{comment}
-
-will produce the incorrect
-
- foo\begin{comment}
-
-A workaround is to use --empty-comments when such tricky usage of the
-comments package is done.
-
-=head3 \makeatletter and use with transfig/xfig with \scalebox{}
-
-If \input{} or \include{} appears as argument to a command, and the
-file included contains \makeatletter, then after expansion, the
-\makeatletter and the @-command appear as argument to the command,
-which is forbidden because the argument is parsed (and the @-command
-badly tokenized) before being executed.
-
-This happens with
-
- \scalebox{ \input{file-generated-by-xfig.pdf_t} }
-
-Workaround: add \makeatletter before the scalebox manually in your
-code, like
-
- \makeatletter{}
- \scalebox{ \input{file-generated-by-xfig.pdf_t} }
- \makeatother{}
-
-In the case of xfig generated files, it is necessary only for the
-first occurence.
-
-A more brute-force workaround is to use latexpand --makeatletter.
-
-=head1 SEE ALSO
-
-Instructions to include only the relevant .bib items (french):
-
-https://lacl.fr/~caubert/notes/portabilite-du-tex.html#dependances
-
-=head1 VERSION
-
-This is latexpand version v1.6.
diff --git a/Build/source/texk/texlive/linked_scripts/light-latex-make/llmk.lua b/Build/source/texk/texlive/linked_scripts/light-latex-make/llmk.lua
deleted file mode 100755
index 949418e751b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/light-latex-make/llmk.lua
+++ /dev/null
@@ -1,1559 +0,0 @@
-#!/usr/bin/env texlua
-
---
--- This is file `llmk.lua'.
---
--- Copyright 2018-2020 Takuto ASAKURA (wtsnjp)
--- GitHub: https://github.com/wtsnjp
--- Twitter: @wtsnjp
---
--- This sofware is released under the MIT License.
---
-
-local llmk = {} -- the module table
-
-----------------------------------------
-
-do -- The "core" submodule
-local M = {}
-
--- option flags (default)
-M.debug = {
- config = false,
- parser = false,
- run = false,
- fdb = false,
- programs = false,
-}
-M.verbosity_level = 1
-M.silent = false
-M.dry_run = false
-
-llmk.core = M
-end
-
-----------------------------------------
-
-do -- The "const" submodule
-local M = {}
-
--- program information
-M.prog_name = 'llmk'
-M.version = '0.2.0'
-M.copyright = 'Copyright 2018-2020'
-M.author = 'Takuto ASAKURA (wtsnjp)'
-M.llmk_toml = 'llmk.toml'
-
--- exit codes
-M.exit_ok = 0
-M.exit_error = 1
-M.exit_failure = 2
-M.exit_parser = 3
-M.exit_type = 4
-
--- config item specification
-M.top_level_spec = {
- -- <program> = {<type>, <default value>}
- bibtex = {'string', 'bibtex'},
- clean_files = {'[string]', {
- '%B.aux', '%B.bbl', '%B.bcf', '%B-blx.bib', '%B.blg', '%B.fls',
- '%B.idx', '%B.ilg', '%B.log', '%B.out', '%B.run.xml', '%B.toc'
- }},
- clobber_files = {'[string]', {'%B.dvi', '%B.pdf', '%B.ps', '%B.synctex.gz'}},
- dvipdf = {'string', 'dvipdfmx'},
- dvips = {'string', 'dvips'},
- latex = {'string', 'lualatex'},
- llmk_version = {'string', nil},
- makeindex = {'string', 'makeindex'},
- max_repeat = {'integer', 5},
- ps2pdf = {'string', 'ps2pdf'},
- sequence = {'[string]', {'latex', 'bibtex', 'makeindex', 'dvipdf'}},
- source = {'*[string]', nil},
-}
-
-M.program_spec = {
- -- <item> = {<type>, {<specifiers allowed>, <default value>}}
- args = {'*[string]', {true, {'%T'}}},
- aux_file = {'string', {true, nil}},
- aux_empty_size = {'integer', {false, nil}},
- command = {'string', {false, ''}}, -- '' default because it must be string
- generated_target = {'boolean', {false, false}},
- opts = {'*[string]', {true, nil}},
- postprocess = {'string', {false, nil}},
- target = {'string', {true, '%S'}},
-}
-
-M.default_programs = {
- bibtex = {
- target = '%B.bib',
- args = {'%B'}, -- "%B.bib" will result in an error
- postprocess = 'latex',
- },
- dvipdf = {
- target = '%B.dvi',
- generated_target = true,
- },
- dvips = {
- target = '%B.dvi',
- generated_target = true,
- },
- latex = {
- opts = {
- '-interaction=nonstopmode',
- '-file-line-error',
- '-synctex=1',
- },
- aux_file = '%B.aux',
- aux_empty_size = 9, -- "\\relax \n" is empty
- },
- makeindex = {
- target = '%B.idx',
- generated_target = true,
- postprocess = 'latex',
- },
- ps2pdf = {
- target = '%B.ps',
- generated_target = true,
- },
-}
-
-llmk.const = M
-end
-
-----------------------------------------
-
-do -- The "util" submodule
-local M = {}
-
-local function log(label, msg, ...)
- local prefix = llmk.const.prog_name .. ' ' .. label .. ': '
- io.stderr:write(prefix .. msg:format(...) .. '\n')
-end
-
-function M.err_print(err_type, msg, ...)
- if err_type == 'error' then
- -- error must be reported
- elseif err_type == 'info' then
- if llmk.core.verbosity_level < 2 then return end
- elseif err_type == 'warning' then
- if llmk.core.verbosity_level < 1 then return end
- end
- log(err_type, msg, ...)
-end
-
-function M.dbg_print(dbg_type, msg, ...)
- if llmk.core.debug[dbg_type] then
- log('debug-' .. dbg_type, msg, ...)
- end
-end
-
-function M.dbg_print_table(dbg_type, table)
- if not llmk.core.debug[dbg_type] then return end
-
- local function helper(tab, ind)
- local function pp(msg, ...)
- M.dbg_print(dbg_type, string.rep(' ', ind) .. msg, ...)
- end
- for k, v in pairs(tab) do
- if type(v) == 'table' then
- pp(k .. ':')
- helper(v, ind + 2)
- elseif type(v) == 'string' then
- pp(k .. ': "%s"', v)
- else -- number, boolean, etc.
- pp(k .. ': %s', tostring(v))
- end
- end
- end
-
- helper(table, 2)
-end
-
--- return the filename if exits, even if the ".tex" extension is omitted
--- otherwise return nil
-local lfs = require("lfs")
-
--- Replace config param to filename
-function M.replace_specifiers(str, source, target)
- local tmp = '/' .. source
- local basename = tmp:match('^.*/(.*)%..*$')
-
- str = str:gsub('%%S', source)
- str = str:gsub('%%T', target)
-
- if basename then
- str = str:gsub('%%B', basename)
- else
- str = str:gsub('%%B', source)
- end
-
- return str
-end
-
-llmk.util = M
-end
-
-----------------------------------------
-
-do -- The "checker" submodule
-local M = {}
-
-local function checked_value(k, v, expected)
- local function error_if_wrong_type(val, t)
- if type(val) ~= t then
- llmk.util.err_print('error',
- '[Type Error] Key "%s" must have value of type %s', k, expected)
- os.exit(llmk.const.exit_type)
- end
- end
-
- if expected == 'integer' then
- error_if_wrong_type(v, 'number')
- elseif expected == 'boolean' then
- error_if_wrong_type(v, 'boolean')
- elseif expected == 'string' then
- error_if_wrong_type(v, 'string')
- elseif expected == '[string]' then
- error_if_wrong_type(v, 'table')
-
- if v[1] ~= nil then -- it is not an empty array
- error_if_wrong_type(v[1], 'string')
- end
- elseif expected == '*[string]' then
- if type(v) == 'string' then
- v = {v}
- else
- error_if_wrong_type(v, 'table')
-
- if v[1] ~= nil then -- it is not an empty array
- error_if_wrong_type(v[1], 'string')
- end
- end
- end
-
- return v
-end
-
-local function type_check(tab)
- local new_top = {}
-
- for k, v in pairs(tab) do
- if k == 'programs' then
- if type(v) ~= 'table' then
- llmk.util.err_print('error', '[Type Error] Key "programs" must be a table')
- os.exit(llmk.const.exit_type)
- end
-
- local new_prog = {}
- for p_name, p_val in pairs(v) do
- if type(p_val) ~= 'table' then
- llmk.util.err_print('error',
- '[Type Error] Key "programs.%s" must be a table', p_name)
- os.exit(llmk.const.exit_type)
- else
- new_prog[p_name] = {}
- for ik, iv in pairs(p_val) do
- if not llmk.const.program_spec[ik] then
- llmk.util.err_print('warning',
- 'Program key "%s" is unknown; ignoring it', ik)
- else
- expected = llmk.const.program_spec[ik][1]
- new_prog[p_name][ik] = checked_value(ik, iv, expected)
- end
- end
- end
- end
- new_top[k] = new_prog
- else
- if not llmk.const.top_level_spec[k] then
- llmk.util.err_print('warning',
- 'Top-level key "%s" is unknown; ignoring it', k)
- else
- expected = llmk.const.top_level_spec[k][1]
- new_top[k] = checked_value(k, v, expected)
- end
- end
- end
-
- return new_top
-end
-
-local function version_check(given_version)
- if not given_version then -- nothing to do
- return
- end
-
- -- parse the given version to the llmk_version key
- local given_major, given_minor = given_version:match('^(%d+)%.(%d+)')
- if not given_major or not given_minor then
- llmk.util.err_print('warning', 'In valid llmk_version: ' .. given_version)
- return
- else
- given_major, given_minor = tonumber(given_major), tonumber(given_minor)
- end
-
- -- the version of this program
- local major, minor = llmk.const.version:match('^(%d+)%.(%d+)')
- major, minor = tonumber(major), tonumber(minor)
-
- -- warn if this program is older than the given version
- if major < given_major or (major == given_major and minor < given_minor) then
- llmk.util.err_print('warning',
- 'This program (v%d.%d) is older than the specified llmk_version (v%d.%d)',
- major, minor, given_major, given_minor)
- end
-
- -- Note: no breaking change has been made (yet)
-end
-
-function M.check(tab)
- local new_tab = type_check(tab)
- version_check(new_tab.llmk_version)
- return new_tab
-end
-
-llmk.checker = M
-end
-
-----------------------------------------
-
-do -- The "config" submodule
-local M = {}
-
-local function init_config()
- local config = {}
-
- for k, v in pairs(llmk.const.top_level_spec) do
- config[k] = v[2]
- end
-
- config.programs = llmk.const.default_programs
- return config
-end
-
--- copy command name from top level
-local function fetch_from_top_level(config, name)
- if config.programs[name] then
- if not config.programs[name].command and config[name] then
- config.programs[name].command = config[name]
- end
- end
- return config
-end
-
-local function update_config(config, tab)
- -- merge the table from TOML
- local function merge_table(tab1, tab2)
- for k, v in pairs(tab2) do
- if k == 'programs' then
- local programs1 = tab1[k]
- local programs2 = tab2[k]
-
- for i_k, i_v in pairs(programs2) do
- if type(programs1[i_k]) == 'table' then
- for ii_k, ii_v in pairs(programs2[i_k]) do
- programs1[i_k][ii_k] = ii_v
- end
- else
- programs1[i_k] = i_v
- end
- end
- else
- tab1[k] = v
- end
- end
- return tab1
- end
- local config = merge_table(config, tab)
-
- -- set essential program names from top-level
- local prg_names = {'latex', 'bibtex', 'makeindex', 'dvipdf', 'dvips', 'ps2pdf'}
- for _, name in pairs(prg_names) do
- config = fetch_from_top_level(config, name)
- end
-
- -- show config table (for debug)
- llmk.util.dbg_print('config', 'The final config table is as follows:')
- llmk.util.dbg_print_table('config', config)
-
- return config
-end
-
-function M.fetch_from_latex_source(fn)
- local tab
- local config = init_config()
-
- -- get TOML field and parse it
- local toml, line = llmk.parser.get_toml(fn)
- if toml == '' then
- llmk.util.err_print('warning',
- 'Neither TOML field nor magic comment is found in "%s"; ' ..
- 'using default config', fn)
- end
- tab = llmk.parser.parse_toml(toml, {fn, line})
-
- -- check input and merge it to the config
- tab = llmk.checker.check(tab)
- config = update_config(config, tab)
-
- return config
-end
-
-function M.fetch_from_llmk_toml()
- local tab
- local config = init_config()
-
- local f = io.open(llmk.const.llmk_toml)
- if f ~= nil then
- local toml = f:read('*all')
- tab = llmk.parser.parse_toml(toml, {llmk.const.llmk_toml, 1})
- f:close()
- else
- llmk.util.err_print('error', 'No target specified and no %s found',
- llmk.const.llmk_toml)
- os.exit(llmk.const.exit_error)
- end
-
- -- check input and merge it to the config
- tab = llmk.checker.check(tab)
- config = update_config(config, tab)
-
- return config
-end
-
-llmk.config = M
-end
-
-----------------------------------------
-
-do -- The "parser" submodule
---[[
-This TOML parser is modified version of toml.lua
-- Copyright 2017 Jonathan Stoler
-- Licensed under MIT
- https://github.com/jonstoler/lua-toml/blob/master/LICENSE
-]]
-local M = {}
-
-function M.parse_toml(toml, file_info)
- -- basic local variables
- local ws = '[\009\032]'
- local nl = '[\10\13\10]'
-
- local buffer = ''
- local cursor = 1
-
- local line = 0
-
- local res = {}
- local obj = res
-
- -- basic local functions
- local function parser_err(msg)
- local function get_toml_str(nol)
- local pattern = string.format('([^%s]*)%s', nl:sub(2, -2), nl)
- local l = 0
- for cur_line in toml:gmatch(pattern) do
- if l == nol then
- return cur_line
- end
- l = l + 1
- end
- end
-
- llmk.util.err_print('error', '[Parse Error] %s', msg)
- llmk.util.err_print('error', '--> %s:%d: %s',
- file_info[1], file_info[2] + line, get_toml_str(line))
- os.exit(llmk.const.exit_parser)
- end
-
- local function char(n)
- n = n or 0
- return toml:sub(cursor + n, cursor + n)
- end
-
- local function step(n)
- n = n or 1
- for i = 0, n-1 do
- if char(i):match(nl) then
- line = line + 1
- end
- end
- cursor = cursor + n
- end
-
- local function skip_ws()
- while(char():match(ws)) do
- step()
- end
- end
-
- local function trim(str)
- return str:gsub('^%s*(.-)%s*$', '%1')
- end
-
- local function bounds()
- return cursor <= toml:len()
- end
-
- -- parse functions for each type
- local function parse_string()
- -- TODO: multiline
- local del = char() -- ' or "
- local str = ''
- -- all available escape characters
- local escape = {
- b = "\b",
- t = "\t",
- n = "\n",
- f = "\f",
- r = "\r",
- ['"'] = '"',
- ["\\"] = "\\",
- }
- -- utf function from http://stackoverflow.com/a/26071044
- -- converts \uXXX into actual unicode
- local function utf(char)
- local bytemarkers = {{0x7ff, 192}, {0xffff, 224}, {0x1fffff, 240}}
- if char < 128 then return string.char(char) end
- local charbytes = {}
- for bytes, vals in pairs(bytemarkers) do
- if char <= vals[1] then
- for b = bytes + 1, 2, -1 do
- local mod = char % 64
- char = (char - mod) / 64
- charbytes[b] = string.char(128 + mod)
- end
- charbytes[1] = string.char(vals[2] + char)
- break
- end
- end
- return table.concat(charbytes)
- end
-
- -- skip the quotes
- step()
-
- while(bounds()) do
- -- end of string
- if char() == del then
- step()
- break
- end
-
- if char():match(nl) then
- parser_err('Single-line string cannot contain line break')
- end
-
- if del == '"' and char() == '\\' then -- process escape characters
- if escape[char(1)] then
- -- normal escape
- str = str .. escape[char(1)]
- step(2) -- go past backslash and the character
- elseif char(1) == 'u' then
- -- utf-16
- step()
- local uni = char(1) .. char(2) .. char(3) .. char(4)
- step(5)
- uni = tonumber(uni, 16)
- if (uni >= 0 and uni <= 0xd7ff) and not (uni >= 0xe000 and uni <= 0x10ffff) then
- str = str .. utf(uni)
- else
- parser_err('Unicode escape is not a Unicode scalar')
- end
- elseif char(1) == 'U' then
- -- utf-32
- step()
- local uni = char(1) .. char(2) .. char(3) .. char(4) ..
- char(5) .. char(6) .. char(7) .. char(8)
- step(9)
- uni = tonumber(uni, 16)
- if (uni >= 0 and uni <= 0xd7ff) and not (uni >= 0xe000 and uni <= 0x10ffff) then
- str = str .. utf(uni)
- else
- parser_err('Unicode escape is not a Unicode scalar')
- end
- else
- parser_err('Invalid escape')
- end
- else -- literal string; leave as it is
- str = str .. char()
- step()
- end
- end
-
- return str
- end
-
- local function parse_number()
- -- TODO: exp, date
- local num = ''
-
- while(bounds()) do
- if char():match('[%+%-%.eE_0-9]') then
- if char() ~= '_' then
- num = num .. char()
- end
- elseif char():match(nl) then
- break
- elseif char():match(ws) or char() == '#' then
- break
- else
- parser_err('Invalid number')
- end
- step()
- end
-
- return tonumber(num)
- end
-
- local get_value
-
- local function parse_array()
- step()
- skip_ws()
-
- local a_type
- local array = {}
-
- while(bounds()) do
- if char() == ']' then
- break
- elseif char():match(nl) then
- step()
- skip_ws()
- elseif char() == '#' then
- while(bounds() and not char():match(nl)) do
- step()
- end
- else
- local v = get_value()
- if not v then break end
-
- if a_type == nil then
- a_type = type(v)
- elseif a_type ~= type(v) then
- parser_err('Mixed types in array')
- end
-
- array = array or {}
- table.insert(array, v)
-
- if char() == ',' then
- step()
- end
- skip_ws()
- end
- end
- step()
-
- return array
- end
-
- local function parse_boolean()
- local bool
-
- if toml:sub(cursor, cursor + 3) == 'true' then
- step(4)
- bool = true
- elseif toml:sub(cursor, cursor + 4) == 'false' then
- step(5)
- bool = false
- else
- parser_err('Invalid primitive')
- end
-
- skip_ws()
- if char() == '#' then
- while(not char():match(nl)) do
- step()
- end
- end
-
- return bool
- end
-
- -- judge the type and get the value
- get_value = function()
- if (char() == '"' or char() == "'") then
- return parse_string()
- elseif char():match('[%+%-0-9]') then
- return parse_number()
- elseif char() == '[' then
- return parse_array()
- -- TODO: array of table, inline table
- else
- return parse_boolean()
- end
- end
-
- -- main loop of parser
- while(cursor <= toml:len()) do
- -- ignore comments and whitespace
- if char() == '#' then
- while(not char():match(nl)) do
- step()
- end
- end
-
- if char() == '=' then
- step()
- skip_ws()
-
- -- prepare the key
- local key = trim(buffer)
- buffer = ''
-
- if key == '' then
- parser_err('Empty key name')
- elseif obj[key] then
- -- duplicate keys are not allowed
- parser_err('Cannot redefine key "' .. key .. '"')
- end
-
- local value = get_value()
- if value ~= nil then
- obj[key] = value
- --dbg_print('parser', 'Entry "' .. key .. ' = ' .. value .. '"')
- end
-
- -- skip whitespace and comments
- skip_ws()
- if char() == '#' then
- while(bounds() and not char():match(nl)) do
- step()
- end
- end
-
- -- if garbage remains on this line, raise an error
- if not char():match(nl) and cursor < toml:len() then
- parser_err('Invalid primitive')
- end
-
- elseif char() == '[' then
- buffer = ''
- step()
- local table_array = false
-
- if char() == '[' then
- table_array = true
- step()
- end
-
- obj = res
-
- local function process_key(is_last)
- is_last = is_last or false
- buffer = trim(buffer)
-
- if buffer == '' then
- parser_err('Empty table name')
- end
-
- if is_last and obj[buffer] and not table_array and #obj[buffer] > 0 then
- parser_err('Cannot redefine tabel')
- end
-
- if table_array then
- if obj[buffer] then
- obj = obj[buffer]
- if is_last then
- table.insert(obj, {})
- end
- obj = obj[#obj]
- else
- obj[buffer] = {}
- obj = obj[buffer]
- if is_last then
- table.insert(obj, {})
- obj = obj[1]
- end
- end
- else
- obj[buffer] = obj[buffer] or {}
- obj = obj[buffer]
- end
- end
-
- while(bounds()) do
- if char() == ']' then
- if table_array then
- if char(1) ~= ']' then
- parser_err('Mismatching brackets')
- else
- step()
- end
- end
- step()
-
- process_key(true)
- buffer = ''
- break
- --elseif char() == '"' or char() == "'" then
- -- TODO: quoted keys
- elseif char() == '.' then
- step()
- process_key()
- buffer = ''
- else
- buffer = buffer .. char()
- step()
- end
- end
-
- buffer = ''
- --elseif (char() == '"' or char() == "'") then
- -- TODO: quoted keys
- end
-
- -- put the char to the buffer and proceed
- buffer = buffer .. (char():match(nl) and '' or char())
- step()
- end
-
- return res
-end
-
-function M.get_toml(fn)
- local toml = ''
- local toml_field = false
- local toml_source = fn
-
- local f = io.open(toml_source)
-
- llmk.util.dbg_print('config', 'Looking for config in the file "%s"', toml_source)
-
- local ts_tmp
- local ts_latex
- local ts_bibtex
-
- local first_line = true
- local shebang
-
- local line = 0
- local start_pos = -1
-
- for l in f:lines() do
- line = line + 1
-
- -- 1. llmk-style TOML field
- if string.match(l, '^%s*%%%s*%+%+%++%s*$') then
- -- NOTE: only topmost field is valid
- if not toml_field then
- toml_field = true
- start_pos = line + 1
- else
- llmk.util.dbg_print('config', 'TOML field found')
- break
- end
- else
- if toml_field then
- toml = toml .. string.match(l, '^%s*%%%s*(.-)%s*$') .. '\n'
- end
- end
-
- -- 2. TeXShop directives
- ts_tmp = string.match(l, '^%s*%%%s*!%s*TEX%s+program%s*=%s*(.-)%s*$') or
- string.match(l, '^%s*%%%s*!%s*TEX%s+TS%-program%s*=%s*(.-)%s*$')
- if ts_tmp then
- ts_latex = ts_latex or ts_tmp
- end
-
- ts_tmp = string.match(l, '^%s*%%%s*!%s*BIB%s+program%s*=%s*(.-)%s*$') or
- string.match(l, '^%s*%%%s*!%s*BIB%s+TS%-program%s*=%s*(.-)%s*$')
- if ts_tmp then
- ts_bibtex = ts_bibtex or ts_tmp
- end
-
- -- 3. shebang
- if first_line then
- first_line = false
- shebang = string.match(l, '^%s*%%#!%s*(.-)%s*$')
- end
- end
-
- f:close()
-
- -- convert magic or shebang to TOML
- if toml == '' and (ts_latex or ts_bibtex) then
- llmk.util.dbg_print('config', 'TeXShop directives found')
- if ts_latex then
- toml = toml .. 'latex = "' .. ts_latex .. '"\n'
- end
- if ts_bibtex then
- toml = toml .. 'bibtex = "' .. ts_bibtex .. '"\n'
- end
- elseif toml == '' and shebang then
- llmk.util.dbg_print('config', 'Shebang found')
- toml = 'latex = "' .. shebang .. '"\n'
- end
-
- return toml, start_pos
-end
-
-llmk.parser = M
-end
-
-----------------------------------------
-
-do -- The "runner" submodule
-local M = {}
-
--- dependencies
-local lfs = require 'lfs'
-local md5 = require 'md5'
-
--- module local variable
-local start_time = os.time()
-
-local function table_copy(org)
- local copy
- if type(org) == 'table' then
- copy = {}
- for org_key, org_value in next, org, nil do
- copy[table_copy(org_key)] = table_copy(org_value)
- end
- setmetatable(copy, table_copy(getmetatable(org)))
- else -- number, string, boolean, etc.
- copy = org
- end
- return copy
-end
-
-local function setup_programs(fn, config)
- --[[Setup the programs table for each sequence.
-
- Collecting tables of only related programs, which appears in the
- `config.sequence` or `prog.postprocess`, and replace all specifiers.
-
- Args:
- fn (str): the input FILE name
-
- Returns:
- table of program tables
- ]]
- local prognames = {}
- local new_programs = {}
- local programs = config.programs
-
- -- collect related programs
- local function add_progname(name)
- -- is the program known?
- if not programs[name] then
- llmk.util.err_print('error', 'Unknown program "%s" is in the sequence', name)
- os.exit(llmk.const.exit_error)
- end
-
- -- if not new, no addition
- for _, c in pairs(prognames) do
- if c == name then
- return
- end
- end
-
- -- if new, add it!
- prognames[#prognames + 1] = name
- end
-
- for _, name in pairs(config.sequence) do
- -- add the program name
- add_progname(name)
-
- -- add postprocess program if any
- local postprocess = programs[name].postprocess
- if postprocess then
- add_progname(postprocess)
- end
- end
-
- -- setup the programs
- for _, name in ipairs(prognames) do
- local prog = table_copy(programs[name])
-
- -- setup the `prog.target`
- local cur_target
-
- if prog.target == nil then
- -- the default value of `prog.target` is `fn`
- cur_target = fn
- else
- -- here, %T should be replaced by `fn`
- cur_target = llmk.util.replace_specifiers(prog.target, fn, fn)
- end
-
- prog.target = cur_target
-
- -- initialize other items
- for k, v in pairs(llmk.const.program_spec) do
- if k ~= 'target' then -- target is a special case: already treated
- if prog[k] == nil then
- if type(v[2][2]) == 'table' then
- prog[k] = table_copy(v[2][2])
- else
- prog[k] = v[2][2]
- end
- end
-
- if v[2][1] then -- need to replace specifiers
- if type(prog[k]) == 'table' then
- for ik, iv in ipairs(prog[k]) do
- if type(prog[k][ik]) == 'string' then
- prog[k][ik] = llmk.util.replace_specifiers(iv, fn, cur_target)
- end
- end
- elseif type(prog[k]) == 'string' then
- prog[k] = llmk.util.replace_specifiers(prog[k], fn, cur_target)
- end
- end
- end
- end
-
- -- register the program
- new_programs[name] = prog
- end
-
- return new_programs
-end
-
-local function file_mtime(path)
- return lfs.attributes(path, 'modification')
-end
-
-local function file_size(path)
- return lfs.attributes(path, 'size')
-end
-
-local function file_md5sum(path)
- local f = assert(io.open(path, 'rb'))
- local content = f:read('*a')
- f:close()
- return md5.sumhexa(content)
-end
-
-local function file_status(path)
- return {
- mtime = file_mtime(path),
- size = file_size(path),
- md5sum = file_md5sum(path),
- }
-end
-
-local function init_file_database(programs, fn, config)
- -- the template
- local fdb = {
- targets = {},
- aux_files = {},
- }
-
- -- investigate current status
- for _, v in ipairs(config.sequence) do
- -- names
- local cur_target = programs[v].target
- local cur_aux = programs[v].aux_file
-
- -- target
- if lfs.isfile(cur_target) and not fdb.targets[cur_target] then
- fdb.targets[cur_target] = file_status(cur_target)
- end
-
- -- aux_file
- if cur_aux then -- `prog.aux_file` is optional
- if lfs.isfile(cur_aux) and not fdb.aux_files[cur_aux] then
- fdb.aux_files[cur_aux] = file_status(cur_aux)
- end
- end
- end
-
- return fdb
-end
-
-local function construct_cmd(prog, fn, target)
- -- construct the option
- local cmd_opt = ''
-
- if prog.opts then
- -- construct each option
- for _, opt in ipairs(prog.opts) do
- if #opt > 0 then
- cmd_opt = cmd_opt .. ' ' .. opt
- end
- end
- end
-
- -- construct the argument
- local cmd_arg = ''
-
- -- construct each argument
- for _, arg in ipairs(prog.args) do
- cmd_arg = cmd_arg .. ' "' .. arg .. '"'
- end
-
- -- whole command
- return prog.command .. cmd_opt .. cmd_arg
-end
-
-local function check_rerun(prog, fdb)
- llmk.util.dbg_print('run', 'Checking the neccessity of rerun')
-
- local aux = prog.aux_file
- local old_aux_exist = false
- local old_status
-
- -- if aux file does not exist, no chance of rerun
- if not aux then
- llmk.util.dbg_print('run', 'No auxiliary file specified')
- return false, fdb
- end
-
- -- if aux file does not exist, no chance of rerun
- if not lfs.isfile(aux) then
- llmk.util.dbg_print('run', 'The auxiliary file "%s" does not exist', aux)
- return false, fdb
- end
-
- -- copy old information and update fdb
- if fdb.aux_files[aux] then
- old_aux_exist = true
- old_status = table_copy(fdb.aux_files[aux])
- end
- local aux_status = file_status(aux)
- fdb.aux_files[aux] = aux_status
-
- -- if aux file is not new, no rerun
- local new = aux_status.mtime >= start_time
- if not new and old_aux_exist then
- new = aux_status.mtime > old_status.mtime
- end
-
- if not new then
- llmk.util.dbg_print('run', 'No rerun because the aux file is not new')
- return false, fdb
- end
-
- -- if aux file is empty (or almost), no rerun
- if aux_status.size < prog.aux_empty_size then
- llmk.util.dbg_print('run', 'No rerun because the aux file is (almost) empty')
- return false, fdb
- end
-
- -- if new aux is not different from older one, no rerun
- if old_aux_exist then
- if aux_status.md5sum == old_status.md5sum then
- llmk.util.dbg_print('run', 'No rerun because the aux file has not been changed')
- return false, fdb
- end
- end
-
- -- ok, then try rerun
- llmk.util.dbg_print('run', 'Try to rerun!')
- return true, fdb
-end
-
-local function silencer(cmd)
- local redirect_code
- if os.type == 'windows' then
- redirect_code = ' >NUL 2>&1'
- else
- redirect_code = ' >/dev/null 2>&1'
- end
- silencer = function(cmd) return cmd .. redirect_code end
- return silencer(cmd)
-end
-
-local function run_program(name, prog, fn, fdb, postprocess)
- -- preparation for dry run
- local function concat_cond(tab)
- local res
- for i, v in ipairs(tab) do
- if i == 1 then
- res = v
- else
- res = res .. '; ' .. v
- end
- end
- return res
- end
- local cond = {}
-
- if postprocess then
- cond[#cond + 1] = 'as postprocess'
- end
-
- if prog.aux_file then
- cond[#cond + 1] = 'possibly with rerunning'
- end
-
- -- does command specified?
- if #prog.command < 1 then
- llmk.util.err_print('warning',
- 'The "command" key is not set for program "%s"; skipping', name)
- return false
- end
-
- -- does target exist?
- if not llmk.core.dry_run and not lfs.isfile(prog.target) then
- llmk.util.dbg_print('run',
- 'Skiping "%s" because target (%s) does not exist',
- prog.command, prog.target)
- return false
- end
-
- -- is the target modified?
- if prog.generated_target then
- if llmk.core.dry_run then
- cond[#cond + 1] = string.format('if the target file "%s" has been generated',
- prog.target)
- elseif file_mtime(prog.target) < start_time then
- llmk.util.dbg_print('run',
- 'Skiping "%s" because target (%s) is not updated',
- prog.command, prog.target)
- return false
- end
- else
- if llmk.core.dry_run then
- cond[#cond + 1] = string.format('if the target file "%s" exists', prog.target)
- end
- end
-
- local cmd = construct_cmd(prog, fn, prog.target)
- if llmk.core.dry_run then
- print('Dry running: ' .. cmd)
- if #cond > 0 then
- llmk.util.err_print('info', '<-- ' .. concat_cond(cond))
- end
- return false
- else
- llmk.util.err_print('info', 'Running command: ' .. cmd)
- end
-
- -- redirect stdout and stderr to NULL in silent mode
- if llmk.core.silent then
- cmd = silencer(cmd)
- end
-
- -- call and check the status
- local status = os.execute(cmd)
- if status > 0 then
- llmk.util.err_print('error',
- 'Fail running %s (exit code: %d)', cmd, status)
- os.exit(llmk.const.exit_failure)
- end
-
- return true
-end
-
-local function process_program(programs, name, fn, fdb, config, postprocess)
- local postprocess = postprocess or false
- local prog = programs[name]
- local should_rerun
-
- -- execute the command
- local run = false
- local exe_count = 0
- while true do
- exe_count = exe_count + 1
- run = run_program(name, prog, fn, fdb, postprocess)
-
- -- if the run is skipped, break immediately
- if not run then break end
-
- -- if not neccesarry to rerun or reached to max_repeat, break the loop
- should_rerun, fdb = check_rerun(prog, fdb)
- if not ((exe_count < config.max_repeat) and should_rerun) then
- break
- end
- end
-
- -- go to the postprocess process
- if prog.postprocess and (run or llmk.core.dry_run) then
- llmk.util.dbg_print('run', 'Going to postprocess "%s"', prog.postprocess)
- process_program(programs, prog.postprocess, fn, fdb, config, true)
- end
-end
-
-function M.run_sequence(fn, config)
- llmk.util.err_print('info', 'Beginning a sequence for "%s"', fn)
-
- -- setup the programs table
- local programs = setup_programs(fn, config)
- llmk.util.dbg_print('programs', 'Current programs table:')
- llmk.util.dbg_print_table('programs', programs)
-
- -- create a file database
- local fdb = init_file_database(programs, fn, config)
- llmk.util.dbg_print('fdb', 'The initial file database is as follows:')
- llmk.util.dbg_print_table('fdb', fdb)
-
- for _, name in ipairs(config.sequence) do
- llmk.util.dbg_print('run', 'Preparing for program "%s"', name)
- process_program(programs, name, fn, fdb, config)
- end
-end
-
-llmk.runner = M
-end
-
-do -- The "cleaner" submodule
-local M = {}
-
--- dependencies
-local lfs = require("lfs")
-
--- fn is filepath of target to remove.
-local function remove(fn)
- if llmk.core.dry_run then
- print(string.format('Dry running: removing file "%s"', fn))
- else
- local ok = os.remove(fn)
-
- if ok ~= true then
- llmk.util.err_print('error', 'Failed to remove "%s"', fn)
- else
- llmk.util.err_print('info', 'Removed "%s"', fn)
- end
- end
-end
-
-local function replace_spec_and_remove_files(fns, source)
- for _, fn in ipairs(fns) do
- local replaced_fn = llmk.util.replace_specifiers(fn, source, source)
- if lfs.isfile(replaced_fn) then
- remove(replaced_fn)
- end
- end
-end
-
--- the actual process for the --clean action
-function M.clean(fn, config)
- llmk.util.err_print('info', 'Begining cleaning for "%s"', fn)
- replace_spec_and_remove_files(config.clean_files, fn)
-end
-
--- the actual process for the --clobber action
-function M.clobber(fn, config)
- llmk.util.err_print('info', 'Begining clobbering for "%s"', fn)
- replace_spec_and_remove_files(config.clean_files, fn)
- replace_spec_and_remove_files(config.clobber_files, fn)
-end
-
-llmk.cleaner = M
-end
-
-----------------------------------------
-
-do -- The "cli" submodule
-local M = {}
-local C = llmk.const
-
-local help_text = [[
-Usage: llmk [OPTION]... [FILE]...
-
-Options:
- -c, --clean Remove the temporary files such as aux and log files.
- -C, --clobber Remove all generated files including final PDFs.
- -d CAT, --debug=CAT Activate debug output restricted to CAT.
- -D, --debug Activate all debug output (equal to "--debug=all").
- -h, --help Print this help message.
- -n, --dry-run Show what would have been executed.
- -q, --quiet Suppress most messages.
- -s, --silent Silence messages from called programs.
- -v, --verbose Print additional information.
- -V, --version Print the version number.
-
-Please report bugs to <https://github.com/wtsnjp/llmk/issues>.
-]]
-
-local version_text = [[
-%s %s
-
-%s %s.
-License: The MIT License <https://opensource.org/licenses/mit-license>.
-This is free software: you are free to change and redistribute it.
-]]
-
--- execution functions
-local function read_options()
- local curr_arg
- local action = false
-
- -- modified Alternative Get Opt
- -- cf. http://lua-users.org/wiki/AlternativeGetOpt
- local function getopt(arg, options)
- local tmp
- local tab = {}
- local saved_arg = {table.unpack(arg)}
- for k, v in ipairs(saved_arg) do
- if string.sub(v, 1, 2) == '--' then
- table.remove(arg, 1)
- local x = string.find(v, '=', 1, true)
- if x then
- table.insert(tab, {string.sub(v, 3, x-1), string.sub(v, x+1)})
- else
- table.insert(tab, {string.sub(v, 3), true})
- end
- elseif string.sub(v, 1, 1) == '-' then
- table.remove(arg, 1)
- local y = 2
- local l = string.len(v)
- local jopt
- while (y <= l) do
- jopt = string.sub(v, y, y)
- if string.find(options, jopt, 1, true) then
- if y < l then
- tmp = string.sub(v, y+1)
- y = l
- else
- table.remove(arg, 1)
- tmp = saved_arg[k + 1]
- end
- if string.match(tmp, '^%-') then
- table.insert(tab, {jopt, false})
- else
- table.insert(tab, {jopt, tmp})
- end
- else
- table.insert(tab, {jopt, true})
- end
- y = y + 1
- end
- end
- end
- return tab
- end
-
- local opts = getopt(arg, 'd')
- for _, tp in pairs(opts) do
- k, v = tp[1], tp[2]
- if #k == 1 then
- curr_arg = '-' .. k
- else
- curr_arg = '--' .. k
- end
-
- -- action
- if (curr_arg == '-h') or (curr_arg == '--help') then
- return 'help' -- immediately show help
- elseif (curr_arg == '-V') or (curr_arg == '--version') then
- return 'version' -- immediately show version
- elseif (curr_arg == '-c') or (curr_arg == '--clean') then
- action = 'clean'
- elseif (curr_arg == '-C') or (curr_arg == '--clobber') then
- action = 'clobber'
- -- debug
- elseif (curr_arg == '-D') or
- (curr_arg == '--debug' and (v == 'all' or v == true)) then
- for c, _ in pairs(llmk.core.debug) do
- llmk.core.debug[c] = true
- end
- elseif (curr_arg == '-d') or (curr_arg == '--debug') then
- if llmk.core.debug[v] == nil then
- llmk.util.err_print('warning', 'unknown debug category: ' .. v)
- else
- llmk.core.debug[v] = true
- end
- -- verbosity
- elseif (curr_arg == '-q') or (curr_arg == '--quiet') then
- llmk.core.verbosity_level = 0
- elseif (curr_arg == '-v') or (curr_arg == '--verbose') then
- llmk.core.verbosity_level = 2
- elseif (curr_arg == '-s') or (curr_arg == '--silent') then
- llmk.core.silent = true
- -- dry run
- elseif (curr_arg == '-n') or (curr_arg == '--dry-run') then
- llmk.core.dry_run = true
- -- problem
- else
- llmk.util.err_print('error', 'unknown option: ' .. curr_arg)
- os.exit(C.exit_error)
- end
- end
-
- return action
-end
-
-local function check_filename(fn)
- if lfs.isfile(fn) then
- return fn -- ok
- end
-
- local ext = fn:match('%.(.-)$')
- if ext ~= nil then
- return nil
- end
-
- local new_fn = fn .. '.tex'
- if lfs.isfile(new_fn) then
- return new_fn
- else
- return nil
- end
-end
-
-local function make(fns, func)
- local config
- if #fns > 0 then
- for _, fn in ipairs(fns) do
- local checked_fn = check_filename(fn)
- if checked_fn then
- config = llmk.config.fetch_from_latex_source(checked_fn)
- func(checked_fn, config)
- else
- llmk.util.err_print('error', 'Source file "%s" does not exist', fn)
- os.exit(C.exit_error)
- end
- end
- else
- config = llmk.config.fetch_from_llmk_toml()
-
- local source = config.source
- if source ~= nil then
- for _, fn in ipairs(source) do
- local checked_fn = check_filename(fn)
- if checked_fn then
- func(checked_fn, config)
- else
- llmk.util.err_print('error', 'Source file "%s" does not exist', fn)
- os.exit(C.exit_error)
- end
- end
- else
- llmk.util.err_print('error', 'No source detected')
- os.exit(C.exit_error)
- end
- end
-end
-
-local function do_action(action)
- if action == 'help' then
- io.stdout:write(help_text)
- elseif action == 'version' then
- io.stdout:write(version_text:format(
- C.prog_name, C.version, C.copyright, C.author))
- elseif action == 'clean' then
- make(arg, llmk.cleaner.clean)
- elseif action == 'clobber' then
- make(arg, llmk.cleaner.clobber)
- end
-end
-
-function M.exec()
- local action = read_options()
-
- if action then
- do_action(action)
- os.exit(C.exit_ok)
- end
-
- make(arg, llmk.runner.run_sequence)
- os.exit(C.exit_ok)
-end
-
-llmk.cli = M
-end
-
-----------------------------------------
-
-assert(llmk.cli, 'Internal error: llmk is not installed properly')
-llmk.cli.exec()
-
--- EOF
diff --git a/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-glyph-commands.py b/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-glyph-commands.py
deleted file mode 100755
index dae48cda009..00000000000
--- a/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-glyph-commands.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python
-
-# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-# %
-# This file is part of the 'lilyglyphs' LaTeX package. %
-# ========== %
-# %
-# https://github.com/openlilylib/lilyglyphs %
-# http://www.openlilylib.org/lilyglyphs %
-# %
-# Copyright 2012-2020 Urs Liska and others, ul@openlilylib.org %
-# %
-# 'lilyglyphs' is free software: you can redistribute it and/or modify %
-# it under the terms of the LaTeX Project Public License, either %
-# version 1.3 of this license or (at your option) any later version. %
-# You may find the latest version of this license at %
-# http://www.latex-project.org/lppl.txt %
-# more information on %
-# http://latex-project.org/lppl/ %
-# and version 1.3 or later is part of all distributions of LaTeX %
-# version 2005/12/01 or later. %
-# %
-# This work has the LPPL maintenance status 'maintained'. %
-# The Current Maintainer of this work is Urs Liska (see above). %
-# %
-# This work consists of the files listed in the file 'manifest.txt' %
-# which can be found in the 'license' directory. %
-# %
-# This program is distributed in the hope that it will be useful, %
-# but WITHOUT ANY WARRANTY; without even the implied warranty of %
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
-# %
-# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-# ########################################################################
-# #
-# genGlyphCommands.py #
-# #
-# generate commands based on Emmentaler glyphs #
-# #
-# ########################################################################
-
-import os, sys, argparse, lilyglyphs_common as lg
-
-def main(input_file):
- """Do the main work of the script"""
-
- in_dir, in_file = os.path.split(input_file)
- os.chdir(in_dir)
-
- # load and parse input file
- lg.read_input_file(in_file)
- read_entries()
-
- # generate LaTeX commands and save them to output file
- # (will be a .tex sibling of the input file)
- lg.generate_latex_commands()
- out_file, out_ext = os.path.splitext(input_file)
- lg.write_latex_file(os.path.join(os.getcwd(), out_file + '.tex'))
-
-def read_entries():
- """Parse the input file and fill a dictionary"""
- entry = {}
- def reset_entry():
- """Set all members of the dict empty,
- because not all are present in each entry."""
- entry['cmd'] = ''
- entry['element'] = ''
- entry['type'] = 'glyphname'
- entry['comment'] = []
- entry['raise'] = ''
- entry['scale'] = ''
-
- reset_entry()
- scale = ''
- rais = ''
- for line in lg.definitions_file:
- line = line.strip()
- # empty line = end of entry
- if not len(line):
- # skip if cmd and glyph haven't been filled both
- if not (entry['cmd'] and entry['element']):
- print('Skip malformed entry \'' + entry['cmd'] + '\'. Please check input file')
- reset_entry()
- else:
- print('Read entry \'' + entry['cmd'] + '\'')
- lg.in_cmds[entry['cmd']] = {}
- lg.in_cmds[entry['cmd']]['element'] = entry['element']
- lg.in_cmds[entry['cmd']]['type'] = entry['type']
- lg.in_cmds[entry['cmd']]['comment'] = entry['comment']
- if scale:
- lg.in_cmds[entry['cmd']]['scale'] = scale
- if rais:
- lg.in_cmds[entry['cmd']]['raise'] = rais
- reset_entry()
- # ignore Python or LaTeX style comments
- elif line[0] in '#%':
- continue
- else:
- # add element to the entry
- keyval = line.split('=')
- if keyval[0] == 'scale':
- scale = keyval[1]
- elif keyval[0] == 'raise':
- rais = keyval[1]
- if keyval[0] == 'comment':
- entry['comment'] = [keyval[1]]
- else:
- entry[keyval[0].strip()] = keyval[1].strip()
-
-
-def usage():
- print('genGlyphCommands.py')
- print('is part of the lilyglyphs package')
- print('')
- print('Usage:')
- print('Pass the name (without path) of an input definitions file')
- print('(this has to be located in the /stash_new_commands directory.')
- print('Please refer to the manual (documentation/lilyglyphs.pdf).')
-
-# ####################################
-# Finally launch the program
-if __name__ == "__main__":
- # parse command line arguments
- parser = argparse.ArgumentParser(
- description='Generate LaTeX commands using Emmentaler glyphs',
- parents=[lg.common_arguments])
- parser.add_argument('i',
- type=lg.is_file,
- metavar='INPUT',
- help='File with command templates.')
- args = parser.parse_args()
-
- # if we have exactly one existing file
- # join its components and run the program
- main(os.path.join(os.getcwd(), vars(args)['i']))
diff --git a/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-image-commands.py b/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-image-commands.py
deleted file mode 100755
index 741ad40e9b4..00000000000
--- a/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-image-commands.py
+++ /dev/null
@@ -1,321 +0,0 @@
-#!/usr/bin/env python
-
-# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-# %
-# This file is part of the 'lilyglyphs' LaTeX package. %
-# ========== %
-# %
-# https://github.com/openlilylib/lilyglyphs %
-# http://www.openlilylib.org/lilyglyphs %
-# %
-# Copyright 2012-2020 Urs Liska and others, ul@openlilylib.org %
-# %
-# 'lilyglyphs' is free software: you can redistribute it and/or modify %
-# it under the terms of the LaTeX Project Public License, either %
-# version 1.3 of this license or (at your option) any later version. %
-# You may find the latest version of this license at %
-# http://www.latex-project.org/lppl.txt %
-# more information on %
-# http://latex-project.org/lppl/ %
-# and version 1.3 or later is part of all distributions of LaTeX %
-# version 2005/12/01 or later. %
-# %
-# This work has the LPPL maintenance status 'maintained'. %
-# The Current Maintainer of this work is Urs Liska (see above). %
-# %
-# This work consists of the files listed in the file 'manifest.txt' %
-# which can be found in the 'license' directory. %
-# %
-# This program is distributed in the hope that it will be useful, %
-# but WITHOUT ANY WARRANTY; without even the implied warranty of %
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
-# %
-# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-import os, sys, getopt, datetime, subprocess, argparse, lilyglyphs_common as lg
-
-
-
-# ###############
-# string to be printed before the actual command
-lily_src_prefix = """\\version "2.16.2"
-
-#(set-global-staff-size 14)
-
-\paper {
- indent = 0
-}
-\header {
- tagline = ""
-}
-
-"""
-
-# string to be printed after the actual command definition
-lily_src_score = """
- \\score {
- \\new Staff \\with {
- \\remove "Staff_symbol_engraver"
- \\remove "Clef_engraver"
- \\remove "Time_signature_engraver"
- }
-"""
-
-def main():
- """Do the actual work of the script"""
- print('')
- print('buildglyphimages.py,')
- print('Part of lilyglyphs.')
- print('')
-
- # set CWD and ensure the necessary subdirs are present
- check_paths()
- print('')
-
- # load and parse input file
- lg.read_input_file(in_file)
- read_entries()
- print('')
-
- # generate LilyPond source files for each command
- # and compile them
- write_lily_src_files()
- print('')
- lg.compile_lily_files()
- print('')
-
- # remove intermediate files and move pdfs to pdf directory
- lg.cleanup_lily_files()
- print('')
-
- # generate latex commands and example code
- # and write them to the output file
- lg.generate_latex_commands()
- print('')
- write_latex_file()
-
-
-def check_paths():
- """Sets CWD to 'glyphimages' subdir or root of lilyglyphs_private
- and makes sure that the necessary subdirectories are present"""
-
- # one level above 'definitions' is 'glyphimages'
- os.chdir(os.path.join(in_path, '..'))
-
- # check the presence of the necessary subdirectories
- # and create them if necessary
- # (otherwise we'll get errors when trying to write in them)
- ls = os.listdir('.')
- if not lg.dir_lysrc in ls:
- os.mkdir(lg.dir_lysrc)
- if not lg.dir_pdfs in ls:
- os.mkdir(lg.dir_pdfs)
- if not lg.dir_cmd in ls:
- os.mkdir(lg.dir_cmd)
-
-def cmd_filename(cmd_name):
- if cmd_name.startswith('lily'):
- return cmd_name[:4] + '-' + cmd_name[4:]
- elif cmd_name.startswith('lily-'):
- return cmd_name
- else:
- return 'lily-' + cmd_name
-
-# set default scale and raise arguments to empty
-scale = ''
-rais = ''
-
-def read_entries():
- """Parses the input source file and extracts glyph entries"""
- print('Read entries of LilyPond commands:')
- for i in range(len(lg.definitions_file)):
- if '%%lilyglyphs' in lg.definitions_file[i]:
- i = read_entry(i)
- print(lg.lily_files)
-
-def read_entry(i):
- """Reads a single glyph entry from the input file and stores it
- in the global dictionary lg.in_cmds"""
- global scale, rais
- # read comment line(s)
- i += 1
- is_protected = False
- comment = []
- # loop over the comment line(s)
- while i < len(lg.definitions_file):
- line = lg.definitions_file[i].strip()
- # check for 'protected' entries that shouldn't be processed newly
- if not line[0] == '%':
- break
- elif '%%protected' in line:
- is_protected = True
- elif 'scale=' in line:
- dummy, scale = line.split('=')
- elif 'raise=' in line:
- dummy, rais = line.split('=')
- else:
- line = line[1:].strip()
- comment.append(line)
- i += 1
-
- # remove any empty lines
- while len(lg.definitions_file[i].strip()) == 0:
- i += 1
-
- # read command name
- line = lg.definitions_file[i].strip()
- cmd_name = line[: line.find('=') - 1]
- print('- ' + cmd_name, end=' ')
- if is_protected:
- print('(protected and skipped)')
- else:
- print('') #(for line break only)
-
- # read actual command until we find a line the begins with a closing curly bracket
- i += 1
- lilySrc = []
- while lg.definitions_file[i][0] != '}':
- lilySrc.append(lg.definitions_file[i])
- i += 1
- if not is_protected:
- lg.in_cmds[cmd_name] = {}
- lg.in_cmds[cmd_name]['comment'] = comment
- lg.in_cmds[cmd_name]['lilySrc'] = lilySrc
- lg.in_cmds[cmd_name]['element'] = cmd_filename(cmd_name)
- lg.in_cmds[cmd_name]['type'] = 'image'
- if scale:
- lg.in_cmds[cmd_name]['scale'] = scale
- if rais:
- lg.in_cmds[cmd_name]['raise'] = rais
-
- lg.lily_files.append(cmd_filename(cmd_name))
- return i
-
-
-def usage():
- print("""buildglyphimages. Part of the lilyglyphs package.
- Parses a template file, creates
- single .ly files from it, uses LilyPond to create single glyph
- pdf files and set up template files to be used in LaTeX.
- The input file has to be located in the glyphimages folder
- of either the lilyglyph package itself or of a copy of
- the lilyglyphs_private directory structure contained in the
- distribution.
- For detailed instructions refer to the manual.
- Usage:
- buildglyphimages.py in-file-name.
- """)
-
-def write_file_info(name, fout):
- """Formats file specific information for the lilyPond source file"""
- long_line = '% This file defines a single glyph to be created with LilyPond: %\n'
- width = len(long_line) - 1
- header = '%' * width + '\n'
- spacer = '%' + ' ' * (width - 2) + '%\n'
- padding = width - len(name) - 8
- fout.write(header)
- fout.write(spacer)
- fout.write(long_line)
- fout.write(spacer)
- fout.write('% ' + name + '.ly' + ' ' * padding + '%\n')
- fout.write(spacer)
- fout.write(header)
- fout.write(lg.signature())
- fout.write('\n\n')
-
-def write_latex_file():
- """Composes LaTeX file and writes it to disk"""
- print('Generate LaTeX file')
- print(lg.dir_cmd, in_basename)
- lg.write_latex_file(os.path.join(os.getcwd(), lg.dir_cmd, in_basename + '.tex'))
-
-def write_lily_src_files():
- """Generates one .ly file for each found new command"""
- skip_cmds = []
- print('Write .ly files for each entry:')
- for cmd_name in lg.in_cmds:
- print('- ' + cmd_name)
- gen_src_name = os.path.join(lg.dir_lysrc, cmd_filename(cmd_name) + '.ly')
- # handle existing commands
- if os.path.exists(gen_src_name):
- action = ''
- while not (action == 'Y' or action == 'N'):
- action = input('already present. Overwrite (y/n)? ')
- action = action.upper()
- if action == 'N':
- skip_cmds.append(cmd_name)
- continue
-
- # open a single lily src file for write access
- fout = open(gen_src_name, 'w')
-
- #output the license information
- fout.write(lg.lilyglyphs_copyright_string)
- fout.write('\n')
-
- #output information on the actual file
- write_file_info(cmd_name, fout)
-
- #write the default LilyPond stuff
- fout.write(lily_src_prefix)
-
- # write the comment for the command
- fout.write('%{\n')
- for line in lg.in_cmds[cmd_name]['comment']:
- fout.write(line + '\n')
- fout.write('%}\n\n')
-
- # write the actual command
- fout.write(cmd_name + ' = {\n')
- for line in lg.in_cmds[cmd_name]['lilySrc']:
- fout.write(line + '\n')
- fout.write('}\n')
-
- # write the score definition
- fout.write(lily_src_score)
-
- # finish the LilyPond file
- fout.write(' \\' + cmd_name + '\n')
- fout.write('}\n\n')
-
- fout.close()
-
- # remove skipped commands from in_cmds
- print(skip_cmds)
- for cmd_name in skip_cmds:
- del lg.in_cmds[cmd_name]
- lg.lily_files.remove(cmd_filename(cmd_name))
-
-# ####################################
-# Finally launch the program
-if __name__ == "__main__":
-
- # parse command line arguments
- parser = argparse.ArgumentParser(
- description='Process templates to LilyPond input files,' +
- 'compile these and generate LaTeX commands.',
- parents=[lg.common_arguments])
- parser.add_argument('i',
- type=lg.is_file,
- metavar='INPUT',
- help='File with command templates.')
- args = parser.parse_args()
-
- # if we have exactly one existing file
- # join its components and run the program
-
- # process filename argument, providing absolute path
- script_path, script_name = os.path.split(sys.argv[0])
-
- in_file = os.path.join(os.getcwd(), vars(args)['i'])
- # check if the input file is in the right place
- # this has to be the definitions subdir of
- # the package directory or the lilyglyphs_private dir
- in_path, in_filename = os.path.split(in_file)
- in_path = os.path.normpath(in_path)
- if not (('lilyglyphs' in in_path) and (in_path.endswith('definitions'))):
- print('File in the wrong location: ' + in_path)
- usage()
- sys.exit(2)
- in_basename, in_ext = os.path.splitext(in_filename)
- main()
diff --git a/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-rebuild-pdfs.py b/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-rebuild-pdfs.py
deleted file mode 100755
index 03a94d87773..00000000000
--- a/Build/source/texk/texlive/linked_scripts/lilyglyphs/lily-rebuild-pdfs.py
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/usr/bin/env python
-
-# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-# %
-# This file is part of the 'lilyglyphs' LaTeX package. %
-# ========== %
-# %
-# https://github.com/openlilylib/lilyglyphs %
-# http://www.openlilylib.org/lilyglyphs %
-# %
-# Copyright 2012-2020 Urs Liska and others, ul@openlilylib.org %
-# %
-# 'lilyglyphs' is free software: you can redistribute it and/or modify %
-# it under the terms of the LaTeX Project Public License, either %
-# version 1.3 of this license or (at your option) any later version. %
-# You may find the latest version of this license at %
-# http://www.latex-project.org/lppl.txt %
-# more information on %
-# http://latex-project.org/lppl/ %
-# and version 1.3 or later is part of all distributions of LaTeX %
-# version 2005/12/01 or later. %
-# %
-# This work has the LPPL maintenance status 'maintained'. %
-# The Current Maintainer of this work is Urs Liska (see above). %
-# %
-# This work consists of the files listed in the file 'manifest.txt' %
-# which can be found in the 'license' directory. %
-# %
-# This program is distributed in the hope that it will be useful, %
-# but WITHOUT ANY WARRANTY; without even the implied warranty of %
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
-# %
-# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-# ########################################################################
-# #
-# rebuild-pdfs.py #
-# #
-# This program looks in the directories where the generated .ly files #
-# and the generated pdf images are stored. #
-# If it finds that there are missing pdfs it will recompile them #
-# using LilyPond. #
-# #
-# The main purpose is to allow the creation of pdf images of glyphs #
-# that already have been processed to LaTeX commands but whose PDF #
-# files have been lost. #
-# The other purpose is to update the set of PDF files to a new version #
-# of Emmentaler or LilyPond without touching the definitions. #
-# #
-# ########################################################################
-
-import os, sys, subprocess, argparse, lilyglyphs_common as lg
-
-
-def main():
- """Main walk through the program"""
- print('rebuild-pdfs.py')
- print('regenerate all pdf images that are not present (anymore)')
- print('')
-
- # Check if we are in a legal CWD and ensure a PDF subdir is present
- check_paths()
-
- # build a list of commands with missing PDF files
- src_files = check_missing_pdfs()
-
- # is there anything to be done at all?
- if len(src_files) == 0:
- print('')
- print('No image files missing, nothing to be done.')
- print('If you want to re-create pdfs, then delete them first')
- sys.exit(0)
- print('')
- print('Found ' + str(len(src_files)) + ' missing file(s).')
- for cmd in src_files:
- print('- ' + cmd)
-
- # compile all LilyPond files without matching pdf
- lg.lily_files = src_files
- lg.compile_lily_files()
-
- # clean up directories
- lg.cleanup_lily_files()
-
-def check_missing_pdfs():
- """Compares the list of LilyPond source and resulting PDF files.
- Returns a list of LilyPond source file basenames
- which don't have a corresponding PDF file"""
- print('Reading file lists, counting missing pdf files')
-
- # read existing .pdf files in lg.dir_pdfs
- img_files = []
- for entry in os.listdir(lg.dir_pdfs):
- entry = os.path.join(lg.dir_pdfs, entry)
- if os.path.isfile(entry):
- path, name = os.path.split(entry)
- basename, ext = os.path.splitext(name)
- if ext == '.pdf':
- img_files.append(basename)
-
- # read existing .ly source files in in_dir
- # and add them to the sources list if the image is missing
- src_files = []
- for entry in os.listdir(lg.dir_lysrc):
- entry = os.path.join(lg.dir_lysrc, entry)
- if os.path.isfile(entry):
- path, name = os.path.split(entry)
- basename, ext = os.path.splitext(name)
- if ext == '.ly' and basename not in img_files:
- src_files.append(basename)
- return src_files
-
-def check_paths():
- """Checks if we're in the right CWD
- and makes sure that there is a pdf output directory available"""
-
- print('Checking directories ...')
-
- # check the presence of the necessary subdirectories
- ls = os.listdir('.')
- if not 'generated_src' in ls:
- print('No LilyPond source files directory found.')
- print('Sorry, there is something wrong :-(')
- print('Current working directory is: ' + os.getcwd())
- print('Please consult the manual.')
- sys.exit(2)
- if not 'pdfs' in ls:
- os.mkdir('pdfs')
-
- print('... done')
- print('')
-
-
-# ####################################
-# Finally launch the program
-if __name__ == "__main__":
- # parse command line arguments
- parser = argparse.ArgumentParser(
- description='Rebuild all pdfs missing in the \'pdfs\' subdiredtory',
- parents=[lg.common_arguments])
- args = parser.parse_args()
- main()
diff --git a/Build/source/texk/texlive/linked_scripts/listbib/listbib b/Build/source/texk/texlive/linked_scripts/listbib/listbib
deleted file mode 100755
index d66eab74c90..00000000000
--- a/Build/source/texk/texlive/linked_scripts/listbib/listbib
+++ /dev/null
@@ -1,245 +0,0 @@
-#!/bin/sh
-#!/bin/sh -x
-#!/bin/bash
-#
-# listbib
-#
-# List the contents of all given BibTeX files (bibliographic data bases,
-# extension .bib).
-# Prerequisites:
-# LaTeX 2e, <1999/06/01> will work (earlier ones might)
-# bibtex 0.99b
-# package listbib, version 2.0 or later
-#
-# If we had bash, we could do some decent programming. However, listbib
-# must also work with something as braindead as solaris 2.7 /bin/sh,
-# so we won't...
-#
-# Copyright Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
-# Released under the GNU General Public License (GPL) Version 2.
-#
-# Volker Kuhlmann
-# 15, 16, 17 Mar; 12, 15 Apr; 30 Jul; 28 Aug 2000
-#
-
-VERSION="VK 1.2.3, 28 Aug 2000"
-
-# The root of the filenames generated by latex etc.
-#outfile="listbib-$$" # numbers are awkward
-#outfile="listbib" # not good!
-outfile="listedbibs"
-
-
-####
-#### Usage
-#
-usage() {
- echo "
-Usage: `basename $0` [OPTIONS] [BIBFILE[.bib] ..] BIBFILE_N[.bib]
-Version $VERSION
-
-Options:
- -h|--help shows help
- -o|--output FILE generates FILE.dvi / FILE.ps (default $outfile)
- -O|--same as -o, but generate FILE.dvi and BIBFILE_N.ps
- -p|--ps|--postscript generate PostScript as well as dvi
- -d|--deltemp delete all generated files but .dvi
- -P|--psonly generate only PostScript (delete all generated files
- but .ps)
- -- stop option processing; only .bib files remain
-
-Examples:
- List contents of mystrings.bib and mybib.bib, generating $outfile.dvi:
- listbib -d mystrings.bib mybib.bib
- As before, but only generate $outfile.ps:
- listbib -P mystrings.bib mybib.bib
- Generate mybib.ps instead:
- listbib -P -O mystrings.bib mybib.bib
-"
- exitwith ErrUsage
-}
-
-####
-#### Error/Exit codes
-#
-exitwith() {
- exec 1>&2 # write stdout on stderr instead
- case "$1" in
- ErrUsage|ErrHelp)
- # usage already displayed
- exit 1;;
- ErrTex)
- echo "File '$2' already exists."
- exit 2;;
- ErrListbibtex)
- echo "Refusing to create temp file 'listbib.tex'. That file already"
- echo "exists, and an infinite loop would result."
- exit 3;;
- ErrCall)
- echo "An error occured."
- echo "Investigate by running $2 on '$3',"
- echo "or by examining log file '$outfile$4'."
- exit 4;;
- ErrStop)
- exit 8;;
- ErrMissingParameter)
- echo "A required parameter for option $2 is missing."
- echo "Call with -h for help."
- exit 9;;
- *)
- echo "Error: exitwith() was called with illegal error code '$1'."
- exit 19;;
- esac
-}
-
-####
-#### Parse command line
-#
-checkargmm() {
- test "$1" != "--" -a "$2" != "--"
- #true # uncomment this to allow "--" as argument to an option
-}
-checkarg2() {
- test $# -ge 2 && checkargmm "$2" && return
- exitwith ErrMissingParameter "$1"
-}
-parse_cmd_line() {
- unset -v ps deltmp psonly outfileps
- if [ $# -eq 0 ]; then usage; fi
- while [ -n "$1" ]; do
- case "$1" in
- -h|--help)
- usage;;
- -o|--output)
- checkarg2 "$@"; outfile="$2"; shift;;
- -O|--same)
- test -z "$2" && usage
- eval outfileps=\${$#}
- # strip trailing ".bib":
- concat_bibnames "$outfileps"; outfileps="$listbibs";;
- -p|--ps|--postscript)
- ps="1";;
- -d|--deltemp)
- deltmp="1";;
- -P|--psonly)
- psonly="1";;
- -PO|-OP)
- shift; set FILL -P -O "$@";;
- -po)
- shift; set FILL -p -o "$@";;
- -dpo|-pdo)
- shift; set FILL -d -p -o "$@";;
- --) shift;;
- *) break;;
- esac
- shift
- done
- #fileargs=("$@")
- fileargs="$@"
-}
-
-####
-#### Functions
-#
-concat_bibnames() {
- listbibs=
- while [ -n "$1" ]; do
- #listbibs="$listbibs,$1"
- if [ -n "$listbibs" ]; then listbibs="$listbibs,"; fi
- listbibs="$listbibs`echo $1 | sed -e 's,\.$,,' -e 's,.bib$,,'`"
- shift
- done
-}
-
-idstring="% listbib $VERSION"
-check_tex_is_ours() {
- # exit with error if existing .tex is not a listbib one
- test -f "$outfile".tex || return
- awk "/$idstring/ {exit 0}; {exit 1}" "$outfile".tex \
- || exitwith ErrTex "$outfile".tex
-}
-
-create_latexfile() {
- test "$outfile" = "listbib" && exitwith ErrListbibtex
-
- cat >"$outfile".tex - <<EOF
- $idstring
- % File automatically generated by listbib. Delete if you wish.
- \\batchmode
- \\def\\listbibs{$listbibs}
- \\input{listbib}
-EOF
-}
-
-run_latex() {
- echo "Running latex ..."
- latex >/dev/null </dev/null "$outfile"
- # a non-zero exit code means termination with error
- # This assumes the latex program does set the exit status. Tough if not...
- test $? -ne 0 && exitwith ErrCall "latex" "$outfile" .log
- true
-}
-
-run_bibtex() {
- echo "Running bibtex ..."
- #bibtex >/dev/null </dev/null "$outfile"
- bibtex "$outfile"
- test $? -ne 0 && exitwith ErrCall "bibtex" "$outfile" .blg
- true
-}
-
-#LaTeX Warning: There were undefined references.
-#LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
-#LaTeX Warning: Citation `Book' undefined on input line 8.
-make_dvi() {
- test -r "$outfile".aux && { rm "$outfile".aux || return; }
- test -r "$outfile".bbl && { rm "$outfile".bbl || return; }
- run_latex
- run_bibtex
- run_latex
- # just in case...
- warn1='There were undefined references\.'
- warn2='Label\(s\) may have changed\. Rerun to get cross-references right.'
- warn3="Citation \`Book\' undefined on input line "
- egrep >/dev/null "LaTeX Warning: ($warn1|$warn2|$warn3)" "$outfile".log \
- && {
- #cp "$outfile".log debug.log
- echo "Again"
- run_latex
- }
- true
-}
-
-run_dvips() {
- [ -z "$outfileps" ] && outfileps="$outfile"
- if [ -n "$ps" -o -n "$psonly" ]; then
- echo "Running dvips ..."
- dvips >/dev/null 2>&1 -o "$outfileps.ps" "$outfile"
- fi
-}
-
-rm_temp() {
- if [ -n "$deltmp" -o -n "$psonly" ]; then
- rm >/dev/null 2>&1 "$outfile".aux "$outfile".bbl "$outfile".blg \
- "$outfile".log "$outfile".tex
- fi
- test -n "$psonly" && rm >/dev/null 2>&1 "$outfile".dvi
- test -n "$signal" && rm >/dev/null 2>&1 "$outfileps".ps
- true
-}
-
-####
-#### Main
-
-parse_cmd_line "$@"
-concat_bibnames $fileargs
-echo "listbib $VERSION"
-echo "Listing bibliographies:" $listbibs
-check_tex_is_ours
-signal=""
-trap "echo >&2 'Deleting temp files';\
- psonly=1 signal=1 rm_temp; exitwith ErrStop" HUP INT QUIT PIPE TERM
-create_latexfile
-make_dvi || exit $?
-run_dvips || exit $?
-rm_temp || exit $?
diff --git a/Build/source/texk/texlive/linked_scripts/listings-ext/listings-ext.sh b/Build/source/texk/texlive/linked_scripts/listings-ext/listings-ext.sh
deleted file mode 100755
index 5e47ec064bf..00000000000
--- a/Build/source/texk/texlive/linked_scripts/listings-ext/listings-ext.sh
+++ /dev/null
@@ -1,359 +0,0 @@
-#! /bin/sh
-### listings-ext.sh ---
-
-## Author: Dr. Jobst Hoffmann <j.hoffmann_(at)_fh-aachen.de>
-## Version: $Id: listings-ext.dtx 67 2010-06-29 16:38:12Z ax006ho $
-## Keywords: LaTeX, listings
-## Copyright: (C) 2008-2010 Jobst Hoffmann, <j.hoffmann_(at)_fh-aachen.de>
-##-------------------------------------------------------------------
-##
-## This file may be distributed and/or modified under the
-## conditions of the LaTeX Project Public License, either version 1.2
-## of this license or (at your option) any later version.
-## The latest version of this license is in:
-##
-## http://www.latex-project.org/lppl.txt
-##
-## and version 1.2 or later is part of all distributions of LaTeX
-## version 1999/12/01 or later.
-##
-## This file belongs to the listings-ext package.
-##
-## listings-ext.sh creates code to be inserted into a
-## LaTeX file from a source file.
-##
-## The commented code can be seen in listings-ext.pdf, which is provided
-## with the distribution package.
-ERR_HELP=1
-ME=$(basename $0)
-USAGE="usage:\n\t${ME} [-c|--command] [-e|--ext] [-g|--debug] \\\\\n\
-\t\t[-h|--help] [-n|--no-header] \\\\\n\
-\t\t[{-o|--output-file} [<output filename>]] <filename>, ...\n\
-\t-c:\tgenerate commands, which can be input and later used by\n\
-\t\t\\\\lstuse, optional\n\
-\t-e:\tinclude file name extension into the identifier\n\
-\t-g:\tdebug mode, create some additional output, optional\n\
-\t-h:\tshow this help, optional\n\
-\t-n:\twrite no header into the LaTeX code, optional; valid only,\n\
-\t\tif -c isn't used\n\
-\t-o [<output filename>]: if this argument is present, the output will\n\
-\t\tbe written into a file <output filename>; if the\n\
-\t\t<output filename> is omitted, the output is redirected\n\
-\t\tinto a file with a basename corresponding to the name\n\
-\t\tof the current directory, it has an extension of \".lst\".\n\
-"
-DEBUG_MODE=0
-EXTENSION=0
-HEADER=1
-
-show_usage() { # display help massage
- printf "${USAGE}"
- exit ${ERR_HELP}
-}
-print_header() {
- FILE=$1
- printf "%%%% -- file $1 generated on $(date) by ${ME}\n"
- FILE=$(echo $(basename $1 .lst) | sed -e s/[_\-]//g)
- printf "\\\\csname ${FILE}LstLoaded\\\\endcsname\n"
- printf "\\\\expandafter\\\\let\\\\csname ${FILE}LstLoaded\\\\endcsname\\\\endinput\n"
-}
-do_the_job() {
- PATHCOMPONENT=$(pwd)
- SOURCEFILE=$1
-
- if [ ! -f ${SOURCEFILE} ]
- then
- printf "${SOURCEFILE} is no valid file\n"
- return $ERR_NOFILE
- fi
- SOURCEFILE=${SOURCEFILE##${PATHCOMPONENT}/}
-
- grep -n "^[[:space:]]*[/%;#!][/\* ;][[:space:]]*[cbe]e:" $1 | \
- awk -v pathcomponent="${PATHCOMPONENT}" -v file="${SOURCEFILE}" \
- -v header="${HEADER}" -v command="${COMMAND}" -v application="${ME}" \
- -v debugmode="${DEBUG_MODE}" -v respect_extension="${EXTENSION}"\
- -F : \
-'
-BEGIN {
- is_opened = 0;
- initialised = 0;
- configured = 0;
- join = 0;
- combine = 0;
-
- idChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- split(idChar, idArray, "")
- idPt = 0
- linerange = "";
-
- linelen = 75; # length of the output line
- addchars = 8; # number of additional characters like %, > or so
-
- if ( debugmode ) printf("path: %s\n", pathcomponent) > "/dev/stderr"
- if ( debugmode ) printf("file: %s\n", file) > "/dev/stderr"
- n = split(pathcomponent, partsa, "/");
- curr_dir = parts[n]
- n++;
- partsa[n] = file;
- inputfile = "/" partsa[2];
- for ( i = 3; i <= n; i++ ) {
- inputfile = inputfile "/" partsa[i];
- }
- if ( debugmode ) printf("inputfile: %s\n", inputfile) > "/dev/stderr"
- n = split(file, partsa, "/")
- n = split(partsa[n], partsb, ".")
- identifier = partsb[1]
- for ( i = 2; i < n; i++ ) {
- identifier = identifier partsb[i]
- }
- if ( respect_extension ) {
- identifier = identifier partsb[n]
- }
- identifier = replace_characters(identifier)
- if ( debugmode ) printf("identifier: %s\n", identifier) > "/dev/stderr"
-}
-{
- if ( debugmode ) print $0 > "/dev/stderr"
- if ( !initialised ) {
- if ( match($2, /ce/) > 0 ) {
- n = split($(NF), text, ",");
- if ( match(text[1], "join") ) {
- join = 1;
- } else if ( match(text[1], "combine") ) {
- combine = 1;
- }
- } else if ( match($2, /be/) > 0 ) {
- opening_tag = $(NF)
- gsub(/\r/, "", opening_tag);
- is_opened = 1
- start = $1 + 1; # entry $1 is the line number
- } else if ( match($2, /ee/) > 0 ) {
- print_error($1, "missing \"be\" declaration")
- }
- initialised = 1;
- } else {
- tag = $(NF)
- if ( match($2, /be/) > 0 ) {
- if ( is_opened ) {
- print_error($1, "incorrect grouping, previous group"\
- " not closed")
- } else {
- opening_tag = $(NF)
- gsub(/\r/, "", opening_tag);
- is_opened = 1
- start = $1 + 1; # entry $1 is the line number
- }
- } else {
- if ( match($2, /ee/) > 0 ) {
- closing_tag = $(NF)
- gsub(/\r/, "", closing_tag);
- if ( !is_opened ) {
- print_error($1, "missing \"be\" declaration")
- } else if ( opening_tag == closing_tag ) {
- is_opened = 0
- split($(NF), text, "*"); # omit a trailing comment
- sub(/ /, "", text[1]); # delete leading spaces
- gsub(/"/, "", text[1]);
- if ( index(text[1], "_") > 0 ) gsub(/_/, "\\_", text[1]);
- caption = "\\lstinline|" file "|: " text[1]
-
- # setup the prefixes
- len = linelen - addchars - length(caption);
- begin_prefix = "%%";
- cnt = 0;
- while ( cnt < len) {
- begin_prefix = begin_prefix "=";
- cnt++;
- };
- begin_prefix = begin_prefix ">";
- end_prefix = begin_prefix;
- sub(/%%/, "%%==", end_prefix);
- if ( join ) {
- linerange = linerange ", " start "-" $1-1;
- } else if ( combine ) {
- sub(/ /, "", closing_tag)
- if ( combine_array[closing_tag] == "" ) {
- combine_array[closing_tag] = start "-" $1-1
- } else {
- combine_array[closing_tag] = \
- combine_array[closing_tag] ", " start "-" $1-1
- }
- if ( debugmode ) printf("combine_array: >%s<\n",\
- combine_array[closing_tag]) > "/dev/stderr"
- } else {
- linerange = start "-" $1-1;
- if ( command ) {
- print_command(\
- (identifier toB26(idPt++)), \
- linerange);
- } else {
- print_linerange(\
- (identifier toB26(idPt++)), \
- caption, linerange);
- }
- }
- } else if ( opening_tag != closing_tag ) {
- print_error($1, "opening and closing tags differ")
- } else {
- print_error($1, "unknown error")
- }
- }
- }
- }
-}
-END {
- if ( is_opened ) {
- print_error($1, "missing \"ee\" declaration")
- }
- caption = "\\lstinline|" file "|";
- if ( join ) {
- sub(/, /, "", linerange);
- if ( command ) {
- print_command(identifier, linerange);
- } else {
- caption = "\\lstinline|" file "|";
- print_linerange(identifier, caption, linerange);
- }
- } else if ( combine ) {
- for ( range in combine_array ) {
- if ( debugmode ) printf("range: %s, combine_array[range]: >%s<\n", \
- range, combine_array[range]) > "/dev/stderr"
- printf("%%%%-->> %s <<--\n", range)
- if ( command ) {
- print_command((identifier toB26(idPt++)), \
- combine_array[range]);
- } else {
- print_linerange((identifier toB26(idPt++)), caption, \
- combine_array[range]);
- }
- }
- }
-}
-function replace_characters(identifier) {
- tmp = ""
- toUppercase = 0
- n = split(identifier, sequence, "") # split the string into an array
- # of single characters
- for ( i = 1; i <= n; i++ )
- {
- if ( (sequence[i] == "_") || (sequence[i] == "-") ) {
- toUppercase = 1
- } else {
- if ( toUppercase ) {
- cTmp = toupper(sequence[i])
- tmp = (tmp cTmp)
- toUppercase = 0
- } else {
- tmp = (tmp sequence[i])
- }
- }
- }
- return tmp
-}
-function print_command(identifier, linerange) {
- if ( debugmode ) printf("print_command.linerange: >%s<\n", linerange) > "/dev/stderr"
- print break_line("\\lstdef{" identifier "}{" inputfile "}{" \
- linerange "}", linelen)
-}
-function print_linerange(identifier, caption, linerange) {
- print break_line(begin_prefix "begin{" \
- identifier"}\n{%\n \\def\\inputfile{%\n " inputfile "%\n }");
- local_style = "";
- if ( header )
- {
- print " \\ifLecture{%\n \\lstdefinestyle{localStyle}{%\n " \
- "caption={" caption"}\n }%\n }\n {%\n" \
- " \\lstdefinestyle{localStyle}{%\n" \
- " title={" caption "}\n }%\n }";
- local_style="style=localStyle, "
- }
- print " \\lstinputlisting[" local_style "linerange={" linerange "}]" \
- "{%\n \\inputfile\n }\n" \
- "}%\n" end_prefix "end{"identifier"}";
-}
-function print_error(linenumber, error_message)
-{
- printf "%--> error (line number %d): %s\n", \
- linenumber, error_message > "/dev/stderr"
-}
-function break_line(input_line, line_len) {
- n = split(input_line, parts, "/");
- output_line = parts[1];
- len_curr = length(output_line)
- for ( i = 2; i <= n; i++ ) {
- len_next = length(parts[i])
- if ( len_curr + len_next + 1 < linelen ) {
- output_line = output_line "/" parts[i];
- len_curr += len_next + 1 # continue current line
- } else {
- output_line = output_line "%\n /" parts[i];
- len_curr = len_next + 7 # start a new line
- }
- }
- return output_line
-}
-function toB26(n10) {
- v26 = ""
- do {
- remainder = n10%26
- v26 = idArray[remainder+1] v26
- n10 = int(n10/26)
- } while ( n10 != 0 )
- return v26
-}
-'
- return $?
-}
-
-if [ $# -eq 0 ]
-then
- show_usage
-fi
-GETOPT=$(getopt -o ceghno:: \
- --longoptions command,debug-mode,ext,help,no-header,output-file:: \
- -n ${ME} -- "$@")
-
-if [ $? -ne 0 ] # no success
-then
- show_usage
-fi
-
-eval set -- "$GETOPT"
-
-while true
-do
- case "$1" in
- -c|--command) COMMAND=1; HEADER=0; shift;;
- -e|--ext) EXTENSION=1; shift;;
- -g|--debug-mode) DEBUG_MODE=1; shift;;
- -h|--help) show_usage ;;
- -n|--no-header) HEADER=0; shift;;
- -o|--output-file)
- case "$2" in
- "") OUTFILE=$(basename $(pwd)).lst; shift 2 ;;
- *) OUTFILE=$2; shift 2 ;;
- esac ;;
- --) shift ; break ;;
- *) show_usage ;;
- esac
-done
-if [ -n "${OUTFILE}" ]
-then
- if [ -f "${OUTFILE}" ]
- then
- printf "%s\n" "%--> file \"${OUTFILE}\" already exists, creating backup"
- mv ${OUTFILE} ${OUTFILE}~
- fi
- exec > ${OUTFILE} # redirect stdout to ${OUTFILE}
- CURR_DIR=$(basename $(pwd))
- print_header ${OUTFILE} ${CURR_DIR}
-fi
-
-# now take all remaining arguments (should be all filenames) and do the job
-for arg do
- printf "%s\n" "%%--> processing file \"$arg\"" 1>&2 # echo the current
- # filename to stderr
- do_the_job $arg
-done
-
-### listings-ext.sh ends here
diff --git a/Build/source/texk/texlive/linked_scripts/ltxfileinfo/ltxfileinfo b/Build/source/texk/texlive/linked_scripts/ltxfileinfo/ltxfileinfo
deleted file mode 100755
index 9b74dd95a8d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ltxfileinfo/ltxfileinfo
+++ /dev/null
@@ -1,421 +0,0 @@
-#!/bin/bash
-
-version=2.04
-myname=$(basename "$0")
-
-<<'DOC'
-= ltxfileinfo - print version information for a LaTeX file
-
-= Synopsis
-ltxfileinfo [options] filename
-
-Options:
--h,--help print this help and exit
--H,--Help print full documentation via less and exit
--V print this script's version and exit
--d,--date print file's date only
--v,--version print file's version only
--i,--info print file's description text only
--l,--location print file's full path only (same output as kpsewhich)
--f,--flat output as 1 line with 4 tab-separated file, date, version and info fields
--s,--star mark mal-formatted data with a star
--c,--color mark mal-formatted data with red color (ANSI coloring)
--D,--debug for debugging, keep temporary files
-
-= Description
-ltxfileinfo displays version information for LaTeX files. If no path
-information is given, the file is searched using kpsewhich. As an extra,
-for developers, the script will (use the |--star| or |--color| options)
-check the valididity of the |\Provides...| statement in the files.
-The script uses code from Uwe LĂĽck's |readprov.sty|.
-
-Without an option, the output will be of the form:
- $ ltxfileinfo ctable.sty
- name: ctable.sty
- date: 2012/08/23
- vers: v1.24
- info: Easy, key=value directed, option-rich, typesetting of floats
- loca: /usr/local/texlive/2012/../texmf-local/tex/latex/ctable/ctable.sty
-
-Missing information is represented by |--|:
- $ ltxfileinfo yhmath.sty
- name: yhmath.sty
- date: --
- vers: --
- info: --
- loca: /usr/local/texlive/2012/texmf-dist/tex/latex/yhmath/yhmath.sty
-
-ltxfileinfo tries to detect (and report) mal-formatted dates and versions;
-use the |--star| option to mark such fields with a star, of use the |--color|
-option to color invalid fields red, if you work in a terminal with ANSI-coloring
-capabilities.
-These options are useful for developers who want to check the correctness
-of their |\Provides...| statements. For example:
-
- $ ltxfileinfo -s arfonts.sty
- file: ARfonts.sty* (case difference in \Provides statement)
- date: 2006/01/01
- vers: --*
- info: Part of the Arabi package
- loca: /usr/local/texlive/2012/texmf-dist/tex/latex/arabi/arfonts.sty
-
-We see here, that the |\ProvidesPackage| statement has an incorrect first
-argument and has no version information.
-
-= Other output formats
-With the |--date| option, only the file's date will be shown, unlabeled.
-The |--version|, |--location|, |--info| options are treated analogously.
-
- $ ltxfileinfo -v chronology.sty
- v1.0
-
-The |--flat| option prints the fields (except loca:, the last field) on one
-line, unlabeled and tab-separated:
-
- $ ltxfileinfo --star --flat chronology.sty
- chronology.sty 2010/6/12* v1.0 Horizontal timeline
-
-The date is starred, because its format is not yyyy/mm/dd (and the |--star|
-option is given.)
-
-= Bugs
-
-On my system, I have a total of 8699 kpsewhich-detectable files that contain a |\Provides...| statement.
-I ran them all through |ltxfileinfo| and made the following summary of detected errors:
-
- 8695 Total \Provides... containing files tested
-
- 660 \Provides... could not be interpreted; reason:
- 160 Argument of \Provides... not equal to file's name
- 8 Latex3 package (not handled yet)
- 480 Unidentified problem with \ProvidesPackage statement
- 12 \Provides... used in file without a ... extension
-
- 8035 Files could be evaluated
- 482 had no date
- 95 had a mal-formatted date
- 2666 had no version
- 357 had a mal-formatted version
- 765 had a \Provides... first argument different from the filename
-
-The .dtx files have more problems than other files:
-
- 1345 .dtx files:
-
- 320 \Provides... could not be interpreted; reason:
- 81 Argument of \Provides... not equal to...
- 6 Latex3 package (not handled yet)
- 233 Unidentified problem with \ProvidesPackage statement
-
- 1025 Files could be evaluated
- 49 had no date
- 15 had a mal-formatted date
- 99 had no version
- 52 had a mal-formatted version
- 468 had a \Provides... first argument different from the filename
-
-= Author and copyright
-Author Wybo Dekker
-Email U{Wybo@dekkerdocumenten.nl}{wybo@dekkerdocumenten.nl}
-License Released under the U{www.gnu.org/copyleft/gpl.html}{GNU General Public License}
-DOC
-
- die() { echo -e "$myname: $Err${*}$Nor" 1>&2; exit 1; }
- help() { sed -n '/^= Synopsis/,/^= /p' "$0"|sed '1s/.*/Usage:/;/^= /d'; exit; }
-helpall() { sed -n '/^<<.DOC.$/,/^DOC$/p' "$0"|sed -n '1d;$d;p'|less; exit; }
-version() { echo $version; exit; }
-install() { which instscript>&/dev/null && instscript --zip --pdf --markdown "$myname"; exit; }
-
-Nor='\e[0m' # reset color ]
-Err='\e[31;1m' # light red ]
-[[ ${BASH_VERSINFO[0]} -ge 4 ]] || die "Need bash version >= 4 (you have $BASH_VERSION)"
-
-# remove leading and trailing whitespace from a string
-function trim {
- local var="$*"
- var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace
- var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace
- echo -n "$var"
-}
-
-# mark a string by appending a * (--star and --color options)
-function mark {
- echo "$mark1${*}$mark2"
-}
-
-# special treatment for .mbs and .bst files:
-function dombsbst {
- # look at the first \ProvidesFile only:
- out="File: "$(grep '\ProvidesFile{' "$loca" |head -1 |sed 's/^[ %]*\\ProvidesFile{//;s/}\[/ /;s/\]$//')
-}
-
-# unpack the fields
-function extract {
- shift # remove File:
- file=$1
- shift # remove filename
- if [[ -z $1 ]]; then
- date=--; vers=--; info=--; return
- elif [[ $1 =~ ^[0-9]+/[0-9]+/[0-9]+ ]]; then
- date="$1"
- shift
- else
- date="--"
- fi
- if [[ -z $1 ]]; then
- vers=--; info=--; return
- elif [[ $1 =~ ^v?[[:digit:]][.[:digit:]]+[a-z]* ]]; then
- vers="$1"
- shift
- info="${*:---}"
- return
- else
- fixed=false
- # sometimes the version is of the form v.1.3 or vers:1.3 or such:
- for i in version ver. ver: ver v. V v; do
- if [[ $1 =~ $i[[:digit:]][.[:digit:]]*[a-z]* ]]; then
- vers="$1"
- shift
- fixed=true
- break
- fi
- done
- if ! $fixed; then
- # sometimes the version is reported as "v 1.3" or "vers: 1.3" or such:
- for i in version ver: ver v. V v; do
- if [[ $1 == "$i" ]]; then
- if [[ $2 =~ [[:digit:]][.[:digit:]]+[a-z]* ]]; then
- vers="$1 $2"
- shift 2
- fixed=true
- break
- fi
- fi
- done
- fi
- info="${*:---}"
- if ! $fixed; then
- vers=--
- fi
- fi
-}
-
-# display the results
-function display {
- # file should be equal to arg (the argument)
- if [[ $file != "$arg" ]] && [[ -n $mark2 ]]; then
- file="$(mark "$file") (case difference in \\Provides statement)"
- fi
-
- # to be correct, date must be of the form yyyy/mm/dd
- if [[ $date == -- ]]; then
- date="$(mark $date) (file modification date: $(stat -c %z "$loca"|sed -e 's/\..*//'))"
- elif [[ -n $mark2 ]]; then
- local wrong=false add=''
- if [[ ! $date =~ ^[[:digit:]]{4}/[[:digit:]]{2}/[[:digit:]]{2}$ ]]; then
- add+=" (wrong format)"
- wrong=true
- fi
- if [ "$(date -d "$date" +%arg 2>&1 | grep invalid)" != "" ]; then
- # even if it matches, the date must be valid:
- add+=" (invalid date)"
- wrong=true
- fi
- if $wrong; then date="$(mark "$date")$add"; fi
- fi
-
- # version should be 1.2 or 1.2.3, maybe prefixed with v and suffixed with zero or more lower case letters
- if [[ ! $vers =~ ^v?[[:digit:]]+.[[:digit:]]+(.[[:digit:]]+)?[[:lower:]]*$ ]]; then vers=$(mark $vers); fi
-
- if [ ! "$key" ]; then
- if $flat; then
- echo -e "$file\t$date\t$vers\t$info"
- else
- cat <<-EOF
- file: $file
- date: $date
- vers: $vers
- info: $info
- loca: $loca
- EOF
- fi
- else
- eval "echo \$$key"
- fi
-}
-
-if ! options=$(getopt\
- -n "$myname" \
- -o hHiVIdvlifcsD \
- -l help,Help,date,version,location,info,flat,star,color,debug -- "$@"
-); then exit 1; fi
-eval set -- "$options"
-debug=false flat=false
-while [ $# -gt 0 ]; do
- case $1 in
- (-h|--help) # print this help and exit
- help
- ;;
- (-H|--Help) # print full documentation via less and exit
- helpall
- ;;
- (-V) version
- ;;
- (-d|--date) # print file's date only
- key=date
- ;;
- (-v|--version) # print file's version only
- key=vers
- ;;
- (-i|--info) # print file's description text only
- key=info
- ;;
- (-l|--location) # print file's full path only (same output as kpsewhich)
- key=loca
- ;;
- (-f|--flat) # output as 1 line with 4 tab-separated file, date, version and info fields
- flat=true
- ;;
- (-s|--star) # mark mal-formatted data with a star
- mark1=''
- mark2='*'
- ;;
- (-c|--color) # mark mal-formatted data with red color (ANSI coloring)
- mark1=''
- mark2=''
- ;;
- (-D|--debug) # for debugging, keep temporary files
- debug=true
- ;;
- (-I) install
- ;;
- (--) shift
- break
- ;;
- (*) break
- ;;
- esac
- shift
-done
-
-arg=$1
-case $arg in
-(*/*) loca=$arg
- [[ -e $loca ]] || die "$loca: file does not exist";;
-('') help;;
-(*) loca=$(kpsewhich "$arg") || die "$arg: not found by kpsewhich"
-esac
-loca=$(kpsewhich "$arg")
-prov=$(grep '\\Provides' "$loca") || die "no \\Provides..."
-[[ $prov =~ ExplPackage ]] && die 'Latex3 package (not handled yet)'
-
-# the file must contain a \ProvidesXXX statement, where XXX is Class, Package, or File:
-[[ $prov =~ \\Provides(Class|Package|File)[[:space:]]*\{ ]] ||
- die "Found no \\ProvidesClass/Package/File statement"
-
-# readprov.sty does not work on .mbs and .bst files: special treatment;
-# \ProvideFile statements in them mostly refer to merlin.mbs, or other names
-[[ $arg =~ \.(mbs|bst)$ ]] && dombsbst
-
-dir=$(mktemp -d -t "$myname.XXXXXXXXXX")
-if $debug; then
- echo "Running in $dir"
-else
- trap 'rm -rf $dir' 0 1 2 15
-fi
-cp "$loca" "$dir"
-cd "$dir" || die "Could not cd to $dir"
-
-# The following code is mostly from Uwe Lueck's readprov.sty:
-printf %s '
-\makeatletter
-\def\GetFileInfo#1{%
- \def\filename{#1}%
- \def\@tempb##1 ##2 ##3\relax##4\relax{%
- \def\filedate{##1}%
- \def\fileversion{##2}%
- \def\fileinfo{##3}}%
- \read@file@info\@tempb{#1}}
-\newcommand*{\read@file@info}[2]{%
- \expandafter \expandafter \expandafter
- #1\csname ver@#2\endcsname \relax? ? \relax\relax}
-\newcommand*{\ReadFileInfos}[1]{%
- \begingroup
- \let\RP@@provfile\@providesfile
- \def\@providesfile##1[##2]{\RP@@provfile{##1}[{##2}]\endinput}%
- \def\ProvidesClass ##1{\ProvidesFile{##1.\@clsextension}}%
- \def\ProvidesPackage##1{\ProvidesFile{##1.\@pkgextension}}%
- \@for\@tempa:=#1\do{%
- \edef\@tempa{\expandafter\read@no@spaces\@tempa\@nil}%
- \input{\@tempa}%
- \global\let\@gtempa\@tempa}%
- \endgroup
- \GetFileInfo\@gtempa%
-}
-\def\read@no@spaces#1#2\@nil{#1#2}%
-\def\NeedsTeXFormat#1{\expandafter\@needsformat}
-\ReadFileInfos{'"$loca"'}
-\endinput
-' > ltxfileinfo.tex
-
-pdflatex -interaction=batchmode ltxfileinfo.tex >& /dev/null
-
-IFS= # do not remove any whitespace
-base=${arg##*/} # strip the path
-base=${base%.*} # strip the extension
-shopt -s nocasematch # MS people don't pay attention to case differences in file names...
-while read -r line; do
- if [[ $line =~ ^File:.$base ]]; then
- out="$line"
- while [ ${#line} -eq 79 ]; do # gather continuation lines
- read -r line
- out="$out$line"
- done
- fi
-done <ltxfileinfo.log
-IFS=' ' # back to
-shopt -u nocasematch # normal
-
-# if the \Provides statement is not recognized, try to find out why, and die:
-if [[ -z $out ]]; then
- read -r provtype provarg <<<"$(sed -n '/\Provides\(Class\|Package\|File\)\s*{[^}]*}/s/.*\(Class\|Package\|File\)\s*{\([^}]*\)}.*/\1 \2/p' "$loca")"
- if [[ -z $provarg || $provarg =~ \\ ]]; then die Unidentified problem with \\ProvidesPackage statement; fi
- case $provtype in
- (Package)
- if [[ ! $arg =~ \.(sty|dtx)$ ]]; then
- die \\ProvidesPackage used in file without a .sty extension
- elif [[ $provarg =~ \.sty$ ]]; then
- die "Argument of \\ProvidesPackage ($provarg) should not contain .sty extension"
- elif [[ $provarg != "$base" ]]; then
- die "Argument of \\ProvidesPackage ($provarg) not equal to file's base name ($base)"
- else
- die Unidentified problem with \\ProvidesPackage statement
- fi
- ;;
- (Class)
- if [[ ! $arg =~ \.(cls|dtx)$ ]]; then
- die \\ProvidesClass used in file without a .cls extension
- elif [[ $provarg =~ \.cls$ ]]; then
- die "Argument of \\ProvidesClass ($provarg) should not contain .cls extension"
- elif [[ $provarg != "$base" ]]; then
- die "Argument of \\ProvidesClass ($provarg) not equal to file's base name ($base)"
- else
- die Unidentified problem with \\ProvidesPackage statement
- fi
- ;;
- (File)
- if [[ $arg != "$provarg" ]]; then
- die "Argument of \\ProvidesFile ($provarg) not equal to file's name ($arg)"
- else
- die Unidentified problem with \\ProvidesPackage statement
- fi
- ;;
- (*)
- die "Found \\Provides$provarg statement - cannot handle it"
- ;;
- esac
-fi
-
-out=($out)
-extract "${out[@]}"
-display
diff --git a/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl b/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
deleted file mode 100755
index 791c9316856..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ltximg/ltximg.pl
+++ /dev/null
@@ -1,3284 +0,0 @@
-#!/usr/bin/env perl
-use v5.26;
-
-############################# LICENCE ##################################
-# This program is free software; you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation; either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, but #
-# WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
-# General Public License for more details. #
-########################################################################
-
-use Getopt::Long qw(:config bundling_values require_order no_ignore_case);
-use File::Spec::Functions qw(catfile devnull);
-use File::Basename;
-use Archive::Tar;
-use Data::Dumper;
-use FileHandle;
-use IO::Compress::Zip qw(:all);
-use File::Path qw(remove_tree);
-use File::Temp qw(tempdir);
-use POSIX qw(strftime);
-use File::Copy;
-use File::Find;
-use Env qw(PATH);
-use autodie;
-use Config;
-use Cwd;
-use if $^O eq 'MSWin32', 'Win32';
-use if $^O eq 'MSWin32', 'Module::Load::Conditional' => qw(can_load check_install requires);
-# Need on Windows cmd for colors, TeX Live not provide 'Win32::Console::ANSI'
-if($^O eq 'MSWin32' && check_install( module => 'Win32::Console::ANSI')) {
- require Win32::Console::ANSI;
-}
-use Term::ANSIColor;
-
-### Directory for work and temp files
-my $tempDir = tempdir( CLEANUP => 1);
-my $workdir = cwd;
-
-### Script identification
-my $scriptname = 'ltximg';
-my $program = 'LTXimg';
-my $nv = 'v2.0';
-my $date = '2021-01-24';
-my $copyright = <<"END_COPYRIGHT" ;
-[$date] - LaTeX environments to image and standalone files
-END_COPYRIGHT
-
-### Standart info in terminal
-my $title = "$program $nv $copyright";
-
-### Log vars
-my $LogFile = "$scriptname.log";
-my $LogWrite;
-my $LogTime = strftime("%y-%m-%d %H:%M:%S", localtime);
-
-### Default values
-my $skiptag = 'noltximg'; # internal tag for regex
-my $extrtag = 'ltximg'; # internal tag for regex
-my @extr_env_tmp; # save extract environments
-my @skip_env_tmp; # save skip environments
-my @verb_env_tmp; # save verbatim environments
-my @verw_env_tmp; # save verbatim write environments
-my @delt_env_tmp; # save delete environments in output file
-my @clean; # clean document options
-my $outfile = 0; # write output file
-my $outsrc = 0; # write standalone files
-my $PSTexa = 0; # run extract PSTexample environments
-my $STDenv = 0; # run extract standart environments
-my $verbose = 0; # verbose info
-my $gscmd; # ghostscript executable name
-my $write18; # storing write18 for compiler in TeXLive and MikTeX
-my $log = 0; # log file
-my @currentopt; # storing current options for log file
-
-### Hash to store options for Getopt::Long and log file
-my %opts_cmd;
-$opts_cmd{string}{prefix} = 'fig';
-$opts_cmd{string}{dpi} = '150';
-$opts_cmd{string}{runs} = '1';
-$opts_cmd{string}{margin} = '0';
-$opts_cmd{string}{imgdir} = 'images';
-$opts_cmd{string}{myverb} = 'myverb';
-$opts_cmd{clean} = 'doc';
-
-### Error in command line
-sub errorUsage {
- my $msg = shift;
- die color('red').'* Error!!: '.color('reset').$msg.
- " (run $scriptname --help for more information)\n";
- return;
-}
-
-### Extended error messages
-sub exterr {
- chomp(my $msg_errno = $!);
- chomp(my $msg_extended_os_error = $^E);
- if ($msg_errno eq $msg_extended_os_error) {
- $msg_errno;
- }
- else {
- "$msg_errno/$msg_extended_os_error";
- }
-}
-
-### Funtion uniq
-sub uniq {
- my %seen;
- return grep !$seen{$_}++, @_;
-}
-
-### Funtion array_minus
-sub array_minus(\@\@) {
- my %e = map{ $_ => undef } @{$_[1]};
- return grep !exists $e{$_}, @{$_[0]};
-}
-
-### Funtion to create hash begin -> BEGIN, end -> END
-sub crearhash {
- my %cambios;
- for my $aentra(@_){
- for my $initend (qw(begin end)) {
- $cambios{"\\$initend\{$aentra"} = "\\\U$initend\E\{$aentra";
- }
- }
- return %cambios;
-}
-
-### Print colored info in screen
-sub Infocolor {
- my $type = shift;
- my $info = shift;
- if ($type eq 'Running') {
- print color('cyan'), '* ', color('reset'), color('green'),
- "$type: ", color('reset'), color('cyan'), "$info\r\n", color('reset');
- }
- if ($type eq 'Warning') {
- print color('bold red'), "* $type: ", color('reset'),
- color('yellow'), "$info\r\n", color('reset');
- }
- if ($type eq 'Finish') {
- print color('cyan'), '* ', color('reset'), color('magenta'),
- "$type!: ", color('reset'), color('green'), "$info\r\n",color('reset');
- }
- return;
-}
-
-### Write Log line and print msg (common)
-sub Infoline {
- my $msg = shift;
- my $now = strftime("%y-%m-%d %H:%M:%S", localtime);
- if ($log) { $LogWrite->print(sprintf "[%s] * %s\n", $now, $msg); }
- say $msg;
- return;
-}
-
-### Write Log line (no print msg and time stamp)
-sub Logline {
- my $msg = shift;
- if ($log) { $LogWrite->print("$msg\n"); }
- return;
-}
-
-### Write Log line (time stamp)
-sub Log {
- my $msg = shift;
- my $now = strftime("%y-%m-%d %H:%M:%S", localtime);
- if ($log) { $LogWrite->print(sprintf "[%s] * %s\n", $now, $msg); }
- return;
-}
-
-### Write array env in Log
-sub Logarray {
- my ($env_ref) = @_;
- my @env_tmp = @{ $env_ref }; # dereferencing and copying each array
- if ($log) {
- if (@env_tmp) {
- my $tmp = join "\n", map { qq/* $_/ } @env_tmp;
- print {$LogWrite} "$tmp\n";
- }
- else {
- print {$LogWrite} "Not found\n";
- }
- }
- return;
-}
-
-### Extended print info for execute system commands using $ command
-sub Logrun {
- my $msg = shift;
- my $now = strftime("%y-%m-%d %H:%M:%S", localtime);
- if ($log) { $LogWrite->print(sprintf "[%s] \$ %s\n", $now, $msg); }
- return;
-}
-
-### Capture and execute system commands
-sub RUNOSCMD {
- my $cmdname = shift;
- my $argcmd = shift;
- my $showmsg = shift;
- my $captured = "$cmdname $argcmd";
- Logrun($captured);
- if ($showmsg eq 'show') {
- if ($verbose) {
- Infocolor('Running', $captured);
- }
- else{ Infocolor('Running', $cmdname); }
- }
- if ($showmsg eq 'only' and $verbose) {
- Infocolor('Running', $captured);
- }
- # Run system system command
- $captured = qx{$captured};
- if ($log) { $LogWrite->print($captured); }
- if ($? == -1) {
- my $errorlog = "* Error!!: ".$cmdname." failed to execute (%s)!\n";
- my $errorprint = "* Error!!: ".color('reset').$cmdname." failed to execute (%s)!\n";
- if ($log) { $LogWrite->print(sprintf $errorlog, exterr); }
- print STDERR color('red');
- die sprintf $errorprint, exterr;
- } elsif ($? & 127) {
- my $errorlog = "* Error!!: ".$cmdname." died with signal %d!\n";
- my $errorprint = "* Error!!: ".color('reset').$cmdname." died with signal %d!\n";
- if ($log) { $LogWrite->print(sprintf $errorlog, ($? & 127)); }
- print STDERR color('red');
- die sprintf $errorprint, ($? & 127);
- } elsif ($? != 0 ) {
- my $errorlog = "* Error!!: ".$cmdname." exited with error code %d!\n";
- my $errorprint = "* Error!!: ".color('reset').$cmdname." exited with error code %d!\n";
- if ($log) { $LogWrite->print(sprintf $errorlog, $? >> 8); }
- print STDERR color('red');
- die sprintf $errorprint, $? >> 8;
- }
- if ($verbose) { print $captured; }
- return;
-}
-
-### Help for command line
-sub usage {
-find_ghostscript();
-
-my $usage = <<"END_OF_USAGE";
-${title}Syntax
-\$ ltximg [<options>] [--] <filename>.<tex|ltx>
-
-Description
- ltximg is a "perl" script that automates the process of extracting and
- converting "environments" provided by tikz, pstricks and other packages
- from LaTeX file to image formats and "standalone" files using ghostscript
- and poppler-utils. Generates a one file with only extracted environments
- and other with all extracted environments converted to \\includegraphics.
-
- By default the extracted environments are:
-
- preview pspicture tikzpicture pgfpicture psgraph postscript PSTexample
-
-Options
- Options that accept a value require either a blank space or = between
- the option and the value. Multiple short options can be bundling and
- if the last option takes a comma separated list you need -- at the end.
- Relative or absolute paths for directories and files is not supported.
-
- If used without [<options>] the extracted environments are converted
- to pdf image format and saved in "./images" directory using pdflatex
- and preview package for process.
-
- [default]
--h, --help Display command line help and exit [off]
--v, --version Display current version ($nv) and exit [off]
--V, --verbose Verbose printing information [off]
--l, --log Write .log file with debug information [off]
--t, --tif Create .tif files using ghostscript [$gscmd]
--b, --bmp Create .bmp files using ghostscript [$gscmd]
--j, --jpg Create .jpg files using ghostscript [$gscmd]
--p, --png Create .png files using ghostscript [$gscmd]
--e, --eps Create .eps files using poppler-utils [pdftops]
--s, --svg Create .svg files using poppler-utils [pdftocairo]
--P, --ppm Create .ppm files using poppler-utils [pdftoppm]
--g, --gray Gray scale for images using ghostscript [off]
--f, --force Capture "\\psset" and "\\tikzset" to extract [off]
--n, --noprew Create images files without "preview" package [off]
--r <integer>, --runs=<integer>
- Set the number of times the compiler will run
- on the input file for environment extraction [1]
--d <integer>, --dpi=<integer>
- Dots per inch resolution for images [150]
--m <integer>, --margins=<integer>
- Set margins in bp for pdfcrop [0]
--o <filename>, --output=<filename>
- Create output file [off]
---imgdir=<dirname> Set name of directory to save images/files [images]
---prefix=<string> Set prefix append to each generated files [fig]
---myverb=<macroname> Add "\\macroname" to verbatim inline search [myverb]
---clean=doc|pst|tkz|all|off
- Removes specific block text in output file [doc]
---zip Compress files generated in .zip [off]
---tar Compress files generated in .tar.gz [off]
---srcenv Create files with only code of environments [off]
---subenv Create standalone files for environments [off]
---shell Enable \\write18\{shell command\} [off]
---latex Using latex>dvips>ps2pdf for compiler input
- and pdflatex for compiler output [off]
---dvips Using latex>dvips>ps2pdf for compiler input
- and latex>dvips>ps2pdf for compiler output [off]
---dvilua Using dvilualatex>dvips>ps2pdf for compiler
- input and lualatex for compiler output [off]
---dvipdf Using latex>dvipdfmx for compiler input and
- latex>dvipdfmx for compiler output [off]
---xetex Using xelatex for compiler input and output [off]
---luatex Using lualatex for compiler input and output [off]
---arara Use arara for compiler input and output [off]
---latexmk Using latexmk for compiler output file [off]
---norun Run script, but no create images files [off]
---nopdf Don't create a ".pdf" image files [off]
---nocrop Don't run pdfcrop [off]
---extrenv=<env1,...> Add new environments to extract [empty]
---skipenv=<env1,...> Skip some default environments to extract [empty]
---verbenv=<env1,...> Add new verbatim environments [empty]
---writenv=<env1,...> Add new verbatim write environments [empty]
---deltenv=<env1,...> Delete environments in output file [empty]
-
-Example
-\$ ltximg --latex -e -p --subenv --imgdir mypics -o test-out.ltx test-in.ltx
-
- Create a "./mypics" directory (if it doesn't exist) with all
- extracted environments converted to ".pdf", ".eps", ".png" and
- standalone files ".ltx", a file "test-in-fig-all.ltx" with all
- extracted environments and the file "test-out.ltx" with all
- environments converted to \\includegraphics using latex>dvips>ps2pdf
- and preview package for <test-in.ltx> and pdflatex for
- <test-out.ltx>.
-
-Documentation
-For full documentation use:
-\$ texdoc ltximg
-
-Issues and reports
-Repository : https://github.com/pablgonz/ltximg
-Bug tracker: https://github.com/pablgonz/ltximg/issues
-Copyright(C) 2013-2021 by Pablo González, pablgonz<at>yahoo.com
-END_OF_USAGE
-print $usage;
-exit 0;
-}
-
-### Getopt configuration
-my $result=GetOptions (
-# image options
- 'b|bmp' => \$opts_cmd{image}{bmp}, # gs
- 't|tif' => \$opts_cmd{image}{tif}, # gs
- 'j|jpg' => \$opts_cmd{image}{jpg}, # gs
- 'p|png' => \$opts_cmd{image}{png}, # gs
- 's|svg' => \$opts_cmd{image}{svg}, # pdftocairo
- 'e|eps' => \$opts_cmd{image}{eps}, # pdftops
- 'P|ppm' => \$opts_cmd{image}{ppm}, # pdftoppm
-# compilers
- 'arara' => \$opts_cmd{compiler}{arara}, # arara compiler
- 'xetex' => \$opts_cmd{compiler}{xetex}, # xelatex compiler
- 'latex' => \$opts_cmd{compiler}{latex}, # latex compiler
- 'latexmk' => \$opts_cmd{compiler}{latexmk}, # latex compiler
- 'dvips' => \$opts_cmd{compiler}{dvips}, # dvips compiler
- 'dvipdf' => \$opts_cmd{compiler}{dvipdf}, # dvipdfmx compiler
- 'dvilua' => \$opts_cmd{compiler}{dvilua}, # dvilualatex compiler
- 'luatex' => \$opts_cmd{compiler}{luatex}, # lualatex compiler
-# boolean
- 'zip' => \$opts_cmd{boolean}{zip}, # zip images dir
- 'tar' => \$opts_cmd{boolean}{tar}, # tar images dir
- 'shell' => \$opts_cmd{boolean}{shell}, # set write18 for compiler
- 'nopdf' => \$opts_cmd{boolean}{nopdf}, # no pdf image format
- 'norun' => \$opts_cmd{boolean}{norun}, # no run compiler
- 'nocrop' => \$opts_cmd{boolean}{nocrop}, # no run pdfcrop
- 'subenv' => \$opts_cmd{boolean}{subenv}, # subfile environments (bolean)
- 'srcenv' => \$opts_cmd{boolean}{srcenv}, # source files (bolean)
- 'g|gray' => \$opts_cmd{boolean}{gray}, # gray (boolean)
- 'f|force' => \$opts_cmd{boolean}{force}, # force (boolean)
- 'n|noprew' => \$opts_cmd{boolean}{noprew}, # no preview (boolean)
-# string
- 'd|dpi=i' => \$opts_cmd{string}{dpi}, # positive integer < 2500
- 'r|runs=i' => \$opts_cmd{string}{runs}, # positive integer 1,2,3
- 'm|margins=i' => \$opts_cmd{string}{margins}, # integer
- 'extrenv=s{1,9}' => \@extr_env_tmp, # extract environments
- 'skipenv=s{1,9}' => \@skip_env_tmp, # skip environments
- 'verbenv=s{1,9}' => \@verb_env_tmp, # verbatim environments
- 'writenv=s{1,9}' => \@verw_env_tmp, # verbatim write environments
- 'deltenv=s{1,9}' => \@delt_env_tmp, # delete environments
- 'o|output=s{1}' => \$opts_cmd{string}{output}, # output file name (string)
- 'imgdir=s{1}' => \$opts_cmd{string}{imgdir}, # images dir name
- 'myverb=s{1}' => \$opts_cmd{string}{myverb}, # \myverb inline (string)
- 'prefix=s{1}' => \$opts_cmd{string}{prefix}, # prefix
- 'clean=s{1}' => \$opts_cmd{clean}, # clean output file
-# internal
- 'h|help' => \$opts_cmd{internal}{help}, # help
- 'v|version' => \$opts_cmd{internal}{version}, # version
- 'l|log' => \$log, # write log file
- 'V|verbose' => \$verbose, # verbose mode
- ) or do { $log = 0 ; die usage(0); };
-
-### Open log file
-if ($log) {
- if (!defined $ARGV[0]) { errorUsage('Input filename missing'); }
- my $tempname = $ARGV[0];
- $tempname =~ s/\.(tex|ltx)$//;
- if ($LogFile eq "$tempname.log") { $LogFile = "$scriptname-log.log"; }
- $LogWrite = FileHandle->new("> $LogFile");
-}
-
-### Init ltximg.log file
-Log("The script $scriptname $nv was started in $workdir");
-Log("Creating the temporary directory $tempDir");
-
-### Make ENV safer (perldoc perlsec)
-delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
-
-### The next code it's part of pdfcrop (adapted from TexLive 2014)
-# Windows detection
-my $Win = 0;
-if ($^O =~ /mswin32/i) { $Win = 1; }
-
-my $archname = $Config{'archname'};
-$archname = 'unknown' unless defined $Config{'archname'};
-
-# Get ghostscript command name
-sub find_ghostscript {
- if ($log) {
- Log('General information about the Perl instalation and operating system');
- print {$LogWrite} "* Perl executable: $^X\n";
- if ($] < 5.006) {
- print {$LogWrite} "* Perl version: $]\n";
- }
- else {
- printf {$LogWrite} "* Perl version: v%vd\n", $^V;
- }
- if (defined &ActivePerl::BUILD) {
- printf {$LogWrite} "* Perl product: ActivePerl, build %s\n", ActivePerl::BUILD();
- }
- printf {$LogWrite} "* Pointer size: $Config{'ptrsize'}\n";
- printf {$LogWrite} "* Pipe support: %s\n",
- (defined $Config{'d_pipe'} ? 'yes' : 'no');
- printf {$LogWrite} "* Fork support: %s\n",
- (defined $Config{'d_fork'} ? 'yes' : 'no');
- }
- my $system = 'unix';
- $system = 'win' if $^O =~ /mswin32/i;
- $system = 'msys' if $^O =~ /msys/i;
- $system = 'cygwin' if $^O =~ /cygwin/i;
- $system = 'miktex' if defined $ENV{'TEXSYSTEM'} and
- $ENV{'TEXSYSTEM'} =~ /miktex/i;
- if ($log) {
- print {$LogWrite} "* OS name: $^O\n";
- print {$LogWrite} "* Arch name: $archname\n";
- if ($^O eq 'MSWin32') {
- my $tmp = Win32::GetOSName();
- print {$LogWrite} "* System: $tmp\n";
- }
- else { print {$LogWrite} "* System: $system\n"; }
- }
- Log('Trying to locate the executable for Ghostscript');
- my %candidates = (
- 'unix' => [qw|gs|],
- 'win' => [qw|gswin32c|],
- 'msys' => [qw|gswin64c gswin32c|],
- 'cygwin' => [qw|gs|],
- 'miktex' => [qw|mgs gswin32c|],
- );
- if ($system eq 'win' or $system eq 'miktex') {
- if ($archname =~ /mswin32-x64/i) {
- my @a = ();
- foreach my $name (@{$candidates{$system}}) {
- push @a, 'gswin64c' if $name eq 'gswin32c';
- push @a, $name;
- }
- $candidates{$system} = \@a;
- }
- }
- my %exe = (
- 'unix' => q{},
- 'win' => '.exe',
- 'msys' => '.exe',
- 'cygwin' => '.exe',
- 'miktex' => '.exe',
- );
- my $candidates_ref = $candidates{$system};
- my $exe = $Config{'_exe'};
- $exe = $exe{$system} unless defined $exe;
- my @path = File::Spec->path();
- my $found = 0;
- foreach my $candidate (@$candidates_ref) {
- foreach my $dir (@path) {
- my $file = File::Spec->catfile($dir, "$candidate$exe");
- if (-x $file) {
- $gscmd = $candidate;
- $found = 1;
- if ($log) { print {$LogWrite} "* Found ($candidate): $file\n"; }
- last;
- }
- if ($log) { print {$LogWrite} "* Not found ($candidate): $file\n"; }
- }
- last if $found;
- }
- if (not $found and $Win and $system ne 'msys') {
- $found = SearchRegistry();
- }
- if (not $found and $system eq 'msys') {
- $found = Searchbyregquery();
- }
- if ($found) {
- if ($log) { print {$LogWrite} "* Autodetected ghostscript command: $gscmd\n"; }
- }
- else {
- $gscmd = $$candidates_ref[0];
- if ($log) { print {$LogWrite} "* Default ghostscript command: $gscmd\n"; }
- }
-}
-
-sub SearchRegistry {
- my $found = 0;
- # The module Win32::TieRegistry not aviable in cygwin/msys
- eval 'use Win32::TieRegistry qw|KEY_READ REG_SZ|';
- if ($@) {
- if ($log) {
- print {$LogWrite} "* Registry lookup for Ghostscript failed:\n";
- my $msg = $@;
- $msg =~ s/\s+$//;
- foreach (split /\r?\n/, $msg) {
- print {$LogWrite} " $_\n";
- }
- }
- return $found;
- }
- my $open_params = {Access => KEY_READ(), Delimiter => q{/}};
- my $key_name_software = 'HKEY_LOCAL_MACHINE/SOFTWARE/';
- my $current_key = $key_name_software;
- my $software = new Win32::TieRegistry $current_key, $open_params;
- if (not $software) {
- if ($log) {
- print {$LogWrite} "* Cannot find or access registry key `$current_key'!\n";
- }
- return $found;
- }
- if ($log) { print {$LogWrite} "* Search registry at `$current_key'.\n"; }
- my %list;
- foreach my $key_name_gs (grep /Ghostscript/i, $software->SubKeyNames()) {
- $current_key = "$key_name_software$key_name_gs/";
- if ($log) { print {$LogWrite} "* Registry entry found: $current_key\n"; }
- my $key_gs = $software->Open($key_name_gs, $open_params);
- if (not $key_gs) {
- if ($log) { print {$LogWrite} "* Cannot open registry key `$current_key'!\n"; }
- next;
- }
- foreach my $key_name_version ($key_gs->SubKeyNames()) {
- $current_key = "$key_name_software$key_name_gs/$key_name_version/";
- if ($log) { print {$LogWrite} "* Registry entry found: $current_key\n"; }
- if (not $key_name_version =~ /^(\d+)\.(\d+)$/) {
- if ($log) { print {$LogWrite} " The sub key is not a version number!\n"; }
- next;
- }
- my $version_main = $1;
- my $version_sub = $2;
- $current_key = "$key_name_software$key_name_gs/$key_name_version/";
- my $key_version = $key_gs->Open($key_name_version, $open_params);
- if (not $key_version) {
- if ($log) { print {$LogWrite} "* Cannot open registry key `$current_key'!\n"; }
- next;
- }
- $key_version->FixSzNulls(1);
- my ($value, $type) = $key_version->GetValue('GS_DLL');
- if ($value and $type == REG_SZ()) {
- if ($log) { print {$LogWrite} " GS_DLL = $value\n"; }
- $value =~ s|([\\/])([^\\/]+\.dll)$|$1gswin32c.exe|i;
- my $value64 = $value;
- $value64 =~ s/gswin32c\.exe$/gswin64c.exe/;
- if ($archname =~ /mswin32-x64/i and -f $value64) {
- $value = $value64;
- }
- if (-f $value) {
- if ($log) { print {$LogWrite} "EXE found: $value\n"; }
- }
- else {
- if ($log) { print {$LogWrite} "EXE not found!\n"; }
- next;
- }
- my $sortkey = sprintf '%02d.%03d %s',
- $version_main, $version_sub, $key_name_gs;
- $list{$sortkey} = $value;
- }
- else {
- if ($log) { print {$LogWrite} "Missing key `GS_DLL' with type `REG_SZ'!\n"; }
- }
- }
- }
- foreach my $entry (reverse sort keys %list) {
- $gscmd = $list{$entry};
- if ($log) { print {$LogWrite} "* Found (via registry): $gscmd\n"; }
- $found = 1;
- last;
- }
- return $found;
-} # end GS search registry
-
-### This part is only necessary if you're using Git on windows and don't
-### have gs configured in PATH. Git for windows don't have a Win32::TieRegistry
-### module for perl (is not supported in the current versions of msys).
-sub Searchbyregquery {
- my $found = 0;
- my $gs_regkey;
- my $opt_reg = '//s //v';
- if ($log) { print {$LogWrite} "* Search Ghostscript in Windows registry under mingw/msys:\n";}
- $gs_regkey = qx{reg query "HKLM\\Software\\GPL Ghostscript" $opt_reg GS_DLL};
- if ($? == 0) {
- if ($log) { print {$LogWrite} "* Registry entry found for GS_DLL (64 bits version)\n";}
- }
- else {
- $gs_regkey = qx{reg query "HKLM\\Software\\Wow6432Node\\GPL Ghostscript" $opt_reg GS_DLL};
- if ($? == 0) {
- if ($log) { print {$LogWrite} "* Registry entry found for GS_DLL (32 bits version)\n";}
- }
- }
- my ($gs_find) = $gs_regkey =~ m/(?:\s* GS_DLL \s* REG_SZ \s*) (.+?)(?:\.dll.+?\R)/s;
- if ($gs_find) {
- my ($gs_vol, $gs_path, $gs_ver) = $gs_find =~ m/
- (\w{1})(?:\:) # volumen
- (.+?) # path to executable
- (?:\\gsdll) # LIB
- (\d{2}) # Version
- /xs;
- # Adjust
- $gs_vol = lc($gs_vol);
- $gs_path = '/'.$gs_vol.$gs_path;
- $gs_path =~ s|\\|/|gmsxi;
- # Add to PATH
- if ($log) { print {$LogWrite} "* Add $gs_path to PATH for current session\n"; }
- $PATH .= ":$gs_path";
- # Set executable
- $gscmd = 'gswin'.$gs_ver.'c';
- if ($log) { print {$LogWrite} "* Found (via reg query): $gscmd\n"; }
- $found = 1;
- }
- if ($@) {
- if ($log) {
- print {$LogWrite} "* Registry lookup for Ghostscript by reg query failed:\n";
- my $msg = $@;
- $msg =~ s/\s+$//;
- foreach (split /\r?\n/, $msg) {
- print {$LogWrite} " $_\n";
- }
- }
- return $found;
- }
- return $found;
-}
-
-### Call GS
-find_ghostscript();
-
-### Windows need suport space in path
-if ($Win and $gscmd =~ /\s/) { $gscmd = "\"$gscmd\"";}
-
-### Help
-if (defined $opts_cmd{internal}{help}) {
- usage(1);
- exit 0;
-}
-
-### Version
-if (defined $opts_cmd{internal}{version}) {
- print $title;
- exit 0;
-}
-
-### Check <input file> from command line
-@ARGV > 0 or errorUsage('Input filename missing');
-@ARGV < 2 or errorUsage('Unknown option or too many input files');
-
-### Check <input file> extention
-my @SuffixList = ('.tex', '.ltx');
-my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
-if ($ext eq '.tex' or $ext eq '.ltx') {
- $ext = $ext;
-}
-else {
- errorUsage('Invalid or empty extention for input file');
-}
-
-### Read <input file> in memory, need [:crlf] for old windows files
-Log("Read input file $name$ext in memory");
-open my $INPUTfile, '<:crlf', "$name$ext";
- my $ltxfile;
- {
- local $/;
- $ltxfile = <$INPUTfile>;
- }
-close $INPUTfile;
-
-### Set tmp random number for <name-fig-tmp> and others
-my $tmp = int(rand(10000));
-
-### Identification message in terminal
-print $title;
-
-### Remove white space and '=' in array captured from command line
-s/^\s*(\=):?|\s*//mg foreach @extr_env_tmp;
-s/^\s*(\=):?|\s*//mg foreach @skip_env_tmp;
-s/^\s*(\=):?|\s*//mg foreach @verb_env_tmp;
-s/^\s*(\=):?|\s*//mg foreach @verw_env_tmp;
-s/^\s*(\=):?|\s*//mg foreach @delt_env_tmp;
-
-### Split comma separte list options from command line
-@extr_env_tmp = split /,/,join q{},@extr_env_tmp;
-@skip_env_tmp = split /,/,join q{},@skip_env_tmp;
-@verb_env_tmp = split /,/,join q{},@verb_env_tmp;
-@verw_env_tmp = split /,/,join q{},@verw_env_tmp;
-@delt_env_tmp = split /,/,join q{},@delt_env_tmp;
-
-### Validate environments options from comand line
-if (grep /(^\-|^\.).*?/, @extr_env_tmp) {
- Log('Error!!: Invalid argument for --extrenv, some argument from list begin with -');
- errorUsage('Invalid argument for --extrenv option');
-}
-if (grep /(^\-|^\.).*?/, @skip_env_tmp) {
- Log('Error!!: Invalid argument for --skipenv, some argument from list begin with -');
- errorUsage('Invalid argument for --skipenv option');
-}
-if (grep /(^\-|^\.).*?/, @verb_env_tmp) {
- Log('Error!!: Invalid argument for --verbenv, some argument from list begin with -');
- errorUsage('Invalid argument for --verbenv option');
-}
-if (grep /(^\-|^\.).*?/, @verw_env_tmp) {
- Log('Error!!: Invalid argument for --writenv, some argument from list begin with -');
- errorUsage('Invalid argument for --writenv option');
-}
-if (grep /(^\-|^\.).*?/, @delt_env_tmp) {
- Log('Error!!: Invalid argument for --deltenv, some argument from list begin with -');
- errorUsage('Invalid argument for --deltenv option');
-}
-
-### Default environment to extract
-my @extr_tmp = qw (
- preview postscript tikzpicture pgfpicture pspicture psgraph PSTexample
- );
-push @extr_env_tmp, @extr_tmp;
-
-### Default verbatim environment
-my @verb_tmp = qw (
- Example CenterExample SideBySideExample PCenterExample PSideBySideExample
- verbatim Verbatim BVerbatim LVerbatim SaveVerbatim PSTcode
- LTXexample tcblisting spverbatim minted listing lstlisting
- alltt comment chklisting verbatimtab listingcont boxedverbatim
- demo sourcecode xcomment pygmented pyglist program programl
- programL programs programf programsc programt
- );
-push @verb_env_tmp, @verb_tmp;
-
-### Default verbatim write environment
-my @verbw_tmp = qw (
- scontents filecontents tcboutputlisting tcbexternal tcbwritetmp extcolorbox extikzpicture
- VerbatimOut verbatimwrite filecontentsdef filecontentshere filecontentsdefmacro
- filecontentsdefstarred filecontentsgdef filecontentsdefmacro filecontentsgdefmacro
- );
-push @verw_env_tmp, @verbw_tmp;
-
-########################################################################
-# One problem that can arise is the filecontents environment, this can #
-# contain a complete document and be anywhere, before dividing we will #
-# make some replacements for this and comment lines #
-########################################################################
-
-### Create a Regex for verbatim write environment
-@verw_env_tmp = uniq(@verw_env_tmp);
-my $tmpverbw = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verw_env_tmp;
-$tmpverbw = qr/$tmpverbw/x;
-my $tmp_verbw = qr {
- (
- (?:
- \\begin\{$tmpverbw\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$tmpverbw\*?\})
- (?!end\{$tmpverbw\*?\})|
- (?-1)
- )*
- \\end\{$tmpverbw\*?\}
- )
- )
- }x;
-
-### A pre-regex for comment lines
-my $tmpcomment = qr/^ \s* \%+ .+? $ /mx;
-
-### Hash for replace in verbatim's and comment lines
-my %document = (
- '\begin{document}' => '\BEGIN{document}',
- '\end{document}' => '\END{document}',
- '\documentclass' => '\DOCUMENTCLASS',
- '\pagestyle{' => '\PAGESTYLE{',
- '\thispagestyle{' => '\THISPAGESTYLE{',
- );
-
-### Changes in <input file> for verbatim write and comment lines
-while ($ltxfile =~ / $tmp_verbw | $tmpcomment /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- while (my($busco, $cambio) = each %document) {
- $encontrado =~ s/\Q$busco\E/$cambio/g;
- }
- substr $ltxfile, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($ltxfile) = $pos_inicial + length $encontrado;
-}
-
-### Now, split input file in $atbegindoc and contain % ltximg : <argument>
-my ($atbegindoc, $document) = $ltxfile =~ m/\A (\s* .*? \s*) (\\documentclass.*)\z/msx;
-
-### Capture options in preamble of <input file>
-# % ltximg : extrenv : {extrenv1, extrenv2, ... , extrenvn}
-# % ltximg : skipenv : {skipenv1, skipenv2, ... , skipenvn}
-# % ltximg : verbenv : {verbwrt1, verbwrt2, ... , verbwrtn}
-# % ltximg : writenv : {verbwrt1, verbwrt2, ... , verbwrtn}
-# % ltximg : deltenv : {deltenv1, deltenv2, ... , deltenvn}
-# % ltximg : options : {opt1=arg, opt2=arg, ... , booleans}
-
-my $readoptfile = qr/
- ^ %+ \s* ltximg (?&SEPARADOR) (?<clave>(?&CLAVE)) (?&SEPARADOR) \{ (?<argumentos>(?&ARGUMENTOS)) \}
- (?(DEFINE)
- (?<CLAVE> \w+ )
- (?<ARGUMENTOS> .+? )
- (?<SEPARADOR> \s* : \s* )
- )
-/mx;
-
-### Search options in <input file> and store in %opts_file
-my %opts_file;
-while ($atbegindoc =~ /$readoptfile/g) {
- my ($clave, $argumentos) = @+{qw(clave argumentos)};
- my @argumentos = split /\s*,\s*?/, $argumentos;
- for (@argumentos) { s/^ \s* | \s* $//gx; }
- if ($clave eq 'options') {
- for my $argumento (@argumentos) {
- if ($argumento =~ /(?<key>\S+) \s* = \s* (?<valor>\S+)/x) {
- $opts_file{$clave}{$+{'key'}} = $+{'valor'};
- }
- else {
- $opts_file{$clave}{$argumento} = 1;
- }
- }
- }
- else {
- push @{ $opts_file{ $clave } }, @argumentos;
- }
-}
-
-### Process options from <input file>
-if(%opts_file) {
- Infocolor('Warning', "Found options for script in $name$ext");
- # Search and extract options from <input file>
- Log("Searching options for script in $name$ext");
- if (exists $opts_file{extrenv}) {
- Log("Found \% ltximg\: extrenv\: \{...\} in $name$ext");
- if (grep /(^\-|^\.).*?/, @{$opts_file{extrenv}}) {
- Log('Error!!: Invalid argument for % ltximg: extrenv: {...}, some argument from list begin with -');
- errorUsage('Invalid argument in % ltximg: extrenv: {...}');
- }
- Logarray(\@{$opts_file{extrenv}});
- push @extr_env_tmp, @{$opts_file{extrenv}};
- }
- # Add skipenv options from <input file>
- if (exists $opts_file{skipenv}) {
- Log("Found \% ltximg\: skipenv\: \{...\} in $name$ext");
- if (grep /(^\-|^\.).*?/, @{$opts_file{skipenv}}) {
- Log('Error!!: Invalid argument for % ltximg: skipenv: {...}, some argument from list begin with -');
- errorUsage('Invalid argument in % ltximg: skipenv: {...}');
- }
- Logarray(\@{$opts_file{skipenv}});
- push @skip_env_tmp, @{$opts_file{skipenv}};
- }
- # Add verbenv options from <input file>
- if (exists $opts_file{verbenv}) {
- Log("Found \% ltximg\: verbenv\: \{...} in $name$ext");
- if (grep /(^\-|^\.).*?/, @{$opts_file{verbenv}}) {
- Log('Error!!: Invalid argument for % ltximg: verbenv: {...}, some argument from list begin with -');
- errorUsage('Invalid argument in % ltximg: verbenv: {...}');
- }
- Logarray(\@{ $opts_file{verbenv}});
- push @verb_env_tmp, @{$opts_file{verbenv}};
- }
- # Add writenv options from <input file>
- if (exists $opts_file{writenv}) {
- Log("Found \% ltximg\: writenv\: \{...\} in $name$ext");
- if (grep /(^\-|^\.).*?/, @{ $opts_file{writenv}}) {
- Log('Error!!: Invalid argument for % ltximg: writenv: {...}, some argument from list begin with -');
- errorUsage('Invalid argument in % ltximg: writenv: {...}');
- }
- Logarray(\@{ $opts_file{writenv}});
- push @verw_env_tmp, @{$opts_file{writenv}};
- }
- # Add deltenv options from <input file>
- if (exists $opts_file{deltenv}) {
- Log("Found \% ltximg\: deltenv\: \{...\} in $name$ext");
- if (grep /(^\-|^\.).*?/, @{$opts_file{deltenv}}) {
- Log('Error!!: Invalid argument for % ltximg: deltenv: {...}, some argument from list begin with -');
- errorUsage('Invalid argument in % ltximg: deltenv: {...}');
- }
- Logarray(\@{ $opts_file{deltenv}});
- push @delt_env_tmp, @{$opts_file{deltenv}};
- }
- # Add all other options from <input file>
- if (exists $opts_file{options}) {
- Log("Found \% ltximg\: options\: \{...\} in $name$ext");
- # Add compilers from <input file>
- for my $opt (qw(arara xetex luatex latex dvips dvipdf dvilua latexmk)) {
- if (exists $opts_file{options}{$opt}) {
- Log("Found [$opt] compiler option in $name$ext");
- $opts_cmd{compiler}{$opt} = 1;
- }
- }
- # Add image options
- for my $opt (qw(eps ppm svg png jpg bmp tif)) {
- if (exists $opts_file{options}{$opt}) {
- Log("Found [$opt] image option in $name$ext");
- $opts_cmd{image}{$opt} = 1;
- }
- }
- # Add boolean options
- for my $opt (qw(shell nopdf norun nocrop srcenv subenv zip tar gray force noprew)) {
- if (exists $opts_file{options}{$opt}) {
- Log("Found [$opt] option in $name$ext");
- $opts_cmd{boolean}{$opt} = 1;
- }
- }
- # Add string options
- for my $opt (qw(dpi myverb margins prefix imgdir output runs)) {
- if (exists $opts_file{options}{$opt}) {
- Log("Found [$opt = $opts_file{options}{$opt}] in $name$ext");
- $opts_cmd{string}{$opt} = $opts_file{options}{$opt};
- }
- }
- # Add clean option
- for my $opt (qw(doc off pst tkz all)) {
- if ($opts_file{options}{clean} eq "$opt" ) {
- Log("Found [clean = $opt] in $name$ext");
- $opts_cmd{clean} = $opt;
- }
- }
- }
-}
-
-### Validate --dpi
-if( $opts_cmd{string}{dpi} <= 0 or $opts_cmd{string}{dpi} >= 2500) {
- Log('Error!!: Invalid argument for --dpi, argument out of range');
- errorUsage('Invalid argument for --dpi option');
-}
-
-### Validate --runs
-if( $opts_cmd{string}{runs} <= 0 or $opts_cmd{string}{runs} >= 3) {
- Log('Error!!: Invalid argument for --runs, argument out of range');
- errorUsage('Invalid argument for --runs option');
-}
-
-### Check --arara and others compilers
-if ($opts_cmd{compiler}{arara}) {
- # Search others compilers options
- for my $opt (qw(xetex luatex latex dvips dvipdf dvilua latexmk)) {
- if (defined $opts_cmd{compiler}{$opt}) {
- Log("Error!!: Options --arara and --$opt are mutually exclusive");
- errorUsage("Options --arara and --$opt are mutually exclusive");
- }
- }
-}
-
-### Check --srcenv and --subenv option
-if ($opts_cmd{boolean}{srcenv} && $opts_cmd{boolean}{subenv}) {
- Log('Error!!: Options --srcenv and --subenv are mutually exclusive');
- errorUsage('Options --srcenv and --subenv are mutually exclusive');
-}
-
-### If --srcenv or --subenv option are OK activate write <sub files>
-if ($opts_cmd{boolean}{srcenv}) {
- $outsrc = 1;
- $opts_cmd{boolean}{subenv} = undef;
-}
-if ($opts_cmd{boolean}{subenv}) {
- $outsrc = 1;
- $opts_cmd{boolean}{srcenv} = undef;
-}
-
-### Add pdf image format if --nopdf
-if (!$opts_cmd{boolean}{nopdf}) {
- $opts_cmd{image}{pdf} = 1;
-}
-
-### Store defined image formats in $format
-my $format = join q{, },grep { defined $opts_cmd{image}{$_} } keys %{$opts_cmd{image}};
-
-### Write defined image format in log file
-if (!$opts_cmd{boolean}{norun}) {
- Log("Defined image formats for creating: $format");
-}
-
-### Check --norun and no images type
-if (!$opts_cmd{boolean}{norun} and $format eq q{}) {
- Log('Error!!: Option --nopdf need --norun or an image option');
- errorUsage('Option --nopdf need --norun or an image option');
-}
-
-### Check --dvips and no eps image type
-if ($opts_cmd{compiler}{dvips} and !$opts_cmd{image}{eps} and !$opts_cmd{boolean}{norun}) {
- Log('Error!!: Option --dvips need --eps');
- errorUsage('Option --dvips need --eps');
-}
-
-### Validate myverb = macro option
-if (defined $opts_cmd{string}{myverb}) {
- if ($opts_cmd{string}{myverb} =~ /^(?:\\|\-).+?/) {
- Log('Error!!: Invalid argument for --myverb option, argument begin with - or \ ');
- errorUsage('Invalid argument for --myverb');
- }
- else { Log("Set myverb = $opts_cmd{string}{myverb}"); }
-}
-
-### Validate imgdir = string option
-if (defined $opts_cmd{string}{imgdir}) {
- if ($opts_cmd{string}{imgdir} =~ /^(?:\\|\-).+?/) {
- Log('Error!!: Invalid argument for --imgdir option, argument begin with -, \ or /');
- errorUsage('Invalid argument for --imgdir');
- }
- else { Log("Set imgdir = $opts_cmd{string}{imgdir}"); }
-}
-
-### Validate clean
-my %clean = map { $_ => 1 } @clean;
-$clean{doc} = 1; # by default clean = doc
-
-### Pass $opts_cmd{clean} to $clean{$opt}
-for my $opt (qw(doc off pst tkz all)) {
- if ($opts_cmd{clean} eq "$opt") {
- $clean{$opt} = 1;
- push @currentopt, "--clean=$opt";
- }
-}
-
-### Activate clean options for script
-if ($clean{pst} or $clean{tkz}) { $clean{doc} = 1; }
-if ($clean{all}) { @clean{qw(pst doc tkz)} = (1) x 3; }
-if ($clean{off}) { undef %clean; }
-
-### Validating the <output file> name and save extension
-my $outext;
-if (defined $opts_cmd{string}{output}) {
- Log('Validating name and extension for output file');
- # Capture and split
- my ($outname, $outpath, $tmpext) = fileparse($opts_cmd{string}{output}, @SuffixList);
- if ($outname =~ /(^\-|^\.).*?/) {
- Log('The name of output file begin with dash -');
- errorUsage("$opts_cmd{string}{output} it is not a valid name for output file");
- }
- if ($tmpext eq q{}) { # Check and set extension
- Log("Set extension for output file to $ext");
- $outext = $ext;
- }
- else {
- Log("Set extension for output file to $tmpext");
- $outext = $tmpext;
- }
- if ($outname eq $name) { # Check name
- Log("The name of the output file must be different that $name");
- Infoline("Changing the output file name to $name-out");
- $opts_cmd{string}{output} = "$name-out";
- }
- else {
- Log("Set name of the output file to $outname");
- $opts_cmd{string}{output} = $outname;
- }
- # If output name are ok, then $outfile = 1
- $outfile = 1;
-}
-
-### Storing the current options of script in array for ltximg.log file
-my @allopt = qw (arara xetex luatex latex dvips dvipdf dvilua latexmk
- shell nopdf norun nocrop srcenv subenv zip tar gray force
- noprew eps ppm svg png jpg bmp tif dpi myverb margins
- prefix imgdir output runs
- );
-
-for my $opt (@allopt) {
- if (defined $opts_cmd{boolean}{$opt}) {
- push @currentopt, "--$opt";
- }
- if (defined $opts_cmd{compiler}{$opt}) {
- push @currentopt, "--$opt";
- }
- if (defined $opts_cmd{image}{$opt}) {
- push @currentopt, "--$opt";
- }
- if (defined $opts_cmd{string}{$opt}) {
- push @currentopt, "--$opt=$opts_cmd{string}{$opt}"
- }
-}
-
-### Write all options in ltximg.log file
-@currentopt = sort { length $a <=> length $b } @currentopt;
-Log('The script will execute the following options:');
-Logarray(\@currentopt);
-
-### Rules to capture for regex
-my $braces = qr/ (?:\{)(.+?)(?:\}) /msx;
-my $braquet = qr/ (?:\[)(.+?)(?:\]) /msx;
-my $no_corchete = qr/ (?:\[ .*? \])? /msx;
-
-### Array for capture new verbatim environments defined in input file
-my @new_verb = qw (
- newtcblisting DeclareTCBListing ProvideTCBListing NewTCBListing
- lstnewenvironment NewListingEnvironment NewProgram specialcomment
- includecomment DefineVerbatimEnvironment newverbatim newtabverbatim
- );
-
-### Regex to capture names for new verbatim environments from input file
-my $newverbenv = join q{|}, map { quotemeta} sort { length $a <=> length $b } @new_verb;
-$newverbenv = qr/\b(?:$newverbenv) $no_corchete $braces/msx;
-
-### Array for capture new verbatim write environments defined in input file
-my @new_verb_write = qw (
- renewtcbexternalizetcolorbox renewtcbexternalizeenvironment
- newtcbexternalizeenvironment newtcbexternalizetcolorbox newenvsc
- );
-
-### Regex to capture names for new verbatim write environments from input file
-my $newverbwrt = join q{|}, map { quotemeta} sort { length $a <=> length $b } @new_verb_write;
-$newverbwrt = qr/\b(?:$newverbwrt) $no_corchete $braces/msx;
-
-### Regex to capture MINTED related environments
-my $mintdenv = qr/\\ newminted $braces (?:\{.+?\}) /x;
-my $mintcenv = qr/\\ newminted $braquet (?:\{.+?\}) /x;
-my $mintdshrt = qr/\\ newmint $braces (?:\{.+?\}) /x;
-my $mintcshrt = qr/\\ newmint $braquet (?:\{.+?\}) /x;
-my $mintdline = qr/\\ newmintinline $braces (?:\{.+?\}) /x;
-my $mintcline = qr/\\ newmintinline $braquet (?:\{.+?\}) /x;
-
-### Filter input file, now $ltxfile is pass to $filecheck
-Log("Filter $name$ext \(remove % and comments\)");
-my @filecheck = $ltxfile;
-s/%.*\n//mg foreach @filecheck; # del comments
-s/^\s*|\s*//mg foreach @filecheck; # del white space
-my $filecheck = join q{}, @filecheck;
-
-### Search verbatim and verbatim write environments <input file>
-Log("Search verbatim and verbatim write environments in $name$ext");
-
-### Search new verbatim write names in <input file>
-my @newv_write = $filecheck =~ m/$newverbwrt/xg;
-if (@newv_write) {
- Log("Found new verbatim write environments in $name$ext");
- Logarray(\@newv_write);
- push @verw_env_tmp, @newv_write;
-}
-
-### Search new verbatim environments in <input file> (for)
-my @verb_input = $filecheck =~ m/$newverbenv/xg;
-if (@verb_input) {
- Log("Found new verbatim environments in $name$ext");
- Logarray(\@verb_input);
- push @verb_env_tmp, @verb_input;
-}
-
-### Search \newminted{$mintdenv}{options} in <input file>, need add "code" (for)
-my @mint_denv = $filecheck =~ m/$mintdenv/xg;
-if (@mint_denv) {
- Log("Found \\newminted\{envname\} in $name$ext");
- # Append "code"
- $mintdenv = join "\n", map { qq/$_\Qcode\E/ } @mint_denv;
- @mint_denv = split /\n/, $mintdenv;
- Logarray(\@mint_denv);
- push @verb_env_tmp, @mint_denv;
-}
-
-### Search \newminted[$mintcenv]{lang} in <input file> (for)
-my @mint_cenv = $filecheck =~ m/$mintcenv/xg;
-if (@mint_cenv) {
- Log("Found \\newminted\[envname\] in $name$ext");
- Logarray(\@mint_cenv);
- push @verb_env_tmp, @mint_cenv;
-}
-
-### Remove repetead again :)
-@verb_env_tmp = uniq(@verb_env_tmp);
-
-### Capture verbatim inline macros in input file
-Log("Search verbatim macros in $name$ext");
-
-### Store all minted inline/short in @mintline
-my @mintline;
-
-### Search \newmint{$mintdshrt}{options} in <input file> (while)
-my @mint_dshrt = $filecheck =~ m/$mintdshrt/xg;
-if (@mint_dshrt) {
- Log("Found \\newmint\{macroname\} (short) in $name$ext");
- Logarray(\@mint_dshrt);
- push @mintline, @mint_dshrt;
-}
-
-### Search \newmint[$mintcshrt]{lang}{options} in <input file> (while)
-my @mint_cshrt = $filecheck =~ m/$mintcshrt/xg;
-if (@mint_cshrt) {
- Log("Found \\newmint\[macroname\] (short) in $name$ext");
- Logarray(\@mint_cshrt);
- push @mintline, @mint_cshrt;
-}
-
-### Search \newmintinline{$mintdline}{options} in <input file> (while)
-my @mint_dline = $filecheck =~ m/$mintdline/xg;
-if (@mint_dline) {
- Log("Found \\newmintinline\{macroname\} in $name$ext");
- # Append "inline"
- $mintdline = join "\n", map { qq/$_\Qinline\E/ } @mint_dline;
- @mint_dline = split /\n/, $mintdline;
- Logarray(\@mint_dline);
- push @mintline, @mint_dline;
-}
-
-### Search \newmintinline[$mintcline]{lang}{options} in <input file> (while)
-my @mint_cline = $filecheck =~ m/$mintcline/xg;
-if (@mint_cline) {
- Log("Found \\newmintinline\[macroname\] in $name$ext");
- Logarray(\@mint_cline);
- push @mintline, @mint_cline;
-}
-
-### Add standart mint, mintinline and lstinline
-my @mint_tmp = qw(mint mintinline lstinline);
-
-### Join all inline verbatim macros captured
-push @mintline, @mint_tmp;
-@mintline = uniq(@mintline);
-
-### Create a regex using @mintline
-my $mintline = join q{|}, map { quotemeta } sort { length $a <=> length $b } @mintline;
-$mintline = qr/\b(?:$mintline)/x;
-
-### Reserved words in verbatim inline (while)
-my %changes_in = (
- '%<*ltximg>' => '%<*LTXIMG>',
- '%</ltximg>' => '%</LTXIMG>',
- '%<*noltximg>' => '%<*NOLTXIMG>',
- '%</noltximg>' => '%</NOLTXIMG>',
- '%<*remove>' => '%<*REMOVE>',
- '%</remove>' => '%</REMOVE>',
- '\psset' => '\PSSET',
- '\tikzset' => '\TIKZSET',
- '\pspicture' => '\TRICKS',
- '\endpspicture' => '\ENDTRICKS',
- '\pgfpicture' => '\PGFTRICKS',
- '\endpgfpicture' => '\ENDPGFTRICKS',
- '\tikzpicture' => '\TKZTRICKS',
- '\endtikzpicture' => '\ENDTKZTRICKS',
- '\psgraph' => '\PSGRAPHTRICKS',
- '\endpsgraph' => '\ENDPSGRAPHTRICKS',
- '\usepackage' => '\USEPACKAGE',
- '{graphicx}' => '{GRAPHICX}',
- '\graphicspath{' => '\GRAPHICSPATH{',
- );
-
-### Hash to replace \begin and \end in verbatim inline
-my %init_end = (
- '\begin{' => '\BEGIN{',
- '\end{' => '\END{',
- );
-
-### Join changes in new hash (while) for verbatim inline
-my %cambios = (%changes_in,%init_end);
-
-### Variables and constantes
-my $no_del = "\0";
-my $del = $no_del;
-
-### Rules
-my $llaves = qr/\{ .+? \} /x;
-my $no_llaves = qr/(?: $llaves )? /x;
-my $corchetes = qr/\[ .+? \] /x;
-my $delimitador = qr/\{ (?<del>.+?) \} /x;
-my $scontents = qr/Scontents [*]? $no_corchete /ix;
-my $verb = qr/(?:((spv|(?:q|f)?v|V)erb|$opts_cmd{string}{myverb})[*]?) /ix;
-my $lst = qr/(?:(lst|pyg)inline)(?!\*) $no_corchete /ix;
-my $mint = qr/(?: $mintline |SaveVerb) (?!\*) $no_corchete $no_llaves $llaves /ix;
-my $no_mint = qr/(?: $mintline) (?!\*) $no_corchete /ix;
-my $marca = qr/\\ (?:$verb | $lst |$scontents | $mint |$no_mint) (?:\s*)? (\S) .+? \g{-1} /sx;
-my $comentario = qr/^ \s* \%+ .+? $ /mx;
-my $definedel = qr/\\ (?: DefineShortVerb | lstMakeShortInline| MakeSpecialShortVerb ) [*]? $no_corchete $delimitador /ix;
-my $indefinedel = qr/\\ (?: (Undefine|Delete)ShortVerb | lstDeleteShortInline) $llaves /ix;
-
-Log('Making changes to inline/multiline verbatim before extraction');
-
-### Changes in input file for verbatim inline/multiline
-while ($document =~
- / $marca
- | $comentario
- | $definedel
- | $indefinedel
- | $del .+? $del
- /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- if ($encontrado =~ /$definedel/) {
- $del = $+{del};
- $del = "\Q$+{del}" if substr($del,0,1) ne '\\';
- }
- elsif ($encontrado =~ /$indefinedel/) {
- $del = $no_del;
- }
- else {
- while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/g;
- }
- substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
- }
-}
-
-### Change "escaped braces" to <LTXSB.> (this label is not the one in the document)
-$document =~ s/\\[{]/<LTXSBO>/g;
-$document =~ s/\\[}]/<LTXSBC>/g;
-
-### Regex for verbatim inline/multiline with braces {...}
-my $nestedbr = qr / ( [{] (?: [^{}]++ | (?-1) )*+ [}] ) /x;
-my $fvextra = qr /\\ (?: (Save|Esc)Verb [*]?) $no_corchete /x;
-my $mintedbr = qr /\\ (?:$mintline|pygment) (?!\*) $no_corchete $no_llaves /x;
-my $tcbxverb = qr /\\ (?: tcboxverb [*]?| Scontents [*]? |$opts_cmd{string}{myverb} [*]?|lstinline) $no_corchete /x;
-my $verb_brace = qr / (?:$tcbxverb|$mintedbr|$fvextra) (?:\s*)? $nestedbr /x;
-
-### Change \verb*{code} for verbatim inline/multiline
-while ($document =~ /$verb_brace/pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/g;
- }
- substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
-}
-
-### We recovered the escaped braces
-$document =~ s/<LTXSBO>/\\{/g;
-$document =~ s/<LTXSBC>/\\}/g;
-
-### Reverse changes for extract and output file
-my %changes_out = (
- '\PSSET' => '\psset',
- '\TIKZSET' => '\tikzset',
- '\TRICKS' => '\pspicture',
- '\ENDTRICKS' => '\endpspicture',
- '\PGFTRICKS' => '\pgfpicture',
- '\ENDPGFTRICKS' => '\endpgfpicture',
- '\TKZTRICKS' => '\tikzpicture',
- '\ENDTKZTRICKS' => '\endtikzpicture',
- '\PSGRAPHTRICKS' => '\psgraph',
- '\ENDPSGRAPHTRICKS' => '\endpsgraph',
- '\USEPACKAGE' => '\usepackage',
- '{GRAPHICX}' => '{graphicx}',
- '\GRAPHICSPATH{' => '\graphicspath{',
- '\BEGIN{' => '\begin{',
- '\END{' => '\end{',
- '\DOCUMENTCLASS' => '\documentclass',
- '\PAGESTYLE{' => '\pagestyle{',
- '\THISPAGESTYLE{' => '\thispagestyle{',
- );
-
-### Reverse tags, need back in all file to extract
-my %reverse_tag = (
- '%<*LTXIMG>' => '%<*ltximg>',
- '%</LTXIMG>' => '%</ltximg>',
- '%<*NOLTXIMG>' => '%<*noltximg>',
- '%</NOLTXIMG>' => '%</noltximg>',
- '%<*REMOVE>' => '%<*remove>',
- '%</REMOVE>' => '%</remove>',
- );
-
-### First we do some security checks to ensure that they are verbatim and
-### verbatim write environments are unique and disjointed
-@verb_env_tmp = array_minus(@verb_env_tmp, @verw_env_tmp); #disjointed
-my @verbatim = uniq(@verb_env_tmp);
-my %verbatim = crearhash(@verbatim);
-
-Log('The environments that are considered verbatim:');
-Logarray(\@verbatim);
-
-### Create a Regex for verbatim standart environment
-my $verbatim = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verbatim;
-$verbatim = qr/$verbatim/x;
-my $verb_std = qr {
- (
- (?:
- \\begin\{$verbatim\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim\*?\})
- (?!end\{$verbatim\*?\})|
- (?-1)
- )*
- \\end\{$verbatim\*?\}
- )
- )
- }x;
-
-### Verbatim write
-@verw_env_tmp = array_minus(@verw_env_tmp, @verb_env_tmp); #disjointed
-my @verbatim_w = uniq(@verw_env_tmp);
-my %verbatim_w = crearhash(@verbatim_w);
-
-Log('The environments that are considered verbatim write:');
-Logarray(\@verbatim_w);
-
-### Create a Regex for verbatim write environment
-my $verbatim_w = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verbatim_w;
-$verbatim_w = qr/$verbatim_w/x;
-my $verb_wrt = qr {
- (
- (?:
- \\begin\{$verbatim_w\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim_w\*?\})
- (?!end\{$verbatim_w\*?\})|
- (?-1)
- )*
- \\end\{$verbatim_w\*?\}
- )
- )
- }x;
-
-### Check skip environments
-my @skipped;
-if (@skip_env_tmp) {
- my %envcheck = map { $_ => 1 } @skip_env_tmp;
- if (exists $envcheck{PSTexample}) {
- Log('The [PSTexample] environment is not allowed for skipping');
- @skip_env_tmp = grep !/PSTexample/, @skip_env_tmp;
- }
- if (exists $envcheck{preview}) {
- Log('The [preview] environment is not allowed for skipping');
- @skip_env_tmp = grep !/preview/, @skip_env_tmp;
- }
- # Valid environments for skip
- for my $skip (qw(pspicture tikzpicture pgfpicture psgraph postscript)) {
- if (exists $envcheck{$skip}) {
- push @skipped,$skip;
- }
- }
-}
-
-### List of environments to be skiped from extraction
-@skipped = uniq(@skip_env_tmp);
-Log('The environments that will be skiped for extraction:');
-Logarray(\@skipped);
-
-### Create a Regex for skip environment
-my $skipenv = join q{|}, map { quotemeta } sort { length $a <=> length $b } @skipped;
-$skipenv = qr/$skipenv/x;
-my $skip_env = qr {
- (
- (?:
- \\begin\{$skipenv\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$skipenv\*?\})
- (?!end\{$skipenv\*?\})|
- (?-1)
- )*
- \\end\{$skipenv\*?\}
- )
- )
- }x;
-
-### Check reserved environments
-my %envcheck = map { $_ => 1 } @extr_env_tmp;
-
-if (exists $envcheck{document}) {
- Log('The [document] environment is allowed for extraction');
- @extr_env_tmp = grep !/document/, @extr_env_tmp;
-}
-if (exists $envcheck{nopreview}) {
- Log('The [nopreview] environment is allowed for extraction');
- @extr_env_tmp = grep !/nopreview/, @extr_env_tmp;
-}
-
-### An array with all environments to extract, including nopreview
-my @extract_env = qw(nopreview);
-push @extract_env,@extr_env_tmp;
-
-### Some oprations for skip environments
-@extract_env = array_minus(@extract_env, @skip_env_tmp);
-@extract_env = uniq(@extract_env);
-
-### Hash for regex
-my %extract_env = crearhash(@extract_env);
-
-Log('The environments that will be searched for extraction:');
-my @real_extract_env = grep !/nopreview/, @extract_env;
-Logarray(\@real_extract_env);
-
-### Create a regex to extract environments
-my $environ = join q{|}, map { quotemeta } sort { length $a <=> length $b } @extract_env;
-$environ = qr/$environ/x;
-my $extr_tmp = qr {
- (
- (?:
- \\begin\{$environ\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$environ\*?\})
- (?!end\{$environ\*?\})|
- (?-1)
- )*
- \\end\{$environ\*?\}
- )
- )
- }x;
-
-### Check delete environments
-if (@delt_env_tmp) {
- my %envcheck = map { $_ => 1 } @delt_env_tmp;
- if (exists $envcheck{document}) {
- Log('The [document] environment is not allowed for delete');
- @delt_env_tmp = grep !/document/, @delt_env_tmp;
- }
-}
-
-### An array of environments to be removed in <output file>
-my @delete_env = uniq(@delt_env_tmp);
-my %delete_env = crearhash(@delete_env);
-
-Log('The environments that will be removed in output file:');
-Logarray(\@delete_env);
-
-### Create a Regex for delete environment in <output file>
-my $delenv = join q{|}, map { quotemeta } sort { length $a <=> length $b } @delete_env;
-$delenv = qr/$delenv/x;
-my $delt_env = qr {
- (
- (?:
- \\begin\{$delenv\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$delenv\*?\})
- (?!end\{$delenv\*?\})|
- (?-1)
- )*
- \\end\{$delenv\*?\}
- )
- )
- }x;
-
-########################################################################
-# In this first part the script only detects verbatim environments and #
-# verbatim write don't distinguish between which ones are extracted, #
-# that's done in a second pass. #
-########################################################################
-
-Log('Making changes to verbatim and verbatim write environments before extraction');
-
-### First, revert %<*TAGS> to %<*tags> in all document
-my $ltxtags = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %reverse_tag;
-$document =~ s/^($ltxtags)/$reverse_tag{$1}/gmsx;
-
-### Create an array with the temporary extraction list, no verbatim environments
-my @extract_tmp = array_minus(@extract_env, @verb_env_tmp);
-@extract_tmp = array_minus(@extract_tmp, @verw_env_tmp);
-@extract_tmp = uniq(@extract_tmp);
-my %extract_tmp = crearhash(@extract_tmp);
-
-### Hash and Regex for changes, this "regex" is re-used in ALL script
-my %replace = (%verbatim, %extract_tmp, %changes_in, %document); # revert tags again :)
-my $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
-
-### We go line by line and make the changes in verbatim's envoronments (/p for ${^MATCH})
-while ($document =~ /$verb_wrt | $verb_std /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- if ($encontrado =~ /$verb_wrt/) {
- $encontrado =~ s/($find)/$replace{$1}/g;
- substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
- }
- if ($encontrado =~ /$verb_std/) {
- %replace = (%verbatim_w, %extract_tmp, %changes_in, %document);
- $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
- $encontrado =~ s/($find)/$replace{$1}/g;
- substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
- }
-}
-
-### Now split document
-my ($preamble,$bodydoc,$enddoc) = $document =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
-
-### Internal <dtxtag> for mark verbatim and verbatim write environments
-my $dtxverb = "verbatim$tmp";
-
-### Match <dtxtags>, if they're matched, we turn them :)
-my @tag_extract = $bodydoc =~ m/(?:^\%<\*ltximg>.+?\%<\/ltximg>)/gmsx;
-my @tag_noextract = $bodydoc =~ m/(?:^\%<\*noltximg>.+?\%<\/noltximg>)/gmsx;
-
-if (@tag_extract) {
- Log('Pass extract tags %<*ltximg> ... %</ltximg> to \begin{preview} ... \end{preview}');
- $bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ^\%<\*$extrtag>(.+?)\%<\/$extrtag>/\\begin\{preview\}$1\\end\{preview\}/gmsx;
-}
-if (@tag_noextract) {
- Log('Pass no extract tags %<*noltximg> ... %</noltximg> to \begin{nopreview} ... \end{nopreview}');
- $bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ^\%<\*$skiptag>(.+?)\%<\/$skiptag>/\\begin\{nopreview\}$1\\end\{nopreview\}/gmsx;
-}
-
-########################################################################
-# We now make the real changes for environment extraction. Since we #
-# don't know what kind of environments are passed, need to redefine #
-# all regex to make the changes. #
-########################################################################
-
-my @new_verb_tmp = array_minus(@verbatim, @extract_env);
-$verbatim = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verb_tmp;
-$verbatim = qr/$verbatim/x;
-$verb_std = qr {
- (
- (?:
- \\begin\{$verbatim\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim\*?\})
- (?!end\{$verbatim\*?\})|
- (?-1)
- )*
- \\end\{$verbatim\*?\}
- )
- )
- }x;
-
-my @new_verbw_tmp = array_minus(@verbatim_w, @extract_env);
-$verbatim_w = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verbw_tmp;
-$verbatim_w = qr/$verbatim_w/x;
-$verb_wrt = qr {
- (
- (?:
- \\begin\{$verbatim_w\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim_w\*?\})
- (?!end\{$verbatim_w\*?\})|
- (?-1)
- )*
- \\end\{$verbatim_w\*?\}
- )
- )
- }x;
-
-### Regex using hash
-%replace = (%extract_env);
-$find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
-
-### We go line by line and make the changes (/p for ${^MATCH})
-while ($bodydoc =~ /$verb_wrt | $verb_std /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- $encontrado =~ s/($find)/$replace{$1}/g;
- substr $bodydoc, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($bodydoc) = $pos_inicial + length $encontrado;
-}
-
-### Now put a internal dtxmark in no extraction/replace environments
-Log("Pass verbatim write environments to %<*$dtxverb> ... %</$dtxverb>");
-$bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ($verb_wrt)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-$preamble =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ($verb_wrt)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-$atbegindoc =~ s/($verb_wrt)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-
-Log("Pass verbatim environments to %<*$dtxverb> ... %</$dtxverb>");
-$bodydoc =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ($verb_std)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-$preamble =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ($verb_std)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-$atbegindoc =~ s/($verb_std)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-
-### Check plain TeX syntax
-my %plainsyntax = map { $_ => 1 } @extract_env; # anon hash
-
-if (exists $plainsyntax{pspicture}) {
- Log('Convert plain \pspicture to LaTeX syntax [skip in PSTexample]');
- $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- \\pspicture(\*)?(.+?)\\endpspicture/\\begin\{pspicture$1\}$2\\end\{pspicture$1\}/gmsx;
-}
-
-if (exists $plainsyntax{psgraph}) {
- Log('Convert plain \psgraph to LaTeX syntax [skip in PSTexample]');
- $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- \\psgraph(\*)?(.+?)\\endpsgraph/\\begin\{psgraph$1\}$2\\end\{psgraph$1\}/gmsx;
-}
-
-if (exists $plainsyntax{tikzpicture}) {
- Log('Convert plain \tikzpicture to LaTeX syntax');
- $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- \\tikzpicture(.+?)\\endtikzpicture/\\begin{tikzpicture}$1\\end{tikzpicture}/gmsx;
-}
-
-if (exists $plainsyntax{pgfpicture}) {
- Log('Convert plain \pgfpicture to LaTeX syntax');
- $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- \\pgfpicture(.+?)\\endpgfpicture/\\begin{pgfpicture}$1\\end{pgfpicture}/gmsx;
-}
-
-### Force mode for pstricks/psgraph/tikzpiture
-if ($opts_cmd{boolean}{force}) {
- if (exists $plainsyntax{pspicture} or exists $plainsyntax{psgraph}) {
- Log('Try to capture \psset{...} for pstricks environments [force mode]');
- $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- \\begin\{postscript\}.+?\\end\{postscript\}(*SKIP)(*F)|
- (?<code>
- (?:\\psset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
- \\begin\{(?<env> pspicture\*?| psgraph)\} .+? \\end\{\k<env>\}
- )
- /\\begin\{preview\}$+{code}\\end\{preview\}/gmsx;
- }
- if (exists $plainsyntax{tikzpicture}) {
- Log('Try to capture \tikzset{...} for tikzpicture environments [force mode]');
- $bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- \\begin\{postscript\}.+?\\end\{postscript\}(*SKIP)(*F)|
- (?<code>
- (?:\\tikzset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
- \\begin\{(?<env> tikzpicture)\} .+? \\end\{\k<env>\}
- )
- /\\begin\{preview\}$+{code}\\end\{preview\}/gmsx;
- }
-}
-
-Log('Pass skip environments to \begin{nopreview} ... \end{nopreview}');
-$bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- ($skip_env)/\\begin\{nopreview\}$1\\end\{nopreview\}/gmsx;
-
-### Pass all captured environments in body \begin{preview} ... \end{preview}
-Log('Pass all captured environments to \begin{preview} ... \end{preview}');
-$bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ($extr_tmp)/\\begin\{preview\}$1\\end\{preview\}/gmsx;
-
-########################################################################
-# All environments are now classified: #
-# Extraction -> \begin{preview} ... \end{preview} #
-# No Extraction -> \begin{nopreview} ... \end{nopreview} #
-# Verbatim's -> %<\*$dtxverb> ... <\/$dtxverb> #
-########################################################################
-
-### The %<*remove> ... %</remove> tags need a special treatment :)
-$bodydoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ^(\%<(?:\*|\/))(remove)(\>)/$1$2$tmp$3/gmsx;
-$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ^(\%<(?:\*|\/))(remove)(\>)/$1$2$tmp$3/gmsx;
-$atbegindoc =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{preview\}.+?\\end\{preview\}(*SKIP)(*F)|
- ^(\%<(?:\*|\/))(remove)(\>)/$1$2$tmp$3/gmsx;
-
-### Pass \begin{preview} ... \end{preview} to \START{preview} ... \STOP{preview}
-### Pass \begin{nopreview} ... \end{nopreview} to \START{nopreview} ... \STOP{nopreview}
-$bodydoc =~ s/\\begin\{((no)?preview)\}/\\START\{$1\}/gmsx;
-$bodydoc =~ s/\\end\{((no)?preview)\}/\\STOP\{$1\}/gmsx;
-
-### We restore the changes of all environments in body
-my @lineas = split /\n/, $bodydoc;
-my $NEWDEL;
-for (@lineas) {
- %replace = (%changes_out);
- $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
- if (/\\START\{((no)?preview)(?{ $NEWDEL = "\Q$^N" })\}/ .. /\\STOP\{$NEWDEL\}/) {
- s/($find)/$replace{$1}/msgx;
- }
- if (/\%<\*($dtxverb)(?{ $NEWDEL = "\Q$^N" })>/ .. /\%<\/$NEWDEL>/) {
- s/($find)/$replace{$1}/msgx;
- }
-}
-$bodydoc = join "\n", @lineas;
-
-### We restore the changes of all environments in preamble
-while ($preamble =~ /\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/pgmsx) {
- %cambios = (%changes_out);
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/msxg;
- }
- substr $preamble, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($preamble) = $pos_inicial + length $encontrado;
-}
-
-### Set wrapped environments for extraction
-my $wrapping = "$scriptname$tmp";
-Log("Set up the environment [$wrapping] to encapsulate the extraction");
-
-### Set vars for match/regex
-my $BP = "\\\\begin\{$wrapping\}";
-my $EP = "\\\\end\{$wrapping\}";
-my $BE = '\\\\begin\{PSTexample\}';
-my $EE = '\\\\end\{PSTexample\}';
-
-### Wrap environments for extraction
-Log("Pass all captured environments to \\begin{$wrapping} ... \\end{$wrapping}");
-$bodydoc =~ s/\\START\{preview\}
- (?<code>.+? )
- \\STOP\{preview\}
- /\\begin\{$wrapping\}$+{code}\\end\{$wrapping\}/gmsx;
-
-$bodydoc =~ s/\\START\{nopreview\}
- (?<code>.+? )
- \\STOP\{nopreview\}
- /\\begin\{nopreview\}\%$tmp$+{code}\\end\{nopreview\}\%$tmp/gmsx;
-
-### We put back ltximg tags :)
-$bodydoc =~ s/($ltxtags)/$reverse_tag{$1}/gmsx;
-$preamble =~ s/($ltxtags)/$reverse_tag{$1}/gmsx;
-
-### First search PSTexample environments for extract
-my @exa_extract = $bodydoc =~ m/(?:\\begin\{$wrapping\})($BE.+?$EE)(?:\\end\{$wrapping\})/gmsx;
-my $exaNo = scalar @exa_extract;
-
-### Set vars for log and print in terminal
-my $envEXA = $exaNo > 1 ? 'PSTexample environments' : 'PSTexample environment';
-my $fileEXA = $exaNo > 1 ? 'files' : 'file';
-
-### Check if PSTexample environment found
-if ($exaNo!=0) {
- $PSTexa = 1;
- Log("Found $exaNo $envEXA in $name$ext");
- my $figNo = 1;
- for my $item (@exa_extract) {
- Logline("%##### PSTexample environment captured number $figNo ######%");
- Logline($item);
- $figNo++;
- }
- # Add [graphic={[...]...}] to \begin{PSTexample}[...]
- Log('Append [graphic={[...]...}] to \begin{PSTexample}[...]');
- $figNo = 1;
- while ($bodydoc =~ /\\begin\{$wrapping\}(\s*)?\\begin\{PSTexample\}(\[.+?\])?/gsm) {
- my $swpl_grap = "graphic=\{\[scale=1\]$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa";
- my $corchetes = $1;
- my ($pos_inicial, $pos_final) = ($-[1], $+[1]);
- if (not $corchetes) { $pos_inicial = $pos_final = $+[0]; }
- if (not $corchetes or $corchetes =~ /\[\s*\]/) {
- $corchetes = "[$swpl_grap-$figNo}]";
- }
- else { $corchetes =~ s/\]/,$swpl_grap-$figNo}]/; }
- substr($bodydoc, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
- pos($bodydoc) = $pos_inicial + length $corchetes;
- }
- continue { $figNo++; }
- Log('Pass PSTexample environments to \begin{nopreview} ... \end{nopreview}');
- $bodydoc =~ s/\\begin\{$wrapping\}
- (?<code>\\begin\{PSTexample\} .+? \\end\{PSTexample\})
- \\end\{$wrapping\}
- /\\begin\{nopreview\}\%$tmp$+{code}\\end\{nopreview\}\%$tmp/gmsx;
-}
-
-### Second search standart environments for extract
-my @env_extract = $bodydoc =~ m/(?<=$BP)(.+?)(?=$EP)/gms;
-my $envNo = scalar @env_extract;
-
-### Set vars for log and print in terminal
-my $envSTD = $envNo > 1 ? 'standard environments' : 'standard environment';
-my $fileSTD = $envNo > 1 ? 'files' : 'file';
-
-### If any standard environments found
-if ($envNo!=0) {
- $STDenv = 1;
- Log("Found $envNo $envSTD in $name$ext");
- my $figNo = 1;
- for my $item (@env_extract) {
- Logline("%##### Standard environment captured number $figNo ######%");
- Logline($item);
- $figNo++;
- }
-}
-
-### Run script process only if any enviroment found in <input file>
-if ($envNo == 0 and $exaNo == 0) {
- errorUsage("$scriptname can not find any environment to extract in $name$ext");
-}
-
-### Set directory to save generated files, need full path for goog log :)
-my $imgdirpath = File::Spec->rel2abs($opts_cmd{string}{imgdir});
-
-if (-e $opts_cmd{string}{imgdir}) {
- Infoline("The generated files will be saved in $imgdirpath");
-}
-else {
- Infoline("Creating the directory $imgdirpath to save the generated files");
- Infocolor('Running', "mkdir $imgdirpath");
- Logline("[perl] mkdir($opts_cmd{string}{imgdir},0744)");
- mkdir $opts_cmd{string}{imgdir},0744 or errorUsage("Can't create the directory $opts_cmd{string}{imgdir}");
-}
-
-### Set compiler
-my $compiler = $opts_cmd{compiler}{xetex} ? 'xelatex'
- : $opts_cmd{compiler}{luatex} ? 'lualatex'
- : $opts_cmd{compiler}{latex} ? 'latex'
- : $opts_cmd{compiler}{dvips} ? 'latex'
- : $opts_cmd{compiler}{dvilua} ? 'dvilualatex'
- : $opts_cmd{compiler}{dvipdf} ? 'latex'
- : $opts_cmd{compiler}{arara} ? 'arara'
- : 'pdflatex'
- ;
-
-if (!$opts_cmd{boolean}{norun}) {
- if ($compiler eq 'arara') {
- Log("The file will be processed using $compiler, no ducks will be harmed in this process");
- }
- else { Log("The file will be processed using $compiler"); }
-}
-
-### Set option for pdfcrop (last version of pdfcrop https://github.com/ho-tex/pdfcrop)
-my $opt_crop = $opts_cmd{compiler}{xetex} ? "--xetex --margins $opts_cmd{string}{margin}"
- : $opts_cmd{compiler}{luatex} ? "--luatex --margins $opts_cmd{string}{margin}"
- : $opts_cmd{compiler}{latex} ? "--margins $opts_cmd{string}{margin}"
- : "--pdftex --margins $opts_cmd{string}{margin}"
- ;
-
-### Set options for preview packpage
-my $opt_prew = $opts_cmd{compiler}{xetex} ? 'xetex,'
- : $opts_cmd{compiler}{latex} ? q{}
- : $opts_cmd{compiler}{dvipdf} ? q{}
- : $opts_cmd{compiler}{dvips} ? q{}
- : $opts_cmd{compiler}{dvilua} ? q{}
- : 'pdftex,'
- ;
-
-########################################################################
-# One problem with using arara is that we don't know what the file is #
-# really compiled with, this affects [preview] and [pdfcrop]. #
-########################################################################
-
-### Try to capture arara:compiler in preamble of <input file>
-my @arara_engines = qw (latex pdflatex lualatex xelatex luahbtex);
-my $arara_engines = join q{|}, map { quotemeta} sort { length $a <=> length $b } @arara_engines;
-$arara_engines = qr/\b(?:$arara_engines)/x;
-my $arara_rule = qr /^(?:\%\s{1}arara[:]\s{1}) ($arara_engines) /msx;
-
-### Set options for [compiler], [preview] and [pdfcrop]
-if ($compiler eq 'arara') {
- Log('Trying to detect some suported [engine] in the rules of arara');
- my @engine = $atbegindoc =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|$arara_rule/msx;
- my %engine = map { $_ => 1 } @engine; # anon hash
- if (exists $engine{latex}) {
- Log('The [latex] engine was found in arara rule');
- # Set options for [preview] and [pdfcrop]
- $opt_crop = "--margins $opts_cmd{string}{margin}";
- $opt_prew = q{};
- }
- elsif (exists $engine{lualatex} or exists $engine{luahbtex}) {
- Log('The [lualatex] engine was found in arara rule');
- # Set options for [preview] and [pdfcrop]
- $opt_crop = "--luatex --margins $opts_cmd{string}{margin}";
- $opt_prew = 'pdftex,';
- }
- elsif (exists $engine{xelatex}) {
- Log('The [xelatex] engine was found in arara rule');
- # Set options for [preview] and [pdfcrop]
- $opt_crop = "--xetex --margins $opts_cmd{string}{margin}";
- $opt_prew = 'xetex,';
- }
- elsif (exists($engine{pdflatex})) {
- Log('The [pdflatex] engine was found in arara rule');
- # Set options for [preview] and [pdfcrop]
- $opt_crop = "--pdftex --margins $opts_cmd{string}{margin}";
- $opt_prew = 'pdftex,';
- }
- else {
- Log('No supported [engine] could be detected, default values will be used');
- # Set options for [preview] and [pdfcrop]
- $opt_crop = "--pdftex --margins $opts_cmd{string}{margin}";
- $opt_prew = 'pdftex,';
- }
-}
-
-### Message in command line for compiler
-my $msg_compiler = $opts_cmd{compiler}{xetex} ? 'xelatex'
- : $opts_cmd{compiler}{luatex} ? 'lualatex'
- : $opts_cmd{compiler}{latex} ? 'latex>dvips>ps2pdf'
- : $opts_cmd{compiler}{dvips} ? 'latex>dvips>ps2pdf'
- : $opts_cmd{compiler}{dvilua} ? 'dvilualatex>dvips>ps2pdf'
- : $opts_cmd{compiler}{dvipdf} ? 'latex>dvipdfmx'
- : $opts_cmd{compiler}{arara} ? 'arara'
- : 'pdflatex'
- ;
-
-### Set write18 for compiler
-if ($opts_cmd{boolean}{shell}) {
- $write18 = '-shell-escape';
- $write18 = '--enable-write18' if defined $ENV{'TEXSYSTEM'} and $ENV{'TEXSYSTEM'} =~ /miktex/i;
-}
-else {
- $write18 = '-no-shell-escape';
- $write18 = '--disable-write18' if defined $ENV{'TEXSYSTEM'} and $ENV{'TEXSYSTEM'} =~ /miktex/i;
-}
-
-### Set options for compiler
-my $opt_compiler = $opts_cmd{compiler}{arara} ? '--log'
- : $opts_cmd{compiler}{xetex} ? "$write18 -interaction=nonstopmode -recorder -no-pdf"
- : "$write18 -interaction=nonstopmode -recorder"
- ;
-
-if (!$opts_cmd{boolean}{norun}) {
- Log("The options '$opt_compiler' will be passed to [$compiler]");
-}
-
-### Set -q for system command line (gs, poppler-utils, dvips, dvipdfmx)
-my $quiet = $verbose ? q{}
- : '-q'
- ;
-
-### Set options for ghostscript in command line
-my %opt_gs_dev = (
- pdf => '-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite',
- gray => '-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -sProcessColorModel=DeviceGray',
- png => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -r$opts_cmd{string}{dpi}",
- bmp => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=bmp32b -r$opts_cmd{string}{dpi}",
- jpg => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=jpeg -r$opts_cmd{string}{dpi} -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4",
- tif => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=tiff32nc -r$opts_cmd{string}{dpi}",
- );
-
-### Set executable from poppler-utils
-my %cmd_poppler = (
- eps => "pdftops",
- ppm => "pdftoppm",
- svg => "pdftocairo",
- );
-
-### Set options for poppler-utils
-my %opt_poppler = (
- eps => "$quiet -eps",
- ppm => "$quiet -r $opts_cmd{string}{dpi}",
- svg => "$quiet -svg",
- );
-
-### Copy preamble and body for temp file with all environments
-my $atbeginout = $atbegindoc;
-my $preamout = $preamble;
-my $tmpbodydoc = $bodydoc;
-
-### Match \pagestyle and \thispagestyle in preamble
-my $style_page = qr /(?:\\)(?:this)?(?:pagestyle\{) (.+?) (?:\})/x;
-my @style_page = $preamout =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)| $style_page/gmsx;
-my %style_page = map { $_ => 1 } @style_page; # anon hash
-
-### Seting \pagestyle{empty} for subfiles and process
-if (@style_page) {
- if (!exists $style_page{empty}) {
- Log("Replacing page style for generated files");
- $preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (\\(this)?pagestyle)(?:\{.+?\})/$1\{empty\}/gmsx;
- }
-}
-else {
- Log('Add \pagestyle{empty} for generated files');
- $preamout = $preamout."\\pagestyle\{empty\}\n";
-}
-
-#### Remove wraped postscript environments provide by pst-pdf, auto-pst-pdf, auto-pst-pdf-lua pkgs
-Log("Convert postscript environments to \\begin\{$wrapping\} ... \\end\{$wrapping\} for standalone files");
-$tmpbodydoc =~ s/(?:$BP)(?:\\begin\{postscript\})(?:\s*\[ [^]]*? \])?
- (?<code>.+?)
- (?:\\end\{postscript\})
- (?:$EP)
- /\\begin\{$wrapping\}$+{code}\\end\{$wrapping\}/gmsx;
-
-### We created a preamble for standalone files
-my $sub_prea = "$atbeginout$preamout".'\begin{document}';
-
-### Revert changes
-$sub_prea =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
-%replace = (%changes_out);
-$find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
-$sub_prea =~ s/($find)/$replace{$1}/g;
-$sub_prea =~ s/(remove$tmp)/remove/g;
-
-### Write standalone files for environments
-if ($outsrc) {
- my $src_name = "$name-$opts_cmd{string}{prefix}-";
- my $srcNo = 1;
- if ($opts_cmd{boolean}{srcenv}) {
- Log('Extract source code of all captured environments without preamble');
- if ($STDenv) {
- if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-1$ext") {
- Log("Recreating $envNo $fileSTD [$ext] with source code for $envSTD in $imgdirpath");
- print "Recreating $envNo $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envSTD\r\n";
- }
- else {
- Log("Creating $envNo $fileSTD [$ext] with source code for $envSTD in $imgdirpath");
- print "Creating $envNo $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envSTD\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BP\s*(?<env_src>.+?)\s*$EP/gms) {
- open my $outexasrc, '>', "$opts_cmd{string}{imgdir}/$src_name$srcNo$ext";
- print {$outexasrc} $+{'env_src'};
- close $outexasrc;
- }
- continue { $srcNo++; }
- }
- if ($PSTexa) {
- if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-1$ext") {
- Log("Recreating $exaNo $fileEXA [$ext] with source code for $envEXA in $imgdirpath");
- print "Recreating $exaNo $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envEXA\r\n";
- }
- else {
- Log("Creating $exaNo $fileEXA [$ext] with source code for $envEXA in $imgdirpath");
- print "Creating $exaNo $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envEXA\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BE\[.+?(?<pst_exa_name>$opts_cmd{string}{imgdir}\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
- open my $outstdsrc, '>', "$+{'pst_exa_name'}$ext";
- print {$outstdsrc} $+{'exa_src'};
- close $outstdsrc;
- }
- }
- }
- if ($opts_cmd{boolean}{subenv}) {
- Log('Extract source code of all captured environments with preamble');
- if ($STDenv) {
- if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-1$ext") {
- Log("Recreating a $envNo standalone $fileSTD [$ext] for $envSTD in $imgdirpath");
- print "Recreating a $envNo standalone $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " for $envSTD\r\n";
- }
- else {
- Log("Creating a $envNo standalone $fileSTD [$ext] for $envSTD in $imgdirpath");
- print "Creating a $envNo standalone $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " for $envSTD\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BP(?:\s*)?(?<env_src>.+?)(?:\s*)?$EP/gms) {
- open my $outstdfile, '>', "$opts_cmd{string}{imgdir}/$src_name$srcNo$ext";
- print {$outstdfile} "$sub_prea\n$+{'env_src'}\n\\end\{document\}";
- close $outstdfile;
- }
- continue { $srcNo++; }
- }
- if ($PSTexa) {
- if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-1$ext") {
- Log("Recreating a $exaNo standalone $fileEXA [$ext] for $envEXA in $imgdirpath");
- print "Recreating a $exaNo standalone $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " for $envEXA\r\n";
- }
- else {
- Log("Creating a $exaNo standalone $fileEXA [$ext] for $envEXA in $imgdirpath");
- print "Creating a $exaNo standalone $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " for $envEXA\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BE\[.+?(?<pst_exa_name>$opts_cmd{string}{imgdir}\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
- open my $outexafile, '>', "$+{'pst_exa_name'}$ext";
- print {$outexafile} "$sub_prea\n$+{'exa_src'}\n\\end\{document\}";
- close $outexafile;
- }
- }
- }
-}
-
-### Store options for preview and pst-pdf (add at begin document)
-my $previewpkg = <<"EXTRA";
-\\PassOptionsToPackage\{inactive\}\{pst-pdf\}%
-\\AtBeginDocument\{%
-\\RequirePackage\[inactive\]\{pst-pdf\}%
-\\RequirePackage\[${opt_prew}active,tightpage\]\{preview\}%
-\\renewcommand\\PreviewBbAdjust\{-60pt -60pt 60pt 60pt\}\}%
-EXTRA
-
-### Store options for pst-pdf (add at begin document)
-my $pstpdfpkg = <<'EXTRA';
-\PassOptionsToPackage{inactive}{pst-pdf}
-\AtBeginDocument{%
-\RequirePackage[inactive]{pst-pdf}}%
-EXTRA
-
-### First match preview package in preamble (prevent option clash)
-my $REQPACK = quotemeta'\RequirePackage';
-my $USEPACK = quotemeta'\usepackage';
-my $CORCHETES = qr/\[ [^]]*? \]/x;
-
-my $PALABRAS = qr/\b (?: preview )/x;
-my $FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
-
-Log('Remove preview package (if found) in preamble [memory]');
-$preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
-$preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
-$preamout =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
-
-### Remove %<*$dtxverb> ... %</$dtxverb> in tmpbodydoc and preamout
-$tmpbodydoc =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-$preamout =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-$atbeginout =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-
-### Adjust nopreview environments
-$tmpbodydoc =~ s/\\begin\{nopreview\}\%$tmp
- (?<code> .+?)
- \\end\{nopreview\}\%$tmp
- /\\begin\{nopreview\}\n$+{code}\n\\end\{nopreview\}\n/gmsx;
-
-### Adjust $wrapping environments (need \n after close for some environments, like a Verbatim)
-$tmpbodydoc =~ s/\\begin\{$wrapping\}
- (?<code>.+?)
- \\end\{$wrapping\}
- /\\begin\{$wrapping\}\n$+{code}\n\\end\{$wrapping\}/gmsx;
-
-### Reverse changes for temporary file with all env (no in -exa file)
-$tmpbodydoc =~ s/($find)/$replace{$1}/g;
-$tmpbodydoc =~ s/(\%$tmp)//g;
-$tmpbodydoc =~ s/(remove$tmp)/remove/g;
-$preamout =~ s/($find)/$replace{$1}/g;
-$atbeginout =~ s/(remove$tmp)/remove/g;
-$atbeginout =~ s/($find)/$replace{$1}/g;
-
-### We created a preamble for individual files with all environments
-$sub_prea = $opts_cmd{boolean}{noprew} ? "$atbeginout$pstpdfpkg$preamout".'\begin{document}'
- : "$atbeginout$previewpkg$preamout"
- ;
-
-### Create a one file with "all" PSTexample environments extracted
-if ($PSTexa) {
- @exa_extract = undef;
- Log("Adding packages to $name-$opts_cmd{string}{prefix}-exa-$tmp$ext");
- Logline($pstpdfpkg);
- Log('Convert plain Tex syntax for pspicture and psgraph to LaTeX syntax in PSTexample environments');
- while ($tmpbodydoc =~ m/$BE\[.+? $opts_cmd{string}{imgdir}\/.+?-\d+\}\] .+?$EE/pgsmx ) { # search
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- $encontrado =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin\{pspicture$1\}$2\\end\{pspicture$1\}/gmsx;
- $encontrado =~ s/\\psgraph(\*)?(.+?)\\endpsgraph/\\begin\{psgraph$1\}$2\\end\{psgraph$1\}/gmsx;
- substr $tmpbodydoc, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($tmpbodydoc) = $pos_inicial + length $encontrado;
- }
- # Write files
- Infoline("Creating $name-$opts_cmd{string}{prefix}-exa-$tmp$ext with $exaNo $envEXA extracted");
- while ($tmpbodydoc =~ m/$BE\[.+? $opts_cmd{string}{imgdir}\/.+?-\d+\}\](?<exa_src>.+?)$EE/gmsx ) { # search
- push @exa_extract, $+{'exa_src'}."\\newpage\n";
- open my $allexaenv, '>', "$name-$opts_cmd{string}{prefix}-exa-$tmp$ext";
- print {$allexaenv} "$atbeginout$pstpdfpkg$preamout".'\begin{document}'."@exa_extract"."\\end\{document\}";
- close $allexaenv;
- }
- # Remove [graphic={...}] in PSTexample example environments
- $tmpbodydoc =~ s/($BE)(?:\[graphic=\{\[scale=1\]$opts_cmd{string}{imgdir}\/.+?-\d+\}\])/$1/gmsx;
- $tmpbodydoc =~ s/($BE\[.+?)(?:,graphic=\{\[scale=1\]$opts_cmd{string}{imgdir}\/.+?-\d+\})(\])/$1$2/gmsx;
- # Moving and renaming
- if ($opts_cmd{boolean}{norun}) {
- Infoline("Moving and renaming $name-$opts_cmd{string}{prefix}-exa-$tmp$ext to $name-$opts_cmd{string}{prefix}-exa-all$ext");
- if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext") {
- Infocolor('Warning', "The file [$name-$opts_cmd{string}{prefix}-exa-all$ext] already exists and will be rewritten");
- Log("Rewriting the file $name-$opts_cmd{string}{prefix}-exa-all$ext in $imgdirpath");
- }
- else {
- Log("Writing the file $name-$opts_cmd{string}{prefix}-exa-all$ext in $imgdirpath");
- }
- if ($verbose) {
- Infocolor('Running', "mv $workdir/$name-$opts_cmd{string}{prefix}-exa-$tmp$ext $imgdirpath/$name-$opts_cmd{string}{prefix}-exa-all$ext");
- }
- else {
- Infocolor('Running', "mv $name-$opts_cmd{string}{prefix}-exa-$tmp$ext ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext");
- }
- Logline("[perl] move($workdir/$name-$opts_cmd{string}{prefix}-exa-$tmp$ext, $imgdirpath/$name-$opts_cmd{string}{prefix}-exa-all$ext)");
- move("$workdir/$name-$opts_cmd{string}{prefix}-exa-$tmp$ext", "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext")
- or die "* Error!!: Couldn't be renamed $name-$opts_cmd{string}{prefix}-exa-$tmp$ext to ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-exa-all$ext";
- }
-}
-
-### Create a one file with "all" standard environments extracted
-if ($STDenv) {
- if ($opts_cmd{boolean}{noprew}) {
- Log("Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted [no preview]");
- print "Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted",
- color('magenta'), " [no preview]\r\n",color('reset');
- }
- else {
- Log("Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted [preview]");
- print "Creating $name-$opts_cmd{string}{prefix}-$tmp$ext with $envNo $envSTD extracted",
- color('magenta'), " [preview]\r\n",color('reset');
- }
- open my $allstdenv, '>', "$name-$opts_cmd{string}{prefix}-$tmp$ext";
- if ($opts_cmd{boolean}{noprew}) {
- my @env_extract;
- while ($tmpbodydoc =~ m/(?:$BP)(?<env_src>.+?)(?:$EP)/gms) {
- push @env_extract, $+{'env_src'}."\\newpage\n";
- }
- Log("Adding packages to $name-$opts_cmd{string}{prefix}-$tmp$ext");
- Logline($pstpdfpkg);
- print {$allstdenv} $sub_prea."@env_extract"."\\end{document}";
- }
- else {
- Log("Adding packages to $name-$opts_cmd{string}{prefix}-$tmp$ext");
- Logline($previewpkg);
- Log("Convert $wrapping to preview environments in $name-$opts_cmd{string}{prefix}-$tmp$ext");
- # Convert $wrapping to preview environments
- $tmpbodydoc =~ s/\\begin\{$wrapping\}(?<code>.+?)\\end\{$wrapping\}
- /\\begin\{preview\}$+{code}\\end\{preview\}\n/gmsx;
- print {$allstdenv} $sub_prea.$tmpbodydoc."\n\\end{document}";
- }
- close $allstdenv;
- if ($opts_cmd{boolean}{norun}) {
- # Moving and renaming
- Infoline("Moving and renaming $name-$opts_cmd{string}{prefix}-$tmp$ext to $name-$opts_cmd{string}{prefix}-all$ext");
- if (-e "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext") {
- Infocolor('Warning', "The file [$name-$opts_cmd{string}{prefix}-all$ext] already exists and will be rewritten");
- Log("Rewriting the file $name-$opts_cmd{string}{prefix}-all$ext in $imgdirpath");
- }
- else {
- Log("Writing the file $name-$opts_cmd{string}{prefix}-all$ext in $imgdirpath");
- }
- if ($verbose) {
- Infocolor('Running', "mv $workdir/$name-$opts_cmd{string}{prefix}-$tmp$ext $imgdirpath/$name-$opts_cmd{string}{prefix}-all$ext");
- }
- else {
- Infocolor('Running', "mv $name-$opts_cmd{string}{prefix}-$tmp$ext ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext");
- }
- Logline("[perl] move($workdir/$name-$opts_cmd{string}{prefix}-$tmp$ext, $imgdirpath/$name-$opts_cmd{string}{prefix}-all$ext)");
- move("$workdir/$name-$opts_cmd{string}{prefix}-$tmp$ext", "$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext")
- or die "* Error!!: Couldn't be renamed $name-$opts_cmd{string}{prefix}-$tmp$ext to ./$opts_cmd{string}{imgdir}/$name-$opts_cmd{string}{prefix}-all$ext";
- }
-}
-
-### Compiler and generate PDF files -dALLOWPSTRANSPARENCY
-if (!$opts_cmd{boolean}{norun}) {
-Log('Generate a PDF file with all captured environments');
-my @compiler = (1..$opts_cmd{string}{runs});
-opendir (my $DIR, $workdir);
- while (readdir $DIR) {
- if (/(?<name>$name-$opts_cmd{string}{prefix}(-exa)?)(?<type>-$tmp$ext)/) {
- Log("Compiling the file $+{name}$+{type} using [$msg_compiler]");
- print "Compiling the file $+{name}$+{type} using ", color('magenta'), "[$msg_compiler]\r\n",color('reset');
- for (@compiler){
- RUNOSCMD("$compiler $opt_compiler","$+{name}$+{type}",'show');
- }
- # Using xdvipdfmx
- if ($compiler eq 'xelatex') {
- RUNOSCMD("xdvipdfmx $quiet -E", "-o $+{name}-$tmp.pdf $+{name}-$tmp.xdv",'show');
- }
- # Compiling file using latex>dvips>ps2pdf
- if ($compiler eq 'dvips' or $compiler eq 'latex' or $compiler eq 'dvilualatex') {
- RUNOSCMD("dvips $quiet -Ppdf", "-o $+{name}-$tmp.ps $+{name}-$tmp.dvi",'show');
- RUNOSCMD("ps2pdf -sPDFSETTINGS=prepress -sAutoRotatePages=None -dALLOWPSTRANSPARENCY", "$+{name}-$tmp.ps $+{name}-$tmp.pdf",'show');
- }
- # Compiling file using latex>dvipdfmx
- if ($compiler eq 'dvipdf') {
- RUNOSCMD("dvipdfmx $quiet", "$+{name}-$tmp.dvi",'show');
- }
- # Moving and renaming temp files with source code
- Infoline("Moving and renaming $+{name}$+{type} to $+{name}-all$ext");
- if (-e "$opts_cmd{string}{imgdir}/$+{name}-all$ext") {
- Infocolor('Warning', "The file [$+{name}-all$ext] already exists and will be rewritten");
- Log("Rewriting the file $+{name}-all$ext with all source for environments in $imgdirpath");
- }
- else {
- Log("Writing the file $+{name}-all$ext with all source for environments in $imgdirpath");
- }
- if ($verbose){
- Infocolor('Running', "mv $workdir/$+{name}$+{type} $imgdirpath/$+{name}-all$ext");
- }
- else {
- Infocolor('Running', "mv $+{name}$+{type} ./$opts_cmd{string}{imgdir}/$+{name}-all$ext");
- }
- Logline("[perl] move($workdir/$+{name}$+{type}, $imgdirpath/$+{name}-all$ext)");
- move("$workdir/$+{name}$+{type}", "$opts_cmd{string}{imgdir}/$+{name}-all$ext")
- or die "* Error!!: Couldn't be renamed $+{name}$+{type} to $opts_cmd{string}{imgdir}/$+{name}-all$ext";
- # pdfcrop
- if (!$opts_cmd{boolean}{nocrop}) {
- Infoline("Cropping the file $+{name}-$tmp.pdf");
- RUNOSCMD("pdfcrop $opt_crop", "$+{name}-$tmp.pdf $+{name}-$tmp.pdf",'show');
- }
- # gray
- if ($opts_cmd{boolean}{gray}) {
- Infoline("Creating the file $+{name}-all.pdf [gray] in $tempDir");
- RUNOSCMD("$gscmd $quiet $opt_gs_dev{gray} ","-o $tempDir/$+{name}-all.pdf $workdir/$+{name}-$tmp.pdf",'show');
- }
- else {
- Infoline("Creating the file $+{name}-all.pdf in $tempDir");
- if ($verbose){
- Infocolor('Running', "mv $workdir/$+{name}-$tmp.pdf $tempDir/$+{name}-all.pdf");
- }
- else { Infocolor('Running', "mv $+{name}-$tmp.pdf $tempDir/$+{name}-all.pdf"); }
- # Renaming pdf file
- Logline("[perl] move($workdir/$+{name}-$tmp.pdf, $tempDir/$+{name}-all.pdf)");
- move("$workdir/$+{name}-$tmp.pdf", "$tempDir/$+{name}-all.pdf")
- or die "* Error!!: Couldn't be renamed $+{name}-$tmp.pdf to $tempDir/$+{name}-all.pdf";
- }
- }
- }
-closedir $DIR;
-}
-
-### Create image formats in separate files
-if (!$opts_cmd{boolean}{norun}) {
- Log("Creating the image formats: $format, working on $tempDir");
- opendir(my $DIR, $tempDir);
- while (readdir $DIR) {
- # PDF/PNG/JPG/BMP/TIFF format suported by ghostscript
- if (/(?<name>$name-$opts_cmd{string}{prefix}(-exa)?)(?<type>-all\.pdf)/) {
- for my $var (qw(pdf png jpg bmp tif)) {
- if (defined $opts_cmd{image}{$var}) {
- Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $gscmd");
- print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
- RUNOSCMD("$gscmd $quiet $opt_gs_dev{$var} ", "-o $workdir/$opts_cmd{string}{imgdir}/$+{name}-%1d.$var $tempDir/$+{name}$+{type}",'show');
- }
- }
- }
- # EPS/PPM/SVG format suported by poppler-utils
- if (/(?<name>$name-$opts_cmd{string}{prefix}-exa)(?<type>-all\.pdf)/) { # pst-exa package
- for my $var (qw(eps ppm svg)) {
- if (defined $opts_cmd{image}{$var}) {
- Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $cmd_poppler{$var}");
- print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
- if (!$verbose){
- Infocolor('Running', "$cmd_poppler{$var} $opt_poppler{$var}");
- }
- for (my $epsNo = 1; $epsNo <= $exaNo; $epsNo++) {
- RUNOSCMD("$cmd_poppler{$var} $opt_poppler{$var}", "-f $epsNo -l $epsNo $tempDir/$+{name}$+{type} $workdir/$opts_cmd{string}{imgdir}/$+{name}-$epsNo.$var",'only');
- }
- }
- }
- }
- if (/(?<name>$name-$opts_cmd{string}{prefix})(?<type>-all\.pdf)/) {
- for my $var (qw(eps ppm svg)) {
- if (defined $opts_cmd{image}{$var}) {
- Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $cmd_poppler{$var}");
- print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
- if (!$verbose){
- Infocolor('Running', "$cmd_poppler{$var} $opt_poppler{$var}");
- }
- for (my $epsNo = 1; $epsNo <= $envNo; $epsNo++) {
- RUNOSCMD("$cmd_poppler{$var} $opt_poppler{$var}", "-f $epsNo -l $epsNo $tempDir/$+{name}$+{type} $workdir/$opts_cmd{string}{imgdir}/$+{name}-$epsNo.$var",'only');
- }
- }
- }
- }
- } # close while
- closedir $DIR;
- # Renaming PPM image files
- if (defined $opts_cmd{image}{ppm}) {
- Log("Renaming [ppm] images in $imgdirpath");
- if ($verbose){
- print 'Renaming', color('blue'), " [ppm] ", color('reset'),"images in $imgdirpath\r\n";
- }
- opendir(my $DIR, $opts_cmd{string}{imgdir});
- while (readdir $DIR) {
- if (/(?<name>$name-$opts_cmd{string}{prefix}(-exa)?-\d+\.ppm)(?<sep>-\d+)(?<ppm>\.ppm)/) {
- if ($verbose){
- Infocolor('Running', "mv $+{name}$+{sep}$+{ppm} $+{name}");
- }
- Logline("[perl] move($imgdirpath/$+{name}$+{sep}$+{ppm}, $imgdirpath/$+{name})");
- move("$opts_cmd{string}{imgdir}/$+{name}$+{sep}$+{ppm}", "$opts_cmd{string}{imgdir}/$+{name}")
- or die "* Error!!: Couldn't be renamed $+{name}$+{sep}$+{ppm} to $+{name}";
- }
- }
- closedir $DIR;
- }
-} # close run
-
-### Constant
-my $findgraphicx = 'true';
-
-### Add $atbegindoc to $preamble
-$preamble = "$atbegindoc$preamble";
-
-### Replacing the extracted environments with \\includegraphics
-if ($outfile) {
- my @tag_remove_preamble = $preamble =~ m/(?:^\%<\*remove$tmp>.+?\%<\/remove$tmp>)/gmsx;
- if (@tag_remove_preamble) {
- Log("Removing the content between <*remove> ... </remove> tags in preamble for $opts_cmd{string}{output}$outext");
- $preamble =~ s/^\%<\*remove$tmp>\s*(.+?)\s*\%<\/remove$tmp>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
- }
- Log("Convert standard extracted environments to \\includegraphics for $opts_cmd{string}{output}$outext");
- my $grap = "\\includegraphics[scale=1]{$name-$opts_cmd{string}{prefix}-";
- my $close = '}';
- my $imgNo = 1;
- $bodydoc =~ s/$BP.+?$EP/$grap@{[$imgNo++]}$close/msg;
-}
-
-### pst-exa package
-my $pstexa = qr/(?:\\ usepackage) \[\s*(.+?)\s*\] (?:\{\s*(pst-exa)\s*\} ) /x;
-my @pst_exa;
-my %pst_exa;
-
-### Search pst-exa package
-@pst_exa = $preamble =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|$pstexa/gmsx;
-%pst_exa = map { $_ => 1 } @pst_exa;
-
-### If found comment and adjust path for graphic files
-if (@pst_exa and $outfile) {
- Log("Comment pst-exa package in preamble for $opts_cmd{string}{output}$outext");
- $findgraphicx = 'false';
- $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (\\usepackage\[)\s*(swpl|tcb)\s*(\]\{pst-exa\})/\%$1$2,pdf$3/msxg;
- if (exists $pst_exa{tcb}) {
- Log("Suport for \\usepackage[tcb,pdf]\{pst-exa\} for $opts_cmd{string}{output}$outext");
- $bodydoc =~ s/(graphic=\{)\[(scale=\d*)\]($opts_cmd{string}{imgdir}\/$name-$opts_cmd{string}{prefix}-exa-\d*)\}/$1$2\}\{$3\}/gsmx;
- }
-}
-
-### Regex for clean file (pst) in preamble
-$PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add | -pdf )? | psfrag |psgo |vaucanson-g| auto-pst-pdf(?: -lua )? )/x;
-$FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
-
-### Clean PST content in preamble
-if ($clean{pst} and $outfile) {
- Log("Remove pstricks packages in preamble for $opts_cmd{string}{output}$outext");
- $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
- $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
- if (@pst_exa) {
- Log("Uncomment pst-exa package in preamble for $opts_cmd{string}{output}$outext");
- $preamble =~ s/(?:\%)(\\usepackage\[\s*)(swpl|tcb)(,pdf\s*\]\{pst-exa\})/$1$2$3/msxg;
- }
- Log("Remove \\psset\{...\} in preamble for $opts_cmd{string}{output}$outext");
- $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
- Log("Remove \\SpecialCoor in preamble for $opts_cmd{string}{output}$outext");
- $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\SpecialCoor(?:[\t ]*(?:\r?\n|\r))+//gmsx;
- Log("Remove empty lines in preamble for $opts_cmd{string}{output}$outext");
- $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
-}
-
-### To be sure that the package graphicx and \graphicspath is in the main
-### document and not in a verbatim write environment we make the changes
-my %tmpreplace = (
- 'graphicx' => 'TMPGRAPHICXTMP',
- 'graphicspath' => 'TMPGRAPHICSPATHTMP',
-);
-my $findtmp = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %tmpreplace;
-
-### We go line by line and make the changes [need /p for ${^MATCH}]
-while ($preamble =~ /\%<\*$dtxverb>(.+?)\%<\/$dtxverb> | $tmpcomment /pgmsx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- $encontrado =~ s/($findtmp)/$tmpreplace{$1}/g;
- substr $preamble, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($preamble) = $pos_inicial + length $encontrado;
-}
-
-### Now we're trying to capture \graphicspath{...}
-my $graphicspath= qr/\\ graphicspath \{ ((?: $llaves )+) \}/ix;
-my @graphicspath;
-@graphicspath = $preamble =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|($graphicspath)/gmsx;
-
-if (@graphicspath and $outfile) {
- Log("Found \\graphicspath in preamble for $opts_cmd{string}{output}$outext");
- $findgraphicx = 'false';
- while ($preamble =~ /$graphicspath /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- if ($encontrado =~ /$graphicspath/) {
- my $argumento = $1;
- if ($argumento !~ /\{$opts_cmd{string}{imgdir}\/\}/) {
- $argumento .= "\{$opts_cmd{string}{imgdir}/\}";
- my $cambio = "\\graphicspath{$argumento}";
- substr $preamble, $pos_inicial, $pos_final-$pos_inicial, $cambio;
- pos($preamble) = $pos_inicial + length $cambio;
- }
- }
- }
-}
-
-### Possible packages that load graphicx
-my @pkgcandidates = qw (
- rotating epsfig lyluatex xunicode parsa xepersian-hm gregoriotex teixmlslides
- teixml fotex hvfloat pgfplots grfpaste gmbase hep-paper postage schulealt
- schule utfsym cachepic abc doclicense rotating epsfig semtrans mgltex
- graphviz revquantum mpostinl cmpj cmpj2 cmpj3 chemschemex register papercdcase
- flipbook wallpaper asyprocess draftwatermark rutitlepage dccpaper-base
- nbwp-manual mandi fmp toptesi isorot pinlabel cmll graphicx-psmin ptmxcomp
- countriesofeurope iodhbwm-templates fgruler combinedgraphics pax pdfpagediff
- psfragx epsdice perfectcut upmethodology-fmt ftc-notebook tabvar vtable
- teubner pas-cv gcard table-fct pdfpages keyfloat pdfscreen showexpl simplecd
- ifmslide grffile reflectgraphics markdown bclogo tikz-page pst-uml realboxes
- musikui csbulobalka lwarp mathtools sympytex mpgraphics miniplot.sty:77
- dottex pdftricks2 feupphdteses tex4ebook axodraw2 hagenberg-thesis dlfltxb
- hu-berlin-bundle draftfigure quicktype endofproofwd euflag othelloboard
- pdftricks unswcover breqn pdfswitch latex-make figlatex repltext etsvthor
- cyber xcookybooky xfrac mercatormap chs-physics-report tikzscale ditaa
- pst-poker gmp CJKvert asypictureb hletter tikz-network powerdot-fuberlin
- skeyval gnuplottex plantslabels fancytooltips ieeepes pst-vectorian
- phfnote overpic xtuformat stubs graphbox ucs pdfwin metalogo mwe
- inline-images asymptote UNAMThesis authorarchive amscdx pst-pdf adjustbox
- trimclip fixmetodonotes incgraph scanpages pst-layout alertmessage
- svg quiz2socrative realhats autopdf egplot decorule figsize tikzexternal
- pgfcore frontespizio textglos graphicx tikz tcolorbox pst-exa
- );
-
-my $pkgcandidates = join q{|}, map { quotemeta } sort { length $a <=> length $b } @pkgcandidates;
-$pkgcandidates = qr/$pkgcandidates/x;
-my @graphicxpkg;
-
-### Now we're trying to capture graphicx package
-@graphicxpkg = $preamble =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|($pkgcandidates)/gmsx;
-if (@graphicxpkg and $outfile and $findgraphicx ne 'false') {
- Log("Found graphicx package in preamble for $opts_cmd{string}{output}$outext");
- $findgraphicx = 'false';
-}
-
-### Revert changes in preamble for temp <output file>
-my %tmpoutreplace = (
- 'TMPGRAPHICXTMP' => 'graphicx',
- 'TMPGRAPHICSPATHTMP' => 'graphicspath',
-);
-
-%replace = (%changes_out,%tmpoutreplace);
-$find = join q{|}, map {quotemeta} sort { length $a <=> length $b } keys %replace;
-
-### Capture graphicx.sty in .log of LaTeX file
-if ($findgraphicx ne 'false' and $outfile) {
- Log("Couldn't capture the graphicx package for $opts_cmd{string}{output}$ext in preamble");
- my $ltxlog;
- my @graphicx;
- my $null = devnull();
- # Copy preamble and revert changes
- my $preambletmp = $preamble;
- $preambletmp =~ s/($find)/$replace{$1}/g;
- $preambletmp =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
- Log("Creating $name-$opts_cmd{string}{prefix}-$tmp$ext [only preamble]");
- if ($verbose) { say "Creating [$name-$opts_cmd{string}{prefix}-$tmp$ext] with only preamble"; }
- open my $OUTfile, '>', "$name-$opts_cmd{string}{prefix}-$tmp$ext";
- print {$OUTfile} "$preambletmp\n\\stop";
- close $OUTfile;
- # Set compiler
- if ($opts_cmd{compiler}{arara}) {
- my @engine = $atbegindoc =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|$arara_rule/msx;
- my %engine = map { $_ => 1 } @engine;
- if (%engine) {
- for my $var (@arara_engines) {
- if (defined $engine{$var}) {
- Log("Found engine [$var] for arara");
- $compiler = $var;
- }
- }
- }
- else {
- Log("Not detected engine for arara, use default [pdflatex]");
- $compiler = 'pdflatex';
- }
- }
- if ($opts_cmd{compiler}{latex}) { $compiler = 'pdflatex'; }
- if ($opts_cmd{compiler}{dvilua}) { $compiler = 'lualatex'; }
- # Compiling file
- RUNOSCMD("$compiler $write18 -interaction=batchmode", "$name-$opts_cmd{string}{prefix}-$tmp$ext >$null", 'only');
- # Restore arara compiler
- if ($opts_cmd{compiler}{arara}) { $compiler = 'arara'; }
- Log("Search graphicx package in $name-$opts_cmd{string}{prefix}-$tmp.log");
- open my $LaTeXlog, '<', "$name-$opts_cmd{string}{prefix}-$tmp.log";
- {
- local $/;
- $ltxlog = <$LaTeXlog>;
- }
- close $LaTeXlog;
- # Try to capture graphicx
- @graphicx = $ltxlog =~ m/.+? (graphicx\.sty)/xg;
- if (@graphicx) {
- Log("Found graphicx package in $name-$opts_cmd{string}{prefix}-$tmp.log");
- }
- else {
- Log("Not found graphicx package in $name-$opts_cmd{string}{prefix}-$tmp.log");
- Log("Add \\usepackage\{graphicx\} to preamble of $opts_cmd{string}{output}$outext");
- $preamble= "$preamble\\usepackage\{graphicx\}\n";
- }
-}
-
-### Add last lines
-if ($outfile) {
- if (!@graphicspath) {
- Log("Not found \\graphicspath in preamble for $opts_cmd{string}{output}$outext");
- Log("Add \\graphicspath\{\{$opts_cmd{string}{imgdir}/\}\} to preamble for $opts_cmd{string}{output}$ext");
- $preamble= "$preamble\\graphicspath\{\{$opts_cmd{string}{imgdir}/\}\}\n";
- }
- Log("Add \\usepackage\{grfext\} to preamble for $opts_cmd{string}{output}$ext");
- $preamble = "$preamble\\usepackage\{grfext\}\n";
- Log("Add \\PrependGraphicsExtensions\*\{\.pdf\} to preamble for $opts_cmd{string}{output}$ext");
- $preamble = "$preamble\\PrependGraphicsExtensions\*\{\.pdf\}";
- $preamble =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
- $preamble =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
- $preamble =~ s/^(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
-}
-
-### We remove environments from the <output file>
-if (%delete_env and $outfile) {
- Log("Remove environments in body of $opts_cmd{string}{output}$ext");
- %replace = (%delete_env);
- $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
- # We must prevent eliminating somewhere wrong
- # We re-create the regular expressions to make the changes
- my @new_verb_tmp = array_minus(@verbatim, @delete_env);
- $verbatim = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verb_tmp;
- $verbatim = qr/$verbatim/x;
- $verb_std = qr {
- (
- (?:
- \\begin\{$verbatim\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim\*?\})
- (?!end\{$verbatim\*?\})|
- (?-1)
- )*
- \\end\{$verbatim\*?\}
- )
- )
- }x;
-
- my @new_verbw_tmp = array_minus(@verbatim_w, @delete_env);
- $verbatim_w = join q{|}, map { quotemeta } sort { length $a <=> length $b } @new_verbw_tmp;
- $verbatim_w = qr/$verbatim_w/x;
- $verb_wrt = qr {
- (
- (?:
- \\begin\{$verbatim_w\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim_w\*?\})
- (?!end\{$verbatim_w\*?\})|
- (?-1)
- )*
- \\end\{$verbatim_w\*?\}
- )
- )
- }x;
- while ($bodydoc =~ /$verb_wrt | $verb_std /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- $encontrado =~ s/($find)/$replace{$1}/g;
- substr $bodydoc, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($bodydoc) = $pos_inicial + length $encontrado;
- }
- # Now remove
- $bodydoc =~ s/($delt_env)(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
-}
-
-### Create a <output file>
-if ($outfile) {
- # Options for out_file (add $end to outfile)
- my $out_file = $clean{doc} ? "$preamble\n$bodydoc\n\\end\{document\}"
- : "$preamble\n$bodydoc\n$enddoc"
- ;
- # Clean \psset{...} content in <output file>
- if ($clean{pst}) {
- $out_file =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \%<\*$dtxverb> .+? \%<\/$dtxverb>(*SKIP)(*F)|
- \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
- }
- # Clean \tikzset{...} content in <output file>
- if ($clean{tkz}) {
- $out_file =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \%<\*$dtxverb> .+? \%<\/$dtxverb>(*SKIP)(*F)|
- \\tikzset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
- }
- # Revert all changes in outfile
- $out_file =~ s/\\begin\{nopreview\}\%$tmp\s*(.+?)\s*\\end\{nopreview\}\%$tmp/$1/gmsx;
- my @tag_remove_outfile = $out_file =~ m/(?:^\%<\*remove$tmp>.+?\%<\/remove$tmp>)/gmsx;
- if (@tag_remove_outfile) {
- Log("Removing the content between <*remove> ... </remove> tags in all $opts_cmd{string}{output}$outext");
- $out_file =~ s/^\%<\*remove$tmp>\s*(.+?)\s*\%<\/remove$tmp>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
- }
- # Remove internal mark for verbatim and verbatim write environments
- $out_file =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
- %replace = (%changes_out);
- $find = join q{|}, map {quotemeta} sort { length $a <=> length $b } keys %replace;
- $out_file =~ s/($find)/$replace{$1}/g;
- if (-e "$opts_cmd{string}{output}$outext") {
- Log("Rewriting the file $opts_cmd{string}{output}$outext in $workdir");
- Infocolor('Warning', "The file [$opts_cmd{string}{output}$outext] already exists and will be rewritten");
- }
- else{
- Infoline("Creating the file $opts_cmd{string}{output}$outext");
- Log("Write the file $opts_cmd{string}{output}$outext in $workdir");
- }
- # Write <output file>
- open my $OUTfile, '>', "$opts_cmd{string}{output}$outext";
- print {$OUTfile} $out_file;
- close $OUTfile;
-}
-
-### Set compiler for process <output file>
-$compiler = $opts_cmd{compiler}{xetex} ? 'xelatex'
- : $opts_cmd{compiler}{luatex} ? 'lualatex'
- : $opts_cmd{compiler}{dvips} ? 'latex'
- : $opts_cmd{compiler}{dvilua} ? 'lualatex'
- : $opts_cmd{compiler}{dvipdf} ? 'latex'
- : $opts_cmd{compiler}{arara} ? 'arara'
- : $opts_cmd{compiler}{latexmk} ? 'latexmk'
- : 'pdflatex'
- ;
-
-### Set options for latexmk
-my $ltxmkopt = $opts_cmd{compiler}{xetex} ? "-pdfxe -silent -xelatex=\"xelatex $write18 -recorder %O %S\""
- : $opts_cmd{compiler}{luatex} ? "-pdflua -silent -lualatex=\"lualatex $write18 -recorder %O %S\""
- : $opts_cmd{compiler}{dvilua} ? "-pdflua -silent -lualatex=\"lualatex $write18 -recorder %O %S\""
- : $opts_cmd{compiler}{dvips} ? "-pdfps -silent -latex=\"latex $write18 -recorder %O %S\""
- : $opts_cmd{compiler}{dvipdf} ? "-pdfdvi -silent -latex=\"latex $write18 -recorder %O %S\""
- : "-pdf -silent -pdflatex=\"pdflatex $write18 -recorder %O %S\""
- ;
-
-### Set options for compiler <output file>
-$opt_compiler = $opts_cmd{compiler}{arara} ? '--log'
- : $opts_cmd{compiler}{latexmk} ? "$ltxmkopt"
- : "$write18 -interaction=nonstopmode -recorder"
- ;
-
-### Message in command line for compiler
-$msg_compiler = $opts_cmd{compiler}{xetex} ? 'xelatex'
- : $opts_cmd{compiler}{luatex} ? 'lualatex'
- : $opts_cmd{compiler}{latex} ? 'pdflatex'
- : $opts_cmd{compiler}{dvips} ? 'latex>dvips>ps2pdf'
- : $opts_cmd{compiler}{dvilua} ? 'lualatex'
- : $opts_cmd{compiler}{dvipdf} ? 'latex>dvipdfmx'
- : $opts_cmd{compiler}{arara} ? 'arara'
- : 'latexmk'
- ;
-
-### Now set message for latexmk
-if ($opts_cmd{compiler}{latexmk}) {
- $msg_compiler = 'latexmk';
-}
-
-### Compiling <output file>
-if (!$opts_cmd{boolean}{norun} and $outfile) {
- Log("Compiling the file $opts_cmd{string}{output}$outext using [$msg_compiler]");
- print "Compiling the file $opts_cmd{string}{output}$outext using ", color('magenta'), "[$msg_compiler]\r\n",color('reset');
- RUNOSCMD("$compiler $opt_compiler", "$opts_cmd{string}{output}$outext",'show');
- # Compiling <output file> using dvips>ps2pdf
- if ($opts_cmd{compiler}{dvips}) {
- RUNOSCMD("dvips $quiet -Ppdf", "$opts_cmd{string}{output}.dvi",'show');
- RUNOSCMD("ps2pdf -sPDFSETTINGS=prepress -sAutoRotatePages=None", "$opts_cmd{string}{output}.ps $opts_cmd{string}{output}.pdf", 'show');
- }
- # Compiling <output file> using latex>dvipdfmx
- if ($opts_cmd{compiler}{dvipdf}) {
- RUNOSCMD("dvipdfmx $quiet", "$opts_cmd{string}{output}.dvi", 'show');
- }
-}
-
-### Remove temporary files
-my @tmpfiles;
-my @protected = qw();
-my $flsline = 'OUTPUT';
-my @flsfile;
-
-### Protect generated files
-if (defined $opts_cmd{string}{output}) {
- push @protected, "$opts_cmd{string}{output}$outext", "$opts_cmd{string}{output}.pdf";
-}
-
-### Find files
-find(\&aux_files, $workdir);
-sub aux_files{
- my $findtmpfiles = $_;
- if (-f $findtmpfiles && $findtmpfiles =~ m/$name-$opts_cmd{string}{prefix}(-exa)?-$tmp.+?$/) { # search
- push @tmpfiles, $_;
- }
- return;
-}
-
-### Add if exists
-if (-e 'arara.log') {
- push @flsfile, 'arara.log';
-}
-if (-e "$name-$opts_cmd{string}{prefix}-$tmp.fls") {
- push @flsfile, "$name-$opts_cmd{string}{prefix}-$tmp.fls";
-}
-if (-e "$name-$opts_cmd{string}{prefix}-exa-$tmp.fls") {
- push @flsfile, "$name-$opts_cmd{string}{prefix}-exa-$tmp.fls";
-}
-if (-e "$opts_cmd{string}{output}.fls") {
- push @flsfile, "$opts_cmd{string}{output}.fls";
-}
-
-### Read .fls file
-for my $filename(@flsfile){
- open my $RECtmp, '<', $filename;
- push @tmpfiles, grep /^$flsline/,<$RECtmp>;
- close $RECtmp;
-}
-foreach (@tmpfiles) { s/^$flsline\s+|\s+$//g; }
-push @tmpfiles, @flsfile;
-@tmpfiles = uniq(@tmpfiles);
-@tmpfiles = array_minus(@tmpfiles, @protected);
-
-Log('The files that will be deleted are:');
-Logarray(\@tmpfiles);
-
-### Remove only if exist
-if (@tmpfiles) {
- Infoline("Remove temporary files created in $workdir");
- foreach my $tmpfiles (@tmpfiles) {
- move($tmpfiles, $tempDir);
- }
-}
-
-### Find dirs created by minted
-my @deldirs;
-my $mintdir = "\_minted\-$name-$opts_cmd{string}{prefix}-$tmp";
-my $mintdirexa = "\_minted\-$name-$opts_cmd{string}{prefix}-exa-$tmp";
-if (-e $mintdir) { push @deldirs, $mintdir; }
-if (-e $mintdirexa) { push @deldirs, $mintdirexa; }
-
-Log('The directory that will be deleted are:');
-Logarray(\@deldirs);
-
-### Remove only if exist
-if (@deldirs) {
- Infoline("Remove temporary directories created by minted in $workdir");
- foreach my $deldirs (@deldirs) {
- remove_tree($deldirs);
- }
-}
-
-### Compress ./images with all generated files
-my $archivetar;
-if ($opts_cmd{boolean}{zip} or $opts_cmd{boolean}{tar}) {
- my $stamp = strftime("%Y-%m-%d", localtime);
- $archivetar = "$opts_cmd{string}{imgdir}-$stamp";
-
- my @savetozt;
- find(\&zip_tar, $opts_cmd{string}{imgdir});
- sub zip_tar{
- my $filesto = $_;
- if (-f $filesto && $filesto =~ m/$name-$opts_cmd{string}{prefix}-.+?$/) { # search
- push @savetozt, $File::Find::name;
- }
- return;
- }
- Log("The files are compress found in $imgdirpath are:");
- Logarray(\@savetozt);
- if ($opts_cmd{boolean}{zip}) {
- if (-e "$archivetar.zip") {
- Infocolor('Warning', "The file [$archivetar.zip] already exists and will be rewritten");
- Log("Rewriting the file $archivetar.zip in $workdir");
- }
- else{
- print "Creating the file ", color('magenta'), "[$archivetar.zip]",
- color('reset'), " with generate files in ./$opts_cmd{string}{imgdir}\r\n";
- Log("Writen the file $archivetar.tar.gz in $workdir");
- }
- zip \@savetozt => "$archivetar.zip";
- }
- if ($opts_cmd{boolean}{tar}) {
- if (-e "$archivetar.tar.gz") {
- Infocolor('Warning', "The file [$archivetar.tar.gz] already exists and will be rewritten");
- Log("Rewriting the file $archivetar.tar.gz in $workdir");
- }
- else{
- print "Creating the file ", color('magenta'), "[$archivetar.tar.gz]",
- color('reset'), " with generate files in ./$opts_cmd{string}{imgdir}\r\n";
- Log("Writen the file $archivetar.tar.gz in $workdir");
- }
- my $imgdirtar = Archive::Tar->new();
- $imgdirtar->add_files(@savetozt);
- $imgdirtar->write("$archivetar.tar.gz", 9);
- }
-}
-
-### End script process
-if (!$opts_cmd{boolean}{norun} and ($opts_cmd{boolean}{srcenv} or $opts_cmd{boolean}{subenv})) {
- Log("The image files: $format and generated files are in $imgdirpath");
-}
-if (!$opts_cmd{boolean}{norun} and (!$opts_cmd{boolean}{srcenv} and !$opts_cmd{boolean}{subenv})) {
- Log("The image files: $format are in $imgdirpath");
-}
-if ($opts_cmd{boolean}{norun} and ($opts_cmd{boolean}{srcenv} or $opts_cmd{boolean}{subenv})) {
- Log("The generated files are in $imgdirpath");
-}
-if ($outfile) { Log("The file $opts_cmd{string}{output}$ext are in $workdir"); }
-
-Infocolor('Finish', "The execution of $scriptname has been successfully completed");
-
-Log("The execution of $scriptname has been successfully completed");
-
-__END__
-=encoding UTF-8
-
-=head1 NAME
-
-ltximg - LaTeX environments to image and standalone files
-
-=head1 SYNOPSIS
-
-B<ltximg> [E<lt>I<options>E<gt>] [S<-->] E<lt>I<filename>E<gt>.E<lt>I<tex>|I<ltx>E<gt>
-
-=head1 DESCRIPTION
-
-B<ltximg> automates the process of extracting and converting
-environments from LaTeX file to image formats and I<standalone> files
-using I<ghostscript> and I<poppler-utils>. Generates a one file with
-only extracted environments and other with all extracted environments
-converted to C<\includegraphics>.
-
-By default the extracted environments are:
-
-B<preview> B<pspicture> B<tikzpicture> B<pgfpicture> B<psgraph> B<postscript> B<PSTexample>
-
-=head1 OPTIONS
-
-Options that accept a value require either a blank space or C<=> between
-the option and the value. Multiple short options can be bundling and
-if the last option takes a comma separated list you need C<--> at the end.
-Relative or absolute paths for directories and files is not supported.
-
-If used without [E<lt>I<options>E<gt>] the extracted environments are converted
-to I<pdf> image format and saved in C<./images> directory using C<pdflatex>
-and I<preview> package for process.
-
-General script options:
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display command line help and exit.
-
-=item B<-v>, B<--version>
-
-Display current version and exit.
-
-=item B<-V>, B<--verbose>
-
-Verbose printing information.
-
-=item B<-l>, B<--log>
-
-Write C<.log> file with debug information.
-
-=item B<-t>, B<--tif>
-
-Create C<.tif> files using I<ghostscript>.
-
-=item B<-b>, B<--bmp>
-
-Create C<.bmp> files using I<ghostscript>.
-
-=item B<-j>, B<--jpg>
-
-Create C<.jpg> files using I<ghostscript>.
-
-=item B<-p>, B<--png>
-
-Create C<.png> files using I<ghostscript>.
-
-=item B<-e>, B<--eps>
-
-Create C<.eps> files using I<pdftops>.
-
-=item B<-s>, B<--svg>
-
-Create C<.svg> files using I<pdftocairo>.
-
-=item B<-P>, B<--ppm>
-
-Create C<.ppm> files using I<pdftoppm>.
-
-=item B<-g>, B<--gray>
-
-Gray scale for images using I<ghostscript>.
-
-=item B<-f>, B<--force>
-
-Capture C<\psset> and C<\tikzset> to extract.
-
-=item B<-n>, B<--noprew>
-
-Create images files without I<preview> package.
-
-=item B<-r> I<integer>, B<--runs>=I<integer>
-
-Set the number of times the compiler will run on the F<input> file for
-environment extraction (default: 1).
-
-=item B<-d> I<integer>, B<--dpi>=I<integer>
-
-Dots per inch resolution for images (default: 150).
-
-=item B<-m> I<integer>, B<--margins>=I<integer>
-
-Set margins in bp for I<pdfcrop> (default: 0).
-
-=item B<-o> F<filename>, B<--output>=F<filename>
-
-Create F<output> file.
-
-=item B<--imgdir>=I<dirname>
-
-Set name of directory to save images and files (default: images).
-
-=item B<--prefix>=I<string>
-
-Set I<prefix> append to each generated files (default: fig).
-
-=item B<--myverb>=I<macroname>
-
-Add C<\macroname> to verbatim inline search (default: myverb).
-
-=item B<--clean>=I<doc>|I<pst>|I<tkz>|I<all>|I<off>
-
-Removes specific block text in F<output> file (default: doc).
-
-=item B<--zip>
-
-Compress files generated in C<.zip> format.
-
-=item B<--tar>
-
-Compress files generated in C<.tar.gz> format.
-
-=item B<--srcenv>
-
-Create files with only code of environments.
-
-=item B<--subenv>
-
-Create standalone files for environments.
-
-=item B<--shell>
-
-Enable C<\write18{SHELL COMMAND}>.
-
-=item B<--latex>
-
-Using C<latexE<gt>dvipsE<gt>ps2pdf> for compiler F<input> and C<pdflatex> for compiler
-F<output>.
-
-=item B<--dvips>
-
-Using C<latexE<gt>dvipsE<gt>ps2pdf> for compiler F<input> and C<latexE<gt>dvipsE<gt>ps2pdf> for
-compiler F<output>.
-
-=item B<--dvilua>
-
-Using C<dvilualatexE<gt>dvipsE<gt>ps2pdf> for compiler F<input> and C<lualatex> for
-compiler F<output>.
-
-=item B<--dvipdf>
-
-Using C<latexE<gt>dvipdfmx> for compiler F<input> and C<latexE<gt>dvipdfmx> for compiler
-F<output>.
-
-=item B<--xetex>
-
-Using C<xelatex> for compiler F<input> and F<output>.
-
-=item B<--luatex>
-
-Using C<lualatex> for compiler F<input> and F<output>.
-
-=item B<--arara>
-
-Use C<arara> for compiler F<input> and F<output>.
-
-=item B<--latexmk>
-
-Using C<latexmk> for compiler F<output> file.
-
-=item B<--norun>
-
-Run script, but no create images files.
-
-=item B<--nopdf>
-
-Don't create a C<.pdf> image files.
-
-=item B<--nocrop>
-
-Don't run I<pdfcrop>.
-
-=item B<--extrenv>=I<env1,env2,...>
-
-Add new environments to extract.
-
-=item B<--skipenv>=I<env1,env2,...>
-
-Skip some default environments to extract.
-
-=item B<--verbenv>=I<env1,env2,...>
-
-Add new verbatim environments.
-
-=item B<--writenv>=I<env1,env2,...>
-
-Add new verbatim write environments.
-
-=item B<--deltenv>=I<env1,env2,...>
-
-Delete environments in F<output> file.
-
-=back
-
-=head1 EXAMPLE
-
-B<ltximg> --latex -e -p --subenv -o test-out.ltx test-in.ltx
-
-Create a C<./images> directory (if it doesn't exist) with all extracted
-environments converted to C<.pdf>, C<.eps>, C<.png> and I<standalone>
-files, a file F<test-in-fig-all.ltx> with all extracted environments
-and the file F<test-out.ltx> with all environments converted to
-C<\includegraphics> using C<latexE<gt>dvipsE<gt>ps2pdf> and I<preview>
-package for F<test-in.ltx> and C<pdflatex> for F<test-out.ltx>.
-
-=head1 DOCUMENTATION
-
-For full documentation use:
-
-texdoc B<ltximg>
-
-=head1 ISSUES AND REPORTS
-
-B<Repository> : L<https://github.com/pablgonz/ltximg>
-
-B<Bug tracker>: L<https://github.com/pablgonz/ltximg/issues>
-
-=head1 AUTHOR
-
-Pablo González Luengo, I<pablgonz@yahoo.com>.
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2013-2021 Pablo González, I<pablgonz@yahoo.com>.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-=head1 SEE ALSO
-
-gs(1), dvips(1), ps2pdf(1), pdfcrop(1), pdftops(1), pdftocairo(1), pdftoppm(1)
-
-=cut
-
diff --git a/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua b/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua
deleted file mode 100755
index 0c583639033..00000000000
--- a/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua
+++ /dev/null
@@ -1,1645 +0,0 @@
-#!/usr/bin/env texlua
------------------------------------------------------------------------
--- FILE: luaotfload-tool.lua
--- DESCRIPTION: database functionality
--- REQUIREMENTS: matching luaotfload
--- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
--- LICENSE: GPL v2.0
------------------------------------------------------------------------
-
-local ProvidesLuaModule = {
- name = "luaotfload-tool",
- version = "3.17", --TAGVERSION
- date = "2021-01-08", --TAGDATE
- description = "luaotfload-tool / database functionality",
- license = "GPL v2.0"
-}
-
-function luaotfload_module(module) end -- We don't log module loading here
-
-
-luaotfload = luaotfload or { }
-local version = ProvidesLuaModule.version
-luaotfload.version = ProvidesLuaModule.version
-luaotfload.self = "luaotfload-tool"
-luaotfload.fontloader = _G -- We don't isolate the fontloader here
-
---[[doc--
-
-luaotfload-tool(1)
-
-This file was originally written (as \fileent{mkluatexfontdb.lua}) by
-Elie Roux and Khaled Hosny and, as a derived work of ConTeXt, is
-provided under the terms of the GPL v2.0 license as printed in full
-text in the manual (luaotfload.pdf).
-
- \url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html}.
-
-This file is a wrapper for the luaotfload font names module
-(luaotfload-database.lua). It is part of the luaotfload bundle, please
-see the luaotfload documentation for more info. Report bugs to
-
- \url{https://github.com/latex3/luaotfload/issues}.
-
---doc]]--
-
-kpse.set_program_name "luatex"
-
-local iowrite = io.write
-local kpsefind_file = kpse.find_file
-local mathfloor = math.floor
-local next = next
-local osdate = os.date
-local ostype = os.type
-local stringexplode = string.explode
-local stringformat = string.format
-local stringlower = string.lower
-local stringrep = string.rep
-local tableconcat = table.concat
-local texiowrite_nl = texio.write_nl
-local texiowrite = texio.write
-local tonumber = tonumber
-local type = type
-
-do
- local runtime = _G.jit and { "jit" , jit.version }
- or { "stock", _VERSION }
- local minimum = {110, 0}
- local revn = tonumber (status.luatex_revision) or 0 --[[ : string ]]
-
- if status.luatex_version < minimum[1]
- 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
- \tPlease update your TeX distribution!\n\n",
- math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2]))
- error "version check failed"
- end
- luaotfload.runtime = runtime
-end
-
-local C, Ct, P, S = lpeg.C, lpeg.Ct, lpeg.P, lpeg.S
-local lpegmatch = lpeg.match
-
-string.quoted = string.quoted or function (str)
- return string.format("%q",str)
-end
-
---[[doc--
-
- XXX:
- Creating the config table will be moved to the common
- initialization when the times comes.
-
---doc]]--
-
-config = config or { }
-local config = config
-config.luaotfload = config.luaotfload or { }
-
-config.lualibs = config.lualibs or { }
-config.lualibs.verbose = false
-config.lualibs.prefer_merged = true
-config.lualibs.load_extended = true
-
-require "lualibs"
-
-local iosavedata = io.savedata
-local lfsisdir = lfs.isdir
-local lfsisfile = lfs.isfile
-local stringsplit = string.split
-local tablekeys = table.keys
-local tableserialize = table.serialize
-local tablesortedkeys = table.sortedkeys
-local tabletohash = table.tohash
-
---[[doc--
-\fileent{luatex-basics-gen.lua} calls functions from the
-\luafunction{texio.*} library; too much for our taste.
-We intercept them with dummies.
-
-Also, it sets up dummies in place of the tables created by the Context
-libraries. Since we have loaded the lualibs already this would cause
-collateral damage for some libraries whose namespace would be
-overridden. We employ our usual backup-restore strategy to work around
-this. (Postponing the loading of the lualibs code is not an option
-because the functionality is needed by basics-gen itself.)
---doc]]--
-
-local function dummy_function ( ) end
-local backup = {
- write = texio.write,
- write_nl = texio.write_nl,
- utilities = utilities,
-}
-
-texio.write, texio.write_nl = dummy_function, dummy_function
-require "fontloader-basics-gen.lua"
-texio.write, texio.write_nl = backup.write, backup.write_nl
-utilities = backup.utilities
-
-pdf = pdf or { } --- for fonts-tfm
-
-require "fontloader-data-con"
-require "fontloader-font-ini"
-require "fontloader-font-con"
-require "fontloader-fonts-enc"
-require "fontloader-font-cid"
-require "fontloader-font-map"
-require "fontloader-font-oti"
-require "fontloader-font-otr"
-require "fontloader-font-ott"
-require "fontloader-font-cff"
-require "fontloader-font-ttf"
-require "fontloader-font-dsp"
-require "fontloader-font-oup"
-require "fontloader-font-onr"
-require "fontloader-font-def"
-
-fonts = fonts or { }
-local fontsnames = fonts.names or { }
-fonts.names = fontsnames
-
-local require_init = { }
-
-local function loadmodule (name)
- local v = require ("luaotfload-" .. name)
- if v then
- local mod = { }
- local tv = type (v)
- if tv == "table" then
- mod.name = name
- mod.init = v.init
- require_init [#require_init + 1] = mod
- elseif tv == "function" then
- mod.name = name
- mod.init = v
- require_init [#require_init + 1] = mod
- end
- end
-end
-
-require "alt_getopt"
-
-loadmodule "log" --- this populates the luaotfload.log.* namespace
-loadmodule "parsers" --- fonts.conf, configuration, and request syntax
-loadmodule "configuration" --- configuration file handling
-loadmodule "database"
-loadmodule "resolvers" --- Font lookup
-
-local logreport
-
-local function init_modules ()
- --- NB we don’t command the logger at this point.
- local todo = #require_init
- local ret = true
- for i = 1, todo do
- local mod = require_init[i]
- local name = mod.name
- local init = mod.init
- if type (init) ~= "function" then
- error ("luaotfload broken; module "
- .. name .. " missing initializers!")
- end
- local v = mod.init ()
- if v == true then
- --- evaluated well
- elseif type (v) == "table" then
- luaotfload[name] = v
- else
- error ("luaotfload broken; initialization of module "
- .. name .. " returned " .. tostring (v) .. ".")
- return false
- end
- end
- logreport = luaotfload.log.report
- return ret
-end
-
-
-local help_messages = {
- ["luaotfload-tool"] = [[
-
-Usage: %s [OPTIONS...]
-
- Luaotfload font management and diagnostic utility.
- This program is part of the Luaotfload package.
-
- Valid options are:
-
--------------------------------------------------------------------------------
- VERBOSITY AND DIAGNOSTICS
-
- -q --quiet don't output anything
- -v --verbose=LEVEL be more verbose (print the searched directories)
- -v, -vv .. -vvvvvvvvv set loglevel in unary
- --log=stdout redirect log output to stdout
-
- -V --version print version and exit
- -h --help print this message
- --diagnose=CHECK run a self test procedure; one of "files",
- "environment", "index", "permissions", or
- "repository"
-
--------------------------------------------------------------------------------
- DATABASE
-
- -u --update update the database
- -n --no-reload suppress db update
- --no-strip keep redundant information in db
- -f --force force re-indexing all fonts
- -L --local scan font files in $PWD
- -c --no-compress do not gzip index file (text version only)
- -l --flush-lookups empty lookup cache of font requests
- -D --dry-run skip loading of fonts, just scan
- --formats=[+|-]EXTENSIONS set, add, or subtract file formats
- -p --prefer-texmf prefer fonts in the TEXMF over system fonts
- --max-fonts=N process at most N font files
-
- --find="font name" query the database for a font name
- -F --fuzzy look for approximate matches if --find fails
- --limit=n limit display of fuzzy matches to <n>
- (default: n = 1)
-
- -i --info display basic font metadata
- -I --inspect display detailed font metadata
-
- --list=<criterion> output list of entries by field <criterion>
- --list=<criterion>:<value> restrict to entries with <criterion>=<value>
- --fields=<f1>,<f2>,…,<fn> which fields <f> to print with --list
- -b --show-blacklist show blacklisted files
-
- --bisect=<directive> control database bisection: valid
- directives are "start", "stop", "run", "status",
- "good", "bad"
-
-The font database will be saved to
- %s
- %s
-
--------------------------------------------------------------------------------
- FONT CACHE
-
- --cache=<directive> operate on font cache, where <directive> is
- "show", "purge", or "erase"
-
-The font cache will be written to
- %s
-
-]],
- mkluatexfontdb = [[
-FATAL ERROR
-As of Luaotfload v2.5, legacy behavior is not supported anymore. Please
-update your scripts and/or habits! Kthxbye.
-]],
- short = [[
-Usage: luaotfload-tool [--help] [--version] [--verbose=<lvl>]
- [--update] [--force] [--prefer-texmf] [--local]
- [--dry-run] [--formats=<extension list>]
- [--find=<font name>] [--fuzzy] [--info] [--inspect]
- [--list=<criterion>] [--fields=<field list>]
- [--cache=<directive>] [--flush-lookups]
- [--show-blacklist] [--diagnose=<procedure>]
- [--no-compress] [--no-strip] [--local]
- [--max-fonts=<n>] [--bisect=<directive>]
-
-Enter 'luaotfload-tool --help' for a larger list of options.
-]]
-}
-
-local function help_msg (version)
- local template = help_messages[version]
- local paths = config.luaotfload.paths
- local names_plain = paths.index_path_lua
- local names_gzip = names_plain .. ".gz"
- local names_bin = paths.index_path_luc
-
- iowrite(stringformat(template,
- luaotfload.self,
- names_gzip,
- names_bin,
- caches.getwritablepath (config.luaotfload.paths.cache_dir, "")))
-end
-
-local about = [[
-%s:
- Luaotfload font management and diagnostic utility.
- License: GNU GPL v2.0.
- Report problems to <https://github.com/latex3/luaotfload/issues>
-]]
-
-local function version_msg ( )
- local out = function (...) texiowrite_nl (stringformat (...)) end
- local uname = os.uname ()
- local meta = fonts.names.getmetadata ()
-
- local runtime = luaotfload.runtime
- local notes = config.luaotfload.status
- local notes = status and status.notes or { }
-
- out (about, luaotfload.self)
- out ("%s version: %q", luaotfload.self, version)
- if notes.description then
- out ("Luaotfload: %q", notes.description)
- end
- out ("Revision: %q", notes.revision)
- out ("Lua interpreter: %s; version %q", runtime[1], runtime[2])
---[[out ("Luatex SVN revision: %d", info.luatex_svn)]] --> SVN r5624
- out ("Luatex version: %d.%d", math.floor(status.luatex_version / 100), status.luatex_version % 100)
- out ("Platform: type=%s name=%s", os.type, os.name)
-
- local uname_vars = tablesortedkeys (uname)
- for i = 1, #uname_vars do
- local var = uname_vars[i]
- out (" + %8s: %s", var, uname[var])
- end
- if meta == false then
- out("No database metadata available.")
- else
- out ("Index: version=%q created=%q modified=%q",
- meta.version or "too old",
- meta.created or "ages ago",
- meta.modified or "ages ago")
- end
- out ""
-end
-
-
---- makeshift formatting
-
-local head_adornchars = {
- [1] = "*", [2] = "=", [3] = "~", [4] = "-", [5] = "·",
-}
-
-local textwidth = 80
-local wd_leftcolumn = mathfloor(textwidth * .25)
-local key_fmt = stringformat([[%%%ds]], wd_leftcolumn)
-local val_fmt = [[%s]]
-local fieldseparator = ":"
-local info_fmt = key_fmt .. fieldseparator .. " " .. val_fmt
-
-local currentdepth = 0
-local counterstack = { } -- counters per level
-local counterformat = "%d"
-
-local function format_counter (stack)
- local acc = { }
- for lvl=1, #stack do
- acc[#acc+1] = stringformat(counterformat, stack[lvl])
- end
- return tableconcat(acc, ".")
-end
-
-local function print_heading (title, level)
- if not title then return end
- local structuredata
- if currentdepth == level then -- top is current
- counterstack[#counterstack] = counterstack[#counterstack] + 1
- elseif currentdepth < level then -- push new
- counterstack[#counterstack+1] = 1
- else -- pop
- local diff = currentdepth - level
- while diff > 0 do
- counterstack[#counterstack] = nil
- diff = diff - 1
- end
- counterstack[#counterstack] = counterstack[#counterstack] + 1
- end
- currentdepth = level
-
- texiowrite_nl ""
- if not level or level > #head_adornchars then
- level = #head_adornchars
- end
- local adornchar = head_adornchars[level]
-
- local counter = format_counter(counterstack)
-
- local s = adornchar .. adornchar .. " "
- .. counter .. " "
- .. title .. " "
- texiowrite_nl (s .. stringrep(adornchar, textwidth-utf.len(s)))
-end
-
-local baseindent = " "
-
---[[doc--
-
- show_info_items -- Together with show_info_table prints the table returned by
- readers.getinfo(), recursing into nested tables if appropriate (as necessitated
- by Luatex versions 0.78+ which include the pfminfo table in the result.
-
---doc]]--
-
-local function show_info_table (t, depth)
- depth = depth or 0
- local indent = stringrep (baseindent, depth)
- local keys = tablesortedkeys (t)
- for n = 1, #keys do
- local key = keys [n]
- local val = t [key]
- if key == "subfontindex" then
- val = val - 1 -- We use 0-based subfont indices
- end
- if type (val) == "table" then
- texiowrite_nl (indent .. stringformat (info_fmt, key, "<table>"))
- show_info_table (val, depth + 1)
- else
- texiowrite_nl (indent .. stringformat (info_fmt, key, val))
- end
- end
-end
-
-local function show_info_items (fontinfo)
- print_heading (fontinfo.fullname, 1)
- texiowrite_nl ""
- show_info_table (fontinfo)
- texiowrite_nl ""
-end
-
-local p_spacechar = S" \n\r\t\v"
-local p_wordchar = (1 - p_spacechar)
-local p_whitespace = p_spacechar^1
-local p_word = C(p_wordchar^1)
-local p_words = Ct(p_word * (p_whitespace * p_word)^0)
-
---- string -> int -> string list
-local function reflow (text, width)
- local words
- local t_text = type (text)
- if t_text == "string" then
- words = lpegmatch(p_words, text)
- if #words < 2 then
- return { text }
- end
- elseif t_text == "table" then
- words = text
- if #text < 2 then
- return text
- end
- end
-
- local space = " "
- local utflen = utf.len
- local reflowed = { }
-
- local first = words[1]
- local linelen = #first
- local line = { first }
-
- for i=2, #words do
- local word = words[i]
- local lword = utflen(word)
- linelen = linelen + lword + 1
- if linelen > width then
- reflowed[#reflowed+1] = tableconcat(line)
- linelen = #word
- line = { word }
- else
- line[#line+1] = space
- line[#line+1] = word
- end
- end
- reflowed[#reflowed+1] = tableconcat(line)
- return reflowed
-end
-
---- string -> 'a -> string list
-local function print_field (key, val)
- val = tostring(val)
- local lhs = stringformat(key_fmt, key) .. fieldseparator .. " "
- local wd_lhs = #lhs
- local lines = reflow(val, textwidth - wd_lhs)
-
- texiowrite_nl(lhs)
- texiowrite(lines[1])
- if #lines > 1 then
- local indent = stringrep(" ", wd_lhs)
- for i=2, #lines do
- texiowrite_nl(indent)
- texiowrite (lines[i])
- end
- end
-end
-
---- see luafflib.c
-local general_fields = {
- --- second: l -> literal | n -> length | d -> date
- { "fullname", "l", "font name" },
- { "version", "l", "font version" },
- { "width", "l", "width" },
- { "averagewidth", "l", "average width" },
- { "panosewidth", "l", "panose width" },
- { "weight", "l", "weight indicator" },
- { "pfmweight", "l", "numerical weight" },
- { "panoseweight", "l", "panose weight" },
- { "designsize", "l", "design size" },
- { "minsize", "l", "design size min" },
- { "maxsize", "l", "design size max" },
- { "units", "l", "units per em" },
- { "ascender", "l", "ascender height" },
- { "descender", "l", "descender height" },
- { "capheight", "l", "capital height" },
-}
-
-local function display_general (fullinfo)
- texiowrite_nl ""
- print_heading("General Information", 2)
- texiowrite_nl ""
- for i=1, #general_fields do
- local field = general_fields[i]
- local key, mode, desc = unpack(field)
- local val
- if mode == "l" then
- val = fullinfo[key]
- elseif mode == "S" then --- style names table
- local data = fullinfo[key]
- if type (data) == "table" then
- if #data > 0 then
- for n = 1, #data do
- local nth = data[n]
- if nth.lang == 1033 then
- val = nth.name
- goto found
- end
- end
- val = next (data).name
- else
- val = ""
- end
- ::found::
- else
- val = data
- end
- elseif mode == "n" then
- local v = fullinfo[key]
- if v then
- val = #fullinfo[key]
- end
- elseif mode == "d" then
- if ostype == "unix" then
- val = osdate("%F %T", fullinfo[key])
- else
- --- the MS compiler doesn’t support C99, so
- --- strftime is missing some functionality;
- --- see loslib.c for details.
- val = osdate("%Y-%m-d %H:%M:%S", fullinfo[key])
- end
- end
- if not val then
- val = "<none>"
- end
- print_field(desc, val)
- end
-end
-
-local function print_features (features)
- for tag, data in next, features do
- print_heading(tag, 4)
- for script, languages in next, data do
- local field = stringformat(key_fmt, script).. fieldseparator .. " "
- local wd_field = #field
- local lines = reflow(tablekeys(languages), textwidth - wd_field)
- local indent = stringrep(" ", wd_field)
- texiowrite_nl(field)
- texiowrite(lines[1])
- if #lines > 1 then
- for i=1, #lines do
- texiowrite_nl(indent .. lines[i])
- end
- end
- end
- end
-end
-
-local function display_feature_set (set)
- print_features(set)
-end
-
-local function display_features_type (id, feat)
- if feat and next (feat) then
- print_heading(id, 3)
- display_feature_set(feat)
- return true
- end
- return false
-end
-
-local function display_features (features)
- texiowrite_nl ""
- print_heading("Features", 2)
-
- local status = 0
- if not display_features_type ("GSUB Features", features.gsub) then
- status = status + 1
- end
- if not display_features_type ("GPOS Features", features.gpos) then
- status = status + 2
- end
- if status == 3 then
- texiowrite_nl("font defines neither gsub nor gpos features")
- elseif status == 2 then
- texiowrite_nl("font defines no gpos feature")
- elseif status == 1 then
- texiowrite_nl("font defines no gsub feature")
- end
-end
-
-local function show_full_info (path, subfont)
- local rawinfo, warn = fonts.handlers.otf.readers.loadfont (path, subfont)
- if not rawinfo then
- texiowrite_nl(stringformat([[cannot open font %s]], path))
- return
- end
- display_general(rawinfo.metadata)
- display_features(rawinfo.resources.features)
-end
-
-local function subfont_by_name (lst, askedname, n)
- for n = 1, #lst do
- local font = lst[n]
- if fonts.names.sanitize_fontname (font.fullname) == askedname then
- return font
- end
- end
- return false
-end
-
---[[doc--
-The font info knows two levels of detail:
-
- a) basic information returned by readers.getinfo(); and
- b) detailed information that is a subset of the font table
- returned by readers.loadfont().
---doc]]--
-
-local function show_font_info (basename, askedname, detail, subfont)
- local filenames = fonts.names.data().files
- local index = filenames.base[basename]
- local fullname = filenames.full[index]
- askedname = fonts.names.sanitize_fontname (askedname)
- if not fullname then -- texmf
- fullname = resolvers.findfile(basename)
- end
- if fullname then
- local shortinfo = fonts.handlers.otf.readers.getinfo (fullname, {
- subfont = subfont,
- platformnames = true,
- rawfamilynames = true,
- })
- local nfonts = #shortinfo
- if nfonts > 0 then -- true type collection
- local subfont
- if askedname then
- logreport (true, 1, "resolve",
- [[%s is part of the font collection %s]],
- askedname, basename)
- subfont = subfont_by_name(shortinfo, askedname)
- end
- if subfont then
- show_info_items(subfont)
- if detail == true then
- show_full_info(fullname, subfont)
- end
- else -- list all subfonts
- logreport (true, 1, "resolve",
- [[%s is a font collection]], basename)
- for subfont = 1, nfonts do
- logreport (true, 1, "resolve",
- [[Showing info for font no. %d]],
- subfont - 1)
- show_info_items(shortinfo[subfont])
- if detail == true then
- show_full_info(fullname, subfont)
- end
- end
- end
- else
- show_info_items(shortinfo)
- if detail == true then
- show_full_info(fullname, subfont)
- end
- end
- else
- logreport (true, 1, "resolve", "Font %s not found", filename)
- end
-end
-
---[[--
-Running the scripts triggers one or more actions that have to be
-executed in the correct order. To avoid duplication we track them in a
-set.
---]]--
-
-local action_sequence = {
- "config" , "loglevel" , "help" , "version" ,
- "dumpconf" , "diagnose" , "blacklist" , "cache" ,
- "flush" , "bisect" , "generate" , "list" ,
- "query" ,
-}
-
-local action_pending = tabletohash(action_sequence, false)
-
-action_pending.config = true --- always read the configuration
-action_pending.loglevel = true --- always set the loglevel
-action_pending.generate = false --- this is the default action
-
-local actions = { } --- (jobspec -> (bool * bool)) list
-
-function actions.loglevel (job)
- local lvl = job.log_level
- if lvl then
- luaotfload.log.set_loglevel(lvl)
- logreport ("info", 3, "util", "Setting the log level to %d.", lvl)
- logreport ("log", 2, "util", "Lua=%q", _VERSION)
- end
- return true, true
-end
-
-function actions.config (job)
- local defaults = luaotfload.default_config
- local vars = config.actions.read (job.extra_config)
- config.luaotfload = config.actions.apply (defaults, vars)
- config.luaotfload = config.actions.apply (config.luaotfload, job.config)
-
- --inspect(config.luaotfload)
- --os.exit()
- if not config.actions.reconfigure () then
- return false, false
- end
- return true, true
-end
-
-function actions.version (job)
- version_msg()
- return true, false
-end
-
-function actions.dumpconf (job)
- config.actions.dump ()
- return true, false
-end
-
-function actions.help (job)
- help_msg (job.help_version or "luaotfload-tool")
- return true, false
-end
-
-function actions.blacklist (job)
- fonts.names.read_blacklist()
- local n = 0
- for n, entry in next, tablesortedkeys(fonts.names.blacklist) do
- iowrite (stringformat("(%d %s)\n", n, entry))
- end
- return true, false
-end
-
-function actions.generate (job)
- local _ = fonts.names.update ({ }, job.force_reload, job.dry_run)
- local namedata = fonts.names.data ()
- if namedata then
- logreport ("info", 2, "db",
- "Fonts in the database: %i",
- #namedata.mappings)
- return true, true
- end
- return false, false
-end
-
--------------------------------------------------------------------------------
---- bisect mode
--------------------------------------------------------------------------------
-
-local bisect_status_path = caches.getwritablepath ("bisect", "")
-local bisect_status_file = bisect_status_path .."/" .. "luaotfload-bisect-status.lua"
-local bisect_status_fmt = [[
---[==[-------------------------------------------------------------------------
- This file is generated by Luaotfload. It can be safely deleted.
- Creation date: %s.
--------------------------------------------------------------------------]==]--
-
-%s
-
---- vim:ft=lua:ts=8:et:sw=2
-]]
-
---[[doc--
-
- write_bisect_status -- Write the history of the current bisection to disk.
-
---doc]]--
-
---- state list -> bool
-local function write_bisect_status (data)
- local payload = tableserialize (data, true)
- local status = stringformat (bisect_status_fmt,
- osdate ("%Y-%m-d %H:%M:%S", os.time ()),
- payload)
- if status and iosavedata (bisect_status_file, status) then
- logreport ("info", 4, "bisect",
- "Bisection state written to %s.",
- bisect_status_file)
- return true
- end
- logreport ("info", 0, "bisect",
- "Failed to write bisection state to %s.",
- bisect_status_file)
- return false
-end
-
---[[doc--
-
- read_bisect_status -- Read the bisect log from disk.
-
---doc]]--
-
---- unit -> state list
-local function read_bisect_status ()
- logreport ("info", 4, "bisect",
- "Testing for status file: %q.",
- bisect_status_file)
- if not lfsisfile (bisect_status_file) then
- logreport ("info", 2, "bisect",
- "No such file: %q.", bisect_status_file)
- logreport ("info", 0, "bisect",
- "Not in bisect mode.")
- return false
- end
- logreport ("info", 4, "bisect",
- "Reading status file: %q.", bisect_status_file)
- local success, status = pcall (dofile, bisect_status_file)
- if not success then
- logreport ("info", 0, "bisect",
- "Could not read status file.")
- return false
- end
- return status
-end
-
---[[doc--
-
- bisect_start -- Begin a bisect session. Determines the number of
- fonts and sets the initial high, low, and pivot values.
-
---doc]]--
-
-local function bisect_start ()
- if lfsisfile (bisect_status_file) then
- logreport ("info", 0, "bisect",
- "Bisect session in progress.",
- bisect_status_file)
- logreport ("info", 0, "bisect",
- "Use --bisect=stop to erase it before starting over.")
- return false, false
- end
- logreport ("info", 2, "bisect",
- "Starting bisection of font database %q.",
- bisect_status_file)
- local n = fonts.names.count_font_files ()
- local pivot = mathfloor (n / 2)
- local data = { { 1, n, pivot } }
- logreport ("info", 0, "bisect",
- "Initializing pivot to %d.", pivot)
- if write_bisect_status (data) then
- return true, false
- end
- return false, false
-end
-
---[[doc--
-
- bisect_stop -- Terminate bisection session by removing all state info.
-
---doc]]--
-
-local function bisect_stop ()
- logreport ("info", 3, "bisect",
- "Erasing bisection state at %s.",
- bisect_status_file)
- if lfsisfile (bisect_status_file) then
- local success, msg = os.remove (bisect_status_file)
- if not success then
- logreport ("info", 2, "bisect",
- "Failed to erase file %s (%s).",
- bisect_status_file, msg)
- end
- end
- if lfsisdir (bisect_status_path) then
- local success, msg = os.remove (bisect_status_path)
- if not success then
- logreport ("info", 2, "bisect",
- "Failed to erase directory %s (%s).",
- bisect_status_path, msg)
- end
- end
- if lfsisfile (bisect_status_file) then
- return false, false
- end
- return true, false
-end
-
---[[doc--
-
- bisect_terminate -- Wrap up a bisect session by printing the
- offending font and removing the state file.
-
---doc]]--
-
-local function bisect_terminate (nsteps, culprit)
- logreport ("info", 1, "bisect",
- "Bisection completed after %d steps.", nsteps)
- logreport ("info", 0, "bisect",
- "Bad file: %s.", fonts.names.nth_font_filename (culprit))
- logreport ("info", 0, "bisect",
- "Run with --bisect=stop to finish bisection.")
- return true, false
-end
-
---[[doc--
-
- list_remainder -- Show remaining fonts in bisect slice.
-
---doc]]--
-
-local function list_remainder (lo, hi)
- local fonts = fonts.names.font_slice (lo, hi)
- logreport ("info", 0, "bisect", "%d fonts left.", hi - lo + 1)
- for i = 1, #fonts do
- logreport ("info", 1, "bisect", " · %2d: %s", lo, fonts[i])
- lo = lo + 1
- end
-end
-
---[[doc--
-
- bisect_set -- Prepare the next bisection step by setting high, low,
- and pivot to new values.
-
- The “run” directive always picks the segment below the pivot so we
- can rely on the “outcome parameter” to be referring to that.
-
---doc]]--
-
-local function bisect_set (outcome)
- local status = read_bisect_status ()
- if not status then
- return false, false
- end
-
- local nsteps = #status
- local previous = status[nsteps]
- if previous == true then
- --- Bisection already completed; we exit early through
- --- bisect_terminate() to avoid further writes to the
- --- state files that mess up step counting.
- nsteps = nsteps - 1
- return bisect_terminate (nsteps, status[nsteps][1])
- end
-
- local lo, hi, pivot = unpack (previous)
-
- logreport ("info", 3, "bisect",
- "Previous step %d: lo=%d, hi=%d, pivot=%d.",
- nsteps, lo, hi, pivot)
-
- if outcome == "bad" then
- hi = pivot
- if lo >= hi then --- complete
- status[nsteps + 1] = { lo, lo, lo }
- status[nsteps + 2] = true
- write_bisect_status (status)
- return bisect_terminate (nsteps, lo)
- end
- pivot = mathfloor ((lo + hi) / 2)
- logreport ("info", 0, "bisect",
- "Continuing with the lower segment: lo=%d, hi=%d, pivot=%d.",
- lo, hi, pivot)
- elseif outcome == "good" then
- lo = pivot + 1
- if lo >= hi then --- complete
- status[nsteps + 1] = { lo, lo, lo }
- write_bisect_status (status)
- status[nsteps + 2] = true
- return bisect_terminate (nsteps, lo)
- end
- pivot = mathfloor ((lo + hi) / 2)
- logreport ("info", 0, "bisect",
- "Continuing with the upper segment: lo=%d, hi=%d, pivot=%d.",
- lo, hi, pivot)
- else -- can’t happen
- logreport ("info", 0, "bisect",
- "What the hell?", lo, hi, pivot)
- return false, false
- end
-
- status[nsteps + 1] = { lo, hi, pivot }
- write_bisect_status (status)
- if hi - lo <= 10 then
- list_remainder (lo, hi)
- end
- return true, false
-end
-
---[[doc--
-
- bisect_status -- Output information about the current bisect session.
-
---doc]]--
-
-local function bisect_status ()
- local status = read_bisect_status ()
- if not status then
- return false, false
- end
- local nsteps = #status
- if nsteps > 1 then
- for i = nsteps - 1, 1, -1 do
- local step = status[i]
- logreport ("info", 2, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.",
- i, unpack (step))
- end
- end
- local current = status[nsteps]
- logreport ("info", 0, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.",
- nsteps, unpack (current))
- return true, false
-end
-
---[[doc--
-
- bisect_run -- Run Luaotfload utilizing the current bisection state.
- This should be combined with the --update mode, possibly with the
- --force option.
-
- Luaotfload always tests the segment below the pivot first.
-
---doc]]--
-
-local function bisect_run ()
- local status = read_bisect_status ()
- if not status then
- return false, false
- end
- local nsteps = #status
- local currentstep = nsteps + 1
- local current = status[nsteps]
- if current == true then -- final step
- current = status[nsteps - 1]
- end
- local lo, hi, pivot = unpack (current)
- logreport ("info", 3, "bisect", "Previous step %d: lo=%d, hi=%d, pivot=%d.",
- nsteps, lo, hi, pivot)
- logreport ("info", 1, "bisect", "Step %d: Testing fonts from %d to %d.",
- currentstep, lo, pivot)
- config.luaotfload.misc.bisect = { lo, pivot }
- return true, true
-end
-
-local bisect_modes = {
- start = bisect_start,
- good = function () return bisect_set "good" end,
- bad = function () return bisect_set "bad" end,
- stop = bisect_stop,
- status = bisect_status,
- run = bisect_run,
-}
-
-function actions.bisect (job)
- local mode = job.bisect
- local runner = bisect_modes[mode]
- if not runner then
- logreport ("info", 0, "bisect", "Unknown directive %q.", mode)
- return false, false
- end
- return runner (job)
-end
-
-function actions.flush (job)
- local success = fonts.names.flush_lookup_cache()
- if success then
- local success = fonts.names.save_lookups()
- if success then
- logreport ("info", 2, "cache", "Lookup cache emptied")
- return true, true
- end
- end
- return false, false
-end
-
-local function cache_directives ()
- --- These exist only after initialization.
- return {
- ["purge"] = fonts.names.purge_cache,
- ["erase"] = fonts.names.erase_cache,
- ["show"] = fonts.names.show_cache,
- }
-end
-
-function actions.cache (job)
- local directive = cache_directives()[job.cache]
- if not directive or type(directive) ~= "function" then
- logreport ("info", 2, "cache",
- "Invalid font cache directive %s.", job.cache)
- return false, false
- end
- if directive() then
- return true, true
- end
- return false, false
-end
-
-function actions.query (job)
-
- require "luaotfload-features"
-
- local query = job.query
-
- local tmpspec = {
- name = query,
- lookup = "name",
- specification = query,
- optsize = 0,
- features = { },
- }
-
- tmpspec = fonts.names.handle_request (tmpspec)
-
- if not tmpspec.size then
- tmpspec.size = 655360 --- assume 10pt
- end
-
- local foundname, subfont, success, needle
-
- if tmpspec.lookup == "name" then
- if fonts.definers.resolvers.name (tmpspec) then
- needle = tmpspec.resolved
- end
- elseif tmpspec.lookup == "anon" then
- if fonts.definers.resolvers.anon (tmpspec) then
- needle = tmpspec.resolved or tmpspec.name
- end
- elseif tmpspec.lookup == "file" then
- needle = tmpspec.name
- end
- subfont = tmpspec.sub
-
- if needle then
- foundname, _, success = fonts.names.lookup_font_file (tmpspec.name)
- end
-
- if success then
- logreport (false, 0, "resolve", "Font %q found!", query)
- if subfont then
- logreport (false, 0, "resolve",
- "Resolved file name %q, subfont nr. %q",
- foundname, subfont - 1)
- else
- logreport (false, 0, "resolve",
- "Resolved file name %q", foundname)
- end
- if job.show_info then
- logreport (false, 3, "resolve", "Dump extra info.")
- show_font_info (foundname, query, job.full_info, subfont)
- iowrite "\n"
- end
- else
- logreport (false, 0, "resolve", "Cannot find %q in index.", query)
- if job.fuzzy == true then
- logreport (false, 0, "resolve",
- "Looking for close matches, this may take a while ...")
- local _success = fonts.names.find_closest(query, job.fuzzy_limit)
- else
- logreport (false, 0, "resolve",
- "Hint: use the --fuzzy option to display suggestions.",
- query)
- end
- end
- return true, true
-end
-
---- --list=<criterion>
---- --list=<criterion>:<value>
----
---- --list=<criterion> --fields=<f1>,<f2>,<f3>,...<fn>
-
-local function get_fields (entry, fields)
- local acc = {}
- for n, field in ipairs(fields) do
- local chain = stringsplit (field, "->")
- local tmp = entry
- for i = 1, #chain do
- tmp = tmp [chain [i]]
- if not tmp then
- --- invalid field
- break
- end
- end
- acc[n] = tmp or false
- end
- return acc
-end
-
-local separator = "\t" --- could be “,” for csv
-
-local function format_fields (fields, acc, n)
- if not acc then
- return format_fields(fields, { }, 1)
- end
-
- local field = fields[n]
- if field ~= nil then
- if field == false then
- acc[#acc+1] = "<none>"
- else
- acc[#acc+1] = tostring(field)
- end
- return format_fields(fields, acc, n+1)
- end
- return tableconcat(acc, separator)
-end
-
-local function set_primary_field (fields, addme, acc, n)
- if not acc then
- return set_primary_field(fields, addme, { addme }, 1)
- end
-
- local field = fields[n]
- if field then
- if field ~= addme then
- acc[#acc+1] = field
- end
- return set_primary_field(fields, addme, acc, n+1)
- end
- return acc
-end
-
-local function sane_pattern (p)
- local l = lpeg or require'lpeg'
- local special = l.Cg(l.P'*' * l.Cc'.*')
- local pattern = l.Cs(l.Cc'^' * (special + (1 - special)^1/fonts.names.sanitize_fontname)^0 * l.Cc'$')
- function sane_pattern (p)
- return pattern:match(p)
- end
- return sane_pattern(p)
-end
-
-function actions.list (job)
- local criterion = job.criterion
- local asked_fields = job.asked_fields
- local name_index = fonts.names.data ()
-
- if asked_fields then
- local splitcomma = luaotfload.parsers.splitcomma
- asked_fields = lpegmatch(splitcomma, asked_fields)
- end
-
- if not asked_fields then
- --- some defaults
- asked_fields = { "plainname", "version", }
- end
-
- if not name_index then
- name_index = fonts.names.load()
- end
-
- local mappings = name_index.mappings
- local nmappings = #mappings
-
- if criterion == "*" then
- logreport (false, 1, "list", "All %d entries", nmappings)
- for i=1, nmappings do
- local entry = mappings[i]
- local fields = get_fields(entry, asked_fields)
- --- we could collect these instead ...
- local formatted = format_fields(fields)
- texiowrite_nl(formatted)
- end
-
- else
- criterion = stringexplode(criterion, ":") --> { field, value }
- local asked_value = criterion[2]
- criterion = criterion[1]
- asked_fields = set_primary_field(asked_fields, criterion)
-
- logreport (false, 1, "list", "By %s", criterion)
-
- --- firstly, build a list of fonts to operate on
- local targets = { }
- if asked_value then --- only those whose value matches
- local sane_asked_pattern = sane_pattern(asked_value)
- logreport (false, 2, "list", "Restricting to value %s", asked_value)
- for i=1, nmappings do
- local entry = mappings[i]
- local entryvalue = tostring(entry[criterion])
- if entryvalue
- and (entryvalue == asked_value or entryvalue:match(sane_asked_pattern))
- then
- targets[#targets+1] = entry
- end
- end
-
- else --- whichever have the field, sorted
- local categories, by_category = { }, { }
- for i=1, nmappings do
- local entry = mappings[i]
- local tmp = entry
- local chain = stringsplit (criterion, "->")
- for i = 1, #chain - 1 do
- tmp = tmp [chain [i]]
- if not tmp then
- break
- end
- end
- local value = tmp and tmp [chain [#chain]] or "<none>"
- if value then
- --value = tostring(value)
- local entries = by_category[value]
- if not entries then
- entries = { entry }
- categories[#categories+1] = value
- else
- entries[#entries+1] = entry
- end
- by_category[value] = entries
- end
- end
- table.sort(categories)
-
- for i=1, #categories do
- local entries = by_category[categories[i]]
- for j=1, #entries do
- targets[#targets+1] = entries[j]
- end
- end
- end
- local ntargets = #targets
- logreport (false, 2, "list", "%d entries", ntargets)
-
- --- now, output the collection
- for i=1, ntargets do
- local entry = targets[i]
- local fields = get_fields(entry, asked_fields)
- local formatted = format_fields(fields)
- texiowrite_nl(formatted)
- end
- end
-
- texiowrite_nl ""
-
- return true, true
-end
-
-function actions.diagnose (job)
- --- diagnostics are loaded on demand
- local diagnose = require "luaotfload-diagnostics.lua"
- return diagnose (job)
-end
-
---- stuff to be carried out prior to exit
-
-local finalizers = { }
-
---- returns false if at least one of the actions failed, mainly
---- for closing io channels
-local function finalize ()
- local success = true
- for _, fun in next, finalizers do
- if type (fun) == "function" then
- if fun () == false then success = false end
- end
- end
- return success
-end
-
---[[--
-Command-line processing.
-luaotfload-tool relies on the script alt_getopt to process argv and
-analyzes its output.
-
-TODO with extended lualibs we have the functionality from the
-environment.* namespace that could eliminate the dependency on
-alt_getopt.
---]]--
-
-local function process_cmdline ( ) -- unit -> jobspec
- local result = { -- jobspec
- force_reload = nil,
- full_info = false,
- criterion = "",
- query = "",
- log_level = nil,
- bisect = nil,
- config = { db = { }, misc = { }, run = { live = false }, paths = { } },
- }
-
- local long_options = {
- ["bisect"] = 1,
- cache = 1,
- conf = 1,
- diagnose = 1,
- dumpconf = 0,
- ["dry-run"] = "D",
- ["flush-lookups"] = "l",
- fields = 1,
- find = 1,
- force = "f",
- formats = 1,
- fuzzy = "F",
- help = "h",
- info = "i",
- inspect = "I",
- limit = 1,
- list = 1,
- ["local"] = "L",
- log = 1,
- ["max-fonts"] = 1,
- ["no-compress"] = "c",
- ["no-reload"] = "n",
- ["no-strip"] = 0,
- ["skip-read"] = "R",
- ["prefer-texmf"] = "p",
- ["print-conf"] = 0,
- quiet = "q",
- ["show-blacklist"] = "b",
- stats = "S",
- update = "u",
- verbose = 1,
- version = "V",
- }
-
- local short_options = "bcDfFiIlLnpqRSuvVh"
-
- local options, _, optarg =
- alt_getopt.get_ordered_opts (arg, short_options, long_options)
-
- local nopts = #options
- for n=1, nopts do
- local v = options[n]
- if v == "q" then
- result.log_level = 0
- elseif v == "u" then
- action_pending["generate"] = true
- elseif v == "v" then
- local lvl = result.log_level
- if not lvl or lvl < 1 then
- lvl = 1
- else
- lvl = lvl + 1
- end
- result.log_level = lvl
- elseif v == "V" then
- action_pending["version"] = true
- elseif v == "h" then
- action_pending["help"] = true
- elseif v == "f" then
- result.update = true
- result.force_reload = 1
- elseif v == "verbose" then
- local lvl = optarg[n]
- if lvl then
- lvl = tonumber(lvl)
- result.log_level = lvl
- end
- elseif v == "log" then
- local str = optarg[n]
- if str then
- finalizers = luaotfload.log.set_logout(str, finalizers)
- end
- elseif v == "find" then
- action_pending["query"] = true
- result.query = optarg[n]
- elseif v == "F" then
- result.fuzzy = true
- elseif v == "limit" then
- local lim = optarg[n]
- if lim then
- result.fuzzy_limit = tonumber(lim)
- end
- elseif v == "i" then
- result.show_info = true
- elseif v == "I" then
- result.show_info = true
- result.full_info = true
- elseif v == "l" then
- action_pending["flush"] = true
- elseif v == "L" then
- action_pending["generate"] = true
- result.config.db.scan_local = true
- elseif v == "list" then
- action_pending["list"] = true
- result.criterion = optarg[n]
- elseif v == "fields" then
- result.asked_fields = optarg[n]
- elseif v == "cache" then
- action_pending["cache"] = true
- result.cache = optarg[n]
- elseif v == "D" then
- result.dry_run = true
- elseif v == "p" then
- fonts.names.set_location_precedence {
- "local", "texmf", "system"
- }
- elseif v == "b" then
- action_pending["blacklist"] = true
- elseif v == "diagnose" then
- action_pending["diagnose"] = true
- result.asked_diagnostics = optarg[n]
- elseif v == "formats" then
- result.config.db.formats = optarg[n]
- --names.set_font_filter (optarg[n])
- elseif v == "n" then
- result.config.db.update_live = false
- elseif v == "S" then
- result.config.misc.statistics = true
- elseif v == "R" then
- --- dev only, undocumented
- result.config.db.skip_read = true
- elseif v == "c" then
- result.config.db.compress = false
- elseif v == "no-strip" then
- result.config.db.strip = false
- elseif v == "max-fonts" then
- local n = optarg[n]
- if n then
- n = tonumber(n)
- if n and n > 0 then
- result.config.db.max_fonts = n
- end
- end
- elseif v == "bisect" then
- result.bisect = optarg[n]
- action_pending.bisect = true
- elseif v == "conf" then
- local confname = optarg[n]
- if confname then
- local extra = stringexplode (optarg[n], ",+")
- if extra then
- local extra_config = result.extra_config
- if extra_config then
- table.append (extra_config, extra)
- else
- result.extra_config = extra
- end
- end
- end
- elseif v == "dumpconf" then
- action_pending["dumpconf"] = true
- elseif v == "print-conf" then
- result.print_config = true
- end
- end
-
- if nopts == 0 then
- action_pending["help"] = true
- result.help_version = "short"
- end
- return result
-end
-
-local function main ( ) -- unit -> int
- if init_modules () == false then return -42 end
-
- local retval = 0
- local job = process_cmdline()
-
--- inspect(action_pending)
--- inspect(job)
-
- for i=1, #action_sequence do
- local actionname = action_sequence[i]
- local exit = false
- if action_pending[actionname] then
- logreport ("log", 3, "util", "Preparing for task", "%s", actionname)
-
- local action = actions[actionname]
- local success, continue = action(job)
-
- if not success then
- logreport (false, 0, "util",
- "Failed to execute task.", "%s", actionname)
- retval = -1
- exit = true
- elseif not continue then
- logreport (false, 3, "util",
- "Task completed, exiting.", "%s", actionname)
- exit = true
- else
- logreport (false, 3, "util",
- "Task completed successfully.", "%s", actionname)
- end
- end
- if exit then break end
- end
-
- if finalize () == false then
- retval = -1
- end
-
- --texiowrite_nl""
- return retval
-end
-
-return main()
-
--- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/Build/source/texk/texlive/linked_scripts/lwarp/lwarpmk.lua b/Build/source/texk/texlive/linked_scripts/lwarp/lwarpmk.lua
deleted file mode 100755
index 95c5d37a137..00000000000
--- a/Build/source/texk/texlive/linked_scripts/lwarp/lwarpmk.lua
+++ /dev/null
@@ -1,914 +0,0 @@
-#!/usr/bin/env texlua
-
--- Copyright 2016-2021 Brian Dunn
-
-printversion = "v0.895"
-requiredconfversion = "2" -- also at *lwarpmk.conf
-
-function printhelp ()
-print ("lwarpmk: Use lwarpmk -h or lwarpmk --help for help.") ;
-end
-
-function printusage ()
---
--- Print the usage of the lwarpmk command:
---
-print ( [[
-
-lwarpmk print [-p project]: Compile the print version if necessary.
-lwarpmk print1 [-p project]: Forced single compile of the print version.
-lwarpmk printindex [-p project]: Process print indexes.
-lwarpmk printglossary [-p project]: Process the glossary for the print version.
-lwarpmk html [-p project]: Compile the HTML version if necessary.
-lwarpmk html1 [-p project]: Forced single compile of the HTML version.
-lwarpmk htmlindex [-p project]: Process HTML indexes.
-lwarpmk htmlglossary [-p project]: Process the glossary for the html version.
-lwarpmk again [-p project]: Touch the source code to trigger recompiles.
-lwarpmk limages [-p project]: Process the "lateximages" created by lwarp.sty.
-lwarpmk pdftohtml [-p project]:
- For use with latexmk or a Makefile:
- Converts project_html.pdf to project_html.html and individual HTML files.
- Finishes the HTML conversion even if there was a compile error.
-lwarpmk pdftosvg <list of file names>: Converts each PDF file to SVG.
-lwarpmk epstopdf <list of file names>: Converts each EPS file to PDF.
-lwarpmk clean [-p project]: Remove *.aux, *.toc, *.lof/t,
- *.idx, *.ind, *.bbl, *.log, *_html_inc.*, .gl*,
- *_html.pdf, *_html.html, *_html.sidetoc
-lwarpmk cleanall [-p project]: Remove auxiliary files, project.pdf, *.html
-lwarpmk cleanlimages: Removes all images from the "lateximages" directory.
-lwarpmk -v: Print the version number.
-lwarpmk -h: Print this help message.
-lwarpmk --help: Print this help message.
-
-]] )
--- printconf ()
-end
-
-function splitfilename ( pathandfilename )
---
--- Separates out the path and extension from a filename.
--- Returns path, filename with extension, and extension.
--- Ex: thispath, thisfilename, thisextension = splitfilename ("path/to/filename.ext")
---
--- https://www.fhug.org.uk/wiki/wiki/doku.php?id=plugins:code_snippets:
--- split_filename_in_to_path_filename_and_extension
---
- if lfs.attributes(pathandfilename,"mode") == "directory" then
- local strPath = pathandfilename:gsub("[\\/]$","") -- $ (syntax highlighting)
- return strPath.."\\","",""
- end
- pathandfilename = pathandfilename.."."
- return pathandfilename:match("^(.-)([^\\/]-)%.([^\\/%.]-)%.?$")
-end
-
-function splitfile (destfile,sourcefile)
---
--- Split one large sourcefile into a number of files,
--- starting with destfile.
--- The file is split at each occurance of <!--|Start file|newfilename|*
---
-print ("lwarpmk: Splitting " .. sourcefile .. " into " .. destfile) ;
-local sfile = io.open(sourcefile)
-io.output(destfile)
-for line in sfile:lines() do
-i,j,copen,cstart,newfilename = string.find (line,"(.*)|(.*)|(.*)|") ;
-if ( (i~= nil) and (copen == "<!--") and (cstart == "Start file")) then
- -- split the file
- io.output(newfilename) ;
-else
- -- not a splitpoint
- io.write (line .. "\n") ;
-end
-end -- do
-io.close(sfile)
-end -- function
-
-function cvalueerror ( line, linenum , cvalue )
---
--- Incorrect value, so print an error and exit.
---
- print ("lwarpmk: ===")
- print ("lwarpmk: " .. linenum .. " : " .. line ) ;
- print (
- "lwarpmk: incorrect variable value \"" .. cvalue ..
- "\" in lwarpmk.conf.\n"
- ) ;
- print ("lwarpmk: ===")
--- printconf () ;
- os.exit(1) ;
-end
-
-function printhowtorecompile ()
--- Tells the user how to recompile to regenerate the configuration files.
- print ("lwarpmk: The configuration files lwarpmk.conf and "..sourcename..".lwarpmkconf" )
- print ("lwarpmk: must be updated. To do so, recompile" )
- print ("lwarpmk: " , sourcename..".tex" )
- if ( printlatexcmd == "" ) then
- print ("lwarpmk: using xe/lua/pdflatex," )
- else
- print ("lwarpmk: using the command:")
- print ("lwarpmk: " , printlatexcmd )
- end
- print ("lwarpmk: then use lwarpmk again.")
-end -- printhowtorecompile
-
-function ignoreconf ()
--- Global argument index
-argindex = 2
-end
-
-function loadconf ()
---
--- Load settings from the project's "lwarpmk.conf" file:
---
--- Default configuration filename:
-local conffile = "lwarpmk.conf"
-local confroot = "lwarpmk"
--- Global argument index
-argindex = 2
--- Optional configuration filename:
-if ( arg[argindex] == "-p" ) then
- argindex = argindex + 1
- confroot = arg[argindex]
- conffile = confroot..".lwarpmkconf"
- argindex = argindex + 1
-end
--- Additional defaults:
-confversion = "0"
-opsystem = "Unix"
-imagesdirectory = "lateximages"
-imagesname = "image-"
-latexmk = "false"
-printlatexcmd = ""
-HTMLlatexcmd = ""
-printindexcmd = ""
-HTMLindexcmd = ""
-latexmkindexcmd = ""
--- to be removed:
--- indexprog = "makeindex"
--- makeindexstyle = "lwarp.ist"
--- xindylanguage = "english"
--- xindycodepage = "utf8"
--- xindystyle = "lwarp.xdy"
--- pdftotextenc = "UTF-8"
-glossarycmd = "makeglossaries"
--- Verify the file exists:
-if (lfs.attributes(conffile,"mode")==nil) then
- -- file not exists
- print ("lwarpmk: ===")
- print ("lwarpmk: File \"" .. conffile .."\" does not exist.")
- print ("lwarpmk: Move to the project's source directory,")
- print ("lwarpmk: recompile using pdflatex, xelatex, or lualatex,")
- print ("lwarpmk: then try using lwarpmk again.")
- if ( arg[argindex] ~= nil ) then
- print (
- "lwarpmk: (\"" .. confroot ..
- "\" does not appear to be a project name.)"
- )
- end
- print ("lwarpmk: ===")
- printhelp () ;
- os.exit(1) -- exit the entire lwarpmk script
-else -- file exists
--- Read the file:
-print ("lwarpmk: Reading " .. conffile ..".")
-local cfile = io.open(conffile)
--- Scan each line, parsing each line as: name = [[string]]
-local linenum = 0
-for line in cfile:lines() do -- scan lines
-linenum = linenum + 1
-i,j,cvarname,cvalue = string.find (line,"([%w-_]*)%s*=%s*%[%[([^%]]*)%]%]") ;
--- Error if incorrect enclosing characters:
-if ( i == nil ) then
- print ("lwarpmk: ===")
- print ("lwarpmk: " .. linenum .. " : " .. line ) ;
- print ("lwarpmk: Incorrect entry in " .. conffile ..".\n" ) ;
- print ("lwarpmk: ===")
--- printconf () ;
- os.exit(1) ;
-end -- nil
-if ( cvarname == "confversion" ) then
- confversion = cvalue
-elseif ( cvarname == "opsystem" ) then
- -- Verify choice of opsystem:
- if ( (cvalue == "Unix") or (cvalue == "Windows") ) then
- opsystem = cvalue
- else
- cvalueerror ( line, linenum , cvalue )
- end
-elseif ( cvarname == "sourcename" ) then sourcename = cvalue
-elseif ( cvarname == "homehtmlfilename" ) then homehtmlfilename = cvalue
-elseif ( cvarname == "htmlfilename" ) then htmlfilename = cvalue
-elseif ( cvarname == "imagesdirectory" ) then imagesdirectory = cvalue
-elseif ( cvarname == "imagesname" ) then imagesname = cvalue
-elseif ( cvarname == "latexmk" ) then latexmk = cvalue
-elseif ( cvarname == "printlatexcmd" ) then printlatexcmd = cvalue
-elseif ( cvarname == "HTMLlatexcmd" ) then HTMLlatexcmd = cvalue
-elseif ( cvarname == "printindexcmd" ) then printindexcmd = cvalue
-elseif ( cvarname == "HTMLindexcmd" ) then HTMLindexcmd = cvalue
-elseif ( cvarname == "latexmkindexcmd" ) then latexmkindexcmd = cvalue
-elseif ( cvarname == "glossarycmd" ) then glossarycmd = cvalue
-elseif ( cvarname == "pdftotextenc" ) then pdftotextenc = cvalue
-else
- print ("lwarpmk: ===")
- print ("lwarpmk: " .. linenum .. " : " .. line ) ;
- print (
- "lwarpmk: Incorrect variable name \"" .. cvarname .. "\" in " ..
- conffile ..".\n"
- ) ;
- print ("lwarpmk: ===")
--- printconf () ;
-os.exit(1) ;
-end -- cvarname
-end -- do scan lines
-io.close(cfile)
-end -- file exists
--- Error if sourcename is "lwarp".
--- This could happen if a local copy of lwarp has recently been recompiled.
-if sourcename=="lwarp" then
- print ("lwarpmk: ===")
- print ("lwarpmk: lwarp.sty has recently been recompiled in this directory,")
- print ("lwarpmk: and \"lwarpmk.conf\" is no longer set for your own project.")
- print ("lwarpmk: (Perhaps you are not in your project's directory?)")
- print ("lwarpmk: In your project directory, recompile your project")
- print ("lwarpmk: using pdf/lua/xelatex <projectname>.")
- print ("lwarpmk: After a recompile, \"lwarpmk.conf\" will be set for your project,")
- print ("lwarpmk: and you may again use lwarpmk.")
- print ("lwarpmk: ===")
- os.exit(1)
-end -- sourcename of "lwarp"
--- Select some operating-system commands:
-if opsystem=="Unix" then -- For Unix / Linux / Mac OS:
- rmname = "rm"
- mvname = "mv"
- cpname = "cp"
- touchnamepre = "touch"
- touchnamepost = ""
- newtouchname = "touch"
- dirslash = "/"
- opquote= "\'"
- cmdgroupopenname = " ( "
- cmdgroupclosename = " ) "
- seqname = " && "
- bgname = " &"
-elseif opsystem=="Windows" then -- For Windows
- rmname = "DEL"
- mvname = "MOVE"
- cpname = "COPY"
- touchnamepre = "COPY /b"
- touchnamepost = "+,,"
- newtouchname = "echo empty >"
- dirslash = "\\"
- opquote= "\""
- cmdgroupopenname = ""
- cmdgroupclosename = ""
- seqname = " & "
- bgname = ""
-else
- print ("lwarpmk: ===")
- print ("lwarpmk: Select Unix or Windows for opsystem." )
- print ("lwarpmk: ===")
- os.exit(1)
-end --- for Windows
--- Warning if the operating system does not appear to be correct,
--- in case files were transferred to another system.
-if ( (package.config:sub(1,1)) ~= dirslash ) then
- print ("lwarpmk: ===")
- print ("lwarpmk: It appears that lwarpmk.conf is for a different operating system." )
- printhowtorecompile ()
- print ("lwarpmk: ===")
- os.exit(1)
-end
--- Error if the configuration file's version is not current:
-if ( confversion ~= requiredconfversion ) then
- print ("lwarpmk: ===")
- printhowtorecompile ()
- print ("lwarpmk: ===")
- os.exit(1)
-end
-end -- loadconf
-
-function executecheckerror ( executecommands , errormessage )
---
--- Execute an operating system call,
--- and maybe exit with an error message.
---
-local err
-err = os.execute ( executecommands )
-if ( err ~= 0 ) then
- print ("lwarpmk: ===")
- print ("lwarpmk: " .. errormessage )
- print ("lwarpmk: ===")
- os.exit(1)
-end
-end -- executecheckerror
-
-function refreshdate ()
-os.execute(touchnamepre .. " " .. sourcename .. ".tex " .. touchnamepost)
-end
-
-function reruntoget (filesource)
---
--- Scan the LaTeX log file for the phrase "Rerun to get",
--- indicating that the file should be compiled again.
--- Return true if found.
---
-local fsource = io.open(filesource)
-for line in fsource:lines() do
-if ( string.find(line,"Rerun to get") ~= nil ) then
- io.close(fsource)
- return true
-end -- if
-end -- do
-io.close(fsource)
-return false
-end
-
-function onetime (latexcmd, fsuffix)
---
--- Compile one time, return true if should compile again.
--- fsuffix is "" for print, "_html" for HTML output.
---
-print("lwarpmk: Compiling with: " .. latexcmd)
-executecheckerror (
- latexcmd ,
- "Compile error."
-)
-return (reruntoget(sourcename .. fsuffix .. ".log") ) ;
-end
-
-function manytimes (latexcmd, fsuffix)
---
--- Compile up to five times.
--- fsuffix is "" for print, "_html" for HTML output
---
-if onetime(latexcmd, fsuffix) == true then
-if onetime(latexcmd, fsuffix) == true then
-if onetime(latexcmd, fsuffix) == true then
-if onetime(latexcmd, fsuffix) == true then
-if onetime(latexcmd, fsuffix) == true then
-end end end end end
-end
-
-function verifyfileexists (filename)
---
--- Exit if the given file does not exist.
---
-if (lfs.attributes ( filename , "modification" ) == nil ) then
- print ("lwarpmk: ===")
- print ("lwarpmk: " .. filename .. " not found." ) ;
- print ("lwarpmk: ===")
- os.exit (1) ;
-end
-end
-
-function pdftohtml ()
---
--- Convert <project>_html.pdf into HTML files:
---
--- Convert to text:
-print ("lwarpmk: Converting " .. sourcename
- .."_html.pdf to " .. sourcename .. "_html.html")
-os.execute("pdftotext -enc " .. pdftotextenc .. " -nopgbrk -layout "
- .. sourcename .. "_html.pdf " .. sourcename .. "_html.html")
--- Split the result into individual HTML files:
-splitfile (homehtmlfilename .. ".html" , sourcename .. "_html.html")
-end
-
-function removeaux ()
---
--- Remove auxiliary files:
--- All .aux files are removed since there may be many bbl*.aux files.
--- Also removes sourcename_html.pdf, sourcename_html.html,
--- and sourcename_html.sidetoc, plus comment_*.cut.
---
-os.execute ( rmname .. " *.aux " ..
- sourcename ..".toc " .. sourcename .. "_html.toc " ..
- sourcename ..".lof " .. sourcename .. "_html.lof " ..
- sourcename ..".lot " .. sourcename .. "_html.lot " ..
- sourcename ..".bbl " .. sourcename .. "_html.bbl " ..
- " *.idx " ..
- " *.ind " ..
- sourcename ..".ps " .. sourcename .."_html.ps " ..
- sourcename ..".log " .. sourcename .. "_html.log " ..
- sourcename ..".gl* " .. sourcename .. "_html.gl* " ..
- sourcename .. "_html.pdf " ..
- sourcename .. "_html.html " ..
- sourcename .. "_html.sidetoc " ..
- " *_html_inc.* " ..
- " comment_*.cut"
- )
-end
-
-function checkhtmlpdfexists ()
---
--- Error if the HTML document does not exist.
--- The lateximages are drawn from the HTML PDF version of the document,
--- so "lwarpmk html" must be done before "lwarpmk limages".
---
-local htmlpdffile = io.open(sourcename .. "_html.pdf", "r")
-if ( htmlpdffile == nil ) then
- print ("")
- print ("lwarpmk: ===")
- print ("lwarpmk: The HTML version of the document does not exist.")
- print ("lwarpmk: Enter \"lwarpmk html\" to compile the HTML version.")
- print ("lwarpmk: ===")
- os.exit(1)
-end
-io.close (htmlpdffile)
-end -- checkhtmlpdfexists
-
-function warnlimages ()
---
--- Warning of a missing <sourcename>-images.txt file:
- print ("lwarpmk: ===")
- print ("lwarpmk: \"" .. sourcename .. "-images.txt\" does not exist.")
- print ("lwarpmk: Your project does not use SVG math or other lateximages,")
- print ("lwarpmk: or the file has been deleted somehow.")
- print ("lwarpmk: Use \"lwarpmk html1\" to recompile your project")
- print ("lwarpmk: and recreate \"" .. sourcename .. "-images.txt\".")
- print ("lwarpmk: If your project does not use SVG math or other lateximages,")
- print ("lwarpmk: then \"" .. sourcename .. "-images.txt\" will never exist, and")
- print ("lwarpmk: \"lwarpmk limages\" will not be necessary.")
- print ("lwarpmk: ===")
-end -- warnlimages
-
-function warnlimagesrecompile ()
--- Warning if must recompile before creating limages:
- print ("")
- print ("lwarpmk: ===")
- print ("lwarpmk: Cross-references are not yet correct.")
- print ("lwarpmk: The document must be recompiled before creating the lateximages.")
- print ("lwarpmk: Enter \"lwarpmk html1\" again, then try \"lwarpmk limages\" again.")
- print ("lwarpmk: ===")
-end --warnlimagesrecompile
-
-function checklimages ()
---
--- Check <sourcename>.txt to see if need to recompile first.
--- If any entry has a page number of zero, then there were incorrect images.
---
-print ("lwarpmk: Checking for a valid " .. sourcename .. "-images.txt file.")
-local limagesfile = io.open(sourcename .. "-images.txt", "r")
-if ( limagesfile == nil ) then
- warnlimages ()
- os.exit(1)
-end
--- Track warning to recompile if find a page 0
-local pagezerowarning = false
--- Scan <sourcename>.txt
-for line in limagesfile:lines() do
- -- lwimgpage is the page number in the PDF which has the image
- -- lwimghash is true if this filename is a hash
- -- lwimgname is the lateximage filename root to assign for the image
- i,j,lwimgpage,lwimghash,lwimgname = string.find (line,"|(.*)|(.*)|(.*)|")
- -- For each entry:
- if ( (i~=nil) ) then
- -- If the page number is 0, image references are incorrect
- -- and must recompile the soure document:
- if ( lwimgpage == "0" ) then
- pagezerowarning = true
- end
- end -- if i~=nil
-end -- do
--- The last line should be |end|end|end|.
--- If not, the compile must have aborted, and the images are incomplete.
-if ( lwimgpage ~= "end" ) then
- warnlimagesrecompile()
- os.exit(1) ;
-end
-if ( pagezerowarning ) then
- warnlimagesrecompile()
- os.exit(1) ;
-end -- pagezerowarning
-end -- checklimages
-
-function createuniximage ( lwimgfullname )
---
--- Create one lateximage for Unix / Linux / Mac OS.
---
-executecheckerror (
- cmdgroupopenname ..
- "pdfseparate -f " .. lwimgpage .. " -l " .. lwimgpage .. " " ..
- sourcename .."_html.pdf " ..
- imagesdirectory .. dirslash .."lateximagetemp-%d" .. ".pdf" ..
- seqname ..
- -- Crop the image:
- "pdfcrop --hires " .. imagesdirectory .. dirslash .. "lateximagetemp-" ..
- lwimgpage .. ".pdf " ..
- imagesdirectory .. dirslash .. lwimgname .. ".pdf" ..
- seqname ..
- -- Convert the image to svg:
- "pdftocairo -svg -noshrink " .. imagesdirectory .. dirslash .. lwimgname .. ".pdf " ..
- imagesdirectory .. dirslash .. lwimgname ..".svg" ..
- seqname ..
- -- Remove the temporary files:
- rmname .. " " .. imagesdirectory .. dirslash .. lwimgname .. ".pdf" .. seqname ..
- rmname .. " " .. imagesdirectory .. dirslash .. "lateximagetemp-" .. lwimgpage .. ".pdf" ..
- cmdgroupclosename .. " >/dev/null " .. bgname
- ,
- "File error trying to convert " .. lwimgfullname
-)
--- Every 32 images, wait for completion at below normal priority,
--- allowing other image tasks to catch up.
-numimageprocesses = numimageprocesses + 1
-if ( numimageprocesses > 32 ) then
- numimageprocesses = 0
- print ( "lwarpmk: waiting" )
- executecheckerror ( "wait" , "File error trying to wait.")
-end
-end -- createuniximage
-
-function createwindowsimage ( lwimgfullname )
---
--- Create one lateximage for Windows.
---
--- Every 32 images, wait for completion at below normal priority,
--- allowing other image tasks to catch up.
-numimageprocesses = numimageprocesses + 1
-if ( numimageprocesses > 32 ) then
- numimageprocesses = 0
- thiswaitcommand = "/WAIT /BELOWNORMAL"
- print ( "lwarpmk: waiting" )
-else
- thiswaitcommand = ""
-end
--- Execute the image generation command
-executecheckerror (
- "start /B " .. thiswaitcommand .. " \"\" lwarp_one_limage " ..
- lwimgpage .. " " ..
- lwimghash .. " " ..
- lwimgname .. " " ..
- sourcename .. " <nul >nul"
- ,
- "File error trying to create image."
-)
-end -- createwindowsimage
-
-function createonelateximage ( line )
---
--- Given the next line of <sourcename>.txt, convert a single image.
---
--- lwimgpage is the page number in the PDF which has the image
--- lwimghash is true if this filename is a hash
--- lwimgname is the lateximage filename root to assign for the image
-i,j,lwimgpage,lwimghash,lwimgname = string.find (line,"|(.*)|(.*)|(.*)|")
--- For each entry:
-if ( (i~=nil) ) then
- -- Skip if the page number is 0:
- if ( lwimgpage == "0" ) then
- pagezerowarning = true
- -- Skip if the page number is "end":
- else if ( lwimgpage == "end" ) then
- else
- -- Skip is this image is hashed and already exists:
- local lwimgfullname = imagesdirectory .. dirslash .. lwimgname .. ".svg"
- if (
- (lwimghash ~= "true") or
- (lfs.attributes(lwimgfullname,"mode")==nil) -- file not exists
- )
- then -- not hashed or not exists:
- -- Print the name of the file being generated:
- print ( "lwarpmk: " .. lwimgname )
- -- Touch/create the dest so that only once instance tries to build it:
- executecheckerror (
- newtouchname .. " " .. lwimgfullname ,
- "File error trying to touch " .. lwimgfullname
- )
- -- Separate out the image into its own single-page pdf:
- if opsystem=="Unix" then
- createuniximage (lwimgfullname)
- elseif opsystem=="Windows" then
- createwindowsimage (lwimgfullname)
- end
- end -- not hashed or not exists
- end -- not page "end"
- end -- not page 0
-end -- not nil
-end -- createonelateximage
-
-function createlateximages ()
---
--- Create lateximages based on <sourcename>-images.txt:
---
--- See if the document must be recompiled first:
-checklimages ()
--- See if the HTML version exists:
-checkhtmlpdfexists ()
--- Attempt to create the lateximages:
-print ("lwarpmk: Creating lateximages.")
-local limagesfile = io.open(sourcename .. "-images.txt", "r")
-if ( limagesfile == nil ) then
- warnlimages ()
- os.exit(1)
-end
--- Create the lateximages directory, ignore error if already exists
-err = os.execute("mkdir " .. imagesdirectory)
--- For Windows, create lwarp_one_limage.cmd from lwarp_one_limage.txt:
-if opsystem=="Windows" then
- executecheckerror (
- cpname .. " lwarp_one_limage.txt lwarp_one_limage.cmd" ,
- "File error trying to copy lwarp_one_limage.txt to lwarp_one_limage.cmd"
- )
-end -- create lwarp_one_limage.cmd
--- Track the number of parallel processes
-numimageprocesses = 0
--- Track warning to recompile if find a page 0
-pagezerowarning = false
--- Scan <sourcename>.txt
-for line in limagesfile:lines() do
- createonelateximage ( line )
-end -- do
-io.close(limagesfile)
-print ( "lwarpmk limages: ===")
-print ( "lwarpmk limages: Wait a moment for the images to complete" )
-print ( "lwarpmk limages: before reloading the page." )
-print ( "lwarpmk limages: ===")
-print ( "lwarpmk limages: Done." )
-if ( pagezerowarning == true ) then
- print ( "lwarpmk limages: WARNING: Images will be incorrect." )
- print ( "lwarpmk limages: Enter \"lwarpmk cleanlimages\", then" )
- print ( "lwarpmk limages: recompile the document one more time, then" )
- print ( "lwarpmk limages: repeat \"lwarpmk images\" again." )
-end -- pagezerowarning
-end -- function
-
-function convertepstopdf ()
---
--- Converts EPS files to PDF files.
--- The filenames are arg[argindex] and up.
--- arg[1] is the command "epstopdf".
---
-ignoreconf ()
-for i = argindex , #arg do
- if (lfs.attributes(arg[i],"mode")==nil) then
- print ("lwarpmk: File \"" .. arg[i] .. "\" does not exist.")
- else
- print ("lwarpmk: Converting \"" .. arg[i] .. "\"")
- thispath, thisfilename, thisextension = splitfilename(arg[i])
- if ( thispath == nil ) then
- os.execute ( "epstopdf " .. arg[i] )
- else
- os.execute (
- "epstopdf " ..
- thispath .. thisfilename .. "." .. thisextension .. " " ..
- thispath .. thisfilename .. ".pdf"
- )
- end
- end -- if
-end -- do
-end --function
-
-function convertpdftosvg ()
---
--- Converts PDF files to SVG files.
--- The filenames are arg[argindex] and up.
--- arg[1] is the command "pdftosvg".
---
-ignoreconf ()
-for i = argindex , #arg do
- if (lfs.attributes(arg[i],"mode")==nil) then
- print ("lwarpmk: File \"" .. arg[i] .. "\" does not exist.")
- else
- print ("lwarpmk: Converting \"" .. arg[i] .. "\"")
- thispath, thisfilename, thisextension = splitfilename(arg[i])
- if ( thispath == nil ) then
- os.execute ( "pdftocairo -svg " .. arg[i] )
- else
- os.execute (
- "pdftocairo -svg " ..
- thispath .. thisfilename .. "." .. thisextension .. " " ..
- thispath .. thisfilename .. ".svg"
- )
- end
- end -- if
-end -- do
-end --function
-
--- Force an update and conclude processing:
-function updateanddone ()
-print ("lwarpmk: Forcing an update of " .. sourcename ..".tex.")
-refreshdate ()
-print ("lwarpmk: " .. sourcename ..".tex is ready to be recompiled.")
-print ("lwarpmk: Done.")
-end -- function
-
--- Start of the main code: --
-
--- lwarpmk --version :
-
-if (arg[1] == "--version") then
-print ( "lwarpmk: " .. printversion )
-
-else -- not --version
-
--- print intro:
-
-print ("lwarpmk: " .. printversion .. " Automated make for the LaTeX Lwarp package.")
-
--- lwarpmk print:
-
-if arg[1] == "print" then
-loadconf ()
-if ( latexmk == "true" ) then
- print ("lwarpmk: Compiling with: " .. printlatexcmd)
- executecheckerror (
- printlatexcmd ,
- "Compile error."
- )
- print ("lwarpmk: Done.")
-else -- not latexmk
- verifyfileexists (sourcename .. ".tex") ;
- -- See if up to date:
- if (
- ( lfs.attributes ( sourcename .. ".pdf" , "modification" ) == nil ) or
- (
- lfs.attributes ( sourcename .. ".tex" , "modification" ) >
- lfs.attributes ( sourcename .. ".pdf" , "modification" )
- )
- ) then
- -- Recompile if not yet up to date:
- manytimes(printlatexcmd, "")
- print ("lwarpmk: Done.") ;
- else
- print ("lwarpmk: " .. sourcename .. ".pdf is up to date.") ;
- end
-end -- not latexmk
-
--- lwarpmk print1:
-
-elseif arg[1] == "print1" then
- loadconf ()
- verifyfileexists (sourcename .. ".tex") ;
- onetime(printlatexcmd, "")
- print ("lwarpmk: Done.") ;
-
--- lwarpmk printindex:
--- Compile the index then touch the source
--- to trigger a recompile of the document:
-
-elseif arg[1] == "printindex" then
-loadconf ()
-os.execute ( printindexcmd )
-print ("lwarpmk: -------")
-updateanddone ()
-
--- lwarpmk printglossary:
--- Compile the glossary then touch the source
--- to trigger a recompile of the document:
-
-elseif arg[1] == "printglossary" then
-loadconf ()
-print ("lwarpmk: Processing the glossary.")
-
-os.execute(glossarycmd .. " " .. sourcename)
-updateanddone ()
-
--- lwarpmk html:
-
-elseif arg[1] == "html" then
-loadconf ()
-if ( latexmk == "true" ) then
- print ("lwarpmk: Compiling with: " .. HTMLlatexcmd)
- executecheckerror (
- HTMLlatexcmd ,
- "Compile error."
- )
- pdftohtml ()
- print ("lwarpmk: Done.")
-else -- not latexmk
- verifyfileexists ( sourcename .. ".tex" ) ;
- -- See if exists and is up to date:
- if (
- ( lfs.attributes ( homehtmlfilename .. ".html" , "modification" ) == nil ) or
- (
- lfs.attributes ( sourcename .. ".tex" , "modification" ) >
- lfs.attributes ( homehtmlfilename .. ".html" , "modification" )
- )
- ) then
- -- Recompile if not yet up to date:
- manytimes(HTMLlatexcmd, "_html")
- pdftohtml ()
- print ("lwarpmk: Done.")
- else
- print ("lwarpmk: " .. homehtmlfilename .. ".html is up to date.")
- end
-end -- not latexmk
-
--- lwarpmk html1:
-
-elseif arg[1] == "html1" then
- loadconf ()
- verifyfileexists ( sourcename .. ".tex" ) ;
- onetime(HTMLlatexcmd, "_html")
- pdftohtml ()
- print ("lwarpmk: Done.")
-
--- lwarpmk pdftohtml:
-elseif arg[1] == "pdftohtml" then
- loadconf ()
- pdftohtml ()
-
--- lwarpmk htmlindex:
--- Compile the index then touch the source
--- to trigger a recompile of the document:
-
-elseif arg[1] == "htmlindex" then
-loadconf ()
-os.execute ( HTMLindexcmd )
-print ("lwarpmk: -------")
-updateanddone ()
-
--- lwarpmk htmlglossary:
--- Compile the glossary then touch the source
--- to trigger a recompile of the document.
--- The <sourcename>.xdy file is created by the glossaries package.
-
-elseif arg[1] == "htmlglossary" then
-loadconf ()
-print ("lwarpmk: Processing the glossary.")
-os.execute(glossarycmd .. " " .. sourcename .. "_html")
-updateanddone ()
-
--- lwarpmk limages:
--- Scan the <sourcename>.txt file to create lateximages.
-
-elseif arg[1] == "limages" then
-loadconf ()
-print ("lwarpmk: Processing images.")
-createlateximages ()
-print ("lwarpmk: Done.")
-
--- lwarpmk again:
--- Touch the source to trigger a recompile.
-
-elseif arg[1] == "again" then
-loadconf ()
-updateanddone ()
-
--- lwarpmk clean:
--- Remove project.aux, .toc, .lof, .lot, .log, *.idx, *.ind, *_html_inc.*, .gl*
-
-elseif arg[1] == "clean" then
-loadconf ()
-removeaux ()
-print ("lwarpmk: Done.")
-
--- lwarpmk cleanall
--- Remove project.aux, .toc, .lof, .lot, .log, *.idx, *.ind, *_html_inc.*, .gl*
--- and also project.pdf, project.dvi, *.html
-
-elseif arg[1] == "cleanall" then
-loadconf ()
-removeaux ()
-os.execute ( rmname .. " " ..
- sourcename .. ".pdf " .. sourcename .. "_html.pdf " ..
- sourcename .. ".dvi " .. sourcename .. "_html.dvi " ..
- "*.html"
- )
-print ("lwarpmk: Done.")
-
--- lwarpmk cleanlimages
--- Remove images from the imagesdirectory.
-
-elseif arg[1] == "cleanlimages" then
-loadconf ()
-os.execute ( rmname .. " " .. imagesdirectory .. dirslash .. "*" )
-print ("lwarpmk: Done.")
-
--- lwarpmk epstopdf <list of file names>
--- Convert EPS files to PDF using epstopdf
-elseif arg[1] == "epstopdf" then
-convertepstopdf ()
-print ("lwarpmk: Done.")
-
--- lwarpmk pdftosvg <list of file names>
--- Convert PDF files to SVG using pdftocairo
-elseif arg[1] == "pdftosvg" then
-convertpdftosvg ()
-print ("lwarpmk: Done.")
-
--- lwarpmk with no argument :
-
-elseif (arg[1] == nil) then
-printhelp ()
-
--- lwarpmk -v:
-
-elseif (arg[1] == "-v" ) then
--- The version number has already been printed
--- by the lwarpmk intro.
-
--- lwarpmk -h or lwarpmk --help :
-
-elseif (arg[1] == "-h" ) or (arg[1] == "--help") then
-printusage ()
-
--- Unknown command:
-
-else
-printhelp ()
-print ("\nlwarpmk: ****** Unknown command \""..arg[1].."\". ******\n")
-end
-
-end -- not --version
diff --git a/Build/source/texk/texlive/linked_scripts/m-tx/m-tx.lua b/Build/source/texk/texlive/linked_scripts/m-tx/m-tx.lua
deleted file mode 100755
index 0a62d8fc447..00000000000
--- a/Build/source/texk/texlive/linked_scripts/m-tx/m-tx.lua
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env texlua
-
-print ("The m-tx[.lua] script has been retired; please switch")
-print ("to the musixtex script, which now processes .mtx files.")
-
diff --git a/Build/source/texk/texlive/linked_scripts/make4ht/make4ht b/Build/source/texk/texlive/linked_scripts/make4ht/make4ht
deleted file mode 100755
index 079c464ecd2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/make4ht/make4ht
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env texlua
--- Package make4ht. Author Michal Hoftich <michal.h21@gmail.com>
--- This package is subject of LPPL license, version 1.3
-kpse.set_program_name("luatex")
-
--- logging should be globally available
-logging = require "make4ht-logging"
-if os.type == "windows" then logging.use_colors = false end
-local log = logging.new("make4ht")
-local make4ht = require("make4ht-lib")
-local lapp = require("lapp-mk4")
-local mkutils = require("mkutils")
-local mkparams = require("mkparams")
-local mk_config = require("make4ht-config")
--- args string is here just as sample, we dont pass it it to
--- mkparams.get_args() so default args string is used
-local args = [[
-make4ht - build system for TeX4ht
-Usage:
-make4ht [options] filename ["tex4ht.sty op." "tex4ht op." "t4ht op" "latex op"]
--c,--config (default xhtml) Custom config file
--d,--output-dir (default nil) Output directory
--l,--lua Use lualatex for document compilation
--s,--shell-escape Enables running external programs from LaTeX
--u,--utf8 For output documents in utf8 encoding
--x,--xetex Use xelatex for document compilation
-<filename> (string) Input file name
-]]
-
--- set version number. the template should be replaced by the
--- actual version number by the build script
-local version = "v0.3f"
-mkparams.version_number = version
-
-local args = mkparams.get_args()
-
-local parameters = mkparams.process_args(args)
-
-log:status("Conversion started")
-log:status("Input file: " .. parameters.tex_file)
-
-local mode = parameters.mode
-local build_file = parameters.build_file
-
--- handle output formats
-local allowed_output_formats = {xhtml = true, html5=true, odt = true, docbook=true, tei=true, jats=true}
--- formatter is Lua library which must provide at least prepare_parameters
--- and process_build_sequence functions
-local formatter
-local output_format = parameters.output_format
-if allowed_output_formats[ output_format ] then
- formatter = mkutils.load_output_format(output_format)
-else
- -- load html5 as default output format
- if output_format then
- log:warning("Cannot load output format: ".. output_format)
- end
- formatter = mkutils.load_output_format("html5")
-end
--- find make4ht configuration file
-local configname = "make4ht"
-local conffile = mk_config.find_config(configname) or mk_config.find_xdg_config(configname)
-if conffile then
- log:info("Using configuration file: " .. conffile)
- mkutils.load_config(parameters, conffile)
-end
-local extensions = formatter.prepare_extensions(parameters.extensions)
-extensions = mkutils.load_extensions(extensions, output_format)
-
-
-
--- run extensions with prepare_parameters function
-parameters = formatter.prepare_parameters(parameters,extensions)
-local make = mkutils.load_config(parameters, build_file)["Make"]
-make.params = parameters
-if make:length() < 1 then
- if mode == "draft" then
- make:htlatex()
- else
- make:htlatex()
- make:htlatex()
- make:htlatex()
- end
-end
-
-
-if not args["no-tex4ht"] then
- make:tex4ht()
-end
-
-local ext = args.xetex and "xdv" or "dvi"
-if #make.image_patterns > 0 then
- make.params.t4ht_par = make.params.t4ht_par .. " -p"
-end
-make:t4ht {ext = ext}
--- run extensions which modify the build sequence
-if #extensions > 0 then
- make = mkutils.extensions_modify_build(extensions, make)
-end
-
--- allow output formats to modify the build process at the end
-make = formatter.modify_build(make) or make
-
-make:match("tmp$", function(filename,params)
- -- remove the temporary tex file created when the input comes from the standard input
- if params.is_tmp_file then
- log:info("removing temp file", params.tex_file)
- os.remove(params.tex_file)
- end
- -- prevent copying of the temporary file to the outdir
- return false,"tmp file" end
-)
-
-make:match(".*",function(filename,par)
- local outdir = '' --par["outdir"] and par["outdir"] .."/" or ''
- if par['outdir'] ~= "" then outdir = par['outdir'] .. '/' end
- log:info("outdir: "..outdir)
- local outfilename = outdir .. filename
- mkutils.copy(filename,outfilename)
- return true
-end)
-
-make:run()
-
-log:status("Conversion finished")
-
diff --git a/Build/source/texk/texlive/linked_scripts/makedtx/makedtx.pl b/Build/source/texk/texlive/linked_scripts/makedtx/makedtx.pl
deleted file mode 100755
index 772ea33ff99..00000000000
--- a/Build/source/texk/texlive/linked_scripts/makedtx/makedtx.pl
+++ /dev/null
@@ -1,1022 +0,0 @@
-#!/usr/bin/perl
-
-# File : makedtx
-# Author : Nicola L. C. Talbot
-# Date : 29 Oct 2004
-# Last Modified : 2017-04-08
-# Version : 1.2
-
-# usage : makedtx [options] -src <expr>=><expr> -doc <filename> <basename>
-#
-# -h : help message
-# -src <expr>=><expr> : e.g. -src "(foo)src\.(bar)=>$1.$2" will add foosrc.bar to <basename>.dtx to be extracted to foo.bar
-# -doc <filename> : file containing documentation.
-# -prefinale <string> : text to add to dtx file just before \Finale (added to version 0.91b)
-# <basename> : create <basename>.dtx and <basename>.ins
-
-use Getopt::Long;
-
-$version = "1.2";
-
-# process command line options
-
- %optctl = ();
-
-# v1.1 added section switch
-&GetOptions(\%optctl, "h", "help", "v", "src=s@", "doc=s",
-"dir=s", "op=s", "askforoverwrite!", "ins!",
-"preamble=s", "postamble=s", "setambles=s@", "testmode", "macrocode=s@",
-"author=s", "date=s", "stopeventually=s",
-"prefinale=s", "codetitle=s", "comment=s@",
-"version", "license=s", "section=s") or &syntaxerror();
-
-$srcdir = ".";
-$patternop = "=";
-$verbose = 0;
-$noins = 0;
-$testmode = 0;
-$askforoverwrite = 0;
-$preamble = "";
-$postamble = "";
-my $author;
-if ($^O =~ m/MSWin/)
-{
- $author = $ENV{"USERNAME"};
- if ($author eq ""){ $author = 'Unknown';}
-}
-else
-{
- $author = (getpwuid($<))[6] || 'Unknown';
-}
-$stopeventually = "";
-$prefinale = "";
-$codetitle = "The Code";
-$section = "section";
-$license = "lppl";
-
-($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
-
-$year = $year + 1900;
-$copyright_date = $year;
-$creation_date = "$year/" . ($mon+1) . "/$mday $hour:" . ($min<10?"0$min" : $min);
-
-foreach $setting (keys %optctl)
-{
- if (($setting eq "h") || ($setting eq "help"))
- {
- &help();
- }
- elsif ($setting eq "version")
- {
- print "makedtx version $version\n";
- exit 0;
- }
- elsif ($setting eq "doc")
- {
- $docsrc = $optctl{$setting};
- }
- elsif ($setting eq "src")
- {
- @source = @{ $optctl{$setting} };
- }
- elsif ($setting eq "dir")
- {
- $srcdir = $optctl{$setting};
- }
- elsif ($setting eq "op")
- {
- $patternop = $optctl{$setting};
- }
- elsif ($setting eq "v")
- {
- $verbose = 1;
- }
- elsif ($setting eq "ins")
- {
- $noins = 1-$optctl{$setting};
- }
- elsif ($setting eq "askforoverwrite")
- {
- $askforoverwrite = $optctl{$setting};
- }
- elsif ($setting eq "preamble")
- {
- $preamble = $optctl{$setting};
- }
- elsif ($setting eq "postamble")
- {
- $postamble = $optctl{$setting};
- }
- elsif ($setting eq "setambles")
- {
- @setambles = @{ $optctl{$setting} };
- }
- elsif ($setting eq "macrocode")
- {
- @macrocode = @{ $optctl{$setting} };
- }
- elsif ($setting eq "author")
- {
- $author = $optctl{$setting};
- }
- elsif ($setting eq "date")
- {
- $copyright_date = $optctl{$setting};
- }
- elsif ($setting eq "stopeventually")
- {
- $stopeventually = $optctl{$setting};
- }
- elsif ($setting eq "prefinale")
- {
- $prefinale = $optctl{$setting};
- }
- elsif ($setting eq "codetitle")
- {
- $codetitle = $optctl{$setting};
- }
- elsif ($setting eq "section")
- {
- $section = $optctl{$setting};
- }
- elsif ($setting eq "testmode")
- {
- $testmode = $optctl{$setting};
- if($testmode)
- {
- $version = "x.y";
- $copyright_date = "YYYY";
- $creation_date = "YYYY/MM/DD hh:mm";
- }
- }
- elsif ($setting eq "comment")
- {
- @comment = @{ $optctl{$setting} };
- }
- elsif ($setting eq "license")
- {
- $license = $optctl{$setting};
- }
-}
-
-if ($#ARGV != 0)
-{
- print "No basename specified\n";
- &syntaxerror();
-}
-
-$basename = $ARGV[0];
-
-if ($docsrc eq "")
-{
- print "No document source specified (missing -doc)\n";
- &syntaxerror();
-}
-
-if ($#source == -1)
-{
- print "No source code specified (missing -src)\n";
- &syntaxerror();
-}
-
-open DTX, ">:unix","$basename.dtx" or die "Can't open '$basename.dtx'\n";
-
-if ($verbose)
-{
- print "Documentation source : " . $docsrc . "\n";
-}
-
-# work out the derived files
-
- @srcdirfile = glob("$srcdir/*");
-
- @derivedfiles = ();
-
- @outputfiles = ();
-
-$numoutput = 0;
-
-foreach $source (@source)
-{
- ($infile, $outfile, $remainder) = split /=>/, $source;
-
- if ($outfile eq "")
- {
- print "-src $source argument invalid (no output file specified)\n";
-
- &syntaxerror();
- }
-
- if (not ($remainder eq ""))
- {
- print "-src $source argument invalid (too many => specified)\n";
-
- &syntaxerror();
- }
-
- foreach $srcdirfile (@srcdirfile)
- {
- $fileexp = $srcdir . "/" . $infile;
-
- $_ = $srcdirfile;
-
- $expr = "s$patternop$fileexp$patternop$outfile$patternop";
-
- if (eval($expr))
- {
- $thisoutfile = $_;
-
- $thisinfile = $srcdirfile;
-
- $file{$thisinfile} = $thisoutfile;
- $derivedfiles[$numoutput]{'in'} = $thisinfile;
- $derivedfiles[$numoutput]{'out'} = $thisoutfile;
- $outputfiles[$numoutput] = $thisoutfile;
-
- $numoutput++;
- }
- }
-}
-
-if ($preamble eq "")
-{
- if ($license eq "lppl")
- {
-# v1.2 fixed typo in preamble
- $preamble = <<_END_LICENSE;
-
- $basename.dtx
- Copyright $copyright_date $author
-
- This work may be distributed and/or modified under the
- conditions of the LaTeX Project Public License, either version 1.3
- of this license or (at your option) any later version.
- The latest version of this license is in
- http://www.latex-project.org/lppl.txt
- and version 1.3 or later is part of all distributions of LaTeX
- version 2005/12/01 or later.
-
- This work has the LPPL maintenance status `maintained'.
-
- The Current Maintainer of this work is $author.
-
-_END_LICENSE
- }
- elsif ($license eq 'bsd')
- {
- $preamble = <<_END_LICENSE;
-
- $basename.dtx
- Copyright (c) $copyright_date $author
- All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-_END_LICENSE
- }
- elsif ($license eq 'gpl')
- {
- $preamble = <<_END_LICENSE;
-
- $basename.dtx
- Copyright (c) $copyright_date $author
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-_END_LICENSE
- }
- else
- {
- die "Unknown license '$license'\n".
- "Known licenses: lppl, bsd, gpl";
- }
-
- $preamble .= " This work consists of the files "
- . "$basename.dtx and $basename.ins and the derived "
- . ($numoutput > 1 ? "files" : "file")
- . " " . join(', ', @outputfiles) . ".\n";
-}
-
-open DOC, '<:crlf',$docsrc or die "Can't open '$docsrc'\n";
-
-print DTX "\%\\iffalse\n";
-print DTX "\% $basename.dtx generated using makedtx version $version (c) Nicola Talbot\n";
-print DTX "\% Command line args:\n";
-
-@cmdline_args = ();
-foreach $setting (keys %optctl)
-{
- if ($setting eq "src")
- {
- foreach $source (@source)
- {
- push @cmdline_args ,"-src \"$source\"";
- }
- }
- elsif ($setting eq "setambles")
- {
- foreach $setamble (@setambles)
- {
- push @cmdline_args ,"-setambles \"$setamble\"";
- }
- }
- elsif ($setting eq "macrocode")
- {
- foreach $macrocode (@macrocode)
- {
- push @cmdline_args ,"-macrocode \"$macrocode\"";
- }
- }
- elsif ($setting eq "comment")
- {
- foreach $comment (@comment)
- {
- push @cmdline_args ,"-comment \"$comment\"";
- }
- }
- else
- {
- $val = $optctl{$setting};
- $val=~s/\\/\\\\/g;
- push @cmdline_args ,("-" . $setting . " \"" . $val . "\"");
- }
-}
-if($testmode){
- @cmdline_args = sort @cmdline_args;
-}
-foreach $arg (@cmdline_args){
- print DTX "\% ", $arg , "\n";
-}
-
-print DTX "\% $basename\n";
-
-print DTX "\% Created on $creation_date\n";
-print DTX "\%\\fi\n";
-print DTX "\%\\iffalse\n";
-print DTX "\%<*package>\n";
-print DTX "\%\% \\CharacterTable\n";
-print DTX "\%\% {Upper-case \\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\n";
-print DTX "\%\% Lower-case \\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\n";
-print DTX "\%\% Digits \\0\\1\\2\\3\\4\\5\\6\\7\\8\\9\n";
-print DTX "\%\% Exclamation \\! Double quote \\\" Hash (number) \\#\n";
-print DTX "\%\% Dollar \\\$ Percent \\\% Ampersand \\&\n";
-print DTX "\%\% Acute accent \\\' Left paren \\( Right paren \\)\n";
-print DTX "\%\% Asterisk \\* Plus \\+ Comma \\,\n";
-print DTX "\%\% Minus \\- Point \\. Solidus \\/\n";
-print DTX "\%\% Colon \\: Semicolon \\; Less than \\<\n";
-print DTX "\%\% Equals \\= Greater than \\> Question mark \\?\n";
-print DTX "\%\% Commercial at \\\@ Left bracket \\[ Backslash \\\\\n";
-print DTX "\%\% Right bracket \\] Circumflex \\^ Underscore \\_\n";
-print DTX "\%\% Grave accent \\\` Left brace \\{ Vertical bar \\|\n";
-print DTX "\%\% Right brace \\} Tilde \\~}\n";
-print DTX "\%</package>\n";
-print DTX "\%\\fi\n";
-
-print DTX "\% \\iffalse\n";
-print DTX "\% Doc-Source file to use with LaTeX2e\n";
-print DTX "\% Copyright (C) $copyright_date $author, all rights reserved.\n";
-print DTX "\% \\fi\n";
-
-# driver
-
-print DTX "\% \\iffalse\n";
-print DTX "\%<*driver>\n";
-
-$indoc=0;
-
-while (<DOC>)
-{
- s/\\usepackage\{creatdtx}//;
-
- $restofline = $_;
-
- $beginline = "";
- $line = $restofline;
-
- while ($restofline =~ /(.*)\\ifmakedtx(.*)/)
- {
- $beginline = $1;
-
- ($group,$restofline,$done) = &getnextgroup($2);
-
- $startline = $.;
-
- while (!$done)
- {
- if ($nextline = <DOC>)
- {
- $line = $line . $nextline;
-
- $restofline = $restofline . $nextline;
-
- ($group,$restofline,$done) = &getnextgroup($restofline);
- }
- else
- {
- die "EOF found whilst scanning first argument to \\ifmakedtx on line $startline\n";
- }
- }
-
- # print first arg, ignore second
-
- $beginline = $beginline . $group;
-
- ($group,$restofline,$done) = &getnextgroup($restofline);
-
- while (!$done)
- {
- if ($nextline = <DOC>)
- {
- $line = $line . $nextline;
-
- $restofline = $restofline . $nextline;
-
- ($group,$restofline,$done) = &getnextgroup($restofline);
- }
- else
- {
- die "EOF found whilst scanning second argument to \\ifmakedtx on line $startline\n";
- }
- }
-
- $line = $restofline;
- }
-
- $line = $beginline . $restofline;
-
- print DTX $line;
-
- if ($line=~/\\begin\{document}/)
- {
- $indoc = 1;
-
- last;
- }
-}
-
-print DTX "\\DocInput{$basename.dtx}\n";
-print DTX "\\end{document}\n";
-print DTX "\%</driver>\n";
-print DTX "\%\\fi\n";
-
-$inverb=0;
-$stopfound=0;
-
-print DTX "\%";
-
-while (<DOC>)
-{
- if (/\\begin\{verbatim}/)
- {
- $inverb=1;
- }
-
- if (/\\end\{verbatim}/)
- {
- $inverb=0;
- }
-
- if (/\\StopEventually/ && ($inverb==0))
- {
- $stopfound=1;
- }
-
- $restofline = $_;
-
- $beginline = "";
- $line = $restofline;
-
- while ($restofline =~ /(.*)\\ifmakedtx(.*)/)
- {
- $beginline = $1;
-
- ($group,$restofline,$done) = &getnextgroup($2);
-
- $startline = $.;
-
- while (!$done)
- {
- if ($nextline = <DOC>)
- {
- $line = $line . $nextline;
-
- $restofline = $restofline . $nextline;
-
- ($group,$restofline,$done) = &getnextgroup($restofline);
- }
- else
- {
- die "EOF found whilst scanning first argument to \\ifmakedtx on line $startline\n";
- }
- }
-
- # print first arg, ignore second
-
- $beginline = $beginline . $group;
-
- ($group,$restofline,$done) = &getnextgroup($restofline);
-
- while (!$done)
- {
- if ($nextline = <DOC>)
- {
- $line = $line . $nextline;
-
- $restofline = $restofline . $nextline;
-
- ($group,$restofline,$done) = &getnextgroup($restofline);
- }
- else
- {
- die "EOF found whilst scanning second argument to \\ifmakedtx on line $startline\n";
- }
- }
-
- $line = $restofline;
- }
-
- $line = $beginline . $restofline;
-
- if (($line=~/\\end\{document}/) and not $inverb)
- {
- $indoc=0;
-
- $line=~s/\\end\{document}//;
- }
-
- $line=~s/\n/\n\%/mg;
-
- print DTX "$line";
-}
-
-close DOC;
-
-print DTX "\n";
-
-if ($stopfound==0)
-{
- print DTX "\%\\StopEventually{$stopeventually}\n";
-}
-
-# v1.0 added check
-if ($codetitle)
-{
- # v1.1 added section
- print DTX "\%\\$section\{$codetitle\}\n";
-}
-
-for (my $idx = 0; $idx <= $#derivedfiles; $idx++)
-{
- $thisinfile = $derivedfiles[$idx]{'in'};
- $thisoutfile = $derivedfiles[$idx]{'out'};
-
- if ($verbose)
- {
- print "$srcdirfile -> $_ \n";
- }
-
- open SRC, "<:crlf", $thisinfile or die "Can't open $thisinfile\n";
-
- print DTX "\%\\iffalse\n";
- print DTX "\% \\begin{macrocode}\n";
- print DTX "\%<*$thisoutfile>\n";
- print DTX "\% \\end{macrocode}\n";
- print DTX "\%\\fi\n";
-
- $macrocode = 0;
- $comment = 0;
-
- foreach $expr (@comment)
- {
- if ($thisoutfile =~ m/$expr/)
- {
- print DTX "\%\\iffalse\n";
-
- $comment = 1;
- }
- }
-
- foreach $expr (@macrocode)
- {
- if ($thisoutfile =~ m/$expr/)
- {
- print DTX "\% \\begin{macrocode}\n";
-
- $macrocode = 1;
- }
- }
-
- while (<SRC>)
- {
- print DTX "$_";
- }
-
- if ($macrocode == 1)
- {
- print DTX "\% \\end{macrocode}\n";
- }
-
- if ($comment == 1)
- {
- print DTX "\%\\fi\n";
- }
-
- print DTX "\%\\iffalse\n";
- print DTX "\% \\begin{macrocode}\n";
- print DTX "\%</$thisoutfile>\n";
- print DTX "\% \\end{macrocode}\n";
- print DTX "\%\\fi\n";
-
- close SRC;
-}
-
-print DTX "\%$prefinale\n" if ($prefinale);
-print DTX "\%\\Finale\n";
-print DTX "\\endinput\n";
-
-close DTX;
-
-if (!$noins)
-{
- open INS, ">:unix","$basename.ins" or die "Can't open '$basename.ins'\n";
-
- print INS "\% $basename.ins generated using makedtx version $version $creation_date\n";
-
- print INS "\\input docstrip\n\n";
- print INS "\\preamble\n";
- print INS "$preamble\n";
- print INS "\\endpreamble\n\n";
-
- if ($postamble ne "")
- {
- print INS "\\postamble\n";
- print INS "$postamble\n";
- print INS "\\endpostamble\n\n";
- }
-
- if ($askforoverwrite)
- {
- print INS "\\askforoverwritetrue\n\n";
- }
- else
- {
- print INS "\\askforoverwritefalse\n\n";
- }
-
- print INS "\\generate{";
-
- for (my $idx = 0; $idx <= $#derivedfiles; $idx++)
- {
- $file = $derivedfiles[$idx]{'in'};
- $outfile = $derivedfiles[$idx]{'out'};
-
- print INS "\\file{$outfile}{";
-
- $ambleset = 0;
- $noamble = 0;
-
- foreach $setamble (@setambles)
- {
- ($fileexp, $amble, $remainder) = split /=>/, $setamble;
-
- if (not ($remainder eq ""))
- {
- die "-setambles $setamble argument invalid (too many => specified)\n";
- }
-
- if ($outfile =~ m/$fileexp/)
- {
- if ($verbose)
- {
- print "$fileexp matches $outfile -> setting \"$amble\"\n";
- }
-
- print INS $amble;
-
- $ambleset = 1;
-
- if ($amble =~ m/\\nopreamble/)
- {
- $noamble = 1;
- }
- }
- }
-
- if (!$ambleset)
- {
- print INS "\\usepreamble\\defaultpreamble\n\\usepostamble\\defaultpostamble";
- }
-
- print INS "\\from{$basename.dtx}{$outfile";
-
- if ($noamble == 0)
- {
- # this will add the character table to all files except those that use \nopreamble
-
- print INS ",package";
- }
-
- print INS "}}\n";
- }
-
- print INS "}\n\n";
-
- print INS "\\endbatchfile\n";
-
- close INS;
-}
-
-sub syntaxerror
-{
- die "Syntax : makedtx [options] <basename>\nUse -h for help\n";
-}
-
-sub help
-{
- print "makedtx Help\n\n";
-
- print "Current Version : $version\n\n";
-
- print "usage : makedtx [options] -src \"<expr>=><expr>\" -doc <filename> <basename>\n\n";
-
- print "makedtx can be used to construct a LaTeX2e dtx and ins file from\n";
- print "the specified source code. The final command line argument\n";
- print "<basename> should be used to specify the basename of the dtx\n";
- print "and ins files.\n\n";
-
- print "-src \"<expr1>=><expr2>\"\n";
- print "The command line switch -src identifies the original source code and the name\n";
- print "of the file to which it will utimately be extracted on latexing the ins file\n";
- print "<expr1> can be a Perl expression, such as (foo)src.(sty), and <expr2> can\n";
- print "a Perl substitution style expression, such as $1.$2\n";
- print "Note that double quotes must be used to prevent shell expansion\n";
- print "Multiple invocations of -src are permitted\n";
- print "See examples below.\n\n";
-
- print "-doc <filename>\n";
- print "The name of the documentation source code. This should be a LaTeX2e document\n\n";
-
- print "Optional Arguments:\n\n";
-
- print "-dir <directory> : search for source files in <directory>\n";
- print "-op <character> : set the pattern matching operator (default '$patternop')\n";
- print "-askforoverwrite : set askforoverwrite switch in INS file to true\n";
- print "-noaskforoverwrite : set askforoverwrite switch in INS file to false (default)\n";
- print "-preamble <text> : set the preamble. Standard one inserted if omitted\n";
- print "-postamble <text> : set the postamble.\n";
- print "-setambles \"<pattern>=><text>\" : set pre- and postambles to <text> if file matches pattern\n";
- print "-author <text> : name of author (inserted into standard preamble. User name inserted if omitted)\n";
- print "-date <text> : copyright date\n";
- print "-ins : create the ins file (default)\n";
- print "-noins : don't create the ins file\n";
- print "-prefinale <text> : add <text> immediately prior to \\Finale\n";
- print "-macrocode <expr> : surround any file which matches <expr> in a macrocode environment\n";
- print "-comment <expr> : surround any file which matches <expr> with \\iffalse \\fi pair\n";
- print "-codetitle <text> : The title for the documented code section (default: The Code)\n";
- print "-section <cs> : The sectioning command to use for the documented code section (default: 'section')\n";
- print "-license <license> : use the given license for the preamble.\n";
- print " Known licenses: lppl (default), bsd, gpl.\n";
- print "-h : help message\n";
- print "-v : verbose\n\n";
-
- print "Examples:\n\n";
-
- print "Example 1:\n";
- print "Documenation is in foodoc.tex\n";
- print "Source code is in foosrc.sty. The final extracted version should be \n";
- print "called foo.sty. The dtx file should be called foo.dtx and the ins file\n";
- print " should be called foo.ins\n\n";
-
- print "makedtx -src \"foosrc\\.sty=>foo.sty\" -doc foodoc.tex foo\n\n";
-
- print "Example 2:\n";
- print "Documenation is in bardoc.tex\n";
- print "Source code is in barsrc.sty. The final extracted version should be\n";
- print "called bar.sty. Source code is also in barsrc.bst. The final extracted\n";
- print "version should be called bar.bst. The dtx file should be called bar.dtx and\n";
- print "the ins file should be called bar.ins\n\n";
-
- print "makedtx -src \"barsrc\\.sty=>bar.sty\" -src \"barsrc\\.bst=>bar.bst\" -doc bardoc.tex bar\n\n";
-
- print "Or\n\n";
-
- print "makedtx -src \"barsrc\\.(bst|sty)=>bar.\$1\" -doc bardoc.tex bar\n\n";
-
- die;
-}
-
-sub eatinitialspaces
-{
- my ($STR) = @_;
-
- while (substr($STR,0,1) eq "\s")
- {
- $STR = substr($STR,1);
- }
-
- return $STR;
-}
-
-sub getnextgroup
-{
- my($curline) = @_;
-
- $curline = &eatinitialspaces($curline);
-
- # check to see if current string is blank
-
- if ($curline!~/[^\s]+/m)
- {
- return ("","",0);
- }
-
- if (($group = substr($curline,0,1)) ne "{")
- {
- # next group hasn't been delimited with braces
- # return first non-whitespace character
-
- $curline = substr($curline,1);
-
- # unless it's a backslash, in which case get command name
-
- if ($group eq "\\")
- {
- if ($curline=~/([a-zA-Z]+)(^[a-zA-Z].*)/m)
- {
- $group = $1;
-
- $curline = $2;
- }
- else
- {
- # command is made up of backslash followed by symbol
-
- $curline=~/([\W_0-9\s\\])(.*)/m;
-
- $group = $1;
-
- $curline = $2;
- }
- }
-
- return ($group,$curline,1);
- }
-
- my $pos=index($curline, "{");
- my $startpos=$pos;
- my $posopen=0;
- my $posclose=0;
-
- my $bracelevel = 1;
-
- my $done=0;
-
- while (!$done)
- {
- $pos++;
-
- $posopen = index($curline, "{", $pos);
-
- # check to make sure it's not a \{
-
- while ((substr($curline, $posopen-1,1) eq "\\") and ($posopen > 0))
- {
- # count how many backlashes come before it.
-
- $i = $posopen-1;
-
- $numbs = 1;
-
- while ((substr($curline, $i-1,1) eq "\\") and ($i > 0))
- {
- $numbs++;
- $i--;
- }
-
- # is $numbs is odd, we have a \{, otherwise we have \\{
-
- if ($numbs%2 == 0)
- {
- last;
- }
- else
- {
- $posopen = index($curline, "{", $posopen+1);
- }
- }
-
- $posclose= index($curline, "}", $pos);
-
- # check to make sure it's not a \}
-
- while ((substr($curline, $posclose-1,1) eq "\\") and ($posclose > 0))
- {
- # count how many backlashes come before it.
-
- $i = $posclose-1;
-
- $numbs = 1;
-
- while ((substr($curline, $i-1,1) eq "\\") and ($i > 0))
- {
- $numbs++;
- $i--;
- }
-
- # is $numbs is odd, we have a \}, otherwise we have \\}
-
- if ($numbs%2 == 0)
- {
- last;
- }
- else
- {
- $posclose = index($curline, "}", $posclose+1);
- }
- }
-
- if (($posopen==-1) and ($posclose==-1))
- {
- $done=1;
- }
- elsif ($posopen==-1)
- {
- $pos=$posclose;
-
- $bracelevel--;
-
- if ($bracelevel==0)
- {
- $group = substr($curline, $startpos+1, $pos-$startpos-1);
-
- $curline = substr($curline, $pos+1);
-
- return ($group,$curline,1);
- }
- }
- elsif ($posclose==-1)
- {
- $pos=$posopen;
-
- $bracelevel++;
- }
- elsif ($posopen<$posclose)
- {
- $pos=$posopen;
-
- $bracelevel++;
- }
- elsif ($posclose<$posopen)
- {
- $pos=$posclose;
-
- $bracelevel--;
-
- if ($bracelevel==0)
- {
- $group = substr($curline, $startpos+1, $pos-$startpos-1);
-
- $curline = substr($curline, $pos+1);
-
- return ($group,$curline,1);
- }
- }
- }
-
- # closing brace must be on another line
-
- return ("", $curline, 0);
-}
-1;
diff --git a/Build/source/texk/texlive/linked_scripts/match_parens/match_parens b/Build/source/texk/texlive/linked_scripts/match_parens/match_parens
deleted file mode 100755
index 5387e908d9d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/match_parens/match_parens
+++ /dev/null
@@ -1,214 +0,0 @@
-#!/usr/bin/env ruby
-# encoding: utf-8
-
- MYNAME = File.basename($0)
-Version = '1.43'
-
-<<'DOC'
-= match_parens - find mismatches of various brackets and quotes
-
-= Synopsis
-match_parens [filename]
-
-Options:
--p,--pairs=S set matching pairs to S (default: |{}[]()""“”''â€â€™|)
--n,--number=N set number of mismatching characters shown to N (default: 10)
--l,--latex convert |``...''| to |“...”| before testing
--V,--version print version and exit
--h,--help print short help information and exit
- --test do an internal test and exit
-
-= Description
-Mismatches of parentheses, braces, (angle) brackets, especially in TeX
-sources which may be rich in those, may be difficult to trace. This little
-script helps you by writing your text to standard output, after adding a
-left margin to your text, which will normally be almost empty, but will
-clearly show up to 10 mismatches. (Just try me on myself to see that the
-parenthesis starting this sentence will not appear to be matched at the end
-of the file. If you look at me in the vim editor, then select this
-paragraph and try the command: |:!%|.
-
-By default, the following pairs are tested:
-() round brackets or parentheses
-{} curly brackets or braces
-[] square brackets
-<> angle brackets (within html text only)
-"" ASCII double quotes
-“” Unicode double quotation marks
-'' ASCII single quotes
-â€â€™ Unicode single quotation marks
-
-The exit value of the script is 0 when there are no mismatches, 1 otherwise.
-
-Angle brackets are only looked for inside HTML text, where HTML is
-supposed to start with |<html>| or |=begin rdoc| and to end with
-|</html>| or |=end|.
-
-= Options
--p,--pairs=S
- Set matching pairs to S (default: |{}[]()""“”''â€â€™|). For example, if you
- want to look for mismatching ASCII single quotes /only/, use |--pairs="''"|.
- Or, if you want to match braces and guillemets only, use |-p «»|.
- Note that if html is detected in your text, |<>| is automatically added
- to the pairs list. So by default, |<...>| is tested only in html, but
- you can test that in other text by specifying the |<>| pair in the
- |--pairs| option.
--n,--number=N
- Set number of mismatching characters shown to N. By default, only the
- first 10 are shown.
--l,--latex
- convert |``...''| to |“...”|` before testing.
--V,--version
- print this script's version and exit.
--h,--help
- print short help information and exit.
- --test
- do an internal test and exit. Note that if, with the |--pairs| option,
- you specify an other pairs list than the default, the test will
- probably fail, but you can still see the effects of your pairs list on
- the test data.
-
-= Examples
-Suppose we have two files, |good| and |bad|, containing these texts:
- good: bad:
- This is a (simple) test This is a (simple test
- without mismatches containing mismatches
-
-then here are some usage examples. First a simple test on these files:
- $ match_parens good
- 1 | | This is a (simple) test
- 2 | | without mismatches
- $ echo $?
- 0
- $ match_parens bad
- 1 | ( | This is a (simple test
- 2 | ( | containing mismatches
- $ echo $?
- 1
-
-Just report if there are mismatches:
- $ match_parens good >/dev/null && echo fine || echo problems
- fine
- $ match_parens bad >/dev/null && echo fine || echo problems
- problems
-
-Report all tex files with mismatches in the current directory:
- $ for i in *.tex; do match_parens $i >/dev/null || echo $i; done
-
-Matches must be in correct order:
- $ echo -e "This is a ([simple)] test\n" | match_parens
- 1 ([)] This is a ([simple)] test
- 2 ([)]
-
-= Changes
-Changes with respect to version 1.41:
-- test on more quote characters (single, double, ASCII, Unicode)
-- option for changing the character pairs to be tested
-- conversion of latex' ``...'' is now an option
-- built-in test option |--test|
-
-= Author and copyright
-Author Wybo Dekker
-Email U{Wybo@dekkerdocumenten.nl}{wybo@dekkerdocumenten.nl}
-License Released under the U{www.gnu.org/copyleft/gpl.html}{GNU General Public License}
-DOC
-
-require 'optparse'
-
-number, input, latex, lineno, s, html, test, parenstext =
- 10, STDIN, false, 0, '', false, false, %q{{}[]()""“”''â€â€™}
-
-ARGV.options do |opt|
- opt.banner = "#{MYNAME} - find mismatches of parentheses, braces, (angle) brackets, in texts\n"
- opt.on('-p','--pairs=S',String,
- "set matching pairs to S (default: #{parenstext})"
- ) do |v|
- parenstext = v
- end
- opt.on('-n','--number=N',Integer,
- "set number of mismatching characters shown to N (default: #{number})"
- ) do |v|
- number = v
- end
- opt.on('-l','--latex',
- 'convert ``...'' to “...” before testing') do
- latex=true
- end
- opt.on('-V','--version',
- 'print version and exit') do
- puts Version
- exit
- end
- opt.on('-h','--help',
- 'print this help and exit') do
- puts opt.to_s.sub(/^ *-I\n/,'')
- exit
- end
- opt.on('--test',
- 'do an internal test and exit') do
- input = DATA
- test = true
- end
- opt.on('-I') do system("instscript --zip --pdf --markdown #{MYNAME}"); exit; end
- opt.parse!
-end
-parenshtml = parenstext =~ /<>/ ? parenstext : parenstext + '<>'
-parens = parenstext
-
-arg = ARGV[0] || ''
-unless arg.empty?
- test(?e,arg) or raise("file #{arg} does not exist")
- test(?r,arg) or raise("file #{arg} is not readable")
- input = File.new(arg)
-end
-while x = input.gets()
- # convert LaTeX's ``...'' to “...”
- if latex
- x = x.gsub(/``/,'“').gsub(/''/,'”')
- end
-
- # only inside html text we check <>, too:
- if html && (x=~/^([# ]*=end)/ || x=~/<\/html>/i)
- html = false
- parens = parenstext
- elsif x=~/^([# ]*=begin rdoc)/ || x=~/<html>/i
- html = true
- parens = parenshtml
- end
- # match any pair like (), {}, [], “”, <> in parens
- re = Regexp.new(parens.scan(/../).join('|').gsub(/[{}()\[\]]/,'\\\\\&'))
-
- # move parens' characters into s
- s << x.tr('^'+parens,'')
- # remove matches from inside
- while s.gsub!(re,'') do end
- puts "%4d | %-*s | %s" % [lineno+=1,number,s.slice(0..number-1),x]
-end
-
-if test
- if s != '“{”}'
- raise("test failed! (final mismatch should be “{”})")
- else
- puts "test succeeded"
- end
-else
- exit s.empty? ? 0 : 1
-end
-__END__
-This first line “{()}” has no mismatch
-but here ( we have one.
-It is even extended “{() with two more.
-
-Here comes an untested angle bracket <, but here }” all) mismatches are erased.
-
-=begin rdoc
-Inside html text now. â€{There is an unmatched} single quote here.
-A brace { is added to it here,
-and an angle bracket < is added.
-But > all mismatches <are>}’ cancelled here.
-=end
-
-Four mismatches start ({"'start {here} but
-are cancelled '" here}).
-We end here with a mismatch caused by “{(improper)”} nesting!
-But the test succeeds because we expected that.
diff --git a/Build/source/texk/texlive/linked_scripts/mathspic/mathspic.pl b/Build/source/texk/texlive/linked_scripts/mathspic/mathspic.pl
deleted file mode 100755
index 5c3ed4ec1f9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/mathspic/mathspic.pl
+++ /dev/null
@@ -1,3336 +0,0 @@
-#!/usr/bin/perl
-#
-#(c) Copyright 2005-2010 VERSION 1.13 April 26, 2010
-# Apostolos Syropoulos & R.W.D. Nickalls
-# asyropoulos@yahoo.com dick@nickalls.org
-#
-# This program can be redistributed and/or modified under the terms
-# of the LaTeX Project Public License Distributed from CTAN
-# archives in directory macros/latex/base/lppl.txt; either
-# version 1 of the License, or any later version.
-#
-package DummyFH;
-my $index = 0;
-sub TIEHANDLE {
- my $class = shift;
- my $self= shift;
- bless $self, $class;
-}
-sub READLINE {
- my $self = shift;
- #shift @$self;
- if ($index > $#$self) {
- $index = 0;
- return undef;
- }
- else {
- return $self->[$index++];
- }
-}
-
-package main;
-use Math::Trig;
-our $version_number = "1.13 Apr 26, 2010";
-our $commandLineArgs = join(" ", @ARGV);
-our $command = "";
-our $curr_in_file = "";
-our %PointTable = ();
-our %VarTable = ();
-our %ConstTable = ();
-our $no_errors = 0;
-our $xunits = "1pt";
-our $yunits = "1pt";
-our $units = "pt|pc|in|bp|cm|mm|dd|cc|sp";
-our $defaultsymbol = "\$\\bullet\$";
-our $defaultLFradius = 0;
-use constant PI => atan2(1,1)*4;
-use constant R2D => 180 / PI;
-use constant D2R => PI / 180;
-our $arrowLength = 2;
-our $arrowLengthUnits = "mm";
-our $arrowAngleB = 30;
-our $arrowAngleC = 40;
-our %DimOfPoint = ();
-our $GlobalDimOfPoints = 0;
-our @Macros = ();
-our $LineThickness = 0.4;
-
- sub mpp {
- my $in_line;
- chomp($in_line = shift);
- my $LC = shift;
- my $out_line = $in_line;
- my $macro_name = "";
- my @macro_param = ();
- my $macro_code = "";
- if ($in_line =~ s/^%def\s*//) {
- if ($in_line =~ s/^(\w+)\s*//){
- $macro_name = $1;
- }
- else {
- PrintErrorMessage("No macro name has been found",$LC);
- return ""
- }
- if ($in_line =~ s/^\(\s*//) {
- # do nothing
- }
- else {
- PrintErrorMessage("No left parenthesis after macro name has been found",$LC);
- return "";
- }
- if ($in_line =~ s/^\)//) {
- # Macro has no parameters!
- }
- else {
- MACROS: while (1) {
- if ($in_line =~ s/^(\w+)\s*//) {
- push (@macro_param, $1);
- }
- else {
- PrintErrorMessage("No macro parameter name has been found",$LC);
- return "";
- }
- if ($in_line =~ s/^,\s*//) {
- next MACROS;
- }
- else {
- last MACROS;
- }
- }
- if ($in_line =~ s/^\)//) {
- # do nothing!
- }
- else {
- PrintErrorMessage("No closing parenthesis after macro parameters",$LC);
- return "";
- }
- }
- $in_line =~ s/([^%]+)(%.*)/$1/;
- $macro_code = $in_line;
- push ( @Macros , { 'macro_name' => $macro_name,
- 'macro_code' => $macro_code,
- 'macro_param' => \@macro_param });
- return $out_line;
- }
- elsif ($in_line =~ s/^%undef\s*//) {
- if ($in_line =~ s/^(\w+)//) {
- my $undef_macro = $1;
- for(my $i = $#Macros; $i >= 0; $i--) {
- if ($Macros[$i]->{'macro_name'} eq $undef_macro) {
- splice(@Macros,$i,1);
- }
- }
- }
- return $out_line;
- }
- elsif ($in_line =~ s/^\s*%//) {
- return $out_line;
- }
- else {
- my $comment = $2 if $in_line =~ s/([^%]+)(%.+)/$1/;
- EXPANSIONLOOP: while () {
- my $org_in_line = $in_line;
- for(my $i = $#Macros; $i >= 0; $i--) {
- my $macro_name = $Macros[$i]->{'macro_name'};
- if ($in_line =~ /&$macro_name\b/) { ############################
- my $num_of_macro_args = @{$Macros[$i]->{'macro_param'}};
- if ( $num_of_macro_args > 0 ) {
- # Macro with parameters
- my $pattern = "&$macro_name\\(";
- foreach my $p ( 1..$num_of_macro_args ) {
- my $comma = ($p == $num_of_macro_args) ? "\\s*" : "\\s*,\\s*";
- $pattern .= "\\s*[^\\s\\)]+$comma";
- }
- $pattern .= "\\)";
- while($in_line =~ /&$macro_name\b/) {
- if ($in_line =~ /$pattern/) {
- my $before = $`;
- my $after = $';
- my $match = $&;
- my $new_code = $Macros[$i]->{'macro_code'};
- $match =~ s/^&$macro_name\(\s*//;
- $match =~ s/\)$//;
- foreach my $arg ( 0..($num_of_macro_args - 1) ) {
- my $old = $Macros[$i]->{'macro_param'}->[$arg];
- my $comma = ($arg == ($num_of_macro_args - 1)) ? "" : ",";
- $match =~ s/^\s*([^\s,]+)\s*$comma//;
- my $new = $1;
- # 'g': Parameter may occur several times
- # in $new_code.
- # '\b': Substitute only whole words
- # not x in xA
- $new_code =~ s/\b$old\b/$new/g;
- }
- $in_line = "$before$new_code$after";
- }
- else {
- PrintErrorMessage("Usage of macro &$macro_name does not " .
- "match its definition", $LC);
- return "";
- }
- }
- }
- else {
- # Macro without parameters
- my $replacement = $Macros[$i]->{'macro_code'};
- # '\b': Substitute only whole words
- # not x in xA
- $in_line =~ s/&$macro_name\b/$replacement/g;
- }
- }
- }
- last EXPANSIONLOOP if ( $org_in_line eq $in_line );
- }
- return "$in_line$comment";
- }
- }
-
- sub PrintErrorMessage {
- my $errormessage = shift;
- my $error_line = shift;
- my ($l,$A);
- $l = 1+length($command)-length;
- $A = substr($command,0,$l);
- $l += 7 +length($error_line);
-
- for my $fh (STDOUT, LOG) {
- print $fh "$curr_in_file", "Line $error_line: $A\n";
- print $fh " " x $l ,$_,"***Error: $errormessage\n";
- }
- if ($comments_on) { #print to output file file
- print OUT "%% *** $curr_in_file", "Line $error_line: $A\n";
- print OUT "%% *** "," " x $l ,$_,"%% ... Error: $errormessage\n";
- }
- $no_errors++;
- }
-
- sub PrintWarningMessage {
- my $warningMessage = shift;
- my $warning_line = shift;
- my ($l,$A);
- $l = 1+length($command)-length;
- $A = substr($command,0,$l);
- $l += 7 +length($warning_line);
-
- for my $fh (STDOUT, LOG) {
- print $fh "$curr_in_file", "Line $warning_line: $A\n";
- print $fh " " x $l ,$_,"***Warning: $warningMessage\n";
- }
- if ($comments_on) { #print to output file file
- print OUT "%% *** $curr_in_file", "Line $warning_line: $A\n";
- print OUT "%% *** "," " x $l ,$_,"%% ... Warning: $warningMessage\n";
- }
- }
-
- sub PrintFatalError {
- my $FatalMessage = shift;
- my $fatal_line = shift;
- my ($l,$A);
- $l = 1+length($command)-length;
- $A = substr($command,0,$l);
- $l += 7 +length($fatal_line);
-
- die "$curr_in_file", "Line $fatal_line: $A\n" .
- (" " x $l) . $_ . "***Fatal Error: $FatalMessage\n";
- }
-
- sub chk_lparen {
- my $token = $_[0];
- my $lc = $_[1];
- s/\s*//;
- if (/^[^\(]/) {
- PrintErrorMessage("Missing ( after $token",$lc);
- }
- else {
- s/^\(\s*//;
- }
- }
-
- sub chk_rparen {
- my $token = $_[0];
- my $lc = $_[1];
- s/\s*//;
- if (s/^\)//) {
- s/\s*//;
- }
- else {
- PrintErrorMessage("Missing ) after $token",$lc);
- }
- }
-
-
- sub chk_lcb {
- my $token = $_[0];
- my $lc = $_[1];
- s/\s*//;
- if ($_ !~ /^\{/) {
- PrintErrorMessage("Missing { after $token",$lc);
- }
- else {
- s/^{\s*//;
- }
- }
-
- sub chk_rcb {
- my $token = $_[0];
- my $lc = $_[1];
- if ($_ !~ /^\s*\}/) {
- PrintErrorMessage("Missing } after $token",$lc);
- }
- else {
- s/^\s*}\s*//;
- }
- }
-
- sub chk_lsb {
- my $token = $_[0];
- my $lc = $_[1];
-
- s/\s*//;
- if ($_ !~ /^\[/) {
- PrintErrorMessage("Missing [ after $token",$lc);
- }
- else {
- s/^\[\s*//;
- }
- }
-
- sub chk_rsb {
- my $token = $_[0];
- my $lc = $_[1];
-
- s/\s*//;
- if ($_ !~ /^\]/) {
- PrintErrorMessage("Missing ] after $token",$lc);
- }
- else {
- s/^\]\s*//;
- }
- }
-
- sub chk_comma {
- my $lc = $_[0];
-
- s/\s*//;
- if (/^[^,]/) {
- PrintErrorMessage("Did not find expected comma",$lc);
- }
- else {
- s/^,\s*//;
- }
- }
-
- sub chk_comment {
- my $lc = $_[0];
-
- s/\s*//;
- if (/^%/) {
- # do nothing!
- }
- elsif (/^[^%]/) {
- PrintWarningMessage("Trailing text is ignored",$lc);
- }
- }
-
- sub print_headers
- {
- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
- $year+=1900;
- $mon+=1;
- $now_string = "$year/" . ($mon>9 ? "$mon/" : "0$mon/") .
- ($mday>9 ? "$mday " : "0$mday ") .
- ($hour>9 ? "$hour:" : "0$hour:") .
- ($min>9 ? "$min:" : "0$min:") .
- ($sec>9 ? "$sec" : "0$sec");
- print OUT "%* -----------------------------------------------\n";
- print OUT "%* mathspic (Perl version $version_number)\n";
- print OUT "%* A filter program for use with PiCTeX\n";
- print OUT "%* Copyright (c) 2005-2010 A Syropoulos & RWD Nickalls \n";
- print OUT "%* Command line: $0 $commandLineArgs\n";
- print OUT "%* Input filename : $source_file\n";
- print OUT "%* Output filename: $out_file\n";
- print OUT "%* Date & time: $now_string\n";
- print OUT "%* -----------------------------------------------\n";
- #
- print LOG "----\n";
- print LOG "$now_string\n";
- print LOG "mathspic (Perl version $version_number)\n";
- print LOG "Copyright (c) 2005-2010 A Syropoulos & RWD Nickalls \n";
- print LOG "Input file = $source_file\n";
- print LOG "Output file = $out_file\n";
- print LOG "Log file = $log_file\n";
- print LOG "----\n";
- }
-
- sub get_point {
-
- my ($lc) = $_[0];
- my ($PointName);
-
- if (s/^([^\W\d_]\d{0,4})\s*//i) { #point name
- $PointName = $1;
- if (!exists($PointTable{lc($PointName)})) {
- PrintErrorMessage("Undefined point $PointName",$lc);
- return "_undef_";
- }
- else {
- return lc($PointName);
- }
- }
- else {
- PrintErrorMessage("Point name expected",$lc);
- return "_undef_";
- }
- }
-
- sub perpendicular {
- my ($xP, $yP, $xA, $yA, $xB, $yB) = @_;
- my ($xF, $yF, $deltax, $deltay, $m1, $m2, $c1, $c2, $factor);
-
- $deltax = $xA - $xB;
- return ($xA, $yP) if abs($deltax) < 0.0000001;
- $deltay = $yA - $yB;
- return ($xP, $yA) if abs($deltay) < 0.0000001;
- $m1 = $deltay / $deltax;
- eval { $m2 = (-1) / $m1;};
- PrintFatalError("Division by zero",$lc) if $@;
- $c1 = $yA - $m1 * $xA;
- $c2 = $yP - $m2 * $xP;
- eval { $factor = 1 / ($m1 - $m2)};
- PrintFatalError("Division by zero",$lc) if $@;
- return (($c2 - $c1) * $factor, ($m1 * $c2 - $m2 * $c1) * $factor);
- }
-
- sub Length {
- my ($xA, $yA, $xB, $yB)=@_;
- return sqrt(($xB - $xA)**2 + ($yB - $yA)**2);
- }
-
- sub triangleArea {
- my ($xA, $yA, $xB, $yB, $xC, $yC)=@_;
- my ($lenAB, $lenBC, $lenCA, $s);
-
- $lenAB = Length($xA,$yA,$xB,$yB);
- $lenBC = Length($xB,$yB,$xC,$yC);
- $lenCA = Length($xC,$yC,$xA,$yA);
- $s = ($lenAB + $lenBC + $lenCA) / 2;
- return sqrt($s * ($s - $lenAB)*($s - $lenBC)*($s - $lenCA));
- }
-
- sub pointOnLine {
- my ($xA, $yA, $xB, $yB, $dist)=@_;
- my ($deltax, $deltay, $xPol, $yPol);
-
- $deltax = $xB - $xA;
- $deltay = $yB - $yA;
- $xPol = $xA + ($dist * $deltax / &Length($xA,$yA,$xB,$yB));
- $yPol = $yA + ($dist * $deltay / &Length($xA,$yA,$xB,$yB));
- return ($xPol, $yPol);
- }
-
-
-
- sub circumCircleCenter {
- my ($xA, $yA, $xB, $yB, $xC, $yC, $lc)=@_;
- my ($deltay12, $deltax12, $xs12, $ys12);
- my ($deltay23, $deltax23, $xs23, $ys23);
- my ($xcc, $ycc);
- my ($m23, $mr23, $c23, $m12, $mr12, $c12);
- my ($sideA, $sideB, $sideC, $a, $radius);
-
- if (abs(triangleArea($xA, $yA, $xB, $yB, $xC, $yC)) < 0.0000001)
- {
- PrintErrorMessage("Area of triangle is zero!",$lc);
- return (0,0,0);
- }
- $deltay12 = $yB - $yA;
- $deltax12 = $xB - $xA;
- $xs12 = $xA + $deltax12 / 2;
- $ys12 = $yA + $deltay12 / 2;
- #
- $deltay23 = $yC - $yB;
- $deltax23 = $xC - $xB;
- $xs23 = $xB + $deltax23 / 2;
- $ys23 = $yB + $deltay23 / 2;
- #
- CCXYLINE:{
- if (abs($deltay12) < 0.0000001)
- {
- $xcc = $xs12;
- if (abs($deltax23) < 0.0000001)
- {
- $ycc = $ys23;
- last CCXYLINE;
- }
- else
- {
- $m23 = $deltay23 / $deltax23;
- $mr23 = -1 / $m23;
- $c23 = $ys23 - $mr23 * $xs23;
- $ycc = $mr23 * $xs12 + $c23;
- last CCXYLINE;
- }
- }
- if (abs($deltax12) < 0.0000001)
- {
- $ycc = $ys12;
- if (abs($deltay23) < 0.0000001)
- {
- $xcc = $xs23;
- last CCXYLINE;
- }
- else
- {
- $m23 = $deltay23 / $deltax23;
- $mr23 = -1 / $m23;
- $c23 = $ys23 - $mr23 * $xs23;
- $xcc = ($ys12 - $c23) / $mr23;
- last CCXYLINE;
- }
- }
- if (abs($deltay23) < 0.0000001)
- {
- $xcc = $xs23;
- if (abs($deltax12) < 0.0000001)
- {
- $ycc = $ys12;
- last CCXYLINE;
- }
- else
- {
- $m12 = $deltay12 / $deltax12;
- $mr12 = -1 / $m12;
- $c12 = $ys12 - $mr12 * $xs12;
- $ycc = $mr12 * $xcc + $c12;
- last CCXYLINE;
- }
- }
- if (abs($deltax23) < 0.0000001)
- {
- $ycc = $ys23;
- if (abs($deltay12) < 0.0000001)
- {
- $xcc = $xs12;
- last CCXYLINE;
- }
- else
- {
- $m12 = $deltay12 / $deltax12;
- $mr12 = -1 / $m12;
- $c12 = $ys12 - $mr12 * $xs12;
- $xcc = ($ycc - $c12) / $mr12;
- last CCXYLINE;
- }
- }
- $m12 = $deltay12 / $deltax12;
- $mr12 = -1 / $m12;
- $c12 = $ys12 - $mr12 * $xs12;
- #-----
- $m23 = $deltay23 / $deltax23;
- $mr23 = -1 / $m23;
- $c23 = $ys23 - $mr23 * $xs23;
- $xcc = ($c23 - $c12) / ($mr12 - $mr23);
- $ycc = ($c23 * $mr12 - $c12 * $mr23) / ($mr12 - $mr23);
- }
- #
- $sideA = &Length($xA,$yA,$xB,$yB);
- $sideB = &Length($xB,$yB,$xC,$yC);
- $sideC = &Length($xC,$yC,$xA,$yA);
- $a = triangleArea($xA, $yA, $xB, $yB, $xC, $yC);
- $radius = ($sideA * $sideB * $sideC) / (4 * $a);
- #
- return ($xcc, $ycc, $radius);
- }
-
- sub ComputeDist {
- my ($lc) = $_[0];
- my ($v1, $v2);
-
- if (s/^((\+|-)?\d+(\.\d+)?([eE](\+|-)?\d+)?)//) #is it a number?
- {
- return ($1, 1);
- }
- elsif (/^[^\W\d_]\d{0,4}[^\W\d_]\d{0,4}/) #it is a pair of IDs?
- {
- s/^([^\W\d_]\d{0,4})//i;
- $v1 = $1;
- if (!exists($PointTable{lc($v1)})) {
- if (exists($VarTable{lc($v1)})) {
- return ($VarTable{lc($v1)}, 1);
- }
- PrintErrorMessage("Point $v1 has not been defined", $lc);
- s/^\s*[^\W\d_]\d{0,4}//i;
- return (0,0);
- }
- $v1 = lc($v1);
- s/^\s*([^\W\d_]\d{0,4})//i;
- $v2 = $1;
- if (!exists($PointTable{lc($v2)}))
- {
- PrintErrorMessage("Point $v2 has not been defined", $lc);
- return (0,0);
- }
- $v2 = lc($v2);
- my ($x1,$y1,$pSV1,$pS1) = unpack("d3A*",$PointTable{$v1});
- my ($x2,$y2,$pSV2,$pS2) = unpack("d3A*",$PointTable{$v2});
- return (Length($x1,$y1,$x2,$y2), 1);
- }
- elsif (s/^([^\W\d_]\d{0,4})//i) # it is a single id
- {
- $v1 = $1;
- if (!exists($VarTable{lc($v1)})) #it isn't a variable
- {
- PrintErrorMessage("Variable $v1 has not been defined", $lc);
- return (0,0);
- }
- return ($VarTable{lc($v1)}, 1);
- }
- else
- {
- PrintErrorMessage("Unexpected token", $lc);
- return (0,0);
- }
- }
-
- sub intersection4points {
- my ($x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4) = @_;
- my ($deltay12, $deltax12, $deltay34, $deltax34);
- my ($xcc, $ycc, $m34, $c34, $m12, $c12);
-
- $deltay12 = $y2 - $y1;
- $deltax12 = $x2 - $x1;
- #
- $deltay34 = $y4 - $y3;
- $deltax34 = $x4 - $x3;
- I4PXYLINE:{
- if (abs($deltay12) < 0.0000001)
- {
- $ycc = $y1;
- if (abs($deltax34) < 0.0000001)
- {
- $xcc = $x3;
- last I4PXYLINE;
- }
- else
- {
- $m34 = $deltay34 / $deltax34;
- $c34 = $y3 - $m34 * $x3;
- $xcc = ($ycc - $c34) / $m34;
- last I4PXYLINE;
- }
- }
- if (abs($deltax12) < 0.0000001)
- {
- $xcc = $x1;
- if (abs($deltay34) < 0.0000001)
- {
- $ycc = $y3;
- last I4PXYLINE;
- }
- else
- {
- $m34 = $deltay34 / $deltax34;
- $c34 = $y3 - $m34 * $x3;
- $ycc = $m34 * $xcc + $c34;
- last I4PXYLINE;
- }
- }
- if (abs($deltay34) < 0.0000001)
- {
- $ycc = $y3;
- if (abs($deltax12) < 0.0000001)
- {
- $xcc = $x1;
- last I4PXYLINE;
- }
- else
- {
- $m12 = $deltay12 / $deltax12;
- $c12 = $y1 - $m12 * $x1;
- $xcc = ($ycc - $c12) / $m12;
- last I4PXYLINE;
- }
- }
- if (abs($deltax34) < 0.0000001)
- {
- $xcc = $x3;
- if (abs($deltay12) < 0.0000001)
- {
- $ycc = $y1;
- last I4PXYLINE;
- }
- else
- {
- $m12 = $deltay12 / $deltax12;
- $c12 = $y1 - $m12 * $x1;
- $ycc = $m12 * $xcc + $c12;
- last I4PXYLINE;
- }
- }
- $m12 = $deltay12 / $deltax12;
- $c12 = $y1 - $m12 * $x1;
- $m34 = $deltay34 / $deltax34;
- $c34 = $y3 - $m34 * $x3;
- $xcc = ($c34 - $c12) / ($m12 - $m34);
- $ycc = ($c34 * $m12 - $c12 * $m34) / ($m12 - $m34);
- }
- return ($xcc, $ycc);
- }
-
- sub IncircleCenter {
- my ($Ax, $Ay, $Bx, $By, $Cx, $Cy) = @_;
- my ($sideA, $sideB, $sideC);
- my ($ba1, $xA1, $yA1, $cb1, $ac1, $xB1, $yB1, $xC1, $yC1, $a, $s, $r);
-
- #determine the lengths of the sides
- $sideA = Length($Bx, $By, $Cx, $Cy);
- $sideB = Length($Cx, $Cy, $Ax, $Ay);
- $sideC = Length($Ax, $Ay, $Bx, $By);
- #
- $ba1 = ($sideC * $sideA) / ($sideB + $sideC);
- ($xA1, $yA1) = pointOnLine($Bx, $By, $Cx, $Cy, $ba1);
- $cb1 = ($sideA * $sideB) / ($sideC + $sideA);
- ($xB1, $yB1) = pointOnLine($Cx, $Cy, $Ax, $Ay, $cb1);
- $ac1 = ($sideB * $sideC) / ($sideA + $sideB);
- ($xC1, $yC1) = pointOnLine($Ax, $Ay, $Bx, $By, $ac1);
- ($xcenter, $ycenter) = &intersection4points($Ax, $Ay, $xA1, $yA1,
- $Bx, $By, $xB1, $yB1);
- # get radius
- $a = &triangleArea($Ax, $Ay, $Bx, $By, $Cx, $Cy);
- $s = ($sideA + $sideB +$sideC) / 2;
- $r = $a / $s;
- return ($xcenter, $ycenter, $r);
- }
-
- sub Angle {
- my ($Ax, $Ay, $Bx, $By, $Cx, $Cy) = @_;
- my ($RAx, $RAy, $RBx, $RBy, $RCx, $RCy, $deltax, $deltay);
- my ($lineBA, $lineBC, $lineAC, $k, $kk, $angle);
- my ($T, $cosT, $sinT) = (0.3, cos(0.3), sin(0.3));
-
- $RAx = $Ax * $cosT + $Ay * $sinT;
- $RAy = -$Ax * $sinT + $Ay * $cosT;
- $RBx = $Bx * $cosT + $By * $sinT;
- $RBy = -$Bx * $sinT + $By * $cosT;
- $RCx = $Cx * $cosT + $Cy * $sinT;
- $RCy = -$Cx * $sinT + $Cy * $cosT;
- $deltax = $RBx - $RAx;
- $deltay = $RBy - $RAy;
- $lineBA = sqrt($deltax*$deltax + $deltay*$deltay);
- if ($lineBA < 0.0000001)
- {
- return -500;
- }
- $deltax = $RBx - $RCx;
- $deltay = $RBy - $RCy;
- $lineBC = sqrt($deltax*$deltax + $deltay*$deltay);
- if ($lineBC < 0.0000001)
- {
- return -500;
- }
- $deltax = $RAx - $RCx;
- $deltay = $RAy - $RCy;
- $lineAC = sqrt($deltax*$deltax + $deltay*$deltay);
- if ($lineAC < 0.0000001)
- {
- return -500;
- }
- $k = ($lineBA*$lineBA + $lineBC*$lineBC - $lineAC*$lineAC ) /
- (2 * $lineBA * $lineBC);
- $k = -1 if $k < -0.99999;
- $k = 1 if $k > 0.99999;
- $kk = $k * $k;
- if (($kk * $kk) == 1)
- {
- $angle = PI if $k == -1;
- $angle = 0 if $k == 1;
- }
- else
- {
- $angle = (PI / 2) - atan2($k / sqrt(1 - $kk),1);
- }
- return $angle * 180 / PI;
- }
-
- sub excircle {
- my ($A, $B, $C, $D, $E) = @_;
- my ($Ax,$Ay,$Bx,$By,$Dx,$Dy,$Ex,$Ey,$ASVA,$ASA);
- ($Ax,$Ay,$ASVA,$ASA)=unpack("d3A*",$PointTable{$A});
- ($Bx,$By,$ASVA,$ASA)=unpack("d3A*",$PointTable{$B});
- ($Cx,$Cy,$ASVA,$ASA)=unpack("d3A*",$PointTable{$C});
- ($Dx,$Dy,$ASVA,$ASA)=unpack("d3A*",$PointTable{$D});
- ($Ex,$Ey,$ASVA,$ASA)=unpack("d3A*",$PointTable{$E});
- my ($sideA, $sideB, $sideC, $s, $R, $theAdeg, $d);
- my ($Xmypoint, $Ymypoint, $deltax, $deltay, $mylength, $xc, $yc);
-
- $sideA = &Length($Bx, $By, $Cx, $Cy);
- $sideB = &Length($Cx, $Cy, $Ax, $Ay);
- $sideC = &Length($Ax, $Ay, $Bx, $By);
- $s = ($sideA + $sideB + $sideC) / 2;
- $R = triangleArea($Ax, $Ay, $Bx, $By, $Cx, $Cy) /
- ($s - &Length($Dx, $Dy, $Ex, $Ey));
- if (($D eq $A && $E eq $B) || ($D eq $B && $E eq $A))
- {
- $theAdeg = &Angle($Bx, $By, $Cx, $Cy, $Ax, $Ay);
- $Xmypoint = $Cx;
- $Ymypoint = $Cy;
- }
- elsif (($D eq $B && $E eq $C) || ($D eq $C && $E eq $B))
- {
- $theAdeg = &Angle($Cx, $Cy, $Ax, $Ay, $Bx, $By);
- $Xmypoint = $Ax;
- $Ymypoint = $Ay;
- }
- elsif (($D eq $C && $E eq $A) || ($D eq $A && $E eq $C))
- {
- $theAdeg = &Angle($Ax, $Ay, $Bx, $By, $Cx, $Cy);
- $Xmypoint = $Bx;
- $Ymypoint = $By;
- }
- else
- {
- return (0,0,0);
- }
- $d = $R / sin($theAdeg * PI / 180 / 2);
- my ($xIn, $yIn, $rin) = &IncircleCenter($Ax, $Ay, $Bx, $By, $Cx, $Cy);
- $deltax = $xIn - $Xmypoint;
- $deltay = $yIn - $Ymypoint;
- $mylength = sqrt($deltax*$deltax + $deltay*$deltay);
- $xc = $Xmypoint + $d * $deltax / $mylength;
- $yc = $Ymypoint + $d * $deltay / $mylength;
- return ($xc, $yc, $R);
- }
-
- sub DrawLineOrArrow {
- my $draw_Line = shift;
- my $lc = shift;
- my $lineLength = -1;
- my $stacklen = 0;
- my @PP = ();
- # if ($draw_Line != 2) {
- # s/\s*//;
- # if (s/^\[\s*//) { # optional length specifier
- # $lineLength = expr($lc);
- # if ($lineLength <= 0) {
- # PrintErrorMessage("length must greater than zero",$lc);
- # $lineLength = -1;
- # }
- # chk_rsb("optional part",$lc);
- # }
- # }
- chk_lparen("$cmd",$lc);
- DRAWLINES:while(1) {
- @PP = () ;
- while(1) {
- if (s/^([^\W\d_]\d{0,4})\s*//i) { #point name
- $P = $1;
- if (!exists($PointTable{lc($P)})) {
- PrintErrorMessage("Undefined point $P",$lc);
- }
- else {
- push (@PP,$P);
- }
- }
- else {
- $stacklen = @PP;
- if ($draw_Line != 2) {
- if ($stacklen <= 1) {
- PrintErrorMessage("Wrong number of points",$lc);
- }
- else {
- push(@PP,$lc);
- if ($draw_Line == 0) {
- drawarrows(@PP);
- }
- elsif ($draw_Line == 1) {
- drawlines(@PP);
- }
- }
- }
- if (s/^,\s*// and $draw_Line != 2) {
- next DRAWLINES;
- }
- else {
- last DRAWLINES;
- }
- }
- }
- }
- if ($draw_Line == 2) {
- $stacklen = @PP;
- if ($stacklen < 2) {
- PrintErrorMessage("Wrong number of points",$lc);
- }
- elsif ($stacklen % 2 == 0) {
- PrintErrorMessage("Number of points must be odd",$lc);
- }
- else {
- drawCurve(@PP);
- }
- }
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
- }
-
- sub drawarrows {
- my ($NoArgs);
- $NoArgs = @_;
- my ($lc) = $_[$NoArgs-1]; #line number is the last argument
- my ($NumberOfPoints, $p, $q, $r12, $d12);
- my ($px,$py,$pSV,$pS, $qx,$qy,$qSV,$qS);
-
- $NumberOfPoints = $NoArgs - 1;
- LOOP: for(my $i=0; $i < $NumberOfPoints - 1; $i++)
- {
- $p = $_[$i];
- $q = $_[$i+1];
- ($px,$py,$pSV,$pS) = unpack("d3A*",$PointTable{lc($p)});
- ($qx,$qy,$qSV,$qS) = unpack("d3A*",$PointTable{lc($q)});
- $pSV = $defaultLFradius if $pSV == 0;
- $qSV = $defaultLFradius if $qSV == 0;
- $r12 = $pSV + $qSV;
- $d12 = Length($px,$py,$qx,$qy);
- if ($d12 <= $r12)
- {
- if($d12 == 0)
- {
- PrintErrorMessage("points $p and $q are the same", $lc);
- next LOOP;
- }
- PrintWarningMessage("arrow $p$q not drawn: points too close or ".
- "radii too big", $lc);
- next LOOP;
- }
- ($px, $py) = pointOnLine($px, $py, $qx, $qy, $pSV) if $pSV > 0;
- ($qx, $qy) = pointOnLine($qx, $qy, $px, $py, $qSV) if $qSV > 0;
- my ($beta, $gamma);
- $beta = tan($arrowAngleB * D2R / 2);
- $gamma = 2 * tan($arrowAngleC * D2R / 2);
- printf OUT "\\arrow <%.5f%s> [%.5f,%.5f] from %.5f %.5f to %.5f %.5f\n",
- $arrowLength, $arrowLengthUnits, $beta, $gamma, $px, $py, $qx, $qy;
- }
- }
-
- sub drawlines {
- my ($NoArgs);
- $NoArgs = @_;
- my ($lc) = $_[$NoArgs-1]; #line number is the last argument
- my ($NumberOfPoints, $p, $q, $r12, $d12);
- my ($px,$py,$pSV,$pS, $qx,$qy,$qSV,$qS);
-
- $NumberOfPoints = $NoArgs - 1;
- LOOP: for(my $i=0; $i < $NumberOfPoints - 1; $i++)
- {
- $p = $_[$i];
- $q = $_[$i+1];
- ($px,$py,$pSV,$pS) = unpack("d3A*",$PointTable{lc($p)});
- ($qx,$qy,$qSV,$qS) = unpack("d3A*",$PointTable{lc($q)});
- $pSV = $defaultLFradius if $pSV == 0;
- $qSV = $defaultLFradius if $qSV == 0;
- $r12 = $pSV + $qSV;
- $d12 = Length($px,$py,$qx,$qy);
- if ($d12 <= $r12)
- {
- if($d12 == 0)
- {
- PrintErrorMessage("points $p and $q are the same", $lc);
- next LOOP;
- }
- PrintWarningMessage("line $p$q not drawn: points too close or ".
- "radii too big", $lc);
- next LOOP;
- }
- ($px, $py) = pointOnLine($px, $py, $qx, $qy, $pSV) if $pSV > 0;
- ($qx, $qy) = pointOnLine($qx, $qy, $px, $py, $qSV) if $qSV > 0;
- if ($px == $qx || $py == $qy)
- {
- printf OUT "\\putrule from %.5f %.5f to %.5f %.5f %%%% %s%s\n",
- $px,$py,$qx,$qy,$p,$q;
- }
- else
- {
- printf OUT "\\plot %.5f %.5f\t%.5f %.5f / %%%% %s%s\n",
- $px, $py,$qx,$qy,$p,$q;
- }
- }
- }
-
- sub drawCurve {
- my ($NoArgs);
- $NoArgs = @_;
- my ($lc) = $_[$NoArgs-1]; #line number is the last argument
- my ($NumberOfPoints, $p);
-
- $NumberOfPoints = $NoArgs - 1;
- print OUT "\\setquadratic\n\\plot\n";
- for(my $i=0; $i <= $NumberOfPoints; $i++)
- {
- $p = $_[$i];
- my ($px,$py,$pSV,$pS) = unpack("d3A*",$PointTable{lc($p)});
- printf OUT "\t%0.5f %0.5f", $px, $py;
- print OUT (($i == $NumberOfPoints) ? " / %$p\n" : " %$p\n");
- }
- print OUT "\\setlinear\n";
- }
-
- sub drawpoints {
- my ($NumberOfPoints,$p);
- $NumberOfPoints = @_;
- my ($px,$py,$pSV,$pS);
-
- for($i=0; $i < $NumberOfPoints; $i++)
- {
- $p = $_[$i];
- ($px,$py,$pSV,$pS) = unpack("d3A*",$PointTable{lc($p)});
- if ($pS eq "" and $defaultsymbol =~ /circle|square/) {
- $pS = $defaultsymbol;
- }
- POINTSWITCH: {
- if ($pS eq "") # no plot symbol specified
- {
- printf OUT "\\put {%s} at %.5f %.5f %%%% %s\n",
- $defaultsymbol, $px, $py, $p;
- last POINTSWITCH;
- }
- if ($pS eq "circle") # plot symbol is a circle
- {
- my $radius = (defined($DimOfPoint{lc($p)})) ? $DimOfPoint{lc($p)} :
- $GlobalDimOfPoints;
- if ($radius > 0) # draw a circle using the current units
- {
- if ($radius == 1.5) # use \bigcirc
- {
- printf OUT "\\put {\$\\bigcirc\$} at %.5f %.5f %%%% %s\n",
- $px, $py, $p;
- }
- else
- {
- printf OUT "\\circulararc 360 degrees from %.5f %.5f center at %.5f %.5f %%%% %s\n",
- $px+$radius, $py, $px, $py, $p;
- }
- }
- else #use \circ symbol
- {
- printf OUT "\\put {\$\\circ\$} at %.5f %.5f %%%% %s\n",
- $px,$py,$p;
- }
- last POINTSWITCH;
- }
- if ($pS eq "square")
- {
- my $side = (defined($DimOfPoint{lc($p)})) ? $DimOfPoint{lc($p)} :
- $GlobalDimOfPoints;
- printf OUT "\\put {%s} at %.5f %.5f %%%% %s\n",
- drawsquare($side), $px, $py, $p;
- last POINTSWITCH;
- }
- printf OUT "\\put {%s} at %.5f %.5f %%%% %s\n", $pS,$px,$py,$p;
- }
- }
- }
-
- sub drawAngleArc {
- my ($P1, $P2, $P3, $radius, $inout, $direction) = @_;
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$P1});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$P2});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$P3});
-
- my $internalAngle = Angle($x1, $y1, $x2, $y2, $x3, $y3);
- my $externalAngle = 360 - $internalAngle;
- my ($x, $y) = pointOnLine($x2, $y2, $x1, $y1, $radius);
- my $code = "";
- if ($inout eq "internal" and $direction eq "clockwise" ) {
- $code = sprintf "\\circulararc %.5f degrees from %.5f %.5f center at %.5f %.5f\n",
- -1 * $internalAngle, $x, $y, $x2, $y2;
- }
- elsif ($inout eq "internal" and $direction eq "anticlockwise" ) {
- $code = sprintf "\\circulararc %.5f degrees from %.5f %.5f center at %.5f %.5f\n",
- $internalAngle, $x, $y, $x2, $y2;
- }
- elsif ($inout eq "external" and $direction eq "clockwise" ) {
- $code = sprintf "\\circulararc %.5f degrees from %.5f %.5f center at %.5f %.5f\n",
- -1 * $externalAngle, $x, $y, $x2, $y2;
- }
- elsif ($inout eq "external" and $direction eq "anticlockwise" ) {
- $code = sprintf "\\circulararc %.5f degrees from %.5f %.5f center at %.5f %.5f\n",
- $externalAngle, $x, $y, $x2, $y2;
- }
- return $code;
- }
-
- sub drawAngleArrow {
- my ($P1, $P2, $P3, $radius, $inout, $direction) = @_;
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$P1});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$P2});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$P3});
-
- my $code = drawAngleArc($P1, $P2, $P3, $radius, $inout, $direction);
-
- my ($xqp, $yqp) = pointOnLine($x2, $y2, $x1, $y1, $radius);
- my ($deltax, $deltay) = ($x1 - $x2, $y1 - $y2);
- my $AL;
-
- if ($xunits =~ /mm/) {
- $AL = 1;
- }
- elsif ($xunits =~ /cm/) {
- $AL = 0.1;
- }
- elsif ($xunits =~ /pt/) {
- $AL = 2.845;
- }
- elsif ($xunits =~ /bp/) {
- $AL = 2.835;
- }
- elsif ($xunits =~ /pc/) {
- $AL = 0.2371;
- }
- elsif ($xunits =~ /in/) {
- $AL = 0.03937;
- }
- elsif ($xunits =~ /dd/) {
- $AL = 2.659;
- }
- elsif ($xunits =~ /cc/) {
- $AL = 0.2216;
- }
- elsif ($xunits =~ /sp/) {
- $AL = 186467.98;
- }
- my $halfAL = $AL / 2;
- my $d = sqrt($radius * $radius - $halfAL * $halfAL);
- my $alpha = atan2($d / $halfAL, 1) * R2D;
- my $beta = 2 * (90 - $alpha);
- my $thetaqr;
- if (abs($deltay) < 0.00001) {
- if ($deltax > 0 ) {$thetaqr = 0 }
- elsif ($deltax < 0) {$thetaqr = -180}
- }
- else {
- if (abs($deltax) < 0.00001) {
- $thetaqr = 90;
- }
- else {
- $thetaqr = atan2($deltay / $deltax, 1) * R2D;
- }
- }
- my ($xqr, $yqr) = pointOnLine($x2, $y2, $x3, $y3, $radius);
- $deltax = $x3 - $x2;
- $deltay = $y3 - $y2;
- $alpha = atan2(sqrt($radius * $radius - $halfAL * $halfAL) / $halfAL, 1) /
- D2R;
- $beta = 2 * (90 - $alpha);
- LINE2 : {
- if (abs($deltax) < 0.00001) {
- if ($deltay > 0) { $thetaqr = 90 }
- elsif ($deltay < 0) { $thetaqr = - 90 }
- last LINE2;
- }
- else {
- $thetaqr = atan2($deltay / $deltax, 1) * R2D;
- }
- if (abs($deltay) < 0.00001) {
- if ($deltax > 0) { $thetaqr = 0 }
- elsif ($deltax < 0) { $thetaqr = -180 }
- last LINE2;
- }
- else {
- $thetaqr = atan2($deltay / $deltax, 1) * R2D;
- }
- if ($deltax < 0 and $deltay > 0) { $thetaqr += 180 }
- elsif ($deltax < 0 and $deltay < 0) { $thetaqr += 180 }
- elsif ($deltax > 0 and $deltay < 0) { $thetaqr += 360 }
- }
- my $xqrleft = $x2 + $radius * cos(($thetaqr + $beta) * D2R);
- my $yqrleft = $y2 + $radius * sin(($thetaqr + $beta) * D2R);
- my $xqrright = $x2 + $radius * cos(($thetaqr - $beta) * D2R);
- my $yqrright = $y2 + $radius * sin(($thetaqr - $beta) * D2R);
- if ($inout eq "internal" and $direction eq "clockwise") {
- $code .= sprintf "\\arrow <1.5mm> [0.5, 1] from %.5f %.5f to %.5f %.5f\n",
- $xqrleft, $yqrleft, $xqr, $yqr;
- }
- elsif ($inout eq "internal" and $direction eq "anticlockwise") {
- $code .= sprintf "\\arrow <1.5mm> [0.5, 1] from %.5f %.5f to %.5f %.5f\n",
- $xqrright, $yqrright, $xqr, $yqr;
- }
- elsif ($inout eq "external" and $direction eq "clockwise") {
- $code .= sprintf "\\arrow <1.5mm> [0.5, 1] from %.5f %.5f to %.5f %.5f\n",
- $xqrleft, $yqrleft, $xqr, $yqr;
- }
- elsif ($inout eq "external" and $direction eq "anticlockwise") {
- $code .= sprintf "\\arrow <1.5mm> [0.5, 1] from %.5f %.5f to %.5f %.5f\n",
- $xqrright, $yqrright, $xqr, $yqr;
- }
- return $code;
- }
-
- sub expr {
- my $lc = $_[0];
- my($left,$op,$right);
-
- $left = term($lc);
- while ($op = addop()) {
- $right = term($lc);
- if ($op eq '+')
- { $left += $right }
- else
- { $left -= $right }
- }
- return $left;
- }
-
- sub addop {
- s/^([+-])// && $1;
- }
-
- sub term {
- my $lc = $_[0];
- my ($left, $op, $right);
- $left = factor($lc);
- while ($op = mulop()) {
- $right = factor($lc);
- if ($op eq '*')
- { $left *= $right }
- elsif ($op =~ /rem/i) {
- eval {$left %= $right};
- PrintFatalError("Division by zero", $lc) if $@;
- }
- else {
- eval {$left /= $right};
- PrintFatalError("Division by zero", $lc) if $@;
- }
- }
- return $left;
- }
-
- sub mulop {
- (s#^([*/])## || s/^(rem)//i) && lc($1);
- }
-
- sub factor {
- my $lc = $_[0];
- my ($left);
-
- $left = primitive($lc);
- if (s/^\*\*//) {
- $left **= factor($lc);
- }
- return $left;
- }
-
- sub primitive {
- my $lc = $_[0];
- my $val;
- s/\s*//;
- if (s/^\(//) { #is it an expr in parentheses
- $val = expr($lc);
- s/^\)// || PrintErrorMessage("Missing right parenthesis", $lc);
- }
- elsif (s/^-//) { # is it a negated primitive
- $val = - primitive();
- }
- elsif (s/^\+//) { # is it a positive primitive
- $val = primitive();
- }
- elsif (s/^angledeg//i) {
- chk_lparen("angledeg",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- my $point_3 = get_point($lc);
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point_3});
- my $d12 = Length($x1, $y1, $x2, $y2);
- my $d23 = Length($x2, $y2, $x3, $y3);
- my $d31 = Length($x3, $y3, $x1, $y1);
- if ( $d12 == 0 ) {
- PrintErrorMessage("points `$point_1' and `$point_2' are the same", $lc);
- $val = 0;
- }
- elsif ( $d23 == 0 ) {
- PrintErrorMessage("points `$point_2' and `$point_3' are the same", $lc);
- $val = 0;
- }
- elsif ( $d31 == 0 ) {
- PrintErrorMessage("points `$point_1' and `$point_3' are the same", $lc);
- $val = 0;
- }
- else {
- $val = Angle($x1, $y1, $x2, $y2, $x3, $y3);
- $val = 0 if $val == -500;
- }
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^angle//i) {
- chk_lparen("angle",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- my $point_3 = get_point($lc);
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point_3});
- my $d12 = Length($x1, $y1, $x2, $y2);
- my $d23 = Length($x2, $y2, $x3, $y3);
- my $d31 = Length($x3, $y3, $x1, $y1);
- if ( $d12 == 0 ) {
- PrintErrorMessage("points `$point_1' and `$point_2' are the same", $lc);
- $val = 0;
- }
- elsif ( $d23 == 0 ) {
- PrintErrorMessage("points `$point_2' and `$point_3' are the same", $lc);
- $val = 0;
- }
- elsif ( $d31 == 0 ) {
- PrintErrorMessage("points `$point_1' and `$point_3' are the same", $lc);
- $val = 0;
- }
- else {
- $val = Angle($x1, $y1, $x2, $y2, $x3, $y3);
- if ($val == -500) {
- $val = 0;
- }
- else {
- $val = D2R * $val;
- }
- }
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^area//i) {
- chk_lparen("angledeg",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- my $point_3 = get_point($lc);
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point_3});
- $val = triangleArea($x1, $y1, $x2, $y2, $x3, $y3);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^asin//i) {
- chk_lparen("asin");
- $val = expr();
- PrintFatalError("Can't take asin of $val", $lc) if $val < -1 || $val > 1;
- $val = asin($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^acos//i) {
- chk_lparen("acos");
- $val = expr();
- PrintFatalError("Can't take acos of $val", $lc) if $val < -1 || $val > 1 ;
- $val = acos($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^atan//i) {
- chk_lparen("atan");
- $val = expr();
- $val = atan($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^cos//i) {
- chk_lparen("cos");
- $val = expr();
- $val = cos($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^directiondeg//i) {
- chk_lparen("directiondeg",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- my $x3 = $x1+1;
- if ( ($y2 - $y1) >= 0) {
- $val = Angle($x3, $y1, $x1, $y1, $x2, $y2);
- $val = 0 if $val == -500;
- }
- else {
- $val = 360 - Angle($x3, $y1, $x1, $y1, $x2, $y2);
- $val = 0 if $val == -500;
- }
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^direction//i) {
- chk_lparen("direction",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- my $x3 = $x1+1;
- if ( ($y2 - $y1) >= 0) {
- $val = Angle($x3, $y1, $x1, $y1, $x2, $y2);
- $val = 0 if $val == -500;
- $val = D2R * $val;
- }
- else {
- $val = 360 - Angle($x3, $y1, $x1, $y1, $x2, $y2);
- $val = 0 if $val == -500;
- $val = D2R * $val;
- }
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^exp//i) {
- chk_lparen("exp");
- $val = expr();
- $val = exp($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^int//i) {
- chk_lparen("int");
- $val = expr();
- $val = int($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^log//i) {
- chk_lparen("log");
- $val = expr();
- PrintFatalError("Can't take log of $val", $lc) if $val <= 0;
- $val = log($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^sin//i) {
- chk_lparen("sin");
- $val = expr();
- $val = sin($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^sgn//i) {
- chk_lparen("sgn");
- $val = expr();
- if ($val > 0) {
- $val = 1;
- }
- elsif ($val == 0) {
- $val = 0;
- }
- else {
- $val = -1;
- }
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^sqrt//i) {
- chk_lparen("sqrt");
- $val = expr();
- $val = sqrt($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^tan//i) {
- chk_lparen("tan");
- $val = expr();
- $val = sin($val)/cos($val);
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^xcoord//i) {
- chk_lparen("xcoord");
- my $point_name = get_point;
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_name});
- $val = $x1;
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^ycoord//i) {
- chk_lparen("ycoord");
- my $point_name = get_point;
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_name});
- $val = $y1;
- chk_rparen("Missing right parenthesis", $lc);
- }
- elsif (s/^_pi_//i) {
- $val = PI;
- }
- elsif (s/^_e_//i) {
- $val = 2.71828182845905;
- }
- elsif (s/^_linethickness_//i) {
- $val = $LineThickness / $xunits;
- }
- else {
- my $err_code;
- ($val,$err_code) = ComputeDist($lc);
- }
- s/\s*//;
- return $val;
- }
-
- sub memberOf {
- my $elem = shift(@_);
-
- my $found = 0;
- foreach $item (@_){
- if ($item eq $elem){
- $found = 1;
- last;
- }
- }
- return $found;
- }
-
- sub midpoint {
- my ($x1, $y1, $x2, $y2)=@_;
- return ($x1 + ($x2 - $x1)/2,
- $y1 + ($y2 - $y1)/2);
- }
-
-
- sub tand {
- my $d = $_[0];
- $d = $d * PI / 180;
- return sin($d)/cos($d);
- }
-
- sub get_string {
- my $string = shift;
- my $lc = shift;
-
- $string =~ s/^\s+//;
- if ($string !~ s/^\"//) {
- PrintErrorMessage("No starting \" found",$lc);
- return (1,$string,$string);
- }
- my @ch = split //,$string;
- my @cmd;
- while (@ch and $ch[0] ne "\"") {
- if ($ch[0] eq "\\" and (defined $ch[1]) and $ch[1] eq "\"") {
- shift @ch;
- push @cmd, $ch[0];
- shift @ch;
- }
- else {
- push @cmd, $ch[0];
- shift @ch;
- }
- }
- if (! defined $ch[0]) {
- PrintErrorMessage("No closing \" found",$lc);
- return (1,join("",@cmd), join("",@ch))
- }
- else {
- shift @ch;
- return (0, join("",@cmd), join("",@ch))
- }
- }
-
- sub is_tainted {
- my $arg = shift;
- my $nada = substr($arg,0,0);
- local $@;
- eval { eval "# $nada"};
- return length($@) != 0;
- }
-
- sub noOfDigits {
- my $num = $_[0];
-
- if ($num =~ /^[\+-]?\d+(?!\.)/) {
- return 0;
- }
- elsif ($num =~ /^[\+-]\d+\.(\d+)?/) {
- return length($1);
- }
- }
-
- sub drawsquare {
- my $s = $_[0];
- #$s *= sqrt(2);
- $s = sprintf "%.5f", $s;
- my $code = "\\setlength{\\unitlength}{$xunits}%\n";
- $code .= "\\begin{picture}($s,$s)\\put(0,0)" .
- "{\\framebox($s,$s){}}\\end{picture}";
- return $code;
- }
-
- sub X2sp {
- my $LT = shift;
- my $units = shift;
-
- if ($units eq "pc") {
- return $LT * 786432;
- }
- elsif ($units eq "pt") {
- return $LT * 65536;
- }
- elsif ($units eq "in") {
- return $LT * 4736286.72;
- }
- elsif ($units eq "bp") {
- return $LT * 65781.76;
- }
- elsif ($units eq "cm") {
- return $LT * 1864679.811023622;
- }
- elsif ($units eq "mm") {
- return $LT * 186467.981102362;
- }
- elsif ($units eq "dd") {
- return $LT * 70124.086430424;
- }
- elsif ($units eq "cc") {
- return $LT * 841489.037165082;
- }
- elsif ($units eq "sp") {
- return $LT;
- }
- }
-
-
- sub sp2X {
- my $LT = shift;
- my $units = shift;
-
- if ($units eq "pc") {
- return $LT / 786432;
- }
- elsif ($units eq "pt") {
- return $LT / 65536;
- }
- elsif ($units eq "in") {
- return $LT / 4736286.72;
- }
- elsif ($units eq "bp") {
- return $LT / 65781.76;
- }
- elsif ($units eq "cm") {
- return $LT / 1864679.811023622;
- }
- elsif ($units eq "mm") {
- return $LT / 186467.981102362;
- }
- elsif ($units eq "dd") {
- return $LT / 70124.086430424;
- }
- elsif ($units eq "cc") {
- return $LT / 841489.037165082;
- }
- elsif ($units eq "sp") {
- return $LT;
- }
- }
-
- sub setLineThickness {
- my $Xunits = shift;
- my $LT = shift;
- $Xunits =~ s/^((\+|-)?\d+(\.\d+)?([eE](\+|-)?\d+)?)//;
- my $xlength = "$1";
- $Xunits =~ s/^\s*($units)//;
- my $x_in_units = $1;
- $LT =~ s/^((\+|-)?\d+(\.\d+)?([eE](\+|-)?\d+)?)//;
- my $LTlength = "$1";
- $LT =~ s/^\s*($units)//;
- my $LT_in_units = $1;
- $LTlength = X2sp($LTlength,$LT_in_units);
- $LTlength = sp2X($LTlength,$x_in_units);
- return $LTlength;
- }
-
- sub process_input {
- my ($INFILE,$currInFile) = @_;
- my $lc = 0;
- my $no_output = 0;
- $curr_in_file = $currInFile;
- LINE: while(<$INFILE>) {
- $lc++;
- chomp($command = $_);
- s/^\s+//;
- if (/^beginSkip\s*/i) {
- $no_output = 1;
- print OUT "%%$_" if $comments_on;
- next LINE;
- }
- elsif (/^endSkip\s*/i) {
- if ($no_output == 0) {
- PrintErrorMessage("endSkip without beginSkip",$lc);
- }
- else {
- $no_output = 0;
- }
- print OUT "%%$_" if $comments_on and !$no_output;
- next LINE;
- }
- elsif ($no_output == 1) {
- next LINE;
- }
- else {
- if (/^[^\\]/) {
- my $out_line = mpp($command,$lc) unless /^\\/; #call macro pre-processor
- $_ = "$out_line\n";
- }
-
- if (/^\s*%/)
- {
- print OUT "$_" if $comments_on;
- }
- elsif (s/^\s*(beginloop(?=\W))//i) {
- s/\s+//;
- my $times = expr($lc);
- print OUT "%% BEGINLOOP $times\n" if $comments_on;
- my @C = ();
- REPEATCOMMS: while (<$INFILE>) {
- if (/^\s*endloop/i) {
- last REPEATCOMMS;
- }
- else {
- push @C, $_;
- }
- }
- if (! /^\s*endloop/i) {
- PrintFatalError("unexpected end of file",$lc);
- }
- else {
- s/^\s*endloop//i;
- for(my $i=1; $i<=$times; $i++) {
- tie *DUMMY, 'DummyFH', \@C;
- process_input(DUMMY, $currInFile);
- untie *DUMMY;
- }
- print OUT "%% ENDLOOP\n" if $comments_on;
- }
- }
- elsif (s/^\s*(ArrowShape(?=\W))//i)
- {
- my $cmd = $1;
- print OUT "%% $cmd$_" if $comments_on;
-
- chk_lparen("$cmd",$lc);
- if (s/^default//i) {
- $arrowLength = 2;
- $arrowLengthUnits = "mm";
- $arrowAngleB = 30;
- $arrowAngleC = 40;
- }
- else {
- my ($LocalArrowLength, $LocalArrowAngleB ,$LocalArrowAngleC) = (0,0,0);
- $LocalArrowLength = expr($lc);
- if (s/^\s*($units)//i) {
- $arrowLengthUnits = "$1";
- }
- else {
- $xunits =~ /(\d+(\.\d+)?)\s*($units)/;
- $LocalArrowLength *= $1;
- $arrowLengthUnits = "$3";
- }
- chk_comma($lc);
- $LocalArrowAngleB = expr($lc);
- chk_comma($lc);
- $LocalArrowAngleC = expr($lc);
- $arrowLength = ($LocalArrowLength == 0 ? 2 : $LocalArrowLength);
- $arrowLengthUnits = ($LocalArrowLength == 0 ? "mm" : $arrowLengthUnits);
- $arrowAngleB = ($LocalArrowAngleB == 0 ? 30 : $LocalArrowAngleB);
- $arrowAngleC = ($LocalArrowAngleC == 0 ? 40 : $LocalArrowAngleC);
- }
- chk_rparen("after $cmd arguments",$lc);
- chk_comment("after $cmd command",$lc);
- print OUT "%% arrowLength = $arrowLength$arrowLengthUnits, ",
- "arrowAngleB = $arrowAngleB ",
- "and arrowAngleC = $arrowAngleC\n" if $comments_on;
-
- }
- elsif (s/^\s*(const(?=\W))//i)
- {
- print OUT "%% $1$_" if $comments_on;
- do{
- s/\s*//;
- PrintErrorMessage("no identifier found after token const",$lc)
- if $_ !~ s/^([^\W\d_]\d{0,4})//i;
- my $Constname = $1;
- my $constname = lc($Constname);
- if (exists $ConstTable{$constname}) {
- PrintErrorMessage("Redefinition of constant $constname",$lc);
- }
- s/\s*//; #remove leading white space
- PrintErrorMessage("did not find expected = sign",$lc)
- if $_ !~ s/^[=]//i;
- my $val = expr($lc);
- $VarTable{$constname} = $val;
- $ConstTable{$constname} = 1;
- print OUT "%% $Constname = $val\n" if $comments_on;
- }while (s/^,//);
- chk_comment($lc);
- s/\s*//;
- if (/^[^%]/) {
- PrintWarningMessage("Trailing text is ignored",$lc);
- }
-
- }
- elsif (s/^\s*(dasharray(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lparen($cmd,$lc);
- my @DashArray = ();
- my $dash = "";
- my $dashpattern = "";
- PATTERN: while (1) {
- $dash = sprintf("%.5f", expr($lc));
- if (s/^\s*($units)//i) {
- push (@DashArray, "$dash$1");
- }
- else {
- PrintErrorMessage("Did not found unit after expression", $lc);
- }
- s/\s*//;
- if (/^[^,]/) {
- last PATTERN;
- }
- else {
- s/^,\s*//;
- }
- }
- print OUT "\\setdashpattern <";
- while (@DashArray) {
- $dashpattern .= shift @DashArray;
- $dashpattern .= ",";
- }
- $dashpattern =~ s/,$//;
- print OUT $dashpattern, ">\n";
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
-
- }
- elsif (s/^\s*(drawAngleArc(?=\W))//i or s/^\s*(drawAngleArrow(?=\W))//i )
- {
- my $cmd = $1;
- print OUT "%% $cmd$_" if $comments_on;
-
- chk_lcb($cmd,$lc);
- my ($P1, $P2, $P3);
- if (s/^angle(?=\W)//i) {
- chk_lparen("token angle of command $cmd",$lc);
- $P1 = get_point($lc);
- next LINE if $P1 eq "_undef_";
- $P2 = get_point($lc);
- next LINE if $P2 eq "_undef_";
- $P3 = get_point($lc);
- next LINE if $P3 eq "_undef_";
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$P1});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$P2});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$P3});
- my $Angle = Angle($x1, $y1, $x2, $y2, $x3, $y3);
- if ($Angle <= 0) {
- if ($Angle == 0) {
- PrintErrorMessage("Angle is equal to zero",$lc);
- next LINE;
- }
- elsif ($Angle < -400) {
- PrintErrorMessage("Something is wrong with the points",$lc);
- next LINE;
- }
- }
- chk_rparen("angle part of command $cmd",$lc);
- }
- else {
- PrintErrorMessage("Did not find expected angle part",$lc);
- next LINE;
- }
-
- s/^,\s*// or s/\s*//; #parse optional comma
-
- my $radius;
- if (s/^radius(?=\W)//i) {
- chk_lparen("token radius of command $cmd",$lc);
- $radius = expr($lc);
- chk_rparen("radius part of command $cmd",$lc);
- }
- else {
- PrintErrorMessage("Did not found expected angle part",$lc);
- next LINE;
- }
-
- s/^,\s*// or s/\s*//; #parse optional comma
- my $inout = "";
- if (s/^(internal(?=\W))//i or s/^(external(?=\W))//i) {
- $inout = $1;
- }
- else {
- PrintErrorMessage("Did not find expected 'internal' specifier", $lc);
- next LINE;
- }
- s/^,\s*// or s/\s*//; #parse optional comma
- my $direction = "";
- if (s/^(clockwise(?=\W))//i or s/^(anticlockwise(?=\W))//i) {
- $direction = $1;
- }
- else {
- PrintErrorMessage("Did not find expected 'direction' specifier", $lc);
- next LINE;
- }
- chk_rcb("arguments of $cmd",$lc);
- chk_comment($lc);
- my $code;
- if (lc($cmd) eq "drawanglearc") {
- $code = drawAngleArc($P1, $P2, $P3, $radius, $inout, $direction);
- }
- else {
- $code = drawAngleArrow($P1, $P2, $P3, $radius, $inout, $direction);
- }
- print OUT $code if $code ne "";
-
- }
- elsif (s/^\s*(drawArrow(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- DrawLineOrArrow(0,$lc);
- }
- elsif (s/^\s*(drawcircle(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lparen("drawcircle",$lc);
- my $Point = get_point($lc);
- next LINE if $Point eq "_undef_";
- chk_comma($lc);
- my $R = expr($lc);
- if ($R <= 0) {
- PrintErrorMessage("Radius must be greater than zero",$lc);
- next LINE;
- }
- my ($x,$y,$pSV,$pS)=unpack("d3A*",$PointTable{lc($Point)});
- printf OUT "\\circulararc 360 degrees from %.5f %.5f center at %.5f %.5f\n",
- $x+$R, $y, $x, $y;
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
-
- }
- elsif (s/^\s*(drawcurve(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- DrawLineOrArrow(2,$lc);
- }
- elsif (s/^\s*(drawcircumcircle(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lparen("drawcircumcircle",$lc);
- my $point1 = get_point($lc);
- next LINE if $point1 eq "_undef_";
- my $point2 = get_point($lc);
- next LINE if $point2 eq "_undef_";
- my $point3 = get_point($lc);
- next LINE if $point3 eq "_undef_";
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point1});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point2});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point3});
- my ($xc, $yc,$r) = circumCircleCenter($x1,$y1,$x2,$y2,$x3,$y3,$lc);
- next LINE if $xc == 0 and $yc == 0 and $r == 0;
- print OUT "%% circumcircle center = ($xc,$yc), radius = $r\n" if $comments_on;
- printf OUT "\\circulararc 360 degrees from %.5f %.5f center at %.5f %.5f\n",
- $xc+$r, $yc, $xc, $yc;
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
-
- }
- elsif (s/^\s*(drawexcircle(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lparen("drawexcircle",$lc);
- my $point1 = get_point($lc);
- next LINE if $point1 eq "_undef_";
- my $point2 = get_point($lc);
- next LINE if $point2 eq "_undef_";
- my $point3 = get_point($lc);
- next LINE if $point3 eq "_undef_";
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point1});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point2});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point3});
- if (triangleArea($x1, $y1, $x2, $y2, $x3, $y3) < 0.0001) {
- PrintErrorMessage("Area of triangle is zero!",$lc);
- next LINE;
- }
- chk_comma($lc);
- my $point4 = get_point($lc);
- if (!memberOf($point4, $point1, $point2, $point3)) {
- PrintErrorMessage("Current point isn't a side point",$lc);
- next LINE;
- }
- next LINE if $point4 eq "_undef_";
- my $point5 = get_point($lc);
- next LINE if $point5 eq "_undef_";
- if (!memberOf($point5, $point1, $point2, $point3)) {
- PrintErrorMessage("Current point isn't a side point",$lc);
- next LINE;
- }
- if ($point4 eq $point5) {
- PrintErrorMessage("Side points are identical",$lc);
- next LINE;
- }
- chk_rparen("arguments of $cmd",$lc);
- my ($xc, $yc, $r) = excircle($point1, $point2, $point3,
- $point4, $point5);
- my $R=$r;
- if (s/^\s*\[\s*//) {
- $R += expr($lc);
- if ($R < 0.0001) {
- PrintErrorMessage("Radius has become equal to zero!",$lc);
- next LINE;
- }
- chk_rsb($lc);
- }
- if ($R > (500 / 2.845)) {
- PrintErrorMessage("Radius is greater than 175mm!",$lc);
- next LINE;
- }
- print OUT "%% excircle center = ($xc,$yc) radius = $R\n" if $comments_on;
- printf OUT "\\circulararc 360 degrees from %.5f %.5f center at %.5f %.5f\n",
- $xc+$R, $yc, $xc, $yc;
- chk_comment($lc);
-
- }
- elsif (s/^\s*(drawincircle(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lparen("drawincircle",$lc);
- my $point1 = get_point($lc);
- next LINE if $point1 eq "_undef_";
- my $point2 = get_point($lc);
- next LINE if $point2 eq "_undef_";
- my $point3 = get_point($lc);
- next LINE if $point3 eq "_undef_";
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point1});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point2});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point3});
- if (triangleArea($x1, $y1, $x2, $y2, $x3, $y3) < 0.0001) {
- PrintErrorMessage("Area of triangle is zero!",$lc);
- next LINE;
- }
- my ($xc, $yc, $r) = IncircleCenter($x1,$y1,$x2,$y2,$x3,$y3);
- my $R=$r;
- if (s/^\s*\[\s*//) {
- $R += expr($lc);
- if ($R < 0.0001) {
- PrintErrorMessage("Radius has become equal to zero!",$lc);
- next LINE;
- }
- chk_rsb($lc);
- }
- if ($R > (500 / 2.845)) {
- PrintErrorMessage("Radius is greater than 175mm!",$lc);
- next LINE;
- }
- print OUT "%% incircle center = ($xc,$yc) radius = $R\n" if $comments_on;
- printf OUT "\\circulararc 360 degrees from %.5f %.5f center at %.5f %.5f\n",
- $xc+$R, $yc, $xc, $yc;
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
-
- }
- elsif (s/^\s*(drawline(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- DrawLineOrArrow(1,$lc);
- }
- elsif (s/^\s*(drawthickarrow(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- print OUT "\\setplotsymbol ({\\usefont{OT1}{cmr}{m}{n}\\large .})%\n";
- print OUT "{\\setbox1=\\hbox{\\usefont{OT1}{cmr}{m}{n}\\large .}%\n";
- print OUT " \\global\\linethickness=0.31\\wd1}%\n";
- DrawLineOrArrow(0,$lc);
- print OUT "\\setlength{\\linethickness}{0.4pt}%\n";
- print OUT "\\setplotsymbol ({\\usefont{OT1}{cmr}{m}{n}\\tiny .})%\n";
- }
- elsif (s/^\s*(drawthickline(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- print OUT "\\setplotsymbol ({\\usefont{OT1}{cmr}{m}{n}\\large .})%\n";
- print OUT "{\\setbox1=\\hbox{\\usefont{OT1}{cmr}{m}{n}\\large .}%\n";
- print OUT " \\global\\linethickness=0.31\\wd1}%\n";
- DrawLineOrArrow(1,$lc);
- print OUT "\\setlength{\\linethickness}{0.4pt}%\n";
- print OUT "\\setplotsymbol ({\\usefont{OT1}{cmr}{m}{n}\\tiny .})%\n";
- }
- elsif (s/^\s*(drawperpendicular(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
-
- chk_lparen($cmd,$lc);
- my $A = get_point($lc);
- next LINE if $A eq "_undef_";
- chk_comma($lc);
- my $B = get_point($lc);
- next LINE if $A eq "_undef_";
- s/\s*//; #ignore white space
- my $C = get_point($lc);
- next LINE if $A eq "_undef_";
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
- #
- #start actual computation
- #
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$A});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$B});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$C});
- my ($xF, $yF) = perpendicular($x1, $y1, $x2, $y2, $x3, $y3);
- printf OUT "\\plot %.5f %.5f %.5f %.5f /\n",
- $x1, $y1, $xF, $yF;
-
- }
- elsif (s/^\s*(drawpoint(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- my ($stacklen);
- chk_lparen("$cmd",$lc);
- if (/^\)/) {
- PrintErrorMessage("There are no point to draw",$lc);
- next LINE;
- }
- my(@PP);
- DRAWPOINTS:while(1) {
- if (s/^([^\W\d_]\d{0,4})//i) { #point name
- $P = $1;
- if (!exists($PointTable{lc($P)})) {
- PrintErrorMessage("Undefined point $P",$lc);
- next DRAWPOINTS;
- }
- else {
- push (@PP,$P);
- s/\s*//;
- }
- }
- else {
- last DRAWPOINTS;
- }
- }
- drawpoints(@PP);
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
-
- }
- elsif (s/^\s*(drawRightAngle(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
-
- chk_lparen("drawRightAngle",$lc);
- my $point1 = get_point($lc);
- next LINE if $point1 eq "_undef_";
- my $point2 = get_point($lc);
- next LINE if $point2 eq "_undef_";
- my $point3 = get_point($lc);
- next LINE if $point3 eq "_undef_";
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point1});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point2});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point3});
- chk_comma($lc);
- my $dist = expr($lc);
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
- #
- #actual computation
- #
- my ($Px, $Py) = pointOnLine($x2, $y2, $x1, $y1, $dist);
- my ($Qx, $Qy) = pointOnLine($x2, $y2, $x3, $y3, $dist);
- my ($Tx, $Ty) = midpoint($Px, $Py, $Qx, $Qy);
- my ($Ux, $Uy) = pointOnLine($x2, $y2, $Tx, $Ty, 2*Length($x2, $y2, $Tx, $Ty));
- if ($Px == $Ux || $Py == $Uy) {
- printf OUT "\\putrule from %.5f %.5f to %.5f %.5f \n", $Px,$Py,$Ux,$Uy;
- }
- else {
- printf OUT "\\plot %.5f %.5f\t%.5f %.5f / \n", $Px, $Py,$Ux,$Uy;
- }
- if ($Ux == $Qx || $Uy == $Qy) {
- printf OUT "\\putrule from %.5f %.5f to %.5f %.5f \n", $Ux,$Uy,$Qx,$Qy;
- }
- else {
- printf OUT "\\plot %.5f %.5f\t%.5f %.5f / \n", $Ux, $Uy,$Qx,$Qy;
- }
-
-
- }
- elsif (s/^\s*(drawsquare(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lparen("drawSquare",$lc);
- my $p = get_point($lc);
- chk_comma($lc);
- my $side = expr($lc);
- $side = $side - (1.1 * $LineThickness/$xunits); #Suggested by RWDN
- my ($x,$y,$pSV,$pS) = unpack("d3A*",$PointTable{$p});
- printf OUT "\\put {%s} at %.5f %.5f %%drawsquare\n", drawsquare($side), $x, $y;
- chk_rparen("arguments of $cmd",$lc);
- chk_comment($lc);
-
- }
- elsif (s/^\s*inputfile\*//i)
- {
- chk_lparen("inputfile*",$lc);
- my $row_in = "";
- if (s/^((\w|-|\.)+)//) {
- $row_in = $1;
- }
- else {
- PrintErrorMessage("No input file name found",$lc);
- next LINE;
- }
- if (!(-e $row_in)) {
- PrintErrorMessage("File $row_in does not exist",$lc);
- next LINE;
- }
- open(ROW, "$row_in")|| die "Can't open file $row_in\n";
- while (defined($in_line=<ROW>)) { print OUT $in_line; }
- print OUT "%% ... end of input file <$row_in>\n";
- close ROW;
- chk_rparen("input file name",$lc);
- chk_comment($lc);
-
-
- }
- elsif (s/^\s*(inputfile(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
-
- chk_lparen("inputfile",$lc);
- my $comm_in = "";
- if (s/^((\w|-|\.)+)//) {
- $comm_in = $1;
- }
- else {
- PrintErrorMessage("No input file name found",$lc);
- next LINE;
- }
- if (!(-e $comm_in)) {
- PrintErrorMessage("File $comm_in does not exist",$lc);
- next LINE;
- }
- chk_rparen("input file name",$lc);
- my $input_times = 1; #default value
- if (s/^\[//) {
- $input_times = expr($lc);
- chk_rsb("optional argument",$lc);
- }
- print OUT "%% ... start of file <$comm_in> loop [$input_times]\n";
- for (my $i=0; $i<int($input_times); $i++) {
- open(COMM,"$comm_in") or die "Can't open file $comm_in\n";
- print OUT "%%% Iteration number: ",$i+1,"\n";
- my $old_file_name = $curr_in_file;
- process_input(COMM,"File $comm_in, ");
- $curr_in_file = $old_file_name;
- close COMM;
- }
- print OUT "%% ... end of file <$comm_in> loop [$input_times]\n";
- chk_comment($lc);
-
- }
- elsif (s/^\s*(linethickness(?=\W))//i)
- {
- my $cmd = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lparen("linethickness", $lc);
- if (s/^default//i) {
- print OUT "\\linethickness=0.4pt\\Linethickness{0.4pt}%%\n";
- print OUT "\\setplotsymbol ({\\usefont{OT1}{cmr}{m}{n}\\tiny .})%\n";
- $LineThickness = setLineThickness($xunits,"0.4pt");
- }
- else {
- my $length = expr($lc);
- if (s/^\s*($units)//i) {
- my $units = $1;
- printf OUT "\\linethickness=%.5f%s\\Linethickness{%.5f%s}%%\n",
- $length, $units, $length, $units;
- $LineThickness = setLineThickness($xunits,"$length$units");
- my $mag;
- if ($units eq "pc") {
- $mag = $length * 12;
- }
- elsif ($units eq "in") {
- $mag = $length * 72.27;
- }
- elsif ($units eq "bp") {
- $mag = $length * 1.00375;
- }
- elsif ($units eq "cm") {
- $mag = $length * 28.45275;
- }
- elsif ($units eq "mm") {
- $mag = $length * 2.845275;
- }
- elsif ($units eq "dd") {
- $mag = $length * 1.07001;
- }
- elsif ($units eq "cc") {
- $mag = $length * 0.08917;
- }
- elsif ($units eq "sp") {
- $mag = $length * 0.000015259;
- }
- elsif ($units eq "pt") {
- $mag = $length;
- }
- $mag = 10 * $mag / 1.00278219;
- printf OUT "\\font\\CM=cmr10 at %.5fpt%%\n", $mag;
- print OUT "\\setplotsymbol ({\\CM .})%\n";
- }
- else {
- PrintErrorMessage("Did not found expect units part",$lc);
- }
- }
- chk_rparen("linethickness", $lc);
- chk_comment($lc);
-
-
- }
- elsif (s/^\s*(paper(?=\W))//i)
- {
- my ($cmd) = $1;
- print OUT "%% $cmd$_" if $comments_on;
- chk_lcb("paper", $lc);
- if (s/^units(?=\W)//i)
- {
-
- chk_lparen("units",$lc);
- if(s/^\)//)
- {
- PrintWarningMessage("Missing value in \"units\"--default is 1pt",
- $lc);
- $xunits = "1pt";
- }
- else {
- $xunits = expr($lc);
- s/\s*//;
- if (s/^($units)//i) {
- $xunits .= "$1";
- $LineThickness = setLineThickness($xunits,"0.4pt");
- }
- elsif(s/^(\w)+//i) {
- PrintErrorMessage("$1 is not a valid mathspic unit",$lc);
- $xunits = "1pt";
- }
- else {
- PrintErrorMessage("No x-units found",$lc);
- $xunits = "1pt";
- }
- s/\s*//; #ignore white space
- if (s/^,//) { # there is a comma so expect an y-units
- s/\s*//; #ignore white space
- $yunits = expr($lc);
- s/\s*//; #ignore white space
- if (s/^($units)//i) {
- $yunits .= "$1";
- }
- elsif(s/^(\w)+//i) {
- PrintErrorMessage("$1 is not a valid mathspic unit",$lc);
- $yunits = "1pt";
- }
- else {
- PrintErrorMessage("No y-units found",$lc);
- $yunits = $xunits;
- }
- }
- else {
- $yunits = $xunits;
- }
- chk_rparen("units",$lc);
- }
-
- $nounits = 0;
- }
- else
- {
- $nounits = 1;
- }
- s/^,\s*// or s/\s*//;
- if (s/^xrange//i)
- {
-
- chk_lparen("xrange",$lc);
- my $ec;
- ($xlow,$ec) = ComputeDist($lc);
- next LINE if $ec == 0;
- chk_comma($lc);
- ($xhigh,$ec) = ComputeDist($lc);
- next LINE if $ec == 0;
- if ($xlow >= $xhigh)
- {
- PrintErrorMessage("xlow >= xhigh in xrange",$lc);
- next LINE;
- }
- chk_rparen("$xhigh",$lc);
-
- $noxrange = 0;
- }
- else
- {
- $noxrange = 1;
- }
- s/^,\s*// or s/\s*//;
- if (s/^yrange//i)
- {
-
- chk_lparen("yrange",$lc);
- my $ec;
- ($ylow,$ec) = ComputeDist($lc);
- next LINE if $ec == 0;
- chk_comma($lc);
- ($yhigh,$ec) = ComputeDist($lc);
- next LINE if $ec == 0;
- if ($ylow >= $yhigh)
- {
- PrintErrorMessage("ylow >= yhigh in yrange",$lc);
- next LINE;
- }
- chk_rparen("$yhigh",$lc);
-
- $noyrange = 0;
- }
- else
- {
- $noyrange = 1;
- }
-
- if (!$nounits)
- {
- printf OUT "\\setcoordinatesystem units <%s,%s>\n",
- $xunits,$yunits;
- }
- if(!$noxrange && !$noyrange)
- {
- printf OUT "\\setplotarea x from %.5f to %.5f, y from %.5f to %.5f\n",
- $xlow, $xhigh, $ylow, $yhigh;
-
- }
-
- s/^,\s*// or s/\s*//;
- $axis = "";
- if (s/^ax[ei]s(?=\W)//i)
- {
-
- chk_lparen("axis",$lc);
- while(/^[^\)]/)
- {
- if (s/^([lrtbxy]{1}\*?)//i)
- {
- $axis .= $1;
- }
- elsif (s/^([^lrtbxy])//i)
- {
- PrintErrorMessage("Non-valid character \"$1\" in axis()",$lc);
- }
- s/\s*//;
- }
- chk_rparen("axis(arguments",$lc);
-
- }
- $axis = uc($axis);
- s/^,\s*// or s/\s*//;
- if (s/^ticks(?=\W)//i)
- {
- chk_lparen("ticks",$lc);
- my $ec;
- ($xticks,$ec) = ComputeDist($lc);
- next LINE if $ec == 0;
- chk_comma($lc);
- ($yticks,$ec) = ComputeDist($lc);
- next LINE if $ec == 0;
- chk_rparen("ticks(arguments",$lc);
-
- }
- else
- {
- $xticks = $yticks = 0;
- }
- chk_rcb("paper", $lc);
- YBRANCH: {
- if (index($axis, "Y")>-1)
- {
- if (index($axis, "Y*")>-1)
- {
- print OUT "\\axis left shiftedto x=0 / \n";
- last YBRANCH;
- }
- if ($yticks > 0)
- {
- if (index($axis, "T")>-1 && index($axis, "B")==-1)
- {
- print OUT "\\axis left shiftedto x=0 ticks numbered from ";
- print OUT "$ylow to -$yticks by $yticks\n from $yticks to ";
- print OUT $yhigh-$yticks," by $yticks /\n";
- }
- elsif (index($axis, "T")==-1 && index($axis, "B")>-1)
- {
- print OUT "\\axis left shiftedto x=0 ticks numbered from ";
- print OUT $ylow+$yticks," to -$yticks by $yticks\n from ";
- print OUT "$yticks to $yhigh by $yticks /\n";
- }
- elsif (index($axis, "T")>-1 && index($axis, "B")>-1)
- {
- print OUT "\\axis left shiftedto x=0 ticks numbered from ";
- print OUT $ylow+$yticks," to -$yticks by $yticks\n from ";
- print OUT "$yticks to ",$yhigh-$yticks," by $yticks /\n";
- }
- else
- {
- print OUT "\\axis left shiftedto x=0 ticks numbered from ";
- print OUT "$ylow to -$yticks by $yticks\n from ";
- print OUT "$yticks to $yhigh by $yticks /\n";
- }
- }
- else
- {
- print OUT "\\axis left shiftedto x=0 /\n";
- }
- }
- }
- XBRANCH: { if (index($axis, "X")>-1)
- {
- if (index($axis, "X*")>-1)
- {
- print OUT "\\axis bottom shiftedto y=0 /\n";
- last XBRANCH;
- }
- if ($xticks > 0)
- {
- if (index($axis, "L")>-1 && index($axis, "R")==1)
- {
- print OUT "\\axis bottom shiftedto y=0 ticks numbered from ";
- print OUT $xlow + $xticks," to -$xticks by $xticks\n from";
- print OUT " $xticks to $xhigh by $xticks /\n";
- }
- elsif (index($axis, "L")==-1 && index($axis, "R")>-1)
- {
- print OUT "\\axis bottom shiftedto y=0 ticks numbered from ";
- print OUT "$xlow to -$xticks by $xticks\n from ";
- print OUT "$xticks to ",$xhigh-$xticks," by $xticks /\n";
- }
- elsif (index($axis, "L")>-1 && index($axis, "R")>-1)
- {
- print OUT "\\axis bottom shiftedto y=0 ticks numbered from ";
- print OUT $xlow + $xticks," to -$xticks by $xticks\n from ";
- print OUT "$xticks to ",$xhigh - $xticks," by $xticks /\n";
- }
- else
- {
- print OUT "\\axis bottom shiftedto y=0 ticks numbered from ";
- print OUT "$xlow to -$xticks by $xticks\n from ";
- print OUT "$xticks to $xhigh by $xticks /\n";
- }
- }
- else
- {
- print OUT "\\axis bottom shiftedto y=0 /\n";
- }
- } }
- LBRANCH: {if (index($axis, "L")>-1)
- {
- if (index($axis, "L")>-1)
- {
- if (index($axis, "L*")>-1)
- {
- print OUT "\\axis left /\n";
- last LBRANCH;
- }
- if ($yticks > 0)
- {
- print OUT "\\axis left ticks numbered from ";
- print OUT "$ylow to $yhigh by $yticks /\n";
- }
- else
- {
- print OUT "\\axis left /\n";
- }
- }
- } }
- RBRANCH: { if (index($axis, "R")>-1)
- {
- if (index($axis, "R*")>-1)
- {
- print OUT "\\axis right /\n";
- last RBRANCH;
- }
- if ($yticks > 0)
- {
- print OUT "\\axis right ticks numbered from $ylow to $yhigh by ";
- print OUT "$yticks /\n";
- }
- else
- {
- print OUT "\\axis right /\n";
- }
- } }
- TBRANCH: { if (index($axis, "T")>-1)
- {
- if (index($axis, "T*")>-1)
- {
- print OUT "\\axis top /\n";
- last TBRANCH;
- }
- if ($xticks > 0)
- {
- print OUT "\\axis top ticks numbered from $xlow to $xhigh by ";
- print OUT "$xticks /\n";
- }
- else
- {
- print OUT "\\axis top /\n";
- }
- } }
- BBRANCH: { if (index($axis, "B")>-1)
- {
- if (index($axis, "B*")>-1)
- {
- print OUT "\\axis bottom /\n";
- last BBRANCH;
- }
- if ($xticks > 0)
- {
- print OUT "\\axis bottom ticks numbered from $xlow to $xhigh by ";
- print OUT "$xticks /\n";
- }
- else
- {
- print OUT "\\axis bottom /\n";
- }
- } }
-
-
- chk_comment($lc);
-
- }
- elsif (s/^\s*(PointSymbol(?=\W))//i)
- {
- my $cmd = $1;
- print OUT "%% $cmd$_" if $comments_on;
-
- chk_lparen("$cmd",$lc);
- if (s/^default//i) #default point symbol
- {
- $defaultsymbol = "\$\\bullet\$";
- }
- elsif (s/^(circle|square)//i) {
- $defaultsymbol = $1;
- chk_lparen($defaultsymbol, $lc);
- $GlobalDimOfPoints = expr($lc);
- chk_rparen("expression", $lc);
- }
- elsif (s/^(((\\,){1}|(\\\)){1}|(\\\s){1}|[^\),\s])+)//) #arbitrary LaTeX point
- {
- $defaultsymbol = $1;
- $defaultsymbol=~ s/\\\)/\)/g;
- $defaultsymbol=~ s/\\,/,/g;
- $defaultsymbol=~ s/\\ / /g;
- }
- else
- {
- PrintErrorMessage("unrecognized point symbol",$lc);
- }
- if (s/\s*,\s*//) {
- $defaultLFradius = expr($lc);
- }
- chk_rparen("after $cmd arguments",$lc);
- chk_comment("after $cmd command",$lc);
-
- }
- elsif (s/^\s*point(?=\W)//i)
- {
- my ($Point_Line);
- chomp($Point_Line=$_);
- my ($pointStar, $PointName, $origPN);
- $pointStar = 0; # default value: he have a point command
- $pointStar = 1 if s/^\*//;
- chk_lparen("point" . (($pointStar)?"*":""),$lc);
- if (s/^([^\W\d_](?![^\W\d_])\d{0,4})//i) {
- #
- # Note: the regular expression (foo)(?!bar) means that we are
- # looking a foo not followed by a bar. Moreover, the regular
- # expression [^\W\d_] means that we are looking for letter.
- #
- $origPN = $1;
- $PointName = lc($1);
- }
- else {
- PrintErrorMessage("Invalid point name",$lc);
- next LINE;
- }
- #if ($pointStar and !exists($PointTable{$PointName})) {
- # PrintWarningMessage("Point $origPN has not been defined",$lc);
- #}
- if (!$pointStar and exists($PointTable{$PointName})) {
- PrintWarningMessage("Point $origPN has been used already",$lc);
- }
- chk_rparen("point" . (($pointStar)?"*":""). "($origPN",$lc);
- chk_lcb("point" . (($pointStar)?"*":""). "($origPN)",$lc);
- my ($Px, $Py);
- if (s/^perpendicular(?=\W)//i) {
- chk_lparen("perpendicular",$lc);
- my $FirstPoint = &get_point($lc);
- next LINE if $FirstPoint eq "_undef_";
- chk_comma($lc);
- my $SecondPoint = &get_point($lc);
- next LINE if $SecondPoint eq "_undef_";
- my $ThirdPoint = &get_point($lc);
- next LINE if $ThirdPoint eq "_undef_";
- chk_rparen("No closing parenthesis found",$lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$FirstPoint});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$SecondPoint});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$ThirdPoint});
- ($Px, $Py) = perpendicular($x1,$y1,$x2,$y2,$x3,$y3);
-
- }
- elsif (s/^intersection(?=\W)//i) {
- chk_lparen("intersection",$lc);
- my $FirstPoint = get_point($lc);
- next LINE if $FirstPoint eq "_undef_";
- my $SecondPoint = get_point($lc);
- next LINE if $SecondPoint eq "_undef_";
- chk_comma($lc);
- my $ThirdPoint = get_point($lc);
- next LINE if $ThirdPoint eq "_undef_";
- my $ForthPoint = get_point($lc);
- next LINE if $ForthPoint eq "_undef_";
- chk_rparen("No closing parenthesis found",$lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$FirstPoint});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$SecondPoint});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$ThirdPoint});
- my ($x4,$y4,$pSV4,$pS4)=unpack("d3A*",$PointTable{$ForthPoint});
- ($Px, $Py) = intersection4points($x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4);
-
-
- }
- elsif (s/^midpoint(?=\W)//i) {
- chk_lparen("midpoint",$lc);
- my $FirstPoint = &get_point($lc);
- next LINE if $FirstPoint eq "_undef_";
- my $SecondPoint = &get_point($lc);
- next LINE if $SecondPoint eq "_undef_";
- chk_rparen("No closing parenthesis found",$lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$FirstPoint});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$SecondPoint});
- ($Px, $Py) = midpoint($x1, $y1, $x2, $y2);
-
- }
- elsif (s/^pointonline(?=\W)//i) {
- chk_lparen("pointonline",$lc);
- my $FirstPoint = &get_point($lc);
- next LINE if $FirstPoint eq "_undef_";
- my $SecondPoint = &get_point($lc);
- next LINE if $SecondPoint eq "_undef_";
- chk_comma($lc);
- # now get the distance
- my $distance = expr($lc);
- chk_rparen("No closing parenthesis found",$lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$FirstPoint});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$SecondPoint});
- ($Px, $Py) = pointOnLine($x1,$y1,$x2,$y2,$distance);
-
- }
- elsif (s/^circumcircleCenter(?=\W)//i) {
- chk_lparen("circumCircleCenter",$lc);
- my $FirstPoint = &get_point($lc);
- next LINE if $FirstPoint eq "_undef_";
- my $SecondPoint = &get_point($lc);
- next LINE if $SecondPoint eq "_undef_";
- my $ThirdPoint = &get_point($lc);
- next LINE if $ThirdPoint eq "_undef_";
- chk_rparen("No closing parenthesis found",$lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$FirstPoint});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$SecondPoint});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$ThirdPoint});
- ($Px, $Py,$r) = &circumCircleCenter($x1,$y1,$x2,$y2,$x3,$y3,$lc);
- next LINE if $Px == 0 and $Py == 0 and $r == 0;
-
- }
- elsif (s/^IncircleCenter(?=\W)//i) {
- chk_lparen("IncircleCenter",$lc);
- my $FirstPoint = &get_point($lc);
- next LINE if $FirstPoint eq "_undef_";
- my $SecondPoint = &get_point($lc);
- next LINE if $SecondPoint eq "_undef_";
- my $ThirdPoint = &get_point($lc);
- next LINE if $ThirdPoint eq "_undef_";
- chk_rparen("No closing parenthesis found",$lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$FirstPoint});
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$SecondPoint});
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$ThirdPoint});
- ($Px, $Py, $r) = IncircleCenter($x1,$y1,$x2,$y2,$x3,$y3);
-
- }
- elsif (s/^ExcircleCenter(?=\W)//i) {
- chk_lparen("ExcircleCenter",$lc);
- my $PointA = get_point($lc);
- next LINE if $PointA eq "_undef_";
- my $PointB = get_point($lc);
- next LINE if $PointB eq "_undef_";
- my $PointC = get_point($lc);
- next LINE if $PointC eq "_undef_";
- chk_comma($lc);
- my $PointD = &get_point($lc);
- next LINE if $PointD eq "_undef_";
- if (!memberOf($PointD, $PointA, $PointB, $PointC)) {
- PrintErrorMessage("Current point isn't a side point",$lc);
- next LINE;
- }
- my $PointE = get_point($lc);
- next LINE if $PointE eq "_undef_";
- if (!memberOf($PointE, $PointA, $PointB, $PointC)) {
- PrintErrorMessage("Current point isn't a side point",$lc);
- next LINE;
- }
- if ($PointD eq $PointE) {
- PrintErrorMessage("Side points are identical",$lc);
- next LINE;
- }
- ($Px, $Py, $r) = excircle($PointA, $PointB, $PointC,
- $PointD, $PointE);
- chk_rparen("after coordinates part",$lc);
-
- }
- elsif (/^[^\W\d_]\d{0,4}\s*[^,\w]/) {
- m/^([^\W\d_]\d{0,4})\s*/i;
- if (exists($PointTable{lc($1)})) {
- my $Tcoord = get_point($lc);
- my ($x,$y,$pSV,$pS)=unpack("d3A*",$PointTable{$Tcoord});
- $Px = $x;
- $Py = $y;
- }
- else {
- $Px = expr();
- chk_comma($lc);
- $Py = expr();
- }
- }
- elsif (/[^\W\d_]\d{0,4}\s*,\s*shift|polar|rotate|vector/i) { #a point?
- s/^([^\W\d_]\d{0,4})//i;
- my $PointA = $1;
- if (exists($PointTable{lc($PointA)})) {
- s/\s*//;
- if (s/^,//) {
- s/\s*//;
- if (s/^shift(?=\W)//i) {
-
- chk_lparen("shift",$lc);
- my $dist1 = expr($lc);
- chk_comma($lc);
- my $dist2 = expr($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{lc($PointA)});
- $Px = $x1 + $dist1;
- $Py = $y1 + $dist2;
- chk_rparen("shift part",$lc);
-
- }
- elsif (s/^polar(?=\W)//i) {
- chk_lparen("polar",$lc);
- my ($R1, $Theta1);
- $R1 = expr($lc);
- chk_comma($lc);
- $Theta1 = expr($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{lc($PointA)});
- s/\s*//;
- if (s/^rad(?=\W)//i) {
- # do nothing!
- }
- elsif (s/^deg(?=\W)//i) {
- $Theta1 = $Theta1 * PI / 180;
- }
- else {
- #$Theta1 = $Theta1 * PI / 180;
- }
- $Px = $x1 + $R1 * cos($Theta1);
- $Py = $y1 + $R1 * sin($Theta1);
- chk_rparen("after polar part",$lc);
-
- }
- elsif (s/^rotate(?=\W)//i) {
- chk_lparen("rotate",$lc);
- my $Q = lc($PointA);
- my $P = get_point($lc);
- next LINE if $P eq "_undef_";
- chk_comma($lc);
- my $Theta1 = expr($lc);
- my ($xP,$yP,$pSV1,$pS1)=unpack("d3A*",$PointTable{$P});
- my ($xQ,$yQ,$pSV2,$pS2)=unpack("d3A*",$PointTable{$Q});
- s/\s*//;
- if (s/^rad(?=\W)//i)
- {
- # do nothing!
- }
- elsif (s/^deg(?=\W)//i)
- {
- $Theta1 = $Theta1 * PI / 180;
- }
- else
- {
- $Theta1 = $Theta1 * PI / 180;
- }
- # shift origin to P
- $xQ -= $xP;
- $yQ -= $yP;
- # do the rotation
- $Px = $xQ * cos($Theta1) - $yQ * sin($Theta1);
- $Py = $xQ * sin($Theta1) + $yQ * cos($Theta1);
- # return origin back to original origin
- $Px += $xP;
- $Py += $yP;
- chk_rparen("after rotate part",$lc);
-
- }
- elsif (s/^vector(?=\W)//i) {
- chk_lparen("vector",$lc);
- my ($x0,$y0,$pSV0,$pS0) = unpack("d3A*",$PointTable{lc($PointA)});
- my $P = get_point($lc);
- my $Q = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1) = unpack("d3A*",$PointTable{$P});
- my ($x2,$y2,$pSV2,$pS2) = unpack("d3A*",$PointTable{$Q});
- $Px = $x0 + $x2 - $x1;
- $Py = $y0 + $y2 - $y1;
- chk_rparen("vector part",$lc);
-
-
- }
- else {
- PrintErrorMessage("unexpected token",$lc);
- next LINE;
- }
- }
- else {
- my ($xA,$yA,$pSVA,$pSA)=unpack("d3A*",$PointTable{lc($PointA)});
- $Px = $xA;
- $Py = $yA;
- }
- }
- else {
- PrintErrorMessage("Undefined point $PointA",$lc);
- next LINE;
- }
- }
- else {
- $Px = expr();
- chk_comma($lc);
- $Py = expr();
- }
-
- chk_rcb("coordinates part",$lc);
- my $sv = $defaultsymbol;
- my $sh = $defaultLFradius;
- my $side_or_radius = undef;
- if (s/^\[\s*//) { # the user has opted to specify the optional part
- if (/^(symbol|radius|side)\s*/i) {
- my @previous_options = ();
- my $number_of_options = 1;
- my $symbol_set = 0;
- while (s/^(symbol|radius)\s*//i and $number_of_options <= 2) {
- my $option = lc($1);
- if (s/^=\s*//) {
- if (memberOf($option,@previous_options)) {
- PrintErrorMessage("Option \"$option\" has been already defined", $lc);
- my $dummy = expr($lc);
- }
- elsif ($option eq "radius") {
- $sh = expr($lc);
- $sv = $defaultsymbol if ! $symbol_set;
- }
- elsif ($option eq "symbol") {
- if (s/^circle\s*//i) {
- $sv = "circle";
- chk_lparen("after token circle",$lc);
- $side_or_radius = expr($lc);
- chk_rparen("expression",$lc);
- }
- elsif (s/^square\s*//i) {
- $sv = "square";
- chk_lparen("after token square",$lc);
- $side_or_radius = expr($lc);
- chk_rparen("expression",$lc);
- }
- elsif (s/^(((\\\]){1}|(\\,){1}|(\\\s){1}|[^\],\s])+)//) {
- $sv = $1;
- $sv =~ s/\\\]/\]/g;
- $sv =~ s/\\,/,/g;
- $sv =~ s/\\ / /g;
- s/\s*//;
- }
- $symbol_set = 1;
- }
- }
- else {
- PrintErrorMessage("unexpected token", $lc);
- next LINE;
- }
- $number_of_options++;
- push (@previous_options, $option);
- s/^,\s*//;
- }
- }
- else {
- PrintErrorMessage("unexpected token", $lc);
- next LINE;
- }
-
- chk_rsb("optional part",$lc);
- }
- # to avoid truncation problems introduced by the pack function, we
- # round each number up to five decimal digits
- $Px = sprintf("%.5f", $Px);
- $Py = sprintf("%.5f", $Py);
- print OUT "%% point$Point_Line \t$origPN = ($Px, $Py)\n" if $comments_on;
- chk_comment($lc);
- $PointTable{$PointName} = pack("d3A*",$Px,$Py,$sh,$sv);
- if (defined($side_or_radius)) {
- $DimOfPoint{$PointName} = $side_or_radius;
- }
-
- }
- elsif (/^\s*setPointNumber(?=\W)/i)
- {
- PrintWarningMessage("Command setPointNumber is ignored",$lc);
- next LINE;
- }
- elsif (s/^\s*(showAngle(?=\W))//i)
- {
- chk_lparen("showangle",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- my $point_3 = get_point($lc);
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point_3});
- my $angle = Angle($x1, $y1, $x2, $y2, $x3, $y3);
- $angle = 0 if $angle == -500;
- printf OUT "%%%% angle(%s%s%s) = %.5f deg ( %.5f rad)\n", $point_1,
- $point_2, $point_3, $angle, $angle*D2R;
- chk_rparen("Missing right parenthesis", $lc);
-
- }
- elsif (s/^\s*(showArea(?=\W))//i)
- {
- chk_lparen("showarea",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- my $point_3 = get_point($lc);
- my ($x3,$y3,$pSV3,$pS3)=unpack("d3A*",$PointTable{$point_3});
- print OUT "%% area($point_1$point_2$point_3) = ",
- triangleArea($x1, $y1, $x2, $y2, $x3, $y3), "\n";
- chk_rparen("Missing right parenthesis", $lc);
-
- }
- elsif (s/^\s*(showLength(?=\W))//i)
- {
- chk_lparen("showlength",$lc);
- my $point_1 = get_point($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{$point_1});
- my $point_2 = get_point($lc);
- my ($x2,$y2,$pSV2,$pS2)=unpack("d3A*",$PointTable{$point_2});
- print OUT "%% length($point_1$point_2) = ",
- Length($x1, $y1, $x2, $y2), "\n";
- chk_rparen("Missing right parenthesis", $lc);
-
-
- }
- elsif (/^\s*showPoints(?=\W)/i)
- {
- print OUT "%%-------------------------------------------------\n";
- print OUT "%% L I S T O F P O I N T S \n";
- print OUT "%%-------------------------------------------------\n";
- foreach my $p (keys(%PointTable)) {
- my ($x, $y, $pSV, $pS) = unpack("d3A*",$PointTable{$p});
- printf OUT "%%%%\t%s\t= ( %.5f, %.5f ), LF-radius = %.5f, symbol = %s\n",
- $p, $x, $y, $pSV, $pS;
- }
- print OUT "%%-------------------------------------------------\n";
- print OUT "%% E N D O F L I S T O F P O I N T S \n";
- print OUT "%%-------------------------------------------------\n";
- next LINE;
- }
- elsif (/^\s*showVariables(?=\W)/i)
- {
- print OUT "%%-------------------------------------------------\n";
- print OUT "%% L I S T O F V A R I A B L E S \n";
- print OUT "%%-------------------------------------------------\n";
- foreach my $var (keys(%VarTable)) {
- print OUT "%%\t", $var, "\t=\t", $VarTable{$var}, "\n";
- }
- print OUT "%%-------------------------------------------------\n";
- print OUT "%% E N D O F L I S T O F V A R I A B L E S \n";
- print OUT "%%-------------------------------------------------\n";
- next LINE;
- }
- elsif (s/^\s*(system(?=\W))//i)
- {
- print OUT "%% $1$_" if $comments_on;
-
- chk_lparen("$cmd",$lc);
- my ($error, $command, $rest) = get_string($_);
- next LINE if $error == 1;
- $_ = $rest;
- if (! is_tainted($command)) {
- system($command);
- }
- else {
- PrintErrorMessage("String \"$command\" has tainted data", $lc);
- next LINE;
- }
- chk_rparen("after $cmd arguments",$lc);
- chk_comment("after $cmd command",$lc);
-
- }
- elsif (s/^\s*(text(?=\W))//i)
- {
- print OUT "%% $1$_" if $comments_on;
-
- chk_lparen("text",$lc);
- my ($level,$text)=(1,"");
- TEXTLOOP: while (1)
- {
- $level++ if /^\(/;
- $level-- if /^\)/;
- s/^(.)//;
- last TEXTLOOP if $level==0;
- $text .= $1;
- }
- chk_lcb("text part",$lc);
- my ($Px, $Py,$dummy,$pos);
- $pos="";
- s/\s*//;
-
- if (/^[^\W\d_]\d{0,4}\s*[^,\w]/) {
- my $Tcoord = get_point($lc);
- my ($x,$y,$pSV,$pS)=unpack("d3A*",$PointTable{$Tcoord});
- $Px = $x;
- $Py = $y;
- }
- elsif (/[^\W\d_]\d{0,4}\s*,\s*shift|polar/i) {
- s/^([^\W\d_]\d{0,4})//i;
- my $PointA = $1;
- if (exists($PointTable{lc($PointA)})) {
- s/\s*//;
- if (s/^,//) {
- s/\s*//;
- if (s/^shift(?=\W)//i) {
-
- chk_lparen("shift",$lc);
- my $dist1 = expr($lc);
- chk_comma($lc);
- my $dist2 = expr($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{lc($PointA)});
- $Px = $x1 + $dist1;
- $Py = $y1 + $dist2;
- chk_rparen("shift part",$lc);
-
- }
- elsif (s/^polar(?=\W)//i) {
- chk_lparen("polar",$lc);
- my ($R1, $Theta1);
- $R1 = expr($lc);
- chk_comma($lc);
- $Theta1 = expr($lc);
- my ($x1,$y1,$pSV1,$pS1)=unpack("d3A*",$PointTable{lc($PointA)});
- s/\s*//;
- if (s/^rad(?=\W)//i) {
- # do nothing!
- }
- elsif (s/^deg(?=\W)//i) {
- $Theta1 = $Theta1 * PI / 180;
- }
- else {
- #$Theta1 = $Theta1 * PI / 180;
- }
- $Px = $x1 + $R1 * cos($Theta1);
- $Py = $y1 + $R1 * sin($Theta1);
- chk_rparen("after polar part",$lc);
-
- }
- }
- }
- else {
- PrintErrorMessage("undefined point/var",$lc);
- next LINE;
- }
- }
- else {
- $Px = expr();
- chk_comma($lc);
- $Py = expr();
- }
-
- chk_rcb("coordinates part of text command",$lc);
- if (s/^\[//)
- {
- s/\s*//;
-
- if (s/^(\w{1})\s*//) {
- $pos .= $1;
- if (memberOf($pos, "l", "r")) {
- if (s/^(\w{1})\s*//) {
- my $np = $1;
- if (memberOf($np, "t", "b", "B")) {
- $pos .= $np;
- }
- else {
- if (memberOf($np, "l", "r")) {
- PrintErrorMessage("$np can't follow 'l' or 'r'", $lc);
- }
- else {
- PrintErrorMessage("$np is not a valid positioning option", $lc);
- }
- next LINE;
- }
- }
- }
- elsif (memberOf($pos, "t", "b", "B")) {
- if (s/^(\w{1})\s*//) {
- my $np = $1;
- if (memberOf($np, "l", "r")) {
- $pos .= $np;
- }
- else {
- if (memberOf($np, "t", "b", "B")) {
- PrintErrorMessage("$np can't follow 't', 'b', or 'B'", $lc);
- }
- else {
- PrintErrorMessage("$np is not a valid positioning option", $lc);
- }
- next LINE;
- }
- }
- }
- else {
- PrintErrorMessage("$pos is not a valid positioning option", $lc);
- next LINE;
- }
- }
- else {
- PrintErrorMessage("illegal token in optional part of text command",$lc);
- next LINE;
- }
-
- s/\s*//;
- chk_rsb("optional part of text command",$lc);
- }
- chk_comment($lc);
- if ($pos eq "")
- {
- printf OUT "\\put {%s} at %f %f\n", $text, $Px, $Py;
- }
- else
- {
- printf OUT "\\put {%s} [%s] at %f %f\n", $text, $pos, $Px, $Py;
- }
-
- }
- elsif (s/^\s*(var(?=\W))//i)
- {
- print OUT "%% $1$_" if $comments_on;
- do{
- s/\s*//;
- PrintErrorMessage("no identifier found after token var",$lc)
- if $_ !~ s/^([^\W\d_]\d{0,4})//i;
- my $Varname = $1;
- my $varname = lc($Varname);
- if (exists $ConstTable{$varname}) {
- PrintErrorMessage("Redefinition of constant $varname",$lc);
- }
- s/\s*//; #remove leading white space
- PrintErrorMessage("did not find expected = sign",$lc)
- if $_ !~ s/^[=]//i;
- my $val = expr($lc);
- $VarTable{$varname} = $val;
- print OUT "%% $Varname = $val\n" if $comments_on;
- }while (s/^,//);
- chk_comment($lc);
- s/\s*//;
- if (/^[^%]/) {
- PrintWarningMessage("Trailing text is ignored",$lc);
- }
- }
- elsif (/^\s*\\(.+)/)
- {
- my $line = $1;
- if ($line =~ /^\s+(.+)/)
- {
- print OUT " $line\n";
- }
- else
- {
- print OUT "\\$line\n";
- }
- next LINE;
- }
- elsif (0==length) #empty line
- {
- next LINE;
- }
- else {
- PrintErrorMessage("command not recognized",$lc);
- next LINE;
- }
-
- }
- }
- }
-
-
-our $alarm="";
-our $comments_on=1;
-our $out_file="default";
-our $argc=@ARGV;
-if ($argc == 0 || $argc > 5 ){ # no command line arguments or more than 4
- # arguments
- die "\nmathspic version $version_number\n" .
- "Usage: mathspic [-h] [-b] [-c] [-o <out file>] <in file>\n\n";
-}
-else {
- our $file = "";
- SWITCHES:
- while($_ = $ARGV[0]) {
- shift;
- if (/^-h$/) {
- die "\nThis is mathspic version $version_number\n" .
- "Type \"man mathspic\" for detailed help\n".
- "Usage:\tmathspic [-h] [-b] [-c] [-o <out file>] <in file>\n" .
- "\twhere,\n" .
- "\t[-b]\tenables bell sound if error exists\n" .
- "\t[-c]\tdisables comments in output file\n" .
- "\t[-h]\tgives this help listing\n" .
- "\t[-o]\tcreates specified output file\n\n";
- }
- elsif (/^-b$/) {
- $alarm = chr(7);
- }
- elsif (/^-c$/) {
- $comments_on = 0;
- }
- elsif (/^-o$/) {
- die "No output file specified!\n" if !@ARGV;
- $out_file = $ARGV[0];
- shift;
- }
- elsif (/^-\w+/) {
- die "$_: Illegal command line switch!\n";
- }
- else {
- $file = $_;
- }
- }my ($xA, $yA, $xB, $yB, $dist)=@_;
- die "No input file specified!\n" if $file eq "";
-
- print "This is mathspic version $version_number\n";
-}
- our ($source_file, $log_file);
- if (! -e $file) {
- die "$file: no such file!\n" if (! (-e "$file.m"));
- $source_file = "$file.m";
- }
- else {
- $source_file = $file;
- $file = $1 if $file =~ /(\w[\w-\.]+)\.\w+/;
- }
- $out_file= "$file.mt" if $out_file eq "default";
- $log_file= "$file.mlg";
-
-
- open(IN,"$source_file")||die "Can't open source file: $source_file\n";
- open(OUT,">$out_file")||die "Can't open output file: $out_file\n";
- open(LOG,">$log_file")||die "Can't open log file: $log_file\n";
- print_headers;
- process_input(IN,"");
-
-print $alarm if $no_errors > 0;
-__END__
-
diff --git a/Build/source/texk/texlive/linked_scripts/mf2pt1/mf2pt1.pl b/Build/source/texk/texlive/linked_scripts/mf2pt1/mf2pt1.pl
deleted file mode 100755
index 3546aee3931..00000000000
--- a/Build/source/texk/texlive/linked_scripts/mf2pt1/mf2pt1.pl
+++ /dev/null
@@ -1,1091 +0,0 @@
-#! /usr/bin/env perl
-
-##################################################
-# Convert stylized Metafont to PostScript Type 1 #
-# By Scott Pakin <scott+mf@pakin.org> #
-##################################################
-
-########################################################################
-# mf2pt1 #
-# Copyright (C) 2005-2020 Scott Pakin #
-# #
-# This program may be distributed and/or modified under the conditions #
-# of the LaTeX Project Public License, either version 1.3c of this #
-# license or (at your option) any later version. #
-# #
-# The latest version of this license is in: #
-# #
-# http://www.latex-project.org/lppl.txt #
-# #
-# and version 1.3c or later is part of all distributions of LaTeX #
-# version 2006/05/20 or later. #
-########################################################################
-
-our $VERSION = "2.6"; # mf2pt1 version number
-require 5.6.1; # I haven't tested mf2pt1 with older Perl versions
-
-use File::Basename;
-use File::Spec;
-use Getopt::Long;
-use Pod::Usage;
-use Math::Trig;
-use warnings;
-use strict;
-
-# Define some common encoding vectors.
-my @standardencoding =
- ((map {"_a$_"} (0..31)),
- qw (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),
- (map {"_a$_"} (127..160)),
- qw (exclamdown cent sterling fraction yen florin section currency
- quotesingle quotedblleft guillemotleft guilsinglleft
- guilsinglright fi fl _a176 endash dagger daggerdbl
- periodcentered _a181 paragraph bullet quotesinglbase
- quotedblbase quotedblright guillemotright ellipsis
- perthousand _a190 questiondown _a192 grave acute circumflex
- tilde macron breve dotaccent dieresis _a201 ring cedilla
- _a204 hungarumlaut ogonek caron emdash),
- (map {"_a$_"} (209..224)),
- qw (AE _a226 ordfeminine _a228 _a229 _a230 _a231 Lslash Oslash OE
- ordmasculine _a236 _a237 _a238 _a239 _a240 ae _a242 _a243
- _a244 dotlessi _a246 _a247 lslash oslash oe germandbls _a252
- _a253 _a254 _a255));
-my @isolatin1encoding =
- ((map {"_a$_"} (0..31)),
- qw (space exclam quotedbl numbersign dollar percent ampersand
- quoteright parenleft parenright asterisk plus comma minus
- 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),
- (map {"_a$_"} (128..143)),
- qw (dotlessi grave acute circumflex tilde macron breve dotaccent
- dieresis _a153 ring cedilla _a156 hungarumlaut ogonek
- caron space exclamdown cent sterling currency yen brokenbar
- section dieresis copyright ordfeminine guillemotleft
- logicalnot hyphen registered macron degree plusminus
- twosuperior threesuperior acute mu paragraph periodcentered
- cedilla onesuperior ordmasculine guillemotright onequarter
- onehalf threequarters questiondown Agrave Aacute Acircumflex
- Atilde Adieresis Aring AE Ccedilla Egrave Eacute Ecircumflex
- Edieresis Igrave Iacute Icircumflex Idieresis Eth Ntilde
- Ograve Oacute Ocircumflex Otilde Odieresis multiply Oslash
- Ugrave Uacute Ucircumflex Udieresis Yacute Thorn germandbls
- agrave aacute acircumflex atilde adieresis aring ae ccedilla
- egrave eacute ecircumflex edieresis igrave iacute icircumflex
- idieresis eth ntilde ograve oacute ocircumflex otilde
- odieresis divide oslash ugrave uacute ucircumflex udieresis
- yacute thorn ydieresis));
-my @ot1encoding =
- qw (Gamma Delta Theta Lambda Xi Pi Sigma Upsilon Phi
- Psi Omega ff fi fl ffi ffl dotlessi dotlessj grave acute caron
- breve macron ring cedilla germandbls ae oe oslash AE OE Oslash
- suppress exclam quotedblright 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 exclamdown equal questiondown
- 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 quotedblleft bracketright circumflex dotaccent
- 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
- endash emdash hungarumlaut tilde dieresis);
-my @t1encoding =
- qw (grave acute circumflex tilde dieresis hungarumlaut ring caron
- breve macron dotaccent cedilla ogonek quotesinglbase
- guilsinglleft guilsinglright quotedblleft quotedblright
- quotedblbase guillemotleft guillemotright endash emdash cwm
- perthousand dotlessi dotlessj ff fi fl ffi ffl 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
- sfthyphen Abreve Aogonek Cacute Ccaron Dcaron Ecaron Eogonek
- Gbreve Lacute Lcaron Lslash Nacute Ncaron Eng Ohungarumlaut
- Racute Rcaron Sacute Scaron Scedilla Tcaron Tcedilla
- Uhungarumlaut Uring Ydieresis Zacute Zcaron Zdotaccent IJ
- Idotaccent dcroat section abreve aogonek cacute ccaron dcaron
- ecaron eogonek gbreve lacute lcaron lslash nacute ncaron eng
- ohungarumlaut racute rcaron sacute scaron scedilla tcaron
- tcedilla uhungarumlaut uring ydieresis zacute zcaron zdotaccent
- ij exclamdown questiondown sterling Agrave Aacute Acircumflex
- Atilde Adieresis Aring AE Ccedilla Egrave Eacute Ecircumflex
- Edieresis Igrave Iacute Icircumflex Idieresis Eth Ntilde Ograve
- Oacute Ocircumflex Otilde Odieresis OE Oslash Ugrave Uacute
- Ucircumflex Udieresis Yacute Thorn SS agrave aacute acircumflex
- atilde adieresis aring ae ccedilla egrave eacute ecircumflex
- edieresis igrave iacute icircumflex idieresis eth ntilde ograve
- oacute ocircumflex otilde odieresis oe oslash ugrave uacute
- ucircumflex udieresis yacute thorn germandbls);
-
-# Define font parameters that the user can override.
-my $fontversion;
-my $creationdate;
-my $comment;
-my $familyname;
-my $weight;
-my $fullname;
-my $fixedpitch;
-my $italicangle;
-my $underlinepos;
-my $underlinethick;
-my $fontname;
-my $uniqueID;
-my $designsize;
-my ($mffile, $pt1file, $pfbfile, $ffscript);
-my $encoding;
-my $rounding;
-my $bpppix;
-
-# Define all of our other global variables.
-my $progname = basename $0, ".pl";
-my $mag;
-my @fontbbox;
-my @charbbox;
-my @charwd;
-my @glyphname;
-my @charfiles;
-my $filebase;
-my $filedir;
-my $filenoext;
-my $versionmsg = "mf2pt1 version $VERSION
-
-Copyright (C) 2005-2020 Scott Pakin
-
-This program may be distributed and/or modified under the conditions
-of the LaTeX Project Public License, either version 1.3c of this
-license or (at your option) any later version.
-
-The latest version of this license is in:
-
- http://www.latex-project.org/lppl.txt
-
-and version 1.3c or later is part of all distributions of LaTeX
-version 2006/05/20 or later.
-";
-
-
-######################################################################
-
-# The routines to compute the fractional approximation of a real number
-# are heavily based on code posted by Ben Tilly
-# <http://www.perlmonks.org/?node_id=26179> on Nov 16th, 2000, to the
-# PerlMonks list. See <http://www.perlmonks.org/index.pl?node_id=41961>.
-
-
-# Takes numerator/denominator pairs.
-# Returns a PS fraction string representation (with a trailing space).
-sub frac_string (@)
-{
- my $res = "";
-
- while (@_) {
- my $n = shift;
- my $d = shift;
- $res .= $n . " ";
- $res .= $d . " div " if $d > 1;
- }
-
- return $res;
-}
-
-
-# Takes a number.
-# Returns a numerator and denominator with the smallest denominator
-# so that the difference of the resulting fraction to the number is
-# smaller or equal to $rounding.
-sub frac_approx ($)
-{
- my $num = shift;
- my $f = ret_frac_iter ($num);
-
- while (1) {
- my ($n, $m) = $f->();
- my $approx = $n / $m;
- my $delta = abs ($num - $approx);
- return ($n, $m) if ($delta <= $rounding);
- }
-}
-
-
-# Takes a number, returns the best integer approximation and (in list
-# context) the error.
-sub best_int ($)
-{
- my $x = shift;
- my $approx = sprintf '%.0f', $x;
- if (wantarray) {
- return ($approx, $x - $approx);
- }
- else {
- return $approx;
- }
-}
-
-
-# Takes a numerator and denominator, in scalar context returns
-# the best fraction describing them, in list the numerator and
-# denominator.
-sub frac_standard ($$)
-{
- my $n = best_int(shift);
- my $m = best_int(shift);
- my $k = gcd($n, $m);
- $n /= $k;
- $m /= $k;
- if ($m < 0) {
- $n *= -1;
- $m *= -1;
- }
- if (wantarray) {
- return ($n, $m);
- }
- else {
- return "$n/$m";
- }
-}
-
-
-# Euclidean algorithm for calculating a GCD.
-# Takes two integers, returns the greatest common divisor.
-sub gcd ($$)
-{
- my ($n, $m) = @_;
- while ($m) {
- my $k = $n % $m;
- ($n, $m) = ($m, $k);
- }
- return $n;
-}
-
-
-# Takes a list of terms in a continued fraction, and converts it
-# into a fraction.
-sub ints_to_frac (@)
-{
- my ($n, $m) = (0, 1); # Start with 0
- while (@_) {
- my $k = pop;
- if ($n) {
- # Want frac for $k + 1/($n/$m)
- ($n, $m) = frac_standard($k*$n + $m, $n);
- }
- else {
- # Want $k
- ($n, $m) = frac_standard($k, 1);
- }
- }
- return frac_standard($n, $m);
-}
-
-
-# Takes a number, returns an anon sub which iterates through a set of
-# fractional approximations that converges very quickly to the number.
-sub ret_frac_iter ($)
-{
- my $x = shift;
- my $term_iter = ret_next_term_iter($x);
- my @ints;
- return sub {
- push @ints, $term_iter->();
- return ints_to_frac(@ints);
- }
-}
-
-
-# Terms of a continued fraction converging on that number.
-sub ret_next_term_iter ($)
-{
- my $x = shift;
- return sub {
- (my $n, $x) = best_int($x);
- if (0 != $x) {
- $x = 1/$x;
- }
- return $n;
- }
-}
-
-######################################################################
-
-# Round a number to the nearest integer.
-sub round ($)
-{
- return int($_[0] + 0.5*($_[0] <=> 0));
-}
-
-
-# Round a number to a given precision.
-sub prec ($)
-{
- return round ($_[0] / $rounding) * $rounding;
-}
-
-
-# Set a variable's value to the first defined value in the given list.
-# If the variable was not previously defined and no value in the list
-# is defined, do nothing.
-sub assign_default (\$@)
-{
- my $varptr = shift; # Pointer to variable to define
- return if defined $$varptr && $$varptr ne "UNSPECIFIED";
- foreach my $val (@_) {
- next if !defined $val;
- $$varptr = $val;
- return;
- }
-}
-
-
-# Print and execute a shell command. An environment variable with the
-# same name as the command overrides the command name. Return 1 on
-# success, 0 on failure. Optionally abort if the command fails, based
-# on the first argument to execute_command.
-sub execute_command ($@)
-{
- my $abort_on_failure = shift;
- my @command = @_;
- $command[0] = $ENV{uc $command[0]} || $command[0];
- my $prettyargs = join (" ", map {/[\\ ]/ ? "'$_'" : $_} @command);
- print "Invoking \"$prettyargs\"...\n";
- my $result = system @command;
- die "${progname}: \"$prettyargs\" failed ($!)\n" if $result && $abort_on_failure;
- return !$result;
-}
-
-
-# Output the font header.
-sub output_header ()
-{
- # Show the initial boilerplate.
- print OUTFILE <<"ENDHEADER";
-%!FontType1-1.0: $fontname $fontversion
-%%CreationDate: $creationdate
-% Font converted to Type 1 by mf2pt1, written by Scott Pakin.
-11 dict begin
-/FontInfo 11 dict dup begin
-/version ($fontversion) readonly def
-/Notice ($comment) readonly def
-/FullName ($fullname) readonly def
-/FamilyName ($familyname) readonly def
-/Weight ($weight) readonly def
-/ItalicAngle $italicangle def
-/isFixedPitch $fixedpitch def
-/UnderlinePosition $underlinepos def
-/UnderlineThickness $underlinethick def
-end readonly def
-/FontName /$fontname def
-ENDHEADER
-
- # If we're not using an encoding that PostScript knows about, then
- # create an encoding vector.
- if ($encoding==\@standardencoding) {
- print OUTFILE "/Encoding StandardEncoding def\n";
- }
- else {
- print OUTFILE "/Encoding 256 array\n";
- print OUTFILE "0 1 255 {1 index exch /.notdef put} for\n";
- foreach my $charnum (0 .. $#{$encoding}) {
- if ($encoding->[$charnum] && $encoding->[$charnum]!~/^_a\d+$/) {
- print OUTFILE "dup $charnum /$encoding->[$charnum] put\n";
- }
- }
- print OUTFILE "readonly def\n";
- }
-
- # Show the final boilerplate.
- print OUTFILE "/UniqueID $uniqueID def\n" if defined $uniqueID;
- print OUTFILE <<"ENDHEADER";
-/PaintType 0 def
-/FontType 1 def
-/FontMatrix [0.001 0 0 0.001 0 0] readonly def
-/FontBBox{@fontbbox}readonly def
-currentdict end
-currentfile eexec
-dup /Private 5 dict dup begin
-/RD{string currentfile exch readstring pop}executeonly def
-/ND{noaccess def}executeonly def
-/NP{noaccess put}executeonly def
-ENDHEADER
-}
-
-
-# Use MetaPost to generate one PostScript file per character. We
-# calculate the font bounding box from these characters and store them
-# in @fontbbox. If the input parameter is 1, set other font
-# parameters, too.
-sub get_bboxes ($)
-{
- execute_command 1, ("mpost", "-mem=mf2pt1", "-progname=mpost",
- "\\mode:=localfont; mag:=$mag; bpppix $bpppix; nonstopmode; input $mffile");
- opendir (CURDIR, ".") || die "${progname}: $! ($filedir)\n";
- @charfiles = sort
- { ($a=~ /\.(\d+)$/)[0] <=> ($b=~ /\.(\d+)$/)[0] }
- grep /^$filebase.*\.\d+$/, readdir(CURDIR);
- close CURDIR;
- @fontbbox = (1000000, 1000000, -1000000, -1000000);
- foreach my $psfile (@charfiles) {
- # Read the character number from the output file's extension.
- $psfile =~ /\.(\d+)$/;
- my $charnum = $1;
-
- # Process in turn each line of the current PostScript file.
- my $havebbox = 0;
- open (PSFILE, "<$psfile") || die "${progname}: $! ($psfile)\n";
- while (<PSFILE>) {
- my @tokens = split " ";
- if ($tokens[0] eq "%%BoundingBox:") {
- # Store the MetaPost-produced bounding box, just in case
- # the given font doesn't use beginchar.
- @tokens = ("%", "MF2PT1:", "glyph_dimensions", @tokens[1..4]);
- $havebbox--;
- }
- next if $#tokens<1 || $tokens[1] ne "MF2PT1:";
-
- # Process a "special" inserted into the generated PostScript.
- MF2PT1_CMD:
- {
- # glyph_dimensions llx lly urx ury -- specified glyph dimensions
- $tokens[2] eq "glyph_dimensions" && do {
- my @bbox = @tokens[3..6];
- $fontbbox[0]=$bbox[0] if $bbox[0]<$fontbbox[0];
- $fontbbox[1]=$bbox[1] if $bbox[1]<$fontbbox[1];
- $fontbbox[2]=$bbox[2] if $bbox[2]>$fontbbox[2];
- $fontbbox[3]=$bbox[3] if $bbox[3]>$fontbbox[3];
- $charbbox[$charnum] = \@bbox;
- $havebbox++;
- last MF2PT1_CMD;
- };
-
- # If all we want is the bounding box, exit the loop now.
- last MF2PT1_CMD if !$_[0];
-
- # glyph_name name -- glyph name
- $tokens[2] eq "glyph_name" && do {
- $glyphname[$charnum] = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # charwd wd -- character width as in TFM
- $tokens[2] eq "charwd" && do {
- $charwd[$charnum] = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_identifier name -- full font name
- $tokens[2] eq "font_identifier" && do {
- $fullname = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_size number -- font design size (pt, not bp)
- $tokens[2] eq "font_size" && $tokens[3] && do {
- $designsize = $tokens[3] * 72 / 72.27;
- last MF2PT1_CMD;
- };
-
- # font_slant number -- italic amount
- $tokens[2] eq "font_slant" && do {
- $italicangle = 0 + rad2deg (atan(-$tokens[3]));
- last MF2PT1_CMD;
- };
-
- # font_coding_scheme string -- font encoding
- $tokens[2] eq "font_coding_scheme" && do {
- $encoding = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_version string -- font version number (xxx.yyy)
- $tokens[2] eq "font_version" && do {
- $fontversion = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_comment string -- font comment notice
- $tokens[2] eq "font_comment" && do {
- $comment = join (" ", @tokens[3..$#tokens]);
- last MF2PT1_CMD;
- };
-
- # font_family string -- font family name
- $tokens[2] eq "font_family" && do {
- $familyname = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_weight string -- font weight (e.g., "Book" or "Heavy")
- $tokens[2] eq "font_weight" && do {
- $weight = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_fixed_pitch number -- fixed width font (0=false, 1=true)
- $tokens[2] eq "font_fixed_pitch" && do {
- $fixedpitch = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_underline_position number -- vertical underline position
- $tokens[2] eq "font_underline_position" && do {
- # We store $underlinepos in points and later
- # scale it by 1000/$designsize.
- $underlinepos = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_underline_thickness number -- thickness of underline
- $tokens[2] eq "font_underline_thickness" && do {
- # We store $underlinethick in points and later
- # scale it by 1000/$designsize.
- $underlinethick = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_name string -- font name
- $tokens[2] eq "font_name" && do {
- $fontname = $tokens[3];
- last MF2PT1_CMD;
- };
-
- # font_unique_id number (as string) -- globally unique font ID
- $tokens[2] eq "font_unique_id" && do {
- $uniqueID = 0+$tokens[3];
- last MF2PT1_CMD;
- };
- }
- }
- close PSFILE;
- if (!$havebbox) {
- warn "${progname}: No beginchar in character $charnum; glyph dimensions are probably incorrect\n";
- }
- }
-}
-
-
-# Convert ordinary, MetaPost-produced PostScript files into Type 1
-# font programs.
-sub output_font_programs ()
-{
- # Iterate over all the characters. We convert each one, line by
- # line and token by token.
- print "Converting PostScript graphics to Type 1 font programs...\n";
- foreach my $psfile (@charfiles) {
- # Initialize the font program.
- $psfile =~ /\.(\d+)$/;
- my $charnum = $1;
- my $gname = $glyphname[$charnum] || $encoding->[$charnum];
- my @fontprog;
- push @fontprog, ("/$gname {",
- frac_string (frac_approx ($charbbox[$charnum]->[0]),
- frac_approx ($charbbox[$charnum]->[2]))
- . "hsbw");
- my ($cpx, $cpy) =
- ($charbbox[$charnum]->[0], 0); # Current point (PostScript)
-
- # Iterate over every line in the current file.
- open (PSFILE, "<$psfile") || die "${progname}: $! ($psfile)\n";
- while (my $oneline=<PSFILE>) {
- next if $oneline=~/^\%/;
- next if $oneline=~/set/; # Fortunately, "set" never occurs on "good" lines.
- my @arglist; # Arguments to current PostScript function
-
- # Iterate over every token in the current line.
- TOKENLOOP:
- foreach my $token (split " ", $oneline) {
- # Number: Round and push on the argument list.
- $token =~ /^[-.\d]+$/ && do {
- push @arglist, prec ($&);
- next TOKENLOOP;
- };
-
- # curveto: Convert to vhcurveto, hvcurveto, or rrcurveto.
- $token eq "curveto" && do {
- my ($dx1, $dy1) = ($arglist[0] - $cpx,
- $arglist[1] - $cpy);
- my ($dx1n, $dx1d) = frac_approx ($dx1);
- my ($dy1n, $dy1d) = frac_approx ($dy1);
- $cpx += $dx1n / $dx1d;
- $cpy += $dy1n / $dy1d;
-
- my ($dx2, $dy2) = ($arglist[2] - $cpx,
- $arglist[3] - $cpy);
- my ($dx2n, $dx2d) = frac_approx ($dx2);
- my ($dy2n, $dy2d) = frac_approx ($dy2);
- $cpx += $dx2n / $dx2d;
- $cpy += $dy2n / $dy2d;
-
- my ($dx3, $dy3) = ($arglist[4] - $cpx,
- $arglist[5] - $cpy);
- my ($dx3n, $dx3d) = frac_approx ($dx3);
- my ($dy3n, $dy3d) = frac_approx ($dy3);
- $cpx += $dx3n / $dx3d;
- $cpy += $dy3n / $dy3d;
-
- if (!$dx1n && !$dy3n) {
- push @fontprog, frac_string ($dy1n, $dy1d,
- $dx2n, $dx2d,
- $dy2n, $dy2d,
- $dx3n, $dx3d)
- . "vhcurveto";
- }
- elsif (!$dy1n && !$dx3n) {
- push @fontprog, frac_string ($dx1n, $dx1d,
- $dx2n, $dx2d,
- $dy2n, $dy2d,
- $dy3n, $dy3d)
- . "hvcurveto";
- }
- else {
- push @fontprog, frac_string ($dx1n, $dx1d,
- $dy1n, $dy1d,
- $dx2n, $dx2d,
- $dy2n, $dy2d,
- $dx3n, $dx3d,
- $dy3n, $dy3d)
- . "rrcurveto";
- }
- next TOKENLOOP;
- };
-
- # lineto: Convert to vlineto, hlineto, or rlineto.
- $token eq "lineto" && do {
- my ($dx, $dy) = ($arglist[0] - $cpx,
- $arglist[1] - $cpy);
- my ($dxn, $dxd) = frac_approx ($dx);
- my ($dyn, $dyd) = frac_approx ($dy);
- $cpx += $dxn / $dxd;
- $cpy += $dyn / $dyd;
-
- if (!$dxn) {
- push @fontprog, frac_string ($dyn, $dyd)
- . "vlineto" if $dyn;
- }
- elsif (!$dyn) {
- push @fontprog, frac_string ($dxn, $dxd)
- . "hlineto";
- }
- else {
- push @fontprog, frac_string ($dxn, $dxd, $dyn, $dyd)
- . "rlineto";
- }
- next TOKENLOOP;
- };
-
- # moveto: Convert to vmoveto, hmoveto, or rmoveto.
- $token eq "moveto" && do {
- my ($dx, $dy) = ($arglist[0] - $cpx,
- $arglist[1] - $cpy);
- my ($dxn, $dxd) = frac_approx ($dx);
- my ($dyn, $dyd) = frac_approx ($dy);
- $cpx += $dxn / $dxd;
- $cpy += $dyn / $dyd;
-
- if (!$dxn) {
- push @fontprog, frac_string ($dyn, $dyd)
- . "vmoveto";
- }
- elsif (!$dyn) {
- push @fontprog, frac_string ($dxn, $dxd)
- . "hmoveto";
- }
- else {
- push @fontprog, frac_string ($dxn, $dxd, $dyn, $dyd)
- . "rmoveto";
- }
- next TOKENLOOP;
- };
-
- # closepath: Output as is.
- $token eq "closepath" && do {
- push @fontprog, $token;
- next TOKENLOOP;
- };
- }
- }
- close PSFILE;
- push @fontprog, ("endchar",
- "} ND");
- print OUTFILE join ("\n\t", @fontprog), "\n";
- }
-}
-
-
-# Output the final set of code for the Type 1 font.
-sub output_trailer ()
-{
- print OUTFILE <<"ENDTRAILER";
-/.notdef {
- 0 @{[frac_string (frac_approx ($fontbbox[2] - $fontbbox[0]))]} hsbw
- endchar
- } ND
-end
-end
-readonly put
-noaccess put
-dup/FontName get exch definefont pop
-mark currentfile closefile
-cleartomark
-ENDTRAILER
-}
-
-######################################################################
-
-# Parse the command line. Asterisks in the following represents
-# commands also defined by Plain Metafont.
-my %opthash = ();
-GetOptions (\%opthash,
- "fontversion=s", # font_version
- "comment=s", # font_comment
- "family=s", # font_family
- "weight=s", # font_weight
- "fullname=s", # font_identifier (*)
- "fixedpitch!", # font_fixed_pitch
- "italicangle=f", # font_slant (*)
- "underpos=f", # font_underline_position
- "underthick=f", # font_underline_thickness
- "name=s", # font_name
- "uniqueid=i", # font_unique_id
- "designsize=f", # font_size (*)
- "encoding=s", # font_coding_scheme (*)
- "rounding=f",
- "bpppix=f",
- "ffscript=s",
- "h|help",
- "V|version") || pod2usage(2);
-if (defined $opthash{"h"}) {
- pod2usage(-verbose => 1,
- -output => \*STDOUT, # Bug workaround for Pod::Usage
- -exitval => "NOEXIT");
- print "Please e-mail bug reports to scott+mf\@pakin.org.\n";
- exit 1;
-}
-do {print $versionmsg; exit 1} if defined $opthash{"V"};
-pod2usage(2) if $#ARGV != 0;
-
-# Extract the filename from the command line.
-$mffile = $ARGV[0];
-my @fileparts = fileparse $mffile, ".mf";
-$filebase = $fileparts[0];
-$filedir = $fileparts[1];
-$filenoext = File::Spec->catfile ($filedir, $filebase);
-$pt1file = $filebase . ".pt1";
-$pfbfile = $filebase . ".pfb";
-
-assign_default $bpppix, $opthash{bpppix}, 0.02;
-
-# Make our first pass through the input, to set values for various options.
-$mag = 100; # Get a more precise bounding box.
-get_bboxes(1); # This might set $designsize.
-
-# Sanity-check the specified precision.
-assign_default $rounding, $opthash{rounding}, 1;
-if ($rounding<=0.0 || $rounding>1.0) {
- die sprintf "%s: Invalid rounding amount \"%g\"; value must be a positive number no greater than 1.0\n", $progname, $rounding;
-}
-
-# Ensure that every user-definable parameter is assigned a value. The only
-# exception is the unique ID, as Adobe no longer recommends specifying one.
-assign_default $fontversion, $opthash{fontversion}, "001.000";
-assign_default $creationdate, scalar localtime;
-assign_default $comment, $opthash{comment}, "Font converted to Type 1 by mf2pt1, written by Scott Pakin.";
-assign_default $weight, $opthash{weight}, "Medium";
-assign_default $fixedpitch, $opthash{fixedpitch}, 0;
-assign_default $uniqueID, $opthash{uniqueid};
-assign_default $designsize, $opthash{designsize};
-die "${progname}: a design size must be specified in $mffile or on the command line\n" if !defined $designsize;
-die "${progname}: the design size must be a positive number\n" if $designsize<=0.0;
-assign_default $underlinepos, $opthash{underpos}, -1;
-$underlinepos = round(1000*$underlinepos/$designsize);
-assign_default $underlinethick, $opthash{underthick}, 0.5;
-$underlinethick = round(1000*$underlinethick/$designsize);
-assign_default $fullname, $opthash{fullname}, $filebase;
-assign_default $familyname, $opthash{family}, $fullname;
-assign_default $italicangle, $opthash{italicangle}, 0;
-assign_default $fontname, $opthash{name}, "$familyname-$weight";
-$fontname =~ s/\s//g;
-assign_default $encoding, $opthash{encoding}, "standard";
-my $encoding_name = $encoding;
-ENCODING:
-{
- if (-e $encoding) {
- # Filenames take precedence over built-in encodings.
- my @enc_array;
- open (ENCFILE, "<$encoding") || die "${progname}: $! ($encoding)\n";
- while (my $oneline = <ENCFILE>) {
- $oneline =~ s/\%.*$//;
- foreach my $word (split " ", $oneline) {
- push @enc_array, substr($word, 1) if substr($word, 0, 1) eq "/";
- }
- }
- close ENCFILE;
- $encoding_name = substr (shift @enc_array, 1);
- $encoding = \@enc_array;
- last ENCODING;
- }
- $encoding=\@standardencoding, last ENCODING if $encoding eq "standard";
- $encoding=\@isolatin1encoding, last ENCODING if $encoding eq "isolatin1";
- $encoding=\@ot1encoding, last ENCODING if $encoding eq "ot1";
- $encoding=\@t1encoding, last ENCODING if $encoding eq "t1";
- $encoding=\@glyphname, last ENCODING if $encoding eq "asis";
- warn "${progname}: Unknown encoding \"$encoding\"; using standard Adobe encoding\n";
- $encoding=\@standardencoding; # Default to standard encoding
-}
-assign_default $fixedpitch, $opthash{fixedpitch}, 0;
-$fixedpitch = $fixedpitch ? "true" : "false";
-assign_default $ffscript, $opthash{ffscript};
-
-# Output the final values of all of our parameters.
-print "\n";
-print <<"PARAMVALUES";
-mf2pt1 is using the following font parameters:
- font_version: $fontversion
- font_comment: $comment
- font_family: $familyname
- font_weight: $weight
- font_identifier: $fullname
- font_fixed_pitch: $fixedpitch
- font_slant: $italicangle
- font_underline_position: $underlinepos
- font_underline_thickness: $underlinethick
- font_name: $fontname
- font_size: $designsize (bp)
- font_coding_scheme: $encoding_name
-PARAMVALUES
- ;
-print " font_unique_id: $uniqueID\n" if defined $uniqueID;
-print "\n";
-
-# Scale by a factor of 1000/design size.
-$mag = 1000.0 / $designsize;
-get_bboxes(0);
-print "\n";
-
-# Output the font in disassembled format.
-open (OUTFILE, ">$pt1file") || die "${progname}: $! ($pt1file)\n";
-output_header();
-printf OUTFILE "2 index /CharStrings %d dict dup begin\n",
- 1+scalar(grep {defined($_)} @charbbox);
-output_font_programs();
-output_trailer();
-close OUTFILE;
-unlink @charfiles;
-print "\n";
-
-# Convert from the disassembled font format to Type 1 binary format.
-if (!execute_command 0, ("t1asm", $pt1file, $pfbfile)) {
- die "${progname}: You'll need either to install t1utils and rerun $progname or find another way to convert $pt1file to $pfbfile\n";
- exit 1;
-}
-print "\n";
-unlink $pt1file;
-
-# Use FontForge to autohint the result.
-my $user_script = 0; # 1=script file was provided by the user; 0=created here
-if (defined $ffscript) {
- # The user provided his own script.
- $user_script = 1;
-}
-else {
- # Create a FontForge script file.
- $ffscript = $filebase . ".pe";
- open (FFSCRIPT, ">$ffscript") || die "${progname}: $! ($ffscript)\n";
- print FFSCRIPT <<'AUTOHINT';
-Open($1);
-SelectAll();
-RemoveOverlap();
-AddExtrema();
-Simplify(0, 2);
-CorrectDirection();
-Simplify(0, 2);
-RoundToInt();
-AutoHint();
-Generate($1);
-Quit(0);
-AUTOHINT
- ;
- close FFSCRIPT;
-}
-if (!execute_command 0, ("fontforge", "-script", $ffscript, $pfbfile)) {
- warn "${progname}: You'll need to install FontForge if you want $pfbfile autohinted (not required, but strongly recommended)\n";
-}
-unlink $ffscript if !$user_script;
-print "\n";
-
-# Finish up.
-print "*** Successfully generated $pfbfile! ***\n";
-exit 0;
-
-######################################################################
-
-__END__
-
-=head1 NAME
-
-mf2pt1 - produce a PostScript Type 1 font program from a Metafont source
-
-
-=head1 SYNOPSIS
-
-mf2pt1
-[B<--help>]
-[B<--version>]
-[B<--comment>=I<string>]
-[B<--designsize>=I<number>]
-[B<--encoding>=I<encoding>]
-[B<--family>=I<name>]
-[B<-->[B<no>]B<fixedpitch>]
-[B<--fontversion>=I<MMM.mmm>]
-[B<--fullname>=I<name>]
-[B<--italicangle>=I<number>]
-[B<--name>=I<name>]
-[B<--underpos>=I<number>]
-[B<--underthick>=I<number>]
-[B<--uniqueid>=I<number>]
-[B<--weight>=I<weight>]
-[B<--rounding>=I<number>]
-[B<--bpppix>=I<number>]
-[B<--ffscript>=I<file.pe>]
-I<infile>.mf
-
-
-=head1 WARNING
-
-The B<mf2pt1> Info file is the main source of documentation for
-B<mf2pt1>. This man page is merely a brief summary.
-
-
-=head1 DESCRIPTION
-
-B<mf2pt1> facilitates producing PostScript Type 1 fonts from a
-Metafont source file. It is I<not>, as the name may imply, an
-automatic converter of arbitrary Metafont fonts to Type 1 format.
-B<mf2pt1> imposes a number of restrictions on the Metafont input. If
-these restrictions are met, B<mf2pt1> will produce valid Type 1
-output. (Actually, it produces "disassembled" Type 1; the B<t1asm>
-program from the B<t1utils> suite will convert this to a true Type 1
-font.)
-
-=head2 Usage
-
- mf2pt1 myfont.mf
-
-=head1 OPTIONS
-
-Font parameters are best specified within a Metafont program. If
-necessary, though, command-line options can override any of these
-parameters. The B<mf2pt1> Info page, the primary source of B<mf2pt1>
-documentation, describes the following in greater detail.
-
-=over 4
-
-=item B<--help>
-
-Provide help on B<mf2pt1>'s command-line options.
-
-=item B<--version>
-
-Output the B<mf2pt1> version number, copyright, and license.
-
-=item B<--comment>=I<string>
-
-Include a font comment, usually a copyright notice.
-
-=item B<--designsize>=I<number>
-
-Specify the font design size in points.
-
-=item B<--encoding>=I<encoding>
-
-Designate the font encoding, either the name of a---typically
-F<.enc>---file which contains a PostScript font-encoding vector or one
-of C<standard> (the default), C<ot1>, C<t1>, or C<isolatin1>.
-
-=item B<--family>=I<name>
-
-Specify the font family.
-
-=item B<--fixedpitch>, B<--nofixedpitch>
-
-Assert that the font uses either monospaced (B<--fixedpitch>) or
-proportional (B<--nofixedpitch>) character widths.
-
-=item B<--fontversion>=I<MMM.mmm>
-
-Specify the font's major and minor version number.
-
-=item B<--fullname>=I<name>
-
-Designate the full font name (family plus modifiers).
-
-=item B<--italicangle>=I<number>
-
-Designate the italic angle in degrees counterclockwise from vertical.
-
-=item B<--name>=I<name>
-
-Provide the font name.
-
-=item B<--underpos>=I<number>
-
-Specify the vertical position of the underline in thousandths of the
-font height.
-
-=item B<--underthick>=I<number>
-
-Specify the thickness of the underline in thousandths of the font
-height.
-
-=item B<--uniqueid>=I<number>
-
-Specify a globally unique font identifier.
-
-=item B<--weight>=I<weight>
-
-Provide a description of the font weight (e.g., ``Heavy'').
-
-=item B<--rounding>=I<number>
-
-Specify the fraction of a font unit (0.0 < I<number> <= 1.0) to which
-to round coordinate values [default: 1.0].
-
-=item B<--bpppix>=I<number>
-
-Redefine the number of big points per pixel from 0.02 to I<number>.
-
-=item B<--ffscript>=I<file.pe>
-
-Name a script to pass to FontForge.
-
-=back
-
-
-=head1 FILES
-
-F<mf2pt1.mem> (which is generated from F<mf2pt1.mp> and F<mfplain.mp>)
-
-
-=head1 NOTES
-
-As stated in L</"WARNING">, the complete source of documentation for
-B<mf2pt1> is the Info page, not this man page.
-
-
-=head1 SEE ALSO
-
-mf(1), mpost(1), t1asm(1), fontforge(1)
-
-
-=head1 AUTHOR
-
-Scott Pakin, I<scott+mf@pakin.org>
diff --git a/Build/source/texk/texlive/linked_scripts/mkgrkindex/mkgrkindex b/Build/source/texk/texlive/linked_scripts/mkgrkindex/mkgrkindex
deleted file mode 100755
index f63f3316cfc..00000000000
--- a/Build/source/texk/texlive/linked_scripts/mkgrkindex/mkgrkindex
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/usr/bin/env perl
-#
-#(c) Copyright 1998-2009 Apostolos Syropoulos
-# asyropoulos@yahoo.com
-#
-# The LaTeX Project Public License (lppl)
-# This software is copyright but you are granted a license which gives you,
-# the "user" of the software, legal permission to copy, distribute, and/or
-# modify the software. However, if you modify the software and then distribute
-# it (even just locally) you must change the name of the software, or use other
-# technical means to avoid confusion.
-#
-$makeindex = "makeindex"; #name of the index generation utility
-sub g2e
-{
- $word = $_[0];
- $tword = "";
- foreach $_ (split(//, $word))
- {
- if (/^a|^A|^á|^Á|^Ü|^\xA2|^\xB6/) { $tword .= "a";}
- elsif (/^b|^B|^â|^Â/) { $tword .= "b"; }
- elsif (/^d|^D|^ä|^Ä/) { $tword .= "d"; }
- elsif (/^e|^E|^ĺ|^Ĺ|^Ý|^¸/) { $tword .= "e"; }
- elsif (/^i|^I|^é|^É|^ß|^ş|^Ŕ/) { $tword .= "i"; }
- elsif (/^o|^O|^ď|^Ď|^ü|^Ľ/) { $tword .= "o"; }
- elsif (/^p|^P|^đ|^Đ/) { $tword .= "p"; }
- elsif (/^g|^G|^ă|^Ă/) { $tword .= "c"; }
- elsif (/^z|^Z|^ć|^Ć/) { $tword .= "f"; }
- elsif (/^h|^H|^ç|^Ç|^Ţ|^ą/) { $tword .= "g"; }
- elsif (/^j|^J|^č|^Č/) { $tword .= "h"; }
- elsif (/^k|^K|^ę|^Ę/) { $tword .= "j"; }
- elsif (/^l|^L|^ë|^Ë/) { $tword .= "k"; }
- elsif (/^m|^M|^ě|^Ě/) { $tword .= "l"; }
- elsif (/^n|^N|^í|^Í/) { $tword .= "m"; }
- elsif (/^x|^X|^î|^Î/) { $tword .= "n"; }
- elsif (/^r|^R|^ń|^Ń/) { $tword .= "q"; }
- elsif (/^s|^c|^S|^ó|^ň|^Ó/) { $tword .= "r"; }
- elsif (/^t|^T|^ô|^Ô/) { $tword .= "s"; }
- elsif (/^u|^U|^ő|^Ő|^ý|^ľ|^ŕ/) { $tword .= "t"; }
- elsif (/^f|^F|^ö|^Ö/) { $tword .= "u"; }
- elsif (/^q|^Q|^÷|^×/) { $tword .= "v"; }
- elsif (/^y|^Y|^ř|^Ř/) { $tword .= "w"; }
- elsif (/^w|^W|^ů|^Ů|^ţ|^ż/) { $tword .= "x"; }
- elsif (/^'|^`|^~|^<|^>/) { }
- else { $tword .= $_ }
- }
- return $tword;
-}
-
-$argc = @ARGV;
-
-if ($argc == 0 || $argc > 4 ) # no command line arguments or more than 3
-{ # arguments
- die "Usage: mkgrkindex.pl [-s A|a] [-l] index\n";
-}
-else
-{
- print "This is mkgrkindex (previously known as mkindex) version 2.2\n";
-
- $style = 0;
- $is_latin = 0;
-
- SWITCHES:
- while($_ = $ARGV[0])
- {
- shift;
- if (/^-s/)
- {
- if ($ARGV[0] eq "a")
- {
- $style = -1;
- }
- elsif ($ARGV[0] eq "A")
- {
- $style = 1;
- }
- else
- {
- die "$ARGV[0]: Illegal argument for switch -s\n";
- }
- shift;
- }
- elsif (/^-l/)
- {
- $is_latin = 1;
- }
- elsif (/^-\w+/)
- {
- die "$_: Illegal command line switch!\n";
- }
- else
- {
- $file = $_;
- }
- }
- die "No index file name specified!\n" if $file eq "";
-
- if (! (-e $file))
- {
- die "$file: no such file!\n" if $file =~ /.+\..+/;
- die "$file.idx: no such file!\n" if (! (-e "$file.idx"));
- $index_file = "$file.idx";
- }
- else
- {
- $index_file = $file;
- $file = $1 if $index_file =~ /(.+)\..+/;
- }
-
-
-}
-
-
-$old_file="$index_file.old";
-
-if ($is_latin == 0)
-{
- rename $index_file, $old_file;
- open(OLD, "<$old_file") || die "Can't open file $old_file\n";
- open(NEW, ">$index_file") || die "Can't open file $index_file\n";
-
- while (<OLD>)
- {
- #\x7B = {, \x7D = },\x40 = @, \x7C = |, \x21 = !, \x28 = (, \x29 = )
- chomp;
- #Nikos Platis has suggested the replacement of the original code with a better
- #parsing method. The code that follows is essentially Nikos's code with
- #some minnor modifications, as explained in the documentation.
- $newentry = "";
- /^\\indexentry\x7B(.+)\x7D(.+)/;
- $fullentry = $1;
- $page = $2;
- ($indexentry, $format) = split(/(?<!")\x7C/, $fullentry);
- @entryparts = split(/(?<!")\x21/, $indexentry);
- $numparts = @entryparts;
- for ($i = 0; $i < $numparts; $i++) {
- ($x, $y) = split(/(?<!")\x40/, @entryparts[$i]);
- if ($i > 0) {
- $newentry .= "!"
- }
- $tx = g2e($x);
- if ($y) {
- $newentry .= "$tx\@$y"
- }
- else {
- $newentry .= "$tx\@$x";
- }
- }
- print NEW "\\indexentry{$newentry";
- if ($format) {
- print NEW "|$format"
- }
- print NEW "}$page\n"
- }
-
- close OLD;
- close NEW;
- unlink $old_file;
-}
-
-rename $index_file, $old_file;
-open(OLD, "<$old_file") || die "Can't open file $old_file\n";
-open(NEW, ">$index_file") || die "Can't open file $index_file\n";
-
-while(<OLD>)
-{
- chomp($_);
- if (/\\indexentry\x7B(.+)\x7D\x7B\\textlatin\s*?\x7B(\w+)\x7D\x7D/)
- {
- print NEW "\\indexentry{$1|textlatin}{$2}\n";
- }
- else
- {
- print NEW "$_\n";
- }
-}
-
-
-close OLD;
-close NEW;
-unlink $old_file;
-
-
-if ($style < 0)
-{
- system("$makeindex -s lowercase-headers.ist $file");
-}
-elsif ($style > 0)
-{
- system("$makeindex -s uppercase-headers.ist $file");
-}
-else
-{
- system("$makeindex $file");
-}
-
-if ($style != 0)
-{
-
-
- %e2g = (
- 'a' => 'á', 'A' => 'Á',
- 'b' => 'â', 'B' => 'Â',
- 'c' => 'ă', 'C' => 'Ă',
- 'd' => 'ä', 'D' => 'Ä',
- 'e' => 'ĺ', 'E' => 'Ĺ',
- 'f' => 'ć', 'F' => 'Ć',
- 'g' => 'ç', 'G' => 'Ç',
- 'h' => 'č', 'H' => 'Č',
- 'i' => 'é', 'I' => 'É',
- 'j' => 'ę', 'J' => 'Ę',
- 'k' => 'ë', 'K' => 'Ë',
- 'l' => 'ě', 'L' => 'Ě',
- 'm' => 'í', 'M' => 'Í',
- 'n' => 'î', 'N' => 'Î',
- 'o' => 'ď', 'O' => 'Ď',
- 'p' => 'đ', 'P' => 'Đ',
- 'q' => 'ń', 'Q' => 'Ń',
- 'r' => 'óv', 'R' => 'Ó',
- 's' => 'ô', 'S' => 'Ô',
- 't' => 'ő', 'T' => 'Ő',
- 'u' => 'ö', 'U' => 'Ö',
- 'v' => '÷', 'V' => '×',
- 'w' => 'ř', 'W' => 'Ř',
- 'x' => 'ů', 'X' => 'Ů'
- );
-
- $ind_file = "$file.ind";
- $old_file="$ind_file.old";
-
- if ($is_latin == 0)
- {
- rename $ind_file, $old_file;
- open(OLD, "<$old_file") || die "Can't open file $old_file\n";
- open(NEW, ">$ind_file") || die "Can't open file $ind_file\n";
-
- while (<OLD>)
- {
- if (/^{\\hfil (\w?) \\hfil}/)
- {
- $lettergr = $e2g{$1};
- print NEW "{\\hfil $lettergr \\hfil}\\nopagebreak\n";
- }
- else
- {
- print NEW ;
- }
- }
-
- close OLD;
- close NEW;
- unlink $old_file;
- }
-
- rename $ind_file, $old_file;
- open(OLD, "<$old_file") || die "Can't open file $old_file\n";
- open(NEW, ">$ind_file") || die "Can't open file $ind_file\n";
-
- while (<OLD>)
- {
- if (/^\x7B\\hfil (\w)ymbols \\hfil\x7D/)
- {
- if ($1 eq "s")
- {
- print NEW "{\\hfil \\textgreek{\\textbf{s'umbola}}";
- print NEW "\\hfil}\\nopagebreak\n";
- }
- elsif ($1 eq "S")
- {
- print NEW "{\\hfil \\textgreek{\\textbf{S'umbola}}";
- print NEW "\\hfil}\\nopagebreak\n";
- }
- else
- {
- die "Illegal header $1 in .ind file\n";
- }
- }
- else
- {
- print NEW;
- }
- }
-
- close OLD;
- close NEW;
- unlink $old_file;
-
-}
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/mkjobtexmf/mkjobtexmf.pl b/Build/source/texk/texlive/linked_scripts/mkjobtexmf/mkjobtexmf.pl
deleted file mode 100755
index c46f4f4a102..00000000000
--- a/Build/source/texk/texlive/linked_scripts/mkjobtexmf/mkjobtexmf.pl
+++ /dev/null
@@ -1,995 +0,0 @@
-#!/usr/bin/env perl
-#
-# ToDos/unsolved problems:
-# * collision of symbol links
-# * texmf.cnf (path settings, variables)
-# * aliases
-# * binaries, libraries
-#
-use strict;
-$^W=1;
-
-my $prj = 'mkjobtexmf';
-my $version = '0.8';
-my $date = '2011/11/10';
-my $author = 'Heiko Oberdiek';
-my $copyright = "Copyright 2007, 2008, 2011 $author";
-
-my $cmd_tex = 'pdflatex';
-my $cmd_kpsewhich = 'kpsewhich';
-my $cmd_texhash = 'texhash';
-my $cmd_strace = 'strace';
-my $ext_tex = '.tex';
-my $ext_recorder = '.fls';
-my $ext_strace = '.strace';
-my $ext_mkjobtexmf = '.mjt';
-my $jobname = '';
-my $texname = '';
-my $destdir = '';
-my @args = ();
-my @texopt = ();
-my $verbose = 0;
-my $output = 0;
-my $strace = 0;
-my $copy = 0;
-my $flat = 0;
-my $texhash = 1;
-my $needs_texhash = 0;
-my @texmf;
-my @exclude_ext;
-my %files;
-my %links;
-my %flat_ignore = (
- 'ls-R' => '',
- 'aliases' => '',
-);
-my $win = 0;
-$win = 1 if $^O =~ /MSWin/i;
-
-my $title = "\U$prj\E $date v$version, $copyright\n";
-
-sub die_error ($) {
- my $msg = shift;
- die "!!! Error: $msg!\n";
-}
-
-sub warning ($) {
- my $msg = shift;
- print "!!! Warning: $msg!\n";
-}
-
-sub verbose (@) {
- my @msg = @_;
- print "* @msg\n" if $verbose;
-}
-
-sub value ($) {
- my $value = $_[0];
- "[$value]";
-}
-
-sub die_usage {
- my $msg = $_[0];
- pod2usage(
- -exitstatus => 2,
- -msg => "\n==> $msg!\n");
-}
-
-use Getopt::Long;
-use Pod::Usage;
-
-my $man = 0;
-my $help = 0;
-my $opt_version = 0;
-
-GetOptions(
- 'jobname=s' => \$jobname,
- 'texname=s' => \$texname,
- 'texopt=s' => \@texopt,
- 'destdir=s' => \$destdir,
- 'cmd-tex=s' => \$cmd_tex,
- 'cmd-kpsewhich=s' => \$cmd_kpsewhich,
- 'cmd-texhash=s' => \$cmd_texhash,
- 'cmd-strace=s' => \$cmd_strace,
- 'strace' => \$strace,
- 'copy' => \$copy,
- 'flat' => \$flat,
- 'texhash!' => \$texhash,
- 'exclude-ext=s' => \@exclude_ext,
- 'verbose' => \$verbose,
- 'output' => \$output,
- 'help|?' => \$help,
- 'man' => \$man,
- 'version' => \$opt_version,
-) or die_usage('Unknown option');
-if ($help) {
- print $title;
- pod2usage(1);
-}
-pod2usage(-exitstatus => 0, -verbose => 2) if $man;
-
-if ($opt_version) {
- print "$prj $date v$version\n";
- exit(0);
-}
-
-print $title;
-
-if (@ARGV > 0) {
- $strace = 1;
- $texname = '';
- my @args = @ARGV;
-}
-$jobname or die_usage('Missing jobname');
-$texname = "$jobname$ext_tex" unless $texname;
-$destdir = "$jobname$ext_mkjobtexmf" unless $destdir;
-
-verbose "jobname: " . value $jobname;
-verbose "texname: " . value $texname if $texname;
-verbose "command: " . value "@args" if @args;
-verbose "destdir: " . value $destdir;
-verbose "system: ". value $^O;
-
-@exclude_ext = split(/,/, join(',', @exclude_ext));
-foreach my $ext (@exclude_ext) {
- verbose "exclude-ext: " . value $ext;
-}
-
-if (!$copy) {
- my $symlink_exists = eval { symlink('', ''); 1 };
- if ($symlink_exists) {
- verbose "symbolic linking: supported";
- }
- else {
- $copy = 1;
- verbose "symbolic linking: unsupported";
- }
-}
-my $umask = umask;
-if (defined($umask)) {
- verbose "umask: " . sprintf("%04o", $umask);
-}
-else {
- $umask = 0;
- verbose "umask: unsupported";
-}
-
-if ($copy) {
- use File::Copy;
-}
-if ($flat) {
- use File::Basename;
-}
-
-sub check_child_error () {
- if ($? != 0) {
- if ($? == -1) {
- die_error "Failed to execute: $!";
- }
- elsif ($? & 127) {
- die_error sprintf "Child died with signal %d, %s coredump",
- ($? & 127), ($? & 128) ? 'with' : 'without';
- }
- else {
- die_error sprintf "Child exited with value %d", $? >> 8;
- }
- }
- verbose "child exit: ok";
-}
-
-sub run_generic (@) {
- my @args = @_;
- my $cmd = $_[0];
- verbose "exec: " . value "@args";
- print '>' x 79, "\n";
- system $cmd @args;
- print '<' x 79, "\n";
- check_child_error;
-}
-
-sub run_tex {
- if ($strace) {
- my @run_args;
- if (@args) {
- @run_args = @args;
- }
- else {
- @run_args = (
- $cmd_tex,
- '-interaction=nonstopmode',
- @texopt,
- $texname
- );
- }
- run_generic(
- $cmd_strace,
- '-f',
- '-e',
- 'trace=open,access', # trace=file
- '-o',
- "$jobname$ext_strace",
- @run_args
- )
- }
- else {
- run_generic(
- $cmd_tex,
- '-recorder',
- "-jobname=$jobname",
- '-interaction=nonstopmode',
- @texopt,
- $texname
- );
- }
-}
-
-sub run_texhash {
- return unless $texhash;
- return if $flat;
- if ($needs_texhash) {
- my $cmd_version = "$cmd_texhash --version";
- verbose "exec: $cmd_version";
- print '>' x 79, "\n";
- my @lines = `$cmd_version`;
- print @lines if $verbose;
- print '<' x 79, "\n";
- if ($? != 0) {
- if ($? == -1) {
- verbose "Execution failed: $!";
- }
- elsif ($? & 127) {
- verbose sprintf "Execution died with signal %d, %s coredump",
- ($? & 127), ($? & 128) ? 'with' : 'without';
- }
- else {
- verbose sprintf "Execution failed with error code: %d",
- $? >> 8;
- }
- }
- else {
- my $catch = "@lines";
- if ($catch =~ /(kpathsea|mktexlsr)/i) {
- run_generic(
- $cmd_texhash,
- "$destdir/texmf"
- );
- }
- else{
- verbose 'Unsupported port of texhax found.';
- }
- }
- }
- else {
- verbose("Run of texhash skipped, no files added.");
- }
-}
-
-use Cwd 'abs_path', 'getcwd';
-
-my $pwd = getcwd;
-verbose "pwd: " . value($pwd);
-
-sub get_texmf_trees () {
- return if $flat;
- my $cmdline = "$cmd_kpsewhich -expand-path='\$TEXMF'";
- $cmdline = "$cmd_kpsewhich -expand-path=\$TEXMF" if $win;
- verbose "exec: " . value($cmdline);
- my $str = `$cmdline`;
- check_child_error;
- $str =~ s/[\r\n]+$//;
- if ($win) {
- @texmf = split ';', $str;
- }
- else {
- @texmf = split ':', $str;
- }
- my %texmf;
- foreach my $texmf (@texmf) {
- $texmf{$texmf} = '';
- $texmf{abs_path($texmf)} = '';
- }
- @texmf = sort keys %texmf;
- if (@texmf == 0 and $win) {
- my $cmdline = "$cmd_kpsewhich --show-path=tfm";
- verbose "exec: " . value($cmdline);
- my $str = `$cmdline`;
- check_child_error;
- $str =~ s/[\n\r]+$//;
- foreach my $texmf (split ';', $str) {
- if ($texmf =~ m|^(.*)/fonts/tfm/*$|) {
- push @texmf, $1;
- }
- }
- }
- if ($verbose) {
- if (@texmf) {
- map { verbose 'texmf: ' . value($_) } @texmf;
- }
- else {
- verbose 'texmf: none';
- }
- }
-}
-
-sub add_file ($) {
- my $file = shift;
- my $add = 1;
- foreach my $ext (@exclude_ext) {
- my $ext = ".$ext";
- my $len_ext = length $ext;
- my $len_file = length $file;
- if ($len_file >= $len_ext) {
- if ($ext eq substr $file, $len_file - $len_ext) {
- $add = 0;
- verbose "excluded: " . value($file);
- last;
- }
- }
- }
- $files{$file} = '' if $add;
-}
-
-sub analyze_recorder {
- my $file_rec = $jobname . ($strace ? $ext_strace : $ext_recorder);
- verbose 'File with recorded file names: ' . value($file_rec);
- open(IN, '<', $file_rec)
- or die_error "Cannot open `$file_rec'";
- if ($strace) {
- while (<IN>) {
- chomp;
- next if /\)\s+= -\d/; # -1 ENOENT, ...
- next if /\WO_DIRECTORY\W/; # skip directories
- my $type = 'INPUT';
- if ($output) {
- $type = 'OUTPUT' if /\WO_WRONLY\W/;
- }
- else {
- next if /\WO_WRONLY\W/;
- }
- /^\d+\s+\w+\(\"([^"]+)\",/ or warning "Unknown entry `$_'";
- my $file = $1;
- add_file $file;
- }
- }
- else {
- while (<IN>) {
- chomp;
- next if /^PWD /;
- next if not $output and /^OUTPUT /;
- /^(INPUT|OUTPUT) (.*)$/ or warning "Unknown entry `$_'";
- my $type = $1;
- my $file = $2;
- add_file $file;
- }
- }
- close(IN);
-}
-
-sub map_files {
- if ($flat) {
- map_files_flat();
- }
- else {
- map_files_texmf();
- }
-}
-
-sub map_files_flat {
- my %abs_files;
- my %names;
- my %clashes;
-
- foreach my $file (keys %files) {
- $abs_files{abs_path($file)} = '';
- }
-
- foreach my $file (keys %abs_files) {
- my $name = basename($file);
- next if exists $flat_ignore{$name};
- if (defined($names{$name})) {
- push @{$names{$name}}, $file;
- $clashes{$name} = '';
- }
- else {
- my @a = ($file);
- $names{$name} = \@a;
- }
- }
-
- foreach my $name (sort keys %clashes) {
- print "* file name clash for " . value($name) . "\n";
- my @a = @{$names{$name}};
- foreach my $file (@a) {
- print " " . value($file) . "\n";
- }
- }
-
- foreach my $name (sort keys %names) {
- my $file = @{$names{$name}}[0];
- my $clash = $clashes{$name} ? ' (clash)' : '';
- verbose value($name) . ' => ' . value($file) . $clash;
- $links{$name} = $file;
- }
-}
-
-sub map_files_texmf {
- my @failed;
- my $pwd_dir = "$pwd/";
- my $pwd_len = length $pwd_dir;
-
- foreach my $file (sort keys %files) {
- verbose "file: " . value($file);
-
- my $abs_file = abs_path($file);
-
- my $found = '';
- if ($pwd_dir eq substr $file, 0, $pwd_len) {
- $found = substr $file, $pwd_len;
- }
- if (not $found) {
- foreach (@texmf) {
- my $texmf = "$_/";
- my $len = length($texmf);
- my $str = substr $file, 0, $len;
- if ($texmf eq $str) {
- $found = 'texmf/' . substr $file, $len;
- if ($found =~ /(^|\/)\.\.\//) {
- $found = '';
- }
- }
- last if $found;
- my $str = substr $abs_file, 0, $len;
- if ($texmf eq $str) {
- $found = 'texmf/' . substr $abs_file, $len;
- last;
- }
- }
- }
- if (not($found)) {
- if ($file =~ /(^|\/)\.\.\// or $file =~ /^\//) {
- push @failed, $file;
- }
- else {
- $found = $file;
- }
- }
- if ($found) {
- $links{$found} = abs_path($file);
- }
- }
-
- if ($verbose) {
- foreach (sort keys %links) {
- verbose value($_) . ' => ' . value($links{$_});
- }
- }
-
- foreach (@failed) {
- print "!!! Failed: " . value($_) . "\n";
- }
-}
-
-sub make_dirs ($) {
- my $path = shift;
- my @elems = split /\/+/, $path;
- if (@elems <= 1) {
- return 1;
- }
- pop @elems;
- my $dir = '';
- foreach my $elem (@elems) {
- $dir .= '/' if $dir;
- $dir .= $elem;
- next if -d $dir;
- if (mkdir $dir) {
- verbose 'mkdir: ' . value($dir);
- next;
- }
- return 0;
- }
- return 1;
-}
-
-sub make_links {
-
- foreach my $key (sort keys %links) {
- my $source = $links{$key};
- my $dest = "$destdir/$key";
- my $result_mkdir = make_dirs $dest;
- if (not $result_mkdir) {
- if ($key =~ s|^([A-Za-z]):/|$1/|) {
- $dest = "$destdir/$key";
- $result_mkdir = make_dirs $dest;
- }
- if (not $result_mkdir) {
- die_error("Cannot create directory `$dest'");
- }
- }
- if (-e $dest) {
- my $type = '';
- if (-l $dest) {
- $type .= 'link';
- }
- elsif (-f $dest) {
- $type = 'file';
- }
- elsif (-d $dest) {
- $type = 'directory';
- }
- elsif (-b $dest) {
- $type = 'block device';
- }
- elsif (-c $dest) {
- $type = 'character device';
- }
- elsif (-p $dest) {
- $type = 'pipe';
- }
- elsif (-S $dest) {
- $type = 'socket';
- }
- elsif (-t $dest) {
- $type = 'tty';
- }
- $type = " ($type)" if $type;
- verbose "destination$type exists: " . value($dest);
- next;
- }
- $needs_texhash = 1;
- do_link_copy($source, $dest);
- }
-}
-
-sub do_link_copy {
- my $source = shift;
- my $dest = shift;
- my $success = 0;
-
- if ($copy) {
- if (copy($source, $dest) == 1) {
- $success = 1;
- my ($source_mode, $source_atime, $source_mtime)
- = (stat($source))[2, 8, 9];
- my ($dest_mode, $dest_atime, $dest_mtime)
- = (stat($dest))[2, 8, 9];
- # preserve executable permissions if necessary
- my $new_dest_mode = $dest_mode
- | (($source_mode & 0111) & ~$umask);
- if ($new_dest_mode != $dest_mode) {
- if (chmod($new_dest_mode, $dest) < 1) {
- print "!!! Setting executive mode failed: "
- . value($dest) . "\n";
- }
- }
- # preserve file times
- if ($source_atime != $dest_atime
- || $source_mtime != $dest_mtime) {
- if (utime($source_atime, $source_mtime, $dest) < 1) {
- print "!!! Setting file times failed: "
- . value($dest) . "\n";
- }
- }
- }
- }
- else {
- if (symlink($source, $dest) == 1) {
- $success = 1;
- }
- }
- if ($success == 0) {
- my $method = $copy ? 'Copying' : 'Symbolic linking';
- print "!!! $method failed:\n "
- . value($dest) . ' => ' . value($source) . "\n";
- }
-}
-
-run_tex;
-get_texmf_trees;
-analyze_recorder;
-map_files;
-make_links;
-run_texhash;
-
-1;
-
-__DATA__
-
-=head1 NAME
-
-mkjobtexmf -- Generate a texmf tree for a particular job
-
-=head1 VERSION
-
-2011-11-10 v0.8
-
-=head1 SYNOPSIS
-
-The progam B<mkjobtexmf> runs a program and tries to
-find the used file names. Two methods are available,
-option C<-recorder> of TeX (Web2C) or the program B<strace>.
-
-Then it generates a directory with a texmf tree. It checks
-the found files and tries sort them in this texmf tree.
-
-It can be used for archiving purposes or to speed up
-following TeX runs.
-
- mkjobtexmf [options]
-
-This runs TeX that can be configured by options.
-Both methods for getting the used file names are available.
-
- mkjobtexmf [options] -- <cmd> [args]
-
-The latter form runs program I<cmd> with arguments I<args>
-instead of TeX. As method only program B<strace> is available.
-
-Options:
-
- --jobname <name> Name of the job (mandatory).
- Usually this is the TeX file
- without extension
- --texname <file> Input file for TeX. Default is the
- job name with extension '.tex'
- --texopt <option> Option for TeX run
- --destdir <directory> Destination directory,
- default is `<jobname>.mjt'
- --output Add also output files
- --strace Use strace instead of TeX's
- option -recorder
- --copy Copy files instead of creating
- symbol links
- --flat Junk paths, do not make directories
- inside the destination directory
- --(no)texhash Run texhash, use --notexhash for MiKTeX
- --exclude-ext <ext> Exclude files with extension <ext>.
- --cmd-tex <cmd> Command for the TeX compiler
- --cmd-kpsewhich <cmd> Command for kpsewhich
- --cmd-texhash <cmd> Command for texhash
- --cmd-strace <cmd> Command for strace
- --verbose Verbose output
- --help Brief help message
- --man Full documentation
- --version Print version identification
-
-=head1 DESCRIPTION
-
-=head2 Running the program
-
-First B<mkjobtexmf> runs a program, usually TeX. The TeX compiler
-is configured by option C<--cmd-tex>. Option C<--texname> can
-be used, if the file name extension differs from F<.tex>:
-
- mkjobtexmf --jobname foo --texname foo.ltx
-
-Even more complicate cases are possible:
-
- mkjobtexmf --jobname foo --texname '\def\abc{...}\input{foo}'
-
-If another program than TeX should be used (dvips, ...),
-then this program can be given after C<-->:
-
- mkjobtexmf --jobname foo -- dvips foo
-
-=head2 File recording
-
-Two methods are available to get the used file names:
-
-=over
-
-=item Recorder of TeX
-
-Some TeX distributions (e.g. Web2C) support the option B<-recorder>
-for its TeX compilers. Then the TeX compiler generates a file with
-extension F<.fls> that records the used input and output files.
-
-=item Program strace
-
-This program traces system calls and signals. It is used here
-to log the used files.
-
-=back
-
-=head2 Analyze and link/copy found files
-
-The result directory F<I<jobname>.mjt> is generated. Inside the
-result TEXMF tree is created. Each found file is compared against
-a list of paths of TEXMF trees. If a match is found, the file is
-linked/copied into the TEXMF tree. The list of paths is generated by
-program B<kpsewhich>.
-
-If the file cannot be mapped to a TEXMF tree and the file is
-a relative file name, then it is directly linked/copied into the
-result directory F<I<jobname>.mjt>. Absolute file names
-are not supported and neither paths with links to parent directories.
-
-Symbolic links are created by default. The files are copied
-if option C<--copy> is given or symbolic linking is not available.
-
-=head1 OPTIONS
-
-=over
-
-=item B<->B<-jobname>=<I<jobname>>
-
-It is the name of the job. `<I<jobname>>.tex' serves as default for
-the TeX file and <I<jobname>> is used for naming various directories
-and files. See section L<"FILES">.
-
-=item B<->B<-texname>=<I<name>>
-
-The name of the TeX input file, if it differs from <I<jobname>>.tex.
-
-=item B<->B<-texopt>=<I<opt>>
-
-Additional option for the TeX compiler, examples are C<--ini> or
-C<--shell-escape>. This option can be given more than once.
-
-=item B<->B<-destdir>=<I<directory>>
-
-Specifies the name of the destination directory where the result
-is collected. As default a directory is generated in the current
-directory with the job name and extension `.mjt'.
-
-=item B<->B<-output>
-
-Also add output files.
-
-=item B<->B<-strace>
-
-Use method with program B<strace>, see L<"DESCRIPTION">.
-
-=item B<->B<-copy>
-
-Files are copied instead of creating symbolic links.
-
-=item B<->B<-flat>
-
-Files are linked or copied without path elements.
-The destination directory will contain a flat list of
-files or links without directory.
-
-The files `ls-R' and `aliases' are ignored.
-
-=item B<->B<-exclude-ext>=<I<ext>>
-
-Files with extension <I<ext>> are excluded. The option can be
-given several times or a comma separated list of extensions
-can be used. Examples:
-
- --exclude-ext aux --exclude-ext log --exclude-ext toc
-
-is the same as
-
- --exclude-ext aux,log,toc
-
-=item B<->B<-(no)texhash>
-
-As default the file `ls-R' is generated in the `texmf' tree,
-because this is the file name database that might be used
-in TeX Live. Because MiKTeX uses a different mechanism, its
-`texhash' does not generate the `ls-R' files and C<--notexhash>
-suppresses the call of `texhash'.
-
-=item B<->B<-cmd-tex>=<I<cmd>>
-
-Command for the TeX compiler. Default is pdflatex.
-
-=item B<->B<-cmd-kpsewhich>=<I<cmd>>
-
-Command for kpsewhich.
-
-=item B<->B<-cmd-texhash>=<I<cmd>>
-
-Command for updating the file name database of the generated
-texmf tree. Default is texmf.
-
-=item B<->B<-cmd-strace>=<I<cmd>>
-
-Command for strace.
-
-=item B<->B<-verbose>
-
-Verbose messages.
-
-=item B<->B<-help>
-
-Display help screen.
-
-=item B<->B(-man>
-
-Print manual page.
-
-=item B<->B<-version>
-
-Print version identification and exit.
-
-=back
-
-=head1 EXAMPLES
-
-TeX file F<test.tex> using TeX's recorder method:
-
- mkjobtexmf --jobname test
-
-TeX file F<test.tex> using LaTeX:
-
- mkjobtexmf --jobname test --cmd-tex latex
-
-Format generation:
-
- mkjobtexmf --jobname test --texopt -ini --texname pdflatex.ini
-
-Example, how the new texmf tree (Linux/bash) can be used:
-
- TEXMF=!!test.mjt/texmf pdflatex test
-
-Example for generating a zip archive (Linux/bash):
-
- (cd test.mjt && zip -9r ../test .)
-
-Example for generating a tar archive:
-
- tar cjhvf test.tar.bz2 -C test.mjt .
-
-=head1 UNSOLVED ISSUES, CAVEATS, TODOS
-
-=over
-
-=item Experimental software
-
-Options, defaults, how the program works might change in
-future versions.
-
-=item F<texmf.cnf>
-
-Currently the method with B<strace> records this files.
-TeX's recorder does not. Useful are F<texmf.cnf> files for
-variable settings. Because we have just one TEXMF tree,
-the path sections should probably rewritten.
-
-=item Settings in environment variables
-
-They are not stored at all.
-
-=item Collisions
-
-The program uses one destination directory and at most
-one TEXMF tree for the result. However, the source files
-can come from different directories and TEXMF trees.
-Therefore name collisions are possible.
-
-The program follows the strategy not to delete files
-in the destination directory. That allows to collect files
-from differnt runs. Thus collisions are resolved
-in the manner that the first entry that is made in
-the destination directory wins.
-
-=item Configuration file
-
-It would save the user from retyping the same options again and again.
-
-=item Uncomplete recording
-
-Bugs in TeX's file recording might result in incomplete
-file recording (e.g. pdfTeX 1.40.3 does not record .pfb and
-.pk files).
-
-=item ...
-
-=back
-
-=head1 FILES
-
-=over
-
-=item F<E<lt>jobnameE<gt>.mjt/>
-
-Directory where the resulting texmf tree and symbol links
-are stored. It can be changed by option C<--destdir>.
-
-=item F<E<lt>jobnameE<gt>.fls>
-
-Name of TeX's recorder file.
-
-=item F<E<lt>jobnameE<gt>.strace>
-
-Log file where the result of B<strace> is stored.
-
-=back
-
-=head1 AUTHOR
-
-Heiko Oberdiek, email: heiko.oberdiek at googlemail.com
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2007, 2008, 2011 by Heiko Oberdiek.
-
-This library is free software; you may redistribute it and/or
-modify it under the same terms as Perl itself
-(Perl Artistic License/GNU General Public License, version 2).
-
-=head1 HISTORY
-
-=over 2
-
-=item B<2007/04/16 v0.1>
-
-=over 2
-
-=item * First experimental version.
-
-=back
-
-=item B<2007/05/09 v0.2>
-
-=over 2
-
-=item * Typo in option name fixed.
-
-=back
-
-=item B<2007/09/03 v0.3>
-
-=over 2
-
-=item * New options: C<--copy>, C<--flat>, C<--destdir>
-
-=back
-
-=item B<2007/09/04 v0.4>
-
-=over 2
-
-=item * Bug fix in map_files_texmf.
-
-=back
-
-=item B<2007/09/06 v0.5>
-
-=over 2
-
-=item * Support for `configure' added.
- (Thanks to Norbert Preining for writing a first version of
- the configure stuff.)
-
-=back
-
-=item B<2008/04/05 v0.6>
-
-=over 2
-
-=item * Tiny fix in target `uninstall' in file `Makefile.in'.
- (Thanks to Karl Berry)
-
-=back
-
-=item B<2008/06/28 v0.7>
-
-=over 2
-
-=item * Fix for unknown option `C<--cmd-strace>'.
- (Thanks to Juho Niemelä)
-
-=back
-
-=item B<2011/11/10 v0.8>
-
-=over 2
-
-=item * Remove colon from drive specification when making directories.
-
-=item * Option C<--(no)texhash> added.
-
-=item * Some support for MiKTeX (thanks Ulrike Fischer).
-
-=item * Various fixes in the generation of the documentation.
-
-=item * Options C<--exclude-ext> and C<--version> added.
-
-=back
-
-=back
-
-=cut
diff --git a/Build/source/texk/texlive/linked_scripts/mkpic/mkpic b/Build/source/texk/texlive/linked_scripts/mkpic/mkpic
deleted file mode 100755
index 2625171b37e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/mkpic/mkpic
+++ /dev/null
@@ -1,864 +0,0 @@
-#!/usr/bin/env perl
-
-use constant
-Version => '1.02';
-
-my $help =
-<<'DOC'
-= mkpic - interface for making pictures with mfpic
-
-= Synopsis
-mkpic [options] [picfile]
-
-Options:
--c,--clean remove all but the input file and die
--p,--pdfsample create pdf file with sample images
--f,--font=<font command> set default font for labels
- --[no]box produce framed boxes
--V,--version report version number and die
--h,--help display help info and die
- --[no]debug display debugging information
--l,--log=<logfile> file for warning messages
-
-Without an input file, the DATA section is used.
-
-= Command overview
-begin name xl yl xmin ymin xmax ymax xlabel ylabel
-end
-stop
-var=value
-# comment
-
-arccst xcenter ycenter xstart ystart theta
-arcset xstart ystart xend yend theta
-arccrtt xcenter ycenter radius theta1 theta2
-arc3 x1 y1 x2 y2 x3 y3
-
-xmark [label1] x1 [label2] x2 ...
-Xmark [label1] x1 [label2] x2 ...
-ymark [label1] y1 [label2] y2 ...
-Ymark [label1] y1 [label2] y2 ...
-
-xdrop x y
-ydrop x y
-xydrop x y
-
-arrow x1 y1 x2 y2 label
-label YX x y label
-xlabels YX x y dx label ...
-ylabels YX x y dy label ...
-
-point x1 y1 x2 y2 ...
-dpoint x1 y1 dx1 dy1 ...
-lines x1 y1 x2 y2 ...
-dlines x1 y1 dx1 dy1 ...
-curve x1 y1 x2 y2 ...
-dcurve x1 y1 dx1 dy1 ...
-
-rect x1 y1 x2 y2
-drect x y dx dy
-dcrect x y dx dy
-crect x1 y1 x2 y2
-arect xc yc width height theta
-bar x xdev height
-
-func xmin xmax step expression-in-x
-
-grid dx dy xgap ygap
-hatch
-bhat
-ehat
-
-= Description
-mkpic provides an easy interface for making small pictures with mfpic. To
-this end you create an input file has to be created consisting of
-commands, one per line, with space separated parameters (or you modify the
-DATA section of the mkpic script, which is used if you run it without an
-input file). For an extensive description see the file mkpicdoc.pdf, which
-is part of the distribution.
-
-mkpic produces two files. Assuming an input file named |picfile| defaulting
-to |mkpic| these are:
-
-picfile.mac
- a macro file which will contain |TeX| commands for every picture
-picfile.sty
- a style file for latex, defining the same |TeX| commands for every picture.
-
-With the |--pdfsample| option, two other files are produced:
-
-picfile.pdf
- a PDF file containing all pictures.
- This lets you easily check the results of your designs.
-
-picfile.tex
- the |TeX| source used for creating this PDF file.
-
-In |LaTeX|, you have to include |\usepackage{picfile}| and to include
-commands like |\Fig|/name/ in your source, where /name/ is the
-name you gave one of your pictures in an mkpic |begin| command.
-
-In TeX and ConTeXt, you have to |\input picfile.mac| and to
-include commands like |\Fig|/name/ in your source, where /name/ is
-the name you gave one of your pictures in an mkpic |begin| command.
-
-In TeX, you must use the |\bye| command (/not/ |\end| to finish your TeX source
-
-See the RUNNING section for how to run mkpic and TeX, LaTeX, or ConTeXt.
-
-= Commands
-The source is set up so that it is easy to add your own commands,
-Currently the following commands have been implemented (the arguments
-are not listed here; for those, refer to the SYNOPSIS section):
-
-begin, end
- Every picture begins with the |begin| command and ends with the |end|
- command. The |begin| command defines a name for the picture and
- defines a tex command with that name, prefixed with 'Fig'. The
- resulting command is written to a |.mac| file. Thus the command
-
- begin aa ...
-
- starts writing |\def\Figaa{...| to the |.mac| file, and the
- picture can be reproduced in a |TeX| document by importing the |.mac| file
- and using the |\Figaa| command.
-
- xl and yl are the lengths of the x- and y-axes. xlabel and ylabel are
- the label that are placed at the ends of those axes. Use a space to
- suppress labeling, or "-" to suppress drawing the axes at all.
-
-stop
- stops further reading of the input. Useful if you have many pictures,
- but want to see only the first few for testing purposes.
-
-var=value
- sets the variable var to value. This variable, or an expression containing it,
- can be used instead of any numerical parameter. Variable names may contain
- lower and uppercase letters, digits or underscores, with the restriction that
- they must start with a letter and may not end in an underscore.
-
-#
- denotes a comment
-
-xmark, ymark, Xmark, Ymark
- These commands place one or more labels along the x- or y-axes, either
- below (|xmark| and |ymark|) or above (|Xmark| and |Ymark|) the axis.
-
- For the |[xXyY]mark| commands a parameter containing any character
- other than [-.0-9] is interpreted as the label (this implies that you
- cannot use expressions here!) to be placed and its position is expected
- in the next parameter. If a parameter is just a number, it is placed at
- that x-position. If you want a number to be interpreted as a label, put
- it in braces: |{1950}|.
-
-arccst
- (Mnemonic: |c|enter |s|tart |t|heta.)
- Draws an arc with its center in |xcenter,ycenter|, starting in |xstart,ystart|
- and with an arc length of |theta| degrees.
-
-arcset
- (Mnemonic: |s|tart |e|nd |t|heta.)
- Draws an arc starting in |xstart,ystart|end ending in |xend,yend|
- and with an arc length of |theta| degrees.
-
-arccrtt
- (Mnemonic: |c|enter |r|adius |t|heta1 |t|heta2.)
- Draws an arc with its center in |xcenter,ycenter|, a radius |radius|
- starting at |theta1| degrees and ending at |theta2| degrees.
-
-arc3
- (Mnemonic: |3| points.)
- Draws an arc starting at |(x1,y1)|, through |(x2,y2)| and ending in |(x3,y3)|.
-
-xdrop, ydrop, xydrop
- These commands draw dotted arrows perpendicularly to the x-axis, the
- y-axis and both axes, respectively, ending on the axes with the
- arrow head.
-
-arrow
- draws an arrow from |(x1,y1)| to |(x2,y2)| labeled on its tail with
- |label|
-
-label
- draws a label at |(x,y)|. |YX| tells how it will be adjusted: for
- Y=t,b,c |(x,y)| will be, in the y-direction, on top, bottom or center
- of the label respectively, for X=l,r,c it will be, in the x-direction,
- left, right or center adjusted on |(x,y)|. Thus
-
- label tl 0 0 Hello World!
-
- will draw the string "Hello World" with its lower left corner at (0,0)
-
-xlabels
- draws many labels, starting at |(x,y)|, and incrementing |x| with |dx|
- after every label. |YX|: see |label|. Labels may not contain spaces;
- if you need spaces, use - instead.
-
-ylabels
- Same as |xlabels|, but incrementing |y| with |dy| instead.
-
-point
- draws points (dots) at |(x1,y1)|, |(x2,y2)| et cetera.
-
-dpoint
- draws points (dots) starting at |(x1,y1)| and then moving by
- |(dx1,dy1)|, |(dx2,dy2)| et cetera.
-
-lines
- draws line segments from |(x1,y1)| to |(x2,y2)|, |(x3,y3)| et cetera.
-
-dlines
- draws line segments starting at |(x1,y1)| and then moving by
- |(dx1,dy1)|, |(dx2,dy2)| et cetera.
-
-curve
- draws a bezier curve from |(x1,y1)| to |(x2,y2)|, |(x3,y3)| et cetera.
-
-dcurve
- draws a bezier curve starting at |(x1,y1)| and then moving by
- |(dx1,dy1)|, |(dx2,dy2)| et cetera.
-
-rect
- draws a rectangle with diagonal points at |(x1,y1)| and |(x2,y2)|.
-
-drect
- draws a rectangle with diagonal points at |(x,y)| and |(x+dx,y+dy)|.
-
-crect
- clears a rectangle with diagonal points at |(x1,y1)| and |(x2,y2)|.
-
-dcrect
- clears a rectangle with diagonal points at |(x,y)| and |(x+dx,y+dy)|.
-
-arect
- draws a rectangle with a widdh |width| and a height |height|;
- the middle of the bottom is at |(xc,yc)| and the centerline through
- |(xc,yc)| makes an angle |theta| with the x-axis.
-
-bar
- draws a equivalent with |rect x-xdev 0 x+xdev height|
-
-func
- draws the function given by |expression-in-x| between |xmin| and
- |xmax|, stepping with |step| units in the x-direction.
- Note that the |expression-in-x| will be evaluated by |Metafont|, so
- you will have to use metafont syntax.
-
-grid
- draw dotted grid lines at distances dx and dy in the x- and y
- directions; the gaps between the dots are set to |xgap| an |ygap|
- respectively. For an esthetic appearance, be sure to use integer
- |dx/xgap| and |dy/ygap| ratios.
-
-hatch
- hatch the closed curve that follows.
-
-bhat
- starts a path that will eventually be closed, and then hatched.
-
-ehat
- ends a path started with |bhat|, closes it and then hatches it.
-
-anything else
- will be inserted as is in the macro file, and therefore should be a
- valid |mfpic| statement. You use this when you need such a statement
- only once, or a few times and therefore see no need to define a proper
- command for it.
-
-= Running mkpic/TeX
-The effect of running
- mkpic picfile
-is the creation of |picfile.mac|, which you can |\input| into a TeX or
-ConTeXt source, and |picfile.sty| which can be input into a LaTeX
-source using the |\usepackage| command.
-
-After running TeX (or LaTeX or ConTeXt), you will find a file
-|picfile.mf| and you will have to run Metafont on it, which
-(assuming you configured TeX for 600 dpi) produces picfile.600gf. This
-file will have to be converted to a pk file with gftopk. Finally, you
-need to run TeX, normally at least twice, again. So for pdfLaTeX the sequence is:
-
- mkpic picfile
- pdflatex file.tex
- mf picfile
- gftopk picfile.600gf
- pdflatex file
- pdflatex file
-
-= Bug
-Currently only up to 256 pictures can be generated. In the future this
-problem will probably be solved by introducing more than one font and
-generating tex-command names that have the font name in front.
-
-= Changes
-Changes with respect to version 0.1:
-- added mkpicdoc.tex to the distribution
-
-= Author and copyright
-Author Wybo Dekker
-Email U{Wybo@dekkerdocumenten.nl}{wybo@dekkerdocumenten.nl}
-License Released under the U{www.gnu.org/copyleft/gpl.html}{GNU General Public License}
-DOC
-;
-
-use vars
- qw/$xgap $ygap $dx $dy $xl $yl $x3 $y3 $height $Z $d $F $r $theta1 $theta2/;
-
-sub evaluate {
- defined or die "Missing parameter at line $.\n";
- if ( !m|^[0-9.]+$| ) {
- my $x = ''; # we build up the expression with $-ized variable names in $x
- while ($_) {
- unless (/[A-Za-z0-9]+/) { $x .= $_; last }
- my ( $left, $middle, $right ) = ( $`, $&, $' );
- $x .= $left
- . ( ( $middle =~ m|^[0-9.]+$| || $fun{$middle} ) ? "" : '$' )
- . $middle;
- $_ = $right;
- }
- $_ = $x;
- eval "\$_=$_" while m|[^0-9.-]|;
- }
- $_;
-}
-
-sub parse {
- my @x;
- ( $command_name, @x ) =
- split ( /\s+/, $_, scalar @_ + 1 ); # input values/expressions in @x
- print LOG "command: $command_name\n" if $debug;
- for ( my $i = 0 ; $i < @_ ; $i++ ) { # each variable to be set
- $_ = $x[$i]; # take the expression
- if ( $_[$i] !~ /^[A-Z]/ )
- { # if name of receiving var not capitalized: await numerical
- evaluate;
- }
- my $varname = "$_[$i]";
- $$varname = $_;
- print LOG "$varname=$_\n" if $debug;
- }
-}
-
-sub parse_array {
- my @x;
- ( $command_name, @x ) = split ( /\s+/, $_[0] );
- print LOG "command: $command_name\n" if $debug;
- unless ( $command_name =~ /mark/ ) {
- for (@x) {
- evaluate;
- }
- }
- print LOG "parse_array returns: @x\n" if $debug;
- @x;
-}
-
-sub open_macrofile {
- my $rerun = 0;
- # we need to rerun if:
- # - one of the needed files is missing or else
- # - the input file is newer than the .mac file or else
- # - the present options differ from/keep the previous ones
-
- # check the presence of needed files:
- chomp( $_ = -f $tex ? $tex : `which mkpic` );
- my $inputtime = ( stat($_) )[9];
- for ( "mac", "sty" ) {
- -f "$tex.$_" or $rerun = 1, last;
- }
- # if all are there, test if the input is older than the .mac file:
- !$rerun && ( stat("$tex.mac") )[9] > $inputtime or $rerun = 1;
-
- # if that's true too, check that the previous option were the same:
- unless ($rerun) {
- open( MAC, "$tex.mac" );
- $_ = <MAC>;
- $_ eq $options or $rerun = 1;
- close MAC;
- }
- $rerun or return (0);
- open( MAC, ">$tex.mac" );
- select MAC;
- $_ = <<'EOF'
- % vim: syntax=tex
- \input mfpic
- \let\circle\undefinedcs
- \mfpicunit.01mm
- \opengraphsfile{TX}
- \def\ifundefined#1{\expandafter\ifx\csname#1\endcsname\relax}
- \def\doatend{\closegraphsfile}
- \ifundefined{typefile}\else\appendtoks\doatend\to\everystoptext\fi % for context
- \ifundefined{documentclass}\else\AtEndDocument{\doatend}\fi % for latex
- \def\bye{\doatend\par\vfill\supereject\end} % plain
- \def\ruledhbox#1{\vbox{\hrule\hbox{\vrule\kern3pt
- \vbox{\kern3pt#1\kern3pt}\kern3pt\vrule}\hrule}}
-
-EOF
- ;
- s/^\s+//gm;
- s/TX/$tex/gm;
- print MAC $options,$_;
-
- open( STY, ">$tex.sty" ) or die "Could not open $tex.sty: $!\n";
- $_ = <<'EOF'
- \ProvidesPackage{TX}
- \input TX.mac
- \endinput
-EOF
- ;
- s/^\s+//gm;
- s/TX/$tex/gm;
- print STY;
- 1;
-}
-
-sub sys {
- system("@_") and die "@_: $?\n";
-}
-
-sub parse_input {
- while (<$input>) {
- chomp;
- s/\s*#.*//; # remove comment
- next unless $_; # skip empty lines
- /^begin/ and do {
- parse qw(Name xl yl xmin ymin xmax ymax Xlabel Ylabel);
- $names{$Name} and die "multiple occurrences of picture named $Name\n";
- $names{$Name} = 1;
-
- $Xlabel = "" if $Xlabel eq '-';
- $Ylabel = "" if $Ylabel eq '-';
- $xscale = int( 100 * $xl / ( $xmax - $xmin ) + .5 );
- $yscale = int( 100 * $yl / ( $ymax - $ymin ) + .5 );
- $sx = sprintf( "%.2f", 100 / $xscale );
- $sy = sprintf( "%.2f", 100 / $yscale );
- $yx = $ymin > 0 ? $ymin : 0; # y-position of the x-axis
- $xy = $xmin > 0 ? $xmin : 0; # x-position of the y-axis
- $xlo = $xy - $sx; # x-pos of right side of y-markers
- $ylo = $yx - $sy; # y-pos of top side of x-markers
- $xhi = $xmax + 3 * $sx; # x-pos of left side of x-labels
- $yhi = $ymax + 3 * $sy; # y-pos of bottom side of y-labels
- print "%\n%====$Name====\n"
- . "\\def\\Fig$Name\{\\$box\{\\mftitle{$Name}%\n"
- . "\\def\\xlo{$xlo}\\def\\xhi{$xhi}%\n"
- . "\\def\\ylo{$ylo}\\def\\yhi{$yhi}%\n"
- . "\\def\\xy{$xy}\\def\\yx{$yx}%\n"
- . "\\mfpic[$xscale][$yscale]{$xmin}{$xmax}{$ymin}{$ymax}%\n"
- . "\\hatchwd{2}%\n"
- . ( $Xlabel ? "\\tlabel[bc]($xy,$yhi){$font $Ylabel}%\n" : '' )
- . ( $Ylabel ? "\\tlabel[cl]($xhi,$yx){$font $Xlabel}%\n" : '' );
- print TEX "\\Fig$Name\\par{\\bf $Name}\\eject\n" if $pdfsample;
- }, next;
-
- /^arccst/ and do { # arc center start theta
- parse qw(xc yc x1 y1 theta);
- print "\\arc[c]{($xc,$yc),($x1,$y1),$theta}\n";
- }, next;
-
- /^arcset/ and do { # arc start end theta
- parse qw(x1 y1 x2 y2 theta);
- print "\\arc[s]{($x1,$y1),($x2,$y2),$theta}\n";
- }, next;
-
- /^arccrtt/ and do { # arc center radius theta1 theta2
- parse qw(xc yc r theta1 theta2);
- print "\\arc[p]{($xc,$yc),$theta1,$theta2,$r}\n";
- }, next;
-
- /^arc3/ and do { # arc three points
- parse qw(x1 y1 x2 y2 x3 y3);
- print "\\arc[t]{($x1,$y1),($x2,$y2),($x3,$y3)}\n";
- }, next;
-
- /^arrow/ and do {
- parse qw(x1 y1 x2 y2 Label);
- my $yd = $y1 > $y2 ? -3 : 3;
- print "\\tlabel[bc]($x1,$y1){$font $Label}%\n"
- . "\\arrow\\lines{($x1,"
- . ( $y1 + $yd * $sy )
- . "),($x2,$y2)}%\n";
- }, next;
-
- /^[xyXY]mark/ and do {
- @z = parse_array($_);
- for ( $i = 0 ; $i < @z ; $i++ ) {
- $label = $z[$i];
- if ( $label =~ /^[-.\d]+$/ ) {
- $label = "\$$label\$";
- } else {
- $i++;
- }
- $x =
- $command_name =~ /x/i ? $z[$i]
- : $command_name =~ /y/ ? $xlo
- : -$xlo;
- $y =
- $command_name =~ /y/i ? $z[$i]
- : $command_name =~ /x/ ? $ylo
- : -$ylo;
- print "\\tlabel[$pos{$command_name}]($x,$y)"
- . "{\\rm \\strut $label}%\n";
- }
- }, next;
-
- /^grid/ and do {
- parse qw(xdist ydist xgap ygap);
- $topmaxy = ( int( $ymax / $ydist ) * $ydist );
- $lftmaxx = ( int( $xmin / $xdist ) * $xdist );
- $botmaxy = ( int( $ymin / $ydist ) * $ydist );
- $rtmaxx = ( int( $xmax / $xdist ) * $xdist );
- for ( $t = $lftmaxx ; $t <= $rtmaxx ; $t += $xdist ) {
- print
- "\\dotted[.5pt,$xgap mm]\\lines{($t,$botmaxy),($t,$topmaxy)}%\n";
- }
- for ( $t = $botmaxy ; $t <= $topmaxy ; $t += $ydist ) {
- print
- "\\dotted[.5pt,$ygap mm]\\lines{($lftmaxx,$t),($rtmaxx,$t)}%\n";
- }
- }, next;
-
- /^bar/ and do {
- parse qw(x xdev height);
- $x1 = $x - $xdev;
- $x2 = $x + $xdev;
- $y1 = 0;
- $y2 = $height;
- print "\\rect{($x1,$y1),($x2,$y2)}%\n";
- }, next;
-
- /^d?(point|lines|curve|rect|crect)/ and do {
- @z = parse_array($_);
- $command_name =~ /^d/ and do { # relative points
- for ( $i = 3 ; $i < @z ; $i += 2 ) {
- $z[$i] += $z[ $i - 2 ];
- $z[ $i - 1 ] += $z[ $i - 3 ];
- }
- $command_name =~ s/^d//;
- };
- $_ = "$command_name @z";
- # for example: crect 5 20 20 5
- s/^/\\/; # \crect 5 20 20 5
- s/\s+/{(/; # \crect{(5 20 20 5
- while (/ +/) {
- s/ +([-.\d]+)(\s+)?/,$1),\n(/;
- } # \crect{(5,20),(20,5)
- s/,\n\($/}/; # \crect{(5,20),(20,5)}
- s/crect/gclear\\rect/;
- # \gclear\rect{(5,20),(20,5)}
- print "$_\n";
- }, next;
-
- /^func/ and do {
- parse qw(x y d F);
- print "\\function{$x,$y,$d}{$F}%\n";
- }, next;
-
- /^hatch/ and do {
- print '\rhatch\draw\lclosed';
- }, next;
-
- /^bhat/ and do {
- print '\rhatch\lclosed\connect', "\n";
- }, next;
-
- /^ehat/ and do {
- print '\endconnect', "\n";
- }, next;
-
- /^xdrop/ and do {
- parse qw(x y);
- print "\\dotted\\arrow" . "\\lines{($x,$y),($xy,$y)}%\n";
- }, next;
-
- /^ydrop/ and do {
- parse qw(x y);
- print "\\dotted\\arrow" . "\\lines{($x,$y),($x,$yx)}%\n";
- }, next;
-
- /^xydrop/ and do {
- parse qw(x y);
- print "\\dashed\\arrow" . "\\lines{($x,$y),($xy,$y)}%\n";
- print "\\dashed\\arrow" . "\\lines{($x,$y),($x,$yx)}%\n";
- }, next;
-
- /^xlabels/ and do {
- parse qw(M x y dx Z);
- @z = split ( /\s+/, $Z );
- for (@z) {
- print "\\tlabel[$M]($x,$y){$font $_}%\n";
- $x += $dx;
- }
- }, next;
-
- /^ylabels/ and do {
- parse qw(M x y dy Z);
- @z = split ( /\s+/, $Z );
- for (@z) {
- print "\\tlabel[$M]($x,$y){$font $_}%\n";
- $y += $dy;
- }
- }, next;
-
- /^label/ and do {
- parse qw(M x y Label);
- $M =~ /^[bct][lcr]$/ or die "illegal label in $_\n";
- print "\\tlabel[$M]($x,$y){$font $Label}%\n";
- }, next;
-
- /^end/ and do {
- # axes drawn last for easier rect clears:
- print "\\arrow[\\axisheadlen]\\lines" . "{($xmin,$yx),($xmax,$yx)}%\n"
- if $Xlabel;
- print "\\arrow[\\axisheadlen]\\lines" . "{($xy,$ymin),($xy,$ymax)}%\n"
- if $Ylabel;
- print "\\endmfpic}}%\n";
- }, next;
-
- /^arect/ and do {
- parse qw/xc yc w h theta/;
- $theta *= 3.141592 / 180;
- $ws = $w / 2 * sin($theta);
- $wc = $w / 2 * cos($theta);
- $hs = $h * sin($theta);
- $hc = $h * cos($theta);
- print "\\lines{($xc-$ws,$yc+$wc),($xc-$ws+$hc,$yc+$wc+$hs),($xc+$ws+$hc,$yc-$wc+$hs),($xc+$ws,$yc-$wc),($xc-$ws,$yc+$wc)}\n";
- }, next;
-
- /^(\w+)\s*=/ and do {
- $var = $1;
- evaluate;
- print LOG "$var=$$var\n" if $debug;
- }, next;
-
- /^stop/ and do { last }; # stop reading the input
-
- print "$_\n" if $_; # anything else printed literally
-
- }
- print MAC "\\endinput\n";
- close(MAC);
- if ($pdfsample) {
- print TEX "\\bye\n";
- close(TEX);
- sys("pdftex --interaction batchmode $tex 2>/dev/null");
- sys("mf $tex; gftopk $tex.${dpi}gf");
- sys("pdftex --interaction batchmode $tex 2>/dev/null");
- for ( ( "log", "mf", "tfm", "${dpi}pk", "${dpi}gf", ) ) {
- unlink "$tex.$_";
- }
- }
-}
-
-sub help { undef $/; open(FH,$0); print "Usage:".[split(/= .*\n/,<FH>)]->[3]; exit 1 }
-sub install { system('instscript --extras=mkpicdoc.tex,mkpicdoc.pdf -zp mkpic'); exit 0; }
-
-use Getopt::Long;
-Getopt::Long::Configure("bundling_override");
-
-GetOptions(
- 'c|clean' => \$clean, # remove all but input file and don't run
- 'p|pdfsample' => \$pdfsample, # create pdf file with sample images
- 'b|box!' => \$box, # produce framed boxes
- 'f|font=s' => \$font, # default font instead of rm
- 'V|version' => \$version, # report version number and die
- 'h|help' => \&help, # display help info and die
- 'd|debug!' => \$debug, # print debug information
- 'l|log=s' => \$log, # file for warning messages
- 'I' => \&install # not for general use
-);
-
-if ($version) { print Version."\n"; exit; };
-$font = $font || '\rm';
-$box ||= '';
-$pdfsample ||= 0;
-if ($log) {
- open( LOG, ">>$log" ) or die "Could not open $log for output: $!\n";
-} else {
- *LOG = *STDERR;
-}
-
-# find printer density
-if ( open( IN, `kpsewhich --format="web2c files" mktex.cnf` ) ) {
- while (<IN>) {
- /BDPI=(\d+)/ and $dpi = $1, last;
- }
-} else {
- print LOG "could not find mktex.cnf; forcing 600dpi\n";
- $dpi = 600;
-}
-
-# we'll place the options in the .mac file so that, in the next run,
-# we can see if the previous run had the same options; if so and if
-# the input file is older than the .mac file, we won't rerun mkpic:
-$options = "% font:$font box:$box dpi=$dpi pdfsample:$pdfsample\n";
-
-$tex = shift;
-if ($tex) {
- open( IN, $tex ) or die "Could not open $tex\n";
- $input = *IN;
-} else {
- $input = *DATA;
- $tex = 'mkpic';
-}
-
-$clean and do {
- for ( eval "qw(mf ${dpi}gf ${dpi}pk log dvi pdf mac tex tfm sty)" ) {
- unlink "$tex.$_";
- }
- exit 0;
-};
-
-open_macrofile() or die "mkpic: no new run needed\n";
-print LOG "Mkpic Warning: Rerun (La)TeX\n" if $log;
-
-$box = $box ? 'ruledhbox' : 'hbox';
-if ($pdfsample) {
- open( TEX, ">$tex.tex" );
- ($_ = <<EOF ) =~ s/^\s+//gm;
- \\input $tex.mac
- \\parindent0pt\\parskip2ex
- \\nopagenumbers\\vsize=260mm
-EOF
- print TEX;
-}
-
-%pos = (
- 'xmark' => 'tc', # positions for [xyXY]marks
- 'ymark' => 'cr',
- 'Xmark' => 'bc',
- 'Ymark' => 'cl'
-);
-%fun = (
- sin => 1,
- cos => 1,
- sqrt => 1,
- atan2 => 1,
- abs => 1,
- exp => 1,
- int => 1,
- log => 1,
- not => 1
-);
-
-%names = ();
-
-parse_input;
-
-__DATA__
-l=20
-begin steps l l 0 0 l l - -
-\pen{2pt}
-dlines 10 10 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1
-end
-
-begin rectangle 64 64 0 0 10 10 $x$ $y$
-arect 5 5 3 2 60
-lines 0 0 10 10 0 10 10 0
-end
-
-begin parabola 64 64 0 -6 4 5 $x$ $y$
-xmark 2
-Xmark 3
-ymark -5 0 4
-bhat
-lines 0 0 0 4
-func 0 3 .05 4-x*x
-lines 3 -5 3 0
-ehat
-func 0 3.2 .05 4-x*x
-xydrop 3 -5
-arrow 3 4 1.7 1.1 $f(x)=4-x^2$
-arrow 2 5 1 2 Area $O_1$
-arrow 4 2 2.8 -2 Area $O_2$
-end
-
-begin droparrows 64 64 0 3 12 8 $x$ $y$
-xmark $a$ 2 $x_1$ 4 $x_2$ 8 $b$ 10
-ydrop 2 4.414
-ydrop 4 5
-ydrop 8 5.828
-ydrop 10 6.162
-label cc 4 4 $f(x_1)$
-label cc 8 4 $f(x_2)$
-label cc 7 8 $f(x)$ increasing on $[a,b]$
-label cc 7 7.5 $x_1<x_2\Rightarrow f(x_1)<F(x_2)$
-func 1 11 .1 x**(.5)+3
-end
-
-begin asymptotes 64 64 0 0 10 10 $x$ $y$
-curve 1 1 2 3 4 5.7 7 8.1 9 9
-point 2 3 4 5.7 7 8.1
-\shift{(-.05,.05)}
-func 1.4 2.6 .1 1.65*x-.3
-func 3.2 4.8 .1 1.025*x+1.6
-func 6.1 7.9 .1 .62*x+3.76
-label cl 9.5 9 $f(x)$
-label tl 5 5 $f^\prime(x)>0$
-label tl 5 4 $f^\prime(x)$ decreasing
-end
-
-# the previous diagram was made when expression were not yet available
-# with them, it's easier to use a defined curve and its calculated slopes
-# and positions:
-begin droppers 64 64 0 0 10 10 $x$ $y$
-func 0 10 .1 3*(sqrt(x))
-point 2 3*sqrt(2) 4 3*sqrt(4) 7 3*sqrt(7)
-\shift{(-.05,.05)}
-func 1.5 2.5 .1 3/2*(x/sqrt(2)+sqrt(2))
-func 3.5 4.5 .1 3/2*(x/sqrt(4)+sqrt(4))
-func 6.5 7.5 .1 3/2*(x/sqrt(7)+sqrt(7))
-label cl 9.5 9 $f(x)$
-label tl 5 5 $f^\prime(x)>0$
-label tl 5 4 $f^\prime(x)$ decreasing
-end
-
-begin inflections 64 64 -.85 -1.5 1.5 5 $x$ $y$
-func -.6 1.5 .05 6*(x**4)-8*(x**3)+1
-lines -.2 1 .2 1
-label cr -.25 1 horizontal
-arrow .5 2 0 1 inflection point
-arrow .8 1 .65 0 inflection point
-arrow 1 5 1.5 4.375 $f(x)=6x^4-8x^3+1$
-Xmark 1
-ymark \raise-8pt\hbox{0} 0 -1
-xydrop 1 -1
-end
-
-begin paraboloid 64 64 -4 -4 4 4 - -
-\dashed
-lines -4 0 0 0 0 0 0 -4 # neg z and neg y
-\dashed
-lines 0 0 3 1.73 # neg x
-\arrow
-lines 0 0 0 4 # pos z
-\arrow
-lines 0 0 4 0 # pos y
-\arrow
-lines 0 0 -3 -1.73 # pos x
-\dotted
-lines -1 4 -1 0 -4 -1.73 # intersections y=-1 plane
-\dotted
-lines -1 -.577 -4 -.577 # intersection x=2 plane with xy-plane
-% extra helplines
-\dotted
-lines -2 .423 -2 -.577 0 0 0 1 -2 .423
-Ymark 3
-% end of extras
-\dotted
-lines 0 3 -1 3 -4 1.27
-\dashed\sclosed
-curve -3 2.42 -1.5 2.711 -1 2.42 -2.5 2.134
-label bc 0 yhi $z$
-label cl xhi 0 $y$
-label tr -3.1 -1.8 $x$
-label cl -.85 -.577 2
-label tc 0 5.5 $f(x,y)=x^2-4x+2y^2+4y+7$
-xmark -1
-Ymark 1
-\shift{(-2,.42)}
-\dashed
-func 0 .5 .1 9*x*x
-func -.5 0 .1 7*x*x
-\dashed
-func -1 0 .1 2*x*x
-func 0 1 .1 2*x*x
-end
diff --git a/Build/source/texk/texlive/linked_scripts/multibibliography/multibibliography.pl b/Build/source/texk/texlive/linked_scripts/multibibliography/multibibliography.pl
deleted file mode 100755
index 16374700359..00000000000
--- a/Build/source/texk/texlive/linked_scripts/multibibliography/multibibliography.pl
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/perl
-# Usage: perl multibibliography.pl jobname
-# By Yannis Haralambous and Michael Cohen
-
-# Changes by Boris Veytsman, $Revision: 1.6 $, $Date: 2013-06-25 03:37:30 $
-
-# This perl script does the bibtexing part, generating 3 separate .bbl
-# files with descriptive names derived from source file name, so no
-# need to separately invoke.
-
-use strict;
-
-sub cleanup {
- local $/=undef;
- my $file = shift;
- open IN, $file;
- my $BIG=<IN>;
- close IN;
- $BIG=~s/(\r\n|\r|\n)/ /g;
- $BIG=~s/\\bibitem/\n\n\\bibitem/g;
- $BIG=~s/\\newblock/\n\\newblock/g;
- $BIG=~s/\\end\{thebibliography\}/\n\n\\end{thebibliography}/g;
- $BIG=~s/[ ]+/ /g;
- open OUT, ">$file";
- print OUT $BIG;
- close OUT;
-}
-
-# First, change "apalike" in the aux file to "unsrt" and generate bbl
-# file, renamed to "fn-sequence.bbl".
-my $filename=$ARGV[0];
-$filename=~s/\.(tex|bib|bbl|aux|log)$//;
-if (-e $filename.".aux") {
- open IN, $filename.".aux";
- my $BIG="";
- while (<IN>) {
- if (m/\\bibstyle\{apalike\}/) {
- $BIG .= "\\bibstyle{unsrt}\n";
- } else {
- $BIG .= $_;
- }
- }
- close IN;
- open OUT, "> $filename-sequence.aux";
- print OUT $BIG;
- close OUT;
- system("bibtex $filename-sequence");
-
- # Now, change "unsrt" in the aux file to "chronological"
- # and generate bbl file, renamed to "fn-timeline.bbl".
-
- open IN, "$filename-sequence.aux";
- $BIG="";
- while (<IN>) {
- if (m/\\bibstyle\{unsrt\}/) {
- $BIG .= "\\bibstyle{chronological}\n";
- } else {
- $BIG .= $_;
- }
- }
- close IN;
- open OUT, "> $filename-timeline.aux";
- print OUT $BIG;
- close OUT;
- system("bibtex $filename-timeline");
-
- # Lastly, change "chronological" in the aux file to "apalike"
- # and generate bbl file, retaining name "fn.bbl".
-
- open IN, "$filename-timeline.aux";
- $BIG="";
- while (<IN>) {
- if (m/\\bibstyle\{chronological\}/) {
- $BIG .= "\\bibstyle{apalike}\n";
- } else {
- $BIG .= $_;
- }
- }
- close IN;
- open OUT, "> $filename.aux";
- print OUT $BIG;
- close OUT;
- system("bibtex $filename");
-
- cleanup("$filename.bbl");
- cleanup("$filename-sequence.bbl");
- cleanup("$filename-timeline.bbl");
-
- open IN, "$filename-sequence.bbl";
- my $counter=1;
- my %UNSRT;
- my %DATE;
- my %NAME;
- while (<IN>) {
- if (m/\\bibitem{([^\}]+?)}/) {
- $UNSRT{$1}=$counter;
- $counter++;
- }
- }
- close IN;
-
- open IN, $filename.".bbl";
- $counter=1;
- while (<IN>) {
- if (m/\\bibitem\[([^\]]+)\]{([^}]+?)}/) {
- my $longdesc=$1;
- my $label=$2;
- if ($longdesc =~ /^(.*),\s+(\S+)$/) {
- $NAME{$label}=$1;
- $DATE{$label}=$2;
- }
- }
- }
- close IN;
-
- open IN, $filename."-sequence.bbl";
- $counter=1;
- $BIG="";
- while (<IN>) {
- if (s/\\bibitem{(.+?)}/\\bibitem[\\MBlabel{$counter}{$NAME{$1}}{$DATE{$1}}]{$1}\n/) {
- $counter++;
- }
- $BIG .= $_;
- }
- close IN;
- open OUT, "> $filename-sequence.bbl";
- print OUT $BIG;
- close OUT;
-
- open IN, $filename.".bbl";
- $BIG="";
- while (<IN>) {
- s/\\bibitem\[[^\]]+\]{(.+?)}/\\bibitem[\\MBlabel{$UNSRT{$1}}{$NAME{$1}}{$DATE{$1}}]{$1}/;
- $BIG .= $_;
- }
- close IN;
- open OUT, ">$filename.bbl";
- print OUT $BIG;
- close OUT;
-
- open IN, $filename."-timeline.bbl";
- $BIG="";
- while (<IN>) {
- s/\\bibitem\[[^\]]+\]{(.+?)}/\\bibitem[\\MBlabel{$UNSRT{$1}}{$NAME{$1}}{$DATE{$1}}]{$1}/;
- $BIG .= $_;
- }
- close IN;
- open OUT, ">$filename-timeline.bbl";
- print OUT $BIG;
- close OUT;
-}
-
-
-
diff --git a/Build/source/texk/texlive/linked_scripts/musixtex/musixflx.lua b/Build/source/texk/texlive/linked_scripts/musixtex/musixflx.lua
deleted file mode 100755
index 0a267f4815c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/musixtex/musixflx.lua
+++ /dev/null
@@ -1,1071 +0,0 @@
-#!/usr/bin/env texlua
-
--- The MUSIXFLXVERSION below is the one checked against.
-
-MUSIXFLXVERSION = "0.83"
-VERSION = "0.83.3.lua7"
-
---[[
-
-Line breaking program for MusiXTeX.
-
- (c) Copyright Ross Mitchell 1992-1997 ross.mitchell@csiro.au
- (c) Copyright J. Hunsberger 1997 jhunsberger@i2k.co
- (c) Copyright 2009, 2010 Peter Breitenlohner <tex-live@tug.org>
- (c) Copyright 2011 Nikhil Helferty 6nh14@queensu.ca
- (c) Copyright 2011 Bob Tennent rdt@cs.queensu.ca
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
---]]
-
---[[
-
-Conversion to Lua by Nikhil Helferty, 2011.
-Minor corrections by Bob Tennent rdt@cs.queensu.ca.
-
-NH: Comments marked NH (such as this one) are comments new to the Lua
-version. Most have to do with explaining any additions or changes made
-necessary due to differences between Lua and C. Comments not so marked
-are retained from C version.
-
-Almost all comments from the C version have been put in this version as
-well. Note that Lua variables are dynamically typed, and Lua has only
-one data structure called "tables" which, though more flexible than
-arrays, are essentially just used as arrays here.
-
---]]
-
---[[
-
- ChangeLog:
-
- lua7 2011/04/21 RDT
- Decode option argument for debugging.
- Revert to accepting .mx1 or .tex filenames.
- Rationalize file-name variables.
-
- lua6 2011/04/18 RDT
- Revert to stand-alone use.
-
- lua5 2011/04/13 RDT
- Allow .mx1 file to have a version number only.
-
- lua4 2011/04/12 RDT
- Adaptation to being called from musixtex.tex
-
- lua3 2011/04/11 RDT
- Replaced body of eightfivefloat by string.format("%8.5f", ... )
-
- lua2 2011/04/11 RDT
- Change PRINT to print for dbug output.
-
- lua1 2011/04/08 RDT
- Strip off pt for L line.
-
---]]
-
--- max sizes
--- NH: these aren't needed for array sizes in Lua (tables grow dynamically)
--- but I am keeping the checks in case the maximums are necessary for
--- TeX processing
-
-MAX_SIGNS = 128; MAX_SECTIONS = 128; MAX_BARS = 2048
-
-function GETLINE()
- linebuf = infile:read()
- return linebuf
-end
-
--- NH: declare tables
-
--- NH: the following tables were all arrays of type int in C
--- the following tables were size MAX_BARS in C (2048)
-zbar = {}; lr_repeat = {}; raggedline = {}
-l_repeat = {}; barno = {}
-
--- NH: the following tables were size MAX_SECTIONS in C (128)
-autolines = {}; bars = {}; mulooseness = {}
-
--- NH: the following was of size MAX_SIGNS in C (128)
-signchange = {}
-
--- NH: the following were counters declared for xbar sign change detection
--- xbar of size MAX_BARS, linegoal MAX_SECTIONS
--- xbar_count, xbar_flag, softspace_count were integers declared here
--- as they aren't tables they'll be declared upon use
-xbar = {}; linegoal = {}
-
--- NH: the following tables were all arrays of type double in C
--- the following were size MAX_BARS
-hardbarlength = {}; softbarlength = {}
-width_leftrightrepeat = {}; width_leftrepeat = {}
-
--- NH: the following were size MAX_SECTIONS
-eff_hardlength = {}; eff_softlength = {}
-
--- NH: the following were size MAX_SIGNS
-oldsignskip = {}; signskip = {}; futuresignskip = {}
-
-
--- NH: (no need to add last \n as print does this)
-function error_exit (error_number)
- -- NH: the following if/elseif/else construction mirrors case structure
-
- if error_number == 0 then
- print("\nFile error.")
- elseif error_number == 1 then
- print("\nUsage: [texlua] musixflx.lua basename[.tex | .mx1] [ d | m | f | s ]")
- elseif error_number == 2 then
- print("\nThis shouldn't happen ! Too few bars or \\mulooseness too large ?")
- elseif error_number == 3 then
- print("\nThis shouldn't happen ! Too few bars in section !")
- elseif error_number == 4 then
- print("\nMissing endmark ! Forgotten \\stop[end]piece ?")
- elseif error_number == 5 then
- print("\nDivision by zero ! Ask a wizard !")
- elseif error_number == 6 then
- print("\nVersion mis-match:")
- print("MusiXTeX version " .. linebuf)
- print("musixflx expected version " .. MUSIXFLXVERSION)
- elseif error_number == 7 then
- print("\nFile not found: " .. infilename)
- elseif error_number == 8 then
- print("\nCorrupted " .. infilename)
- elseif error_number == 9 then
- print("\nToo many sections, maximum number of sections: " .. MAX_SECTIONS)
- elseif error_number == 10 then
- print("\nError in " .. infilename .. " at line " .. currentline)
- elseif error_number == 11 then
- print("\nToo many bars, maximum number of bars: " .. MAX_BARS)
- else
- print("!!! Can't go on !!!")
- end
- os.exit(3)
-
-end
--- end error_exit
-
--- NH: there is really no analogue to the strrchr function in C, which is frequently used
--- to locate the location of a last occurrence of a string
--- so I coded a similar function for Lua
--- takes two strings (str and pat), and returns everything after the last occurence of pat
--- in str - if no occurrences of pat, then returns nil
-function strrchr(str, pat)
- notfound = true
- currentIndex = 0
- lastIndex = 0
- while notfound do
- currentIndex = string.find(str, pat, lastIndex+1, true)
- if (not currentIndex) then -- NH: returned nil - no occurence past lastIndex
- notfound = false
- else -- NH: got a hit for an occurence - store this value as lastIndex
- lastIndex = currentIndex
- end
- end
- if lastIndex == 0 then return nil end -- NH: no occurence found
- return string.sub(str, lastIndex+1)
-end
-
-
--- NH: start "main chunk"
-
-io.write(string.format("Musixflx-%s", VERSION))
-
--- initialize variables
-junk = -9999
-dbug = false
-dbug_lines = false
-dbug_logfile = false
-showresult = false
-detectraggedline = false
-currentline = 1
-samechapter = true
-line_number = 0
-chapterno = 1
-
-lthick = .4
-
-if dbug then
- print("\n ... decoding command line")
-end
-
-filename = arg[1]
-if not filename then
- error_exit(1)
-end
-
-extension = string.sub(filename, -4, -1)
-if extension == ".tex" or extension == ".mx1" then
- basename = string.sub(filename, 1, -5)
-else
- basename = filename
-end
-
---[[
-
-debugging options:
- d output debugging information to the screen
- m output line numbers to the screen
- f output debugging information to file basename.mxl (not mx1)
- s output computed lines to the screen
-
- --]]
-
-if (#arg == 2) then
- if (arg[2] == "d") then
- dbug = true
- elseif (arg[2] == "m") then
- dbug_lines = true
- elseif (arg[2] == "f") then
- dbug = true
- dbug_logfile = true
- dbug_lines = true
- elseif (arg[2] == "s") then
- showresult = true
- else
- error_exit(1)
- end
-end
-
-infilename = basename .. ".mx1"
-
--- open the .mx1 file containing bar length information
-
-if dbug then
- print(" ... opening " .. infilename .. " for input")
--- NH: io.open analagous to fopen C function
--- will return nil value if not successful
--- nil is taken as false in if statements
-end
-infile = io.open(infilename, "r")
-if (not infile) then
- error_exit(7)
-end
-io.write(string.format(" (%s", infilename))
-if showresult then
- print("")
-end
-
-currentline = currentline + 1
-if GETLINE() and (linebuf ~= MUSIXFLXVERSION) then
- error_exit(6)
-end
-
-
--- Open the output file
-outfilename = basename .. ".mx2"
-if dbug then
- print(" ... opening " .. outfilename .. " for output")
-end
-outfile = io.open(outfilename, "w")
-if (not outfile) then
- print("\nCan't create: " .. outfilename)
- os.exit(3)
-end
-
--- Open the logfile
-if dbug_logfile then
- logfilename = basename .. ".mxl"
- print(" ... open " .. logfilename .. " for debugging")
- logfile = io.open(logfilename, "w")
- if (not logfile) then
- print("\nCan't create: " .. logfilename)
- os.exit(3)
- end
- logfile:write("Version ", VERSION, "\n")
-end
-
--- skip startindicator
-
-if GETLINE() and (linebuf ~= "S") then
- error_exit(8)
-end
-
---[[
-do...while loop for
- moretimes call of \startpiece
- >>>>>>>>>>>>>>>>>>>>>>>>>>>
-
- Do while equivalent is repeat...until
- --]]
-
- GETLINE()
-
- repeat
-
--- reset all arrays
-
-if dbug then print("\n------- Chapter " .. chapterno .. " -------\n"); end
-if dbug_logfile then logfile:write("\n------- Chapter ", chapterno, " -------\n\n"); end
--- NH: copying C method of loops but this means will be initializing the max spaces every time
--- ... not taking advantage of dynamic sizes of tables in Lua
--- however necessary to initialize since the starting values are used in operations
--- note upper bounds for these loops are the max-1, as for syntax in lua will include the upper (<= instead of <)
-
-for i = 0, MAX_SIGNS-1 do
- signchange[i] = junk
- oldsignskip[i] = 0
- futuresignskip[i] = 0 -- jh-1
- signskip[i] = 0
-end
-
-for i = 0, MAX_BARS-1 do
- hardbarlength[i] = 0
- softbarlength[i] = 0
- width_leftrightrepeat[i] = 0
- lr_repeat[i] = false
- width_leftrepeat[i] = 0
- xbar[i] = 0 -- jh-1
- l_repeat[i] = false
- zbar[i] = false
- raggedline[i] = false
- barno[i] = 0
-end
-
-for i = 0, MAX_SECTIONS-1 do
- eff_hardlength[i] = 0
- eff_softlength[i] = 0
- bars[i] = 0
- autolines[i] = false
- linegoal[i] = 0
- mulooseness[i] = 0
-end
-
---[[
-
- Read and decode header items:
-
- 1. Linewidth;
- 2. Parindent;
- 3. Beforeruleskip;
- 4. Afterruleskip;
- 5. Elemskip;
- 6. Clefskip;
- 7. Signskip;
- --]]
-
- -- NH: for those curious why it is necessary to take a substring of the line, it is to strip the "pt" off of the string
- -- to make them valid strings for coercion to numbers later on (something that the atof does automatically)
- -- RDT: linebuf tests are to avoid taking a substring of an empty string
-if linebuf then linewidth = string.sub(linebuf, 1, -3); currentline=currentline+1 end
-GETLINE(); if linebuf then parindent = string.sub(linebuf, 1, -3); currentline=currentline+1 end
-GETLINE(); if linebuf then beforerule = string.sub(linebuf, 1, -3); currentline=currentline+1 end
-GETLINE(); if linebuf then afterrule = string.sub(linebuf, 1, -3); currentline=currentline+1 end
-GETLINE(); if linebuf then elemskip = string.sub(linebuf, 1, -3); currentline=currentline+1 end
-GETLINE(); if linebuf then clefskip = string.sub(linebuf, 1, -3); currentline=currentline+1 end
-GETLINE(); if linebuf then signskip[0] = string.sub(linebuf, 1, -3); currentline=currentline+1 end
-
-futuresignskip[0] = signskip[0] -- Initialize for xbar signs, jh-1
-
---[[
- Read the records specifying contributions to bar length.
- Lengths are of two types:
- (a) Hard or unscaleable, eg barlines, clef or meter changes (typ=0).
- (b) Soft or scaleable, eg noteboxes which scale with \elemskip (typ=1).
- Note that \afterruleskip and \beforerulskip are considered soft.
- --]]
-
-jbar = junk
-i = 0
-sign = 0
-xbar_count = 0 -- Used to detect presence of xbars jh-1
-xbar_flag = false -- True allows check for xbar jh-1
-hardsign = 0 -- Accumulator for hard skip from sign change jh-1
-softspace_count = 0 -- Watch for softspace after bars are posted jh-1
-
-all_section = 0
-
-if dbug then
- print(" ... reading")
-end
-
-while (samechapter and GETLINE()) do
-
- currentline = currentline + 1
- local firstChar = string.sub(linebuf, 1, 1)
-
- -- NH: use if/elseif/else to mirror switch/case statements
-
---[[
-'\startpiece'
- stop reading,
- compute,
- write
- and start again
- --]]
-
- if (firstChar == "S") then
- samechapter = false
-
---[[
- End of section. Action:
- Right justify the material ending at the previous bar.
- Read the number following the *, which is the 'looseness'
- parameter of the section just ended.
- Reset the bar test integer to JUNK in case the bar number
- was reset between sections.
- --]]
-
- elseif (firstChar == "*") then
- local firstSpace = string.find(linebuf, " ")
- local secondSpace = string.find(linebuf, " ", firstSpace+1)
- if not secondSpace then -- NH: possibility that there is no second number in line
- mulooseness[all_section] = string.sub(linebuf, firstSpace+1)
- else
- mulooseness[all_section] = string.sub(linebuf, firstSpace+1, secondSpace-1)
- end
- -- NH: above firstSpace/secondSpace mathematics were to mimic function of atol use in original C function
- linegoal[all_section] = 0 -- jh-2 + WS-1
- if secondSpace then
- linegoal[all_section] = string.sub(linebuf, secondSpace+1) -- NH: this my interpretation of an sscanf line signed jh-2 + WS-1 in C
- end
- linegoal[all_section] = linegoal[all_section] + 0 -- NH: this is a fairly silly trick to force coercion for valid comparison to numbers, could also use tonumber function
- mulooseness[all_section] = mulooseness[all_section] + 0
- if ((mulooseness[all_section] ~= 0) and (linegoal[all_section] > 0)) then
- print("\\linegoal{" .. linegoal[all_section] .. "} ignored because \\mulooseness not equal to zero")
- print(" for section " .. all_section+1 .. " in chapter " .. chapterno)
- linegoal[all_section] = 0 -- Reset to ignore it. jh-2 + WS-1
- end
- all_section = all_section + 1
- if all_section > (MAX_SECTIONS - 1) then
- error_exit(9)
- end
- jbar=junk
-
---[[
- Right justify the material ending at the previous bar.
- Set flag.
- Reset the bar test integer to JUNK in case the bar number
- was reset between sections.
- ]]
-
-
- elseif (firstChar == "a") then
- autolines[all_section] = true
- all_section = all_section + 1
- if (all_section > (MAX_SECTIONS - 1)) then
- error_exit(9)
- end
- jbar=junk
-
---[[
- found a raggedline, let's set a flag
- I think, I'll hardly get a Nobel-Award for coding this
- What a pity! :-(
- but perhaps a Pulitzer-Award for my comments. :-)
---]]
-
- elseif (firstChar == "r") then
- raggedline[i+1] = true
-
-
- -- found \zbar, set flag and store barno
- elseif (firstChar == "z") then
- zbar[i] = true
- barno[i] = strrchr(linebuf, " ")
- xbar_count = xbar_count + 1 -- Help detect xbars, track zbar offsets. jh-1
- hardsign = 0 -- reset any sign change skip accumulated. jh-1
- softspace_count = 0 -- Reset for next bar. jh-1
-
-
---[[
- found a leftrightrepeat
- set a flag and store the different widths
- ]]
-
- elseif (firstChar == "l") then
- -- NH: there are some commented out printf lines in C code in this case
- -- I'm assuming they were used at one point for debugging purposes and
- -- am not translating them, but if should be reinstated they exist at lines
- -- 380-387 in C program
- lr_repeat[i] = true
- local firstSpace = string.find(linebuf, " ")
- local secondSpace = string.find(linebuf, " ", firstSpace + 1)
- width_leftrightrepeat[i] = string.sub(linebuf, firstSpace+1, secondSpace-3) -- NH: secondspace-3 as secondspace-1 will include the "pt"
- width_leftrepeat[i] = string.sub(linebuf, secondSpace+1, -3) -- NH: again, -3 to chop off the "pt"
-
-
---[[
- found a leftrepeat
- set a flag and store width
- ]]
-
- elseif (firstChar == "L") then
- l_repeat[i] = true
- local firstSpace = string.find(linebuf, " ")
- width_leftrepeat[i] = string.sub(linebuf, firstSpace+1, -3) -- RDT: again, -3 to chop off the "pt"
-
-
- -- store barno
- elseif (firstChar == "b") then
- barno[i] = strrchr(linebuf, " ")
- xbar_count = xbar_count+1 -- Track possible xbars. jh-1
- xbar_flag = true -- Allow check of next line to detect xbar. jh-1
- hardsign = 0 -- Reset accumulated hard sign skip. jh-1
- softspace_count = 0 -- Reset for next bar. jh-1
-
---[[
- enabling the use of 'hard' offsets
- advance current hardwith
- reduce current softwidth
---]]
-
- elseif (firstChar == "h") then
- x = string.sub(strrchr(linebuf, " "), 1, -3) -- -3 is to chop off "pt" in string to allow x to be valid for arithmetic
- softbarlength[i] = softbarlength[i] - x
- hardbarlength[i] = hardbarlength[i] + x
- eff_softlength[all_section] = eff_softlength[all_section] - x
- eff_hardlength[all_section] = eff_hardlength[all_section] + x
-
-
---[[
- This record began with 's' and specifies a key signature change
- store the signskip, s.b.
- ]]
-
- elseif (firstChar == "s") then -- Changes to detect xbar and signchange interaction, jh-1
-
- local firstSpace = string.find(linebuf, " ")
- local secondSpace = string.find(linebuf, " ", firstSpace+1)
- if not secondSpace then
- tempholdskip = string.sub(linebuf, firstSpace+1, -3)
- else
- tempholdskip = string.sub(linebuf, firstSpace+1, secondSpace-3)
- end
- -- NH: all of above to mimic atof statement
- -- wasn't sure if statements with s would have a second space and more info
- -- so accounted for either possibility
-
- -- We might be in the middle of an xbar setup, and we only want to increment
- -- the sign pointer if this is the first sign change. jh-1
- if (not (signchange[sign] == i)) then -- first time for this bar set jh-1
- sign = sign + 1
- signchange[sign] = i
- signskip[sign] = tempholdskip
- oldsignskip[sign] = hardsign -- Capture accumulated hard space. jh-1
- xbar[i] = xbar[i] + 1 -- Increment to detect xbars with sign changes. jh-1
- --[[
- Housekeeping is done... Now, one more condition to check. If there
- has been any soft space since the bar was declared, then musixtex
- will NOT publish a sign change notice at the end of the line for
- this sign change when there is a line break in this bar.
- In that case, signal that this should be treated as an xbar, which
- will effectively suppress the transfer of hardspace for the sign
- change notice. jh-1
- --]]
- if softspace_count > 0 then xbar[i] = 2 end-- Suppress space move jh-1
- end
- -- Always update the futuresignskip value in case this is the last
- futuresignskip[sign] = tempholdskip
-
- -- comment, do nothing
- elseif (firstChar == "%") then
-
- -- This is an 'ordinary' line, listing a contribution to the barlength.
- else
- if (not (tonumber(firstChar))) then
- error_exit(10)
- end
- local firstSpace = string.find(linebuf, " ")
- local secondSpace = string.find(linebuf, " ", firstSpace + 1)
- bar = string.sub(linebuf, 1, firstSpace-1)
- typ = string.sub(linebuf, firstSpace+1, secondSpace-1)
- x = string.sub(linebuf, secondSpace+1, -3) -- the -3 is to strip the "pt" off of the x
- if (typ ~= "0") then eff_softlength[all_section] = eff_softlength[all_section] + x
- else eff_hardlength[all_section] = eff_hardlength[all_section] + x
- end
-
---[[
- Increment bar number if the bar number
- read from the file has changed.
- Accumulate current bar length.
- --]]
- bar = bar + 0 -- NH: forcing coercion to number type from string
- if tonumber(bar) > jbar then
- i = i + 1
- bars[all_section] = bars[all_section] + 1
- if i > MAX_BARS then
- error_exit(11)
- end
- end
-
- -- At this point, can check if this is an xbar...Only check once. jh-1
- if xbar_flag then
- if ((xbar_count - bar - 1) == 0) then -- find an xbar. jh-1
- xbar_count = xbar_count-1 -- adjust offset to stay on track
-
- --[[
- To handle the special conditions caused by possible xbars and
- sign changes, the xbar logic state has to be examined and changed
- only if this is the first xbar, and not for subsequent ones. jh-1
- --]]
- if (xbar[i] == 0) then -- then this is the first xbar in the setup
- -- or there has already been a sign change
- xbar[i] = 1 -- jh-1
- end
- end
- end
-
- xbar_flag = false -- Reset to prevent checks until next bar. jh-1
-
- if (typ ~= "0") then
- softbarlength[i] = softbarlength[i] + x
- -- Count softspace entries to help in sign/linebreak decisions jh-1
- softspace_count = softspace_count+1
- hardsign = 0 -- Safety - just be sure in case line break jh-1
- else -- jh-1
- hardbarlength[i] = hardbarlength[i] + x
- hardsign = hardsign + x -- accumulate hardspace, there may be a sign change
- end
-
- jbar = bar
-
- end -- end if statements
-
-end -- end while loop
-
---[[
-Decrement the number of sections if the final section is void.
- This will be the usual case where the input file ends with
- an end of section record.
- If this record has been omitted, stop going on to avoid
- 'You can't use \raise....'.
- ]]
-
-if dbug then
- print(" ... compute")
-end
-
-if (bars[all_section] == 0) then
- all_section = all_section - 1
-else
- error_exit(4)
-end
-
--- Summarize sectioning information
-
-if dbug then
- print("\nNumber of sections : " .. (all_section+1) .."\n")
-
- for section = 0, all_section do
- if (autolines[section]) then
- print("---- autoline section ----")
- end
- print("Section : " .. (section+1))
- print("Number of bars in section : " .. bars[section])
- print("Length(hard) of section " .. (section+1) .. " : " .. eff_hardlength[section])
- print("Length(soft) of section " .. (section+1) .. " : " .. eff_softlength[section])
- if (linegoal[section] ~= 0) then -- linegoal applies, signed jh-2 in C
- print("Section line goal was determined by \\linegoal value...")
- print("Line Goal for section : " .. linegoal[section])
- else -- mulooseness applies, signed jh-2 in C
- print("Looseness of section : " .. mulooseness[section])
- end
-
- io.read() -- NH: mimics getchar()
- end -- end for
-
-end -- end if
-
-if dbug_logfile then
- logfile:write("\nNumber of sections : ", all_section+1, "\n\n")
-
- for section = 0, all_section do
- if (autolines[section]) then
- logfile:write("---- autoline section ----\n")
- end
- logfile:write("Section : ", section+1, "\n")
- logfile:write("Number of bars in section : ", bars[section], "\n")
- logfile:write("Length(hard) of section ", section+1, " : ", eff_hardlength[section], "\n")
- logfile:write("Length(soft) of section ", section+1, " : ", eff_softlength[section], "\n")
- if (linegoal[section] ~= 0) then -- line goal applies. signed jh-2 in C
- logfile:write("Section line goal was determined by \\linegoal value...\n")
- logfile:write("Line goal for section : ", linegoal[section], "\n")
- else -- mulooseness applies, signed jh-2 in C
- logfile:write("Looseness of section : ", mulooseness[section], "\n")
- end
- end
-end
-
---[[
-C Comments:
-Loop over the sections defined in the input file.
- Each section must be right justified.
- LAST is the absolute number of the last bar
- in the current section.
---]]
-
-sign = 0
-mark = 0
-lastbarnumber = 0
-
-
-for section = 0, all_section do
- line_in_section = 1
- lastbarnumber = lastbarnumber + bars[section]
-
- -- Find number of lines to work towards
- lines = math.floor(((eff_hardlength[section] + eff_softlength[section] + parindent)/
- (linewidth-(clefskip+signskip[sign]))) + .5) -- need to use floor function as lua has no "integer" type, just numbers
- if (lines == 0) then lines = 1 end -- safety
-
- natural_lines = lines -- Keep this for debug report. Signed jh-2 in C
- lines = lines + mulooseness[section]
- if ((mulooseness[section] ~= 0) and (linegoal[section] > 0)) then -- signed jh-2 in C
- print("Unexpected line goal reset occured for section " .. section+1)
- linegoal[section] = 0 -- Zero it, Safety, should not happen, signed jh-2 in C
- end
- if (linegoal[section] > 0) then lines = linegoal[section] end -- Signed jh-2 in C
- if lines < 1 then
- lines = 1
- print("Don't stress \\mulooseness too much !!!")
- end
-
---[[
-C comments:
- autolinesflag set in current section ?
- iftrue force number of lines to 1
- --]]
-
- if (autolines[section]) then lines = 1 end
-
- if dbug then
- print("Section number : " .. section+1)
- print("Last bar in this section : " .. lastbarnumber)
- print("Number of bars : " .. bars[section])
- print("Natural number of lines : " .. natural_lines) -- signed jh-2 in C
- print("Chosen number of lines : " .. lines .. "\n")
- end
-
- if dbug_logfile then
- logfile:write("Section number : ", section+1, "\n")
- logfile:write("Last bar in this section : ", lastbarnumber, "\n")
- logfile:write("Number of bars : ", bars[section], "\n")
- logfile:write("Natural number of lines : ", natural_lines, "\n") -- signed jh-2 in C
- logfile:write("Chosen number of lines : ", lines, "\n\n")
- end
-
- if (bars[section]<1) then error_exit(3) end
-
---[[
-C comments:
- fill_length is the length of 'bar' material (ie excluding
- signature space) required to fill the remainder
- of the piece. This value will not be exact if there are
- sign changes within the section. However,
- fill_length is used only to keep track of the mean scale factor
- for the remainder of the piece, as opposed to individual lines.
-
- Loop over lines, working out number of bars
- and revised \elemskip for each line.
- added correct computing of fill_length
- --]]
-
-
- for j = 1, lines do
- line_number = line_number + 1
- fill_length = (lines-j+1) * (linewidth - (clefskip + signskip[sign]))
-
-
---[[
-C comments:
- Work out mean element skip over remaining bars
- in the current section.
- EFFWID is the effective line width once
- key signature have been written.
- Set parindent to zero after it has been used for the
- first line of the first section.
- --]]
-
- if (eff_softlength[section] == 0) then error_exit(5) end
- spc_factor = (fill_length - eff_hardlength[section])/eff_softlength[section]
- if ((xbar[mark+1] > 1) and (mark>0)) then
- -- The bar is an bar+xbar with a sign change. Signed jh-1 in C
- eff_linewidth = linewidth - (clefskip+signskip[sign-1]) - parindent
- else -- This is a normal bar. Signed jh-1 in C
- eff_linewidth = linewidth - (clefskip+signskip[sign]) - parindent
- end -- Signed jh-1 in C
-
- signskip[sign] = futuresignskip[sign] -- Supports xbar signs. Signed jh-1 in C
-
- parindent = 0
-
- -- Fill the current line by adding bars until overflow.
-
- i = mark
- firstbarno = barno[mark+1]
- hardlength = 0
- softlength = 0
- x = 0
- lastbar = 0
- detect_end = false
-
- while (x < eff_linewidth) do
- if detect_end then break end
- i = i + 1
- -- Check for raggedline
-
- if raggedline[i] then detectraggedline = true end
-
- -- Check for key signature change at this bar.
-
- if (i == signchange[sign+1]) then sign = sign + 1 end
-
- lastbar = hardbarlength[i] + spc_factor*softbarlength[i]
- x = x + lastbar
-
- -- Enforce termination at last bar and last line
-
- if (i==lastbarnumber) then detect_end = true
- elseif (line_in_section == lines) then
- detect_end = false
- x = 0
- end
-
- hardlength = hardlength + hardbarlength[i]
- softlength = softlength + softbarlength[i]
-
- end
-
---[[
-C comments:
- If the overhang is less than half the barlength,
- include the latest bar in the line,
- and shrink the line accordingly.
---]]
-
- if ((x-eff_linewidth) < (lastbar/2)) then
- barsinline = i - mark
- mark = i
- lastbarno = barno[mark]
-
---[[
-C comments:
- last bar in line a zbar?
- if true -> add to the first bar in next line
- the amount of afterruleskip
---]]
-
- if zbar[mark] then
- softbarlength[i+1] = softbarlength[i+1] + afterrule
- eff_softlength[section] = eff_softlength[section] + afterrule
- end
-
---[[
-C comments:
- last bar in line a leftrightrepeat?
- if true -> reduce hardwidth of current line
- advance the hardwidth of next bar
- advance the softwidth of next bar
---]]
-
- if lr_repeat[mark] then
- -- NH: there are some commented lines of code out here (printf statements) that I have not preserved
- -- if they should be reinstated then they are located at lines 744-746 of the original program
- hardlength = hardlength - (width_leftrightrepeat[i] - width_leftrepeat[i])
- eff_hardlength[section] = eff_hardlength[section] + (width_leftrightrepeat[i] - width_leftrepeat[i])
- hardbarlength[i+1] = hardbarlength[i+1] + width_leftrepeat[i]
- softbarlength[i+1] = softbarlength[i+1] + (afterrule/2)
- eff_softlength[section] = eff_softlength[section] + (afterrule/2)
- end
-
---[[
-C comments:
- last bar in line a leftrepeat?
- if true -> reduce hardwidth of current line
- advance the hardwidth of next bar
- advance the softwidth of next bar
---]]
-
- if l_repeat[mark] then
- hardlength = hardlength - (width_leftrepeat[i] - lthick)
- hardbarlength[i+1] = hardbarlength[i+1] + width_leftrepeat[i]
- softbarlength[i+1] = softbarlength[i+1] + (afterrule/2)
- eff_softlength[section] = eff_softlength[section] + (afterrule/2)
- end
-
- if (signchange[sign+1] == mark+1) then -- signed s.b. in C
- sign = sign + 1
---[[
-C comments:
- Because the bar is staying here in the line, we look ahead
- to see if the upcoming bar is a sign change, and adjust space
- to account for the complimentary sign change notice that will
- be posted at the end of this line. However, if the upcoming
- sign change bar is really a bar+xbar set, where the sign change
- is buried in the xbar, then we don't do the move because the
- change notice really won't be posted in this line.
-
- Signed jh-1 in C.
-
---]]
- if (xbar[mark+1] < 2) then -- okay to do the move. signed jh-1 in C
- hardlength = hardlength + oldsignskip[sign]
- hardbarlength[mark+1] = hardbarlength[mark+1] - oldsignskip[sign]
- end
- end
-
- -- Exclude the latest bar, and stretch the line.
-
- else
- barsinline=i-1-mark
- if (barsinline < 1) then error_exit(2) end
- mark = i - 1
- lastbarno = barno[mark]
- hardlength = hardlength - hardbarlength[i]
- softlength = softlength - softbarlength[i]
-
- if zbar[mark] then softbarlength[i] = softbarlength[i] + afterrule end
-
- if lr_repeat[mark] then
- hardlength = hardlength - (width_leftrightrepeat[i-1]-width_leftrepeat[i-1])
- eff_hardlength[section] = eff_hardlength[section] + (width_leftrightrepeat[i-1] - width_leftrepeat[i-1])
- hardbarlength[i] = hardbarlength[i] + width_leftrepeat[i-1]
- softbarlength[i] = softbarlength[i] + (afterrule/2)
- eff_softlength[section] = eff_softlength[section] + (afterrule/2)
- end
-
- if l_repeat[mark] then
- hardlength = hardlength - (width_leftrepeat[i-1] - lthick)
- hardbarlength[i] = hardbarlength[i] + width_leftrepeat[i-1]
- softbarlength[i] = softbarlength[i] + (afterrule/2)
- eff_softlength[section] = eff_softlength[section] + (afterrule/2)
- end
-
---[[
-C comments:
- Error (o/u-hbox) occurs only when signature change start in next line
- -> look for signature change in next line
- if true then advance the hardwidth of current line
- reduce next hard barlength by signature change
---]]
-
- if (signchange[sign] == (mark+1)) then
---[[
-C comments:
-However, if the next bar is a bar+xbar set where the
-sign change comes from the xbar, then don't do this
-move, because the extra skip is not really there!
-
-Signed jh-1 in C.
---]]
- if(xbar[mark+1] < 2) then -- alright, do the move. signed jh-1 in C
- hardlength = hardlength + oldsignskip[sign]
- hardbarlength[mark+1] = hardbarlength[mark+1] - oldsignskip[sign]
- end
-
- end
-
- end
-
---[[
-C comments:
- Define a flex factor for this line as the ratio
- of soft part of the specified line width,
- to soft width in the approximate line.
- --]]
-
- if (softlength == 0) then error_exit(5) end
- flexit = (eff_linewidth - hardlength) / softlength
- if detectraggedline then
- flexit = 1
- detectraggedline = false
- end
- cor_elemskip = elemskip * flexit
- cor_afterrule = afterrule * flexit
- cor_beforerule = beforerule * flexit
-
- if dbug then
- print("Line number : " .. line_number)
- print("Fill length : " .. fill_length)
- print("Effective length : " .. eff_softlength[section] + eff_hardlength[section])
- print("Mean space factor : " .. spc_factor)
- print("Bars in line : " .. barsinline)
- print("Effective linewidth : " .. eff_linewidth)
- print("Uncorrected hard length : " .. hardlength)
- print("Uncorrected soft length : " .. softlength)
- print("fLex factor (soft) : " .. flexit)
- print("Corrected elemskip : " .. cor_elemskip)
- print("Corrected afterrule : " .. cor_afterrule)
- print("Corrected beforerule : " .. cor_beforerule)
-
- io.read() -- NH: mimics getchar()
- end
-
- if dbug_logfile then
- logfile:write("Line number : ", line_number, "\n")
- logfile:write("Fill length : ", fill_length, "\n")
- logfile:write("Effective length : ", eff_softlength[section] + eff_hardlength[section], "\n")
- logfile:write("Mean space factor : ", spc_factor, "\n")
- logfile:write("Bars in line : ", barsinline, "\n")
- logfile:write("Effective linewidth : ", eff_linewidth, "\n")
- logfile:write("Uncorrected hard length : ", hardlength, "\n")
- logfile:write("Uncorrected soft length : ", softlength, "\n")
- logfile:write("Flex factor (soft) : ", flexit, "\n")
- logfile:write("Corrected elemskip : ", cor_elemskip, "\n")
- logfile:write("Corrected afterrule : ", cor_afterrule, "\n")
- logfile:write("Corrected beforerule : ", cor_beforerule, "\n\n")
- end
-
- eff_hardlength[section] = eff_hardlength[section] - hardlength
- eff_softlength[section] = eff_softlength[section] - softlength
- fill_length = fill_length - eff_linewidth
-
- -- Write a record to the output file
-
- outfile:write(
- string.format("\\lineset{%3d}{%2d}{%8.5fpt}{%8.5fpt}{%8.5fpt}%% %d - %d\n",
- line_number, barsinline, cor_elemskip, cor_afterrule,
- cor_beforerule,
- firstbarno, lastbarno))
-
-
-
- if showresult then
- print(
- string.format("\\lineset{%3d}{%2d}{%8.5fpt}{%8.5fpt}{%8.5fpt}%% %d - %d",
- line_number, barsinline, cor_elemskip, cor_afterrule,
- cor_beforerule,
- firstbarno, lastbarno))
- end
-
- if dbug_lines then print(" ... writing line : " .. line_number) end
- line_in_section = line_in_section + 1 -- NH: need to do this in loop, lua syntax doesn't allow for it in for loop spec
- end -- end lines for
-end -- end sections for
-
-if dbug_lines then print("") end
-
-
-samechapter = true
-chapterno = chapterno + 1
-until (not GETLINE()) -- end repeat loop
-
--- closing files
-infile:close()
-io.write(")")
-if dbug_logfile then
- logfile:close()
- if (not logfile) then error_exit(0) end
-end
-outfile:close()
-if (not outfile) then error_exit(0) end
-
-if dbug then
- print(" ... that's all, bye")
-end
-print("")
--- NH: end main chunk and program!
diff --git a/Build/source/texk/texlive/linked_scripts/musixtex/musixtex.lua b/Build/source/texk/texlive/linked_scripts/musixtex/musixtex.lua
deleted file mode 100755
index 930e90d70fe..00000000000
--- a/Build/source/texk/texlive/linked_scripts/musixtex/musixtex.lua
+++ /dev/null
@@ -1,634 +0,0 @@
-#!/usr/bin/env texlua
-
-VERSION = "0.23a"
-
---[[
- musixtex.lua: processes MusiXTeX files using xml2pmx and/or prepmx and/or pmxab
- and/or autosp as pre-processors (and deletes intermediate files)
-
- (c) Copyright 2011-2020 Bob Tennent rdt@cs.queensu.ca
- and Dirk Laurie dirk.laurie@gmail.com
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
---]]
-
---[[
-
- ChangeLog:
-
- version 0.23a 2020-08-14 RDT
- pmxprep files now deleted by xml2pmx
-
- version 0.23 2020-05-21 RDT
- added support for xml2pmx pre-preprocessing
-
- version 0.22 2020-03-20 RDT
- add -X option
- add -version, --version, -help, --help options
-
- version 0.21 2018-07-27 RDT
- add -P option.
-
- version 0.20 2018-06-11 RDT
- remove .mx1 file before tex processing
-
- version 0.19 2017-12-10 RDT
- Allow non-standard extensions.
- Add -M and -A options.
-
- version 0.18 2017-06-13 RDT
- Allow autosp to generate .ltx files
-
- version 0.17a 2017-01-08 RDT
- Added -D option.
- Avoid writing or concatenating a nil value.
-
- version 0.16e 2016-03-02 DL
- missing version information (caused by batchmode in 0.16c) fixed
-
- version 0.16d 2016-03-02 RDT
- filename argument in autosp failure message fixed
-
- version 0.16c 2016-02-24 RDT
- -interaction batchmode for -q
- report_error reports only the first error
-
- version 0.16b 2016-02-20 DL
- Improved help message as suggested by Bob Tennent.
-
- version 0.16a 2015-12-30 DL
- Corrects bug in -g option reported by Christian Mondrup.
-
- version 0.16 2015-12-24 DL
- Versions read from tempfile and written to musixtex.log.
-
- version 0.15 2015-12-03 DL
- Option -q added, which redirects most screen output into
- a temporary file. If an error occurs at the TeX stage, processing
- halts immediately and the tail of the log file is sent to stderr.
-
- version 0.14 2015-12-01 DL
- Writes `musixtex.log` and deletes other logfiles (except with -i)
- Hierarchy of extensions emphasized in usage() and consistently
- used elsewhere.
- Unknown option-like arguments reported and ignored, not treated
- as filenames
- Warnings and error messages generated by musixtex.lua start with
- respctively `!` and `!!`.
-
- version 0.13 2015-11-30 RDT
- Process .mtx and .pmx files (suggested by Dirk Laurie)
- exit_code is now an error count
- Use pmxab exit code to distinguish between errors and warnings
-
- version 0.12 2015-11-28 RDT
- Process .ltx files, with -l implied
-
- version 0.11 2015-07-16 RDT
- Automatic autosp preprocessing.
-
- version 0.10 2015-04-23 RDT
- Add -a option to preprocess using autosp
-
- version 0.9 2015-02-13 RDT
- Add an additional latex pass to resolve cross-references.
- Add -e0 option to dvips as given in musixdoc.tex
- Add -x option to call makeindex
-
- version 0.8 2014-05-18 RDT
- Add -g option
-
- version 0.7 2013-12-11 RDT
- Add -F fmt option
-
- version 0.6 2012-09-14 RDT
- Add -1 (one-pass [pdf][la]tex processing) option.
-
- version 0.5 2011-11-28 RDT
- Add -i (retain intermediate files) option.
-
- version 0.4 2011-04-30 RDT
- Allow multiple filenames (and options).
- Add -f (default) and -l (latex) options.
-
- version 0.3 2011-04-25 RDT
- Add -d (dvipdfm) and -s (stop at dvi) options.
-
- version 0.2 2011-04-21 RDT
- Allow basename.tex as filename.
- Add -p option for pdfetex processing.
- Add standard -v -h options.
---]]
-local orig_print = print
-
-function usage()
- orig_print
-[[
-Usage: [texlua] musixtex.lua { option | basename[ .xml | .mtx | .pmx | .aspc | .tex | .ltx] } ...
- When no extension is given, extensions are tried in the above order
- until a source file is found. Preprocessing goes xml-pmx-tex or mtx-pmx-tex or
- aspc-tex, with the entry point determined by the extension.
- The normal route after preprocessing goes tex-dvi-ps-pdf, but shorter
- routes are also available, see the options. The default 3-pass processing route
- for .tex files is etex-musixflx-etex.
-Options: -v, --version version
- -h, --help help
- -l latex source
- -p direct tex-pdf (pdftex etc)
- -F fmt use fmt as the TeX processor
- -d tex-dvi-pdf (using dvipdfm if -D not used)
- -D dvixx use dvixx as the dvi processor
- -P ps2pdfxx use ps2pdfxx as the Postscript processor
- -c preprocess pmx file using pmxchords
- -m stop at pmx
- -M prepmxx use prepmxx as the mtx preprocessor
- -A autospx use autospx as the aspc preprocessor
- -X pmxabx use pmxabx as the pmx preprocessor
- -L xmlx use xmlx as the xml preprocessor
- -t stop at tex/mid
- -s stop at dvi
- -g stop at ps
- -i retain intermediate and log files
- -q quiet mode (redirect screen logs, write summary on musixtex.log)
- -1 one-pass [pdf][la]tex processing
- -x run makeindex
- -f restore default processing
-Four TeX engines are available via the -l and -p options.
- etex default
- latex -l
- pdfetex -p
- pdflatex -l -p
-If the -F option is used, options -l and -p need to be set if the engine
-name does not contain "latex" and "pdf" respectively. For example, the
-above four engines can be replaced by:
- -F "luatex --output-format=dvi"
- -F "lualatex --output-format=dvi"
- -F "luatex" -p
- -F "lualatex" -p
-]]
-end
-
-function whoami ()
- print("This is musixtex.lua version ".. VERSION .. ".")
-end
-
-function exists (filename, nolog)
- local f = io.open(filename, "r")
- if f then
- f:close()
- if not nolog then musixlog:write("Processing " .. filename,'\n' ) end
- return true
- else
- return false
- end
-end
-
--- System commands for the various programs are mostly
--- set to nil if the step is to be omitted, which can be
--- tested by a simple "if" statement.
--- Exceptions:
--- 'tex' is the command for processing a TeX file, but it is important
--- to know whether the user has explicitly specified an option that
--- affects this choice, in which case the automatic selection of the
--- command is restricted or disabled.
--- force_engine "use the command provided"
--- override records when 'l' and/or 'p' options are in effect
--- 'dvi' is the command for processing a DVI file, but there are two
--- reasons for not needing it and it is important for the automatic
--- selection of a TeX engine to know which is in effect. This is
--- possible by exploiting the the fact that Lua has two false values.
--- dvi == nil "do not produce a DVI file" (but maybe PDF)
--- dvi == false "do not process the DVI file" (but stop after TeX)
-local dvips = "dvips -e0"
-function defaults()
- xml2pmx = "xml2pmx"
- prepmx = "prepmx"
- pmx = "pmxab"
- autosp = "autosp"
- tex = "etex"
- musixflx = "musixflx"
- dvi = dvips
- ps2pdf = "ps2pdf"
- cleanup = true -- clean up intermediate and log files
- index = false
- latex = false
- force_engine = false -- indicates whether -F is specified
- override = ""
- passes = 2
- quiet = "" -- set by "-q"
-end
-
-------------------------------------------------------------------------
-
-if #arg == 0 then
- whoami()
- usage()
- os.exit(0)
-end
-
--- Logging on `musixtex.log` everything that is printed, all os calls,
--- and warnings from other log files.
-
-musixlog = io.open("musixtex.log","w")
-if not musixlog then
- print"!! Can't open files for writing in current directory, aborting"
- os.exit(1)
-end
-
-------------------------------------------------------------------------
-
-print = function(...)
- orig_print(...)
- musixlog:write(...,"\n") -- only the first argument gets written!
-end
-
-local orig_remove = os.remove
-remove = function(filename)
- if exists(filename,"nolog") then
- musixlog:write(" removing ",filename,"\n")
- return orig_remove(filename)
- end
-end
-
-local orig_execute = os.execute
-execute = function(command)
- musixlog:write(" ",command,"\n")
- return orig_execute(command .. quiet)
-end
-
-function report_warnings(filename,pattern)
- local log = io.open(filename)
- if not log then
- print("! No file "..filename)
- return
- end
- for line in log:lines() do
- if line:match(pattern) then
- musixlog:write("! "..line,"\n")
- end
- end
-end
-
-function report_error(filename)
- local log = io.open(filename)
- if not log then
- print("! No file "..filename)
- return
- end
- local trigger = false
- for line in log:lines() do
- if trigger and line:match"^!" then
- -- report just the first error
- break
- end
- trigger = trigger or line:match"^!"
- if trigger then
- io.stderr:write("! "..line,"\n")
- end
- end
-end
-
-function process_option(this_arg)
- if this_arg == "-v" or this_arg == "-version" or this_arg == "--version" then
- os.exit(0)
- elseif this_arg == "-h" or this_arg == "-help" or this_arg == "--help" then
- usage()
- os.exit(0)
- elseif this_arg == "-l" then
- latex = true
- override = override .. 'l'
- elseif this_arg == "-p" then
- dvi = nil
- override = override .. 'p'
- elseif this_arg == "-d" then
- dvi = "dvipdfm"; ps2pdf = nil
- elseif this_arg == "-D" then
- narg = narg+1
- dvi = arg[narg]
- elseif this_arg == "-c" then
- pmx = "pmxchords"
- elseif this_arg == "-F" then
- narg = narg+1
- tex = arg[narg]
- force_engine = true
- elseif this_arg == "-s" then
- dvi = false; ps2pdf = nil; protect.dvi = true
- elseif this_arg == "-g" then
- dvi = dvips; ps2pdf = nil; protect.ps = true
- elseif this_arg == "-i" then
- cleanup = false
- elseif this_arg == "-x" then
- index = true
- elseif this_arg == "-1" then
- passes = 1
- elseif this_arg == "-f" then
- defaults()
- elseif this_arg == "-t" then
- tex, dvi, ps2pdf = nil,nil,nil
- protect.tex = true
- elseif this_arg == "-m" then
- pmx, tex, dvi, ps2pdf = nil,nil,nil,nil
- protect.pmx = true
- elseif this_arg == "-M" then
- narg = narg+1
- prepmx = arg[narg]
- elseif this_arg == "-A" then
- narg = narg+1
- autosp = arg[narg]
- elseif this_arg == "-L" then
- narg = narg+1
- xml2pmx = arg[narg]
- elseif this_arg == "-q" then
- if not tempname then
- tempname = tempname or os.tmpname()
- print("Redirecting screen output to "..tempname)
- end
- if dvi == dvips then dvi = dvi .. " -q" end
- quiet = " >> " .. tempname
- elseif this_arg == "-P" then
- narg = narg+1
- ps2pdf = arg[narg]
- elseif this_arg == "-X" then
- narg = narg+1
- pmx = arg[narg]
- else
- print("! Unknown option "..this_arg.." ignored")
- end
-end
-
-function find_file(this_arg)
- basename, extension = this_arg:match"(.*)%.(.*)"
- extensions = {["xml"] = true, ["mtx"] = true, ["pmx"] = true, ["aspc"] = true, ["tex"] = true, ["ltx"] = true}
- if extensions[extension] then
- return basename, extension
- end
- basename, extension = this_arg, null
- for ext in ("xml,mtx,pmx,aspc,tex,ltx"):gmatch"[^,]+" do
- if exists (basename .. "." .. ext) then
- extension = ext
- break
- end
- end
- if extension == null then
- print("!! No file " .. basename .. ".[xml|mtx|pmx|aspc|tex|ltx]")
- exit_code = exit_code+1
- return
- end
- return basename, extension
-end
-
-function preprocess(basename,extension)
- if not (basename and extension) then return end
- if extension == "xml" then
- if execute(xml2pmx .. " " .. basename .. ".xml" .. " " .. basename .. ".pmx" ) == 0 then
- extension = "pmx"
- else
- print ("!! xml2pmx preprocessing of " .. basename .. ".xml fails.")
- return
- end
- elseif extension == "mtx" then
- if execute(prepmx .. " " .. basename ) == 0 then
- extension = "pmx"
- else
- print ("!! prepmx preprocessing of " .. basename .. ".mtx fails.")
- return
- end
- end
- if extension == "pmx" then
- local OK = true
- if pmx then
- local code = execute(pmx .. " " .. basename)
- local pmxaerr = io.open("pmxaerr.dat", "r")
- if (not pmxaerr) then
- OK = false
- print("!! No pmx log file.")
- else
- extension = "tex"
- local linebuf = pmxaerr:read()
- local err = tonumber(linebuf)
- if (code == 0) then
- if err ~=0 then
- print ("! pmx produced a warning on line "..err..
- " of "..basename..".pmx")
- end
- else
- OK = false
- print ("!! pmx processing of " .. basename .. ".pmx fails.")
- end
- pmxaerr:close()
- end
- end
- if not OK then
- exit_code = exit_code+1
- return
- end
- end
- if extension == "aspc" then
- if execute (autosp .. " " .. basename .. ".aspc" ) == 0 then
- if exists ( basename .. ".ltx")
- then extension = "ltx"
- else extension = "tex"
- end
- else
- print ("!! autosp preprocessing of " .. basename .. ".aspc fails.")
- exit_code = exit_code+1
- return
- end
- end
- return extension
-end
-
-function tex_process(tex,basename,extension)
- if not (extension == "tex" or extension == "ltx") or not tex then return end
- remove(basename .. ".mx1")
- remove(basename .. ".mx2")
- local filename = basename .. "." ..extension
--- .ltx extension re-selects engine only for the current file, and only
--- if default processing is plain TeX
- local latex = latex
- if extension == "ltx" then
- if not force_engine and not latex then
- if dvi then tex = "latex" else tex = "pdflatex" end
- end
- latex = true
- end
- if quiet ~= "" then
- tex = tex .. " -interaction batchmode"
- end
- local OK = (execute(tex .. " " .. filename) == 0)
- if passes ~= 1 then
- OK = OK and (execute(musixflx .. " " .. basename) == 0)
- and (execute(tex .. " " .. filename) == 0)
- if latex and index then
- OK = OK and (execute("makeindex -q " .. basename) == 0)
- and (execute(tex .. " " .. filename) == 0)
- if exists (basename .. ".toc","nolog") then
- -- an extra line for the index will have been added
- OK = OK and (execute(tex .. " " .. filename) == 0)
- -- there is a tiny possibility that the extra line for the index
- -- has changed the pagination. If you feel this should not be
- -- ignored, here are the possibilities:
- -- a. Do an extra TeX pass regardless.
- -- b. Provide a user option -4 to force the extra pass.
- -- c. Compare aux files to find out.
- end
- end
- end
- if (quiet ~= "") and not OK then
- report_error(basename..".log")
- end
- if OK and latex then
- report_warnings(basename..".log","LaTeX.*Warning")
- end
- if dvi then OK = OK and (execute(dvi .. " " .. basename) == 0) end
- if dvi and ps2pdf then
- OK = OK and (execute(ps2pdf .. " " .. basename .. ".ps") == 0)
- if OK then
- print(basename .. ".pdf generated by " .. ps2pdf .. ".")
- end
- end
- if not OK then
- print("!! Processing of " .. filename .. " fails.\n")
- exit_code = exit_code+1
- end
-end
-
----- Report version information on musixtex.log
-
--- File names and message signatures to be looked for in a TeX log file.
-logtargets = {
-mtxtex = {"mtx%.tex","mtxTeX"},
-mtxlatex = {"mtxlatex%.sty","mtxLaTeX"},
-pmxtex = {"pmx%.tex","PMX"},
-musixtex = {"musixtex%.tex","MusiXTeX"},
-musixltx = {"musixltx%.tex","MusiXLaTeX"},
-musixlyr = {"musixlyr%.tex","MusiXLYR"}
-}
-
--- Signatures of messages displayed on standard output by programs
-capturetargets = {
-MTx = "This is (M%-Tx.->)",
-PMX = "This is (PMX[^\n]+)",
-pdftex = "This is (pdfTeX[^\n]+)",
-musixflx = "Musixflx%S+",
-autosp = "This is autosp.*$",
-index = "autosp,MTx,PMX,musixflx,pdftex"
-}
-
-function report_texfiles(logname)
- local log = logname and io.open(logname)
- if not log then return end
- local lines =
- {"--- TeX files actually included according to "..logname.." ---"}
- log = log:read"*a"
--- The following pattern matches filenames input by TeX, even if
--- interrupted by a line break. It may include the first word of
--- an \immediate\write10 message emitted by the file.
- for pos,filename in log:gmatch"%(()(%.?[/]%a[%-/%.%w\n]+)" do
- local hit
- repeat
- local oldfilename = filename
- filename = oldfilename:match"[^\n]+" -- up to next line break
- hit = io.open(filename) -- success if the file exists
- if hit then break end
- filename = oldfilename:gsub("\n","",1) -- remove line break
- until filename==oldfilename
- if hit then
- for target,sig in pairs(logtargets) do
- if filename:match(sig[1]) then
- local i,j = log:find(sig[2].."[^\n]+",pos)
- if j then lines[#lines+1] = filename.."\n "..log:sub(i,j) end
- end
- end
- end
- end
- return table.concat(lines,'\n').."\n"
-end
-
-function report_versions(tempname)
- if not tempname then return end -- only available with -q
- local logs = io.open(tempname)
- if not logs then
- musixlog:write ("No version information: could not open "..tempname)
- return
- end
- local versions = {}
- musixlog:write("--- Programs actually executed according to "..tempname.." ---\n")
- for line in logs:lines() do
- for target in capturetargets.index:gmatch"[^,]+" do
- if not versions[target] then
- local found = line:match(capturetargets[target])
- if found then
- versions[target] = found
- musixlog:write(found,"\n")
- end
- end
- end
- end
- logs:close()
- return
-end
-
-------------------------------------------------------------------------
-
-whoami()
-
-defaults()
-
-exit_code = 0
-narg = 1
-protect = {} -- extensions not to be deleted, even if cleanup requested
-
-repeat
- this_arg = arg[narg]
- if this_arg:match"^%-" then process_option(this_arg)
- else
- basename, extension = find_file(this_arg) -- nil,nil if not found
- if tex then -- tex output enabled, now select engine
- if tex:match"pdf" then dvi = nil end
- if not dvi then ps2pdf = nil end
- -- .ltx extension will be taken into account later, in `process`
- -- deduce tex/latex from current engine name if -l is not specified
- if not override:match"l" then latex = tex:match"latex" end
- if not force_engine then -- select appropriate default engine
- if latex then
- if dvi==nil then tex = "pdflatex" else tex = "latex" end
- else
- if dvi==nil then tex = "pdfetex" else tex = "etex" end
- end
- end
- end
- extension = preprocess(basename, extension)
- tex_process(tex,basename,extension)
- if basename and io.open(basename..".log") then -- to be printed later
- versions = report_texfiles(basename..".log")
- end
- if basename and cleanup then
- remove("pmxaerr.dat")
- for ext in ("mx1,mx2,dvi,ps,idx,log,ilg,pml"):gmatch"[^,]+" do
- if not protect[ext] then remove(basename.."."..ext)
- end
- end
- end
- protect = {}
- end
- narg = narg+1
-until narg > #arg
-
-if versions then musixlog:write(versions) end
-report_versions(tempname)
-musixlog:close()
-os.exit( exit_code )
diff --git a/Build/source/texk/texlive/linked_scripts/pax/pdfannotextractor.pl b/Build/source/texk/texlive/linked_scripts/pax/pdfannotextractor.pl
deleted file mode 100755
index 085dc43c5d3..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pax/pdfannotextractor.pl
+++ /dev/null
@@ -1,433 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-$^W=1;
-
-# Copyright (C) 2008, 2011, 2012 Heiko Oberdiek
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301 USA
-#
-# This file is part of PDFAnnotExtractor. See README.
-
-my $name = 'PDFAnnotExtractor';
-my $program = "\L$name\E";
-my $file = "$program.pl";
-my $version = "0.1l";
-my $date = "2012/04/18";
-my $author = "Heiko Oberdiek";
-my $copyright = "Copyright (c) 2008, 2011, 2012 by $author.";
-
-# History:
-# 2008/10/01 v0.1i: First version of the wrapper script.
-# 2012/04/18 v0.1l: Option --version added.
-
-my $title = "$name $version, $date - $copyright\n";
-my $usage = <<"END_OF_USAGE";
-${title}Syntax: $program [options] <PDF files[.pdf]>
-Options:
- --help print usage
- --version print version number
- --install try installing PDFBox library
- --debug debug informations
-END_OF_USAGE
-
-my $help = 0;
-my $debug = 0;
-my $install = 0;
-my $opt_version = 0;
-use Getopt::Long;
-GetOptions(
- 'debug!' => \$debug,
- 'install!' => \$install,
- 'help!' => \$help,
- 'version!' => \$opt_version,
-) or die $usage;
-!$help or die $usage;
-if ($opt_version) {
- print "$name $date v$version\n";
- exit(0);
-}
-!$install and (@ARGV >= 1 or die $usage);
-
-print $title;
-
-my $error = '!!! Error:';
-my $url_pdfbox = 'http://prdownloads.sourceforge.net/pdfbox/PDFBox-0.7.3.zip?download';
-my $size_pdfbox_zip = 22769102;
-my $size_pdfbox_jar = 3321771;
-my $name_pdfbox_jar = 'PDFBox-0.7.3.jar';
-my $entry_pdfbox = "PDFBox-0.7.3/lib/$name_pdfbox_jar";
-my $pdfbox = 'PDFBox';
-
-my $prg_kpsewhich = 'kpsewhich';
-my $prg_wget = 'wget';
-my $prg_curl = 'curl';
-my $prg_unzip = 'unzip';
-my $prg_texhash = 'texhash';
-my $prg_mktexlsr = 'mktexlsr';
-my $prg_java = 'java';
-my %prg;
-
-my $jar_pax = 'pax.jar';
-my $main_class = 'pax.PDFAnnotExtractor';
-my $jar_pdfbox = 'pdfbox.jar';
-my @jar_pdfbox = qw[
- pdfbox.jar
- PDFBox.jar
- pdfbox-0.7.3.jar
- PDFBox-0.7.3.jar
- pdfbox-0.7.2.jar
- PDFBox-0.7.2.jar
-];
-my @dir_jar = qw[
- /usr/share/java
- /usr/local/share/java
-];
-my $path_jar_pax = '';
-my $path_jar_pdfbox = '';
-my $classpath = defined $ENV{'CLASSPATH'} ? $ENV{'CLASSPATH'} : '';
-debug('CLASSPATH', $classpath);
-my $pdfbox_in_classpath = $classpath =~ /PDFBox/ ? 1 : 0;
-
-my $is_win = 0;
-$is_win = 1 if $^O =~ /^MSWin(32|64)/i
- or $^O =~ /^dos/i
- or $^O =~ /^os2/i;
-debug('is_win', $is_win);
-
-use File::Which;
-
-sub debug ($$) {
- my $key = shift;
- my $value = shift;
- print "* $key: [$value]\n" if $debug;
-}
-
-sub check_prg ($$) {
- my $prg = shift;
- my $die = shift;
- return 1 if $prg{$prg};
- my $path = which($prg);
- if ($path) {
- $prg{$prg} = $path;
- debug "Which $prg", $path;
- return 1;
- }
- debug "Which $prg", '<not found>';
- if ($die) {
- die "$error Cannot find program `$prg'!\n";
- }
- return 0;
-}
-
-sub find_jar ($) {
- my $jar_name = shift;
-
- check_prg $prg_kpsewhich, 1;
- my $cmd = "kpsewhich"
- . " --progname $program"
- . " --format texmfscripts"
- . " $jar_name";
- debug 'Backticks', $cmd;
- my $path = `$cmd`;
- if ($? == 0) {
- chomp $path;
- debug 'Exit code', '0/success';
- debug $jar_name, $path;
- return $path;
- }
- if ($? == -1) {
- die "!!! Error: Cannot execute `$prg_kpsewhich' ($!)!\n";
- }
- if ($? & 127) {
- die "!!! Error: `$prg_kpsewhich' died with signal " . ($? & 127)
- . (($? & 128) ? ' with coredump' : '') . "!\n";
- }
- debug 'Exit code', ($? >> 8);
- return '';
-}
-
-sub find_jar_pax () {
- return if $path_jar_pax;
- foreach my $dir (@dir_jar) {
- my $path = "$dir/$jar_pax";
- if (-f $path) {
- $path_jar_pax = $path;
- debug $jar_pax, $path_jar_pax;
- return;
- }
- }
- $path_jar_pax = find_jar $jar_pax;
- if (!$path_jar_pax) {
- die "$error Cannot find `$jar_pax'!\n";
- }
-}
-
-sub find_jar_pdfbox () {
- return if $path_jar_pdfbox;
- foreach my $dir (@dir_jar) {
- foreach my $jar (@jar_pdfbox) {
- my $path = "$dir/$jar";
- if (-f $path) {
- $path_jar_pdfbox = $path;
- debug $jar_pdfbox, $path_jar_pdfbox;
- return;
- }
- }
- }
- foreach my $jar_pdfbox (@jar_pdfbox) {
- $path_jar_pdfbox = find_jar $jar_pdfbox;
- last if $path_jar_pdfbox;
- }
-}
-
-sub launch_pax () {
- check_prg $prg_java, 1;
- my @cmd = ($prg_java);
- my $sep = $is_win ? ';' : ':';
- my $cp = "$path_jar_pax";
- $cp .= "$sep$path_jar_pdfbox" if $path_jar_pdfbox;
- $cp .= "$sep$classpath" if $classpath;
- push @cmd, '-cp';
- push @cmd, $cp;
- push @cmd, $main_class;
- push @cmd, @ARGV;
- debug 'System', "@cmd";
- system @cmd;
- if ($? == 0) {
- debug 'Result', 'ok';
- return 0;
- }
- if ($? == -1) {
- die "$error Cannot execute `$prg_java' ($!)!\n";
- }
- if ($? & 127) {
- die "$error `$prg_java' died with signal " . ($? & 127)
- . (($? & 128) ? ' with coredump' : '') . "!\n";
- }
- my $exit_code = $? >> 8;
- debug 'Exit code', $exit_code;
- return $exit_code;
-}
-
-# install part
-
-sub expand_var ($) {
- my $var = shift;
- check_prg $prg_kpsewhich, 1;
- my $cmd = $prg_kpsewhich
- . " --progname $program"
- . ' --expand-var';
- $cmd .= $is_win ? " \$$var" : " \\\$$var";
- debug 'Backticks', $cmd;
- my $path = `$cmd`;
- if ($? == 0) {
- chomp $path;
- debug 'Exit code', '0/success';
- debug "\$$var", $path;
- return $path;
- }
- if ($? == -1) {
- die "!!! Error: Cannot execute `$prg_kpsewhich' ($!)!\n";
- }
- if ($? & 127) {
- die "!!! Error: `$prg_kpsewhich' died with signal " . ($? & 127)
- . (($? & 128) ? ' with coredump' : '') . "!\n";
- }
- debug 'Exit code', ($? >> 8);
- return '';
-}
-
-sub ensure_dir ($) {
- my $dir = shift;
- return if -d $dir;
- mkdir $dir or die "$error Cannot create directory `$dir'!\n";
- debug 'mkdir', $dir;
-}
-
-sub file_size ($) {
- my $file = shift;
- return -1 unless -f $file;
- return (stat $file)[7];
-}
-
-if ($install) {
- # Can PDFBox already be found?
- find_jar_pdfbox;
- if ($path_jar_pdfbox) {
- print "* Nothing to do, because $pdfbox is already found:\n"
- . " $path_jar_pdfbox\n";
- exit(0);
- }
-
- # Find TEXMFVAR
- my $tds_root;
- foreach my $var ('TEXMFVAR', 'VARTEXMF') {
- $tds_root = expand_var $var;
- last if $tds_root;
- }
- $tds_root or die "$error Cannot find settings for `TEXMFVAR' or `VARTEXMF'!\n";
-
- # Create directories
- ensure_dir $tds_root;
- my $tds_pax = $tds_root;
- $tds_pax =~ s/(\/*)$/\/scripts/;
- ensure_dir $tds_pax;
- $tds_pax .= '/pax';
- ensure_dir $tds_pax;
- my $tds_pax_lib = "$tds_pax/lib";
- ensure_dir $tds_pax_lib;
-
- # Download
- my $dest_file = "$tds_pax/PDFBox-0.7.3.zip";
- if (file_size $dest_file == $size_pdfbox_zip) {
- debug "$pdfbox archive found", $dest_file;
- }
- else {
- my @cmd;
- my $prg_download;
- check_prg $prg_wget, 0;
- if ($prg{$prg_wget}) {
- $prg_download = $prg_wget;
- push @cmd, $prg_wget;
- push @cmd, '-O';
- }
- else {
- check_prg $prg_curl, 0;
- $prg{$prg_curl} or die "$error Cannot find programs `wget' or `curl'"
- . " for downloading!\n";
- $prg_download = $prg_curl;
- push @cmd, $prg_curl;
- push @cmd, '-L';
- push @cmd, '-o';
- }
- push @cmd, $dest_file;
- push @cmd, $url_pdfbox;
- debug 'System', "@cmd";
- system @cmd;
- if ($? == 0) {
- debug 'Result', 'ok';
- }
- elsif ($? == -1) {
- die "$error Cannot execute `$prg_download' ($!)!\n";
- }
- elsif ($? & 127) {
- die "$error `$prg_download' died with signal " . ($? & 127)
- . (($? & 128) ? ' with coredump' : '') . "!\n";
- }
- else {
- my $exit_code = $? >> 8;
- die "$error `$prg_download' returns error code `$exit_code'!\n";
- }
- -f $dest_file or die "$error Download failed!\n";
- my $size = file_size $dest_file;
- $size == $size_pdfbox_zip
- or die "$error File size of $dest_file is $size,\n"
- . "but expected size is $size_pdfbox_zip!\n";
- }
- print "* Downloaded: $dest_file\n";
-
- # Unpack jar file
- check_prg $prg_unzip, 0;
- if ($prg{$prg_unzip}) {
- my @cmd = (
- $prg_unzip,
- '-j',
- '-d',
- $tds_pax_lib,
- $dest_file,
- $entry_pdfbox
- );
- debug 'System', "@cmd";
- system @cmd;
- if ($? == 0) {
- debug 'Result', 'ok';
- }
- elsif ($? == -1) {
- die "$error Cannot execute `$prg_unzip' ($!)!\n";
- }
- elsif ($? & 127) {
- die "$error `$prg_unzip' died with signal " . ($? & 127)
- . (($? & 128) ? ' with coredump' : '') . "!\n";
- }
- else {
- my $exit_code = $? >> 8;
- die "$error `$prg_unzip' returns error code `$exit_code'!\n";
- }
- }
- else {
- die "$error `$prg_unzip' not found!\n";
- }
- my $dest_jar = "$tds_pax_lib/$name_pdfbox_jar";
- -f $dest_jar or die "$error Unpacking failed!\n";
- my $size = file_size $dest_jar;
- $size == $size_pdfbox_jar
- or die "$error File size of $dest_jar is $size,\n"
- . "but expected size is $size_pdfbox_jar!\n";
-
- print "* Unpacked: $dest_jar\n";
-
- # Update TDS data base
- my $prg_tds_update;
- check_prg $prg_texhash, 0;
- if ($prg{$prg_texhash}) {
- $prg_tds_update = $prg_texhash;
- }
- else {
- check_prg $prg_mktexlsr, 0;
- $prg{$prg_mktexlsr} or die "$error Neither `$prg_texhash' nor `$prg_mktexlsr' found!\n";
- $prg_tds_update = $prg_mktexlsr;
- }
- my @cmd = ($prg_tds_update, $tds_root);
- debug 'System', "@cmd";
- system @cmd;
- if ($? == 0) {
- debug 'Result', 'ok';
- }
- elsif ($? == -1) {
- die "$error Cannot execute `$prg_tds_update' ($!)!\n";
- }
- elsif ($? & 127) {
- die "$error `$prg_tds_update' died with signal " . ($? & 127)
- . (($? & 128) ? ' with coredump' : '') . "!\n";
- }
- else {
- my $exit_code = $? >> 8;
- die "$error `$prg_tds_update' returns error code `$exit_code'!\n";
- }
-
- # Check installation result
- find_jar_pdfbox;
- if ($path_jar_pdfbox) {
- exit(0);
- }
- die "$error Installation failed, because $pdfbox library cannot be found!\n";
-}
-
-# main program
-
-my $ret = 0;
-find_jar_pax;
-if ($pdfbox_in_classpath) {
- debug 'PDFBox in CLASSPATH', 'yes';
-}
-else {
- find_jar_pdfbox;
- $path_jar_pdfbox or die "$error Cannot find $pdfbox library!\n"
- . "See README and option `--install'.\n";
-}
-exit launch_pax;
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2 b/Build/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2
deleted file mode 100755
index f9bb012cc75..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2
+++ /dev/null
@@ -1,318 +0,0 @@
-#!/usr/bin/env python3
-""" pdfbook2 - transform pdf files to booklets
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- """
-
-
-import os
-import shutil
-import subprocess
-import sys
-from optparse import HelpFormatter, OptionGroup, OptionParser
-
-# ===============================================================================
-# Create booklet for file $name
-# ===============================================================================
-
-
-def booklify(name, opts):
- # ------------------------------------------------------ Check if file exists
- print("\nProcessing", name)
- if not os.path.isfile(name):
- print("SKIP: file not found.")
- return
- print("Getting bounds...", end=" ")
- sys.stdout.flush()
-
- # ---------------------------------------------------------- useful constants
- bboxName = b"%%HiResBoundingBox:"
- tmpFile = ".crop-tmp.pdf"
-
- # ------------------------------------------------- find min/max bounding box
- if opts.crop:
- p = subprocess.Popen(
- ["pdfcrop", "--verbose", "--resolution", repr(opts.resolution), name, tmpFile],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- out, err = p.communicate()
- if len(err) != 0:
- print(err)
- print("\n\nABORT: Problem getting bounds")
- sys.exit(1)
- lines = out.splitlines()
- bboxes = [s[len(bboxName) + 1 :] for s in lines if s.startswith(bboxName)]
- bounds = [[float(x) for x in bbox.split()] for bbox in bboxes]
- minLOdd = min([bound[0] for bound in bounds[::2]])
- maxROdd = max([bound[2] for bound in bounds[::2]])
- if len(bboxes) > 1:
- minLEven = min([bound[0] for bound in bounds[1::2]])
- maxREven = max([bound[2] for bound in bounds[1::2]])
- else:
- minLEven = minLOdd
- maxREven = maxROdd
- minT = min([bound[1] for bound in bounds])
- maxB = max([bound[3] for bound in bounds])
-
- widthOdd = maxROdd - minLOdd
- widthEven = maxREven - minLEven
- maxWidth = max(widthOdd, widthEven)
- minLOdd -= maxWidth - widthOdd
- maxREven += maxWidth - widthEven
-
- print("done")
- sys.stdout.flush()
-
- # --------------------------------------------- crop file to area of interest
- print("cropping...", end=" ")
- sys.stdout.flush()
- p = subprocess.Popen(
- [
- "pdfcrop",
- "--bbox-odd",
- "{L} {T} {R} {B}".format(
- L=minLOdd - opts.innerMargin / 2,
- T=minT - opts.topMargin,
- R=maxROdd + opts.outerMargin,
- B=maxB + opts.outerMargin,
- ),
- "--bbox-even",
- "{L} {T} {R} {B}".format(
- L=minLEven - opts.outerMargin,
- T=minT - opts.topMargin,
- R=maxREven + opts.innerMargin / 2,
- B=maxB + opts.outerMargin,
- ),
- "--resolution",
- repr(opts.resolution),
- name,
- tmpFile,
- ],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- out, err = p.communicate()
- if len(err) != 0:
- print(err)
- print("\n\nABORT: Problem with cropping")
- sys.exit(1)
- print("done")
- sys.stdout.flush()
- else:
- shutil.copy(name, tmpFile)
-
- # -------------------------------------------------------- create the booklet
- print("create booklet...", end=" ")
- sys.stdout.flush()
- pdfJamCallList = [
- "pdfjam",
- "--landscape",
- "--suffix",
- "book",
- tmpFile,
- ]
-
- # add option signature if it is defined else booklet
- if opts.signature != 0:
- pdfJamCallList.append("--signature")
- pdfJamCallList.append(repr(opts.signature))
- else:
- pdfJamCallList.append("--booklet")
- pdfJamCallList.append("true")
-
- # add option --paper to call
- if opts.paper is not None:
- pdfJamCallList.append("--paper")
- pdfJamCallList.append(opts.paper)
-
- # add option --short-edge to call
- if opts.shortedge:
- # check if everyshi.sty exists as texlive recommends
- p = subprocess.Popen(
- ["kpsewhich", "everyshi.sty"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
- out, err = p.communicate()
- if len(out) == 0:
- print("\n\nABORT: The everyshi.sty latex package is needed for short-edge.")
- sys.exit(1)
- else:
- pdfJamCallList.append("--preamble")
- pdfJamCallList.append(
- r"\usepackage{everyshi}\makeatletter\EveryShipout{\ifodd\c@page\pdfpageattr{/Rotate 180}\fi}\makeatother"
- )
-
- # run call to pdfJam to make booklet
- p = subprocess.Popen(pdfJamCallList, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = p.communicate()
-
- # -------------------------------------------- move file and remove temp file
- os.rename(tmpFile[:-4] + "-book.pdf", name[:-4] + "-book.pdf")
- os.remove(tmpFile)
- print("done")
- sys.stdout.flush()
-
-
-# ===============================================================================
-# Help formatter
-# ===============================================================================
-
-
-class MyHelpFormatter(HelpFormatter):
- """Format help with indented section bodies.
- """
-
- def __init__(self, indent_increment=4, max_help_position=16, width=None, short_first=0):
- HelpFormatter.__init__(self, indent_increment, max_help_position, width, short_first)
-
- def format_usage(self, usage):
- return ("USAGE\n\n%*s%s\n") % (self.indent_increment, "", usage)
-
- def format_heading(self, heading):
- return "%*s%s\n\n" % (self.current_indent, "", heading.upper())
-
-
-# ===============================================================================
-# main programm
-# ===============================================================================
-
-if __name__ == "__main__":
- # ------------------------------------------------------------ useful strings
- usageString = "Usage: %prog [options] file1 [file2 ...]"
- versionString = """
- %prog v1.4 (https://github.com/jenom/pdfbook2)
- (c) 2015 - 2020 Johannes Neumann (http://www.neumannjo.de)
- licensed under GPLv3 (http://www.gnu.org/licenses/gpl-3.0)
- based on pdfbook by David Firth with help from Marco Pessotto\n"""
- defaultString = " (default: %default)"
-
- # ------------------------------------------------- create commandline parser
- parser = OptionParser(
- usage=usageString, version=versionString, formatter=MyHelpFormatter(indent_increment=4)
- )
-
- generalGroup = OptionGroup(parser, "General")
- generalGroup.add_option(
- "-p",
- "--paper",
- dest="paper",
- type="str",
- action="store",
- metavar="STR",
- help="Format of the output paper dimensions as latex keyword (e.g. a4paper, letterpaper, legalpaper, ...)",
- )
- generalGroup.add_option(
- "-s",
- "--short-edge",
- dest="shortedge",
- action="store_true",
- help="Format the booklet for short-edge double-sided printing",
- default=False,
- )
- generalGroup.add_option(
- "-n",
- "--no-crop",
- dest="crop",
- action="store_false",
- help="Prevent the cropping to the content area",
- default=True,
- )
- parser.add_option_group(generalGroup)
-
- marginGroup = OptionGroup(parser, "Margins")
- marginGroup.add_option(
- "-o",
- "--outer-margin",
- type="int",
- default=40,
- dest="outerMargin",
- action="store",
- metavar="INT",
- help="Defines the outer margin in the booklet" + defaultString,
- )
- marginGroup.add_option(
- "-i",
- "--inner-margin",
- type="int",
- default=150,
- dest="innerMargin",
- action="store",
- metavar="INT",
- help="Defines the inner margin between the pages in the booklet" + defaultString,
- )
- marginGroup.add_option(
- "-t",
- "--top-margin",
- type="int",
- default=30,
- dest="topMargin",
- action="store",
- metavar="INT",
- help="Defines the top margin in the booklet" + defaultString,
- )
- marginGroup.add_option(
- "-b",
- "--bottom-margin",
- type="int",
- default=30,
- metavar="INT",
- dest="bottomMargin",
- action="store",
- help="Defines the bottom margin in the booklet" + defaultString,
- )
- parser.add_option_group(marginGroup)
-
- advancedGroup = OptionGroup(parser, "Advanced")
- advancedGroup.add_option(
- "--signature",
- dest="signature",
- action="store",
- type="int",
- help="Define the signature for the booklet handed to pdfjam, needs to be multiple of 4"
- + defaultString,
- default=0,
- metavar="INT",
- )
- advancedGroup.add_option(
- "--signature*",
- dest="signature",
- action="store",
- type="int",
- help="Same as --signature",
- metavar="INT",
- )
- advancedGroup.add_option(
- "--resolution",
- dest="resolution",
- action="store",
- type="int",
- help="Resolution used by ghostscript in bp" + defaultString,
- metavar="INT",
- default=72,
- )
- parser.add_option_group(advancedGroup)
-
- opts, args = parser.parse_args()
-
- # ------------------------------------ show help if started without arguments
- if len(args) == 0:
- parser.print_version()
- parser.print_help()
- print("")
- sys.exit(2)
-
- # ------------------------------------------- run for each provided file name
- parser.print_version()
- for arg in args:
- booklify(arg, opts)
diff --git a/Build/source/texk/texlive/linked_scripts/pdfcrop/pdfcrop.pl b/Build/source/texk/texlive/linked_scripts/pdfcrop/pdfcrop.pl
deleted file mode 100755
index c459e5c41e1..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pdfcrop/pdfcrop.pl
+++ /dev/null
@@ -1,1263 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-$^W=1; # turn warning on
-#
-# pdfcrop.pl
-#
-# Copyright (C) 2002, 2004, 2005, 2008-2012 Heiko Oberdiek.
-# 2020 Oberdiek Package Support Group
-#
-# This program may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, version 1.3c or later.
-#
-# See file "README.md" for a list of files that belong to this project.
-#
-# This file "pdfcrop.pl" may be renamed to "pdfcrop"
-# for installation purposes.
-#
-my $prj = 'pdfcrop';
-my $file = "$prj.pl";
-my $program = uc($&) if $file =~ /^\w+/;
-my $version = "1.40";
-my $date = "2020/06/06";
-my $author = "Heiko Oberdiek, Oberdiek Package Support Group";
-my $copyright = "Copyright (c) 2002-2020 by $author.";
-#
-# Reqirements: Perl5, Ghostscript
-# History:
-# 2002/10/30 v1.0: First release.
-# 2002/10/30 v1.1: Option --hires added.
-# 2002/11/04 v1.2: "nul" instead of "/dev/null" for windows.
-# 2002/11/23 v1.3: Use of File::Spec module's "devnull" call.
-# 2002/11/29 v1.4: Option --papersize added.
-# 2004/06/24 v1.5: Clear map file entries so that pdfTeX
-# does not touch the fonts.
-# 2004/06/26 v1.6: Use mgs.exe instead of gswin32c.exe for MIKTEX.
-# 2005/03/11 v1.7: Support of spaces in file names
-# (open("-|") is used for ghostscript call).
-# 2008/01/09 v1.8: Fix for moving the temporary file to the output
-# file across file system boundaries.
-# 2008/04/05 v1.9: Options --resolution and --bbox added.
-# 2008/07/16 v1.10: Support for XeTeX added with new options
-# --pdftex, --xetex, and --xetexcmd.
-# 2008/07/22 v1.11: Workaround for open("-|").
-# 2008/07/23 v1.12: Workarounds for the workaround (error detection, ...).
-# 2008/07/24 v1.13: open("-|")/workaround removed.
-# Input files with unsafe file names are linked/copied
-# to temporary file with safe file name.
-# 2008/09/12 v1.14: Error detection for invalid Bounding Boxes.
-# 2009/07/14 v1.15: Fix for negative coordinates in Bounding Boxes
-# (David Menestrina).
-# 2009/07/16 v1.16: Security fixes:
-# * -dSAFER added for Ghostscript,
-# * -no-shell-escape added for pdfTeX/XeTeX.
-# 2009/07/17 v1.17: Security fixes:
-# * Backticks and whitespace are forbidden
-# for options --(gs|pdftex|xetex)cmd.
-# * Validation of options --papersize and --resolution.
-# 2009/07/18 v1.18: * Restricted mode added.
-# * Option --version added.
-# 2009/09/24 v1.19: * Ghostscript detection rewritten.
-# * Cygwin: `gs' is preferred to `gswin32c'.
-# 2009/10/06 v1.20: * File name sanitizing in .tex file.
-# 2009/12/21 v1.21: * Option --ini added for IniTeX mode.
-# * Option --luatex and --luatexcmd added for LuaTeX.
-# 2009/12/29 v1.22: * Syntax description for option --bbox fixed
-# (Lukas Prochazka).
-# 2010/01/09 v1.23: * Options --bbox-odd and -bbox-even added.
-# 2010/08/16 v1.24: * Workaround added for buggy ghostscript ports
-# that print the BoundingBox data twice.
-# 2010/08/26 v1.25: * Fix for the case that the PDF file contains
-# an entry /CropBox different to /MediaBox.
-# * \pageinclude implemented for XeTeX.
-# * XeTeX: --clip does not die, but this option
-# is ignored, because XeTeX always clip.
-# 2010/08/26 v1.26: * XeTeX's \XeTeXpdffile expects keyword
-# `media', not `mediabox'.
-# * New option --pdfversion.
-# Default is `auto' that means the PDF version
-# is inherited from the input file. Before
-# pdfcrop has used the TeX engine's default.
-# * Option --luatex fixed (extra empty page at end).
-# 2010/09/03 v1.27: * Workaround of v1.24 fixed.
-# 2010/09/06 v1.28: * The Windows registry is searched if Ghostscript
-# is not found via PATH.
-# * Windows only: support of spaces in command
-# names in unrestricted mode.
-# 2010/09/06 v1.29: * Find the latest Ghostscript version in registry.
-# 2010/09/15 v1.30: * Warning of pdfTeX because of \pdfobjcompresslevel
-# avoided when reducing \pdfminorversion.
-# * Fix for TeX syntax characters in input file names.
-# 2010/09/17 v1.31: * Passing the input file name via hex string to TeX.
-# * Again input file names restricted for Ghostscript
-# command line, switch then to symbol link/copy
-# method.
-# 2011/08/10 v1.32: * Detection for gswin64c.exe added.
-# 2012/02/01 v1.33: * Input file can be `-' (standard input).
-# 2012/04/18 v1.34: * Format of --version changed
-# from naked version number to a line with
-# program name, date and version.
-# 2012/10/15 v1.35: * Additional debug infos added for Perl version.
-# 2012/10/16 v1.36: * More error codes added.
-# 2012/10/16 v1.37: * Extended error messages if available.
-# * Fix for broken v1.36.
-# 2012/11/02 v1.38: * Fix for unsufficient cleanup, if function `cleanup' is
-# prematurely called in `eval' for `symlink' checking.
-# 2020/05/24 v1.39: * adapted to pdfversion 2.0, corrected luatex support,
-# corrected a problem with xetex.
-# 2020/06/06 v1.40: * improved ghostscript detection on windows when a bash is used
-# added direct pdf version support to xetex.
-
-
-
-### program identification
-my $title = "$program $version, $date - $copyright\n";
-
-### error strings
-my $Error = "!!! Error:"; # error prefix
-
-### make ENV safer
-delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
-
-# Windows detection (no SIGHUP)
-my $Win = 0;
-$Win = 1 if $^O =~ /mswin32/i;
-$Win = 1 if $^O =~ /cygwin/i;
-use Config;
-my $archname = $Config{'archname'};
-$archname = 'unknown' unless defined $Config{'archname'};
-
-### extended error messages
-sub exterr () {
- chomp(my $msg_errno = $!);
- chomp(my $msg_extended_os_error = $^E);
- if ($msg_errno eq $msg_extended_os_error) {
- $msg_errno;
- }
- else {
- "$msg_errno/$msg_extended_os_error";
- }
-}
-
-### string constants for Ghostscript run
-# get Ghostscript command name
-$::opt_gscmd = '';
-sub find_ghostscript () {
- return if $::opt_gscmd;
- if ($::opt_debug) {
- print "* Perl executable: $^X\n";
- if ($] < 5.006) {
- print "* Perl version: $]\n";
- }
- else {
- printf "* Perl version: v%vd\n", $^V;
- }
- if (defined &ActivePerl::BUILD) {
- printf "* Perl product: ActivePerl, build %s\n", ActivePerl::BUILD();
- }
- use Config;
- printf "* Pointer size: $Config{'ptrsize'}\n";
- printf "* Pipe support: %s\n",
- (defined($Config{'d_pipe'}) ? 'yes' : 'no');
- printf "* Fork support: %s\n",
- (defined($Config{'d_fork'}) ? 'yes' : 'no');
- }
- my $system = 'unix';
- $system = "dos" if $^O =~ /dos/i;
- $system = "os2" if $^O =~ /os2/i;
- $system = "win" if $^O =~ /mswin32/i;
- $system = "cygwin" if $^O =~ /cygwin/i;
- $system = "miktex" if defined($ENV{"TEXSYSTEM"}) and
- $ENV{"TEXSYSTEM"} =~ /miktex/i;
- print "* OS name: $^O\n" if $::opt_debug;
- print "* Arch name: $archname\n" if $::opt_debug;
- print "* System: $system\n" if $::opt_debug;
- my %candidates = (
- 'unix' => [qw|gs gsc gswin64c gswin32c|],
- 'dos' => [qw|gs386 gs|],
- 'os2' => [qw|gsos2 gs|],
- 'win' => [qw|gswin32c gs|],
- 'cygwin' => [qw|gs gswin32c|],
- 'miktex' => [qw|mgs gswin32c gs|]
- );
- if ($system eq 'win' or $system eq 'cygwin' or $system eq 'miktex') {
- if ($archname =~ /mswin32-x64/i) {
- my @a = ();
- foreach my $name (@{$candidates{$system}}) {
- push @a, 'gswin64c' if $name eq 'gswin32c';
- push @a, $name;
- }
- $candidates{$system} = \@a;
- }
- }
- my %ext = (
- 'unix' => '',
- 'dos' => '.exe',
- 'os2' => '.exe',
- 'win' => '.exe',
- 'cygwin' => '.exe',
- 'miktex' => '.exe'
- );
- my $candidates_ref = $candidates{$system};
- my $ext = $Config{'_exe'};
- $ext = $ext{$system} unless defined $ext;
- use File::Spec;
- my @path = File::Spec->path();
- my $found = 0;
- foreach my $candidate (@$candidates_ref) {
- foreach my $dir (@path) {
- my $file = File::Spec->catfile($dir, "$candidate$ext");
- if (-x $file) {
- $::opt_gscmd = $candidate;
- $found = 1;
- print "* Found ($candidate): $file\n" if $::opt_debug;
- last;
- }
- print "* Not found ($candidate): $file\n" if $::opt_debug;
- }
- last if $found;
- }
- if (not $found and $Win) {
- $found = SearchRegistry();
- }
- if ($found) {
- print "* Autodetected ghostscript command: $::opt_gscmd\n" if $::opt_debug;
- }
- else {
- $::opt_gscmd = $$candidates_ref[0];
- print "* Default ghostscript command: $::opt_gscmd\n" if $::opt_debug;
- }
-}
-
-sub SearchRegistry () {
- my $found = 0;
- eval 'use Win32::TieRegistry qw|KEY_READ REG_SZ|;';
- if ($@) {
- if ($::opt_debug) {
- print "* Registry lookup for Ghostscript failed:\n";
- my $msg = $@;
- $msg =~ s/\s+$//;
- foreach (split /\r?\n/, $msg) {
- print " $_\n";
- }
- }
- return $found;
- }
- my $open_params = {Access => KEY_READ(), Delimiter => '/'};
- my $key_name_software = 'HKEY_LOCAL_MACHINE/SOFTWARE/';
- my $current_key = $key_name_software;
- my $software = new Win32::TieRegistry $current_key, $open_params;
- if (not $software) {
- print "* Cannot find or access registry key `$current_key'!\n"
- if $::opt_verbose;
- return $found;
- }
- print "* Search registry at `$current_key'.\n" if $::opt_debug;
- my %list;
- foreach my $key_name_gs (grep /Ghostscript/i, $software->SubKeyNames()) {
- $current_key = "$key_name_software$key_name_gs/";
- print "* Registry entry found: $current_key\n" if $::opt_debug;
- my $key_gs = $software->Open($key_name_gs, $open_params);
- if (not $key_gs) {
- print "* Cannot open registry key `$current_key'!\n" if $::opt_debug;
- next;
- }
- foreach my $key_name_version ($key_gs->SubKeyNames()) {
- $current_key = "$key_name_software$key_name_gs/$key_name_version/";
- print "* Registry entry found: $current_key\n" if $::opt_debug;
- if (not $key_name_version =~ /^(\d+)\.(\d+)$/) {
- print " The sub key is not a version number!\n" if $::opt_debug;
- next;
- }
- my $version_main = $1;
- my $version_sub = $2;
- $current_key = "$key_name_software$key_name_gs/$key_name_version/";
- my $key_version = $key_gs->Open($key_name_version, $open_params);
- if (not $key_version) {
- print "* Cannot open registry key `$current_key'!\n" if $::opt_debug;
- next;
- }
- $key_version->FixSzNulls(1);
- my ($value, $type) = $key_version->GetValue('GS_DLL');
- if ($value and $type == REG_SZ()) {
- print " GS_DLL = $value\n" if $::opt_debug;
- $value =~ s|([\\/])([^\\/]+\.dll)$|$1gswin32c.exe|i;
- my $value64 = $value;
- $value64 =~ s/gswin32c\.exe$/gswin64c.exe/;
- if ($archname =~ /mswin32-x64/i and -f $value64) {
- $value = $value64;
- }
- if (-f $value) {
- print " EXE found: $value\n" if $::opt_debug;
- }
- else {
- print " EXE not found!\n" if $::opt_debug;
- next;
- }
- my $sortkey = sprintf '%02d.%03d %s',
- $version_main, $version_sub, $key_name_gs;
- $list{$sortkey} = $value;
- }
- else {
- print " Missing key `GS_DLL' with type `REG_SZ'!\n" if $::opt_debug;
- }
- }
- }
- foreach my $entry (reverse sort keys %list) {
- $::opt_gscmd = $list{$entry};
- print "* Found (via registry): $::opt_gscmd\n" if $::opt_debug;
- $found = 1;
- last;
- }
- return $found;
-}
-
-# restricted mode
-my $restricted = 0;
-if ($0 =~ /rpdfcrop/ or $0 =~ /restricted/) {
- $restricted = 1;
-}
-
-# "null" device
-use File::Spec::Functions qw(devnull);
-my $null = devnull();
-
-### variables
-my $inputfile = "";
-my $outputfile = "";
-my $tmp = "tmp-\L$program\E-$$";
-
-### paper sizes
-
-my @papersizes = qw[
- 11x17 ledger legal letter lettersmall
- archE archD archC archB archA
- a0 a1 a2 a3 a4 a4small a5 a6 a7 a8 a9 a10
- isob0 isob1 isob2 isob3 isob4 isob5 isob6
- c0 c1 c2 c3 c4 c5 c6
- jisb0 jisb1 jisb2 jisb3 jisb4 jisb5 jisb6
- b0 b1 b2 b3 b4 b5
- flsa flse halfletter
-];
-my %papersizes;
-foreach (@papersizes) {
- $papersizes{$_} = 1;
-}
-
-### option variables
-my @bool = ("false", "true");
-$::opt_version = 0;
-$::opt_help = 0;
-$::opt_debug = 0;
-$::opt_verbose = 0;
-$::opt_pdftexcmd = "pdftex";
-$::opt_xetexcmd = "xetex";
-$::opt_luatexcmd = "luatex";
-$::opt_tex = "pdftex";
-$::opt_margins = "0 0 0 0";
-$::opt_clip = 0;
-$::opt_hires = 0;
-$::opt_papersize = "";
-$::opt_resolution = "";
-$::opt_bbox = "";
-$::opt_bbox_odd = "";
-$::opt_bbox_even = "";
-$::opt_initex = 0;
-$::opt_pdfversion = "auto";
-$::opt_uncompress = 0;
-
-sub usage ($) {
- my $ret = shift;
- find_ghostscript();
- my $usage = <<"END_OF_USAGE";
-${title}Syntax: \L$program\E [options] <input[.pdf]> [output file]
-Function: Margins are calculated and removed for each page in the file.
-Options: (defaults:)
- --help print usage
- --version print version number
- --(no)verbose verbose printing ($bool[$::opt_verbose])
- --(no)debug debug informations ($bool[$::opt_debug])
- --gscmd <name> call of ghostscript ($::opt_gscmd)
- --pdftex | --xetex | --luatex
- use pdfTeX | use XeTeX | use LuaTeX ($::opt_tex)
- --pdftexcmd <name> call of pdfTeX ($::opt_pdftexcmd)
- --xetexcmd <name> call of XeTeX ($::opt_xetexcmd)
- --luatexcmd <name> call of LuaTeX ($::opt_luatexcmd)
- --margins "<left> <top> <right> <bottom>" ($::opt_margins)
- add extra margins, unit is bp. If only one number is
- given, then it is used for all margins, in the case
- of two numbers they are also used for right and bottom.
- --(no)clip clipping support, if margins are set ($bool[$::opt_clip])
- (not available for --xetex)
- --(no)hires using `%%HiResBoundingBox' ($bool[$::opt_hires])
- instead of `%%BoundingBox'
- --(no)ini use iniTeX variant of the TeX compiler ($bool[$::opt_initex])
-Expert options:
- --restricted turn on restricted mode ($bool[$restricted])
- --papersize <foo> parameter for gs's -sPAPERSIZE=<foo>,
- use only with older gs versions <7.32 ($::opt_papersize)
- --resolution <xres>x<yres> ($::opt_resolution)
- --resolution <res> pass argument to ghostscript's option -r
- Example: --resolution 72
- --bbox "<left> <bottom> <right> <top>" ($::opt_bbox)
- override bounding box found by ghostscript
- with origin at the lower left corner
- --bbox-odd Same as --bbox, but for odd pages only ($::opt_bbox_odd)
- --bbox-even Same as --bbox, but for even pages only ($::opt_bbox_even)
- --pdfversion <x.y> | auto | none
- Set the PDF version to x.y, x= 1 or 2, y=0-9.
- If `auto' is given as value, then the
- PDF version is taken from the header
- of the input PDF file.
- An empty value or `none' uses the
- default of the TeX engine. ($::opt_pdfversion)
- --uncompress creates an uncompressed pdf,
- useful for debugging ($bool[$::opt_uncompress])
-
-Input file: If the name is `-', then the standard input is used and
- the output file name must be explicitly given.
-Examples:
- \L$program\E --margins 10 input.pdf output.pdf
- \L$program\E --margins '5 10 5 20' --clip input.pdf output.pdf
-In case of errors:
- Try option --verbose first to get more information.
-In case of bugs:
- Please, use option --debug for bug reports.
-END_OF_USAGE
- if ($ret) {
- die $usage;
- }
- else {
- print $usage;
- exit(0);
- }
-}
-
-### process options
-my @OrgArgv = @ARGV;
-use Getopt::Long;
-GetOptions(
- "help!",
- "version!",
- "debug!",
- "verbose!",
- "gscmd=s",
- "pdftexcmd=s",
- "xetexcmd=s",
- "luatexcmd=s",
- "pdftex" => sub { $::opt_tex = 'pdftex'; },
- "xetex" => sub { $::opt_tex = 'xetex'; },
- "luatex" => sub { $::opt_tex = 'luatex'; },
- "initex!",
- "margins=s",
- "clip!",
- "hires!",
- "papersize=s",
- "resolution=s",
- "bbox=s",
- "bbox-odd=s" => \$::opt_bbox_odd,
- "bbox-even=s" => \$::opt_bbox_even,
- "restricted" => sub { $restricted = 1; },
- "pdfversion=s" => \$::opt_pdfversion,
- "uncompress!",
-) or usage(1);
-!$::opt_help or usage(0);
-
-if ($::opt_version) {
- print "$prj $date v$version\n";
- exit(0);
-}
-
-$::opt_verbose = 1 if $::opt_debug;
-
-@ARGV >= 1 or usage(1);
-
-print $title;
-
-print "* Restricted mode: ", ($restricted ? "enabled" : "disabled"), "\n"
- if $::opt_debug;
-
-$::opt_pdfversion =~ /^(|none|auto|(([1-2])\.(\d)))$/
- or die "!!! Error: Invalid value `$::opt_pdfversion' for option `--pdfversion'!\n";
-print "* Option `pdfversion': $::opt_pdfversion\n" if $::opt_debug;
-$::opt_pdfversion = $2 if $2;
-$::opt_pdfmajorversion = $3 if $2;
-$::opt_pdfminorversion = $4 if $2;
-$::opt_pdfversion = '' if $::opt_pdfversion eq 'none';
-
-find_ghostscript();
-
-if ($::opt_bbox) {
- $::opt_bbox =~ s/^\s+//;
- $::opt_bbox =~ s/\s+$//;
- $::opt_bbox =~ s/\s+/ /;
- if ($::opt_bbox =~ /^-?\d*\.?\d+ -?\d*\.?\d+ -?\d*\.?\d+ -?\d*\.?\d+$/) {
- print "* Explicite Bounding Box: $::opt_bbox\n" if $::opt_debug;
- }
- else {
- die "$Error Parse error (option --bbox \"$::opt_bbox\")!\n";
- }
-}
-if ($::opt_bbox_odd) {
- $::opt_bbox_odd =~ s/^\s+//;
- $::opt_bbox_odd =~ s/\s+$//;
- $::opt_bbox_odd =~ s/\s+/ /;
- if ($::opt_bbox_odd =~ /^-?\d*\.?\d+ -?\d*\.?\d+ -?\d*\.?\d+ -?\d*\.?\d+$/) {
- print "* Explicite Bounding Box for odd pages: $::opt_bbox_odd\n"
- if $::opt_debug;
- }
- else {
- die "$Error Parse error (option --bbox-odd \"$::opt_bbox_odd\")!\n";
- }
-}
-if ($::opt_bbox_even) {
- $::opt_bbox_even =~ s/^\s+//;
- $::opt_bbox_even =~ s/\s+$//;
- $::opt_bbox_even =~ s/\s+/ /;
- if ($::opt_bbox_even =~ /^-?\d*\.?\d+ -?\d*\.?\d+ -?\d*\.?\d+ -?\d*\.?\d+$/) {
- print "* Explicite Bounding Box for even pages: $::opt_bbox_even\n"
- if $::opt_debug;
- }
- else {
- die "$Error Parse error (option --bbox-even \"$::opt_bbox_even\")!\n";
- }
-}
-
-@ARGV <= 2 or die "$Error Too many files!\n";
-
-### input file
-$inputfile = shift @ARGV;
-
-if ($inputfile eq '-') {
- @ARGV == 1 or die "$Error Missing output file name!\n";
- print "* Input file: <stdin>\n" if $::opt_debug;
-}
-else {
- if (! -f $inputfile) {
- if (-f "$inputfile.pdf") {
- $inputfile .= ".pdf";
- }
- else {
- die "$Error Input file `$inputfile' not found!\n";
- }
- }
- print "* Input file: $inputfile\n" if $::opt_debug;
-}
-
-### output file
-if (@ARGV) {
- $outputfile = shift @ARGV;
-}
-else {
- $outputfile = $inputfile;
- $outputfile =~ s/\.pdf$//i;
- $outputfile .= "-crop.pdf";
-}
-
-print "* Output file: $outputfile\n" if $::opt_debug;
-
-### margins
-my ($llx, $lly, $urx, $ury) = (0, 0, 0, 0);
-if ($::opt_margins =~
- /^\s*([\-\.\d]+)\s+([\-\.\d]+)\s+([\-\.\d]+)\s+([\-\.\d]+)\s*$/) {
- ($llx, $lly, $urx, $ury) = ($1, $2, $3, $4);
-}
-else {
- if ($::opt_margins =~ /^\s*([\-\.\d]+)\s+([\-\.\d]+)\s*$/) {
- ($llx, $lly, $urx, $ury) = ($1, $2, $1, $2);
- }
- else {
- if ($::opt_margins =~ /^\s*([\-\.\d]+)\s*$/) {
- ($llx, $lly, $urx, $ury) = ($1, $1, $1, $1);
- }
- else {
- die "$Error Parse error (option --margins)!\n";
- }
- }
-}
-print "* Margins: $llx $lly $urx $ury\n" if $::opt_debug;
-
-### papersize validation (security)
-if ($::opt_papersize ne '') {
- $::opt_papersize =~ /^[0-9A-Za-z]+$/
- or die "$Error Invalid papersize ($::opt_papersize)!\n";
- $papersizes{$::opt_papersize}
- or die "$Error Unknown papersize ($::opt_papersize),"
- . " see ghostscript's documentation for option `-r'!\n";
-}
-
-### resolution validation (security)
-if ($::opt_resolution ne '') {
- $::opt_resolution =~ /^\d+(x\d+)?$/
- or die "$Error Invalid resolution ($::opt_resolution),"
- . " see ghostscript's documentation!\n";
-}
-
-### command name validation (security)
-my %cmd = (
- 'gscmd' => \$::opt_gscmd,
- 'pdftexcmd' => \$::opt_pdftexcmd,
- 'luatexcmd' => \$::opt_luatexcmd,
- 'xetexcmd' => \$::opt_xetexcmd
-);
-foreach my $cmd (keys %cmd) {
- my $cmd_ref = $cmd{$cmd};
- $$cmd_ref =~ s/^\s+//;
- $$cmd_ref =~ s/\s+$//;
- my $val = $$cmd_ref;
- next unless $val;
- next unless $val;
- if ($val =~ /`/) {
- die "$Error Forbidden backtick for option `--$cmd' ($val)!\n";
- }
- if ($val =~ /\s/) {
- my $err = 0;
- if ($restricted or not $Win) {
- $err = 1;
- }
- else {
- $err = 1 if $val =~ /\.exe.*\s/i;
- $err = 1 if $val =~ /\s[-\/@+]/;
- }
- die "$Error Forbidden whitespace for option `--$cmd' ($val)!\n" if $err;
- }
-}
-if ($restricted) {
- if ($::opt_pdftexcmd and $::opt_pdftexcmd ne 'pdftex') {
- die "$Error pdfTeX program name must not be changed in restricted mode!\n";
- }
- if ($::opt_xetexcmd and $::opt_xetexcmd ne 'xetex') {
- die "$Error XeTeX program name must not be changed in restricted mode!\n";
- }
- if ($::opt_luatexcmd and $::opt_luatexcmd ne 'luatex') {
- die "$Error LuaTeX program name must not be changed in restricted mode!\n";
- }
- if ($::opt_gscmd) {
- $::opt_gscmd =~ /^(gs|mgs|gswin32c|gs386|gsos2)$/
- or $::opt_gscmd =~ /^gs[\-_]?(\d|\d[\.-_]?\d\d)c?$/
- or die "$Error: Invalid Ghostscript program name in restricted mode!\n";
- }
-}
-if ($Win and $::opt_gscmd =~ /\s/) {
- $::opt_gscmd = "\"$::opt_gscmd\"";
-}
-
-### cleanup system
-my @unlink_files = ();
-my $exit_code = 1;
-sub clean {
- print "* Cleanup\n" if $::opt_debug;
- if ($::opt_debug) {
- print "* Temporary files: @unlink_files\n";
- }
- else {
- for (; @unlink_files>0; ) {
- unlink shift @unlink_files;
- }
- }
-}
-sub cleanup {
- clean();
- exit($exit_code);
-}
-$SIG{'INT'} = \&cleanup;
-$SIG{'__DIE__'} = \&clean;
-
-### Calculation of BoundingBoxes
-
-# use safe file name for use within cmd line of gs (unknown shell: space, ...)
-# and XeTeX (hash, curly braces, ...)
-my $inputfilesafe = $inputfile;
-if ($inputfile eq '-') {
- $inputfilesafe = "$tmp-stdin.pdf";
- print "* Temporary input file: $inputfilesafe\n" if $::opt_debug;
- push @unlink_files, $inputfilesafe;
- open(OUT, '>', $inputfilesafe)
- or die sprintf "$Error Cannot write `%s' (%s)!\n",
- $inputfilesafe, exterr;
- binmode(OUT);
- my $size = 0;
- my $len = 0;
- my $buf = '';
- my $buf_size = 65536;
- do {
- $len = read STDIN, $buf, $buf_size;
- if (not defined $len) {
- my $msg = exterr;
- die "$Error Reading standard input ($msg)!\n";
- }
- print OUT $buf
- or die sprintf "$Error Writing `%s` (%s)!\n",
- $inputfilesafe, exterr;
- $size += $len;
- }
- while ($len);
- close(OUT);
- print "* File size (STDIN): $size\n" if $::opt_debug;
-}
-elsif (not $inputfile =~ /^[\w\d\.\-\:\/@]+$/) { # /[\s\$~'"#{}%]/
- $inputfilesafe = "$tmp-img.pdf";
- push @unlink_files, $inputfilesafe;
- my $symlink_exists = eval {
- local $SIG{'__DIE__'};
- symlink("", "");
- 1;
- };
- print "* Input file name `$inputfile' contains special characters.\n"
- . "* " . ($symlink_exists ? "Link" : "Copy")
- . " input file to temporary file `$inputfilesafe'.\n"
- if $::opt_verbose;
- if ($symlink_exists) {
- symlink($inputfile, $inputfilesafe)
- or die sprintf "$Error Link from `%s' to `%s' failed (%s)!\n",
- $inputfile, $inputfilesafe, exterr;
- }
- else {
- use File::Copy;
- copy($inputfile, $inputfilesafe)
- or die sprintf "$Error Copy from `%s' to `%s' failed (%s)\n",
- $inputfile, $inputfilesafe, exterr;
- }
-}
-
-if ($::opt_pdfversion eq 'auto') {
- open(IN, '<', $inputfilesafe)
- or die sprintf "!!! Error: Cannot open `%s' (%s)!\n",
- $inputfilesafe, exterr;
- my $buf;
- read(IN, $buf, 1024)
- or die sprintf "!!! Error: Cannot read the header of `%s' failed (%s)!\n",
- $inputfilesafe, exterr;
- close(IN);
- if ($buf =~ /%PDF-((\d).(\d))\s/) {
- $::opt_pdfversion = $1;
- $::opt_pdfmajorversion = $2;
- $::opt_pdfminorversion = $3;
- print "* PDF header: %PDF-$::opt_pdfversion\n" if $::opt_verbose;
- $::opt_pdfminorversion = 2 if ($::opt_pdfmajorversion < 2 && $::opt_pdfminorversion < 2);
- $::opt_pdfversion = $::opt_pdfmajorversion . '.' . $::opt_pdfminorversion;
- }
- else {
- die "!!! Error: Cannot find PDF header of `$inputfilesafe'!\n";
- }
-}
-print '* Using PDF version: ',
- ($::opt_pdfversion ? $::opt_pdfversion : "engine's default"),
- "\n" if $::opt_debug;
-
-my @gsargs = (
- "-sDEVICE=bbox",
- "-dBATCH",
- "-dNOPAUSE"
-);
-push @gsargs, "-sPAPERSIZE=$::opt_papersize" if $::opt_papersize;
-push @gsargs, "-r$::opt_resolution" if $::opt_resolution;
-push @gsargs,
- "-c",
- "save",
- "pop",
- "-f",
- $inputfilesafe
-;
-
-my $tmpfile = "$tmp.tex";
-push @unlink_files, $tmpfile;
-open(TMP, ">$tmpfile")
- or die sprintf "$Error Cannot write tmp file `%s' (%s)!\n",
- $tmpfile, exterr;
-print TMP <<'END_TMP';
-\catcode37 14 % percent
-\catcode33 12 % exclam
-\catcode34 12 % quote
-\catcode35 6 % hash
-\catcode39 12 % apostrophe
-\catcode40 12 % left parenthesis
-\catcode41 12 % right parenthesis
-\catcode45 12 % minus
-\catcode46 12 % period
-\catcode60 12 % less
-\catcode61 12 % equals
-\catcode62 12 % greater
-\catcode64 12 % at
-\catcode91 12 % left square
-\catcode93 12 % right square
-\catcode96 12 % back tick
-\catcode123 1 % left curly brace
-\catcode125 2 % right curly brace
-\catcode126 12 % tilde
-\catcode`\#=6 %
-\escapechar=92 %
-\def\IfUndefined#1#2#3{%
- \begingroup\expandafter\expandafter\expandafter\endgroup
- \expandafter\ifx\csname#1\endcsname\relax
- #2%
- \else
- #3%
- \fi
-}
-END_TMP
-my $pdffilehex = unpack 'H*', $inputfilesafe;
-$pdffilehex = "\U$pdffilehex\E";
-print TMP "\\def\\pdffilehex{$pdffilehex}\n";
-print TMP <<'END_TMP';
-\IfUndefined{pdfunescapehex}{%
- \begingroup
- \gdef\pdffile{}%
- \def\do#1#2{%
- \ifx\relax#2\relax
- \ifx\relax#1\relax
- \else
- \errmessage{Invalid hex string, should not happen!}%
- \fi
- \else
- \lccode`0="#1#2\relax
- \lowercase{%
- \xdef\pdffile{\pdffile0}%
- }%
- \expandafter\do
- \fi
- }%
- \expandafter\do\pdffilehex\relax\relax
- \endgroup
-}{%
- \edef\pdffile{\pdfunescapehex{\pdffilehex}}%
-}
-\immediate\write-1{Input file: \pdffile}
-END_TMP
-if ($::opt_tex eq 'luatex') {
- print TMP <<'END_TMP';
-\begingroup\expandafter\expandafter\expandafter\endgroup
-\expandafter\ifx\csname directlua\endcsname\relax
- \errmessage{LuaTeX not found!}%
-\else
-\fi
-END_TMP
-}
-
-my $uncompress = $::opt_uncompress ? '0 ' : '9 ';
-if ($::opt_tex eq 'pdftex') {
- print TMP "\\pdfcompresslevel=$uncompress ";
- print TMP <<'END_TMP_HEAD';
-\pdfoutput=1 %
-\csname pdfmapfile\endcsname{}
-\def\setpdfversion#1#2{%
- \IfUndefined{pdfobjcompresslevel}{%
- }{%
- \ifnum#1=1 %
- \ifnum#2<5
- \pdfobjcompresslevel=0 %
- \else
- \pdfobjcompresslevel=2 %
- \fi
- \fi
- }%
- \IfUndefined{pdfminorversion}{%
- \IfUndefined{pdfoptionpdfminorversion}{%
- }{%
- \pdfoptionpdfminorversion=#2\relax
- }%
- }{%
- \pdfminorversion=#2\relax
- \IfUndefined{pdfmajorversion}{%
- \ifnum#2=0 \pdfminorversion=5\fi}
- {\pdfmajorversion=#1\relax}%
- }%
-}
-\def\page #1 [#2 #3 #4 #5]{%
- \count0=#1\relax
- \setbox0=\hbox{%
- \pdfximage page #1 mediabox{\pdffile}%
- \pdfrefximage\pdflastximage
- }%
- \pdfhorigin=-#2bp\relax
- \pdfvorigin=#3bp\relax
- \pdfpagewidth=#4bp\relax
- \advance\pdfpagewidth by -#2bp\relax
- \pdfpageheight=#5bp\relax
- \advance\pdfpageheight by -#3bp\relax
- \ht0=\pdfpageheight
- \shipout\box0\relax
-}
-\def\pageclip #1 [#2 #3 #4 #5][#6 #7 #8 #9]{%
- \count0=#1\relax
- \dimen0=#4bp\relax \advance\dimen0 by -#2bp\relax
- \edef\imagewidth{\the\dimen0}%
- \dimen0=#5bp\relax \advance\dimen0 by -#3bp\relax
- \edef\imageheight{\the\dimen0}%
- \pdfximage page #1 mediabox{\pdffile}%
- \setbox0=\hbox{%
- \kern -#2bp\relax
- \lower #3bp\hbox{\pdfrefximage\pdflastximage}%
- }%
- \wd0=\imagewidth\relax
- \ht0=\imageheight\relax
- \dp0=0pt\relax
- \pdfhorigin=#6pt\relax
- \pdfvorigin=#7bp\relax
- \pdfpagewidth=\imagewidth
- \advance\pdfpagewidth by #6bp\relax
- \advance\pdfpagewidth by #8bp\relax
- \pdfpageheight=\imageheight\relax
- \advance\pdfpageheight by #7bp\relax
- \advance\pdfpageheight by #9bp\relax
- \pdfxform0\relax
- \shipout\hbox{\pdfrefxform\pdflastxform}%
-}%
-\def\pageinclude#1{%
- \pdfhorigin=0pt\relax
- \pdfvorigin=0pt\relax
- \pdfximage page #1 mediabox{\pdffile}%
- \setbox0=\hbox{\pdfrefximage\pdflastximage}%
- \pdfpagewidth=\wd0\relax
- \pdfpageheight=\ht0\relax
- \advance\pdfpageheight by \dp0\relax
- \shipout\hbox{%
- \raise\dp0\box0\relax
- }%
-}
-END_TMP_HEAD
- print TMP "\\setpdfversion{$::opt_pdfmajorversion}{$::opt_pdfminorversion}\n" if $::opt_pdfversion;
-}
-elsif ($::opt_tex eq 'luatex')
- {
- print TMP "\\pdfvariable compresslevel=$uncompress ";
- print TMP <<'END_TMP_HEAD';
-\outputmode=1 %
-\pdfextension mapfile {}
-\def\setpdfversion#1#2{%
- \ifnum#1=1 %
- \ifnum#2<5
- \pdfvariable objcompresslevel=0 %
- \else
- \pdfvariable objcompresslevel=2 %
- \fi
- \fi
- \pdfvariable minorversion= #2
- \pdfvariable majorversion= #1
-}
-\def\page #1 [#2 #3 #4 #5]{%
- \count0=#1\relax
- \setbox0=\hbox{%
- \saveimageresource page #1 mediabox{\pdffile}%
- \useimageresource\lastsavedimageresourceindex
- }%
- \pdfvariable horigin=-#2bp\relax
- \pdfvariable vorigin=#3bp\relax
- \pagewidth=#4bp\relax
- \advance\pagewidth by -#2bp\relax
- \pageheight=#5bp\relax
- \advance\pageheight by -#3bp\relax
- \ht0=\pageheight
- \shipout\box0\relax
-}
-\def\pageclip #1 [#2 #3 #4 #5][#6 #7 #8 #9]{%
- \count0=#1\relax
- \dimen0=#4bp\relax \advance\dimen0 by -#2bp\relax
- \edef\imagewidth{\the\dimen0}%
- \dimen0=#5bp\relax \advance\dimen0 by -#3bp\relax
- \edef\imageheight{\the\dimen0}%
- \saveimageresource page #1 mediabox{\pdffile}%
- \setbox0=\hbox{%
- \kern -#2bp\relax
- \lower #3bp\hbox{\useimageresource\lastsavedimageresourceindex}%
- }%
- \wd0=\imagewidth\relax
- \ht0=\imageheight\relax
- \dp0=0pt\relax
- \pdfvariable horigin=#6pt\relax
- \pdfvariable vorigin=#7bp\relax
- \pagewidth=\imagewidth
- \advance\pagewidth by #6bp\relax
- \advance\pagewidth by #8bp\relax
- \pageheight=\imageheight\relax
- \advance\pageheight by #7bp\relax
- \advance\pageheight by #9bp\relax
- \saveboxresource0\relax
- \shipout\hbox{\useboxresource\lastsavedboxresourceindex}%
-}%
-\def\pageinclude#1{%
- \pdfvariable horigin=0pt\relax
- \pdfvariable vorigin=0pt\relax
- \saveimageresource page #1 mediabox{\pdffile}%
- \setbox0=\hbox{\useimageresource\lastsavedimageresourceindex}%
- \pagewidth=\wd0\relax
- \pageheight=\ht0\relax
- \advance\pageheight by \dp0\relax
- \shipout\hbox{%
- \raise\dp0\box0\relax
- }%
-}
-END_TMP_HEAD
- print TMP "\\setpdfversion{$::opt_pdfmajorversion}{$::opt_pdfminorversion}\n" if $::opt_pdfversion;
-}
-else { # XeTeX
- print TMP <<'END_TMP_HEAD';
-\expandafter\ifx\csname XeTeXpdffile\endcsname\relax
- \errmessage{XeTeX not found or too old!}%
-\fi
-\def\setpdfversion#1#2{%
- \special{pdf:majorversion #1}%
- \special{pdf:minorversion #2}}
-
-\def\page #1 [#2 #3 #4 #5]{%
- \count0=#1\relax
- \setbox0=\hbox{%
- \XeTeXpdffile "\pdffile" page #1 media\relax
- }%
- \pdfpagewidth=#4bp\relax
- \advance\pdfpagewidth by -#2bp\relax
- \pdfpageheight=#5bp\relax
- \advance\pdfpageheight by -#3bp\relax
- \shipout\hbox{%
- \kern-1in%
- \kern-#2bp%
- \vbox{%
- \kern-1in%
- \kern#3bp%
- \ht0=\pdfpageheight
- \box0 %
- }%
- }%
-}
-\def\pageclip #1 [#2 #3 #4 #5][#6 #7 #8 #9]{%
- \page {#1} [#2 #3 #4 #5]%
-}
-\def\pageinclude#1{%
- \setbox0=\hbox{%
- \XeTeXpdffile "\pdffile" page #1 media\relax
- }%
- \pdfpagewidth=\wd0\relax
- \pdfpageheight=\ht0\relax
- \advance\pdfpageheight by \dp0\relax
- \shipout\hbox{%
- \kern-1in%
- \vbox{%
- \kern-1in%
- \ht0=\pdfpageheight
- \box0 %
- }%
- }%
-}
-END_TMP_HEAD
-print TMP "\\setpdfversion{$::opt_pdfmajorversion}{$::opt_pdfminorversion}\n" if $::opt_pdfversion;
-}
-
-print "* Running ghostscript for BoundingBox calculation ...\n"
- if $::opt_verbose;
-print "* Ghostscript call: $::opt_gscmd @gsargs\n" if $::opt_debug;
-
-my @bbox;
-my @bbox_all;
-my @bbox_odd;
-my @bbox_even;
-if ($::opt_bbox) {
- $::opt_bbox =~ /([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)/;
- @bbox_all = ($1, $2, $3, $4);
-}
-if ($::opt_bbox_odd) {
- $::opt_bbox_odd =~ /([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)/;
- @bbox_odd = ($1, $2, $3, $4);
-}
-if ($::opt_bbox_even) {
- $::opt_bbox_even =~ /([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)/;
- @bbox_even = ($1, $2, $3, $4);
-}
-
-sub getbbox ($$$$$) {
- my $page = shift;
- my $a = shift;
- my $b = shift;
- my $c = shift;
- my $d = shift;
- if ($page % 2 == 1) {
- if ($::opt_bbox_odd) {
- return @bbox_odd;
- }
- }
- else {
- if ($::opt_bbox_even) {
- return @bbox_even;
- }
- }
- if ($::opt_bbox) {
- return @bbox_all;
- }
- return ($a, $b, $c, $d);
-}
-my $page = 0;
-my $gs_pipe = "$::opt_gscmd -dSAFER @gsargs 2>&1";
-$gs_pipe .= " 1>$null" unless $::opt_verbose;
-$gs_pipe .= " |";
-
-open(GS, $gs_pipe)
- or die sprintf "$Error Cannot call ghostscript `%s' (%s)!\n",
- $::opt_gscmd, exterr;
-my $bb = ($::opt_hires) ? "%%HiResBoundingBox" : "%%BoundingBox";
-my $previous_line = 'Previous line';
-# Ghostscript workaround for buggy ports that prints
-# the bounding box data twice on STDERR.
-while (<GS>) {
- print $_ if $::opt_verbose;
- if (/^$bb:\s*(-?[\.\d]+) (-?[\.\d]+) (-?[\.\d]+) (-?[\.\d]+)/o) {
- }
- else {
- $previous_line = $_;
- next;
- }
- next if $previous_line eq $_;
- $previous_line = $_;
- $page++;
- @bbox = getbbox($page, $1, $2, $3, $4);
-
- my $empty = 0;
- $empty = 1 if $bbox[0] >= $bbox[2];
- $empty = 1 if $bbox[1] >= $bbox[3];
- if ($empty) {
- print <<"END_WARNING";
-
-!!! Warning: Empty Bounding Box is returned by Ghostscript!
-!!! Page $page: @bbox
-!!! Either there is a problem with the page or with Ghostscript.
-!!! Recovery is tried by embedding the page in its original size.
-
-END_WARNING
- print TMP "\\pageinclude{$page}\n";
- next;
- }
-
- print "* Page $page: @bbox\n" if $::opt_verbose;
-
- my @bb = ($bbox[0] - $llx, $bbox[1] - $ury,
- $bbox[2] + $urx, $bbox[3] + $lly);
-
- $empty = 0;
- $empty = 1 if $bb[0] >= $bb[2];
- $empty = 1 if $bb[1] >= $bb[3];
- if ($empty) {
- print <<"END_WARNING";
-
-!!! Warning: The final Bounding Box is empty!
-!!! Page: $page: @bb
-!!! Probably caused by too large negative margin values.
-!!! Recovery by ignoring margin values.
-
-END_WARNING
- print TMP "\\page $page [@bbox]\n";
- # clipping shouldn't make a difference
- next;
- }
- if ($::opt_clip) {
- print TMP "\\pageclip $page [@bbox][$llx $lly $urx $ury]\n";
- }
- else {
- print TMP "\\page $page [@bb]\n";
- }
-}
-close(GS);
-
-if ($? == -1) {
- die sprintf "$Error Ghostscript failed to execute (%s)!\n",
- exterr;
-}
-elsif ($? & 127) {
- die sprintf "$Error Ghostscript died with signal %d!\n",
- ($? & 127);
-}
-elsif ($? != 0) {
- die sprintf "$Error Ghostscript exited with error code %d!\n",
- $? >> 8;
-}
-
-print TMP "\\csname \@\@end\\endcsname\n\\end\n";
-close(TMP);
-
-if ($page == 0) {
- die "$Error Ghostscript does not report bounding boxes!\n";
-}
-
-### Run pdfTeX/XeTeX
-
-push @unlink_files, "$tmp.log";
-my $cmd;
-my $texname;
-if ($::opt_tex eq 'pdftex') {
- $cmd = $::opt_pdftexcmd;
- $texname = 'pdfTeX';
-}
-elsif ($::opt_tex eq 'luatex') {
- $cmd = $::opt_luatexcmd;
- $texname = 'LuaTeX';
-}
-else {
- $cmd = $::opt_xetexcmd;
- $texname = 'XeTeX';
-}
-$cmd = "\"$cmd\"" if $Win and $cmd =~ /\s/;
-$cmd .= ' -no-shell-escape';
-if ($::opt_initex) {
- $cmd .= ' --ini --etex';
-}
-if ($::opt_verbose) {
- $cmd .= " -interaction=nonstopmode $tmp";
-}
-else {
- $cmd .= " -interaction=batchmode $tmp";
-}
-print "* Running $texname ...\n" if $::opt_verbose;
-print "* $texname call: $cmd\n" if $::opt_debug;
-if ($::opt_verbose) {
- system($cmd);
-}
-else {
- `$cmd`;
-}
-if ($? == -1) {
- die sprintf "$Error %s run failed to execute (%s)!\n",
- $texname, exterr;
-}
-elsif ($? & 127) {
- die sprintf "$Error %s run died with signal %d!\n",
- $texname, ($? & 127);
-}
-elsif ($? != 0) {
- die sprintf "$Error %s run failed with value %d!\n",
- $texname, ($? >> 8);
-}
-
-### Check pdf version of temp file
-if ($::opt_pdfversion) {
- open(PDF, '+<', "$tmp.pdf")
- or die sprintf "!!! Error: Cannot open `%s' (%s)!\n",
- "$tmp.pdf", exterr;
- my $header;
- read PDF, $header, 9
- or die sprintf "!!! Error: Cannot read header of `%s' (%s)!\n",
- "$tmp.pdf", exterr;
- $header =~ /^%PDF-(\d\.\d)\s$/ or die "!!! Error: Cannot find header of `$tmp.pdf'!\n";
- if ($1 ne $::opt_pdfversion) {
- seek PDF, 5, 0
- or die sprintf "!!! Error: Cannot seek in `%s' (%s)!\n",
- "$tmp.pdf", exterr;
- print PDF $::opt_pdfversion
- or die sprintf "!!! Error: Cannot write in `%s' (%s)!\n",
- "$tmp.pdf", exterr;
- print "* PDF version correction in output file: $::opt_pdfversion\n"
- if $::opt_debug;
- }
- close(PDF);
-}
-
-### Move temp file to output
-if (!rename("$tmp.pdf", $outputfile)) {
- use File::Copy;
- move "$tmp.pdf", $outputfile or
- die "$Error Cannot move `$tmp.pdf' to `$outputfile'!\n";
-}
-
-print "==> $page page", (($page == 1) ? "" : "s"),
- " written on `$outputfile'.\n";
-
-$exit_code = 0;
-cleanup();
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/pdfjam/pdfjam b/Build/source/texk/texlive/linked_scripts/pdfjam/pdfjam
deleted file mode 100755
index 1f7d84454a2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pdfjam/pdfjam
+++ /dev/null
@@ -1,1292 +0,0 @@
-#!/bin/sh
-version=3.03
-#########################################################################
-## ##
-## pdfjam: A shell-script interface to the "pdfpages" LaTeX package ##
-## ------ ##
-## ##
-## Author: David Firth (http://warwick.ac.uk/dfirth) ##
-## ##
-## Usage: see https://github.com/DavidFirth/pdfjam ##
-## or "pdfjam --help" ##
-## ##
-## Relies on: ##
-## -- pdflatex (or xelatex or lualatex) ##
-## -- the 'pdfpages' package for LaTeX (ideally version >= 0.4f) ##
-## ##
-## License: GPL version 2 or later. This software comes with ##
-## ABSOLUTELY NO WARRANTY of fitness for any purpose at all; if you ##
-## do not accept that, then you must not use it. ##
-## ##
-## The path searched for site-wide configuration files can be set ##
-## by editing the following variable: ##
-## ##
- configpath='/etc:/usr/share/etc:/usr/local/share:/usr/local/etc' ##
-## ##
-## Nothing else in this file should need to be changed. ##
-## ##
-#########################################################################
-##
-## HELP TEXT
-##
-## Defines the output of 'pdfjam --help'
-##
-helptext="
-pdfjam is a shell-script front end to the LaTeX 'pdfpages' package (for
-which, see http://www.ctan.org/tex-archive/macros/latex/contrib/pdfpages).
-
-Usage: pdfjam [OPTIONS] [--] [FILE1 [SEL1]] [FILE2 [SEL2]]...
-where
-* 'FILE1' etc. are PDF files (JPG and PNG files are also allowed). For
- input from /dev/stdin, use the special name '/dev/stdin' in place of any
- of FILE1, FILE2, etc: this can be mixed with 'real' files as needed, to
- allow input through a pipe (note that if /dev/stdin is connected to tty,
- an error results). If 'FILE1' is absent, pdfjam will use '/dev/stdin'
- (and will use '-' for the page selection -- see next item).
-* 'SEL1' is a page selection for FILE1, etc.
- To select all pages (the default) use '-'. See the pdfpages manual for
- more details. An example:
- ... file1 '{},2,4-6,9-' ...
- makes an empty page, followed by pages 2,4,5,6 of file1, followed by pages
- 9 onwards (up to the end of file1).
- A page selection can be applied to more than one file, e.g.,
- ... file1 file2 file3 1-7 ...
- applies page selection '1-7' to all three files; but for example
- ... file1 file2 2- file3 1-7 ...
- would apply the page selection '2-' to file1 and file2, and '1-7'
- to file3. A page selection applies to all the files *immediately*
- preceding it in the argument list. A missing page selection defaults to
- '-'; this includes the case where 'FILE1' is absent and so /dev/stdin gets
- used by default.
-* 'options' are pdfpages specifications in the form '--KEY VALUE' (see
- below), or
- --help (or -h, or -u)
- Output this text only; no processing of PDF files.
- --configpath
- Output the 'configpath' variable and exit immediately; no
- processing of PDF files.
- --version (or -V)
- Output the version number of pdfjam and exit immediately; no
- processing of PDF files.
- --quiet (or -q)
- Suppress verbose commentary on progress.
- --batch
- Run pdfjam sequentially on each input file in turn, and
- produce a separate output file for each input, rather
- than the default behaviour (which is a single run of
- pdfjam on all of the input files, producing a single
- output document). For the location of output
- files, see '--outfile'. The --batch option cannot be
- used in the case of input from stdin.
- --outfile PATH (or -o PATH)
- Specifies where the output file(s) will go. If PATH is an
- existing directory, pdfjam will attempt to write its
- output PDF file(s) there, with name(s) derived from the
- input file name(s) and the --suffix option (see below).
- Otherwise the output file will be PATH. If '/dev/stdin'
- is the only or last input file, PATH cannot be a directory.
- Your current default PATH for output is:
- $outFile
- --suffix STRING
- Specifies a suffix for output file names, to be used when
- --outfile is either (a) a directory, or
- (b) not specified in a --batch call.
- A good STRING should be descriptive: for example,
- --suffix 'rotated'
- would append the text '-rotated' to the name of the input
- file in order to make the output file name, as in
- 'myfile-rotated.pdf'. The STRING must not have zero
- length.
- [Default for you at this site: suffix=$suffix]
- --checkfiles
- --no-checkfiles
- If the Unix 'file' utility is available, with options
- -L and -b, the output of 'file -Lb FILE1' should be
- 'PDF document...' where '...' gives version information.
- If this is the case on your system you should use
- '--checkfiles'; otherwise use '--no-checkfiles',
- in which case all input PDF files must have .pdf or .PDF
- as their name extension.
- [Default for you at this site: checkfiles=$checkfiles]
- --preamble STRING
- Append the supplied STRING to the preamble of the LaTeX
- source file(s), immediately before the '\begin{document}'
- line. An example:
- pdfjam --nup 2x2 myfile.pdf -o myfile-4up.pdf \\
- --preamble '\usepackage{fancyhdr} \pagestyle{fancy}'
- The '--preamble' option can be used, for example, to load
- LaTeX packages and/or to set global options. If '--preamble'
- is used more than once in the call, the supplied preamble
- strings are simply concatenated. For a note on avoiding
- clashes, see the PDFjam-README file (also available at
- http://www.pdfjam.net).
- --keepinfo
- --no-keepinfo
- Preserve (or not) Title, Author, Subject and Keywords
- (from the last input PDF file, if more than one) in the
- output PDF file. This requires the pdfinfo utility, from
- the xpdf package, and the LaTeX 'hyperref' package; if
- either of those is not available, '--keepinfo' is ignored.
- [Default for you at this site: keepinfo=$keepinfo]
- --pdftitle STRING
- --pdfauthor STRING
- --pdfsubject STRING
- --pdfkeywords STRING
- Provide text for the Title, Author, Subject and Keywords
- in the output PDF file. Requires the LaTeX 'hyperref'
- package. These options, individually, over-ride --keepinfo.
- --landscape
- --no-landscape
- Specify landscape page orientation (or not) in the
- output PDF file.
- [Default for you at this site: landscape=$landscape]
- --twoside
- --no-twoside
- Specify (or not) the 'twoside' document class option.
- [Default for you at this site: twoside=$twoside]
- --paper PAPERSPEC (or simply --PAPERSPEC)
- Specify a LaTeX paper size, for example
- '--paper a4paper' or simply '--a4paper' for ISO A4 paper.
- If the LaTeX 'geometry' package is installed, a wider range
- of paper sizes is available. For details see documentation
- for LaTeX and/or the 'geometry' package.
- [Default for you at this site: paper=$paper]
- --papersize '{WIDTH,HEIGHT}'
- Specify a custom paper size, e.g.,
- --papersize '{10in,18cm}'
- (Note the braces, and the comma!)
- If the 'geometry' package is not found, this has no effect.
- --pagecolor RGBSPEC
- Specify a background colour for the output pages. The
- RGBSPEC must be a comma-separated trio of integers
- between 0 and 255. An example:
- --pagecolor 150,200,150
- [Default is no background colour]
- --tidy
- --no-tidy
- Specify whether the temporary directory created by
- pdfjam should be deleted. Use '--no-tidy' to help debug
- most errors.
- [Default for you at this site: tidy=$tidy]
- --latex PATHTOLATEX
- Specify the LaTeX engine to be used (one of pdflatex,
- xelatex, lualatex). The PATHTOLATEX string must be
- the full path to a suitable LaTeX executable (for example
- /usr/bin/xelatex on many unix systems).
- [Default for you at this site: latex=$latex]
- --runs N
- Run latex N times, for each output document made.
- [Default for you at this site: runs=$runs]
- --vanilla
- Suppress the reading of any site-wide or user-specific
- configuration files.
- --KEY VALUE
- Specify options to '\includepdfmerge', in the LaTeX
- 'pdfpages' package. Here KEY is the name of any of the
- many options for '\includepdfmerge', and VALUE is a
- corresponding value. Examples are
- --nup 2x1 (for 2-up side-by-side imposition)
- --scale 0.7 (to scale all input pages to 70% size)
- --offset '1cm 0.5cm'
- (to offset all pages -- note the quotes!)
- --frame true (to put a frame round each input page)
- --trim '1cm 2cm 1cm 2cm' --clip true
- (to trim those amounts from left, bottom,
- right and top, respectively, of input
- pages)
- etc., etc. For more information see the manual for
- the 'pdfpages' package, at
- http://www.ctan.org/tex-archive/macros/latex/contrib/pdfpages
-* '--' can be used to signal that there are no more options to come.
-
-Defaults for the options '--suffix', '--keepinfo', '--paper', '--outfile',
-'--landscape', '--twoside', '--tidy', '--latex', '--runs', '--checkfiles'
-and '--preamble' can be set in site-wide or user-specific configuration files.
-The path that is searched for site-wide configuration files (named pdfjam.conf)
-at this installation is
- $configpath
-This configuration path can be changed by editing the pdfjam script if
-necessary. Any user-specific configuration should be put in a file named
-.pdfjam.conf in your home directory. (All of these files are ignored
-if the '--vanilla' argument is used.)
-
-For more information, including a sample configuration file, see
-https://github.com/DavidFirth/pdfjam.
-"
-##
-## END OF HELP TEXT
-##
-#########################################################################
-##
-## PRELIMINARIES
-##
-## First determine:
-## --- whether verbose commentary should be provided (not if --quiet
-# or --configpath was specified);
-## --- whether this call to pdfjam is a "batch" call;
-## --- whether just the help text is required;
-## --- or whether all configuration files should be ignored.
-##
-verbose=true
-for arg
-do
- case $arg in
- --quiet | -q | --configpath)
- verbose=false ;
- ;;
- --version | -V)
- echo "$version"
- exit 0 ;
- ;;
- --batch)
- batch=true ;
- ;;
- --help | -u | -h)
- printf "%s\n" "$helptext" ;
- exit 0 ;
- ;;
- --vanilla)
- vanilla=true ;
- ;;
- *)
- ;;
- esac
-done
-##
-## Check to see whether this is a "secondary" call to pdfjam:
-##
-if test -z "$PDFJAM_CALL_NUMBER" ## not a secondary call
-then
- PDFJAM_CALL_NUMBER=0
-fi
-##
-## Keep a copy of the internal file separator, so we can change it safely
-##
-OIFS="$IFS"
-##
-## Record the full filename of the current working diractory
-##
-pwd=$(pwd)
-##
-## Trap interrupts so that they kill everything:
-##
-trap 'IFS=$OIFS; exit 1' 1 2 15
-##
-## The following will be useful for readability of the script:
-##
-newline='
-'
-##
-## Define a function to escape tricky characters in file names etc:
-##
-escape_chars () {
- (printf "%s" "${1}" | sed 's/[^a-zA-Z0-9._/\-]/\\&/g')
-}
-##
-## Define a function to output verbose comments:
-##
-prattle () { ## second argument here is non-null for continuation lines
- if test $verbose = true; then
- prefix1=" pdfjam:" ;
- prefix2=$(printf "%s" "$prefix1" | sed 's/pdfjam:/ /') ;
- indent="" ;
- if test "$PDFJAM_CALL_NUMBER" -gt 0 &&
- test "$batch" != true
- then
- indent=" "
- fi
- IFS="$newline" ;
- lineCounter=0 ;
- for line in ${1}
- do
- lineCounter=$((lineCounter + 1)) ;
- if test $lineCounter -eq 1 && test ! -n "${2}" ;
- then
- if test -w "$PDFJAM_MESSAGES_FILE"
- then printf "$prefix1$indent %s\n" "$line" 1>/dev/null >> \
- "$PDFJAM_MESSAGES_FILE"
- else messages="$messages$prefix1$indent $line$newline"
- ## msg file not made yet
- fi
- else
- if test -w "$PDFJAM_MESSAGES_FILE"
- then printf "$prefix2$indent %s\n" "$line" 1>/dev/null >> \
- "$PDFJAM_MESSAGES_FILE"
- else messages="$messages$prefix2$indent $line$newline"
- ## msg file not made yet
- fi
- fi ;
- done ;
- IFS="$OIFS" ;
- fi ;
- return ;
-}
-##
-## And here's the first piece of verbose commentary:
-##
-prattle "----" 1
-prattle "This is pdfjam version ${version}."
-##
-#########################################################################
-##
-## CONFIGURATION
-##
-## THESE SETTINGS WILL BE OVER-RIDDEN by any found in configuration
-## files. By default such files are found at any or all of
-## /etc/pdfjam.conf
-## /usr/share/etc/pdfjam.conf
-## /usr/local/share/pdfjam.conf
-## /usr/local/etc/pdfjam.conf
-## $HOME/.pdfjam.conf
-## (And they are read in that order; if a setting is made more than
-## once, the last instance prevails.)
-##
-## An example configuration file can be found at
-## https://github.com/DavidFirth/pdfjam
-##
-## The path searched for site-wide configuration files can be changed
-## by editing the variable 'configpath' at the top of this file.
-##
-##
-## First get the full path (if it exists) to pdflatex:
-##
-latex=$(command -v pdflatex)
-if [ -z "$latex" ] ; then latex="not found" ; fi
-##
-## Likewise for the pdfinfo (only needed for `--keepinfo'):
-##
-pdfinfo=$(command -v pdfinfo)
-if [ -z "$pdfinfo" ] ; then pdfinfo="not found"; fi
-##
-##
-## Next a permitted location for temporary files on your system:
-##
-tempfileDir='/var/tmp' ## /var/tmp is standard on most unix systems
-##
-##
-## Default for the output file location:
-##
-outFile="$pwd" ## Output to the current working directory
-##
-##
-## A few more default settings for pdfjam:
-##
-runs=1 ## Run latex just once
-##
-tidy='true' ## Delete all temporary files at the end
-##
-keepinfo='false' ## Don't try to preserve "pdfinfo" data
-##
-checkfiles='false' ## Don't use the Unix 'file -Lb' utility to
-## identify PDF files from their contents;
-## rely on the .pdf or .PDF extension instead.
-##
-suffix='pdfjam' ## Default filename suffix to be used when
-## --outfile is either (a) a directory, or (b)
-## not specified in a --batch call.
-##
-preamble='' ## Default LaTeX preamble string.
-##
-## Guess default paper size from locale if possible, otherwise A4
-##
-if command -v locale >/dev/null ; then
- paperheight=$(locale -k LC_PAPER | sed -e '1!d' -e 's/.*=//') ;
- case $paperheight in
- 297)
- paper='a4paper' ;
- ;;
- 279)
- paper='letterpaper' ;
- ;;
- *)
- paper='a4paper' ;
- ;;
- esac
-else paper='a4paper' ; ## fallback paper size is ISO A4
-fi
-##
-## END OF SETTINGS MADE DIRECTLY WITHIN THE SCRIPT
-##
-## Now read the site's or user's configuration file(s) if such exist,
-## unless '--vanilla' was specified.
-##
-if test "$vanilla" != true
-then
- if test "$PDFJAM_CALL_NUMBER" = 0 ## not a secondary call to pdfjam
- then
- configFiles=$(printf "%s" "$configpath" | \
- sed 's/:/\/pdfjam.conf:/g; s/$/\/pdfjam.conf/')
- configFiles="${configFiles}:$HOME/.pdfjam.conf"
- PDFJAM_CONFIG=""
- prattle "Reading any site-wide or user-specific defaults..."
- IFS=':'
- for d in $configFiles
- do
- if test -f "$d"; then
- change=$(sed '/^ *#.*/d ; s/ *#.*//; s/^ *//' "$d")
- comment="## ${newline}## From ${d}: ${newline}##"
- PDFJAM_CONFIG="$PDFJAM_CONFIG$comment$newline$change$newline"
- fi
- done
- IFS="$OIFS"
- PDFJAM_CONFIG=$(printf "%s" "$PDFJAM_CONFIG" | sed 's/^/ /')
- if test "$batch" = true ; then export PDFJAM_CONFIG ; fi
- if test -z "$PDFJAM_CONFIG"
- then
- prattle "(none found)" 1
- else
- prattle "$PDFJAM_CONFIG" 1
- fi
- fi
- if test -n "$PDFJAM_CONFIG" ; then eval "$PDFJAM_CONFIG" ; fi
-else
- if test $PDFJAM_CALL_NUMBER -eq 0
- then
- prattle "Called with '--vanilla': no user or site configuration"
- prattle "files will be read." 1
- fi
-fi
-## For backwards compatibility, check here for a $pdflatex setting in the config file
-if [ -n "${pdflatex:-}" ] ; then latex="$pdflatex" ; fi
-##
-## END OF CONFIGURATION BLOCK
-##
-#########################################################################
-##
-## ERROR CODES
-##
-E_USAGE=64 # command line usage error
-E_NOINPUT=66 # cannot open input
-E_UNAVAILABLE=69 # service unavailable
-E_SOFTWARE=70 # internal software error
-E_OSFILE=72 # file does not exist or cannot be opened
-E_CANTCREATE=73 # can't create (user) output file
-E_CONFIG=78 # configuration error
-##
-## Define a function to print an error message and exit:
-##
-error_exit () {
- if [ -r "$PDFJAM_MESSAGES_FILE" ]
- then cat "$PDFJAM_MESSAGES_FILE" >&2
- else printf "%s" "$messages" 1>&2
- fi
- printf " pdfjam ERROR: %s\n" "$1" 1>&2 ;
- exit "$2" ;
-}
-##
-#########################################################################
-##
-## READ AND PROCESS THE ARGUMENTS
-##
-## In case of NO argument supplied, mention 'pdfjam --help':
-##
-if test $# -eq 0
-then
- prattle "No arguments supplied; continuing anyway. (See"
- prattle "'pdfjam --help' for information on usage.)" 1
-fi
-##
-## Now do the argument loop.
-##
-fileSpec=""
-miscOptions=""
-callOptions=""
-optionsFinished=""
-##
-## First note any '--checkfiles' or '--no-checkfiles' option
-##
-for arg
-do
- case $arg in
- --checkfiles)
- checkfiles=true ;
- callOptions="$callOptions --checkfiles" ;
- ;;
- --no-checkfiles)
- checkfiles=false ;
- callOptions="$callOptions --no-checkfiles" ;
- ;;
- esac
-done
-while test -n "${1}${2}"; do
- argUnmatched=""
- if test "$optionsFinished" != true
- then
- case ${1} in
- --) ## signals end of command-line options
- optionsFinished=true ;
- shift ;
- continue ;
- ;;
- --configpath)
- printf "%s\n" "$configpath" ;
- exit 0;;
- --* | -q | -o)
- if test "$pageSpecAwaited" = true ; then
- ## fill in any missing page specs before continuing
- fileSpec=$(printf "%s" "$fileSpec" | sed 's/|awaited/|-/g')
- pageSpecAwaited=false
- fi
- case ${1} in
- --latex)
- latex="${2}" ;
- callOptions="$callOptions --latex ${2}" ;
- shift ;;
- --batch)
- batch=true ;
- ;;
- --vanilla)
- callOptions="$callOptions ${1}" ;
- ;;
- --quiet | -q)
- verbose=false ;
- callOptions="$callOptions ${1}" ;
- ;;
- --outfile | -o)
- outFile="${2}" ;
- if test "$batch" = true
- then
- outFile=$(escape_chars "$outFile")
- fi
- callOptions="$callOptions --outfile $outFile" ;
- shift ;;
- --suffix)
- if test -n "${2}"
- then
- suffix="${2}" ;
- if test "$batch" = true
- then
- suffix=$(escape_chars "$suffix")
- fi
- callOptions="$callOptions --suffix $suffix"
- shift
- else
- error_exit \
- "'--suffix' string has zero length" \
- $E_USAGE ;
- fi
- ;;
- --runs)
- runs="${2}" ;
- ## check if the argument is a number > 0
- if [ "$runs" -lt 1 ] 2> /dev/null; then
- error_exit \
- "'--runs' number must be at least 1" \
- $E_USAGE ;
- fi
- callOptions="$callOptions --runs ${2}" ;
- shift ;;
- --tidy)
- tidy=true ;
- callOptions="$callOptions --tidy" ;
- ;;
- --no-tidy)
- tidy=false ;
- callOptions="$callOptions --no-tidy" ;
- ;;
- --keepinfo)
- keepinfo=true ;
- callOptions="$callOptions --keepinfo" ;
- ;;
- --no-keepinfo)
- keepinfo=false ;
- callOptions="$callOptions --no-keepinfo" ;
- ;;
- --checkfiles)
- ;; ## already done above
- --no-checkfiles)
- ;; ## already done above
- --pdftitle)
- pdfTitle="${2}" ;
- if test "$batch" = true
- then
- pdfTitle=$(escape_chars "$pdfTitle")
- fi
- callOptions="$callOptions --pdftitle $pdfTitle" ;
- shift ;;
- --pdfauthor)
- pdfAuthor="${2}" ;
- if test "$batch" = true
- then
- pdfAuthor=$(escape_chars "$pdfAuthor")
- fi
- callOptions="$callOptions --pdfauthor $pdfAuthor" ;
- shift ;;
- --pdfsubject)
- pdfSubject="${2}" ;
- if test "$batch" = true
- then
- pdfSubject=$(escape_chars "$pdfSubject")
- fi
- callOptions="$callOptions --pdfsubject $pdfSubject" ;
- shift ;;
- --pdfkeywords)
- pdfKeywords="${2}" ;
- if test "$batch" = true
- then
- pdfKeywords=$(escape_chars "$pdfKeywords")
- fi
- callOptions="$callOptions --pdfkeywords $pdfKeywords" ;
- shift ;;
- --paper)
- paper="${2}"
- callOptions="$callOptions ${1} ${2}" ;
- shift ;;
- --pagecolor)
- pagecolor="${2}" ;
- callOptions="$callOptions ${1} ${2}" ;
- shift ;;
- --a4paper | --a5paper | --b5paper | --letterpaper | \
- --executivepaper | --legalpaper)
- ## standard LaTeX paper sizes
- paper=$(printf "%s" "${1}" | sed 's/^--//') ;
- callOptions="$callOptions ${1}" ;
- ;;
- --a0paper | --a1paper | --a2paper | --a3paper | \
- --a6paper | --b0paper | --b1paper | --b2paper | \
- --b3paper | --b4paper | --b6paper)
- ## the 'geometry' package is needed
- if test "$geometry" != false ;
- then
- paper=$(printf "%s" "${1}" | sed 's/^--//') ;
- callOptions="$callOptions ${1}" ;
- geometry=true ;
- fi ;
- ;;
- --papersize)
- ## the 'geometry' package is needed
- if test "$geometry" != false ;
- then
- papersize="papersize=${2}" ;
- callOptions="$callOptions ${1} '${2}'" ;
- geometry=true ;
- fi ;
- shift ;;
- --landscape)
- landscape=true ;
- callOptions="$callOptions --landscape" ;
- ;;
- --no-landscape)
- landscape=false ;
- callOptions="$callOptions --no-landscape" ;
- ;;
- --twoside)
- twoside=true ;
- callOptions="$callOptions --twoside" ;
- ;;
- --no-twoside)
- twoside=false ;
- callOptions="$callOptions --no-twoside" ;
- ;;
- --preamble)
- preamble="$preamble${2}" ;
- shift ;;
- --*)
- ## options for \includepdfmerge
- argName=$(printf "%s" "${1}" | sed 's/^--//');
- value="${2}"
- miscOptions=$miscOptions,"$argName=$value" ;
- ## saved for possible use in LaTeX file
- callOptions="$callOptions ${1} '$value'" ;
- ## saved for possible use in a further call to pdfjam
- shift ;
- ;;
- esac ;;
- '' | *)
- argUnmatched=true
- ;;
- esac
- fi
- if test "$optionsFinished" = true || test "$argUnmatched" = true
- then
- case ${1} in
- "" | /dev/stdin)
- fileSpec="${fileSpec}${newline}/dev/stdin|awaited"
- pageSpecAwaited=true
- inputFromStdin=true ;;
- -)
- if test "$pageSpecAwaited" = true ; then
- fileSpec=$(printf "%s" "$fileSpec" | \
- sed 's/|awaited/|-/g')
- pageSpecAwaited=false
- else
- error_exit "no PDF/JPG/PNG file found at ${1}" \
- $E_NOINPUT
- fi ;;
- *) ## All other args should be PDF (or JPG/PNG)
- ## source files and page selections; if not, we'll quit
- if test "$checkfiles" = true ; ## not always available
- then
- case $(file -Lb "${1}") in
- "PDF document"*|"JPEG image data"*|"PNG image"*)
- ## it's a PDF file (or JPG/PNG) as expected
- fileSpec="$fileSpec${newline}${1}|awaited"
- pageSpecAwaited=true
- ;;
- *)
- case ${1} in
- *.[pP][dD][fF] | *.[jJ][pP][eE][gG] | \
- *.[jJ][pP][gG] | *.[pP][nN][gG])
- ## should be PDF/JPG/PNG file, but isn't
- error_exit "no PDF/JPG/PNG file found at ${1}" \
- $E_NOINPUT
- ;;
- *) ## if page spec needed, assume this is it;
- ## otherwise something is wrong
- if test "$pageSpecAwaited" = true ; then
- fileSpec=$(printf "%s" "$fileSpec" | \
- sed "s/|awaited/|$1/g")
- pageSpecAwaited=false
- else
- error_exit "no PDF/JPG/PNG file found at ${1}" \
- $E_NOINPUT
- fi
- ;;
- esac
- ;;
- esac
- else ## no checking of file contents; rely on .pdf extension
- case ${1} in
- *.[pP][dD][fF] | *.[jJ][pP][eE][gG] \
- | *.[jJ][pP][gG] | *.[pP][nN][gG])
- ## assume it's a PDF/JPG/PNG file
- test -f "${1}" || error_exit \
- "${1} not found" $E_NOINPUT
- fileSpec="$fileSpec"$newline${1}"|"awaited
- pageSpecAwaited=true
- ;;
- *) ## if page spec needed, assume this is it;
- ## otherwise something is wrong
- if test "$pageSpecAwaited" = true ; then
- fileSpec=$(printf "%s" "$fileSpec" | \
- sed "s/|awaited/|$1/g")
- pageSpecAwaited=false
- else
- error_exit "no PDF/JPG/PNG file found at ${1}" \
- $E_NOINPUT
- fi
- ;;
- esac
- fi
- ;;
- esac
- fi
- shift
-done
-##
-## Use the default page spec for any that remain unspecified:
-##
-fileSpec=$(printf "%s" "$fileSpec" | sed '/^$/d; s/^ //; s/|awaited$/|-/')
-##
-## Check whether input from stdin should be used by default:
-if test $PDFJAM_CALL_NUMBER -eq 0 && test "$inputFromStdin" != true
-then
- ## the special argument '/dev/stdin' was not used
- if test -z "$fileSpec" ; then
- ## no argument specifying a PDF source was given
- inputFromStdin=true
- fileSpec="/dev/stdin|-"
- prattle "No PDF/JPG/PNG source specified: input is from stdin."
- fi
-fi
-##
-## Delete leading comma from $miscOptions:
-##
-miscOptions=$(printf "%s" "$miscOptions" | sed 's/^,//')
-##
-if test -n "$preamble"
-then callOptions="$callOptions --preamble '$preamble'"
-fi
-## Delete leading space from $callOptions:
-##
-callOptions=$(printf "%s" "$callOptions" | sed 's/^ //')
-##
-## Set up a document options variable:
-##
-case $landscape in
- true)
- orientation=landscape ;;
- *)
- orientation="" ;;
-esac
-case $twoside in
- true)
- twoside=twoside ;;
- *)
- twoside="" ;;
-esac
-if test "$geometry" != false
-then
-## we haven't already found that geometry.sty is missing
- case $paper in
- a0paper | a1paper | a2paper | a3paper | \
- a6paper | b0paper | b1paper | b2paper | \
- b3paper | b4paper | b6paper)
- ## the 'geometry' package is needed
- geometry=true ;
- ;;
- *)
- ;;
- esac
-fi
-documentOptions="$paper","$orientation","$twoside"
-documentOptions=$(printf "%s" "$documentOptions" | sed 's/^,//' | sed 's/,$//')
-##
-## END OF ARGUMENT PROCESSING
-##
-#########################################################################
-##
-## CHECK SYSTEM SETUP
-##
-## These checks are not repeated in secondary calls.
-##
-if test $PDFJAM_CALL_NUMBER -eq 0 ## not a secondary call
-then
- ## Check whether there's a suitable latex to use:
- case $latex in
- "not found")
- error_exit "can't find pdflatex!" $E_UNAVAILABLE
- ;;
- *) ##
- if test ! -x "$latex"
- then
- error_exit \
- "configuration error, $latex is not an executable file" \
- $E_CONFIG
- fi
- ;;
- esac
- ##
- ## Check that necessary LaTeX packages are installed:
- ##
- modifyPath=$(printf "%s" "$latex" | sed 's/\/[^\/]*$//')
- if [ -n "$modifyPath" ] ; then
- PATH="$modifyPath:$PATH"
- export PATH
- fi
- (kpsewhich pdfpages.sty >/dev/null) ||
- error_exit \
- "LaTeX package pdfpages.sty is not installed" \
- $E_UNAVAILABLE
- (kpsewhich eso-pic.sty >/dev/null) ||
- error_exit \
- "LaTeX package eso-pic.sty not installed (see the pdfpages manual)" \
- $E_UNAVAILABLE
- (kpsewhich everyshi.sty >/dev/null) ||
- error_exit \
- "LaTeX package everyshi.sty not installed (see the pdfpages manual)" \
- $E_UNAVAILABLE
- if test "$keepinfo" = true ||
- test -n "$pdfTitle$pdfSubject$pdfAuthor$pdfKeywords"
- ## ie, if hyperref is required
- then
- (kpsewhich hyperref.sty >/dev/null) || {
- prattle "LaTeX package hyperref.sty is not installed, so any"
- prattle "--keepinfo, --pdftitle,--pdfauthor, --pdfsubject or" 1
- prattle "--pdfkeywords setting will be ignored." 1
- hyperref=false
- if test "$batch" = true
- then
- export hyperref ## for use in any secondary calls
- fi
- }
- else
- hyperref=false
- fi
- if test "$geometry" = true
- ## ie, if the 'geometry' package is needed for paper size
- then
- (kpsewhich geometry.sty >/dev/null) || {
- prattle "LaTeX package geometry.sty is not installed, so only the"
- prattle "standard LaTeX paper sizes are available." 1
- geometry=false
- if test "$batch" = true
- then
- export geometry ## for use in any secondary calls
- fi
- }
- fi
-fi
-if test "$hyperref" = false
-then
- keepinfo=false
- pdfTitle="" ; pdfAuthor="" ; pdfSubject="" ; pdfKeywords=""
-else
- if test "$keepinfo" = true
- then
- case $pdfinfo in
- "not found")
- if test $PDFJAM_CALL_NUMBER -eq 0
- then
- prattle \
- "The pdfinfo utility was not found, so --keepinfo is ignored."
- fi
- keepinfo=false
- ;;
- pdfinfo)
- ;;
- *) ## $pdfinfo was set in a configuration file
- if test ! -x "$pdfinfo"
- then
- if test $PDFJAM_CALL_NUMBER -eq 0
- then
- prattle \
- "No pdfinfo utility at $pdfinfo, so --keepinfo is ignored."
- keepinfo=false
- fi
- fi
- ;;
- esac
- fi
-fi
-##
-## END OF CHECKING THE SETUP
-##
-#########################################################################
-##
-## TEMPORARY FILES
-##
-## Make a secure temporary directory (following
-## the autoconf manual).
-##
-## Use mktemp if possible; otherwise fall back on mkdir,
-## with random name to make file collisions less likely.
-##
-original_umask=$(umask)
-umask 177
-if test $PDFJAM_CALL_NUMBER = 0 ## don't repeat this work for secondary calls
-then
- PDFJAM_TEMP_DIR=''
- trap 'IFS="$OIFS"; \
- if test $tidy != false ; then cd "$pwd"; rm -rf "$PDFJAM_TEMP_DIR"; fi; exit 1' \
- 1 2 15
- trap 'IFS="$OIFS"; \
- if test $tidy != false ; then cd "$pwd"; rm -rf "$PDFJAM_TEMP_DIR"; fi' 0
- {
- PDFJAM_TEMP_DIR=$( (umask 077 && mktemp -d "$tempfileDir/pdfjam-XXXXXX") 2>/dev/null) &&
- test -n "$PDFJAM_TEMP_DIR" && test -d "$PDFJAM_TEMP_DIR"
- } || {
- ## We'll use awk to make random number, for portability
- random=$(awk 'END { srand(); printf ("%d\n", rand()*1000000); }' /dev/null)
- PDFJAM_TEMP_DIR="$tempfileDir"/pdfjam"$$"-"$random"
- (umask 077 && mkdir "$PDFJAM_TEMP_DIR")
- } || exit $?
-##
- export PDFJAM_TEMP_DIR ## so that same dir is used in secondary calls
- if test $tidy = false ; then
- prattle "Temporary directory for this job is
- $PDFJAM_TEMP_DIR"
- fi
- PDFJAM_MESSAGES_FILE="$PDFJAM_TEMP_DIR"/messages.txt
- export PDFJAM_MESSAGES_FILE
- ## so that secondary calls can write messages there as well
- printf "%s" "$messages" > "$PDFJAM_MESSAGES_FILE" ## initial file contents
- messages="" ## we won't be using this variable again!
-else
- PDFJAM_TEMP_DIR="$PDFJAM_TEMP_DIR/file$PDFJAM_CALL_NUMBER"
- (umask 077 && mkdir "$PDFJAM_TEMP_DIR")
-fi
-umask "$original_umask"
-## Next is from the Cygwin patch contributed by Lucas
-case $(uname) in
- *CYGWIN*) PDFJAM_TEMP_DIR=$(cygpath -w "$PDFJAM_TEMP_DIR");;
-esac
-##
-## TEMPORARY DIRECTORY ALL DONE
-##
-#########################################################################
-##
-## HANDLING THE "--batch" OPTION
-##
-## If --batch was used, we'll call pdfjam separately on each input
-## file.
-##
-if test "$batch" = true ; then
- if test "$fileSpec" = "" ; then
- error_exit "--batch was used, but no PDF/JPG/PNG source file(s) specified" \
- $E_USAGE
- fi
- if test "$inputFromStdin" = true ; then
- error_exit "--batch cannot be used with input from stdin" \
- $E_USAGE
- fi
- IFS="$newline"
- for k in $fileSpec ; do
- sourcePath=$(printf "%s" "$k" | sed 's/|[^|]*$//')
- pageSpec=$(printf "%s" $k | sed 's/.*|//')
- callNumber=$((PDFJAM_CALL_NUMBER + 1))
- prattle "--"
- prattle "Processing file ${callNumber}, '$sourcePath'..."
- prattle "Page spec is '$pageSpec'."
- sourcePath=$(escape_chars "$sourcePath")
- PDFJAM_EFFECTIVE_CALL="$0 $callOptions -- $sourcePath $pageSpec"
- export PDFJAM_EFFECTIVE_CALL
- PDFJAM_CALL_NUMBER=$callNumber
- export PDFJAM_CALL_NUMBER
- eval "$PDFJAM_EFFECTIVE_CALL"
- ## i.e., call pdfjam again with one input file
- done
- if [ "$verbose" = "true" ]; then cat "$PDFJAM_MESSAGES_FILE" >&2 ; fi
- IFS=$OIFS
- exit 0
-fi
-##
-## END OF THE '--batch' PROCESSING
-##
-#########################################################################
-##
-## RECORD THE EFFECTIVE CALL TO PDFJAM, FOR POSSIBLE DEBUGGING PURPOSES
-##
-## Save the text of this (effective) call to pdfjam in a temporary file,
-## for later inspection if necessary.
-##
-## For secondary calls, the effective call text is already made;
-## otherwise we make it here.
-##
-if test "$PDFJAM_CALL_NUMBER" -gt 0
-then
- theCall="$PDFJAM_EFFECTIVE_CALL"
-else
- filePageSpec=""
- IFS="$newline"
- for k in $fileSpec ; do
- ## Last substitution on next line is needed for silly characters in
- ## file names...
- sourcePath=$(printf "%s" $k | sed 's/|[^|]*$//')
- sourcePath=$(escape_chars "$sourcePath")
- pageSpec=$(printf "%s" $k | sed 's/.*|//')
- filePageSpec="$filePageSpec$sourcePath $pageSpec "
- done
- IFS="$OIFS"
- theCall="$0 $callOptions -- $filePageSpec"
-fi
-printf "%s\n%s\n" "cd $pwd" "$theCall" > "$PDFJAM_TEMP_DIR"/call.txt
-prattle "Effective call for this run of pdfjam:"
-prattle "$theCall" 1
-##
-#########################################################################
-##
-## NOW MAKE THE INPUT FILE ETC., READY FOR LATEX
-##
-filePageList="" ## initialize a string to supply to \includepdfmerge
-counter=0
-##
-## Make symbolic link(s) to the source file(s) in the temporary dir,
-## and make the $filePageList string for input to \includepdfmerge
-##
-stdinUnread=true
-IFS="$newline"
-for k in ${fileSpec}
-do
- counter=$((counter + 1))
- sourcePath=$(printf "%s" "$k" | sed 's/|[^|]*$//')
- pageSpec=$(printf "%s" $k | sed 's/.*|//')
- ## Check, though not exhaustively, for problems with the
- ## page spec: leading or trailing comma, double comma or
- ## double dash, alphabetic characters other than the word "last",
- ## braces not paired as {} with nothing inbetween. A fully
- ## specified pattern for valid \includepdfmerge page spec would
- ## be better here; but life is too short...
- if printf "%s" "$pageSpec" | sed 's/last/99/g' | \
- grep '^,.*\|,$\|,,\|--\|[A-Za-z]\|{[^}]\|[^{]}' 1>/dev/null
- then
- error_exit "invalid page spec $pageSpec" $E_USAGE
- fi
- case $sourcePath in
- /dev/stdin)
- uniqueName="$PDFJAM_TEMP_DIR"/stdin.pdf
- if test "$stdinUnread" = true
- then
- if tty -s ; then
- error_exit \
- "tty is connected to connected to stdin, no PDF/JPG/PNG file found" \
- $E_NOINPUT
- fi
- cat > "$uniqueName"
- stdinUnread=false
- fi
- ;;
- *)
- pdfName=$(basename "$sourcePath")
- sourceDir=$(dirname "$sourcePath") ## zsh on Mac OS 10.5 chokes here
- cd "$sourceDir" || exit 1 ## just to get the full path
- sourceDir=$(pwd)
- cd "$pwd" || exit 1
- sourceFullPath="$sourceDir"/"$pdfName"
- uniqueName="source-$counter.pdf"
- uniqueName="$PDFJAM_TEMP_DIR"/"$uniqueName"
- ## Next is from the Cygwin patch contributed by Lucas
- case $(uname) in
- *CYGWIN*) cp "$sourceFullPath" "$uniqueName";;
- *) ln -s "$sourceFullPath" "$uniqueName";;
- esac
- ;;
- esac
- filePageList="$filePageList","$uniqueName","$pageSpec"
-done
-IFS="$OIFS"
-filePageList=$(printf "%s" "$filePageList" | \
- sed 's/^,//') ## remove leading comma
-##
-## Do the pdfinfo stuff (if relevant)...
-##
-if test "$hyperref" != false
-then
- if test "$keepinfo" = true
- then
- prattle "Calling ${pdfinfo}..." ;
- PDFinfo=$(pdfinfo "$uniqueName");
- pdftitl=$(printf "%s" "$PDFinfo" | \
- grep -e '^Title:'| 'sed s/^Title:\\\s\*//' | \
- sed -e 's/[#$%^&_{}~]/\\\&/g');
- pdfauth=$(printf "%s" "$PDFinfo" | \
- grep -e '^Author:'| sed 's/^Author:\\\s\*//' | \
- sed -e 's/[#$%^&_{}~]/\\\&/g');
- pdfsubj=$(printf "%s" "$PDFinfo" | \
- grep -e '^Subject:'| sed 's/^Subject:\\\s\*//' | \
- sed -e 's/[#$%^&_{}~]/\\\&/g');
- pdfkeyw=$(printf "%s" "$PDFinfo" | \
- grep -e '^Keywords:'| sed 's/^Keywords:\\\s\*//' | \
- sed -e 's/[#$%^&_{}~]/\\\&/g');
- fi
- if test -n "$pdfTitle" ; then
- pdftitl="$pdfTitle"
- fi
- if test -n "$pdfAuthor" ; then
- pdfauth="$pdfAuthor"
- fi
- if test -n "$pdfSubject" ; then
- pdfsubj="$pdfSubject"
- fi
- if test -n "$pdfKeywords" ; then
- pdfkeyw="$pdfKeywords"
- fi
-fi
-##
-## Now set up the files for latex...
-##
-fileName="$PDFJAM_TEMP_DIR"/a
-texFile="$fileName".tex
-msgFile="$fileName".msgs
-tempFile="$PDFJAM_TEMP_DIR"/temp.tex
-## Next is adapted from the Cygwin patch sent by Lucas
-case $(uname) in
- *CYGWIN*) filePageList=$(echo "$filePageList" | sed 's~\\~/~g') ;;
-esac
-(cat <<EndTemplate
-\batchmode
-\documentclass[$documentOptions]{article}
-\usepackage{color} \definecolor{bgclr}{RGB}{$pagecolor} \pagecolor{bgclr}
-\usepackage[$papersize]{geometry}
-\usepackage[utf8]{inputenc}
-\usepackage{hyperref}
-\hypersetup{pdftitle={$pdftitl}}
-\hypersetup{pdfauthor={$pdfauth}}
-\hypersetup{pdfsubject={$pdfsubj}}
-\hypersetup{pdfkeywords={$pdfkeyw}}
-\usepackage{pdfpages}
-EndTemplate
- ) > "$texFile"
-if test "$hyperref" = false; then ## we don't need hyperref
- cp "$texFile" "$tempFile"
- sed '/\\\usepackage{hyperref}/d' "$tempFile" | \
- sed '/\\\hypersetup.*/d' > "${texFile}"
- rm "$tempFile"
-fi
-if test -z "$geometry" ; then geometry=false ; fi
-if test "$geometry" = false; then ## geometry package is not to be used
- cp "$texFile" "$tempFile"
- sed '/\\\usepackage.*{geometry}/d' "$tempFile" > "$texFile"
- rm "$tempFile"
-fi
-if test -z "$pagecolor"; then ## color package is not needed
- cp "$texFile" "$tempFile"
- sed '/\\\usepackage.*{color}/d' "$tempFile" > "$texFile"
- rm "$tempFile"
-fi
-(cat <<EndTemplate
-$preamble
-\begin{document}
-\includepdfmerge[$miscOptions]{$filePageList}
-\end{document}
-EndTemplate
- ) >> "$texFile"
-##
-## INPUT FILES ARE ALL READY
-##
-#########################################################################
-##
-## RUN LATEX AND COPY THE RESULTING PDF FILE
-##
-if [ "$runs" -eq 1 ] ;
-then prattle "Calling ${latex}..."
-else prattle "Calling ${latex} $runs times..."
-fi
-cd "$PDFJAM_TEMP_DIR" || exit 1
-failureText=\
-"FAILED.
-The call to $latex resulted in an error.
-If '--no-tidy' was used, you can examine the
-log file at
- $fileName.log
-to try to diagnose the problem."
-i=1
-while [ "$i" -le "$runs" ] ; do
- $latex "$texFile" > "$msgFile" || {
- prattle "$failureText"
- error_exit "Run $i: Output file not written" $E_SOFTWARE
- }
- i=$((i + 1))
-done
-cd "$pwd" || exit 1
-if test -f "$fileName".pdf ## if LaTeX didn't choke
-then
- ## Checks on output file path:
- if test -d "$outFile" ## outfile is a directory
- then
- if test "$sourcePath" = /dev/stdin
- then
- error_exit \
- "--outfile cannot be a directory when input is stdin" \
- $E_USAGE
- fi
- if test ! -w "$outFile"
- then
- error_exit \
- "FAILED: no write permission on ${outFile}." \
- $E_OSFILE
- fi
- separator="-"
- if test "$pageSpec" != "-"
- then
- separator=-"$pageSpec"-
- fi
- outFile=$(printf "%s" "$outFile" | sed 's/\/$//')
- ## (delete any trailing slash)
- pdfName=$(basename "$sourcePath")
- pdfName=$(printf "%s" "$pdfName" | \
- sed 's/\.[pP][dD][fF]$//') ## strip extension
- pdfName="$pdfName$separator$suffix".pdf
- outFile="$outFile"/"$pdfName"
- fi
-fi
-if test -f "$outFile" && test ! -w "$outFile"
- ## file exists and we can't over-write it
-then
- error_exit "no write permission at ${outFile}" $E_CANTCREATE
-fi
-#fileSize=$(wc -c < "$fileName.pdf" | sed 's/^\ *//')
-if cat "$fileName".pdf > "$outFile" 2>/dev/null
-then
- prattle "Finished. Output was written to '${outFile}'."
-else
- error_exit "cannot write output at ${outFile}" $E_CANTCREATE
-fi
-if [ "$PDFJAM_CALL_NUMBER" = "0" ] && [ "$verbose" = "true" ]
-then cat "$PDFJAM_MESSAGES_FILE" >&2
-fi
-exit 0
-##
-## END
-##
-#########################################################################
diff --git a/Build/source/texk/texlive/linked_scripts/pdflatexpicscale/pdflatexpicscale.pl b/Build/source/texk/texlive/linked_scripts/pdflatexpicscale/pdflatexpicscale.pl
deleted file mode 100755
index ef16ea86397..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pdflatexpicscale/pdflatexpicscale.pl
+++ /dev/null
@@ -1,258 +0,0 @@
-#!/usr/bin/perl -w
-# Scale pictures to be included into a LaTeX generated PDF file.
-# written by peter willadt
-# contact: willadt at t-online.de
-# this software is subject to the LaTeX project public license.
-# changes:
-# 2016-07-27 first public release
-# 2016-08-02 changed regex to prevent problem with long filenames
-# 2016-08-02 changed > to gt (shame on me)
-# 2016-10-20 corrected behaviour when program gets called without arguments
-# (shame on me, again)
-# 2016-10-20 added undocumented switch --help to show usage.
-# 2017-01-23 Updated documentation (see pdflatexpicscale.tex),
-# and corrected version number
-# Please note: version numbers will be updated to keep sync
-# with the documentation, even when the perl code does not change.
-# 2017-02-01 pdflatexpicscale did not work correct when log lines were
-# wrapped twice. This is fixed.
-#
-use strict;
-use File::Basename;
-use File::Spec;
-use File::Copy;
-use Getopt::Long;
-
-my $version = '0.32';
-my $versiondate = '2018-02-12'; #version %version
-my $showversion;
-
-my $verbose;
-my $help;
-my $TeXproject;
-
-# folders for scaled graphics, relative names
-my $printfolderprefix = 'printimg';
-my $previewfolderprefix = 'previewimg';
-my $srcfolder = '';
-
-# final resolution. special b/w handling not implemented yet
-my $printdpi = 300;
-my $printbwdpi = 4 * $printdpi;
-my $previewdpi = 72;
-my $tolerance = 20;
-
-# file formats
-my %canhandle =
-( JPG => '1',
- PNG => '1',
-);
-
-# bookkeeping
-my %processedimages;
-my $copied = 0;
-my $scaled = 0;
-my $skipped = 0;
-
-sub printInplaceError
-{
- my $filename = shift;
- print "I will not do inplace modification of graphics:\n" .
- "($filename) will not be processed. (Missing path?)\n";
-}
-
-sub printMissingError
-{
- my $filename = shift;
- print "I can not find ($filename). (What have you done?)\n";
-}
-
-sub handleImage
-{
- my $filename = shift;
- my $dstwidth = shift;
- my $dstheight = shift;
- my ($srcwidth, $srcheight, $srcdepth);
- my $dstfilename;
- my $xfilename;
- my @xsrcdirs;
- my @dstdirs;
- my @convertargs;
- my $idstring;
- print "$filename\n";
- $dstdirs[0] = '.';
- $dstdirs[1] = $printfolderprefix;
- $dstfilename = File::Spec->catfile(@dstdirs, basename($filename));
- if($filename eq $dstfilename){
- unless ($srcfolder gt ' ') {
- printInplaceError($filename);
- $skipped++;
- return;
- }
- $xsrcdirs[0] = $srcfolder;
- $xfilename = File::Spec->catfile(@xsrcdirs, basename($filename));
- unless (-e $xfilename){
- printMissingError($xfilename);
- $skipped++;
- return;
- }
- $filename = $xfilename;
- }
- # check for image width and height
- $idstring = `identify -format "%w x %h %[depth] " $filename`;
- return unless $idstring =~ /(\d+) x (\d+) (\d+)/;
- $srcwidth = $1; $srcheight = $2; $srcdepth = $3;
- if($srcdepth == 1) { # hires for bw pix
- $dstwidth = int($dstwidth * $printbwdpi / 72.27 + .5);
- $dstheight = int($dstheight * $printbwdpi / 72.27 + .5);
- }else { # moderate res for any other
- $dstwidth = int($dstwidth * $printdpi / 72.27 + .5);
- $dstheight = int($dstheight * $printdpi / 72.27 + .5);
- }
- if(-e $dstfilename){
- # if younger and requested size: skip
- my ($mtime1, $mtime2, $size1, $size2, $idstring2, $existwidth);
- my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
- $atime, $ctime, $blksize, $blocks);
- ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
- $atime, $mtime1, $ctime, $blksize, $blocks)
- = stat($dstfilename);
- ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
- $atime, $mtime2, $ctime, $blksize, $blocks)
- = stat($filename);
- if($mtime1 >= $mtime2){
- $idstring2 = `identify -format "%w x %h %[depth] " $dstfilename`;
- if($idstring2 =~ /(\d+) x (\d+) (\d+)/){
- $existwidth = $1;
- if($existwidth == $dstwidth){
- $processedimages{$filename} = $existwidth;
- $skipped++;
- return;
- }
- }
- }
- }
- if(($dstwidth >= $srcwidth) ||
- ($dstwidth *(100 + $tolerance)/100 >= $srcwidth)) {
- # we do no upscaling, but will probably copy the file.
- if (defined $processedimages{$filename}){
- $skipped++;
- }else {
- $processedimages{$filename} = $srcwidth;
- print "will copy $filename to $dstfilename\n" if $verbose;
- copy($filename, $dstfilename);
- $copied++;
- return;
- }
- }else {
- if((defined $processedimages{$filename}) &&
- ($processedimages{$filename} >= $dstwidth)) {
- $skipped++;
- return;
- }
- # we do some downscaling
- $processedimages{$filename} = $dstwidth;
- $convertargs[0] = 'convert';
- $convertargs[1] = ${filename};
- $convertargs[2] = '-resize';
-# $convertargs[3] = "${dstwidth}x${dstheight}!";
- $convertargs[3] = "${dstwidth}x${dstheight}";
- $convertargs[4] = "-density";
- $convertargs[5] = $printdpi;
- $convertargs[6] = ${dstfilename};
- print "will @convertargs\n" if $verbose;
- system(@convertargs);
- $scaled++;
- }
-}
-
-sub readlog
-{
- my $logfilename = shift;
- $logfilename .= '.log';
- my ($picname, $picext, $picwidth, $picheight);
- my ($picextu, $state, $buffer);
- open LOGFILE, "<$logfilename" or die "Cannot read $logfilename";
- $state = 0;
- while (<LOGFILE>){
- if (/^Package pdftex\.def\sInfo\:\s/){
- $buffer = $_;
- unless ($buffer =~ /\sused/){
- chomp $buffer;
- $buffer .= <LOGFILE>;
- } # twice ought to be enough
- unless ($buffer =~ /\sused/){
- chomp $buffer;
- $buffer .= <LOGFILE>;
- }
- if($buffer =~ /Info:\s(\S*)\.(\w+)\sused/){
- $picname = $1;
- $picext = $2;
- ($picextu = $picext) =~ tr/a-z/A-Z/;
- if(defined $canhandle{$picextu}){
- $state = 1;
- next;
- }
- }
- }
- next unless ($state == 1);
- next unless /Requested size: (\d+\.\d+)pt x (\d+\.\d+)pt/;
- $picwidth = $1;
- $picheight = $2;
- handleImage("$picname.$picext", $picwidth, $picheight);
- $state = 0;
- }
-}
-
-sub usage
-{
- print <<'_endusage';
-pdflatexpicscale will downscale large raster images for your TeX project
-to reasonable size.
-Basic usage:
- pdflatexpicscale myarticle
-where your main LaTeX file is called 'myarticle.tex' and a log file exists.
-Fine tuning:
---destdir=folder (relative path, must exist,
- defaults to 'printimg' subfolder of current folder)
---srcdir=folder (folder to find original images, if this software
- can't figure it out on it's own, because you already
- used the target directory.)
---printdpi=XXX (default 300)
---tolerance=XX (default 20 Percents over printdpi to ignore scaling)
---verbose (if you want to know what the script attempts to do)
---version (show software version)
-_endusage
-}
-
-GetOptions('verbose' => \$verbose,
- 'printdpi=i' => \$printdpi,
- 'destdir=s' => \$printfolderprefix,
- 'tolerance=i' => \$tolerance,
- 'srcdir=s' => \$srcfolder,
- 'version' => \$showversion,
- 'help' => \$help,
- 'usage' => \$help,
- );
-
-
-if($showversion){
- print "pdflatexpicscale Version $version $versiondate\n";
-}
-
-if($help){
- usage();
-}
-
-$TeXproject = shift;
-
-if((defined $TeXproject) && ($TeXproject gt ' ')){
- readlog($TeXproject);
- if($verbose) {
- print "pdflatexpicscale Version $version:\n"
- . "$copied file(s) copied, $scaled file(s) converted " .
- "and $skipped occurence(s) skipped for:\n${TeXproject}.log.\n";
- }
-}else {
- usage();
-}
diff --git a/Build/source/texk/texlive/linked_scripts/pdftex-quiet/pdftex-quiet b/Build/source/texk/texlive/linked_scripts/pdftex-quiet/pdftex-quiet
deleted file mode 100755
index 7bf4599c71b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pdftex-quiet/pdftex-quiet
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/bin/bash
-#
-# pdftex-quiet
-# Copyright (C) 2018 Jiří Kozlovský <pdftex-quiet@jkozlovsky.cz>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-VERSION="v1.1.0"
-
-# Do not ignore failures within the pipe
-set -o pipefail
-
-# Get the script name
-BASENAME=`basename "$0"`
-
-# Remove the script's name '-quiet' suffix to get the underlying program to wrap
-WRAPPED_PROGRAM=${BASENAME/%-quiet}
-
-# Assert the wrapped program is either pdflatex or pdftex
-[[ "$WRAPPED_PROGRAM" =~ ^pdf(la)?tex$ ]] || {
- echo "ERROR: Unsupported program to be wrapped!";
- echo " - only pdftex & pdflatex is allowed, but '$WRAPPED_PROGRAM' was provided.";
- exit 101;
-}
-
-# Assert the underlying program is installed
-hash "$WRAPPED_PROGRAM" 2>/dev/null || {
- echo "ERROR: You need to install $WRAPPED_PROGRAM first!";
- exit 102;
-}
-
-# Print version if required
-[[ "$@" =~ -v ]] && {
- echo "pdfTeX-quiet $VERSION";
- "$WRAPPED_PROGRAM" --version;
- exit $?;
-}
-
-# Print help if required (let's print it even if only -h is specified
-# although it's ambiguous because of -halt-on-error, but the regex should take care of that)
-[[ "$@" =~ -h([^a]|$) ]] && {
- echo -e "Usage: $BASENAME [OPTION]... TEXNAME[.tex]\n";
-
- # Print only arguments from the pdftex|pdflatex help
- "$WRAPPED_PROGRAM" --help | grep --color=never -E '^[\[-]' -A500;
- exit $?;
-}
-
-# FILENAME is always the last argument for pdftex|pdflatex
-# Create FILENAME variable only if there was provided some argument
-test $# -gt 0 && eval FILENAME=\${$#}
-
-# Test that the filename was provided
-test -z "$FILENAME" && {
- echo "It's mandatory to provide the filename of tex source as first argument!";
- exit 103;
-}
-
-# Test the existence of the file provided
-test -f "$FILENAME" || test -f "$FILENAME.tex" || {
- echo "Last argument must be a file! Provided file '$FILENAME' doesn't exist!";
- exit 104;
-}
-
-# Run pdftex|pdflatex on the file.
-# Use -halt-on-error because grep basically disables the interactive mode.
-# Using $@ we also allow to pass all other arguments to the pdftex|pdflatex.
-
-# Use grep to show only errors that occur with another 200 lines followed by the error.
-# Errors start with '!' at the line start. We match whole line to mark it in red bold color.
-
-# Finally, let's inverse the grep command result so the command is considered failed
-# only if grep have found something.
-
-# Also make sure we provide no stdin by piping program with no output ':'
-# We have to do this, because grep basically disables program <-> user dialog by not printing
-# characters without finishing newline character (which is usually printed after user's input).
-
-: | \
- "$WRAPPED_PROGRAM" --halt-on-error $@ | \
- { ! grep --color=auto '^!.*' -A200; }
-
-EVERYTHING_SUCCEEDED=$?
-
-# And finally, print the result accordingly
-if ! test $EVERYTHING_SUCCEEDED -eq 0; then
- # But first let's print empty line to improve readability
- echo
- echo "---------------------------------------------"
- echo "- Failed to compile the provided TEX file! --"
- echo "---------------------------------------------"
-
- # The compilation has actually failed, so exit with failure status code
- exit $EVERYTHING_SUCCEEDED
-else
- echo "The compilation was successful!"
-
- # Finally, we are about to print the result pdf/dvi file name, so parse the arguments provided (if any)
- [[ "$@" =~ -output-format(=|[ ]*)dvi($|[ ]*) ]] && EXTENSION=dvi || EXTENSION=pdf
- [[ "$@" =~ -output-directory(=|[ ]*)([^ $]*) ]] && OUTPUT_DIRECTORY="${BASH_REMATCH[2]}/"
-
- # Replace whatever extension we provided to pdftex|pdflatex with either dvi or pdf (based on arguments provided)
- OUTPUT_FILENAME="${FILENAME/%.*/.${EXTENSION}}"
-
- echo "Output file: '${OUTPUT_DIRECTORY}${OUTPUT_FILENAME}'"
-
- # The compilation has succeeded, so exit with success status code
- exit $EVERYTHING_SUCCEEDED
-fi
diff --git a/Build/source/texk/texlive/linked_scripts/pdfxup/pdfxup b/Build/source/texk/texlive/linked_scripts/pdfxup/pdfxup
deleted file mode 100755
index 12ac684ede8..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pdfxup/pdfxup
+++ /dev/null
@@ -1,1587 +0,0 @@
-#!/bin/bash
-shopt -s extglob
-shopt -s lastpipe
-
-VERSION="2.00"
-VDATE="2020/12/17"
-## see release notes at the end of this file.
-
-
-## (c) 2020/12/17 Nicolas Markey <pdfxup at markey dot fr>
-##
-## This work may be distributed and/or modified under the conditions of
-## the LaTeX Project Public License, either version 1.3 of this license
-## or (at your option) any later version. The latest version of this
-## license is in
-##
-## http://www.latex-project.org/lppl.txt
-##
-## and version 1.3 or later is part of all distributions of LaTeX version
-## 2005/12/01 or later.
-##
-## This work has the LPPL maintenance status `maintained'.
-## The Current Maintainer of this work is Nicolas Markey.
-
-
-
-## Roadmap
-## 1) definition of some functions:
-## defaultvalues() and setdefaultvalues()
-## usage()
-## myecho()
-## dimtopt() and testdim()
-## ifinrangelist()
-## setconfigfile() [look for configuration file]
-## cleancslor() [clean comma-sep. list of ranges]
-## cleanup
-## 2) script:
-## - set default options
-## - test for ghostscript and pdflatex
-## - process command-line options
-## - check number of pages
-## - set up variables
-## - compute bounding box
-## - prepare latex file
-## - create PDF
-## - clean up
-## 3) manual, examples and release notes
-##
-
-######################################################################
-## default values for all options.
-######################################################################
-## Can be modified from command line
-## For instance, "dfpdfxupBB=1-4 pdfxup ..." automatically sets "-bb=1-4"
-## (might be useful for defining derived scripts)
-function defaultvalues()
-{
- : ${dfpdfxupNB_COLUMNS=2}
- : ${dfpdfxupNB_ROWS=1}
- : ${dfpdfxupLANDSCAPE=1}
- : ${dfpdfxupPAPERSIZE="a4"}
- : ${dfpdfxupBOOKLET=0}
- : ${dfpdfxupCLIP=1}
- : ${dfpdfxupOUTPUTFILE="pdfxup.pdf"}
- : ${dfpdfxupINNER_HMARGIN="5pt"}
- : ${dfpdfxupINNER_VMARGIN="5pt"}
- : ${dfpdfxupINNER_MARGINS="5pt"}
- : ${dfpdfxupHMARGIN="5pt"}
- : ${dfpdfxupVMARGIN="5pt"}
- : ${dfpdfxupMARGINS="5pt"}
- : ${dfpdfxupINTERM_HSPACE="1pt"}
- : ${dfpdfxupINTERM_VSPACE="1pt"}
- : ${dfpdfxupINTERM_SPACES="1pt"}
- : ${dfpdfxupFRAME_WIDTH=".4pt"}
- : ${dfpdfxupPAGES="-"}
- : ${dfpdfxupINCLUDE_FOR_BBOX="-"}
- : ${dfpdfxupEXCLUDE_FOR_BBOX=""}
- : ${dfpdfxupKEEP_ORIG_BBOX="0"}
- : ${dfpdfxupCOMPUTE_BBOX_ONLY="0"}
- : ${dfpdfxupVERBOSITY="1"}
- : ${dfpdfxupDEBUG="0"}
- : ${dfpdfxupWATERMARK_PERIOD="1"}
- : ${dfpdfxupSILENTLY_OVERWRITE="0"}
- : ${dfpdfxupSET_BBOX=""}
- : ${dfpdfxupTIGHT_FRAME="0"}
-}
-
-function setdefaultvalues()
-{
- # number of columns
- NB_COLUMNS=$dfpdfxupNB_COLUMNS;
- # number of rows
- NB_ROWS=$dfpdfxupNB_ROWS;
- # landscape mode (1=landscape, 0=portrait)
- LANDSCAPE=$dfpdfxupLANDSCAPE;
- # booklet mode ('se'=booklet 'short-edge', 'le'=booklet 'long-edge')
- BOOKLET=$dfpdfxupBOOKLET;
- # clip pages to bounding box (1=yes, 0=no)
- CLIP=$dfpdfxupCLIP;
- # papersize ('a4', 'letter', ...)
- PAPERSIZE=$dfpdfxupPAPERSIZE;
- # name of output file
- OUTPUTFILE=$dfpdfxupOUTPUTFILE
- # (minimal) inner horizontal margin (between frame and logical page)
- INNER_HMARGIN=$dfpdfxupINNER_HMARGIN;
- # (minimal) inner vertical margin (between frame and logical page)
- INNER_VMARGIN=$dfpdfxupINNER_VMARGIN;
- # (minimal) inner margin (both horizontal and vertical)
- INNER_MARGINS=$dfpdfxupINNER_MARGINS;
- # horizontal margin (between content and border of physical page)
- HMARGIN=$dfpdfxupHMARGIN;
- # vertical margin (between content and border of physical page)
- VMARGIN=$dfpdfxupVMARGIN;
- # margin (between content and border of physical page)
- MARGINS=$dfpdfxupMARGINS;
- # intermediate horizontal space (between logical pages)
- INTERM_HSPACE=$dfpdfxupINTERM_HSPACE;
- # intermediate vertical space (between logical pages)
- INTERM_VSPACE=$dfpdfxupINTERM_VSPACE;
- # intermediate space (between logical pages)
- INTERM_SPACES=$dfpdfxupINTERM_SPACES;
- # frame width
- FRAME_WIDTH=$dfpdfxupFRAME_WIDTH;
- # verbosity level
- ## don't overwrite VERBOSITY if set on command line
- : ${VERBOSITY=$dfpdfxupVERBOSITY};
- # debug mode
- DEBUG=$dfpdfxupDEBUG;
- # file used for watermarking
- WATERMARK_FILE="";
- # number of pages to repeat when watermarking
- WATERMARK_PERIOD=$dfpdfxupWATERMARK_PERIOD;
- # keep original bounding box (hence do not recompute)
- KEEP_ORIG_BBOX=$dfpdfxupKEEP_ORIG_BBOX;
- # only compute bounding box (hence do not produce PDF output)
- COMPUTE_BBOX_ONLY=$dfpdfxupCOMPUTE_BBOX_ONLY;
- # overwrite output file without warning
- SILENTLY_OVERWRITE=$dfpdfxupSILENTLY_OVERWRITE;
- # make frame tight around logical pages
- TIGHT_FRAME=$dfpdfxupTIGHT_FRAME;
- # initial bounding box
- SET_BBOX=$dfpdfxupSET_BBOX
-
- ## Notice: the names for h and w should actually be X and Y:
- ## they are not width and height, but coordinates of upper right corner.
- ## Notice: PAGES, INCLUDE_FOR_BBOX and EXCLUDE_FOR_BBOX will be set to default values if empty after
- ## processing options
-}
-
-######################################################################
-## Usage
-######################################################################
-function usage()
-{
- defaultvalues;
- if [[ "$dfpdfxupPAGES" == "-" ]]; then
- explicitPAGES=" (all)";
- fi
- if [[ "$dfpdfxupEXCLUDE_FOR_BBOX" == "" ]]; then
- explicitEXCLUDE_FOR_BBOX=" (none)";
- fi
- if [[ "$dfpdfxupINCLUDE_FOR_BBOX" == "-" ]]; then
- explicitBB=" (all)";
- fi
- if [[ "$dfpdfxupSET_BBOX" == "" ]]; then
- explicitSET_BBOX=" (unset)";
- fi
- echo "pdfxup: n-up pages of a PDF document, preserving readability
-usage: `basename $0` [OPTIONS] file
-The main OPTIONS are:
- -x n n columns per page [default: \"$dfpdfxupNB_COLUMNS\"]
- -y n n lines per page [default: \"$dfpdfxupNB_ROWS\"]
- -l [0|1] landscape-mode [default: \"$dfpdfxupLANDSCAPE\"]
- -b [0|1|le|se] booklet-mode [default: \"$dfpdfxupBOOKLET\"]
- -cf file import config. parameters from file [default: none]
- -m n margins [default: \"$dfpdfxupMARGINS\"]
- -fw n frame width [default: \"$dfpdfxupFRAME_WIDTH\"]
- -o file write output to file [default: \"$dfpdfxupOUTPUTFILE\"]
- -p pages only include these pages [default: \"$dfpdfxupPAGES\"$explicitPAGES]
- -nobb pages pages to omit when computing b.box [default: \"$dfpdfxupEXCLUDE_FOR_BBOX\"$explicitEXCLUDE_FOR_BBOX]
- -bb pages pages to use for computing b.box [default: \"$dfpdfxupINCLUDE_FOR_BBOX\"$explicitBB]
- -g [0|1] only computes bounding box [default: \"$dfpdfxupCOMPUTE_BBOX_ONLY\"]
- -s x y X Y force bounding box [default: \"$dfpdfxupSET_BBOX\"$explicitSET_BBOX]
- -w file add watermarking [default: none]
- -wp n repeat last n pages of watermark file [default: \"$dfpdfxupWATERMARK_PERIOD\"]
- -i ask before overwriting/removing files
- -d debug mode: keep intermediary files
- -v show version number and exit
-See the manual page ('man pdfxup') for the list of all options.";
-
-##
-## Some options are not presented, for the sake of brevity...
-##
-## -c [0|1] clip pages to bounding box [default: \"$dfpdfxupCLIP\"]
-## -im n inner margins [default: \"$dfpdfxupINNER_MARGINS\"]
-## -ihm n inner horizontal margin [default: \"$dfpdfxupINNER_HMARGIN\"]
-## -ivm n inner vertical margin [default: \"$dfpdfxupINNER_VMARGIN\"]
-## -hm n horizontal margin [default: \"$dfpdfxupHMARGIN\"]
-## -vm n vertical margin [default: \"$dfpdfxupVMARGIN\"]
-## -ihs n interm. horizontal space [detault: \"$dfpdfxupINTERM_HSPACE\"]
-## -ivs n interm. vertical space [detault: \"$dfpdfxupINTERM_VSPACE\"]
-## -is n interm. spaces [default: \"$dfpdfxupINTERM_SPACES\"]
-## -kbb keep original bounding box [default: \"$dfpdfxupKEEP_ORIG_BBOX\"]
-## -ow allow overwriting [default: \"$dfpdfxupSILENTLY_OVERWRITE\"]
-## -ps s output paper size [default: \"$dfpdfxupPAPERSIZE\"]
-## -tf draw tight frame around each page [default: \"$dfpdfxupTIGHT_FRAME\"]
-## -q run quietly (equiv. '-V=0')
-## -h show this help message
-## -V [0-3] select verbosity [default: \"$dfpdfxupVERBOSITY\"]
-##
-##
-##
- exit 0;
-}
-
-######################################################################
-## Auxiliary functions
-######################################################################
-## myecho handles several levels of verbosity
-function myecho()
-{
- ECHO=0;
- case $1 in
- +([0-9])\+)
- if [[ $VERBOSITY -ge ${1%+} ]]; then ECHO=1; fi
- ;;
- +([0-9]))
- if [[ $VERBOSITY -eq $1 ]]; then ECHO=1; fi
- ;;
- +([0-9])-)
- if [[ $VERBOSITY -le ${1%-} ]]; then ECHO=1; fi
- ;;
- esac
- if [[ $ECHO == 1 ]]; then
- case $2 in
- -*)
- echo $2 "$3"
- ;;
- *)
- echo "$2"
- ;;
- esac
- fi
-}
-
-DELAYEDECHO="";
-function delaymyecho ()
-{
- DELAYEDECHO+="\n$1";
-}
-
-
-## transforms given dimension (in cm, mm, in) in pt
-function dimtopt()
-{
- dim=$1;
- case $dim in
- *pt)
- ;;
- *mm)
- dim=${dim%mm};
- eval dim=$((dim*2845/100))pt;
- ;;
- *cm)
- dim=${dim%cm};
- eval dim=$((dim*284/10))pt;
- ;;
- *in)
- dim=${dim%in};
- eval dim=$((dim*723/10))pt;
- ;;
- *[!0-9]*)
- ## should not occur... has been filtered out by main 'case'
- myecho 1+ " illegal unit of measure in option '$3'; ignoring";
- dim=$2;
- ;;
- *)
- dim=${dim}pt;
- ;;
- esac
-}
-
-## check valid unit for given dimension
-function testdim()
-{
- dim=$1;
- case $dim in
- +([0-9])@(pt|in|cm|mm))
- ;;
- +([0-9]))
- dim=${dim}pt
- ;;
- +([0-9])*)
- echo " illegal unit of measure in option '$3'; ignoring";
- dim=$2;
- ;;
- *)
- echo " not a valid dimension in option '$3'; ignoring";
- dim=$2;
- ;;
- esac
-}
-
-## sets variable $in to 1 if $1 is in list of ranges $2
-function ifinrangelist()
-{
- n=$1;
- list=$2;
- in=0;
-
- for i in ${list//,/$IFS}; do
- case $i in
- +([0-9]))
- first=$i;
- last=$i;;
- -+([0-9]))
- first=1;
- last=`echo $i|tr -d -`;;
- +([0-9])-)
- first=`echo $i|tr -d -`;
- last=$nbp;;
- +([0-9])-+([0-9]))
- first=`echo $i|cut -d- -f1`;
- last=`echo $i|cut -d- -f2`;;
- -)
- first=1;
- last=$nbp;;
- *)
- myecho 1+ " error in range of pages (option '$3' contains '$i')";
- esac
- if [[ $n -ge $first && $n -le $last ]]; then
- in=1;
- return;
- fi
- done
- return;
-}
-
-## look for config file
-function setconfigfile()
-{
- if [[ `echo "$1"|grep -v "/"` ]]; then
- if [[ `echo "$1"|grep "\.xup$"` && $KPSEWHICH ]]; then
- CFFILE=`$KPSEWHICH $1`
- else
- CFFILE=`$KPSEWHICH $1.xup`
- fi
- fi
- if [[ (! -e $CFFILE) ]]; then
- if [[ -e $1 ]]; then
- CFFILE=$1
- else
- if [[ -e $1.xup ]]; then
- CFFILE=$1.xup
- fi
- fi
- fi
- #echo $CFFILE;
-}
-
-## normalize list + count number of pages to be displayed
-function cleancslor()
-{
- list=$1;
- result="";
- for i in ${list//,/$IFS}; do
- case $i in
- +([0-9]))
- if [[ $i -le $nbp ]]; then
- result+="$i,";
- nbpages+=1;
- else
- myecho 1+ " $file has $nbp page(s); page $i does not exist."
- fi
- ;;
- -+([0-9]))
- if [[ $i -le $nbp ]]; then
- result+="1$i,";
- nbpages+=${i#-};
- else
- myecho 1+ " $file has $nbp page(s); changed 1$i to 1-$nbp."
- result+="1$nbp,";
- nbpages+=${nbp#-};
- fi
- ;;
- +([0-9])-)
- if [[ $i -le $nbp ]]; then
- result+="$i$nbp,";
- nbpages+=$(expr $nbp + 1 - ${i%-});
- else
- myecho 1+ " $file has $nbp page(s); pages $i do not exist."
- fi
- ;;
- +([0-9])-+([0-9]))
- fstp=`echo $i|cut -d- -f1`
- if [[ $fstp -gt $nbp ]]; then
- myecho 1+ " $file has $nbp page(s); range $i omitted."
- fi
- lstp=`echo $i|cut -d- -f2`
- if [[ $lstp -gt $nbp ]]; then
- myecho 1+ " $file has $nbp page(s); range $i changed to $fstp-$nbp."
- lstp=$nbp;
- fi
- if [[ $lstp -ge $fstp ]]; then
- result+="$fstp-$lstp,";
- nbpages+=$(expr 1 + $lstp - $fstp)
- fi
- ;;
- -)
- result+="1-$nbp,";
- nbpages+=$nbp;;
- +([0-9])%+([0-9]))
- ## explicitly list all values...
- ## (simpler, but admitedly less efficient,
- ## than handling real modulos)
- declare -i cptr;
- cptr=`echo $i|cut -d% -f1`;
- step=`echo $i|cut -d% -f2`;
- while [[ $cptr -le $nbp ]]; do
- result+="$cptr,";
- nbpages+=1;
- cptr+=$step;
- done;;
- *)
- ## anything else is discarded
- ;;
- esac
- done
-}
-
-function cleanup()
-{
- if [[ $DEBUG == 0 ]]; then
- myecho 1+ "-> cleaning";
- myecho 2+ " * rm $RMopt *$filename.*"
- rm $RMopt *$filename.*
- fi
-}
-
-ARGS=$@;
-if [ $# -eq 0 ]; then
- usage;
-fi
-
-defaultvalues;
-setdefaultvalues;
-filename="temp-pdfxup-`date +%s`";
-inputfilename="input-$filename";
-watermarkfilename="watermark-$filename";
-
-######################################################################
-## check for ghostscript and pdflatex
-######################################################################
-## GS could be specified from command-line
-: ${GS=`which gs`}
-GSVERSION=`$GS --version 2>/dev/null`;
-if [ ! "$GSVERSION" ]; then
- echo " /!\\ ghostscript not found; aborting.";
- exit 1;
-fi
-GSNTS="9.27";
-if [ ${GSVERSION%.*} -eq ${GSNTS%.*} ] && [ ${GSVERSION#*.} -gt ${GSNTS#*.} ] || \
- [ ${GSVERSION%.*} -gt ${GSNTS%.*} ]; then
- GSOPTFILE=" --permit-file-read=$inputfilename.pdf "
- GSOPTWATERMARK=" --permit-file-read=$watermarkfilename.pdf "
-fi
-
-## PDFLATEX could be specified on command-line
-: ${PDFLATEX=`which pdflatex`}
-PDFLATEXVERSION=`$PDFLATEX --version 2>/dev/null |grep 3.1415|grep -i tex`;
-if [ ! "$PDFLATEXVERSION" ]; then
- echo " /!\\ pdflatex not found; aborting.";
- exit 1;
-fi
-
-## KPSEWHICH could be specified on command-line
-: ${KPSEWHICH=`which kpsewhich`}
-
-
-######################################################################
-## command-line arguments
-######################################################################
-## go through all arguments and options
-
-while [ $# != 0 ]; do
- case $1 in
- -x|--columns)
- NB_COLUMNS=$2;
- shift 2;;
- -x?(=)+([0-9]))
- NB_COLUMNS=`echo $1|sed -re "s/-x=?//"`;
- shift;;
- -y|--rows)
- NB_ROWS=$2;
- shift 2;;
- -y?(=)+([0-9]))
- NB_ROWS=`echo $1|sed -re "s/-y=?//"`;
- shift;;
- -nup|--nup)
- NB_COLUMNS=`echo $2|sed -re "s/x.*$//"`;
- NB_ROWS=`echo $2|sed -re "s/^.*x//"`;
- shift 2;;
- -?(-)nup?(=)+([0-9])x+([0-9]))
- NB_COLUMNS=`echo $1|sed -re "s/x.*$//"|sed -re "s/--?nup=?//"`;
- NB_ROWS=`echo $1|sed -re "s/^--?nup.*x//"`;
- shift;;
- -l|--landscape)
- case $2 in
- 1|yes|y|true)
- LANDSCAPE=1;
- SHIFT=2;
- ;;
- 0|no|n|false)
- LANDSCAPE=0;
- SHIFT=2;
- ;;
- -*)
- LANDSCAPE=1;
- SHIFT=1;
- ;;
- *)
- LANDSCAPE=1;
- #echo "Normal use of '$1' option is: '$1 [0|1]'";
- #echo "Assuming you want landscape outupt...";
- SHIFT=1;
- esac
- shift $SHIFT;;
- -l*)
- ANS=`echo $1|sed -re "s/-l=?//"`;
- case $ANS in
- 1|yes|y|true)
- LANDSCAPE=1;
- ;;
- 0|no|n|false)
- LANDSCAPE=0;
- ;;
- *)
- LANDSCAPE=1;
- #echo "Normal use of '$1' option is: '$1 [0|1]'";
- #echo "Assuming you want landscape outupt...";
- esac
- shift;;
- -nl|--portrait|--no-landscape|--nolandscape)
- LANDSCAPE=0;
- shift;;
- -b|--booklet)
- case $2 in
- se|short-edge)
- BOOKLET="2";
- SHIFT=2;
- ;;
- 1|yes|y|true|le|long-edge)
- BOOKLET=1;
- SHIFT=2;
- ;;
- 0|no|n|false)
- BOOKLET=0;
- SHIFT=2;
- ;;
- -*)
- BOOKLET=1;
- SHIFT=1;
- ;;
- *)
- BOOKLET=1;
- #echo "Normal use of '$1' option is: '$1 [0|1]'";
- #echo "Assuming you want booklet outupt...";
- SHIFT=1;
- esac
- if [[ $BOOKLET != 0 ]]; then
- FRAME_WIDTH=0pt
- # this is the default, but can be changed by passing -fw option
- fi
- shift $SHIFT;;
- -b[^b]*|--booklet*)
- ANS=`echo $1|sed -re "s/--?b(ooklet)?=?//"`;
- case $ANS in
- se|short-edge)
- BOOKLET="2";
- ;;
- 1|yes|y|true|le|long-edge)
- BOOKLET=1;
- ;;
- 0|no|n|false)
- BOOKLET=0;
- ;;
- *)
- BOOKLET=1;
- #echo "Normal use of '$1' option is: '$1 [0|1]'";
- #echo "Assuming you want booklet outupt...";
- esac
- if [[ $BOOKLET != 0 ]]; then
- FRAME_WIDTH=0pt
- # this is the default, but can be changed by passing -fw option
- fi
- shift;;
- -cf|--config|--config-file|-?(-)mode)
- case $2 in
- -*)
- echo "Error. Option '$1' expects a file name; found '$2'.";
- echo "Aborting.";
- exit 0;
- ;;
- *)
- setconfigfile $2
- ;;
- esac
- if [[ -e "$CFFILE" ]]; then
- source $CFFILE
- else
- myecho 0+ " /!\ configuration file $2 not found"
- fi
- shift 2;;
- -cf=*|--config=*|--config-file=*|-?(-)mode=*)
- TMP=`echo $1|cut -d= -f2-`
- setconfigfile $TMP
- if [[ -e "$CFFILE" ]]; then
- source $CFFILE
- else
- myecho 0+ " /!\ configuration file $TMP not found"
- fi
- shift;;
- -c|--clip)
- case $2 in
- 1|yes|y|true)
- CLIP=1;
- SHIFT=2;
- ;;
- 0|no|n|false)
- CLIP=0;
- SHIFT=2;
- ;;
- *)
- CLIP=1;
- SHIFT=1;
- esac
- shift $SHIFT;;
- -c*|--clip=*)
- ANS=`echo $1|sed -re "s/--?c(lip)?=?//"`;
- case $ANS in
- 1|yes|y|true)
- CLIP=1;
- ;;
- 0|no|n|false)
- CLIP=0;
- ;;
- esac
- shift;;
- -nc|--no-clip)
- CLIP=0;
- shift;;
- -ps|--paper|--paper?(-)size)
- PAPERSIZE=$2;
- shift 2;;
- -ps=*|--paper=*|--paper?(-)size=*)
- ## '=' is compulsory, as we expect a string...
- ANS=`echo $1|sed -re "s/(-ps=|--paper=|--paper-?size=)//"`;
- PAPERSIZE=$ANS;
- shift;;
- -p|--pages|--page)
- case $2 in
- -)
- PAGES+="$2,";
- ;;
- -*)
- echo "Error: option '$1' expects a range, not '$2'.";
- echo "Aborting.";
- exit 0;
- ;;
- *)
- PAGES+="$2,";
- ;;
- esac
- shift 2;;
- -p*|--page*)
- ANS=`echo $1|sed -re "s/--?p(ages?)?=?//"`;
- PAGES=+="$ANS,";
- shift;;
- -o|--out|--output-file|--outfile)
- OUTPUTFILE=$2;
- shift 2;;
- -o=*|--out=*|--output-file=*|--outfile=*)
- ANS=`echo $1|sed -re "s/--?o(ut(put-)?(file)?)?=//"`;
- OUTPUTFILE=$ANS;
- shift;;
- -ow)
- SILENTLY_OVERWRITE="1";
- shift;;
- -ihm|--innerhmargin)
- dimtopt $2 $dfpdfxupINNER_HMARGIN "$1 $2";
- INNER_HMARGIN=$dim;
- shift 2;;
- -ihm?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-ihm=?//"`;
- dimtopt $ANS $dfpdfxupINNER_HMARGIN $1;
- INNER_HMARGIN=$dim;
- shift;;
- -ivm|--innervmargin)
- dimtopt $2 $dfpdfxupINNER_VMARGIN "$1 $2";
- INNER_VMARGIN=$dim;
- shift 2;;
- -ivm?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-ivm=?//"`;
- dimtopt $ANS $dfpdfxupINNER_VMARGIN $1;
- INNER_VMARGIN=$dim;
- shift;;
- -im|--innermargins)
- dimtopt $2 $dfpdfxupINNER_MARGINS "$1 $2";
- INNER_HMARGIN=$dim;
- INNER_VMARGIN=$dim;
- shift 2;;
- -im?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-im=?//"`;
- dimtopt $ANS $dfpdfxupINNER_MARGINS $1;
- INNER_HMARGIN=$dim;
- INNER_VMARGIN=$dim;
- shift;;
- -hm|--hmargin)
- testdim $2 $dfpdfxupHMARGIN "$1 $2";
- HMARGIN=$dim;
- shift 2;;
- -hm?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-hm=?//"`;
- testdim $ANS $dfpdfxupHMARGIN $1;
- HMARGIN=$dim;
- shift;;
- -vm|--vmargin)
- testdim $2 $dfpdfxupVMARGIN "$1 $2";
- VMARGIN=$dim;
- shift 2;;
- -vm?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-vm=?//"`;
- testdim $ANS $dfpdfxupVMARGIN $1;
- VMARGIN=$dim;
- shift;;
- -m|--margins)
- testdim $2 $dfpdfxupMARGINS "$1 $2";
- HMARGIN=$dim;
- VMARGIN=$dim;
- shift 2;;
- -m?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-m=?//"`;
- testdim $ANS $dfpdfxupMARGINS $1;
- HMARGIN=$dim;
- VMARGIN=$dim;
- shift;;
- -ihs|--inthspace)
- testdim $2 $dfpdfxupINTERM_HSPACE "$1 $2";
- INTERM_HSPACE=$dim;
- shift 2;;
- -ihs?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-ihs=?//"`;
- testdim $ANS $dfpdfxupINTERM_HSPACE $1;
- INTERM_HSPACE=$dim;
- shift;;
- -ivs|--intvspace)
- testdim $2 $dfpdfxupINTERM_VSPACE "$1 $2";
- INTERM_VSPACE=$dim;
- shift 2;;
- -ivs?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-ivs=?//"`;
- testdim $ANS $dfpdfxupINTERM_VSPACE $1;
- INTERM_VSPACE=$dim;
- shift;;
- -is|--intspaces)
- testdim $2 $dfpdfxupINTERM_SPACES "$1 $2";
- INTERM_HSPACE=$dim;
- INTERM_VSPACE=$dim;
- shift 2;;
- -is?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-is=?//"`;
- testdim $ANS $dfpdfxupINTERM_SPACES $1;
- INTERM_HSPACE=$dim;
- INTERM_VSPACE=$dim;
- shift;;
- -fw|--framewidth|--frame-width)
- testdim $2 $dfpdfxupFRAME_WIDTH "$1 $2";
- FRAME_WIDTH=$dim;
- shift 2;;
- -fw?(=)+([0-9])*)
- ANS=`echo $1|sed -re "s/-fw=?//"`;
- testdim $ANS $dfpdfxupFRAME_WIDTH $1;
- FRAME_WIDTH=$dim;
- shift;;
- -tf|--tight-frame)
- case $2 in
- 1|yes|y|true)
- TIGHT_FRAME=1;
- SHIFT=1;
- ;;
- 0|no|n|false)
- TIGHT_FRAME=0;
- SHIFT=1;
- ;;
- *)
- TIGHT_FRAME=1;
- SHIFT=1;
- esac
- shift $SHIFT;;
- -tf*|--tight-frame*)
- TIGHT_FRAME=`echo $1|sed -re "s/--?t(ight-)?f(rame)?=?//"`;
- shift;;
- -i)
- MVopt="-i";
- RMopt="-i";
- shift;;
- -nobb|--nobb|-no-bb|--no-bb)
- case $2 in
- -)
- EXCLUDE_FOR_BBOX+="$2,";
- ;;
- -*)
- echo "Error: option '$1' expects a range, not '$2'.";
- echo "Aborting.";
- exit 0;
- ;;
- *)
- EXCLUDE_FOR_BBOX+="$2,";
- ;;
- esac
- shift 2;;
- -nobb*|--no-bb*)
- ANS=`echo $1|sed -re "s/--?no-?bb=?//"`;
- EXCLUDE_FOR_BBOX+="$ANS,";
- shift;;
- -bb|--bb|--bounding-box)
- case $2 in
- -)
- INCLUDE_FOR_BBOX+="$2,";
- ;;
- -*)
- echo "Error: option '$1' expects a range, not '$2'.";
- echo "Aborting.";
- exit 0;
- ;;
- *)
- INCLUDE_FOR_BBOX+="$2,";
- ;;
- esac
- shift 2;;
- -bb*|--bb*|--bounding-box)
- ANS=`echo $1|sed -re "s/--?b(ounding-?)?b(ox)?=?//"`;
- INCLUDE_FOR_BBOX+="$ANS,";
- shift;;
- -kbb|--keepbb|--keep-bb|--original-bb)
- case $2 in
- 1|yes|y|true)
- KEEP_ORIG_BBOX=1;
- SHIFT=2;
- ;;
- 0|no|n|false)
- KEEP_ORIG_BBOX=0;
- SHIFT=2;
- ;;
- -*)
- KEEP_ORIG_BBOX=1;
- SHIFT=1;
- ;;
- *)
- KEEP_ORIG_BBOX=1;
- SHIFT=1;
- esac
- shift $SHIFT;;
- -kbb*|--keepbb*|--keep-bb*|--original-bb*)
- ANS=`echo $1|sed -re "s/--?(k(eep-?)?bb|orig[^=]*bb)=?//"`;
- case $ANS in
- 1|yes|y|true)
- KEEP_ORIG_BBOX=1;
- ;;
- 0|no|n|false)
- KEEP_ORIG_BBOX=0;
- ;;
- *)
- KEEP_ORIG_BBOX=1;
- esac
- shift;;
- -g|--get-bb|--getbb)
- case $2 in
- 1|yes|y|true)
- COMPUTE_BBOX_ONLY=1;
- SHIFT=2;
- ;;
- 0|no|n|false)
- COMPUTE_BBOX_ONLY=0;
- SHIFT=2;
- ;;
- -*)
- COMPUTE_BBOX_ONLY=1;
- SHIFT=1;
- ;;
- *)
- COMPUTE_BBOX_ONLY=1;
- SHIFT=1;
- esac
- shift $SHIFT;;
- -g*|--get-bb=*|--getbb=*)
- ANS=`echo $1|sed -re "s/--?g(etbb|et-bb)?=?//"`;
- case $ANS in
- 1|yes|y|true)
- COMPUTE_BBOX_ONLY=1;
- ;;
- 0|no|n|false)
- COMPUTE_BBOX_ONLY=0;
- ;;
- *)
- COMPUTE_BBOX_ONLY=1;
- #echo "Normal use of '$1' option is: '$1 [0|1]'";
- #echo "Assuming you want landscape outupt...";
- esac
- shift;;
- -s|--set-bb|--setbb)
- case "$2$3$4$5" in
- +([0-9]))
- SET_BBOX="$2 $3 $4 $5"
- ;;
- *)
- echo "Error: option '$1' expects 4 numbers.";
- echo "Aborting.";
- exit 0;
- ;;
- esac
- shift 5;;
- -V)
- case $2 in
- @(0|1|2|3))
- if [[ $VERBOSITY -lt $2 ]]; then
- VERBOSITY=$2;
- fi
- SHIFT=2;;
- *)
- if [[ $VERBOSITY -lt 2 ]]; then
- VERBOSITY=2;
- fi
- SHIFT=1;;
- esac
- shift $SHIFT;;
- -V?(=)@(0|1|2|3))
- if [[ $VERBOSITY -lt `echo $1|sed -re "s/-V=?//"` ]]; then
- VERBOSITY=`echo $1|sed -re "s/-V=?//"`;
- fi
- shift;;
- -V?(=)+([0-9]))
- VERBOSITY=9;
- shift;;
- -VV)
- if [[ $VERBOSITY -lt 3 ]]; then
- VERBOSITY=3;
- fi
- shift;;
- -VVV)
- if [[ $VERBOSITY -lt 4 ]]; then
- VERBOSITY=4;
- fi
- shift;;
- -q|--quiet)
- VERBOSITY=0;
- shift;;
- -w|--watermark|--watermark-file)
- WATERMARK_FILE=$2;
- shift 2;;
- -w=*|--watermark=*|--watermark-file=*)
- ANS=`echo $1|sed -re "s/--?w[^=]*=//"`;
- WATERMARK_FILE=$ANS;
- shift;;
- -wp|--wperiod|--watermark-period)
- WATERMARK_PERIOD=$2;
- shift 2;;
- -wp=*|--wperiod=*|--watermark-period=*)
- ANS=`echo $1|sed -re "s/--?w[^=]*=//"`;
- WATERMARK_PERIOD=$ANS;
- shift;;
- -v|--version)
- echo "pdfxup version $VERSION (released $VDATE)";
- exit 0;;
- -d|--debug)
- DEBUG=1;
- shift;;
- -*)
- usage;;
- *:+([0-9\-,\%]))
- ARG=$1;
- file=${ARG%:*};
- PAGES+="${ARG#*:},";
- ## only one file is allowed, and no options
- ## should appear after the file name...
- break;;
- *)
- file=$1;
- ## only one file is allowed, and no options
- ## should appear after the file name...
- break;;
- esac;
-done
-
-
-## check input file
-if [[ "$file" == "" ]]; then
- echo "pdfxup error: no input file given; exiting.";
- exit 1;
-fi
-
-## try adding .pdf suffix if needed
-if [[ ! -e "$file" && `basename "$file" .pdf` == "$file" && -e "${file}.pdf" ]];
- then
- myecho 2+ " changing file name '$file' to '$file.pdf'";
- file="${file}.pdf";
-fi;
-
-if [[ ! -e "$file" ]]; then
- echo "pdfxup error: file \"$file\" not found; exiting.";
- exit 1;
-fi
-
-## check output file
-
-
-## set bbox
-SBB=0;
-read -r x0 y0 w0 h0 <<<$(echo "-1 -1 -1 -1");
-if [[ "$SET_BBOX" ]]; then
- SBB=1;
- read -r BBX BBY BBW BBH <<<$(echo $SET_BBOX);
-fi
-
-
-## summarize options:
-myecho 1+ "-> processing options";
-if [[ "$FILE" != "" ]]; then
- myecho 2+ " * used configuration file $FILE";
-fi
-if [[ $BOOKLET -eq 1 ]]; then
- myecho 2+ " * booklet mode (long-edge)";
-else if [[ $BOOKLET -eq 2 ]]; then
- myecho 2+ " * booklet mode (short edge)";
- else
- myecho 2+ -ne " * columns=$NB_COLUMNS, rows=$NB_ROWS, ";
- if [[ $LANDSCAPE -eq 1 ]]; then
- myecho 2+ "landscape mode";
- else
- myecho 2+ "portrait mode";
- fi
- fi
-fi
-myecho 2+ " * paper size=$PAPERSIZE";
-if [[ $CLIP -eq 1 ]]; then
- myecho 2+ " * clipping content outside bounding box";
-else
- myecho 2+ " * not clipping content outside bounding box";
-fi
-myecho 2+ " * output file is \"$OUTPUTFILE\"";
-if [[ "$INNER_HMARGIN" == "$INNER_VMARGIN" ]]; then
- myecho 2+ " * inner margins=$INNER_HMARGIN";
-else
- myecho 2+ " * inner horizontal margin=$INNER_HMARGIN, inner vertical margin=$INNER_VMARGIN";
-fi
-if [[ "$HMARGIN" == "$VMARGIN" ]]; then
- myecho 2+ " * margins=$HMARGIN";
-else
- myecho 2+ " * horizontal margin=$HMARGIN, vertical margin=$VMARGIN";
-fi
-if [[ "$INTERM_HSPACE" == "$INTERM_VSPACE" ]]; then
- myecho 2+ " * space between pages=$INTERM_HSPACE";
-else
- myecho 2+ " * horizontal space between pages=$INTERM_HSPACE, vertical space=$INTERM_VSPACE";
-fi
-if [[ $TIGHT_FRAME -eq 1 ]]; then
- TIGHT_FRAMEMESSAGE=" (tight)";
-else
- TIGHT_FRAMEMESSAGE=" (loose)";
-fi
-myecho 2+ " * frame rule width=$FRAME_WIDTH $TIGHT_FRAMEMESSAGE";
-if [[ $MVopt == "-i" && $RMopt == "-i" ]]; then
- myecho 2+ " * interactive clean up";
-else
- myecho 2+ " * non-interactive clean up";
-fi
-if [[ $COMPUTE_BBOX_ONLY -eq 1 ]]; then
- myecho 2+ " * only compute bounding box";
-fi
-if [[ $KEEP_ORIG_BBOX -eq 1 ]]; then
- myecho 2+ " * keep original bounding box";
-fi
-if [[ $SBB -eq 1 ]]; then
- myecho 2+ " * bounding box set to $BBX $BBY $BBW $BBH";
-fi
-if [[ "$WATERMARK_FILE" ]]; then
- myecho 2+ " * watermarking with file $WATERMARK_FILE";
- myecho 2+ " * watermarking period=$WATERMARK_PERIOD";
-fi
-
-
-## here we report on our earlier checks about GS and PDFLATEX
-## (again, we had to know the level of verbosity first...)
-myecho 2+ "-> checking for ghostscript and pdflatex"
-myecho 2+ " ghostscript is $GS (version $GSVERSION)";
-if [ "$GSOPTFILE" ]; then
- myecho 2+ " [gs version > $GSNTS; we will use --permit-file-read]";
-else
- myecho 2+ " [gs version <= $GSNTS; not using --permit-file-read]\"";
-fi
-myecho 2+ " pdflatex is $PDFLATEX (version $PDFLATEXVERSION)";
-
-
-######################################################################
-## get number of pages of input file
-######################################################################
-## for this we make a copy of input file, to avoid problem with
-## ghostscript not correctly handling filenames containing white spaces
-## (see https://stackoverflow.com/questions/42578061/ghostscript-and-spaces-in-filenames)
-cp "$file" $inputfilename.pdf
-myecho 2+ "-> computing number of pages";
-myecho 2+ " * $GS $GSOPTFILE -sDEVICE=bbox -dNOPAUSE -dQUIET -c \"($inputfilename.pdf) (r) file runpdfbegin pdfpagecount = quit\""
-nbp=`$GS $GSOPTFILE -sDEVICE=bbox -dNOPAUSE -dQUIET -c "($inputfilename.pdf) (r) file runpdfbegin pdfpagecount = quit"`
-myecho 2+ " File \"$file\" has $nbp pages";
-
-
-## now we can deal with ranges of pages (INCLUDE_FOR_BBOX, EXCLUDE_FOR_BBOX, PAGES)
-## cleancslor uses $nbp, so we have to compute this before
-declare -i nbpages;
-if [[ ${INCLUDE_FOR_BBOX} != "" ]]; then
- INCLUDE_FOR_BBOX=${INCLUDE_FOR_BBOX%,};
- cleancslor $INCLUDE_FOR_BBOX;
- INCLUDE_FOR_BBOX=${result%,};
- myecho 3+ " * use for bounding-box computation: "${INCLUDE_FOR_BBOX};
-else
- if [[ ${PAGES} != "" ]]; then
- INCLUDE_FOR_BBOX=${PAGES%,};
- cleancslor $INCLUDE_FOR_BBOX;
- INCLUDE_FOR_BBOX=${result%,};
- myecho 3+ " * use for bounding-box computation: "${INCLUDE_FOR_BBOX};
- else
- INCLUDE_FOR_BBOX=$dfpdfxupINCLUDE_FOR_BBOX;
- fi
-fi
-if [[ ${EXCLUDE_FOR_BBOX} != "" ]]; then
- EXCLUDE_FOR_BBOX=${EXCLUDE_FOR_BBOX%,};
- cleancslor $EXCLUDE_FOR_BBOX;
- EXCLUDE_FOR_BBOX=${result%,};
- myecho 3+ " * exclude from bounding-box computation: "${EXCLUDE_FOR_BBOX};
-else
- EXCLUDE_FOR_BBOX=$dfpdfxupEXCLUDE_FOR_BBOX;
-fi
-if [[ ${PAGES} != "" ]]; then
- PAGES=${PAGES%,};
-else
- PAGES=$dfpdfxupPAGES;
-fi
-nbpages=0;
-cleancslor $PAGES;
-PAGES=${result%,};
-myecho 2+ " * pages to display: ${PAGES} (${nbpages} pages)";
-if [[ $nbpages -le 0 ]]; then
- myecho 1+ " No pages to include. Aborting."
- exit 0;
-fi
-
-######################################################################
-## set up some variables
-######################################################################
-## clipping option
-if [[ $CLIP != 0 ]]; then
- myecho 2+ " clipping pages (anything outside bounding box will be dropped)";
- CLIPOPT=",clip";
-else
- myecho 2+ " not clipping pages (anything outside bounding box will be displayed)";
- myecho 2+ " (pages may overlap)";
- CLIPOPT="";
-fi
-
-
-## whether the frame should be tight around pages, or loose (use all width)
-if [[ $TIGHT_FRAME -eq 1 ]]; then
- TIGHT_FRAMEBOX="\fbox";
- WIDE_FRAMEBOX="";
-else
- TIGHT_FRAMEBOX="";
- WIDE_FRAMEBOX="\fbox";
-fi
-
-## special case: if booklet, we force the numbers of rows and cols
-if [[ $BOOKLET != 0 ]]; then
- if [[ $NB_COLUMNS != 2 || $NB_ROWS != 1 || $LANDSCAPE == 0 ]]; then
- myecho 1+ " forcing booklet mode: 2 columns, 1 row, landscape mode";
- NB_COLUMNS=2; NB_ROWS=1; LANDSCAPE=1;
- fi
-fi
-
-
-
-## check watermarking file
-nbwp=1; ## set even if no watemark
-if [[ $WATERMARK_FILE != "" ]]; then
- if [[ ! -e $WATERMARK_FILE ]]; then
- myecho 1+ " pdfxup: watermarking file not found. Omiting watermarking."
- else
- myecho 2+ " * using file $WATERMARK_FILE for watermarking";
- fi
-fi
-
-## get number of pages of WATERMARK_FILE (PDF) file
-if [[ $WATERMARK_FILE != "" ]]; then
- if [[ -e $WATERMARK_FILE ]]; then
- if [[ `file -b $WATERMARK_FILE | grep "PDF"` ]]; then
- ## copy file in case it contains spaces
- cp "$WATERMARK_FILE" $watermarkfilename.pdf
- nbwp=`$GS $GSOPTWATERMARK -sDEVICE=bbox -dNOPAUSE -dQUIET -c "($watermarkfilename.pdf) (r) file runpdfbegin pdfpagecount = quit"`
- if [[ $WATERMARK_PERIOD -gt $nbwp || $WATERMARK_PERIOD -lt 1 ]]; then
- WATERMARK_PERIOD=$nbwp;
- fi
- fi
- fi
-fi
-
-
-######################################################################
-## start computing bounding box
-######################################################################
-x=$x0
-y=$y0
-w=$w0
-h=$h0
-curr=0
-page=0
-step=0
-
-
-if [[ $KEEP_ORIG_BBOX == 0 ]]; then
- if [[ $SBB == 0 ]]; then
- myecho 1+ -n "-> computing bounding box";
- myecho 2+ "";
-
- for r in ${INCLUDE_FOR_BBOX//,/$IFS};
- do
- case $r in
- +([0-9]))
- first=$r;
- last=$r;;
- -+([0-9]))
- first=1;
- last=`echo $r|tr -d -`;;
- +([0-9])-)
- first=`echo $r|tr -d -`;
- last=$nbp;;
- +([0-9])-+([0-9]))
- first=`echo $r|cut -d- -f1`;
- last=`echo $r|cut -d- -f2`;;
- -)
- first=1;
- last=$nbp;;
- esac
- myecho 2+ " * $GS -dNOPAUSE -dSAFER -dQUIET -dBATCH -dFirstPage=$first -dLastPage=$last -sDEVICE=bbox $inputfilename.pdf"
- $GS -dNOPAUSE -dSAFER -dQUIET -dBATCH -dFirstPage=$first -dLastPage=$last -sDEVICE=bbox $inputfilename.pdf 2>&1 |
- while IFS= read -r line; do
- bbox=`echo $line | grep "%%BoundingBox" | sed "s/^.*Box: //"`;
- if [[ $bbox != "" ]]; then
- for i in `echo $line | grep "%%BoundingBox" | sed "s/^.*Box: //"`; do
- if [[ $curr == 0 ]]; then
- eval page=$(( page+1 ));
- fi
- case $curr in
- 0)
- thisx=$i;
- #if [[ $x -gt $i ]]; then x=$i; fi
- ;;
- 1)
- thisy=$i;
- #if [[ $y -gt $i ]]; then y=$i; fi
- ;;
- 2)
- thisw=$i;
- #if [[ $w -lt $i ]]; then w=$i; fi
- ;;
- 3)
- thish=$i;
- #if [[ $h -lt $i ]]; then h=$i; fi
- ifinrangelist $page $EXCLUDE_FOR_BBOX;
- if [ $in == 0 ]; then
- eval step=$(( step+1 ));
- if [[ $x -lt 0 || $x -gt $thisx && $thisx+$thisw -gt 0 ]]; then x=$thisx; fi
- if [[ $y -lt 0 || $y -gt $thisy && $thisy+$thish -gt 0 ]]; then y=$thisy; fi
- if [[ $w -lt 0 || $w -lt $thisw && $thisx+$thisw -gt 0 ]]; then w=$thisw; fi
- if [[ $h -lt 0 || $h -lt $thish && $thisy+$thish -gt 0 ]]; then h=$thish; fi
- myecho 1 -n "."
- myecho 2 -ne " bbox: x=$x y=$y X=$w Y=$h (step $step) \\r";
- myecho 3+ " bbox: x=$x y=$y X=$w Y=$h (step $step) ";
- fi
- ;;
- esac
- eval curr=$(( (curr+1) % 4 ));
- done
- fi
- done;
- done;
- myecho 2- "";
- else
- x=$BBX;
- y=$BBY;
- w=$BBW;
- h=$BBH;
- fi
-fi
-
-
-EMPTYBB=$KEEP_ORIG_BBOX;
-if [[ $KEEP_ORIG_BBOX == 0 && $x -eq $x0 &&
- $y -eq $y0 &&
- $h -eq $h0 &&
- $w -eq $w0 ]]; then
- myecho 1+ " * empty bounding box; keeping original margins";
- EMPTYBB=1;
- #exit 1;
-fi
-
-if [[ $SINCLUDE_FOR_BBOX == 0 && $EMPTYBB == 0 ]]; then
- myecho 1 -n "."
- myecho 2+ -ne " bbox: x=$x y=$y X=$w Y=$h (final) \\r";
- myecho 3+ "";
- myecho 3+ -ne " (processed $page pages) \\r";
- myecho 1+ "";
-fi
-
-if [[ $COMPUTE_BBOX_ONLY != 0 ]]; then
- myecho 1+ " final bounding box: x=$x y=$y X=$w Y=$h";
- cleanup;
- exit 0;
-fi
-
-
-
-## compute options to pass to \includegraphics
-#INNER_HMARGIN=${INNER_HMARGIN%pt};
-#INNER_VMARGIN=${INNER_VMARGIN%pt};
-if [[ $EMPTYBB -eq 0 ]]; then
-# eval x=$((x-INNER_HMARGIN))
-# eval y=$((y-INNER_VMARGIN))
-# eval w=$((w+INNER_HMARGIN))
-# eval h=$((h+INNER_VMARGIN))
- BBOPTION="viewport=$x $y $w $h";
-else
-# BBOPTION="trim=-$INNER_HMARGIN -$INNER_VMARGIN -$INNER_HMARGIN -$INNER_VMARGIN";
- BBOPTION="trim=0 0 0 0";
-fi
-
-######################################################################
-## start writing .tex file
-######################################################################
-cat > $filename.tex <<EOF
- \newif\ifbooklet
- \newif\iflongedge
-EOF
-case $BOOKLET in
- 0)
- echo " \bookletfalse" >> $filename.tex;;
- se)
- echo " \booklettrue" >> $filename.tex
- echo " \longedgefalse" >> $filename.tex;;
- *)
- echo " \booklettrue" >> $filename.tex
- echo " \longedgetrue" >> $filename.tex;;
-esac
-
-cat >> $filename.tex <<EOF
- \def\pdfxupfile{$inputfilename.pdf}
- \def\pdfxuppagelist{$PAGES}
- \def\pdfxupoutputpaper{$PAPERSIZE}
- \def\pdfxupoutputlandscape{$LANDSCAPE}
- \def\pdfxupnbhoriz{$NB_COLUMNS}
- \def\pdfxupnbvert{$NB_ROWS}
- \def\pdfxupnbpages{$nbpages}
- \def\pdfxupvmargin{$VMARGIN}
- \def\pdfxuphmargin{$HMARGIN}
- \def\pdfxupinnervmargin{$INNER_VMARGIN}
- \def\pdfxupinnerhmargin{$INNER_HMARGIN}
- \def\pdfxupintermvspace{$INTERM_VSPACE}
- \def\pdfxupintermhspace{$INTERM_HSPACE}
- \def\pdfxupframewidth{$FRAME_WIDTH}
- \def\pdfxupemptybb{$EMPTYBB}
- \def\pdfxupx{$x}
- \def\pdfxupy{$y}
- \def\pdfxupw{$w}
- \def\pdfxuph{$h}
- \def\pdfxupfilename{$filename}
- \def\pdfxupwatermark{$WATERMARK_FILE}
- \def\pdfxupnbwp{$nbwp}
- \def\pdfxupwperiod{$WATERMARK_PERIOD}
- \def\pdfxupclipopt{$CLIPOPT}
- \def\pdfxupwidefbox{$WIDE_FRAMEBOX}
- \def\pdfxuptightfbox{$TIGHT_FRAMEBOX}
- \def\pdfxupbbox{$BBOPTION}
-
- \input{pdfxup-template}
-
-EOF
-
-######################################################################
-## produce PDF output
-######################################################################
-myecho 1+ "-> producing final file";
-case $VERBOSITY in
- 0|1|2)
- myecho 2+ " * $PDFLATEX -interaction=nonstopmode $filename.tex"
- $PDFLATEX -interaction=batchmode $filename.tex > /dev/null 2>&1 || \
- LATEXFAILED=1;;
- *)
- myecho 3+ " * $PDFLATEX -interaction=nonstopmode $filename.tex"
- $PDFLATEX -interaction=nonstopmode $filename.tex || LATEXFAILED=1;;
-esac
-
-######################################################################
-## clean up
-######################################################################
-if [[ $LATEXFAILED -eq 1 ]]; then
- myecho 1+ "$PDFLATEX: compilation failed!"
- myecho 1+ "Use option '-d' to get and analyse failing file."
- cleanup
- exit 0;
-fi
-if [[ $EMPTYBB -eq 0 ]]; then
- myecho 0+ " final scale: "`cat $filename.scl | sed -e "s/pt$//"`"%"
-fi
-if [[ $SILENTLY_OVERWRITE -eq 1 ]]; then
- myecho 2+ " * mv $MVopt $filename.pdf \"$OUTPUTFILE\""
- mv $MVopt $filename.pdf "$OUTPUTFILE"
-else
- myecho 2+ " * mv $MVopt -i $filename.pdf \"$OUTPUTFILE\""
- mv $MVopt -i $filename.pdf "$OUTPUTFILE"
-fi
-cleanup
-exit 0
-
-
-
-
-
-
-
-##################################################################
-##
-## Manual
-##
-##################################################################
-pdfxup creates a PDF document where each page is obtained by
-combining several pages of a PDF file given as output. The
-important feature of pdfxup, compared to similar programs,
-is that it tries to compute the (global) bounding box of the
-input PDF file, in order to remove the margins and to keep
-the text only. Instead of having the font size divided by 2
-(for the case of 2-up output), in some case you may end up
-with the same font size as in the original document (as is
-the case for a default 'article' document produced by LaTeX).
-
-pdfxup has numerous options:
- * '-x n' and '-y n' can be used to change the number of
- rows and columns of the resulting document.
- [default: -x2 -y1]
- * '-l n' turns the output to landscape (n=1) or portrait
- (n=0).
- [default: -l1]
- * '-b n' toggles the 'booklet' mode: the resulting PDF can
- be printed and folded as a booklet. Printing such a
- booklet requires 2-sided printing, which can follow
- either the 'long-edge' or the 'short edge' of the paper.
- 'long-edge' seems to be the most commonly used, but using
- '-b se' while produce a PDF booklet for 'short-edge'
- 2-sided printing.
- * '-c' clips pages to their bounding box: this is set by
- default, so that any content outside bounding box will be
- lost. Using "-c 0", anything outside the bounding box will
- be displayed, and may overlap neighbouring pages.
- * '-p' can be used to only consider a set of pages of the
- input file. The set of pages to include is a comma-
- separated list of pages, ranges of pages of the form
- 'm-n', or sets of pages of the form "0%2" (all even-
- numbered pages). Alternatively to '-p', the page range
- can be specified after the file name, writing
- 'file.pdf:<list>' in place of '-p <list>'.
- * '-bb' can be used to list the pages to be taken into
- account when computing the bounding box. This is
- especially useful for large documents, because computing the
- bounding box on each page can be long, and because
- computing the bounding box over the first 10 pages is
- usually enough... This will not change the number of pages
- included in the final document.
- Several '-bb' options can be given, which will result in
- considering the union of all the intervals.
- * '-nobb' is used to remove pages from the computation of
- the bounding box. This is useful if one page has e.g.
- special headers (e.g. for arXiv papers). Notice that the
- bounding box of those pages will still be computed by
- ghostscript, so this does not save time. I'd be grateful
- to anyone willing to implement difference of unions of
- intervals... ;-)
- * '-fw d' defines the width of the frame around each page.
- Set to 0pt to have no frame at all.
- * inner margins: margins to be added between each frame and
- its included page.
- * margins: margins of the final document
- * spacing: spacing between frames
- * '-w file' can be used to add watermarking to all pages. The
- file can be anything that pdflatex can handle (eg. png, pdf).
- If it is a PDF with several pages, page n of the watermarking
- file will be used with page n of the input file. By default,
- the last page will be repeated if the input file has more
- pages than the watermarking file. This behaviour can be
- modified with the '-wp n' options, which asks to repeat the
- last n pages instead of only the last one. Setting `-wp 0`
- will repeat all the pages of the watermarking file.
-
-##################################################################
-##
-## Examples
-##
-##################################################################
-
-# pdfxup file.pdf
- -> creates pdfxup.pdf from file.pdf with default options
- (2-up, margins=5pt)
-# pdfxup -bb 1-4 file.pdf
- -> same behaviour, but computes the bounding box only using the
- first 4 pages
- (this saves time when processing long documents)
-# pdfxup -b file.pdf
- -> same behaviour, but creates a booklet
-# pdfxup -kbb -b -o booklet.pdf file.pdf:3-25
- -> creates a booklet from pages 3-25 of file.pdf, without
- reducing margins (option '-kbb' disables bounding-box
- computation; equivalent to e.g. '-bb 0');
- name the resulting file booklet.pdf.
-# pdfxup -kbb -x1 -y2 -l0 beamer-frames.pdf
- -> arranges 2 beamer frames per page (not reducing margins)
-# pdfxup -kbb -x2 -y2 -l1 beamer-frames.pdf
- -> arranges 4 beamer frames per page (not reducing margins)
-# pdfxup -fw0 -w draft.png file.pdf
- -> remove frame border; add 'draft' watermarking on all pages
-
-##################################################################
-##
-## Releases
-##
-##################################################################
-Author: Nicolas Markey
-Please send your comments to <pdfxup@markey.fr>
-
-v1.00 (2015/08/23)
- - first release
-
-v1.10 (2015/09/08)
- - added option 'booklet'
- - corrected numerous computation/spacing bugs in LaTeX file
- - added succinct documentation
-
-v1.20 (2015/09/11)
- - added options -nobb, -bb, -p
- - solved bug with dots in PDF file names
-
-v1.30 (2015/10/06)
- - added options -g and -s for getting and then manually
- - setting bounding box.
- - created man page
-
-v1.50 (2019/12/31)
- - added the -c option (to clip pages)
- - corrected + improved option -p
- - added watermarking
-
-v1.51 (2020/01/06)
- - corrected bug in dimtopt() (conversion mm to pt)
-
-v1.60 (2020/06/24)
- - added --allow-file-read=... option for ghostscript >= 9.28
- (thanks to Janis Kalofolias for pointing out the problem)
- - allow file names containing spaces
- - better inclusion of watermarks
-
-v1.61 (2020/10/21)
- - clean up after option '-g' (thanks to Oliver Redner)
-
-v2.00 (2020/12/17)
- - fixed a bug with inner margins
- - added --tight-frame option: tells whether the frame should
- be tight around the page (and leave horizontal white space
- outside the frame), or as large as possible.
- - added --config-file option: configuration files (default
- extension .xup) can be used to define default values
- for frequent situations.
- - cleaned-up man page, adding some missing options (thanks
- to Louis Gostiaux for pointing undocumented options)
diff --git a/Build/source/texk/texlive/linked_scripts/pedigree-perl/pedigree.pl b/Build/source/texk/texlive/linked_scripts/pedigree-perl/pedigree.pl
deleted file mode 100755
index 209c3131bed..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pedigree-perl/pedigree.pl
+++ /dev/null
@@ -1,544 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright (C) 2006-2012 Boris Veytsman & Leila Akhmadeeva
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-#
-#
-=pod
-
-=head1 NAME
-
-pedigree - create a TeX file for pedigree from a csv file
-
-=head1 SYNOPSIS
-
-B<pedigree> [-c I<configuration_file>] [-d] [-o I<output_file>] [-s I<start_id>] I<input_file>
-
-B<pedigree> -v
-
-=head1 DESCRIPTION
-
-The program converts a comma separated I<input_file> into a TeX file
-with pst-pdgr macros.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-c> I<configuration_file>
-
-The configuration file to read along with the system-wide and user's
-configuration files
-
-=item B<-d>
-
-Debug mode on
-
-=item B<-o> -I<output_file>
-
-The ouput file instead of I<input_file.tex>
-
-=item B<-s> -I<start_id>
-
-If this option is selected, the pedigree is constructed starting from
-the node with the Id i<start_id>. Otherwise it is started from the
-proband node.
-
-This option allows to create pedigrees with multiple probands or absent
-probands, or show people who are not proband's relatives.
-
-=item B<-v>
-
-Print version information
-
-=back
-
-=head1 FILES
-
-=over 4
-
-=item B</etc/pedigree.cfg>
-
-Global configuration file
-
-=item B<$HOME/.pedigreerc>
-
-User configuration file
-
-=back
-
-=head1 SEE ALSO
-
-The manual distributed with this program describes the format of the
-configuration file and the input file.
-
-The library functions are described in Pedigree::Language(3),
-Pedigree::Parser(3), Pedigree::Node(3), Pedigree::PersonNode(3),
-Pedigree::MarriageNode(3), Pedigree::Area(3).
-
-=head1 AUTHOR
-
-Boris Veytsman, Leila Akhmadeeva, 2006-2012
-
-
-=cut
-
-
-#########################################################
-# Packages and Options #
-#########################################################
-
-use strict;
-use vars qw($opt_c $opt_d $opt_o $opt_s $opt_v);
-
-our $TLCONF; # TL config file
-our $TLCONFLOCAL; # TL local config file
-
-BEGIN {
- # find files relative to our installed location within TeX Live
- chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
- if (length($TLMaster)) {
- unshift @INC, "$TLMaster/texmf-dist/scripts/pedigree-perl";
- $TLCONF = "$TLMaster/texmf-config/pedigree/pedigree.cfg";
- chomp($TLCONFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`);
- $TLCONFLOCAL .= "/pedigree/pedigree.cfg";
- }
-}
-
-use Getopt::Std;
-use FileHandle;
-use Pedigree;
-
-#########################################################
-# Options Reading and Global Variables #
-#########################################################
-
-my $USAGE="Usage: $0 [-c configuration_file] [-d] [-o output_file] [-s start_id] input_file\n";
-my $COPYRIGHT=<<END;
-$0 Version 1.0, April 2012
-
-Copyright (C) 2006-2012 Boris Veytsman & Leila Akhmadeeva
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330,
-END
-
-my $GLOBALCONF="/etc/pedigree.cfg";
-
-my $USERCONF="$ENV{HOME}/.pedigreerc";
-
-
-our $IN = new FileHandle;
-our $OUT = new FileHandle;
-
-getopts('c:do:s:v') or die $USAGE;
-
-if ($opt_v) {
- die $COPYRIGHT;
-}
-
-our $DEBUG = $opt_d ||0;
-
-if (scalar @ARGV != 1) {
- die $USAGE;
-}
-
-our $start_id = $opt_s;
-
-#########################################################
-# Opening Files #
-#########################################################
-
-
-if ($ARGV[0] eq '-') {
- $IN->fdopen(fileno(STDIN),"r");
-} else {
- $IN->open($ARGV[0], "r") or die "Cannot read from $ARGV[0]\n";
-}
-
-my $outfile=$ARGV[0];
-if ($opt_o) {
- $outfile = $opt_o;
-} else {
- $outfile =~ s/\.[^\.]*$/.tex/;
-}
-if ($outfile eq '-') {
- $OUT->fdopen(fileno(STDOUT),"w");
-} else {
- $OUT->open($outfile, "w") or die "Cannot write to $outfile\n";
-}
-
-#########################################################
-# Configuration #
-#########################################################
-
-#
-# First, the defaults. Even if we do not find any
-# configuration file, these will work.
-#
-
-
-#
-# Do we want to have a full LaTeX file or just a fragment?
-#
-our $fulldoc=1;
-
-#
-# What kind of document do we want
-#
-# our $documentheader='\documentclass[landscape]{article}';
-our $documentheader='\documentclass{article}';
-
-#
-# Define additional packages here
-#
-# our $addtopreamble=<<END;
-# \\usepackage{graphics}
-# END
-our $addtopreamble=<<END;
-\\psset{descarmA=1}
-END
-
-
-
-#
-# Do we want to print a legend?
-#
-our $printlegend=1;
-
-#
-# Fields to include in the legend. Delete Name for privacy
-# protection.
-#
-our @fieldsforlegend = qw(Name DoB AgeAtDeath Comment);
-
-#
-# Fields to put at the node. Delete Name for privacy
-# protection.
-#
-our @fieldsforchart = qw(Name);
-
-#
-# Language
-#
-# our $language="russian";
-our $language="english";
-
-#
-# Override the encoding
-#
-# our $encoding="koi8-r";
-
-our $encoding;
-
-#
-# descarmA
-#
-our $descarmA = 0.8;
-
-#
-# Fonts for nodes
-#
-our $belowtextfont='\small';
-our $abovetextfont='\scriptsize';
-
-#
-# Distances between nodes (in cm)
-#
-our $xdist=2;
-our $ydist=2;
-
-#
-# Maximal width and height of the pedigree in cm.
-# Set this to 0 to switch off scaling
-#
-our $maxW = 15;
-our $maxH = 19;
-
-#
-# Whether to rotate the page. The values are 'yes', 'no' and 'maybe'
-# If 'maybe' is chosen, the pedigree is rotated if it allows better
-# scaling
-#
-our $rotate = 'maybe';
-
-#
-# Read the global configuration file(s)
-#
-foreach my $conffile ($GLOBALCONF, $TLCONF, $TLCONFLOCAL) {
- if (-r $conffile) {
- if ($DEBUG) {
- print STDERR "Reading global configuration file $conffile\n";
- }
- require "$conffile";
- } else {
- if ($DEBUG) {
- print STDERR "Cannot find global configuration file $conffile; going without it\n";
- }
- }
-}
-
-#
-# Read the user configuration file
-#
-if (-r $USERCONF) {
- if ($DEBUG) {
- print STDERR "Reading user configuration file $USERCONF\n";
- }
- require "$USERCONF";
-} else {
- if ($DEBUG) {
- print STDERR "Cannot find user configuration file $USERCONF; going without it\n";
- }
-}
-
-#
-# Read the option configuration file
-#
-if ($opt_c) {
- if (-r $opt_c) {
- if ($DEBUG) {
- print STDERR "Reading optional configuration file $opt_c\n";
- }
- require "$opt_c";
- } else {
- die "Cannot find $opt_c\n";
- }
-}
-
-#########################################################
-# Setting up #
-#########################################################
-
-my $lang = new Pedigree::Language($language, $encoding);
-$_=<$IN>;
-my $parser = new Pedigree::Parser($_,$lang);
-my $start;
-
-#########################################################
-# Reading input #
-#########################################################
-
-while (<$IN>) {
- my $node = Pedigree->MakeNode($parser->Parse($_));
- if (ref($node)) {
- if ($start_id) {
- if ($start_id eq $node->Id()) {
- $start = $node;
- if ($DEBUG) {
- print STDERR "Found start: ", $start->Id(), "\n";
- }
- }
- } else {
- if ($node->isProband()) {
- if (ref($start)) {
- print STDERR "Two probands? I got ", $start->Id(),
- " and ", $node->Id(), "\n";
- }
- $start=$node;
- if ($DEBUG) {
- print STDERR "Found proband: ", $start->Id(), "\n";
- }
- }
- }
- }
-}
-
-if (!ref($start)) {
- die "Cannot find the start!\n";
-}
-
-#########################################################
-# Process Pedigree #
-#########################################################
-
-#
-# Check all parents
-#
-$start->CheckAllParents();
-
-
-#
-# The root is the root of the tree to which the proband
-# belongs
-#
-
-my ($root, undef)=@{$start->FindRoot(0)};
-if ($DEBUG) {
- print STDERR "Root: ", $root->Id(), "\n";
-}
-
-#
-# Calculate relative coordinates
-#
-$root->SetRelX(0);
-$root->SetRelY(0);
-$root->SetArea();
-
-#
-# Calculate the absolute coordinates
-#
-$root->CalcAbsCoor(0,0);
-
-#
-# Check for consanguinic marriages
-#
-$root->AddConsanguinicMarriages();
-
-#
-# And twins
-#
-$root->AddTwins($ydist);
-
-#
-# Get the frame
-#
-my ($xmin, $ymin, $xmax, $ymax) = @{$root->SetFrame($xdist, $ydist)};
-
-
-
-#########################################################
-# Printing headers #
-#########################################################
-
-if ($fulldoc) {
- printheader($OUT,$lang,$addtopreamble);
-}
-
-#########################################################
-# Calculate scale and check whether to rotate #
-#########################################################
-
-my $scale=1;
-my $scaleRotated = 1;
-
-if ($maxH && $maxW) {
- if ($maxH/($ymax-$ymin) < $scale) {
- $scale = $maxH/($ymax-$ymin);
- }
- if ($maxW/($xmax-$xmin) < $scale) {
- $scale = $maxW/($xmax-$xmin);
- }
- if ($maxW/($ymax-$ymin) < $scaleRotated) {
- $scaleRotated = $maxW/($ymax-$ymin);
- }
- if ($maxH/($xmax-$xmin) < $scaleRotated) {
- $scaleRotated = $maxH/($xmax-$xmin);
- }
-}
-
-my $doRotate = ($rotate =~ /yes/i) || (($rotate =~ /maybe/i) &&
- ($scaleRotated > $scale));
-
-#########################################################
-# Printing pspicture #
-#########################################################
-
-my $pre;
-my $post ='}'."\n";
-
-if ($doRotate) {
- $descarmA *= $scaleRotated;
- $pre="\\rotatebox{90}{%\n\\psset{descarmA=$descarmA}%\n";
- if ($scaleRotated<1) {
- $pre .= '\psset{unit='.$scaleRotated.'}%'."\n";
- }
-} else {
- $descarmA *= $scale;
- $pre="{%\n\\psset{descarmA=$descarmA}%\n";
- if ($scale<1) {
- $pre .= '{\psset{unit='.$scale.'}%'."\n";
- }
-}
-
-print $OUT $pre;
-
-print $OUT '\begin{pspicture}',"($xmin,$ymin)($xmax,$ymax)\n";
-
-print $OUT $root->DrawAll($xdist, $ydist, $belowtextfont,
- $abovetextfont, @fieldsforchart);
-
-print $OUT '\end{pspicture}%',"\n";
-
-print $OUT $post;
-
-#########################################################
-# Printing legend #
-#########################################################
-
-
-if ($printlegend) {
- print $OUT $root->PrintAllLegends($lang, @fieldsforlegend);
-}
-
-#########################################################
-# Printing end #
-#########################################################
-
-
-if ($fulldoc) {
- printend($OUT);
-}
-
-#########################################################
-# Exiting #
-#########################################################
-
-exit 0;
-
-#########################################################
-# Subroutines #
-#########################################################
-
-#
-# Printing headers & footers
-#
-
-sub printheader {
- my ($OUT,$lang,$addtopreamble)=@_;
- print $OUT <<END;
-$documentheader
-\\usepackage{pst-pdgr}
-END
-
- print $OUT $lang->Header;
- print $OUT <<END;
-$addtopreamble
-\\begin{document}
-END
- return 0;
-}
-
-
-sub printend {
- my $OUT=shift;
- print $OUT "\\end{document}\n";
- return 0;
-}
-
-
diff --git a/Build/source/texk/texlive/linked_scripts/perltex/perltex.pl b/Build/source/texk/texlive/linked_scripts/perltex/perltex.pl
deleted file mode 100755
index 3f62031e75c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/perltex/perltex.pl
+++ /dev/null
@@ -1,503 +0,0 @@
-#! /usr/bin/env perl
-
-###########################################################
-# Prepare a LaTeX run for two-way communication with Perl #
-# By Scott Pakin <scott+pt@pakin.org> #
-###########################################################
-
-#-------------------------------------------------------------------
-# This is file `perltex.pl',
-# generated with the docstrip utility.
-#
-# The original source files were:
-#
-# perltex.dtx (with options: `perltex')
-#
-# This is a generated file.
-#
-# Copyright (C) 2003-2019 Scott Pakin <scott+pt@pakin.org>
-#
-# This file may be distributed and/or modified under the conditions
-# of the LaTeX Project Public License, either version 1.3c of this
-# license or (at your option) any later version. The latest
-# version of this license is in:
-#
-# http://www.latex-project.org/lppl.txt
-#
-# and version 1.3c or later is part of all distributions of LaTeX
-# version 2006/05/20 or later.
-#-------------------------------------------------------------------
-
-sub top_level_eval ($)
-{
- return eval $_[0];
-}
-use Safe;
-use Opcode;
-use Getopt::Long;
-use Pod::Usage;
-use File::Basename;
-use Fcntl;
-use POSIX;
-use File::Spec;
-use IO::Handle;
-use warnings;
-use strict;
-my $latexprog;
-my $runsafely = 1;
-my @permittedops;
-my $usepipe = 1;
-my $progname = basename $0;
-my $jobname = "texput";
-my $toperl;
-my $fromperl;
-my $toflag;
-my $fromflag;
-my $doneflag;
-my $logfile;
-my $pipe;
-my @latexcmdline;
-my $styfile;
-my @macroexpansions;
-my $sandbox = new Safe;
-my $sandbox_eval;
-my $latexpid;
-my $pipestring = "\%\%\%\%\% Generated by $progname\n\\endinput\n";
-$latexprog = $ENV{"PERLTEX"} || "latex";
-Getopt::Long::Configure("require_order", "pass_through");
-GetOptions("help" => sub {pod2usage(-verbose => 1)},
- "latex=s" => \$latexprog,
- "safe!" => \$runsafely,
- "pipe!" => \$usepipe,
- "synctext=s" => \$pipestring,
- "makesty" => sub {$styfile = "noperltex.sty"},
- "permit=s" => \@permittedops) || pod2usage(2);
-@latexcmdline = @ARGV;
-my $firstcmd = 0;
-for ($firstcmd=0; $firstcmd<=$#latexcmdline; $firstcmd++) {
- my $option = $latexcmdline[$firstcmd];
- next if substr($option, 0, 1) eq "-";
- if (substr ($option, 0, 1) ne "\\") {
- $jobname = basename $option, ".tex" ;
- $latexcmdline[$firstcmd] = "\\input $option";
- }
- last;
-}
-push @latexcmdline, "" if $#latexcmdline==-1;
-my $separator = "";
-foreach (1 .. 20) {
- $separator .= chr(ord("A") + rand(26));
-}
-$toperl = $jobname . ".topl";
-$fromperl = $jobname . ".frpl";
-$toflag = $jobname . ".tfpl";
-$fromflag = $jobname . ".ffpl";
-$doneflag = $jobname . ".dfpl";
-$logfile = $jobname . ".lgpl";
-$pipe = $jobname . ".pipe";
-$latexcmdline[$firstcmd] =
- sprintf '\makeatletter' . '\def%s{%s}' x 7 . '\makeatother%s',
- '\plmac@tag', $separator,
- '\plmac@tofile', $toperl,
- '\plmac@fromfile', $fromperl,
- '\plmac@toflag', $toflag,
- '\plmac@fromflag', $fromflag,
- '\plmac@doneflag', $doneflag,
- '\plmac@pipe', $pipe,
- $latexcmdline[$firstcmd];
-$toperl = File::Spec->rel2abs($toperl);
-$fromperl = File::Spec->rel2abs($fromperl);
-$toflag = File::Spec->rel2abs($toflag);
-$fromflag = File::Spec->rel2abs($fromflag);
-$doneflag = File::Spec->rel2abs($doneflag);
-$logfile = File::Spec->rel2abs($logfile);
-$pipe = File::Spec->rel2abs($pipe);
-$SIG{"ALRM"} = sub {
- undef $latexpid;
- exit 0;
-};
-$SIG{"PIPE"} = "IGNORE";
-sub delete_files (@)
-{
- foreach my $filename (@_) {
- unlink $filename;
- while (-e $filename) {
- unlink $filename;
- sleep 0;
- }
- }
-}
-sub awaitexists ($)
-{
- while (!-e $_[0]) {
- sleep 0;
- if (waitpid($latexpid, &WNOHANG)==-1) {
- delete_files($toperl, $fromperl, $toflag,
- $fromflag, $doneflag, $pipe);
- undef $latexpid;
- exit 0;
- }
- }
-}
-delete_files($toperl, $fromperl, $toflag, $fromflag, $doneflag, $pipe);
-open (LOGFILE, ">$logfile") || die "open(\"$logfile\"): $!\n";
-autoflush LOGFILE 1;
-if (defined $styfile) {
- open (STYFILE, ">$styfile") || die "open(\"$styfile\"): $!\n";
-}
-if (!$usepipe || !eval {mkfifo($pipe, 0600)}) {
- sysopen PIPE, $pipe, O_WRONLY|O_CREAT, 0755;
- autoflush PIPE 1;
- print PIPE $pipestring;
- close PIPE;
- $usepipe = 0;
-}
-defined ($latexpid = fork) || die "fork: $!\n";
-unshift @latexcmdline, $latexprog;
-if (!$latexpid) {
- exec {$latexcmdline[0]} @latexcmdline;
- die "exec('@latexcmdline'): $!\n";
-}
-if ($runsafely) {
- @permittedops=(":browse") if $#permittedops==-1;
- $sandbox->permit_only (@permittedops);
- $sandbox_eval = sub {$sandbox->reval($_[0])};
-}
-else {
- $sandbox_eval = \&top_level_eval;
-}
-while (1) {
- awaitexists($toflag);
- my $entirefile;
- {
- local $/ = undef;
- open (TOPERL, "<$toperl") || die "open($toperl): $!\n";
- $entirefile = <TOPERL>;
- close TOPERL;
- }
- $entirefile =~ s/\r//g;
- my ($optag, $macroname, @otherstuff) =
- map {chomp; $_} split "$separator\n", $entirefile;
- $macroname =~ s/^[^A-Za-z]+//;
- $macroname =~ s/\W/_/g;
- $macroname = "latex_" . $macroname;
- if ($optag eq "USE") {
- foreach (@otherstuff) {
- s/\\/\\\\/g;
- s/\'/\\\'/g;
- $_ = "'$_'";
- }
- }
- my $perlcode;
- if ($optag eq "DEF") {
- $perlcode =
- sprintf "sub %s {%s}\n",
- $macroname, $otherstuff[0];
- }
- elsif ($optag eq "USE") {
- $perlcode = sprintf "%s (%s);\n", $macroname, join(", ", @otherstuff);
- }
- elsif ($optag eq "RUN") {
- $perlcode = $otherstuff[0];
- }
- else {
- die "${progname}: Internal error -- unexpected operation tag \"$optag\"\n";
- }
- print LOGFILE "#" x 31, " PERL CODE ", "#" x 32, "\n";
- print LOGFILE $perlcode, "\n";
- undef $_;
- my $result;
- {
- my $warningmsg;
- local $SIG{__WARN__} =
- sub {chomp ($warningmsg=$_[0]); return 0};
- $result = $sandbox_eval->($perlcode);
- if (defined $warningmsg) {
- $warningmsg =~ s/at \(eval \d+\) line \d+\W+//;
- print LOGFILE "# ===> $warningmsg\n\n";
- }
- }
- $result = "" if !$result || $optag eq "RUN";
- if ($@) {
- my $msg = $@;
- $msg =~ s/at \(eval \d+\) line \d+\W+//;
- $msg =~ s/\n/\\MessageBreak\n/g;
- $msg =~ s/\s+/ /;
- $result = "\\PackageError{perltex}{$msg}";
- my @helpstring;
- if ($msg =~ /\btrapped by\b/) {
- @helpstring =
- ("The preceding error message comes from Perl. Apparently,",
- "the Perl code you tried to execute attempted to perform an",
- "`unsafe' operation. If you trust the Perl code (e.g., if",
- "you wrote it) then you can invoke perltex with the --nosafe",
- "option to allow arbitrary Perl code to execute.",
- "Alternatively, you can selectively enable Perl features",
- "using perltex's --permit option. Don't do this if you don't",
- "trust the Perl code, however; malicious Perl code can do a",
- "world of harm to your computer system.");
- }
- else {
- @helpstring =
- ("The preceding error message comes from Perl. Apparently,",
- "there's a bug in your Perl code. You'll need to sort that",
- "out in your document and re-run perltex.");
- }
- my $helpstring = join ("\\MessageBreak\n", @helpstring);
- $helpstring =~ s/\. /.\\space\\space /g;
- $result .= "{$helpstring}";
- }
- push @macroexpansions, $result if defined $styfile && $optag eq "USE";
- print LOGFILE "%" x 30, " LATEX RESULT ", "%" x 30, "\n";
- print LOGFILE $result, "\n\n";
- $result .= '\endinput';
- open (FROMPERL, ">$fromperl") || die "open($fromperl): $!\n";
- syswrite FROMPERL, $result;
- close FROMPERL;
- delete_files($toflag, $toperl, $doneflag);
- open (FROMFLAG, ">$fromflag") || die "open($fromflag): $!\n";
- close FROMFLAG;
- if (open (PIPE, ">$pipe")) {
- autoflush PIPE 1;
- print PIPE $pipestring;
- close PIPE;
- }
- awaitexists($toperl);
- delete_files($fromflag);
- open (DONEFLAG, ">$doneflag") || die "open($doneflag): $!\n";
- close DONEFLAG;
- alarm 1;
- if (open (PIPE, ">$pipe")) {
- autoflush PIPE 1;
- print PIPE $pipestring;
- close PIPE;
- }
- alarm 0;
-}
-END {
- close LOGFILE;
- if (defined $latexpid) {
- kill (9, $latexpid);
- exit 1;
- }
-
- if (defined $styfile) {
- print STYFILE <<"STYFILEHEADER1";
-\\NeedsTeXFormat{LaTeX2e}[1999/12/01]
-\\ProvidesPackage{noperltex}
- [2007/09/29 v1.4 Perl-free version of PerlTeX specific to $jobname.tex]
-STYFILEHEADER1
- ;
- print STYFILE <<'STYFILEHEADER2';
-\RequirePackage{filecontents}
-
-\let\noperltex@PackageError=\PackageError
-\renewcommand{\PackageError}[3]{}
-\RequirePackage{perltex}
-\let\PackageError=\noperltex@PackageError
-
-\newcount\plmac@macro@invocation@num
-\gdef\plmac@show@placeholder#1#2\@empty{%
- \ifx#1U\relax
- \endgroup
- \advance\plmac@macro@invocation@num by 1\relax
- \global\plmac@macro@invocation@num=\plmac@macro@invocation@num
- \input{noperltex-\the\plmac@macro@invocation@num.tex}%
- \else
- \endgroup
- \fi
-}
-STYFILEHEADER2
- ;
- foreach my $e (0 .. $#macroexpansions) {
- print STYFILE "\n";
- printf STYFILE "%% Invocation #%d\n", 1+$e;
- printf STYFILE "\\begin{filecontents}{noperltex-%d.tex}\n", 1+$e;
- print STYFILE $macroexpansions[$e], "\\endinput\n";
- print STYFILE "\\end{filecontents}\n";
- }
- print STYFILE "\\endinput\n";
- close STYFILE;
- }
-
- exit 0;
-}
-
-__END__
-
-=head1 NAME
-
-perltex - enable LaTeX macros to be defined in terms of Perl code
-
-=head1 SYNOPSIS
-
-perltex
-[B<--help>]
-[B<--latex>=I<program>]
-[B<-->[B<no>]B<safe>]
-[B<--permit>=I<feature>]
-[B<--makesty>]
-[I<latex options>]
-
-=head1 DESCRIPTION
-
-LaTeX -- through the underlying TeX typesetting system -- produces
-beautifully typeset documents but has a macro language that is
-difficult to program. In particular, support for complex string
-manipulation is largely lacking. Perl is a popular general-purpose
-programming language whose forte is string manipulation. However, it
-has no typesetting capabilities whatsoever.
-
-Clearly, Perl's programmability could complement LaTeX's typesetting
-strengths. B<perltex> is the tool that enables a symbiosis between
-the two systems. All a user needs to do is compile a LaTeX document
-using B<perltex> instead of B<latex>. (B<perltex> is actually a
-wrapper for B<latex>, so no B<latex> functionality is lost.) If the
-document includes a C<\usepackage{perltex}> in its preamble, then
-C<\perlnewcommand> and C<\perlrenewcommand> macros will be made
-available. These behave just like LaTeX's C<\newcommand> and
-C<\renewcommand> except that the macro body contains Perl code instead
-of LaTeX code.
-
-=head1 OPTIONS
-
-B<perltex> accepts the following command-line options:
-
-=over 4
-
-=item B<--help>
-
-Display basic usage information.
-
-=item B<--latex>=I<program>
-
-Specify a program to use instead of B<latex>. For example,
-C<--latex=pdflatex> would typeset the given document using
-B<pdflatex> instead of ordinary B<latex>.
-
-=item B<-->[B<no>]B<safe>
-
-Enable or disable sandboxing. With the default of B<--safe>,
-B<perltex> executes the code from a C<\perlnewcommand> or
-C<\perlrenewcommand> macro within a protected environment that
-prohibits ``unsafe'' operations such as accessing files or executing
-external programs. Specifying B<--nosafe> gives the LaTeX document
-I<carte blanche> to execute any arbitrary Perl code, including that
-which can harm the user's files. See L<Safe> for more information.
-
-=item B<--permit>=I<feature>
-
-Permit particular Perl operations to be performed. The B<--permit>
-option, which can be specified more than once on the command line,
-enables finer-grained control over the B<perltex> sandbox. See
-L<Opcode> for more information.
-
-=item B<--makesty>
-
-Generate a LaTeX style file called F<noperltex.sty>. Replacing the
-document's C<\usepackage{perltex}> line with C<\usepackage{noperltex}>
-produces the same output but does not require PerlTeX, making the
-document suitable for distribution to people who do not have PerlTeX
-installed. The disadvantage is that F<noperltex.sty> is specific to
-the document that produced it. Any changes to the document's PerlTeX
-macro definitions or macro invocations necessitates rerunning
-B<perltex> with the B<--makesty> option.
-
-=back
-
-These options are then followed by whatever options are normally
-passed to B<latex> (or whatever program was specified with
-C<--latex>), including, for instance, the name of the F<.tex> file to
-compile.
-
-=head1 EXAMPLES
-
-In its simplest form, B<perltex> is run just like B<latex>:
-
- perltex myfile.tex
-
-To use B<pdflatex> instead of regular B<latex>, use the B<--latex>
-option:
-
- perltex --latex=pdflatex myfile.tex
-
-If LaTeX gives a ``C<trapped by operation mask>'' error and you trust
-the F<.tex> file you're trying to compile not to execute malicious
-Perl code (e.g., because you wrote it yourself), you can disable
-B<perltex>'s safety mechansisms with B<--nosafe>:
-
- perltex --nosafe myfile.tex
-
-The following command gives documents only B<perltex>'s default
-permissions (C<:browse>) plus the ability to open files and invoke the
-C<time> command:
-
- perltex --permit=:browse --permit=:filesys_open
- --permit=time myfile.tex
-
-=head1 ENVIRONMENT
-
-B<perltex> honors the following environment variables:
-
-=over 4
-
-=item PERLTEX
-
-Specify the filename of the LaTeX compiler. The LaTeX compiler
-defaults to ``C<latex>''. The C<PERLTEX> environment variable
-overrides this default, and the B<--latex> command-line option (see
-L</OPTIONS>) overrides that.
-
-=back
-
-=head1 FILES
-
-While compiling F<jobname.tex>, B<perltex> makes use of the following
-files:
-
-=over 4
-
-=item F<jobname.lgpl>
-
-log file written by Perl; helpful for debugging Perl macros
-
-=item F<jobname.topl>
-
-information sent from LaTeX to Perl
-
-=item F<jobname.frpl>
-
-information sent from Perl to LaTeX
-
-=item F<jobname.tfpl>
-
-``flag'' file whose existence indicates that F<jobname.topl> contains
-valid data
-
-=item F<jobname.ffpl>
-
-``flag'' file whose existence indicates that F<jobname.frpl> contains
-valid data
-
-=item F<jobname.dfpl>
-
-``flag'' file whose existence indicates that F<jobname.ffpl> has been
-deleted
-
-=item F<noperltex-#.tex>
-
-file generated by F<noperltex.sty> for each PerlTeX macro invocation
-
-=back
-
-=head1 NOTES
-
-B<perltex>'s sandbox defaults to what L<Opcode> calls ``C<:browse>''.
-
-=head1 SEE ALSO
-
-latex(1), pdflatex(1), perl(1), Safe(3pm), Opcode(3pm)
-
-=head1 AUTHOR
-
-Scott Pakin, I<scott+pt@pakin.org>
diff --git a/Build/source/texk/texlive/linked_scripts/petri-nets/pn2pdf b/Build/source/texk/texlive/linked_scripts/petri-nets/pn2pdf
deleted file mode 100755
index c42f9c38f30..00000000000
--- a/Build/source/texk/texlive/linked_scripts/petri-nets/pn2pdf
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/perl
-
-## This file is part of the Petri-nets packages. See file README for
-## copyright notice.
-
-use strict;
-use Digest::MD5 qw(md5_hex);
-use Getopt::Long;
-
-##
-## read options
-##
-
-Getopt::Long::Configure ("bundling");
-
-my $keep = 0;
-my $force = 0;
-my $verbose = 0;
-
-GetOptions ("k|keep" => \$keep,
- "f|force" => \$force,
- "v|verbose" => \$verbose,
- "t|test" => \&Test,
- "d|delete" => \&Delete,
- "b|batch" => \&Batch,
- "h|help" => \&Help);
-
-&Help if scalar @ARGV > 1;
-
-##
-## Global variables
-##
-
-my $figure = shift @ARGV;
-my $basename = $figure; $basename =~ s/\.pn$//;
-my $jobname = $basename; $jobname =~ s/-fig\d+$//;
-my $data = "";
-my %sum;
-
-##
-## Load checksums
-##
-
-if (-f "$jobname.sum") {
- open SUM, "$jobname.sum"
- or &Error ("could not open $jobname.sum -- $!");
- while (<SUM>) {
- next unless /^(.+)\s+(.+)$/;
- $sum{$1} = $2;
- }
- close SUM;
-}
-
-##
-## Get preamble
-##
-
-if (-f "$jobname.pre") {
- # read the existing preamble
- my @lines;
- open PRE, "$jobname.pre"
- or &Error ("could not open $jobname.sum -- $!");
- @lines = <PRE>;
- close PRE;
- $data .= join "", @lines;
-} else {
- # create a new preamble
- open TEX, "$jobname.tex"
- or &Error ("could not open $jobname.tex -- $!");
- while (<TEX>) {
- $data .= $_;
- last if /\\begin\{document\}/;
- }
- close TEX;
- $data =~ s/(\\begin\{document\}).*$/$1\n/;
- $data .= "\\pagestyle\{empty\}\n";
- # save it
- open PRE, ">$jobname.pre"
- or &Error ("could not create $jobname.sum -- $!");
- print PRE $data;
- close PRE;
-}
-
-##
-## Read the figure
-##
-
-{
- my $pre = 1;
- open TEX, $figure or &Error ("could not open $figure -- $!");
- open PRE, ">>$jobname.pre"
- or &Error ("could not append $jobname.pre -- $!");
- while (<TEX>) {
- $pre = 0 if /^\\begin\{petrinet\}/;
- print PRE if $pre;
- $data .= $_;
- }
- close TEX;
- close PRE;
-}
-
-##
-## Generate the EPDF
-##
-
-if (&SumChanged ($figure, "$data") or $force or (! -f "$basename.pdf")) {
- open TEX, ">$basename.tex"
- or &Error ("could not create file $basename.tex -- $!\n");
- print TEX "$data\\end\{document\}\n";
- close TEX;
- system "latex", "$basename.tex";
- system "dvips", "-E", "-Ppdf", "-o", "$basename.eps", "$basename";
- system "epstopdf", "$basename.eps";
-}
-
-unlink ("$basename.tex", "$basename.log", "$basename.aux",
- "$basename.dvi", "$basename.eps", "$basename.pn") unless $keep;
-
-##
-## Save checksums
-##
-
-open SUM, ">$jobname.sum"
- or die "pn2pdf: could not create file $jobname.sum -- $!\n";
-foreach my $file (sort keys %sum) {
- print SUM "$file $sum{$file}\n";
-}
-close SUM;
-
-exit 0;
-
-##
-## Sub programs
-##
-
-sub Help {
- print <<"EOF";
-Usage: pn2pdf [OPTIONS]
-Create EPDF files for Petri net figures.
-
- FIGURE process FIGURE
- -b, --batch FILE process the commands in FILE
- -k, --keep keep temporary files
- -f, --force force the rendering of all pictures
- -t, --test FILES create FILES for test purpose
- -d, --delete FILES delete FILES (may be patterns)
- -h, --help display this help and exit
-
-Report bugs to <pommereau\@univ-paris12.fr>
-EOF
- exit 0; }
-
-sub Error {
- foreach my $line (@_) {
- warn "pn2pdf: $line\n";
- }
- exit 1;
-}
-
-sub Verbose {
- return unless $verbose;
- foreach my $line (@_) {
- warn "[pn2pdf] $line\n";
- }
-}
-
-sub SumChanged {
- my ($file, $lines) = @_;
- my $md5 = md5_hex ($lines);
- if ($md5 eq $sum{$file}) {
- return 0;
- } else {
- $sum{$file} = $md5;
- return 1;
- }
-}
-
-sub Test {
- foreach my $file (@ARGV) {
- open FILE, ">$file" or &Error ("could not create $file -- $!");
- close FILE;
- }
- exit 0;
-}
-
-sub Delete {
- foreach my $pattern (@ARGV) {
- unlink glob $pattern unless $keep;
- }
- exit 0;
-}
-
-sub Batch {
- my @lines;
- foreach my $file (@ARGV) {
- $file =~ s/(\.[a-z]{3})?$/.bpn/i;
- open FILE, $file or &Error ("could not open $file -- $!");
- while (<FILE>) {
- next unless /^pn2pdf\s/;
- s/^pn2pdf\s/pn2pdf --keep / if $keep;
- s/^pn2pdf\s/pn2pdf --force / if $force;
- s/^pn2pdf\s/pn2pdf --verbose / if $verbose;
- push @lines, $_;
- }
- close FILE;
- }
- foreach (@lines) {
- system $_;
- }
- exit 0;
-}
diff --git a/Build/source/texk/texlive/linked_scripts/pfarrei/a5toa4.tlu b/Build/source/texk/texlive/linked_scripts/pfarrei/a5toa4.tlu
deleted file mode 100755
index 900a3b6fc25..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pfarrei/a5toa4.tlu
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env texlua
-
---
--- This is file `a5toa4.tlu',
--- generated with the docstrip utility.
---
--- The original source files were:
---
--- pfarrei.dtx (with options: `a5toa4,lua')
---
--- Copyright (c) 2013 Markus Kohm
--- komascript at gmx info
---
--- This file was generated from file(s) of the work `pfarrei'.
--- ------------------------------------------------------------------
---
--- It may be distributed under the conditions of the
--- LaTeX Project Public License in the version distributed together
--- with the work `pfarrei'. You may however distribute the work
--- `pfarrei' without all such generated files. See also
--- <http://www.latex-project.org/lppl.txt> for additional
--- information.
---
--- This work has the LPPL maintenance status `maintained'.
---
--- The Current Maintainer of this work is Markus Kohm.
---
--- The list of files belonging to the work `pfarrei' is given in
--- the file `pfarrei.dtx'.
---
--- $Id: pfarrei.dtx 36 2013-10-16 18:54:26Z mjk $
-
-kpse.set_program_name(arg[-1], 'a5toa4')
-require('pfarrei.pfarrei')
---
---
--- End of file `a5toa4.tlu'.
diff --git a/Build/source/texk/texlive/linked_scripts/pfarrei/pfarrei.tlu b/Build/source/texk/texlive/linked_scripts/pfarrei/pfarrei.tlu
deleted file mode 100755
index d0310cd72d0..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pfarrei/pfarrei.tlu
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/usr/bin/env texlua
-
---
--- This is file `pfarrei.tlu',
--- generated with the docstrip utility.
---
--- The original source files were:
---
--- pfarrei.dtx (with options: `pfarrei,lua')
---
--- Copyright (c) 2013 Markus Kohm
--- komascript at gmx info
---
--- This file was generated from file(s) of the work `pfarrei'.
--- ------------------------------------------------------------------
---
--- It may be distributed under the conditions of the
--- LaTeX Project Public License in the version distributed together
--- with the work `pfarrei'. You may however distribute the work
--- `pfarrei' without all such generated files. See also
--- <http://www.latex-project.org/lppl.txt> for additional
--- information.
---
--- This work has the LPPL maintenance status `maintained'.
---
--- The Current Maintainer of this work is Markus Kohm.
---
--- The list of files belonging to the work `pfarrei' is given in
--- the file `pfarrei.dtx'.
---
-local version_number = string.sub( '$Revision: 36 $', 12, -2 )
-local action_version = ' r' .. version_number .. '\n' .. [[
-
-Copyright (c) 2013 Markus Kohm.
-License: lppl 1.3c or later. See <http://www.latex-project.org/lppl.txt>.
-]]
-local action_help = [[
-action options:
-
- -h, --help Print this help message.
- -V, --version Print the version information.
-
-processing options:
- -b, --booklet Generate a booklet instead of only two pages side by
- side onto one page. The whole booklet will be one
- signature.
- -s, --sidebyside Generate only two pages side by side onto one page
- instead of a booklet.
- -o, --overwrite Write the output to the <PDF file> instead of appending
- "-sidebyside.pdf" or "--booklet.pdf" to the basename
- of <PDF file>
-]]
-local action_opts = {
- ['-h'] = 'help',
- ['--help'] = 'help',
- ['-V'] = 'version',
- ['--version'] = 'version',
-}
-local processing_opts = {
- ['-b'] = 'booklet',
- ['--booklet'] = 'booklet',
- ['-s'] = 'sidebyside',
- ['--sidebyside'] = 'sidebyside',
- ['-o'] = 'overwrite',
- ['--overwrite'] = 'overwrite',
- ['-d'] = 'debug',
- ['--debug'] = 'debug',
-}
-
--- detect action options and do action
-local i = 1
-local action
-while arg[i] do
- action = action_opts[arg[i]]
- i = i+1
- if action == 'help' then
- print( arg[0]..action_version );
- print( 'Usage: ' .. arg[0] .. ' <action option>' )
- print( ' ' .. arg[0] .. ' [<processing options>] <PDF file> ...\n' )
- print( action_help );
- os.exit( 0 );
- elseif action == 'version' then
- print( arg[0] .. action_version );
- os.exit( 0 );
- end
-end
-
--- process options and parameters
-local booklet = false
-local overwrite = false
-local debug = false
-i = 1
-while arg[i] do
- action = processing_opts[arg[i]]
- if action == 'booklet' then booklet = true
- elseif action == 'sidebyside' then booklet = false
- elseif action == 'overwrite' then overwrite = true
- elseif action == 'debug' then debug = true
- elseif action == nil then
- -- build the temporary tex file
- local tmpdir = os.tmpdir("pfarrei.XXXXXX" )
- local tmpfile = string.match( arg[i], '.*/(.*)$') or arg[i]
- local basename = string.match( tmpfile,'(.*)%.[^.]*$') or tmpfile
- tmpfile = tmpdir..'/'..basename..'.tex'
- local file = assert( io.open( tmpfile, 'w' ) )
- if booklet then assert( file:write("\\PassOptionsToPackage{booklet}{pfarrei}\n") ) end
- assert( file:write("\\def\\OriginalFile{",arg[i],"}\n") )
- assert( file:write("\\input{a5toa4.tex}\n") )
- assert( file:flush() )
- file:close()
- -- call pdflatex
- assert( os.execute( 'pdflatex -interaction=batchmode -output-directory='..tmpdir..' '..tmpfile ) )
- -- copy the resulting pdf file
- local srcfile = assert( io.open( tmpdir..'/'..basename..'.pdf', 'rb' ) )
- if overwrite
- then
- tmpfile = arg[i]
- else
- tmpfile = string.match( arg[i], '(.*)%.[^.]*$' ) or arg[i]
- if booklet
- then
- tmpfile = tmpfile..'-booklet.pdf'
- else
- tmpfile = tmpfile..'-sidebyside.pdf'
- end
- end
- local destfile = assert( io.open( tmpfile, 'wb' ) )
- local buffer
- while true do
- buffer = srcfile:read(8388608)
- if buffer==nil then break end
- assert( destfile:write(buffer) )
- end
- assert( destfile:close() )
- srcfile:close()
- if debug
- then
- print('DEBUG: Temporary files in: '..tmpdir);
- else
- tmpfile=tmpdir..'/'..basename
- os.remove( tmpfile..'.aux' )
- os.remove( tmpfile..'.tex' )
- os.remove( tmpfile..'.log' )
- os.remove( tmpfile..'.pdf' )
- os.remove( tmpdir )
- end
- overwrite = false
- end
- i=i+1
-end
---
---
--- End of file `pfarrei.tlu'.
diff --git a/Build/source/texk/texlive/linked_scripts/pkfix-helper/pkfix-helper b/Build/source/texk/texlive/linked_scripts/pkfix-helper/pkfix-helper
deleted file mode 100755
index 73955ff8f04..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pkfix-helper/pkfix-helper
+++ /dev/null
@@ -1,1826 +0,0 @@
-#! /usr/bin/env perl
-
-#############################################
-# Help pkfix decipher fonts in a PostScript #
-# file produced by an ancient dvips #
-# #
-# By Scott Pakin <scott+pkfh@pakin.org> #
-#############################################
-
-use File::Spec;
-use File::Temp qw (tempfile);
-use File::Basename;
-use Getopt::Long;
-use Pod::Usage;
-use warnings;
-use strict;
-
-# Define some global variables.
-my $progname = basename $0; # Name of this program
-our $VERSION = "1.6"; # Version number of this program
-my %name2chars; # Map from a font name to a character list
-my $GS = $ENV{"GS"} || "gs"; # Name of the Ghostscript interpreter
-my $TFTOPL = $ENV{"TFTOPL"} || "tftopl"; # Name of the TFM to PL converter
-my $dpi = 300; # Number of dots per inch used to generate bitmapped characters
-my @tfmlist; # List of TFM files to use
-my %fontmatch; # Map from a font name to its best match
-my $xinc = 48; # Width of font name in PostScript points
-my $yinc = 24; # Height of font in PostScript points
-my $init_yinc = 36; # Space after title
-my %tfmfontwidth; # Map from font name to character number to character width
-my %tfm2size; # Map from font name to design size
-my %tfmmissing; # Set of TFM files we looked for but didn't find
-my ($dvips_xscale, $dvips_yscale); # Scaling factors from Dvips's PostScript CTM
-my $discard_output = $^O eq "MSWin32" ? "> NUL:" : "> /dev/null 2>&1"; # Command suffix to discard all output
-
-# Define the global variables that the user can modify from the command line.
-my $wanthelp = 0; # 1=user wants to see the program's documentation
-my $wantversion = 0; # 1=user wants to see the program's version number
-my $verbose = 1; # 0=quiet; 1=verbose output; 2=more verbose output
-my @forced_fonts; # Font mappings the user asserts are correct
-my @exclude_res; # Regexps for fonts to exclude
-my @extra_tfms; # Extra TFM files to use
-my %retained_t3s; # Type 3 fonts to retain as is
-my $sample_file_ps; # Name of a PostScript file of font samples to write
-my $sample_file_tex; # Name of a TeX file of font samples to write
-my $single_font_use = 0; # 1=one use per font; 0=allow repetitions
-my $samples_per_page = 25; # Number of font samples to print per page
-my $tfm_cache_file; # Name of a file in which to cache font metrics
-my $no_match = 10**9; # Sentinel indicating no match was found
-
-###########################################################################
-
-# Read %tfm2size, %tfmfontwidth, and %tfmmissing from a file named by
-# $tfm_cache_file.
-sub read_tfm_cache_file
-{
- open(CACHEFILE, "<", $tfm_cache_file) || do {
- print STDERR "Ignoring TFM cache file $tfm_cache_file ($!).\n" if $verbose;
- return;
- };
- print STDERR "Reading TFM data from $tfm_cache_file ... " if $verbose;
- my $numlines = 0;
- while (my $oneline = <CACHEFILE>) {
- chomp $oneline;
- my @fields = split " ", $oneline;
- die "${progname}: Internal error" if $#fields == -1;
- my $tfm = shift @fields;
- if ($#fields == -1) {
- # No metrics -- TFM file must not have been found.
- $tfmmissing{$tfm} = 1;
- }
- else {
- # Parse and store the TFM data.
- $tfm2size{$tfm} = shift @fields;
- my %widths = @fields;
- $tfmfontwidth{$tfm} = \%widths;
- }
- $numlines++;
- }
- close CACHEFILE;
- print STDERR "done ($numlines entries).\n" if $verbose;
-}
-
-
-# Write %tfm2size, %tfmfontwidth, and %tfmmissing to a file named by
-# $tfm_cache_file.
-sub write_tfm_cache_file
-{
- my $numlines = 0;
- print STDERR "Writing TFM data to $tfm_cache_file ... " if $verbose;
- open(CACHEFILE, ">", $tfm_cache_file) || die "${progname}: Failed to create $tfm_cache_file ($!)\n";
- while (my ($tfm, $size) = each %tfm2size) {
- my @widths = %{$tfmfontwidth{$tfm}};
- print CACHEFILE "$tfm $size @widths\n";
- $numlines++;
- }
- foreach my $tfm (keys %tfmmissing) {
- print CACHEFILE "$tfm\n";
- $numlines++;
- }
- close CACHEFILE;
- print STDERR "done ($numlines entries).\n" if $verbose;
-}
-
-
-# Given the base name of a .tfm file, process the file and return the
-# font's design size and a mapping from character number to character
-# width.
-sub tfm2widths ($)
-{
- my $tfmname = $_[0]; # Name of the TFM file
- my $designsize; # Design size of the font
- my %num2width; # Resultant mapping
- my $plname; # Name of PL file; some tftopl programs can't write to stdout.
- my $plfile; # Filehandle corresponding to $plname
-
- # First see if the information is already cached.
- if (defined $tfm2size{$tfmname}) {
- print STDERR " Processing $tfmname ... cached.\n" if $verbose >= 2;
- return [$tfm2size{$tfmname}, %{$tfmfontwidth{$tfmname}}];
- }
- if (defined $tfmmissing{$tfmname}) {
- print STDERR " Processing $tfmname ... cached as not found.\n" if $verbose >= 2;
- return [$designsize, %num2width];
- }
-
- # The information is not cached -- read it from a file.
- ($plfile, $plname) = tempfile (DIR => File::Spec->tmpdir(), SUFFIX => ".pl");
- close $plfile;
- if (!system "$TFTOPL $tfmname $plname $discard_output") {
- print STDERR " Processing $tfmname ... " if $verbose >= 2;
- open (PLFILE, "<$plname") || die "${progname}: Unable to open $tfmname ($!)\n";
- my $charnum; # Current character number
- while (my $oneline = <PLFILE>) {
- # Store the current character width.
- $oneline =~ /\(CHARWD R (\S+)\)/ && do {
- $num2width{$charnum} = $1 * $designsize;
- next;
- };
-
- # Store the current character number.
- $oneline =~ /\(CHARACTER (\S) (\S+)/ && do {
- if ($1 eq "O") {
- # Octal character number
- $charnum = oct $2;
- }
- elsif ($1 eq "C") {
- # ASCII character number
- $charnum = ord $2;
- }
- else {
- die "${progname}: Unknown TFM character type \"$1\"\n";
- }
- next;
- };
-
- # Store the font design size.
- $oneline =~ /\(DESIGNSIZE R (\S+)\)/ && do {
- $designsize = $1 + 0.0;
- next;
- };
- }
- close PLFILE;
- print STDERR "done.\n" if $verbose >= 2;
- }
- else {
- print STDERR " Discarding $tfmname (not found).\n" if $verbose >= 3;
- }
- unlink $plname;
- return [$designsize, %num2width];
-}
-
-
-# Given two character maps, one for a document font and one for a TFM
-# file, return the optimal scale factor for the TFM file to best match
-# the document font.
-sub optimal_scale ($$)
-{
- my %docmap = %{$_[0]}; # Map for a document font
- my %tfmmap = %{$_[1]}; # Map for a TFM font
- my $doc_dot_tfm = 0.0; # Sum of $docmap{$c}*$tfmmap{$c} for all $c
- my $tfm_dot_tfm = 0.0; # Sum of $tfmmap{$c}**2 for all $c
-
- while (my ($char, $docwidth) = each %docmap) {
- my $tfmwidth = $tfmmap{$char};
- return undef if !defined $tfmwidth; # Match is impossible.
- $doc_dot_tfm += $docwidth * $tfmwidth;
- $tfm_dot_tfm += $tfmwidth**2;
- }
- return 1.0 if $tfm_dot_tfm == 0.0; # Handle TFM characters that all have zero width.
- my $optscale = $doc_dot_tfm / $tfm_dot_tfm;
- return $optscale;
-}
-
-
-# Compare two character maps and return their mismatch (smaller is
-# better). The third, optional, argument is a scale factor for the
-# TFM file.
-sub compare_maps ($$;$)
-{
- my %docmap = %{$_[0]}; # Map for a document font
- my %tfmmap = %{$_[1]}; # Map for a TFM font
- my $scale = $_[2] || 1.0; # Scale for each TFM width
- my @sqdiffs; # List of squares of differences
- my $sqdiff = 0; # Sum of squares of differences
-
- # Compute the per-character squared difference.
- while (my ($char, $docwidth) = each %docmap) {
- my $tfmwidth = $tfmmap{$char};
- return $no_match if !defined $tfmwidth; # Match is impossible.
- push @sqdiffs, ($docwidth - $tfmwidth*$scale) ** 2;
- }
-
- # Sort the list of squared differences in decreasing order (for
- # floating-point stability), add it up, and return the sum.
- @sqdiffs = sort {$b <=> $a} @sqdiffs;
- foreach my $s (@sqdiffs) {
- $sqdiff += $s;
- }
- return $sqdiff;
-}
-
-
-# Given a Type 3 font definition, surround it with DVIPSBitmapFont comments.
-sub write_comments ($$)
-{
- my ($fontname, $fontdef) = @_;
- return $fontdef if !defined $fontmatch{$fontname}; # Font should not be substituted
- my $tfm = $fontmatch{$fontname}->{"tfm"};
- my $scale = $fontmatch{$fontname}->{"scale"};
- my $origsize = $tfm2size{$tfm};
- my $begincomment = sprintf '%%DVIPSBitmapFont: %s %s %.5g %d',
- $fontname, $tfm, $origsize*$scale, 1+$#{$name2chars{$fontname}};
- my $endcomment = '%EndDVIPSBitmapFont';
- return "\n" . $begincomment . "\n" . $fontdef . "\n" . $endcomment . "\n";
-}
-
-
-# Escape an array of characters for PostScript's benefit.
-sub psify (@)
-{
- my @ps_chars;
- foreach my $onechar (@_) {
- my $charnum = ord $onechar;
- if ($onechar =~ /[\\()]/) {
- push @ps_chars, "\\" . $onechar;
- }
- elsif ($charnum >= 32 && $charnum <= 126) {
- push @ps_chars, $onechar;
- }
- else {
- push @ps_chars, sprintf "\\%03o", $charnum;
- }
- }
- return @ps_chars;
-}
-
-
-# Escape an array of characters for TeX's benefit.
-sub texify (@)
-{
- my @texchars;
- foreach my $onechar (@_) {
- if ($onechar =~ m|[\000-\037\\{}\177-\377]|) {
- push @texchars, sprintf '\char"%02X{}', ord $onechar;
- }
- else {
- push @texchars, $onechar;
- }
- }
- return join "", @texchars;
-}
-
-
-# Parse a font specification into a list of hashes of information.
-sub parse_font_spec ($)
-{
- my $spec = $_[0];
- my $parse_error = "${progname}: Unable to parse font specification \"$spec\"\n";
-
- if ($spec =~ /^\s*([-\w\*]+)(.*)$/o) {
- my $tfm = $1; # Name of tfm file (e.g., "cmr10")
- my $scale_info = $2; # Concatenation of scale type and scale factor
- my $scale_type; # "X"=multiply, "@"=assign
- my $scale_amount; # How much to scale the TFM file, "*"=automatic
-
- # Parse the different scale types.
- if ($scale_info =~ /^\s*$/o) {
- # Empty
- $scale_type = 'X';
- $scale_amount = 1.0;
- }
- elsif ($scale_info =~ /^\s*\@\s*([\d.]+)\s*X\s*$/io) {
- # "@ <number> X"
- $scale_type = 'X';
- $scale_amount = $1 + 0.0;
- }
- elsif ($scale_info =~ /^\s*\@\s*([\d.]+)\s*(pt|bp)\s*$/io) {
- # "@ <number> pt" or "@ <number> bp"
- $scale_type = '@';
- $scale_amount = $1;
- $scale_amount *= 72.0/72.27 if $2 eq "bp"; # Convert to TeX points
- }
- elsif ($scale_info =~ /^\s*\@\s*\*\s*$/o) {
- # "@ *"
- $scale_type = 'X';
- $scale_amount = "*"
- }
- else {
- die $parse_error;
- }
-
- # If the tfm file contains a "*", replace the "*" with a
- # variety of font sizes.
- my @fontlist;
- if ($tfm =~ /\*/) {
- foreach my $fsize (5..17) {
- my $full_tfm = $tfm;
- $full_tfm =~ s/\*/$fsize/g;
- push @fontlist, {"tfm" => $full_tfm,
- "scale_type" => $scale_type,
- "scale" => $scale_amount};
- }
- }
- else {
- push @fontlist, {"tfm" => $tfm,
- "scale_type" => $scale_type,
- "scale" => $scale_amount};
- }
- return \@fontlist;
- }
- die $parse_error;
-}
-
-
-# Return all of the unique items in a given list.
-sub unique_items (@)
-{
- my %item_hash;
- foreach my $item (@_) {
- $item_hash{$item} = 1;
- }
- return keys %item_hash;
-}
-
-
-# Collapse repeated whitespace instances into a single space character.
-sub collapse_spaces ($)
-{
- my $simply_spaced = $_[0];
- $simply_spaced =~ s/\s+/ /gs;
- return $simply_spaced;
-}
-
-# Combine a list of strings with commas and "and".
-sub join_string_list (@)
-{
- my @items = @_;
- return $items[0] if $#items == 0;
- return "$items[0] and $items[1]" if $#items == 1;
- return join(", ", @items[0..$#items-1]) . ", and $items[$#items]";
-}
-
-# Determine a PostScript file's page size. Return it as a pair of TeX
-# points, a description of a standard paper size, and its source in
-# the document.
-sub page_size ($)
-{
- my $ps = $_[0]; # Entire PostScript file
- my $bp2pt = 72.27/72; # Conversion factor from bp to pt
- my @psize = (597.508, 845.047, "A4", "a fallback mechanism"); # Default to A4 paper
-
- # Look for a bounding box. This should work in most cases.
- if ($ps =~ /^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)$/m) {
- $psize[0] = ($3 - $1)*$bp2pt;
- $psize[1] = ($4 - $2)*$bp2pt;
- $psize[3] = "the PostScript bounding box";
- }
- # dvips-produced PostScript files that lack a bounding box may
- # specify a page size when entering the TeXDict dictionary.
- elsif ($ps =~ /\bTeXDict\s+begin\s+(\d+)\s+(\d+)\s+\d+\s+\d+\s+\d+/ms) {
- $psize[0] = $1/65536.0;
- $psize[1] = $2/65536.0;
- $psize[3] = "the TeX dictionary";
- }
-
- # Look for standard paper sizes.
- my $wd = int($psize[0] + 0.5);
- my $ht = int($psize[1] + 0.5);
- if ($wd == 598 && $ht == 845) {
- $psize[2] = "A4";
- }
- elsif ($wd == 614 && $ht == 795) {
- $psize[2] = "US Letter";
- }
- else {
- $psize[2] = "unrecognized paper size";
- }
- return @psize;
-}
-
-###########################################################################
-
-# Parse the command line.
-my @cmdline = @ARGV;
-Getopt::Long::Configure ("bundling");
-GetOptions ("h|help" => \$wanthelp,
- "v|verbose+" => \$verbose,
- "V|version" => \$wantversion,
- "q|quiet" => sub {$verbose = 0},
- "f|force=s" => \@forced_fonts,
- "i|include=s" => \@extra_tfms,
- "x|exclude=s" => \@exclude_res,
- "k|keep=s" => sub {$retained_t3s{$_[1]} = 1},
- "t|tex=s" => \$sample_file_tex,
- "p|ps=s" => \$sample_file_ps,
- "s|spp=i" => \$samples_per_page,
- "C|cache=s" => \$tfm_cache_file,
- "1|no-repeats" => \$single_font_use) || pod2usage(2);
-if ($wantversion) {
- print "pkfix-helper $VERSION\n";
- exit 0;
-}
-if ($wanthelp) {
- pod2usage (-verbose => $verbose,
- -exitval => "NOEXIT");
- print "Report bugs to scott+pkfh\@pakin.org.\n" if $verbose == 1;
- exit 0;
-}
-my $infilename = $#ARGV>=0 ? $ARGV[0] : "-";
-my $outfilename = $#ARGV>=1 ? $ARGV[1] : "-";
-die "${progname}: Samples per page must be at least 1 ($samples_per_page was specified)\n" if $samples_per_page < 1;
-print STDERR "Command line: $0 @cmdline\n" if $verbose >= 2;
-
-# Convert any user-specified TFMs to the appropriate internal format.
-foreach my $tfm (@extra_tfms) {
- my $font_spec = parse_font_spec $tfm;
- push @tfmlist, @$font_spec;
-}
-
-# Parse the list of forced font mappings.
-my %is_forced;
-foreach my $mapstr (@forced_fonts) {
- $mapstr =~ /^(\w+)\s*=\s*(.*)$/ || die "${progname}: Unable to parse font specification \"$mapstr\"\n";
- my $parsed_font_spec = parse_font_spec $2;
- if (defined $fontmatch{$1}) {
- # Append to an existing font match.
- $fontmatch{$1} = [@{$fontmatch{$1}}, @$parsed_font_spec];
- }
- else {
- # Define a new font match,
- $fontmatch{$1} = $parsed_font_spec;
- }
- $is_forced{$1} = 1;
-}
-
-# Construct a list of (possibly nonexistent) TFM files to try. These
-# should be in order of decreasing likelihood. Each entry in the list
-# is of the form {full name, scale factor}.
-@exclude_res = ('^\s*$') if $#exclude_res == -1;
-foreach my $size_scale (# The following are the most common sizes found in
- # old LaTeX documents.
- [10, 1.0], # 10 pt.
- [12, 1.0], # 12 pt.
- [10, 1.095], # 11 pt. -- really 10*sqrt(1.2) pt.
- [17, 17.28/17], # 17 pt. -- really 10*1.2^3 pt.
- [ 9, 1.0],
- [ 8, 1.0],
- [ 7, 1.0],
- [ 6, 1.0],
- [ 5, 1.0],
- # As 10 pt. is LaTeX's most generic font size, LaTeX
- # sometimes needs to scale up a 10 pt. font to make up
- # for no other size being available.
- [10, 1.2], # 12 pt.
- [10, 1.44], # 14 pt. -- really 10*1.2^2 pt.
- [10, 1.728], # 17 pt. -- really 10*1.2^3 pt.
- [10, 2.074], # 20 pt. -- really 10*1.2^4 pt.
- [10, 2.488], # 25 pt. -- really 10*1.2^5 pt.
- # While not particularly common, the following are
- # sometimes encountered with cmbx12 for section
- # headings.
- [12, 14.40/12],
- [12, 17.28/12],
- [12, 20.74/12],
- [12, 24.88/12]) {
- my ($pointsize, $scale) = @$size_scale;
- FONTLOOP:
- foreach my $basefont (qw (cmr cmbx cmtt cmbsy cmbxsl cmcsc cmex cmitt cmmi
- cmmib cmss cmssbx cmssi cmsy cmsl cmsltt cmti cmb
- lasy lasyb msam msbm cmbxti cmssdc cmtcsc)) {
- my $friendly_name = sprintf "%s%d \@ %.5gX", $basefont, $pointsize, $scale;
- foreach my $regexp (@exclude_res) {
- next FONTLOOP if $friendly_name =~ $regexp;
- }
- push @tfmlist, {"tfm" => $basefont . $pointsize,
- "scale_type" => "X",
- "scale" => $scale};
- }
-}
-
-# Read the entire input file.
-$| = 1;
-if ($verbose) {
- printf STDERR "Reading %s ... ", $infilename eq "-" ? "standard input" : $infilename;
-}
-my $entirefile;
-{
- local $/ = undef;
- open (INFILE, "<$infilename") || die "open(\"$infilename\"): $!\n";
- binmode INFILE;
- $entirefile = <INFILE>;
- close INFILE;
-}
-print STDERR "done.\n" if $verbose;
-
-# Warn if the file doesn't look like it was produced by dvips.
-if ($entirefile !~ /dvips/i) {
- warn "${progname}: $infilename does not appear to have been produced by dvips; font conversion is unlikely to succeed\n";
- warn "${progname}: $infilename does not even appear to be a PostScript file\n" if substr($entirefile, 0, 2) ne '%!';
-}
-
-# Compute the byte offset of each DVIPSBeginSection before we modify the input
-# file.
-my @begin_offsets;
-my $idx = 0;
-while (1) {
- $idx = index($entirefile, '%DVIPSBeginSection', $idx);
- last if $idx == -1;
- push @begin_offsets, ++$idx;
-}
-
-# Preprocess the input file to make it easier to parse.
-print STDERR "Preprocessing ... " if $verbose >= 2;
-$entirefile =~ s/[\n\r]+/\n/g; # Normalize line endings to Unix-style.
-$entirefile =~ s/TeXDict\s+begin\s+\%\%Begin(\w+).*?\%\%End\1.*?\n/$&end\nTeXDict begin /gs; # Remove blocks of code between "TeXDict begin" and the first number.
-$entirefile =~ s/TeXDict\s+begin\s+\d+\s+\d+\s+\d+.*?\@/collapse_spaces($&)/gse; # Normalize "TeXDict begin" spacing.
-print STDERR "done.\n" if $verbose >= 2;
-
-# Determine the number of dots per inch used to generate the bitmaps.
-if ($entirefile =~ /dpi=(\d+)/i
- || $entirefile =~ /Resolution (\d+)dpi/i
- || $entirefile =~ /\%Feature: \*Resolution (\d+)/) {
- $dpi = $1 + 0;
- printf STDERR "Bitmapped fonts are typeset at $dpi DPI.\n" if $verbose;
-}
-else {
- warn "${progname}: Could not determine the target printer resolution; assuming $dpi DPI\n";
-}
-
-# Determine the page size.
-my @psize = page_size $entirefile;
-if ($verbose >= 2) {
- printf STDERR "Determined the page size to be %.0fpt by %.0fpt (%s) via %s.\n", $psize[0], $psize[1], $psize[2], $psize[3];
-}
-elsif ($verbose >= 1) {
- printf STDERR "Determined the page size to be %.3fpt by %.3fpt (%s).\n", $psize[0], $psize[1], $psize[2];
-}
-
-# Rename the fonts in each subdocument (figure).
-my @fig_font_renames; # List of {old text, new text, TeX dictionary} triplets
-my $fignum = 1;
-my $numrenamed = 0;
-while ($entirefile =~ /(\%\%BeginDocument: (.*?)\n.*?\%\%EndDocument)/gs) {
- my $figure = $1;
- my $newfigure = $1;
- my $figname = $2;
- if ($verbose >= 2) {
- if ($fignum == 1) {
- print STDERR "Renaming all fonts encountered in figures and other included documents:\n";
- }
- print STDERR " $figname\n";
- }
- while ($figure =~ m|/([^()<>\[\]{}\/\%]+)\s+\d+\s+\d+\s+df(.*?>[^<>]*?[DI])\s+E|gs) {
- my $fontname = $1; # Name of current font (e.g., "Fa")
- $newfigure =~ s,(?<=/)$fontname\b,${fontname}_$fignum,gs;
- $newfigure =~ s,\b$fontname(?=[^()]*\(),${fontname}_$fignum,gs;
- $numrenamed++;
- if ($verbose >= 2) {
- printf STDERR " %s --> %s_%d\n", $fontname, $fontname, $fignum;
- }
- }
- if ($figure ne $newfigure) {
- # Remove the font-defining dictionary from the the subdocument
- # as it may confuse pkfix. Store it so we can later reinsert
- # it into the main document's font-defining dictionary.
- my $texdict = "";
- if ($newfigure =~ s/TeXDict begin \d+ \d+ \d+ \d+ \d+ \(.*?\)\s+\@start(.*?)end//gs) {
- $texdict = $1;
- }
- else {
- warn "${progname}: Failed to extract a font-defining TeXDict from $figname\n";
- }
- push @fig_font_renames, [$figure, $newfigure, $texdict];
- }
- $fignum++;
-}
-if ($verbose && $entirefile =~ /\%\%BeginDocument:/s) {
- print STDERR "Number of Type 3 fonts encountered in included documents: $numrenamed\n";
-}
-foreach my $ren (@fig_font_renames) {
- my ($before, $after, $notused) = @$ren;
- $entirefile =~ s/\Q$before\E/$after/gs;
-}
-
-# Rename the fonts in each section.
-my @sections = $entirefile =~ /(?<=\n)\%DVIPSBeginSection.*?\%DVIPSEndSection\n/gs;
-my @sdoc_font_renames; # List of {old text, new text, TeX dictionary} triplets
-if ($#sections > 0) {
- printf STDERR "Renaming the fonts in %d dvips sections:\n", 1+$#sections if $verbose >= 2;
- my $numrenamed = 0;
- foreach my $secnum (0 .. $#sections) {
- if ($verbose >= 2) {
- printf STDERR " Section %d, beginning at file position %d\n", 1+$secnum, $begin_offsets[$secnum];
- }
- my $oldsection = $sections[$secnum];
- my $newsection = $oldsection;
- while ($oldsection =~ m|/([^()<>\[\]{}\/\%]+)\s+\d+\s+\d+\s+df(.*?>[^<>]*?[DI])\s+E|gs) {
- my $fontname = $1; # Name of current font (e.g., "Fa")
- my $newfontname = sprintf "%s_S%02d", $fontname, 1+$secnum;
- $newsection =~ s,(?<=/)$fontname\b,$newfontname,gs;
- $newsection =~ s,\b$fontname\b(?=[^()]*\(),$newfontname,gs;
- $numrenamed++;
- if ($verbose >= 2) {
- printf STDERR " %s --> %s\n", $fontname, $newfontname;
- }
- }
- if ($oldsection ne $newsection) {
- # Remove the font-defining dictionary from the the section
- # as it may confuse pkfix. Store it so we can later
- # reinsert it into the main document's font-defining
- # dictionary.
- my $texdict = "";
- if ($newsection =~ s/(TeXDict begin \d+ \d+ \d+ \d+ \d+(?: \([^\)]*\))?\s+\@start bos)\s+(.*?)(?=\%DVIPSSectionPage)/$1\n/gs) {
- $texdict = $2;
- }
- else {
- warn "${progname}: Failed to extract a font-defining TeXDict from dvips section @{[1+$secnum]}\n";
- }
- push @sdoc_font_renames, [$oldsection, $newsection, $texdict];
- }
- }
- if ($verbose) {
- printf STDERR "Number of Type 3 fonts encountered in %d dvips sections: %d\n", 1+$#sections, $numrenamed;
- }
-}
-foreach my $ren (@sdoc_font_renames) {
- my ($before, $after, $notused) = @$ren;
- $entirefile =~ s/\Q$before\E/$after/gs;
-}
-
-# If the document contains a section or subdocument with (now renamed)
-# font definitions, hoist those definitions to where pkfix can find
-# them.
-if (@sdoc_font_renames || @fig_font_renames) {
- if ($entirefile =~ /(TeXDict begin \d+ \d+ \d+ \d+ \d+(?: \([^\)]*\))?\s+\@start)(.*?)(?=end)/s) {
- # Construct the PostScript code to add.
- my $texdict_header = $1;
- my $texdict_body = $2;
- my $morefonts = "";
- foreach my $ren (@sdoc_font_renames, @fig_font_renames) {
- $morefonts .= $ren->[2];
- }
-
- # Insert the code at a suitable location.
- if ($entirefile =~ /\%\%EndProlog/s) {
- # First choice: In a ProcSet right before the %%EndProlog
- $entirefile =~ s/(\%\%EndProlog)/\%\%BeginProcSet: ${progname}-fonts.pro\n$texdict_header\n$morefonts\nend\n\%\%EndProcSet\n$1\n\%DVIPSParameters: dpi=$dpi/;
- }
- else {
- # Second choice: Within the first TeXDict usage
- $entirefile =~ s/(\Q$texdict_header$texdict_body\E)/$1$morefonts/s;
- }
- }
- else {
- warn "${progname}: Failed to find a font-defining TeXDict\n";
- }
-}
-
-# Construct a mapping from each document font name to a list of valid
-# characters in that font.
-while ($entirefile =~ m|/([^()<>\[\]{}\/\%]+)\s+\d+\s+\d+\s+df(.*?>[^<>]*?[DI])\s+E|gs) {
- my $fontname = $1; # Name of current font (e.g., "Fa")
- my $fontbody = $2; # List of character definitions as hexadecimal strings
- my $charnum = 0; # Current character number
- my @charlist = (); # List of valid characters in PostScript-friendly format
-
- warn "${progname}: Font $fontname is multiply defined\n" if defined $name2chars{$fontname};
- while ($fontbody =~ /<[0-9A-F\s]+>(.*?[DI])/gs) {
- # Put the current character number in $charnum then append the
- # corresponding character to @charlist.
- my @chardef = split " ", $1;
- if ($chardef[$#chardef] eq "I") {
- $charnum++;
- }
- else {
- $charnum = $chardef[$#chardef-1];
- }
- push @charlist, chr $charnum;
- }
- $name2chars{$fontname} = \@charlist;
-}
-my @sortedfontnames = sort {$#{$name2chars{$b}} <=> $#{$name2chars{$a}}
- || $a cmp $b} keys %name2chars;
-if ($verbose) {
- printf STDERR "Total number of Type 3 fonts encountered: %d\n", 1+$#sortedfontnames;
- if ($verbose >= 2) {
- foreach my $fontname (@sortedfontnames) {
- printf STDERR " %s -- %3d character(s)\n", $fontname, 1+$#{$name2chars{$fontname}};
- }
- }
-}
-die "${progname}: No Type 3 fonts were encountered in the input file\n" if $#sortedfontnames==-1;
-
-# Insert some helper code after the tex.pro ProcSet.
-my $output_width_ps = $entirefile; # PostScript code to output character widths
-my $showfontnamecode = <<"SHOWFONTNAME";
-\%\%BeginProcSet: $progname.pro
-TeXDict begin
-
-% char0 char1 PRINT-WIDTH -
-%
-% Output the name of the current font (font-name-string), its character
-% number (char0), and the character's width in PostScript points.
-
-/print-width {
- pop
- (FONT: ) print font-name-string print
- ( CHAR: ) print 8 string cvs print
- ( XPOS: ) print currentpoint pop 80 string cvs print
- (\\n) print
-} bind def
-
-% font-name sample-string PRINT-CHAR-WIDTHS -
-%
-% Store the name of font-name in the string font-name-string. Then, select
-% font-name and, for each character of test-string, call print-width
-% to output its width.
-
-/print-char-widths {
- /sample-string exch def
- /font-name exch def
- font-name 8 string cvs /font-name-string exch def
- font-name cvx exec {print-width} sample-string kshow
-} bind def
-
-end
-\%\%EndProcSet
-SHOWFONTNAME
- ;#'
-if ($output_width_ps !~ s/\%\%BeginProcSet: tex\w*\.pro.*?\%\%EndProcSet/$&\n$showfontnamecode/s) {
- print STDERR "No tex.pro ProcSet was found. Looking for a suitable TeXDict begin.\n" if $verbose >= 3;
- if ($output_width_ps =~ s/TeXDict begin\s+\d+\s+\d+\s+bop/\n$showfontnamecode\n$&/s) {
- print STDERR "Found a suitable TeXDict begin!\n" if $verbose >= 3;
- }
- else {
- print STDERR "Failed to find a suitable TeXDict begin.\n" if $verbose >= 3;
- die "${progname}: Unable to inject prologue code\n";
- }
-}
-
-# Define some code to display the width of every valid character in
-# every bitmapped font. Fonts are displayed in decreasing order of
-# the number of characters used.
-my $displaycode = "\%\%Page: 1 1\nTeXDict begin\n1 0 bop\n";
-foreach my $fontnum (0 .. $#sortedfontnames) {
- # Duplicate the last character of the sample string so kshow can
- # process the final character delta.
- my $fontname = $sortedfontnames[$fontnum];
- my @charlist = psify @{$name2chars{$fontname}};
- my $samplestring = join("", @charlist) . $charlist[$#charlist];
-
- # Typeset the string starting at horizontal offset 0.
- $displaycode .= sprintf "0 0 moveto\n";
- $displaycode .= "/$fontname ($samplestring) print-char-widths\n";
-}
-
-# Dvips scales the page. Determine the scaling it uses.
-$displaycode .= <<'ENDDISPLAYCODE';
-(CURRENTMATRIX: ) print
-matrix currentmatrix ==
-(\n) print
-eop
-end
-ENDDISPLAYCODE
- ;
-
-# Replace the bulk of the PostScript file with the display code.
-if ($output_width_ps !~ s/(?:\%\%Page|\%DVIPSSectionPage):.*(\%\%Trailer|\%DVIPSSectionTrailer)/$displaycode$1/s) {
- print STDERR 'No %%Page and/or %%Trailer comments were found. Looking for a suitable TeXDict begin.', "\n" if $verbose >= 3;
- if ($output_width_ps =~ s/TeXDict begin\s+\d+\s+\d+\s+bop.*eop\s+end/\n$displaycode\n/s) {
- print STDERR "Found a suitable TeXDict begin!\n" if $verbose >= 3;
- } else {
- print STDERR "Failed to find a suitable TeXDict begin.\n" if $verbose >= 3;
- die "${progname}: Unable to inject display code\n";
- }
-}
-
-# Output the modified PostScript code to a temporary file, run
-# Ghostscript on the temporary file, and process Ghostscript's output.
-my ($psfile, $psfilename) = tempfile ("pkfix-helper-XXXXXX",
- DIR => File::Spec->tmpdir(),
- SUFFIX => ".ps");
-binmode $psfile;
-print $psfile $output_width_ps;
-close $psfile;
-undef $output_width_ps;
-my %fontwidth; # Map from font name to character number to character width
-my @previnfo = ("", 0.0); # Previous font name and final character position
-my $gscmd = "$GS -dNOPAUSE -dBATCH -dNODISPLAY $psfilename";
-print STDERR "Finding character widths ... " if $verbose >= 1;
-print STDERR "\n Invoking: $gscmd\n" if $verbose >= 2;
-print STDERR "done.\n" if $verbose >= 1;
-open (GSCMD, "$gscmd|") || die "${progname}: failed to fork ($!)\n";
-my @gs_output; # Ghostscript diagnostic messages, to output on error
-while (my $oneline = <GSCMD>) {
- if ($oneline =~ /FONT: (\S+)\s*CHAR: (\d+)\s*XPOS: (\S+)/o) {
- my ($fontname, $charnum, $xpos) = ($1, $2, $3);
- my $width = $xpos + 0.0;
- $width -= $previnfo[1] if $fontname eq $previnfo[0];
- $fontwidth{$fontname}->{$charnum} = $width * 72.27 / $dpi;
- @previnfo = ($fontname, $xpos);
- }
- elsif ($oneline =~ /CURRENTMATRIX: \[\s*([-\d.]+)\s+[-\d.]+\s+[-\d.]+\s+([-\d.]+)\s+[-\d.]+\s+[-\d.]+\s*\]/o) {
- $dvips_xscale = $1 * 1.0;
- $dvips_yscale = $2 * -1.0;
- }
- else {
- push @gs_output, $oneline;
- }
-}
-close GSCMD || do {
- foreach my $ln (@gs_output) {
- print STDERR $ln;
- }
- die "${progname}: failed to run $GS ($!)\n";
-};
-unlink $psfilename;
-die "${progname}: No character-width information was found\n" if !%fontwidth;
-
-# Read TFM font metrics from a cache file if specified.
-read_tfm_cache_file() if defined $tfm_cache_file;
-
-# Read each TFM file and store its design size and character widths.
-print STDERR "Reading TFM files ... " if $verbose;
-print STDERR "\n" if $verbose >= 2;
-foreach my $tfm (sort {$a cmp $b}
- unique_items map {$_->{"tfm"}} (@tfmlist, map {@$_} values %fontmatch)) {
- my ($designsize, %num2widths) = @{tfm2widths $tfm};
- if (%num2widths) {
- $tfmfontwidth{$tfm} = \%num2widths;
- $tfm2size{$tfm} = $designsize * 1.0;
- }
- else {
- $tfmmissing{$tfm} = 1;
- }
-}
-
-# Remove nonexistent fonts from @tfmlist and replace all absolute
-# ("@") scaling with relative ("X") scaling.
-my @goodtfmlist;
-foreach my $tfminfo (@tfmlist) {
- my $tfm = $tfminfo->{"tfm"};
- next if !defined ($tfmfontwidth{$tfm});
- $tfminfo->{"designsize"} = $tfm2size{$tfm};
- if ($tfminfo->{"scale_type"} eq "@") {
- # Convert absolute to relative sizes.
- $tfminfo->{"scale_type"} = "X";
- $tfminfo->{"scale"} /= $tfminfo->{"designsize"};
- }
- push @goodtfmlist, $tfminfo;
-}
-@tfmlist = @goodtfmlist;
-undef @goodtfmlist;
-
-# Do the same for all user-specified font mappings but abort if none
-# of the specified possibilities represent a valid TFM file.
-while (my ($fontname, $tfmlist) = each %fontmatch) {
- my $anyvalid = 0;
- foreach my $tfminfo (@$tfmlist) {
- my $tfm = $tfminfo->{"tfm"};
- next if !defined ($tfmfontwidth{$tfm});
- $tfminfo->{"designsize"} = $tfm2size{$tfm};
- if ($tfminfo->{"scale_type"} eq "@") {
- # Convert absolute to relative sizes.
- $tfminfo->{"scale_type"} = "X";
- $tfminfo->{"scale"} /= $tfminfo->{"designsize"};
- }
- $anyvalid = 1;
- }
- if (!$anyvalid) {
- print STDERR "failed.\n" if $verbose;
- die "${progname}: Unable to utilize any of the TFM files specified for font $fontname\n";
- }
-}
-
-# Report the number of fonts in our repertoire.
-my $numtfms = keys %tfm2size;
-my $numfonts = 1 + $#tfmlist;
-print STDERR "done ($numtfms TFMs in $numfonts scaling variations).\n" if $verbose;
-die "${progname}: No TFM files were processed successfully\n" if !$numtfms;
-
-# Write the TFM font metrics to a a cache file if specified.
-write_tfm_cache_file() if defined $tfm_cache_file;
-
-# Compare every document font (ordered by decreasing number of
-# characters utilized) to every TFM file (in increasing order of
-# obscurity).
-print STDERR "Matching fonts:\n" if $verbose;
-my %already_used_tfms; # Set of TFM files already assigned to a document font, empty unless --no-repeats was specified
-foreach my $fontname (@sortedfontnames) {
- my @besttfms; # Best matching TFM file(s), sizes, and scales
- my $bestmatch = $no_match; # Best matching value
- my @besttfms_rep; # Best matching but repeated TFM file(s), sizes, and scales
- my $bestmatch_rep = $no_match; # Best matching repeated value
-
- # Don't substitute the font if we were told not to.
- if (defined $retained_t3s{$fontname}) {
- print STDERR " Retaining $fontname as a bitmapped font.\n" if $verbose == 1;
- next;
- }
-
- # Determine the list of eligible fonts to compare against.
- my @eligible_tfms;
- foreach my $tfminfo ($fontmatch{$fontname} ? @{$fontmatch{$fontname}} : @tfmlist) {
- if ($tfminfo->{"scale"} eq "*") {
- # Replace "*" with the best scaling factor we can find.
- next if !defined $tfmfontwidth{$tfminfo->{"tfm"}};
- my $newscale = optimal_scale $fontwidth{$fontname}, $tfmfontwidth{$tfminfo->{"tfm"}};
- if (defined $newscale) {
- # Replace the "*" with the optimal multiplier.
- my %newtfminfo = %$tfminfo;
- $newtfminfo{"scale"} = $newscale;
- push @eligible_tfms, \%newtfminfo;
- }
- else {
- # Fonts are incomparable.
- my $tfm = $tfminfo->{"tfm"};
- print STDERR " Not scaling $tfm; ${fontname}'s character set is not a subset of ${tfm}'s.\n" if $verbose >= 2;
- }
- }
- else {
- # The desired scaling factor is specified explicitly.
- push @eligible_tfms, $tfminfo;
- }
- }
- die "${progname}: No fonts are eligible to match $fontname\n" if !@eligible_tfms;
-
- # Try each TFM file in increasing order of obscurity.
- print STDERR " Processing $fontname ... " if $verbose == 1;
- foreach my $tfminfo (@eligible_tfms) {
- my $tfm = $tfminfo->{"tfm"};
- next if !defined $tfmfontwidth{$tfm};
- my $scale = $tfminfo->{"scale"};
- printf STDERR " Comparing %s and %s \@ %.5gX ... ", $fontname, $tfm, $scale if $verbose >= 2;
- my $match = compare_maps $fontwidth{$fontname}, $tfmfontwidth{$tfm}, $scale;
- if (defined $already_used_tfms{$tfm}->{$scale}) {
- # Repeated TFM (and --no-repeats was specified) -- not eligible for
- # best TFM.
- if ($bestmatch_rep > $match) {
- # We found a closer match than what we had before.
- $bestmatch_rep = $match;
- @besttfms_rep = ($tfminfo);
- }
- elsif ($bestmatch_rep == $match) {
- # We found an equal match to what we had before.
- push @besttfms_rep, $tfminfo;
- }
- }
- else {
- # Non-repeated TFM -- eligible for best TFM.
- if ($bestmatch > $match) {
- # We found a closer match than what we had before.
- $bestmatch = $match;
- @besttfms = ($tfminfo);
- }
- elsif ($bestmatch == $match) {
- # We found an equal match to what we had before.
- push @besttfms, $tfminfo;
- }
- }
- if ($verbose >= 2) {
- if ($match == $no_match) {
- print STDERR "done (disjoint character sets).\n";
- }
- else {
- printf STDERR "done (mismatch=%.5f).\n", $match;
- }
- }
- }
-
- # Select the first of the best matches.
- $fontmatch{$fontname} = $besttfms[0];
- my $besttfminfo = $fontmatch{$fontname};
- my $besttfm = $besttfminfo->{"tfm"};
- my $bestscale = $besttfminfo->{"scale"};
-
- # Report how good or bad the match is and what other close matches the user
- # might consider instead.
- if ($verbose >= 2) {
- my $forced_str = defined $is_forced{$fontname} ? ", forced by user," : "";
- if ($bestmatch == $no_match) {
- # No match was found.
- printf STDERR " No match was found for %s%s.\n", $fontname, $forced_str;
- }
- elsif ($#besttfms == 0) {
- # There was a single winner.
- printf STDERR " Best match for %s%s is %s \@ %.5gX with mismatch=%.5f.\n",
- $fontname, $forced_str, $besttfm, $bestscale, $bestmatch;
- }
- else {
- # There was a tie for first place.
- my $preposition = $#besttfms == 1 ? "between" : "among";
- printf STDERR " Best match for %s%s is %s \@ %.5gX (tied %s %s) with mismatch=%.5f.\n",
- $fontname, $forced_str, $besttfm, $bestscale, $preposition,
- join_string_list(map {sprintf "%s \@ %.5gX", $_->{"tfm"}, $_->{"scale"}} @besttfms),
- $bestmatch;
- }
- if ($bestmatch_rep < $bestmatch ||
- ($bestmatch < $no_match && $bestmatch_rep <= $bestmatch)) {
- # A repeated font would have matched equally well (excluding
- # failures to match at all) or better.
- printf STDERR " Ignored repeated %s %s with mismatch=%.5f.\n",
- $#besttfms_rep == 0 ? "font" : "fonts",
- join_string_list(map {sprintf "%s \@ %.5gX", $_->{"tfm"}, $_->{"scale"}} @besttfms_rep),
- $bestmatch_rep;
- }
- }
- elsif ($verbose == 1) {
- if ($bestmatch == $no_match) {
- print STDERR "done (no match found";
- }
- else {
- printf STDERR "done (%s \@ %.5gX with mismatch=%.5f", $besttfm, $bestscale, $bestmatch;
- }
- print STDERR ", forced by user" if defined $is_forced{$fontname};
- if ($#besttfms > 0 && $bestmatch != $no_match) {
- # There was a tie for first place.
- printf STDERR ", tied with %s",
- join_string_list(map {sprintf "%s \@ %.5gX", $_->{"tfm"}, $_->{"scale"}} @besttfms[1..$#besttfms]);
- }
- if ($bestmatch_rep < $bestmatch ||
- ($bestmatch < $no_match && $bestmatch_rep <= $bestmatch)) {
- # A repeated font would have matched equally well (excluding
- # failures to match at all) or better.
- printf STDERR "; ignored %s %s with mismatch=%.5f",
- $#besttfms_rep == 0 ? "repeat" : "repeats",
- join_string_list(map {sprintf "%s \@ %.5gX", $_->{"tfm"}, $_->{"scale"}} @besttfms_rep),
- $bestmatch_rep;
- }
- print STDERR ").\n";
- }
- if ($bestmatch == $no_match) {
- warn "${progname}: ${fontname} uses characters that don't appear in any candidate font\n";
- }
- elsif ($bestmatch >= 1.0) {
- warn "${progname}: Best match for $fontname is rather poor\n";
- }
- printf STDERR "\n" if $verbose >= 2; # Warnings should precede the inter-font newline character.
-
- # If --no-repeats was specified, mark the font as having been used.
- if ($single_font_use) {
- $already_used_tfms{$besttfm}->{$bestscale} = 1;
- }
-}
-
-# Merge all sections into a single section to avoid confusing pkfix.
-if ($#sections > 0) {
- my $numreplacements = 0;
- $entirefile =~ s/(TeXDict begin)\s+(\d+ \d+ \d+ \d+ \d+(?: \([^\)]*\))?\s+\@start\s+bos)/$numreplacements++ ? "" : "$1\n$2"/gse;
- $entirefile =~ s/eos\s+end//gs;
- $entirefile =~ s/(.*)(\%DVIPSEndSection)/$1eos end\n$2/s;
-}
-
-# Insert %DVIPSBitmapFont comments around every Type 3 font definition.
-my $commented_ps = $entirefile;
-my $infilename_ps = $infilename; # PostScript version of $infilename
-$infilename_ps =~ s/([\(\)\\])/\\$1/g;
-$commented_ps =~ s|^\%(End)?DVIPSBitmapFont.*$||gm; # Remove existing comments (if any)
-$commented_ps =~ s|/([^()<>\[\]{}\/\%]+)\s+\d+\s+\d+\s+df.*?>[^<]*?[DI]\s+E|write_comments($1, $&)|gse;
-if ($commented_ps !~ /\%\%EndProlog/) {
- # pkfix fails silently if it doesn't see an %%EndProlog.
- print STDERR "No %%EndProlog comment was found. Adding one.\n" if $verbose >= 3;
- $commented_ps =~ s|TeXDict begin\s+\d+\s+\d+\s+bop|\%\%EndProlog\n$&|s;
-}
-
-# Help pkfix handle ancient versions of dvips by artificially making
-# dvips look newer.
-$commented_ps =~ s|(\%\%Creator: dvips\S*) \S+|$1 5.62|; # pkfix rejects dvips <= 5.58
-if ($commented_ps =~ s|(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\@start|$1 $2 $3 $4 $5 ($infilename_ps) \@start|gx) {
- # pkfix expects *six* arguments to @start, not five as in old
- # versions of dvips.
- $commented_ps =~ s|/\@start\s*\{|$& pop |;
-}
-if ($commented_ps !~ /^%DVIPSParameters:.*dpi=([\dx]+)/) {
- # Tell pkfix what resolution to use.
- my $dvips_params = "\%DVIPSParameters: dpi=$dpi";
- if ($commented_ps !~ s|^\%\%EndComments.*$|$&\n$dvips_params|m) {
- # Comments must have been stripped.
- $commented_ps =~ s|\n|\n$dvips_params\n|;
- }
-}
-
-# Write the modified PostScript code to the specified file.
-open (OUTFILE, ">$outfilename") || die "${progname}: Unable to open $outfilename ($!)\n";
-print OUTFILE $commented_ps;
-close OUTFILE;
-undef $commented_ps;
-
-# If the user requested a PostScript font sample, produce that.
-if (defined $sample_file_ps) {
- # Insert some helper code at an appropriate place in the file.
- my $sample_ps = $entirefile;
- my $showfontnamecode = <<"SHOWFONTNAME";
-\%\%BeginProcSet: $progname.pro
-TeXDict begin
-
-% font-name sample-string PRINT-FONT-SAMPLE -
-%
-% Store the name of font-name in the string font-name-string. Then,
-% output font-name-string in Times Bold in case the user wants to view
-% the font samples. Next, select font-name and output the sample
-% string. Finally, move the cursor to the next line in preparation for
-% the next invocation of print-font-sample.
-/print-font-sample {
- /sample-string exch def
- /font-name exch def
- font-name 8 string cvs /font-name-string exch def
- gsave
- /Times-Bold 12 selectfont
- font-name-string show (:) show
- grestore
- gsave
- $xinc 0 rmoveto
- font-name cvx exec
- currentfont bitmap-font-transform makefont setfont
- sample-string show
- grestore
- 0 -$yinc rmoveto
-} def
-
-\% Define a transformation matrix for dvips bitmapped fonts. We _could_
-\% do this dynamically but there seems to be a bug in GhostView (v3.6.1)
-\% or GhostScript (ESP v7.07.1) that causes the page layout to change
-\% with rescaling. To avoid problems we simply hardwire the scaling
-\% factor.
-/bitmap-font-transform [$dvips_xscale 0.0 0.0 $dvips_yscale 0 0] def
-
-end
-\%\%EndProcSet
-SHOWFONTNAME
- ;
- if ($sample_ps !~ s/\%\%BeginProcSet: tex\w*\.pro.*?\%\%EndProcSet/$&\n$showfontnamecode/s) {
- print STDERR "No tex.pro ProcSet was found. Looking for a suitable TeXDict begin.\n" if $verbose >= 3;
- if ($sample_ps =~ s/TeXDict begin\s+\d+\s+\d+\s+bop/\n$showfontnamecode\n$&/s) {
- print STDERR "Found a suitable TeXDict begin!\n" if $verbose >= 3;
- }
- else {
- print STDERR "Failed to find a suitable TeXDict begin.\n" if $verbose >= 3;
- die "${progname}: Unable to inject prologue code\n";
- }
- }
-
- # Generate code to output a sample of each font in turn.
- my $displaycode = <<"PAGEHEADER";
-\%\%Page: 1 1
-TeXDict begin
-1 0 bop
-
-\% Display a page title.
-0 0 moveto
-initmatrix
-0 -9.962 rmoveto
-gsave
- /Helvetica 18 selectfont
- (Fonts used by $infilename_ps) show
-grestore
-0 -18 rmoveto
-0 -$init_yinc rmoveto
-
-\% Display samples of each document font in decreasing order of the number
-\% of characters utilized from the font.
-PAGEHEADER
-;
- my $pageno = 1;
- foreach my $fontnum (0 .. $#sortedfontnames) {
- my $fontname = $sortedfontnames[$fontnum];
- my $samplestring = join("", psify @{$name2chars{$fontname}});
- $displaycode .= "/$fontname ($samplestring) print-font-sample\n";
- if ($fontnum % $samples_per_page == $samples_per_page-1
- && $fontnum != $#sortedfontnames) {
- # Insert a page break after every $samples_per_page font samples.
- $pageno++;
- $displaycode .= <<"PAGETRANSITION";
-eop
-end
-\%\%Page: $pageno $pageno
-TeXDict begin
-$pageno @{[$pageno-1]} bop
-0 0 moveto
-initmatrix
-0 -9.962 rmoveto
-PAGETRANSITION
-;
- }
- }
- $displaycode .= "eop\nend\n";
- if ($sample_ps !~ s/(?:\%\%Page|\%DVIPSSectionPage):.*(\%\%Trailer|\%DVIPSSectionTrailer)/$displaycode$1/s) {
- print STDERR 'No %%Page and/or %%Trailer comments were found. Looking for a suitable TeXDict begin.', "\n" if $verbose >= 3;
- if ($sample_ps =~ s/TeXDict begin\s+\d+\s+\d+\s+bop.*eop\s+end/\n$displaycode\n/s) {
- print STDERR "Found a suitable TeXDict begin!\n" if $verbose >= 3;
- }
- else {
- print STDERR "Failed to find a suitable TeXDict begin.\n" if $verbose >= 3;
- die "${progname}: Unable to inject display code\n";
- }
- }
-
- # Write the PostScript file.
- open (SAMPLE_PS, ">$sample_file_ps") || die "${progname}: Unable to open $sample_file_ps ($!)\n";
- binmode SAMPLE_PS;
- print SAMPLE_PS $sample_ps;
- close SAMPLE_PS;
- undef $sample_ps;
-}
-
-# If the user requested a TeX font sample, produce that.
-if (defined $sample_file_tex) {
- my $oneline; # One line to write to the TeX file.
-
- open (SAMPLE_TEX, ">$sample_file_tex") || die "${progname}: Unable to open $sample_file_tex ($!)\n";
- select (SAMPLE_TEX);
- $| = 1;
- select (STDOUT);
- format SAMPLE_TEX =
-% ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
-$oneline
-.
- $oneline = <<"TEX_HEADER";
-This file was generated by $0. DO NOT EDIT. Edit $progname instead.
-Note that this is a Plain TeX document. Compile it with tex, *not*
-latex.
-TEX_HEADER
- ;
- write SAMPLE_TEX;
-
- my $set_tex_paper_size = <<'SET_TEX_PAPER_SIZE';
-
-% Set the paper size to match that of the original PostScript file.
-% There is no standard mechanism for doing so we include a case for
-% each of the major TeX engines.
-\def\ifIhave#1#2#3{\expandafter\ifx\csname #1\endcsname\relax#3\else#2\fi}
-\ifIhave{pagewidth}{%
- % LuaTeX
- \pagewidth=<WIDTH>%
- \pageheight=<HEIGHT>%
-}{%
- \ifIhave{pdfpagewidth}{%
- % pdfTeX and XeTeX
- \pdfpagewidth=<WIDTH>%
- \pdfpageheight=<HEIGHT>%
- }{%
- % TeX + dvips
- \special{papersize=<WIDTH>,<HEIGHT>}%
- }%
-}
-
-SET_TEX_PAPER_SIZE
- ;
- $set_tex_paper_size =~ s/<WIDTH>/$psize[0]pt/g;
- $set_tex_paper_size =~ s/<HEIGHT>/$psize[1]pt/g;
- print SAMPLE_TEX $set_tex_paper_size;
-
- print SAMPLE_TEX <<'TEX_BOILERPLATE';
-% Make printable all special characters between
-% \makeprintable...\endmakeprintable except for "\", "{", and "}".
-\def\makeprintable{%
- \begingroup
- \def\do##1{\catcode`##1=12}%
- \dospecials
- \catcode`\\=0\relax
- \catcode`\{=1\relax
- \catcode`\}=2\relax
-}
-\let\endmakeprintable=\endgroup
-
-% Put a piece of text at specific PostScript coordinates.
-\newdimen\xofs
-\newdimen\yofs
-\def\put(#1,#2)#{%
- \leavevmode
- \begingroup
- \makeprintable
- \xofs=#1bp
- \yofs=#2bp
- \afterassignment\puthelper
- \toks0=%
-}
-\def\puthelper{%
- \lower\yofs
- \rlap{\hskip\xofs\the\toks0}%
- \endmakeprintable
- \endgroup
-}
-
-% We use Times Bold at 12 point for font names and Times Roman at 8 point
-% for tagging fonts controlled explicitly by the user.
-\font\timesbXII=ptmb at 12bp
-\font\timesVIII=ptmr at 8bp
-
-% Don't add extra space to paragraphs.
-\parindent=0pt
-\parskip=0pt
-
-% Output the document's title.
-\font\somefont=phvr at 18bp\somefont
-TEX_BOILERPLATE
- ;
- # Output the document's title.
- my $infilename_tex = texify split "", $infilename;
- print SAMPLE_TEX '\put(0, 0){New fonts to use for ', "$infilename_tex}\n";
-
- # Output samples of each font in turn.
- print SAMPLE_TEX "\n\% Output font samples.\n";
- my $firstfontnum = 0;
- foreach my $fontnum (0 .. $#sortedfontnames) {
- # Output a single font sample.
- my $fontname = $sortedfontnames[$fontnum];
- my $samplestring = texify @{$name2chars{$fontname}};
- my $yoffset = ($fontnum-$firstfontnum)*$yinc;
- $yoffset += $init_yinc if $firstfontnum == 0;
- if (defined $retained_t3s{$fontname}) {
- printf SAMPLE_TEX "\\timesVIII\\put(-15, %d){(k)}%%\n", $yoffset-1;
- }
- elsif (defined $is_forced{$fontname}) {
- printf SAMPLE_TEX "\\timesVIII\\put(-15, %d){(f)}%%\n", $yoffset-1;
- }
- printf SAMPLE_TEX "\\timesbXII\\put(0, %d){%s:}%%\n", $yoffset, $fontname;
- if (defined $fontmatch{$fontname}) {
- my $tfm = $fontmatch{$fontname}->{"tfm"};
- my $scale = $fontmatch{$fontname}->{"scale"};
- my $size = $tfm2size{$tfm};
- printf SAMPLE_TEX "\\font\\somefont=%s%s\\somefont\n",
- $tfm, $scale==1.0 ? "" : sprintf(" at %.5gpt", $scale*$size);
- printf SAMPLE_TEX "\\put(%d, %d){%s}%%\n", $xinc, $yoffset, $samplestring;
- }
- if ($fontnum%$samples_per_page == $samples_per_page - 1) {
- # Insert a page break after every $samples_per_page font samples.
- print SAMPLE_TEX "\\vskip 0pt plus 1fill\\eject\n";
- $firstfontnum = $fontnum + 1;
- }
- }
-
- # Complete the TeX file.
- print SAMPLE_TEX "\n\\bye\n";
- close SAMPLE_TEX;
-}
-
-###########################################################################
-
-__END__
-
-=head1 NAME
-
-pkfix-helper - preprocess dvips-produced PostScript documents before passing them to pkfix
-
-
-=head1 SYNOPSIS
-
-pkfix-helper
-[B<--help>]
-[B<--verbose>]
-[B<--force>=I<name>=I<fontspec>]
-[B<--ps>=I<filename.ps>]
-[B<--tex>=I<filename.tex>]
-[B<--cache>=I<filename>]
-[B<--include>=I<fontspec>]
-[B<--exclude>=I<regexp>]
-[B<--keep>=I<fontspec>]
-[B<--quiet>]
-[B<--no-repeats>]
-[B<--spp>=I<number>]
-[I<input.ps> [I<output.ps>]]
-
-
-=head1 DESCRIPTION
-
-=head2 Motivation
-
-PostScript documents created with old versions of B<dvips> almost
-invariably utilize bitmapped (PostScript S<Type 3>) fonts. The
-problem with bitmapped fonts is that they target a specific device
-resolution; a PostScript file produced using S<300 DPI> fonts will
-look grainy on a S<600 DPI> printer. Even worse, I<all> bitmapped
-fonts look grainy when zoomed in on screen. The solution is to use
-vector (PostScript S<Type 1>) fonts, which are resolution-independent
-and appear crisp at any size or scale.
-
-While it is no longer difficult to configure B<dvips> to use vector
-fonts, it is not always possible to rerun B<dvips> on an old F<.dvi>
-file. The F<.dvi> file and document source may have been lost; or,
-the source may no longer compile because packages it depends upon may
-no longer be available.
-
-Heiko Oberdiek's B<pkfix> script replaces bitmapped fonts in
-B<dvips>-produced PostScript files with the corresponding vector
-fonts. It works by parsing the PostScript comments with which
-B<dvips> surrounds bitmapped-font definitions. For example, a font
-definition beginning with the comment C<%DVIPSBitmapFont: Fi cmss10 11
-28> and ending with a matching C<%EndDVIPSBitmapFont> is known to
-define font C<Fi> as C<cmss10> (Computer Modern Sans Serif at a design
-size of S<10 points>) scaled to S<C<11> points>. Only the C<28>
-characters actually used by the document are defined. B<pkfix> then
-replaces the font definition with one that defines C<Fi> using the
-same set of characters but taken from the F<cmss10.pfb> vector font
-file.
-
-Unfortunately, B<pkfix> works only with versions of B<dvips> newer
-than v5.58 S<(ca. 1996)>. Naturally, the older a PostScript document,
-the less likely its sources still exist and can still be recompiled.
-Older versions of B<dvips> lack C<%DVIPSBitmapFont> comments and
-various other PostScript comments on which B<pkfix> relies. Without
-PostScript comments to guide it, B<pkfix> is unable to determine which
-vector fonts correspond with which bitmapped fonts.
-
-=head2 Overview
-
-The B<pkfix-helper> script is a preprocessor for B<pkfix> that
-attempts to determine the association between each document-font name
-S<(e.g., C<Fi>)> in a PostScript file and the original font S<(e.g.,
-C<cmss10>)> and fonts size (e.g., S<C<11> points>). It then
-fabricates the PostScript comments that B<pkfix> expects to see so
-that B<pkfix> can do its job.
-
-B<pkfix-helper> works by comparing every document font against every
-F<.tfm> font file it knows about (assuming that each such font has a
-corresponding F<.pfb> vector version) and selecting the best matching
-F<.tfm> file for every document font. B<pkfix-helper> has access only
-to the widths of characters and only to those characters actually used
-in the document. Also, the program recognizes only a limited set of
-the most popular F<.tfm> files and scaling factors. Consequently, the
-comparison is imperfect and B<pkfix-helper> may attribute an incorrect
-font to a given name. Fonts comprising only one or two characters
-actually used in a document are particularly problematic for
-B<pkfix-helper> because many fonts may be near-enough matches to fool
-the problem.
-
-B<pkfix-helper> is designed so that a user can guide the
-font-selection process by manually designating matching fonts. With a
-modicum of diligence and patience a user can correct any mismatched
-fonts and help the program provide proper input to B<pkfix>.
-
-
-=head1 OPTIONS
-
-B<pkfix-helper> accepts on the command line the filename of a
-PostScript document to process (with the default being the standard
-input device) and the filename of a modified PostScript document to
-create (with the default being the standard output device). The
-program also accepts the following command-line options:
-
-=head2 Frequently Used Options
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display usage information and exit. The B<--verbose> and B<--quiet>
-options can be used to increase and decrease the amount of information
-presented.
-
-=item B<-v>, B<--verbose>
-
-Increase the amount of status information that B<pkfix-helper>
-displays as it runs. Additional instances of B<--verbose> on the
-command line further increase the program's verbosity. By default,
-only major operations are displayed. A single B<--verbose>
-additionally displays information about individual font comparisons.
-A second B<--verbose> additionally displays details about some of the
-program's internal operations.
-
-=item B<-f> I<name>=I<fontspec>, B<--force>=I<name>=I<fontspec>
-
-Force B<pkfix-helper> to associate a specific font with a given font
-name appearing the document. I<name> is a (usually) two-character
-B<dvips> font name such as C<Fa>. I<fontspec> is a font specification
-that comprises a font name and an optional scale: "I<font> S<[C<@>
-I<scale>]>". Some examples of I<fontspec>s are C<cmmi8> and
-S<C<cmsy10 @ 1.1X>>.
-
-An asterisk used in the name of the font S<(e.g., C<cmti*>)> will be
-replaced by all integers from 5 to 17 (C<cmti5>, S<C<cmti6>, ...,>
-C<cmti17>). The scale can be written as a multiple of the design size
-(C<X>) or as an absolute size in either TeX points (C<pt>) or
-PostScript "big" points (C<bp>). Hence, S<C<cmsy8 @ 1.5X>>, S<C<cmsy8
-@ 12pt>>, and S<C<cmsy8 @ 11.96bp>> all represent the I<Computer
-Modern Math Symbols 8 Point> font scaled to 12 TeX points/11.96
-PostScript points. Instead of specifying an explicit scale, an
-asterisk can be used (as in S<C<cmsy8 @ *>>) to request that
-B<pkfix-helper> find the scale that best matches the original font's
-metrics.
-
-The B<--force> option can be specified repeatedly on the command line.
-
-=item B<-p> I<filename.ps>, B<--ps>=I<filename.ps>
-
-Create a PostScript file called I<filename.ps> that shows the B<dvips>
-name and a font sample of every font used by the input document.
-
-=item B<-t> I<filename.tex>, B<--tex>=I<filename.tex>
-
-Create a Plain TeX file called I<filename.tex> that shows the B<dvips>
-name and a font sample of every font that B<pkfix-helper> used in the
-output document.
-
-=item B<-k> I<fontspec>, B<--keep>=I<fontspec>
-
-Do not substitute a vector font for bitmapped font I<fontspec> (C<Fa>,
-C<Fb>, etc.). This is useful when converting documents that use
-obscure bitmapped fonts for which there is no vector equivalent. For
-example, it was somewhat common in the past to include graphics such
-as university or corporate logos into a document by converting the
-bitmapped image into a single-character font and using that font in
-LaTeX. B<--keep> prevents such fonts from being replaced. The
-B<--keep> option can be specified repeatedly on the command line.
-
-=item B<-1>, B<--no-repeats>
-
-Prevent B<pkfix-helper> from associating the same I<fontspec> with
-more than one B<dvips> font name.
-
-=back
-
-=head2 Less-frequently Used Options
-
-=over 4
-
-=item B<-q>, B<--quiet>
-
-Instruct B<pkfix-helper> to produce no output during its run except
-for error and warning messages.
-
-=item B<-C> I<filename>, B<--cache>=I<filename>
-
-Speed up TFM file processing by caching character metrics into file
-I<filename>. On some systems it takes a long time to read a TFM file,
-spawn F<tftopl> to convert it to PL format, and extract from the PL
-data the metrics for each character. The first time B<--cache> is
-specified, B<pkfix-helper> proceeds as normal then writes all of the
-extracted character metrics to I<filename>. On subsequent runs in
-which B<--cache>=I<filename> is specified, B<pkfix-helper> reads the
-previously extracted metrics from I<filename>, going through the
-F<tftopl>-based process only for TFM files that were not previously
-encountered.
-
-=item B<-i> I<fontspec>, B<--include>=I<fontspec>
-
-Add I<fontspec> to the list of font specifications against which
-B<pkfix-helper> compares I<every> document font. (In contrast,
-B<--force> designates a font specification to use only for a
-I<specific> document font.) The B<--include> option can be specified
-repeatedly on the command line.
-
-=item B<-x> I<regexp>, B<--exclude>=I<regexp>
-
-Remove all font specifications matching regular expression I<regexp>
-from B<pkfix-helper>'s list of known fonts. The B<--exclude> option
-can be specified repeatedly on the command line.
-
-=item B<-s>, B<--spp>
-
-Specify the number of font samples per page to print to the files
-indicated using the B<--ps> and B<--tex> options. The default
-S<value, 25,> should work well in most circumstances.
-
-=back
-
-
-=head1 DIAGNOSTICS
-
-=over 4
-
-=item C<Best match for I<name> is rather poor>
-
-The best font B<pkfix-helper> found for B<dvips> font name I<name> has
-a mismatch value greater than or equal S<to 1.0>. (The mismatch value
-is the sum of the squares of the difference between the character
-widths of a document font and a potential replacement font.) Use the
-B<--force> option to designate an alternative replacement font or
-scaling amount.
-
-=item C<I<name> uses characters that don't appear in any candidate font>
-
-None of the fonts considered for a match include all of the characters
-in font I<name>. The user should use the B<--force> option to inform
-B<pkfix-helper> which font to use or the B<--keep> option to retain
-the original, bitmapped font.
-
-=item C<Processing I<name> ... done (I<font> with mismatch=I<number>, tied with I<font>...)>
-
-The best match for I<name> is font I<font>. A perfect match has a
-I<number> of 0.00000. Worse matches observe larger values. If a tie
-is reported, this means one or more fonts matched I<name> equally well
-(i.e., they see the same I<number>). In this case, B<pkfix-helper>
-selects the qualitatively most likely font as the winner.
-
-=back
-
-
-=head1 EXAMPLES
-
-For the purpose of the following examples, assume that F<oldfile.ps>
-is the name of a PostScript file produced by an old version of
-B<dvips> and utilizing at least one bitmapped font. It's always worth
-verifying that B<pkfix> can't convert the file on its own:
-
- $ pkfix oldfile.ps newfile.ps
- PKFIX 1.3, 2005/02/25 - Copyright (c) 2001, 2005 by Heiko Oberdiek.
- ==> no fonts converted
-
-(Alternatively B<pkfix> may issue an error message such as C<!!!
-Error: Parse error (@start parameters)!>.) Only when B<pkfix> can't
-replace bitmapped fonts with vector fonts is B<pkfix-helper> needed.
-In its simplest form, B<pkfix-helper> takes the name of an input file
-(F<oldfile.ps> in this example) and the name of an output file
-(F<pkfix-oldfile.ps>), which will have the same contents as the input
-file but serve as suitable input for B<pkfix>:
-
- $ pkfix-helper oldfile.ps pkfix-oldfile.ps
- Reading oldfile.ps ... done.
- Number of Type 3 fonts encountered: 10
- Bitmapped fonts are typeset at 600 DPI.
- Finding character widths ... done.
- Reading TFM files ... done (103 TFMs in 193 scaling variations).
- Matching fonts:
- Processing Fi ... done (cmr10 @ 1X, mismatch=0.11683).
- Processing Fa ... done (cmti10 @ 1X, mismatch=0.08892).
- Processing Fb ... done (cmr8 @ 1X, mismatch=0.07133).
- Processing Ff ... done (cmbx12 @ 1.2X, mismatch=0.02948).
- Processing Fh ... done (cmtt10 @ 1X, mismatch=0.06895).
- Processing Fd ... done (cmmi10 @ 1X, mismatch=0.03966).
- Processing Fj ... done (cmbx12 @ 1X, mismatch=0.03972).
- Processing Fe ... done (cmbx10 @ 1X, mismatch=0.00762).
- Processing Fg ... done (cmsy10 @ 1X, mismatch=0.00875).
- Processing Fc ... done (cmr6 @ 1X, mismatch=0.00284).
-
- $ pkfix pkfix-oldfile.ps newfile.ps
- PKFIX 1.3, 2005/02/25 - Copyright (c) 2001, 2005 by Heiko Oberdiek.
- *** Font conversion: `cmti10' -> `CMTI10'.
- *** Font conversion: `cmr8' -> `CMR8'.
- *** Font conversion: `cmr6' -> `CMR6'.
- *** Font conversion: `cmmi10' -> `CMMI10'.
- *** Font conversion: `cmbx10' -> `CMBX10'.
- *** Font conversion: `cmbx12' -> `CMBX12'.
- *** Font conversion: `cmsy10' -> `CMSY10'.
- *** Font conversion: `cmtt10' -> `CMTT10'.
- *** Font conversion: `cmr10' -> `CMR10'.
- *** Font conversion: `cmbx12' -> `CMBX12'.
- *** Merging font `CMBX12' (2).
- ==> 10 converted fonts.
- ==> 1 merged font.
-
-Although B<pkfix-helper> tries to automate as much as possible the
-font-detection process, some fonts will invariably be incorrectly
-identified. The program outputs a warning message if it I<knows> a
-match is bad but the lack of a warning message does not necessarily
-indicate that B<pkfix-helper> did a good job. It is therefore
-strongly recommended that the user produce "before" and "after" font
-sheets:
-
- $ pkfix-helper -q oldfile.ps pkfix-oldfile.ps \
- --ps=oldfonts.ps --tex=newfonts.tex
-
- $ tex newfonts.tex
- This is TeX, Version 3.14159 (Web2C 7.4.5)
- (./newfonts.tex [1] )
- Output written on newfonts.dvi (1 page, 1292 bytes).
- Transcript written on newfonts.log.
-
- $ dvips newfonts.dvi -o newfonts.ps
- This is dvips(k) 5.92b Copyright 2002 Radical Eye Software (www.radicaleye.com)
- ' TeX output 2006.06.11:1636' -> newfonts.ps
- <texc.pro><8r.enc><texps.pro>. <cmr6.pfb><cmsy10.pfb><cmbx10.pfb><cmbx12.pfb>
- <cmmi10.pfb><cmtt10.pfb><cmr8.pfb><cmti10.pfb><cmr10.pfb>[1]
-
-After running the preceding commands, F<oldfonts.ps> shows samples of
-the fonts in F<oldfile.ps> and F<newfonts.ps> shows samples of the
-replacement fonts that B<pkfix-helper> used to produce
-F<pkfix-oldfile.ps>. Print F<oldfonts.ps> and F<newfonts.ps> and
-compare them carefully for incorrect fonts and sizes.
-
-Suppose that the choice of C<cmbx12 @ 1.2X> for font C<Ff> looks
-wrong; say the characters look taller in F<oldfonts.ps> than in
-F<newfonts.ps>. This is where the trial-and-error stage begins.
-Let's hypothesize that C<cmb12> is a better match than C<cmbx12> but
-we don't know how much to scale the font. Fortunately,
-B<pkfix-helper> allows C<*> to be used as a scaling factor to tell the
-program to automatically detect an optimal scaling factor, even if
-doing so means choosing a nonstandard font size:
-
- $ pkfix-helper oldfile.ps pkfix-oldfile.ps --force="Ff=cmb12 @ *"
- Reading oldfile.ps ... done.
- Number of Type 3 fonts encountered: 10
- Bitmapped fonts are typeset at 600 DPI.
- Finding character widths ... done.
- Reading TFM files ... failed.
- pkfix-helper: Unable to process user-specified TFM file "cmb12"
-
-Oops, it looks like we don't have a F<cmb12.tfm> file on our system.
-Let's try scaling up F<cmb10.tfm> instead:
-
- $ pkfix-helper oldfile.ps pkfix-oldfile.ps --force="Ff=cmb10 @ *"
- Reading oldfile.ps ... done.
- Number of Type 3 fonts encountered: 10
- Bitmapped fonts are typeset at 600 DPI.
- Finding character widths ... done.
- Reading TFM files ... done (103 TFMs in 193 scaling variations).
- Matching fonts:
- Processing Fi ... done (cmr10 @ 1X, mismatch=0.11683).
- Processing Fa ... done (cmti10 @ 1X, mismatch=0.08892).
- Processing Fb ... done (cmr8 @ 1X, mismatch=0.07133).
- Processing Ff ... done (cmb10 @ 1.5X, mismatch=0.00035).
- Processing Fh ... done (cmtt10 @ 1X, mismatch=0.06895).
- Processing Fd ... done (cmmi10 @ 1X, mismatch=0.03966).
- Processing Fj ... done (cmbx12 @ 1X, mismatch=0.03972).
- Processing Fe ... done (cmbx10 @ 1X, mismatch=0.00762).
- Processing Fg ... done (cmsy10 @ 1X, mismatch=0.00875).
- Processing Fc ... done (cmr6 @ 1X, mismatch=0.00284).
-
-The match has definitely improved, although S<15 pt.> is certainly an
-odd size for a font. Then again, many documents I<do> use nonstandard
-sizes so this may in fact be correct. The best way to verify is once
-again to produce, print, and compare a pair of font samples and
-iterate until all of the fonts look correct. Use one instance of
-B<--force> for each font you want to alter.
-
-
-=head1 ENVIRONMENT
-
-B<pkfix-helper> honors the following environment variables:
-
-=over 8
-
-=item GS
-
-The name of the Ghostscript interpreter (default: F<gs>)
-
-=item TFTOPL
-
-The name of a utility for converting F<.tfm> files to F<.pl> files
-(default: F<tftopl>)
-
-=back
-
-
-=head1 RESTRICTIONS
-
-B<pkfix-helper> works only with PostScript files produced by B<dvips>,
-not with arbitrary PostScript files. Only bitmapped fonts loaded by
-B<dvips> can be analyzed, not bitmapped fonts loaded by embedded
-graphics.
-
-B<pkfix-helper> works by comparing character widths, not the actual
-glyphs. Consequently, it is misled by sets of fonts with similar
-character widths (at least for those characters used by a given
-document). As an extreme example, all Computer Modern Teletype fonts
-of a given design size (e.g., C<cmtt10>, C<cmsltt10>, and C<cmitt10>)
-use exactly the same widths for all characters. Human assistance is
-generally needed to guide B<pkfix-helper>'s font-matching procedures,
-especially for fonts for which relatively few characters appear in the
-document.
-
-There is an astonishing variety of B<dvips> output. Different
-versions of the program and different command-line options can result
-in PostScript files with a completely different structure.
-B<pkfix-helper> works hard to find font information buried in numerous
-output-file variants, but it is not uncommon for a PostScript file
-produced by a sufficiently old version of B<dvips> or with
-sufficiently obscure command-line options to utterly confuse
-B<pkfix-helper>. In this case, please send your problematic
-PostScript files to the author of B<pkfix-helper> (see L</AUTHOR>
-below), who may be able to enhance B<pkfix-helper> to handle them.
-
-
-=head1 NOTES
-
-Files produced using the B<--tex> option are Plain TeX files and
-therefore must be compiled with B<tex> (or a variant such as
-B<pdftex>, B<luatex>, B<xetex>, etc.), I<not> with B<latex>.
-
-B<dvips>-produced PostScript files can be structured in sections,
-demarcated by C<%DVIPSBeginSection> and C<%DVIPSEndSection>. Font
-names are local to a section. Hence, a font named C<Fa> may map to
-C<cmex10> in one section and to C<cmmi7> in another. B<pkfix-helper>
-assigns every font in a multi-section document a unique name by
-appending a section-number suffix: C<Fa_S01>, C<Fa_S02>, etc.
-
-Font names are processed in decreasing order of the number of
-characters they have represented in the document. That is, if the
-document includes 10 characters from C<Fa> and 23 characters from
-C<Fb>, B<pkfix-helper> will process C<Fb> before C<Fa>.
-
-=head1 SEE ALSO
-
-pkfix(1), dvips(1), tex(1), gs(1)
-
-PostScript Language Reference, Third Edition.
-Published by Addison-Wesley, ISBN 0-201-37922-8,
-L<http://www.adobe.com/products/postscript/pdfs/PLRM.pdf>.
-
-
-=head1 AUTHOR
-
-Scott Pakin, I<scott+pkfh@pakin.org>
-
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2009-2020, Scott Pakin
-
-This file may be distributed and/or modified under the conditions of
-the LaTeX Project Public License, either version 1.3c of this license
-or (at your option) any later version. The latest version of this
-license is in L<http://www.latex-project.org/lppl.txt> and version
-1.3c or later is part of all distributions of LaTeX version 2006/05/20
-or later.
diff --git a/Build/source/texk/texlive/linked_scripts/pkfix/pkfix.pl b/Build/source/texk/texlive/linked_scripts/pkfix/pkfix.pl
deleted file mode 100755
index 83f8721cb7a..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pkfix/pkfix.pl
+++ /dev/null
@@ -1,886 +0,0 @@
-eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
- if 0;
-use strict;
-$^W=1; # turn warning on
-#
-# pkfix.pl
-#
-# Copyright (C) 2001, 2005, 2007, 2009, 2011, 2012 Heiko Oberdiek.
-#
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.3
-# of this license or (at your option) any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3 or later is part of all distributions of LaTeX
-# version 2003/12/01 or later.
-# This work has the LPPL maintenance status "maintained".
-# This Current Maintainer of this work is Heiko Oberdiek.
-#
-# See file "README" for a list of files that belongs to this project.
-#
-# This file "pkfix.pl" may be renamed to "pkfix"
-# for installation purposes.
-#
-my $file = "pkfix.pl";
-my $program = uc($&) if $file =~ /^\w+/;
-my $project = lc($program);
-my $version = "1.7";
-my $date = "2012/04/18";
-my $author = "Heiko Oberdiek";
-my $copyright = "Copyright (c) 2001, 2005, 2007, 2009, 2011, 2012 by $author.";
-#
-# Reqirements: Perl5, dvips
-# History:
-# 2001/04/12 v0.1:
-# * First try.
-# 2001/04/13 v0.2:
-# * TeX/dvips is called for each font for the case of errors.
-# * First release.
-# 2001/04/15 v0.3:
-# * Call of kpsewhich with option --progname.
-# * Extracting of texps.pro from temporary PostScript file,
-# if kpsewhich failed.
-# * Option -G0 for dvips run added.
-# 2001/04/16 v0.4:
-# * Support for merging PostScript fonts added.
-# * \special{!...}/@fedspecial detection added.
-# * Bug fix: I detection.
-# 2001/04/17 v0.5:
-# * Redirection of stderr (dvips run) if possible.
-# 2001/04/20 v0.6:
-# * Bug fix: dvips font names can contain numbers.
-# 2001/04/21 v0.7:
-# * Bug fix: long dvi file name in ps file.
-# 2001/04/23 v0.8:
-# * Bug fix: post string parsing.
-# 2001/04/26 v0.9:
-# * Check of version number of dvips in PostScript file.
-# 2001/06/30 v1.0:
-# * Problem with DOS line endings fixed.
-# 2005/01/28 v1.1:
-# * Bug fix: encoding files are now included also.
-# * The intermediate DVI files are written directly.
-# * LPPL 1.3
-# 2005/01/29 v1.2:
-# * Merging is now based on type 1 names. This solves
-# the problem, if different bitmap fonts maps to the
-# same type 1 font, eg. (ecrm1000, larm1000) -> SFRM1000.
-# * Suppression of PK generation, if environment variable
-# MKTEXPK is supported.
-# * If output file is "-" (standard output) then messages of
-# pkfix are written to standard error output.
-# 2005/02/25 v1.3:
-# * Bug fix: Detection of "@fedspecial end" improved.
-# * Bug fix: Typo corrected (PRT -> $PRT).
-# 2007/11/07 v1.4:
-# * Deprecation warning of perl 5.8.8 fixed.
-# 2009/03/18 v1.5:
-# * Patch to support dvips 5.399 (submitted by Melissa O'Neill).
-# 2011/04/22 v1.6:
-# * Bug fix: input and output files are read and written in
-# binary mode (thanks M.S. Dousti for bug report).
-# 2012/04/18 v1.7:
-# * Option --version added.
-#
-### program identification
-my $title = "$program $version, $date - $copyright\n";
-
-### error strings
-my $Error = "!!! Error:"; # error prefix
-my $Warning = "!!! Warning:"; # warning prefix
-
-### variables
-my $envvar = uc($project);
-my $infile = "";
-my $outfile = "";
-my $texpsfile = "texps.pro";
-my $prefix = "_${project}_$$";
-# my $prefix = "_${project}_";
-my $tempfile = "$prefix";
-my $texfile = "$tempfile.tex";
-my $dvifile = "$tempfile.dvi";
-my $logfile = "$tempfile.log";
-my $psfile = "$tempfile.ps";
-my $missfile = "missfont.log";
-my @cleanlist = ($dvifile, $psfile);
-push(@cleanlist, $missfile) unless -f $missfile;
-
-my $err_redirect = " 2>&1";
-$err_redirect = "" if $^O =~ /dos/i ||
- $^O =~ /os2/i ||
- $^O =~ /mswin32/i ||
- $^O =~ /cygwin/i;
-
-my $x_resolution = 0;
-my $y_resolution = 0;
-my $blocks_found = 0;
-my $fonts_converted = 0;
-my $fonts_merged = 0;
-my $fonts_misses = 0;
-my $PRT = \*STDOUT;
-
-### option variables
-my @bool = ("false", "true");
-$::opt_tex = "tex";
-$::opt_dvips = "dvips";
-$::opt_kpsewhich = "kpsewhich --progname $project";
-$::opt_options = "-Ppdf -G0";
-$::opt_usetex = 0;
-$::opt_help = 0;
-$::opt_quiet = 0;
-$::opt_debug = 0;
-$::opt_verbose = 0;
-$::opt_clean = 1;
-$::opt_version = 0;
-
-my $usage = <<"END_OF_USAGE";
-${title}Syntax: \L$program\E [options] <inputfile.ps> <outputfile.ps>
-Function: This program tries to replace pk fonts in <inputfile.ps>
- by the type 1 versions. The result is written in <outputfile.ps>.
-Options: (defaults:)
- --help print usage
- --version print version number
- --(no)quiet suppress messages ($bool[$::opt_quiet])
- --(no)verbose verbose printing ($bool[$::opt_verbose])
- --(no)debug debug informations ($bool[$::opt_debug])
- --(no)clean clear temp files ($bool[$::opt_clean])
- --(no)usetex use TeX for generating the DVI file ($bool[$::opt_usetex])
- --tex texcmd tex command name (plain format) ($::opt_tex)
- --dvips dvipscmd dvips command name ($::opt_dvips)
- --options opt dvips options ($::opt_options)
-END_OF_USAGE
-
-### environment variable PKFIX
-if ($ENV{$envvar}) {
- unshift(@ARGV, split(/\s+/, $ENV{$envvar}));
-}
-
-### process options
-my @OrgArgv = @ARGV;
-use Getopt::Long;
-GetOptions(
- "help!",
- "version!",
- "quiet!",
- "debug!",
- "verbose!",
- "clean!",
- "usetex!",
- "tex=s",
- "dvips=s",
- "options=s"
-) or die $usage;
-if ($::opt_version) {
- print "$project $date v$version\n";
- exit(0);
-}
-!$::opt_help or die $usage;
-@ARGV < 3 or die "$usage$Error Too many files!\n";
-@ARGV == 2 or die "$usage$Error Missing file names!\n";
-
-$::opt_quiet = 0 if $::opt_verbose;
-$::opt_clean = 0 if $::opt_debug;
-
-push(@cleanlist, $texfile, $logfile) if $::opt_usetex;
-
-### get file names
-$infile = $ARGV[0];
-$outfile = $ARGV[1];
-
-### suppress PK generation
-$ENV{'MKTEXPK'} = "0";
-
-$PRT = \*STDERR if $outfile eq "-";
-
-print $PRT $title unless $::opt_quiet;
-
-print $PRT "*** input file: `$infile'\n" if $::opt_verbose;
-print $PRT "*** output file: `$outfile'\n" if $::opt_verbose;
-
-if ($::opt_debug) {
- print $PRT <<"END_DEB";
-*** OSNAME: $^O
-*** PERL_VERSION: $]
-*** ARGV: @OrgArgv
-END_DEB
-}
-
-### get texps.pro
-my $texps_data = 0;
-my $texps_string = get_texps_pro();
-
-### Encoding definitions
-my %encoding_files = ();
-my $encoding_string = "";
-
-### open input and output files
-open(IN, $infile) or die "$Error Cannot open `$infile'!\n";
-binmode(IN);
-open(OUT, ">$outfile") or die "$Error Cannot write `$outfile'!\n";
-binmode(OUT);
-
-##################################
-# expected format:
-# ...
-# %%DVIPSParameters:... dpi=([\dx]+)...
-# ...
-# TeXDict begin \d+ \d+ \d+ \d+ \d+ \(\S+\)
-# @start ...
-# ...
-# %DVIPSBitmapFont: (\S+) (\S+) ([\d\.]+) (\d+)
-# /(\S+) ...
-# ...
-# %EndDVIPSBitmapFont
-# ...
-# ... end
-# %%EndProlog
-#
-# or if \special{!...} was used, the lines with TeXDict:
-# TeXdict begin @defspecial
-#
-# ...
-#
-# @fedspecial end TeXDict begin
-# \d+ \d+ \d+ \d+ \d+ \(\S+\) @start
-#
-# or
-# @fedspecial end
-# ...
-#
-# bitmap font:
-# start:
-# %%DVIPSBitmapFont: {dvips font} {font name} {at x pt} {chars}
-# /{dvips font} {chars} {max. char number + 1} df
-# character, variant a:
-# <{hex code}>{char number} D
-# character, variant b:\
-# [<{hex code}>{num1} {num2} {num3} {num4} {num5} {char number} D
-# end:
-# E
-# %%EndDVIPSBitmapFont
-#
-# type 1 font:
-# before TeXDict line:
-# %%BeginFont: CMR10
-# ...
-# %%EndFont
-# after @start:
-# /Fa ... /CMR10 rf
-#
-# Font names: /[F-Z][a-zA-Z0-9]
-#
-# Encoding files before texps.pro:
-# %%BeginProcSet: {file name}.enc 0 0
-# ...
-# %%EndProcSet
-#
-# Melissa O'Neill reported small variations for dvips 5.399:
-# TeXDict begin \d+ \d+ \d+
-# and
-# \d+ \d+ \d+ \(\d+\) @start
-#
-###################################
-
-my $x_comment_resolution = 0;
-my $y_comment_resolution = 0;
-my $start_string = "";
-my $post_string = "";
-my $dvips_resolution = "";
-my $texps_found = 0;
-my @font_list = ();
-my %font_txt = ();
-my %font_count = ();
-my %font_entry = ();
-
-sub init {
- $x_comment_resolution = 0;
- $y_comment_resolution = 0;
- $x_resolution = 0;
- $y_resolution = 0;
- $start_string = "";
- $texps_found = 0;
- @font_list = ();
- %font_txt = ();
- %font_count = ();
- %font_entry = ();
-}
-
-init();
-
-while (<IN>) {
-
- if (/^%%Creator: (dvips\S*) (\S+)\s/) {
- print $PRT "*** %%Creator: $1 $2\n" if $::opt_debug;
- my $foundversion = $2;
- if ($foundversion =~ /(\d+\.\d+)/) {
- $foundversion = $1;
- # 5.62 is ok, 5.58 does not produce font comments
- if ($foundversion <= 5.58) {
- print $PRT "$Warning dvips version $1 does not generate " .
- "the required font comments!\n";
- }
- }
- }
-
- if (/^%%BeginProcSet:\s*(.+)\.enc/) {
- $encoding_files{$1} = "";
- }
-
- if (/^%DVIPSParameters:.*dpi=([\dx]+)/) {
- print OUT;
- my $str = $1;
- $x_comment_resolution = 0;
- $y_comment_resolution = 0;
- if ($str =~ /^(\d+)x(\d+)$/) {
- $x_comment_resolution = $1;
- $y_comment_resolution = $2;
- }
- if ($str =~ /^(\d+)$/) {
- $x_comment_resolution = $1;
- $y_comment_resolution = $1;
- }
- print $PRT "*** %DVIPSParameters: dpi=$str " .
- "(x=$x_comment_resolution, y=$y_comment_resolution)\n"
- if $::opt_debug;
- $x_comment_resolution > 0 && $y_comment_resolution > 0 or
- die "$Error Wrong resolution value " .
- "($x_comment_resolution x $y_comment_resolution)!\n";
- next;
- }
-
- if (/^%%BeginProcSet: texps.pro/) {
- $texps_found = 1;
- print $PRT "*** texps.pro found\n" if $::opt_debug;
- }
-
- if (/^TeXDict begin \@defspecial/) {
- my $saved = $_;
- print $PRT "*** \@defspecial found.\n" if $::opt_debug;
- $start_string = $_;
- while (<IN>) {
- $start_string .= $_;
- if (/^\@fedspecial end/) {
- s/^\@fedspecial end\s*(\S)/$1/;
- last;
- }
- }
- }
- elsif (/^TeXDict begin \d+ \d+ \d+ \d+ \d+/) {
- print $PRT "*** TeXDict begin <5 nums> found.\n" if $::opt_debug;
- $start_string = $_;
- }
- elsif (/^TeXDict begin \d+ \d+ \d+/) { # dvips 5.399
- print $PRT "*** TeXDict begin <3 nums> found.\n" if $::opt_debug;
- $start_string = $_;
- }
- if ($start_string ne "") {
- # look for @start
- unless (/\@start/) {
- while (<IN>) {
- $start_string .= $_;
- last if /\@start/;
- }
- }
-
- # divide post part
- $start_string =~ /^([\s\S]*\@start)\s*([\s\S]*)$/ or
- die "$Error Parse error (\@start)!\n";
- $start_string = "$1\n";
- $post_string = $2;
- $post_string =~ s/\s*$//;
- $post_string .= "\n" unless $post_string eq "";
-
- $start_string =~
- /\d+\s+\d+\s+\d+\s+(\d+)\s+(\d+)\s+\((.*)\)\s+\@start/ or
- /\d+\s+(\d+)\s+(\d+)\s+\@start/ or # dvips 5.399
- die "$Error Parse error (\@start parameters)!\n";
-
- $blocks_found++;
- print $PRT "*** dvi file: $3\n" if $::opt_debug and defined $3;
-
- # get and check resolution values
- $x_resolution = $1;
- $y_resolution = $2;
- print $PRT "*** resolution: $x_resolution x $y_resolution\n"
- if $::opt_debug;
- $x_comment_resolution > 0 or
- die "$Error Missing comment `%DVIPSParameters'!\n";
- $x_resolution == $x_comment_resolution &&
- $y_resolution == $y_comment_resolution or
- die "$Error Resolution values in comment and PostScript " .
- "does not match!\n";
- # setting dvips resolution option(s)
- if ($x_resolution == $y_resolution) {
- $dvips_resolution = "-D $x_resolution";
- }
- else {
- $dvips_resolution = "-X $x_resolution -Y $y_resolution";
- }
-
- while (<IN>) {
- if (/^%%EndProlog/) {
- print OUT $encoding_string;
- $texps_data > 0 or die "$Error File `texps.pro' not found!\n";
- print OUT $texps_string unless $texps_found;
- foreach (@font_list) {
- my $fontname = $_;
- print $PRT "*** Adding font `$fontname'\n"
- if $::opt_debug;
- my ($dummy1, $dummy2, $err);
- if ($font_count{$fontname} > 1) {
- $fonts_merged++;
- print $PRT "*** Merging font `$fontname' ($font_count{$fontname}).\n"
- unless $::opt_quiet;
- ($dummy1, $font_txt{$fontname}, $dummy2, $err) =
- get_font($font_entry{$fontname});
- $err == 0 or die "$Error Cannot merge font `$fontname'!\n";
- }
- print OUT $font_txt{$fontname};
- }
- print OUT $start_string,
- $post_string,
- $_;
- print $PRT "*** %%EndProlog\n" if $::opt_debug;
- init();
- last;
- }
-
- if (/^%DVIPSBitmapFont: (\S+) (\S+) ([\d.]+) (\d+)/) {
- my $bitmap_string = $_;
- my $dvips_fontname = $1;
- my $fontname = $2;
- my $entry = "\\Font\{$1\}\{$2\}\{$3\}\{";
- print $PRT "*** Font $1: $2 at $3pt, $4 chars\n" if $::opt_verbose;
- my $line = "";
- my $num = -1;
- my $chars = $4;
- my $count = 0;
- while (<IN>) {
- $bitmap_string .= $_;
- last if /^%EndDVIPSBitmapFont/;
- s/\r$//; # remove \r of possible DOS line ending
- chomp;
- $line .= " " . $_;
- }
- $line =~ s/<[0-9A-F ]*>/ /g;
-
- print $PRT "*** <Font> $line\n" if $::opt_debug;
-
- while ($line =~ /\s(\d+)\s+D(.*)/) {
- $num = $1;
- $count++;
- $entry .= "$num,";
- $line = $2;
- while ($line =~ /^[\s\d\[]*I(.*)/) {
- $num++;
- $count++;
- $entry .= "$num,";
- $line = $1;
- }
- }
- $chars == $count or
- die "$Error Parse error, $count chars of $chars found " .
- "($fontname)!\n";
-
- $entry =~ s/,$//;
- $entry .= "\}";
-
- print $PRT "*** Font conversion of `$fontname' started.\n"
- if $::opt_verbose;
- my ($newfontname, $font_part, $start_part, $err) = get_font($entry);
- if ($err == 0) {
- print $PRT "*** Font conversion: `$fontname' -> `$newfontname'.\n"
- unless $::opt_quiet;
- if (defined($font_count{$newfontname})) {
- $font_count{$newfontname}++;
- $font_entry{$newfontname} .= "\n$entry";
- }
- else {
- push @font_list, $newfontname;
- $font_txt{$newfontname} = $font_part;
- $font_count{$newfontname} = 1;
- $font_entry{$newfontname} = $entry;
- }
- $start_part =~ s/\/Fa/\/$dvips_fontname/;
- $start_string .= $start_part;
- $fonts_converted++;
- }
- else {
- print $PRT "!!! Failed font conversion of `$fontname'!\n";
- $start_string .= $bitmap_string;
- $fonts_misses++;
- }
-
- next;
- }
-
- $post_string .= $_;
- }
- next;
- }
-
- print OUT;
-}
-
-close(IN);
-close(OUT);
-
-if ($::opt_clean) {
- print $PRT "*** clear temp files\n" if $::opt_verbose;
- map {unlink} @cleanlist;
-}
-
-if (!$::opt_quiet) {
- if ($blocks_found > 1) {
- print $PRT "==> $blocks_found blocks.\n";
- }
- if ($fonts_misses) {
- print $PRT "==> $fonts_misses font conversion",
- (($fonts_misses > 1) ? "s" : ""),
- " failed.\n";
- }
- if ($fonts_converted) {
- print $PRT "==> ",
- (($fonts_converted > 0) ? $fonts_converted : "No"),
- " converted font",
- (($fonts_converted > 1) ? "s" : ""),
- ".\n";
- if ($fonts_merged) {
- print $PRT "==> $fonts_merged merged font",
- (($fonts_merged > 1) ? "s" : ""),
- ".\n";
- }
- }
- else {
- print $PRT "==> no fonts converted\n";
- }
-}
-
-
-# get type 1 font
-# param: $entry: font entry as TeX string
-# return: $name: type 1 font name
-# $font: font file as string
-# $start: font definition after @start
-# $err: error indication
-sub get_font {
- my $entry = shift;
- my $name = "";
- my $font = "";
- my $start = "";
- my $err = 0;
- my @err = ("", "", "", 1);
- local *OUT;
- local *IN;
-
- if ($::opt_usetex) {
- ### write temp tex file
- open(OUT, ">$texfile") or die "$Error Cannot write `$texfile'!\n";
- print OUT <<'TEX_HEADER';
-\nonstopmode
-\nopagenumbers
-\def\Font#1#2#3#4{%
- \expandafter\font\csname font@#1\endcsname=#2 at #3pt\relax
- \csname font@#1\endcsname
- \hbox to 0pt{%
- \ScanChar#4,\NIL
- \hss
- }%
-}
-\def\ScanChar#1,#2\NIL{%
- \char#1\relax
- \ifx\\#2\\%
- \else
- \ReturnAfterFi{%
- \ScanChar#2\NIL
- }%
- \fi
-}
-\long\def\ReturnAfterFi#1\fi{\fi#1}
-\noindent
-TEX_HEADER
-
- print OUT "$entry\n\\bye\n";
- close(OUT);
-
- ### run tex
- {
- print $PRT "*** run TeX\n" if $::opt_verbose;
-
- my $cmd = "$::opt_tex $tempfile";
- print $PRT ">>> $cmd\n" if $::opt_verbose;
- my @capture = `$cmd`;
- if (!@capture) {
- print $PRT "$Warning Cannot execute TeX!\n";
- return @err;
- }
- if ($::opt_verbose) {
- print $PRT @capture;
- }
- else {
- foreach (@capture) {
- print $PRT if /^!\s/;
- }
- }
- if ($?) {
- my $exitvalue = $?;
- if ($exitvalue > 255) {
- $exitvalue >>= 8;
- print $PRT "$Warning Closing TeX (exit status: $exitvalue)!\n";
- return @err;
- }
- print $PRT "$Warning Closing TeX ($exitvalue)!\n";
- return @err;
- }
- }
- }
- else {
- # write dvi directly
-
- # DVI format description: dvitype.web
- my $DVI_pre = 247;
- my $DVI_id_byte = 2;
- my $DVI_num = 25400000;
- my $DVI_den = 473628672; # 7227 * 2^16
- my $DVI_mag = 1000;
- my @t = localtime(time);
- my $DVI_comment = "$program $version output "
- . sprintf("%04d/%02d/%02d %02d:%02d:%02d",
- ($t[5] + 1900), ($t[4] + 1), $t[3], $t[2], $t[1], $t[0]);
- my $DVI_comment_len = length($DVI_comment);
- my $DVI_bop = 139;
- my $DVI_eop = 140;
- my $DVI_fontdef1 = 243;
- my $DVI_fontdef2 = 244;
- my $DVI_fontdef4 = 246;
- my $DVI_design_size = 10; # an arbitrary value
- # A wrong value will trigger a dvips warning
- # (it can be seen in verbose mode):
- # dvips: Design size mismatch in [...].tfm
- # But other consequences could not be noticed.
- # Thus a TFM lookup will be saved.
- my $DVI_checksum = 0; # because of unknown checksum
- my $DVI_fnt_num_0 = 171;
- my $DVI_fnt1 = 235;
- my $DVI_fnt2 = 236;
- my $DVI_fnt4 = 238;
- my $DVI_set1 = 128;
- my $DVI_push = 141;
- my $DVI_pop = 142;
- my $DVI_post = 248;
- my $DVI_u = 67108864; # 1024 pt, an arbitrary value
- my $DVI_l = 67108864; # 1024 pt, an arbitrary value
- my $DVI_post_post = 249;
- my $DVI_trailing = 223;
-
- open(OUT, ">$dvifile") or die "$Error Cannot write `$dvifile'!\n";
- binmode(OUT);
-
- # Preamble (pre)
- print OUT pack("C2N3Ca$DVI_comment_len",
- $DVI_pre, $DVI_id_byte, $DVI_num, $DVI_den, $DVI_mag,
- $DVI_comment_len, $DVI_comment);
- # Begin of page (bop)
- my $pos_bop = tell(OUT);
- print OUT pack("CN1x[N9]l", $DVI_bop, 1, -1);
-
- my $font_defs = "";
- my $font_num = 0;
- foreach(split("\n", $entry)) {
- my $font_def = "";
- /\\Font\{[^}]*\}\{([^}]*)\}\{([^}]*)\}\{([^}]*)\}/ or
- die "!!! Error: Internal parsing error!\n";
- my $font_name = $1;
- my $font_name_len = length($font_name);
- my $font_size = $2;
- my $font_chars = $3;
-
- # define font
- if ($font_num < 256) {
- $font_def = pack("CC", $DVI_fontdef1, $font_num);
- }
- # The other cases are very unlikely, especially there are
- # more than one font in the merging case only.
- elsif ($font_num < 65536) {
- $font_def = pack("Cn", $DVI_fontdef2, $font_num);
- }
- else {
- $font_def = pack("CN", $DVI_fontdef4, $font_num);
- }
- $font_def .= pack("x[N]N2xCa$font_name_len",
- ($font_size * 65536), $DVI_design_size,
- $font_name_len, $font_name);
- print OUT $font_def;
- $font_defs .= $font_def;
-
- # use font
- my $fnt_num;
- if ($font_num < 64) {
- $fnt_num = pack("C", $DVI_fnt_num_0 + $font_num);
- }
- # Other cases are unlikely, see above.
- elsif ($font_num < 256) {
- $fnt_num = pack("CC", $DVI_fnt1, $font_num);
- }
- elsif ($font_num < 65536) {
- $fnt_num = pack("Cn", $DVI_fnt2, $font_num);
- }
- else {
- $fnt_num = pack("CN", $DVI_fnt4, $font_num);
- }
- print OUT $fnt_num;
-
- # print characters
- print OUT pack("C", $DVI_push);
- foreach (split(",", $font_chars)) {
- if ($_ < 128) {
- print OUT pack("C", $_);
- }
- else {
- print OUT pack("CC", $DVI_set1, $_);
- }
- }
- print OUT pack("C", $DVI_pop);
-
- $font_num++;
- }
-
- print OUT pack("C", $DVI_eop);
-
- # Begin of postamble (post)
- my $pos_post = tell(OUT);
- print OUT pack("CN6n2",
- $DVI_post, $pos_bop, $DVI_num, $DVI_den, $DVI_mag,
- $DVI_l, $DVI_u, 1, 1);
- print OUT $font_defs;
- # End of postamble (post_post)
- print OUT pack("CNC5",
- $DVI_post_post, $pos_post, $DVI_id_byte,
- $DVI_trailing, $DVI_trailing, $DVI_trailing, $DVI_trailing);
- my $t_num = (4 - (tell(OUT) % 4)) % 4;
- print OUT pack("C", $DVI_trailing) x $t_num;
- close(OUT);
- }
-
- ### run dvips
- {
- print $PRT "*** run dvips\n" if $::opt_verbose;
-
- my $cmd = "$::opt_dvips $::opt_options $dvips_resolution $tempfile";
- print $PRT ">>> $cmd\n" if $::opt_verbose;
- # dvips writes on stderr :-(
- my @capture = `$cmd$err_redirect`;
- if ($::opt_verbose) {
- print $PRT @capture;
- }
- if ($?) {
- my $exitvalue = $?;
- if ($exitvalue > 255) {
- $exitvalue >>= 8;
- print $PRT "$Warning Closing dvips (exit status: $exitvalue)!\n";
- return @err;
- }
- print $PRT "$Warning Closing dvips ($exitvalue)!\n";
- return @err;
- }
- }
-
- ### get font and start part
- open(IN, $psfile) or die "$Error Cannot open `$psfile'!\n";
-
- while (<IN>) {
- ### get possible encoding files
- if (/^%%BeginProcSet:\s*(.+)\.enc/) {
- my $encoding_file = $1;
- print $PRT "*** encoding file `$encoding_file.enc' found.\n"
- if $::opt_debug;
- next if defined($encoding_files{$encoding_file});
- $encoding_files{$encoding_file} = "";
- $encoding_string .= $_;
- while (<IN>) {
- $encoding_string .= $_;
- last if /^%%EndProcSet/;
- }
- next;
- }
-
- ### get texps.pro if get_texps_pro() has failed
- if ($texps_data == 0 && /^%%BeginProcSet: texps.pro/) {
- $texps_string = $_;
- while (<IN>) {
- $texps_string .= $_;
- last if /^%%EndProcSet/;
- }
- $texps_data = 1;
- print $PRT "*** texps.pro extracted.\n" if $::opt_debug;
- next;
- }
-
- if (/^%%BeginFont:\s*(\S+)/) {
- $name = $1;
- $font .= $_;
- while (<IN>) {
- $font .= $_;
- last if /^%%EndFont/;
- }
- next;
- }
- if (/^\@start/) {
- s/^\@start\s*//;
- $start .= $_;
- while (<IN>) {
- last if /^%%EndProlog/;
- $start .= $_;
- }
- if (($start =~ s/\s*end\s*$/\n/) != 1) {
- $err = 1;
- print $PRT "$Warning Parse error, `end' not found!\n";
- }
- print $PRT "*** start: $start" if $::opt_debug;
- last;
- }
- }
- close(IN);
-
- if ($font eq "") {
- print $PRT "$Warning `%%BeginFont' not found!\n";
- return @err;
- }
- return ($name, $font, $start, $err);
-}
-
-
-# get_texps_pro
-# return: string with content of texps.pro
-sub get_texps_pro {
- $texps_data = 0;
- # get file name
- my $backupWarn = $^W;
- $^W = 0;
- my $file = `$::opt_kpsewhich $texpsfile`;
- $^W = $backupWarn;
- if (!defined($file) or $file eq "") {
- print $PRT "$Warning: Cannot find `$texpsfile' with kpsewhich!\n"
- if $::opt_debug;
- return "";
- }
- chomp $file;
- print $PRT "*** texps.pro: $file\n" if $::opt_debug;
-
- # read file
- local *IN;
- open(IN, $file) or die "$Error: Cannot open `$file'!\n";
- my @lines = <IN>;
- @lines > 0 or die "$Error: Empty file `$file'!\n";
- chomp $lines[@lines-1];
- my $str = "%%BeginProcSet: texps.pro\n";
- $"="";
- $str .= "@lines\n";
- $"=" ";
- $str .= "%%EndProcSet\n";
- $texps_data = 1;
- return $str;
-}
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/pmxchords/pmxchords.lua b/Build/source/texk/texlive/linked_scripts/pmxchords/pmxchords.lua
deleted file mode 100755
index 58179a355a9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pmxchords/pmxchords.lua
+++ /dev/null
@@ -1,244 +0,0 @@
-#! /usr/bin/env texlua
---
--- global constants
---
-VERSION = "0.9.3"
-FILE_SUFFIX = "_chtr"
-PMX_CMD = "pmxab"
-
---[[
- pmxchords.lua: transpose chords (\ch.C.\) and process pmxab
-
- (c) Copyright 2013 Ondrej Fafejta <fafejtao@gmail.com>
- https://github.com/fafejtao/pmxChords
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
---]]
-
---[[
- ChangeLog:
- version 0.9.3 2014-04-21 - fixed transposition problem:
- If song began in E-minor and signature is changed in half of song to A-minor
- transposition must be omitted.
-
- version 0.9.2 2013-12-13 - fixed: stop processing when pmxab fail.
- - When pmxab is called generated file pmxaerr.dat is not removed.
-
- version 0.9.1 2013-12-09 - added some options. Improved processing.
-
- version 0.9 2013-12-05 - rewritted code from perl to lua...
---]]
-
-function usage()
- print("Usage: [texlua] pmxchords.lua basename[.pmx] ")
- print(" 1. transpose chords into new file basename" .. FILE_SUFFIX .. ".pmx")
- print(" 2. call pmxab on transposed file basename" .. FILE_SUFFIX .. ".pmx")
- print(" 3. rename basename" .. FILE_SUFFIX .. ".tex to basename.tex")
- print("options: -v version")
- print(" -h help")
- print(" -s stop after fist step. e.g. generate only transposed basename" .. FILE_SUFFIX .. ".pmx file")
-end
-
-function whoami()
- print("This is pmxchords.lua version " .. VERSION)
-end
-
-whoami()
-if #arg == 0 then
- usage()
- os.exit(0)
-end
-
-kpse.set_program_name("luatex")
-require"ChordsTr"
-
-function parseInputSignature(line)
- -- parse input signature from pmx digits line. Only one line digits format is supported!
- -- e.g.
- -- 1 1 2 4 2 4 0 -1
- -- signature is -1 : F major
- local res = string.match(line, "^%s*[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+([%+%-]?[0-9]+)%s*$")
- return tonumber(res)
-end
-
-function parseOutputSignature(line)
- -- parse output signature from pmx
- -- e.g.
- -- K-2+2
- -- output signature is +2 : D major
- local res = string.match(line, "^K[%+%-]?[0-9]+([%+%-]?[0-9]+)")
- return tonumber(res)
-end
-
---
--- Strip comments from line
--- Comments begin with % character
---
-function lineWithoutComment(line)
- local i = string.find(line, "%%")
- if (i == nil) then
- return line
- end
- return line:sub(0, i - 1)
-end
-
---
--- Function checks only if the line contains \ch. string.
--- It does not check correctly if notes already started. It checks only if chords started..
--- Scenario bellow will fail!
--- d44 f a r / % first line does not contain chords symbol
--- % signature is changed
--- K+0+0
--- \ch.C.\ c44 e g r4 /
---
-function checkChordsAlreadyStarted(line)
- local i = string.find(lineWithoutComment(line), ChordsTr.CHORDS_BEGIN)
- if (i ~= nil) then
- return true
- end
- return false;
-end
-
-function handleErr(msg)
- io.stderr:write(msg .. "\n")
- os.exit(2)
-end
-
---
--- get file name without .pmx suffix
---
-function getBaseFileName(fileName)
- if fileName ~= "" and string.sub(fileName, -4, -1) == ".pmx" then
- return string.sub(fileName, 1, -5)
- else
- return fileName
- end
-end
-
---
--- Make chords transposition. Generates new pmx file with transposed chords.
---
--- param baseName input file name without .pmx suffix
--- return outputBaseName transposed pmx file name without .pmx suffix
---
-function makeChordsTransposition(baseName)
- local inputFileName = baseName .. ".pmx"
- local inputFile = io.open(inputFileName, "r")
- if (inputFile == nil) then
- handleErr("File does not exist: " .. inputFileName)
- end
-
- local outputBaseName = baseName .. FILE_SUFFIX -- output base name without suffix. Used for renaming generated .tex file ...
- local outputFileName = outputBaseName .. ".pmx"
- local outputFile = io.open(outputFileName, "w")
- if (outputFile == nil) then
- handleErr("Can not create temporary file: " .. outputFileName)
- end
-
- --
- -- transpose chords from inputFile into outputFile
- --
- -- input and output signature will be parsed from input pmx file
- --
- local iSig = nil -- input signature
- local chTr = nil -- chords transposition class
-
- -- If song began in E-minor and signature is changed in half of song to A-minor
- -- transposition must be omitted.
- local chordsAlreadyStarted = false;
-
- for line in inputFile:lines() do
- if (chTr ~= nil) then
- outputFile:write(chTr:lineTranspose(line) .. "\n")
- else
- outputFile:write(line .. "\n")
- end
- if (iSig == nil) then
- iSig = parseInputSignature(line)
- if (iSig ~= nil) then
- io.stderr:write("Chords: input signature detected: " .. iSig .. "\n")
- end
- elseif (chTr == nil and not chordsAlreadyStarted) then
- local oSig = parseOutputSignature(line)
- if (oSig ~= nil) then
- io.stderr:write("Chords: output signature detected: " .. oSig .. "\n")
- chTr = ChordsTr(iSig, oSig)
- elseif (checkChordsAlreadyStarted(line)) then
- io.stderr:write("Chords: notes already started. Chords transposition is omitted.\n")
- chordsAlreadyStarted = true;
- end
- end
- end
- inputFile:close()
- outputFile:close()
-
- return outputBaseName
-end
-
---
--- Make pmxab process.
--- param baseName input file name without .pmx suffix
--- param outputBaseName transposed pmx file name without .pmx suffix
---
-function pmxabProcess(baseName, outputBaseName)
- --
- -- call pmxab to generate .tex file
- --
- os.execute(PMX_CMD .. " " .. outputBaseName)
- -- check error
- local pmxaerr = io.open("pmxaerr.dat", "r")
- if (not pmxaerr) then
- handleErr("No log file.")
- end
- local linebuf = pmxaerr:read()
- local err = tonumber(linebuf)
- pmxaerr:close()
- if (err ~= 0) then
- handleErr("PMX process fail! " .. outputBaseName .. ".pmx")
- end
-
- os.rename(outputBaseName .. ".tex", baseName .. ".tex")
-
- -- remove temporary files
- os.remove(outputBaseName .. ".pmx")
- os.remove(outputBaseName .. ".pml")
-end
-
-narg = 1
-onlyTranspose = false
-
-repeat
- local this_arg = arg[narg]
- if this_arg == "-v" then
- os.exit(0)
- elseif this_arg == "-h" then
- usage()
- os.exit(0)
- elseif this_arg == "-s" then
- onlyTranspose = true
- else
- local baseName = getBaseFileName(this_arg)
- local outputBaseName = makeChordsTransposition(baseName)
-
- if (onlyTranspose) then
- os.exit(0)
- end
- pmxabProcess(baseName, outputBaseName)
- end
-
- narg = narg + 1
-until narg > #arg
-
diff --git a/Build/source/texk/texlive/linked_scripts/pst-pdf/ps4pdf b/Build/source/texk/texlive/linked_scripts/pst-pdf/ps4pdf
deleted file mode 100755
index 33ae7428350..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pst-pdf/ps4pdf
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/bin/sh
-
-# Copyright (C) 2004, Thomas Esser. Public domain.
-# 2005-03-08: New option "--crop", Rolf Niepraschk.
-# dvips call only if the dvi file exist (RN).
-# 2005-06-27: ps2pdf call only if the ps file exist (RN).
-# 2006-04-05: "\RequirePackage{pst-pdf}" added to the (pdf)LaTeX calls
-# as suggested by Niall Murphy.
-# 2006-07-14: Better temp dir handling (suggested by Karl Berry) (RN).
-# 2006-07-23: New option --Xps2pdf and code cleanup (thanks to Karl Berry) (RN).
-# 2008-08-04: Remove the parameter "-Ppdf" from the dvips call (RN).
-# 2016-07-02: New option "--xelatex", (hv)
-# "--lualatex" , (hv)
-# 2016-07-11: Better tests if xelatex or lualatex (RN)
-
-# First, work around bugs/limitations in some shells on some systems:
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-###############################################################################
-# cleanup()
-# clean up the temp area and exit with proper exit status
-###############################################################################
-cleanup()
-{
- rc=$?
- $needsCleanup && test -n "$tmpdir" && test -d "$tmpdir" \
- && { rm -f "$tmpdir"/*; cd /; rmdir "$tmpdir"; }
-
- # set exit code in a portable way; see the autoconf manual for details:
- (exit $rc); exit $rc
-}
-
-###############################################################################
-# setupTmpDir()
-# set up a temp directory and a trap to remove it
-###############################################################################
-setupTmpDir()
-{
- $needsCleanup && return
-
- trap 'cleanup' 1 2 3 7 13 15
- needsCleanup=true
- (umask 077; mkdir "$tmpdir") \
- || abort "could not create directory \`$tmpdir'"
-}
-###############################################################################
-# myexec(args)
-# execute the command given as "args"; abort on error; redirect messages to
-# log in "silent" mode; redirect stdin (</dev/null) in silent mode
-###############################################################################
-myexec()
-{
- if $silent; then
- echo "$0: running $@"
- "$@" >$log 2>&1 </dev/null
- rc=$?
- else
- "$@"
- rc=$?
- fi
- if test $rc != 0; then
- echo "$0: command $@ returned with code $rc"
- cat <$log
- (exit $rc) # set return value
- cleanup
- fi
-}
-
-# some initializations
-progname=pdflatexps
-silent=true # default setting; change if you like
-crop=false
-needsCleanup=false
-ps2pdf_opts="-dAutoRotatePages=/None"
-tmpdir=${TMPDIR-${TEMP-${TMP-/tmp}}}/.$progname$$
-log=$tmpdir/log
-version="1.0"
-
-## the defaults
-ENGINE1=latex
-OPTIONS=
-ENGINE2=pdflatex
-DVIPS=dvips
-PS2PDF=ps2pdf
-FILE=$1
-
-# look for optional things first
-while
- case $1 in
- --help|-h) echo "$0 [-v|-q|--crop|--version|--Xps2pdf OPT] FILE"
- echo "Process LaTeX document FILE using the pst-pdf package,"
- echo "including running latex, dvips, and ps2pdf as necessary."
- echo "--Xps2pdf OPT passes OPT to ps2pdf."
- echo " (-dAutoRotatePages=/None is always passed.)"
- echo "--crop runs pdfcrop on ps2pdf output."
- echo "--lualatex using the luatex engine for .dvi and .pdf"
- echo "--xelatex using the xetex engine for .xdv and .pdf"
- exit 0;;
- --version) echo "$progname version $version"; exit 0;;
- --lualatex) ENGINE1=lualatex;
- OPTIONS="--output-format=dvi";
- ENGINE2=lualatex; FILE=$2;;
- --xelatex) ENGINE1=xelatex;
- OPTIONS="-no-pdf";
- ENGINE2=xelatex;
- DVIPS=xdvipdfmx; FILE=$2;;
- --crop|-c) crop=true;;
- --Xps2pdf|-Xps2pdf) shift; ps2pdf_opts="$ps2pdf_opts $1";;
- -q) silent=true;;
- -v) silent=false;;
- -*) echo "$progname: unknown option $1 ignored";;
- *) break;;
- esac
-do
- shift
-done
-
-# remaining option: filename
-if test -z "$FILE"; then
- echo "$0: no file to process, try --help for more information." >&2
- exit 1
-fi
-
-# jobname von TeX: Verzeichnisse entfernen, evtl. vorhandene Extension
-# entfernen.
-job=`echo "x$1" | sed 's@x@@; s@.*/@@; s@\.[^.]*$@@'`
-
-setupTmpDir
-myexec ${ENGINE1} ${OPTIONS} "\AtBeginDocument{\RequirePackage{pst-pdf}} \input{$FILE}"
-
-if test "$ENGINE1" = "latex" || test "$ENGINE1" = "lualatex"; then
- myexec ${DVIPS} -o "$job-pics.ps" "$job.dvi"
-else
- myexec ${DVIPS} -o "$job-pics.pdf" "$job.xdv"
-fi
-
-test -f "$job-pics.ps" && myexec ${PS2PDF} "$ps2pdf_opts" "$job-pics.ps" "$job-pics.pdf"
-
-if $crop; then
- myexec pdfcrop "$job-pics.pdf" "$job-pics-crop.pdf"
- mv "$job-pics-crop.pdf" "$job-pics.pdf"
-fi
-myexec ${ENGINE2} "\AtBeginDocument{\RequirePackage{pst-pdf}} \input{$FILE}"
-true
-cleanup
-
diff --git a/Build/source/texk/texlive/linked_scripts/pst2pdf/pst2pdf.pl b/Build/source/texk/texlive/linked_scripts/pst2pdf/pst2pdf.pl
deleted file mode 100755
index a0cf34c638c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pst2pdf/pst2pdf.pl
+++ /dev/null
@@ -1,2303 +0,0 @@
-#!/usr/bin/env perl
-use v5.26;
-
-############################# LICENCE ##################################
-# v0.20 2020-08-24 simplify the use of PSTricks with pdf #
-# (c) Herbert Voss <hvoss@tug.org> #
-# Pablo González L <pablgonz@yahoo.com> #
-# #
-# This program is free software; you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation; either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, but #
-# WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
-# General Public License for more details. #
-########################################################################
-
-use Getopt::Long qw(:config bundling_override no_ignore_case); # require_order
-use File::Spec::Functions qw(catfile devnull);
-use File::Basename;
-use Archive::Tar;
-use Data::Dumper;
-use FileHandle;
-use IO::Compress::Zip qw(:all);
-use File::Path qw(remove_tree);
-use File::Temp qw(tempdir);
-use POSIX qw(strftime);
-use File::Copy;
-use File::Find;
-use Env qw(PATH);
-use autodie;
-use Config;
-use Cwd;
-use if $^O eq 'MSWin32', 'Win32';
-use if $^O eq 'MSWin32', 'Win32::Console::ANSI'; # need for color :)
-use Term::ANSIColor;
-
-### Internal vars
-my $tempDir = tempdir( CLEANUP => 1); # temporary directory
-my $workdir = cwd; # current working dir
-my $imgdir = 'images'; # where to save the images
-my $margins = '1'; # margins in pdfcrop
-my $clear = 0; # 0 or 1, clears all temporary files
-my $dpi = '300'; # very low value for the png's
-my $runs = '1'; # set runs for compliler
-my $nocorp = 0; # 1->no crop pdf files created
-my $norun = 0; # 1->no create images
-my $noprew = 0; # 1->create images in nopreview mode
-my $runbibtex = 0; # 1->runs bibtex
-my $runbiber = 0; # 1->runs biber and sets $runbibtex=0
-my $xetex = 0; # 1->Using (Xe)LaTeX for compilation.
-my $luatex = 0; # 1->Using dvilualatex for compilation.
-my $latexmk = 0; # 1->Using latexmk for compiler output file.
-my $arara; # 1->Using arara for compiler output file.
-my $nosource = 0; # Delete TeX source for images
-my $srcenv; # write only source code of environments
-my $nopdf; # Don't create a pdf image files
-my $force; # try to capture \psset
-my $nocrop; # Don't crop image files
-my $zip; # compress files generated in .zip
-my $tar; # compress files generated in .tar.gz
-my $help; # help info
-my $version; # version info
-my $shell; # enable -shell-escape
-my $verbose = 0; # verbose info
-my @verb_env_tmp; # store verbatim environments
-my $tmpverbenv; # save verbatim environment
-my $myverb = 'myverb' ; # internal \myverb macro
-my $write18; # storing write18 for compiler in TeXLive and MikTeX
-my $gscmd; # ghostscript executable name
-my $gray; # gray scale ghostscript
-my $log = 0; # log file
-my $PSTexa = 0; # run extract PSTexample environments
-my $STDenv = 0; # run extract pspicture/psfrag environments
-my @currentopt; # storing current options for log file
-my %opts_cmd; # hash to store options for Getopt::Long and log
-
-### Script identification
-my $scriptname = 'pst2pdf';
-my $nv = 'v0.20';
-my $date = '2020-08-22';
-my $ident = '$Id: pst2pdf.pl 119 2020-08-22 12:04:09Z herbert $';
-
-### Log vars
-my $LogFile = "$scriptname.log";
-my $LogWrite;
-my $LogTime = strftime("%y/%m/%d %H:%M:%S", localtime);
-
-### Error in command line
-sub errorUsage {
- my $msg = shift;
- die color('red').'* Error!!: '.color('reset').$msg.
- " (run $scriptname --help for more information)\n";
- return;
-}
-
-### Extended error messages
-sub exterr {
- chomp(my $msg_errno = $!);
- chomp(my $msg_extended_os_error = $^E);
- if ($msg_errno eq $msg_extended_os_error) {
- $msg_errno;
- }
- else {
- "$msg_errno/$msg_extended_os_error";
- }
-}
-
-### Funtion uniq
-sub uniq {
- my %seen;
- return grep !$seen{$_}++, @_;
-}
-
-### Funtion array_minus
-sub array_minus(\@\@) {
- my %e = map{ $_ => undef } @{$_[1]};
- return grep !exists $e{$_}, @{$_[0]};
-}
-
-### Funtion to create hash begin -> BEGIN, end -> END
-sub crearhash {
- my %cambios;
- for my $aentra(@_){
- for my $initend (qw(begin end)) {
- $cambios{"\\$initend\{$aentra"} = "\\\U$initend\E\{$aentra";
- }
- }
- return %cambios;
-}
-
-### Print colored info in screen
-sub Infocolor {
- my $type = shift;
- my $info = shift;
- if ($type eq 'Running') {
- print color('cyan'), '* ', color('reset'), color('green'),
- "$type: ", color('reset'), color('cyan'), "$info\r\n", color('reset');
- }
- if ($type eq 'Warning') {
- print color('bold red'), "* $type: ", color('reset'),
- color('yellow'), "$info\r\n", color('reset');
- }
- if ($type eq 'Finish') {
- print color('cyan'), '* ', color('reset'), color('magenta'),
- "$type!: ", color('reset'), color('green'), "$info\r\n",color('reset');
- }
- return;
-}
-
-### Write Log line and print msg (common)
-sub Infoline {
- my $msg = shift;
- my $now = strftime("%y/%m/%d %H:%M:%S", localtime);
- if ($log) { $LogWrite->print(sprintf "[%s] * %s\n", $now, $msg); }
- say $msg;
- return;
-}
-
-### Write Log line (no print msg and time stamp)
-sub Logline {
- my $msg = shift;
- if ($log) { $LogWrite->print("$msg\n"); }
- return;
-}
-
-### Write Log line (time stamp)
-sub Log {
- my $msg = shift;
- my $now = strftime("%y/%m/%d %H:%M:%S", localtime);
- if ($log) { $LogWrite->print(sprintf "[%s] * %s\n", $now, $msg); }
- return;
-}
-
-### Write array env in Log
-sub Logarray {
- my ($env_ref) = @_;
- my @env_tmp = @{ $env_ref }; # dereferencing and copying each array
- if ($log) {
- if (@env_tmp) {
- my $tmp = join "\n", map { qq/* $_/ } @env_tmp;
- print {$LogWrite} "$tmp\n";
- }
- else {
- print {$LogWrite} "Not found\n";
- }
- }
- return;
-}
-
-### Extended print info for execute system commands using $ command
-sub Logrun {
- my $msg = shift;
- my $now = strftime("%y/%m/%d %H:%M:%S", localtime);
- if ($log) { $LogWrite->print(sprintf "[%s] \$ %s\n", $now, $msg); }
- return;
-}
-
-### Capture and execute system commands
-sub RUNOSCMD {
- my $cmdname = shift;
- my $argcmd = shift;
- my $showmsg = shift;
- my $captured = "$cmdname $argcmd";
- Logrun($captured);
- if ($showmsg eq 'show') {
- if ($verbose) {
- Infocolor('Running', $captured);
- }
- else{ Infocolor('Running', $cmdname); }
- }
- if ($showmsg eq 'only' and $verbose) {
- Infocolor('Running', $captured);
- }
- # Run system system command
- $captured = qx{$captured};
- if ($log) { $LogWrite->print($captured); }
- if ($? == -1) {
- my $errorlog = "* Error!!: ".$cmdname." failed to execute (%s)!\n";
- my $errorprint = "* Error!!: ".color('reset').$cmdname." failed to execute (%s)!\n";
- if ($log) { $LogWrite->print(sprintf $errorlog, exterr); }
- print STDERR color('red');
- die sprintf $errorprint, exterr;
- } elsif ($? & 127) {
- my $errorlog = "* Error!!: ".$cmdname." died with signal %d!\n";
- my $errorprint = "* Error!!: ".color('reset').$cmdname." died with signal %d!\n";
- if ($log) { $LogWrite->print(sprintf $errorlog, ($? & 127)); }
- print STDERR color('red');
- die sprintf $errorprint, ($? & 127);
- } elsif ($? != 0 ) {
- my $errorlog = "* Error!!: ".$cmdname." exited with error code %d!\n";
- my $errorprint = "* Error!!: ".color('reset').$cmdname." exited with error code %d!\n";
- if ($log) { $LogWrite->print(sprintf $errorlog, $? >> 8); }
- print STDERR color('red');
- die sprintf $errorprint, $? >> 8;
- }
- if ($verbose) { print $captured; }
- return;
-}
-
-### General information
-my $copyright = <<"END_COPYRIGHT" ;
-[$date] (c) Herbert Voss <hvoss\@tug.org> and Pablo González L <pablgonz\@yahoo.com>.
-END_COPYRIGHT
-
-my $versiontxt= <<"END_VERSION" ;
-${scriptname} ${nv} ${ident}
-${copyright}
-END_VERSION
-
-### Standart info in terminal
-my $title = "$scriptname $nv - Running a PSTricks document with (pdf/xe/lua)latex [HV \& PG]\n";
-
-### Usage of script
-sub usage {
-find_ghostscript();
-
-my $usage = <<"END_OF_USAGE";
-${title}
- pst2pdf is a Perl script which isolates all PostScript or PSTricks related
- parts of the TeX document, read all postscript, pspicture, psgraph and
- PSTexample environments, extract source code in standalone files and
- converting them into image format. Create new file with all extracted
- environments converted to \\includegraphics and runs (pdf/xe/lua)latex.
-
-Usage: $scriptname [<options>] <texfile>[.tex|.ltx]
- $scriptname <texfile>[.tex|.ltx] [options]
-
- If used without [<options>] the extracted environments are saved in
- standalone files and converted to pdf image format in the "./images"
- directory using "latex>dvips>ps2pdf" and "preview" package to process
- <texfile> and "pdflatex" for compiler <texfile-pdf>.
-
-Options:
- [default]
- -l, --log Write .log file with debug information [off]
- -h, --help Display command line help and exit [off]
- -v, --version Display current version ($nv) and exit [off]
- -V, --verbose Verbose printing information [off]
- -t, --tif Create .tif files using ghostscript [$gscmd]
- -b, --bmp Create .bmp files using ghostscript [$gscmd]
- -j, --jpg Create .jpg files using ghostscript [$gscmd]
- -p, --png Create .png files using ghostscript [$gscmd]
- -e, --eps Create .eps files using poppler-utils [pdftops]
- -s, --svg Create .svg files using poppler-utils [pdftocairo]
- -P, --ppm Create .ppm files using poppler-utils [pdftoppm]
- -g, --gray Gray scale for images using ghostscript [off]
- -f, --force Try to capture \\psset{...} to extract [off]
- -x, --xetex Using xelatex for compiler input and output [off]
- -ns,--nosource Do not create standalone files [off]
- -np, --noprew, --single
- Create images files without preview package [off]
- -ni,--norun, --noimages
- Generate file-pdf.tex, but not images [off]
- -d <integer>, --dpi <integer>
- Dots per inch resolution for images [150]
- -r <integer>, --runs <integer>
- Set the number of times the compiler will
- run on the input file for extraction [1]
- -m <integer>, --margins <integer>
- Set margins in bp for pdfcrop [0]
- --myverb <macro> Add "\\macroname" to verbatim inline search [myverb]
- --ignore <environment>
- Add "environment" to verbatim environments [empty]
- --srcenv Create files with only code environment [off]
- --shell Enable \\write18\{SHELL COMMAND\} [off]
- --nopdf Do not create images in pdf format [off]
- --nocrop Does not run pdfcrop [off]
- --imgdir <dirname> Set name of directory to save images/files [images]
- --luatex Using dvilualatex>dvips>ps2pdf for compiler
- input and lualatex for compiler output file [off]
- --arara Use arara for compiler output file [off]
- --latexmk Using latexmk for compiler output file [off]
- --zip Compress generated files in .zip format [off]
- --tar Compress generated files in .tar.gz format [off]
- --bibtex Run bibtex on the .aux file (if exists) [off]
- --biber Run biber on the .bcf file (if exists) [off]
-
-Example:
-\$ $scriptname -e -p --imgdir pics test.tex
-* Create a ./pics directory (if it doesn't exist) with all extracted
-* environments converted to individual files (.pdf, .eps, .png, .tex),
-* a file test-fig-all.tex with all extracted environments and the file
-* test-pdf.tex with all environments converted to \\includegraphics using
-* latex>dvips>ps2pdf and preview package for <test.tex> and pdflatex
-* for <test-pdf.tex>.
-
-See texdoc pst2pdf for full documentation.
-END_OF_USAGE
-print $usage;
-exit 0;
-}
-
-### Options in terminal
-my $result=GetOptions (
- 'h|help' => \$help, # flag
- 'v|version' => \$version, # flag
- 'l|log' => \$log, # flag
- 'f|force' => \$force, # flag
- 'd|dpi=i' => \$dpi, # numeric
- 'runs=i' => \$runs, # numeric
- 'm|margins=i' => \$margins, # numeric
- 'imgdir=s' => \$imgdir, # string
- 'myverb=s' => \$myverb, # string
- 'ignore=s' => \$tmpverbenv, # string
- 'c|clear' => \$clear, # flag (unused)
- 'ni|norun|noimages' => \$norun, # flag
- 'np|noprew|single' => \$noprew, # flag
- 'bibtex' => \$runbibtex,# flag
- 'biber' => \$runbiber, # flag
- 'arara' => \$arara, # flag
- 'latexmk' => \$latexmk, # flag
- 'srcenv' => \$srcenv, # flag
- 'nopdf' => \$nopdf, # flag
- 'shell' => \$shell, # flag
- 'nocrop' => \$nocrop, # flag
- 'zip' => \$zip, # flag
- 'tar' => \$tar, # flag
- 'g|gray' => \$gray, # flag
- 'b|bmp' => \$opts_cmd{image}{bmp}, # gs
- 't|tif' => \$opts_cmd{image}{tif}, # gs
- 'j|jpg' => \$opts_cmd{image}{jpg}, # gs
- 'p|png' => \$opts_cmd{image}{png}, # gs
- 's|svg' => \$opts_cmd{image}{svg}, # pdftocairo
- 'e|eps' => \$opts_cmd{image}{eps}, # pdftops
- 'P|ppm' => \$opts_cmd{image}{ppm}, # pdftoppm
- 'x|xetex' => \$xetex, # flag
- 'luatex' => \$luatex, # flag
- 'ns|nosource' => \$nosource, # flag
- 'V|Verbose' => \$verbose, # flag
-) or do { $log = 0 ; die usage(0); };
-
-### Open pst2pdf.log file
-if ($log) {
- if (!defined $ARGV[0]) { errorUsage('Input filename missing'); }
- my $tempname = $ARGV[0];
- $tempname =~ s/\.(tex|ltx)$//;
- if ($LogFile eq "$tempname.log") { $LogFile = "$scriptname-log.log"; }
- $LogWrite = FileHandle->new("> $LogFile");
-}
-
-### Init pst2pdf.log file
-Log("The script $scriptname $nv was started in $workdir");
-Log("Creating the temporary directory $tempDir");
-
-### Check --arara and --latexmk
-if ($arara && $latexmk) {
- Log('Error!!: Options --arara and --latexmk are mutually exclusive');
- errorUsage('Options --arara and --latexmk are mutually exclusive');
-}
-
-### Check --biber and --bibtex
-if ($runbiber && $runbibtex) {
- Log('Error!!: Options --biber and --bibtex are mutually exclusive');
- errorUsage('Options --biber and --bibtex are mutually exclusive');
-}
-
-### Check --runs
-if( $runs <= 0 or $runs >= 3) {
- Log('Error!!: Invalid argument for --runs, argument out of range');
- errorUsage('Invalid argument for --runs option');
-}
-
-### Check --dpi
-if( $dpi <= 0 or $dpi >= 2500) {
- Log('Error!!: Invalid argument for --dpi, argument out of range');
- errorUsage('Invalid argument for --dpi option');
-}
-
-### Validate --myverb
-if ($myverb =~ /^(?:\\|\-).+?/) {
- Log('Error!!: Invalid argument for --myverb option, argument begin with \ or -');
- errorUsage('Invalid argument for --myverb');
-}
-
-### Validate --ignore
-if ($tmpverbenv =~ /^(?:\\|\-).+?/) {
- Log('Error!!: Invalid argument for --ignore option, argument begin with \ or -');
- errorUsage('Invalid argument for --ignore');
-}
-
-### If $tmpverbenv is valid pass to @verb_env_tmp
-if ($tmpverbenv) { @verb_env_tmp = $tmpverbenv; }
-
-### Make ENV safer, see perldoc perlsec
-delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
-
-### The next code it's part of pdfcrop (adapted from TexLive 2014)
-# Windows detection
-my $Win = 0;
-if ($^O =~ /mswin32/i) { $Win = 1; }
-
-my $archname = $Config{'archname'};
-$archname = 'unknown' unless defined $Config{'archname'};
-
-# Get ghostscript command name
-sub find_ghostscript () {
- if ($log) {
- Log('General information about the Perl instalation and operating system');
- print {$LogWrite} "* Perl executable: $^X\n";
- if ($] < 5.006) {
- print {$LogWrite} "* Perl version: $]\n";
- }
- else {
- printf {$LogWrite} "* Perl version: v%vd\n", $^V;
- }
- if (defined &ActivePerl::BUILD) {
- printf {$LogWrite} "* Perl product: ActivePerl, build %s\n", ActivePerl::BUILD();
- }
- printf {$LogWrite} "* Pointer size: $Config{'ptrsize'}\n";
- printf {$LogWrite} "* Pipe support: %s\n",
- (defined $Config{'d_pipe'} ? 'yes' : 'no');
- printf {$LogWrite} "* Fork support: %s\n",
- (defined $Config{'d_fork'} ? 'yes' : 'no');
- }
- my $system = 'unix';
- $system = 'win' if $^O =~ /mswin32/i;
- $system = 'msys' if $^O =~ /msys/i;
- $system = 'cygwin' if $^O =~ /cygwin/i;
- $system = 'miktex' if defined $ENV{'TEXSYSTEM'} and
- $ENV{'TEXSYSTEM'} =~ /miktex/i;
- if ($log) {
- print {$LogWrite} "* OS name: $^O\n";
- print {$LogWrite} "* Arch name: $archname\n";
- if ($^O eq 'MSWin32') {
- my $tmp = Win32::GetOSName();
- print {$LogWrite} "* System: $tmp\n";
- }
- else { print {$LogWrite} "* System: $system\n"; }
- }
- Log('Trying to locate the executable for Ghostscript');
- my %candidates = (
- 'unix' => [qw|gs|],
- 'win' => [qw|gswin32c|],
- 'msys' => [qw|gswin64c gswin32c|],
- 'cygwin' => [qw|gs|],
- 'miktex' => [qw|mgs gswin32c|],
- );
- if ($system eq 'win' or $system eq 'miktex') {
- if ($archname =~ /mswin32-x64/i) {
- my @a = ();
- foreach my $name (@{$candidates{$system}}) {
- push @a, 'gswin64c' if $name eq 'gswin32c';
- push @a, $name;
- }
- $candidates{$system} = \@a;
- }
- }
- my %exe = (
- 'unix' => q{},
- 'win' => '.exe',
- 'msys' => '.exe',
- 'cygwin' => '.exe',
- 'miktex' => '.exe',
- );
- my $candidates_ref = $candidates{$system};
- my $exe = $Config{'_exe'};
- $exe = $exe{$system} unless defined $exe;
- my @path = File::Spec->path();
- my $found = 0;
- foreach my $candidate (@$candidates_ref) {
- foreach my $dir (@path) {
- my $file = File::Spec->catfile($dir, "$candidate$exe");
- if (-x $file) {
- $gscmd = $candidate;
- $found = 1;
- if ($log) { print {$LogWrite} "* Found ($candidate): $file\n"; }
- last;
- }
- if ($log) { print {$LogWrite} "* Not found ($candidate): $file\n"; }
- }
- last if $found;
- }
- if (not $found and $Win and $system ne 'msys') {
- $found = SearchRegistry();
- }
- if (not $found and $system eq 'msys') {
- $found = Searchbyregquery();
- }
- if ($found) {
- if ($log) { print {$LogWrite} "* Autodetected ghostscript command: $gscmd\n"; }
- }
- else {
- $gscmd = $$candidates_ref[0];
- if ($log) { print {$LogWrite} "* Default ghostscript command: $gscmd\n"; }
- }
-}
-
-sub SearchRegistry {
- my $found = 0;
- # The module Win32::TieRegistry not aviable in cygwin/msys
- eval 'use Win32::TieRegistry qw|KEY_READ REG_SZ|';
- if ($@) {
- if ($log) {
- print {$LogWrite} "* Registry lookup for Ghostscript failed:\n";
- my $msg = $@;
- $msg =~ s/\s+$//;
- foreach (split /\r?\n/, $msg) {
- print {$LogWrite} " $_\n";
- }
- }
- return $found;
- }
- my $open_params = {Access => KEY_READ(), Delimiter => q{/}};
- my $key_name_software = 'HKEY_LOCAL_MACHINE/SOFTWARE/';
- my $current_key = $key_name_software;
- my $software = new Win32::TieRegistry $current_key, $open_params;
- if (not $software) {
- if ($log) {
- print {$LogWrite} "* Cannot find or access registry key `$current_key'!\n";
- }
- return $found;
- }
- if ($log) { print {$LogWrite} "* Search registry at `$current_key'.\n"; }
- my %list;
- foreach my $key_name_gs (grep /Ghostscript/i, $software->SubKeyNames()) {
- $current_key = "$key_name_software$key_name_gs/";
- if ($log) { print {$LogWrite} "* Registry entry found: $current_key\n"; }
- my $key_gs = $software->Open($key_name_gs, $open_params);
- if (not $key_gs) {
- if ($log) { print {$LogWrite} "* Cannot open registry key `$current_key'!\n"; }
- next;
- }
- foreach my $key_name_version ($key_gs->SubKeyNames()) {
- $current_key = "$key_name_software$key_name_gs/$key_name_version/";
- if ($log) { print {$LogWrite} "* Registry entry found: $current_key\n"; }
- if (not $key_name_version =~ /^(\d+)\.(\d+)$/) {
- if ($log) { print {$LogWrite} " The sub key is not a version number!\n"; }
- next;
- }
- my $version_main = $1;
- my $version_sub = $2;
- $current_key = "$key_name_software$key_name_gs/$key_name_version/";
- my $key_version = $key_gs->Open($key_name_version, $open_params);
- if (not $key_version) {
- if ($log) { print {$LogWrite} "* Cannot open registry key `$current_key'!\n"; }
- next;
- }
- $key_version->FixSzNulls(1);
- my ($value, $type) = $key_version->GetValue('GS_DLL');
- if ($value and $type == REG_SZ()) {
- if ($log) { print {$LogWrite} " GS_DLL = $value\n"; }
- $value =~ s|([\\/])([^\\/]+\.dll)$|$1gswin32c.exe|i;
- my $value64 = $value;
- $value64 =~ s/gswin32c\.exe$/gswin64c.exe/;
- if ($archname =~ /mswin32-x64/i and -f $value64) {
- $value = $value64;
- }
- if (-f $value) {
- if ($log) { print {$LogWrite} "EXE found: $value\n"; }
- }
- else {
- if ($log) { print {$LogWrite} "EXE not found!\n"; }
- next;
- }
- my $sortkey = sprintf '%02d.%03d %s',
- $version_main, $version_sub, $key_name_gs;
- $list{$sortkey} = $value;
- }
- else {
- if ($log) { print {$LogWrite} "Missing key `GS_DLL' with type `REG_SZ'!\n"; }
- }
- }
- }
- foreach my $entry (reverse sort keys %list) {
- $gscmd = $list{$entry};
- if ($log) { print {$LogWrite} "* Found (via registry): $gscmd\n"; }
- $found = 1;
- last;
- }
- return $found;
-} # end GS search registry
-
-### This part is only necessary if you're using Git on windows and don't
-### have gs configured in PATH. Git for windows don't have a Win32::TieRegistry
-### module for perl (is not supported in the current versions of msys).
-sub Searchbyregquery {
- my $found = 0;
- my $gs_regkey;
- my $opt_reg = '//s //v';
- if ($log) { print {$LogWrite} "* Search Ghostscript in Windows registry under mingw/msys:\n";}
- $gs_regkey = qx{reg query "HKLM\\Software\\GPL Ghostscript" $opt_reg GS_DLL};
- if ($? == 0) {
- if ($log) { print {$LogWrite} "* Registry entry found for GS_DLL (64 bits version)\n";}
- }
- else {
- $gs_regkey = qx{reg query "HKLM\\Software\\Wow6432Node\\GPL Ghostscript" $opt_reg GS_DLL};
- if ($? == 0) {
- if ($log) { print {$LogWrite} "* Registry entry found for GS_DLL (32 bits version)\n";}
- }
- }
- my ($gs_find) = $gs_regkey =~ m/(?:\s* GS_DLL \s* REG_SZ \s*) (.+?)(?:\.dll.+?\R)/s;
- if ($gs_find) {
- my ($gs_vol, $gs_path, $gs_ver) = $gs_find =~ m/
- (\w{1})(?:\:) # volumen
- (.+?) # path to executable
- (?:\\gsdll) # LIB
- (\d{2}) # Version
- /xs;
- # Adjust
- $gs_vol = lc($gs_vol);
- $gs_path = '/'.$gs_vol.$gs_path;
- $gs_path =~ s|\\|/|gmsxi;
- # Add to PATH
- if ($log) { print {$LogWrite} "* Add $gs_path to PATH for current session\n"; }
- $PATH .= ":$gs_path";
- # Set executable
- $gscmd = 'gswin'.$gs_ver.'c';
- if ($log) { print {$LogWrite} "* Found (via reg query): $gscmd\n"; }
- $found = 1;
- }
- if ($@) {
- if ($log) {
- print {$LogWrite} "* Registry lookup for Ghostscript by reg query failed:\n";
- my $msg = $@;
- $msg =~ s/\s+$//;
- foreach (split /\r?\n/, $msg) {
- print {$LogWrite} " $_\n";
- }
- }
- return $found;
- }
- return $found;
-}
-
-### Call GS
-find_ghostscript();
-
-### Windows need suport space in path
-if ($Win and $gscmd =~ /\s/) { $gscmd = "\"$gscmd\"";}
-
-### Help
-if (defined $help) {
- usage(1);
- exit 0;
-}
-
-### Version
-if (defined $version) {
- print $versiontxt;
- exit 0;
-}
-
-### Set temp internal vars for <name-fig-tmp> and extraction
-my $tmp = int(rand(10000));
-my $dtxverb = "verbatim$tmp";
-my $wrapping = "$scriptname$tmp"; # wraped for environment extraction
-
-Log("Set up the environment [$wrapping] to encapsulate the extraction");
-
-### Set vars for match/regex
-my $BP = "\\\\begin\{$wrapping\}";
-my $EP = "\\\\end\{$wrapping\}";
-my $BE = '\\\\begin\{PSTexample\}';
-my $EE = '\\\\end\{PSTexample\}';
-
-### Define key = pdf for image format
-if (!$nopdf) {
- $opts_cmd{image}{pdf} = 1;
-}
-
-### Store image formats in hash
-my $format = join q{, },grep { defined $opts_cmd{image}{$_} } keys %{$opts_cmd{image}};
-if (!$norun) {
- Log("Defined image formats for creating: $format");
-}
-
-### Check <input file> from command line
-@ARGV > 0 or errorUsage('Input filename missing');
-@ARGV < 2 or errorUsage('Unknown option or too many input files');
-
-### Check <input file> extention
-my @SuffixList = ('.tex', '', '.ltx'); # posibles
-my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
-$ext = '.tex' if not $ext;
-
-### Read <input file> in memory
-Log("Read input file $name$ext in memory");
-open my $inputfile, '<:crlf', "$name$ext";
- my $ltxfile;
- {
- local $/;
- $ltxfile = <$inputfile>;
- }
-close $inputfile;
-
-### Identification message in terminal
-print $title;
-
-### Default environment to extract
-my @extractenv = qw (
- postscript pspicture psgraph PSTexample
- );
-
-### Default verbatim environment
-my @iverb_env = qw (
- Example CenterExample SideBySideExample PCenterExample PSideBySideExample
- verbatim Verbatim BVerbatim LVerbatim SaveVerbatim PSTcode
- LTXexample tcblisting spverbatim minted listing lstlisting
- alltt comment chklisting verbatimtab listingcont boxedverbatim
- demo sourcecode xcomment pygmented pyglist program programl
- programL programs programf programsc programt
- );
-push @verb_env_tmp, @iverb_env;
-
-### Default verbatim write environment
-my @verw_env_tmp;
-my @iverbw_env = qw (
- scontents filecontents tcboutputlisting tcbexternal tcbwritetmp extcolorbox extikzpicture
- VerbatimOut verbatimwrite filecontentsdef filecontentshere filecontentsdefmacro
- filecontentsdefstarred filecontentsgdef filecontentsdefmacro filecontentsgdefmacro
- );
-push @verw_env_tmp, @iverbw_env;
-
-########################################################################
-# One problem that can arise is the filecontents environment, this can #
-# contain a complete document and be anywhere, before dividing we will #
-# make some replacements for this and comment lines #
-########################################################################
-
-### Create a Regex for verbatim write environment
-@verw_env_tmp = uniq(@verw_env_tmp);
-my $tmpverbw = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verw_env_tmp;
-$tmpverbw = qr/$tmpverbw/x;
-my $tmp_verbw = qr {
- (
- (?:
- \\begin\{$tmpverbw\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$tmpverbw\*?\})
- (?!end\{$tmpverbw\*?\})|
- (?-1)
- )*
- \\end\{$tmpverbw\*?\}
- )
- )
- }x;
-
-### A pre-regex for comment lines
-my $tmpcomment = qr/^ \s* \%+ .+? $ /mx;
-
-### Hash for replace in verbatim's and comment lines
-my %document = (
- '\begin{document}' => '\BEGIN{document}',
- '\end{document}' => '\END{document}',
- '\documentclass' => '\DOCUMENTCLASS',
- '\pagestyle{' => '\PAGESTYLE{',
- '\thispagestyle{' => '\THISPAGESTYLE{',
- );
-
-### Changes in input file for verbatim write and comment lines
-while ($ltxfile =~ / $tmp_verbw | $tmpcomment /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- while (my($busco, $cambio) = each %document) {
- $encontrado =~ s/\Q$busco\E/$cambio/g;
- }
- substr $ltxfile, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($ltxfile) = $pos_inicial + length $encontrado;
-}
-
-### Now, split <input file>
-my ($atbegindoc, $document) = $ltxfile =~ m/\A (\s* .*? \s*) (\\documentclass.*)\z/msx;
-
-### Rules to capture for regex my $CORCHETES = qr/\[ [^]]*? \]/x;
-my $braces = qr/ (?:\{)(.+?)(?:\}) /msx;
-my $braquet = qr/ (?:\[)(.+?)(?:\]) /msx;
-my $no_corchete = qr/ (?:\[ .*? \])? /msx;
-
-### Array for capture new verbatim environments defined in input file
-my @cverb_env = qw (
- newtcblisting DeclareTCBListing ProvideTCBListing NewTCBListing
- lstnewenvironment NewListingEnvironment NewProgram specialcomment
- includecomment DefineVerbatimEnvironment newverbatim newtabverbatim
- );
-
-### Regex to capture names for new verbatim environments from input file
-my $cverbenv = join q{|}, map { quotemeta} sort { length $a <=> length $b } @cverb_env;
-$cverbenv = qr/\b(?:$cverbenv) $no_corchete $braces/msx;
-
-### Array for capture new verbatim write environments defined in input file
-my @cverb_env_w = qw (
- renewtcbexternalizetcolorbox renewtcbexternalizeenvironment
- newtcbexternalizeenvironment newtcbexternalizetcolorbox newenvsc
- );
-
-### Regex to capture names for new verbatim write environments from input file
-my $cverbenvw = join q{|}, map { quotemeta} sort { length $a <=> length $b } @cverb_env_w;
-$cverbenvw = qr/\b(?:$cverbenvw) $no_corchete $braces/msx;
-
-### Regex to capture MINTED related environments
-my $mintdenv = qr/\\ newminted $braces (?:\{.+?\}) /x;
-my $mintcenv = qr/\\ newminted $braquet (?:\{.+?\}) /x;
-my $mintdshrt = qr/\\ newmint $braces (?:\{.+?\}) /x;
-my $mintcshrt = qr/\\ newmint $braquet (?:\{.+?\}) /x;
-my $mintdline = qr/\\ newmintinline $braces (?:\{.+?\}) /x;
-my $mintcline = qr/\\ newmintinline $braquet (?:\{.+?\}) /x;
-
-### Filter input file, now $ltxfile is pass to $filecheck
-Log("Filter $name$ext \(remove % and comments\)");
-my @filecheck = $ltxfile;
-s/%.*\n//mg foreach @filecheck; # del comments
-s/^\s*|\s*//mg foreach @filecheck; # del white space
-my $filecheck = join q{}, @filecheck;
-
-### Search verbatim and verbatim write environments <input file>
-Log("Search verbatim and verbatim write environments in $name$ext");
-
-### Search new verbatim write names in <input file>
-my @new_write_env = $filecheck =~ m/$cverbenvw/xg;
-if (@new_write_env) {
- Log("Found new verbatim write environments in $name$ext");
- Logarray(\@new_write_env);
- push @verw_env_tmp, @new_write_env;
-}
-
-### Search new verbatim environments in <input file>
-my @verb_input = $filecheck =~ m/$cverbenv/xg;
-if (@verb_input) {
- Log("Found new verbatim environments in $name$ext");
- Logarray(\@verb_input);
- push @verb_env_tmp, @verb_input;
-}
-
-### Search \newminted{$mintdenv}{options} in <input file>, need add "code"
-my @mint_denv = $filecheck =~ m/$mintdenv/xg;
-if (@mint_denv) {
- Log("Found \\newminted\{envname\} in $name$ext");
- # Append "code"
- $mintdenv = join "\n", map { qq/$_\Qcode\E/ } @mint_denv;
- @mint_denv = split /\n/, $mintdenv;
- Logarray(\@mint_denv);
- push @verb_env_tmp, @mint_denv;
-}
-
-### Search \newminted[$mintcenv]{lang} in <input file>
-my @mint_cenv = $filecheck =~ m/$mintcenv/xg;
-if (@mint_cenv) {
- Log("Found \\newminted\[envname\] in $name$ext");
- Logarray(\@mint_cenv);
- push @verb_env_tmp, @mint_cenv;
-}
-
-### Remove repetead again :)
-@verb_env_tmp = uniq(@verb_env_tmp);
-
-### Capture verbatim inline macros in <input file>
-Log("Search verbatim macros in $name$ext");
-
-### Store all minted inline/short in @mintline
-my @mintline;
-
-### Search \newmint{$mintdshrt}{options} in <input file> (while)
-my @mint_dshrt = $filecheck =~ m/$mintdshrt/xg;
-if (@mint_dshrt) {
- Log("Found \\newmint\{macroname\} (short) in $name$ext");
- Logarray(\@mint_dshrt);
- push @mintline, @mint_dshrt;
-}
-
-### Search \newmint[$mintcshrt]{lang}{options} in <input file> (while)
-my @mint_cshrt = $filecheck =~ m/$mintcshrt/xg;
-if (@mint_cshrt) {
- Log("Found \\newmint\[macroname\] (short) in $name$ext");
- Logarray(\@mint_cshrt);
- push @mintline, @mint_cshrt;
-}
-
-### Search \newmintinline{$mintdline}{options} in <input file> (while)
-my @mint_dline = $filecheck =~ m/$mintdline/xg;
-if (@mint_dline) {
- Log("Found \\newmintinline\{macroname\} in $name$ext");
- # Append "inline"
- $mintdline = join "\n", map { qq/$_\Qinline\E/ } @mint_dline;
- @mint_dline = split /\n/, $mintdline;
- Logarray(\@mint_dline);
- push @mintline, @mint_dline;
-}
-
-### Search \newmintinline[$mintcline]{lang}{options} in <input file> (while)
-my @mint_cline = $filecheck =~ m/$mintcline/xg;
-if (@mint_cline) {
- Log("Found \\newmintinline\[macroname\] in $name$ext");
- Logarray(\@mint_cline);
- push @mintline, @mint_cline;
-}
-
-### Add standart mint, mintinline and lstinline
-my @mint_tmp = qw(mint mintinline lstinline);
-
-### Join all inline verbatim macros captured
-push @mintline, @mint_tmp;
-@mintline = uniq(@mintline);
-
-### Create a regex using @mintline
-my $mintline = join q{|}, map { quotemeta } sort { length $a <=> length $b } @mintline;
-$mintline = qr/\b(?:$mintline)/x;
-
-### Reserved words in verbatim inline (while)
-my %changes_in = (
- '%CleanPST' => '%PSTCLEAN',
- '\psset' => '\PSSET',
- '\pspicture' => '\TRICKS',
- '\endpspicture' => '\ENDTRICKS',
- '\psgraph' => '\PSGRAPHTRICKS',
- '\endpsgraph' => '\ENDPSGRAPHTRICKS',
- '\usepackage' => '\USEPACKAGE',
- '{graphicx}' => '{GRAPHICX}',
- '\graphicspath{' => '\GRAPHICSPATH{',
- );
-
-### Hash to replace \begin and \end in verbatim inline
-my %init_end = (
- '\begin{' => '\BEGIN{',
- '\end{' => '\END{',
- );
-
-### Join changes in new hash (while) for verbatim inline
-my %cambios = (%changes_in,%init_end);
-
-### Variables and constantes
-my $no_del = "\0";
-my $del = $no_del;
-
-### Rules
-my $llaves = qr/\{ .+? \} /x;
-my $no_llaves = qr/(?: $llaves )? /x;
-my $corchetes = qr/\[ .+? \] /x;
-my $delimitador = qr/\{ (?<del>.+?) \} /x;
-my $scontents = qr/Scontents [*]? $no_corchete /ix;
-my $verb = qr/(?:((spv|(?:q|f)?v|V)erb|$myverb)[*]?) /ix;
-my $lst = qr/(?:(lst|pyg)inline)(?!\*) $no_corchete /ix;
-my $mint = qr/(?: $mintline |SaveVerb) (?!\*) $no_corchete $no_llaves $llaves /ix;
-my $no_mint = qr/(?: $mintline) (?!\*) $no_corchete /ix;
-my $marca = qr/\\ (?:$verb | $lst |$scontents | $mint |$no_mint) (?:\s*)? (\S) .+? \g{-1} /sx;
-my $comentario = qr/^ \s* \%+ .+? $ /mx;
-my $definedel = qr/\\ (?: DefineShortVerb | lstMakeShortInline| MakeSpecialShortVerb ) [*]? $no_corchete $delimitador /ix;
-my $indefinedel = qr/\\ (?: (Undefine|Delete)ShortVerb | lstDeleteShortInline) $llaves /ix;
-
-Log('Making changes to inline/multiline verbatim macro before extraction');
-
-### Changes in input file for verbatim inline/multiline
-while ($document =~
- / $marca
- | $comentario
- | $definedel
- | $indefinedel
- | $del .+? $del
- /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- if ($encontrado =~ /$definedel/) {
- $del = $+{del};
- $del = "\Q$+{del}" if substr($del,0,1) ne '\\';
- }
- elsif ($encontrado =~ /$indefinedel/) {
- $del = $no_del;
- }
- else {
- while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/g;
- }
- substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
- }
-}
-
-### Change "escaped braces" to <LTXSB.> (this label is not the one in the document)
-$document =~ s/\\[{]/<LTXSBO>/g;
-$document =~ s/\\[}]/<LTXSBC>/g;
-
-### Regex for verbatim inline/multiline with braces {...}
-my $nestedbr = qr / ( [{] (?: [^{}]++ | (?-1) )*+ [}] ) /x;
-my $fvextra = qr /\\ (?: (Save|Esc)Verb [*]?) $no_corchete /x;
-my $mintedbr = qr /\\ (?:$mintline|pygment) (?!\*) $no_corchete $no_llaves /x;
-my $tcbxverb = qr /\\ (?: tcboxverb [*]?| Scontents [*]? |$myverb [*]?|lstinline) $no_corchete /x;
-my $verb_brace = qr / (?:$tcbxverb|$mintedbr|$fvextra) (?:\s*)? $nestedbr /x;
-
-### Change \verb*{code} for verbatim inline/multiline
-while ($document =~ /$verb_brace/pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- while (my($busco, $cambio) = each %cambios) {
- $encontrado =~ s/\Q$busco\E/$cambio/g;
- }
- substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
-}
-
-### We recovered the escaped braces
-$document =~ s/<LTXSBO>/\\{/g;
-$document =~ s/<LTXSBC>/\\}/g;
-
-### We recovered CleanPST in all file, but only at begin of line
-$document =~ s/^%PSTCLEAN/%CleanPST/gmsx;
-
-### First we do some security checks to ensure that they are verbatim and
-### verbatim write environments are unique and disjointed
-@verb_env_tmp = array_minus(@verb_env_tmp, @verw_env_tmp); #disjointed
-my @verbatim = uniq(@verb_env_tmp);
-
-Log('The environments that are considered verbatim:');
-Logarray(\@verbatim);
-
-### Create a Regex for verbatim standart environment
-my $verbatim = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verbatim;
-$verbatim = qr/$verbatim/x;
-my $verb_std = qr {
- (
- (?:
- \\begin\{$verbatim\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim\*?\})
- (?!end\{$verbatim\*?\})|
- (?-1)
- )*
- \\end\{$verbatim\*?\}
- )
- )
- }x;
-
-### Verbatim write
-@verw_env_tmp = array_minus(@verw_env_tmp, @verb_env_tmp); #disjointed
-my @verbatim_w = uniq(@verw_env_tmp);
-
-Log('The environments that are considered verbatim write:');
-Logarray(\@verbatim_w);
-
-### Create a Regex for verbatim write environment
-my $verbatim_w = join q{|}, map { quotemeta } sort { length $a <=> length $b } @verbatim_w;
-$verbatim_w = qr/$verbatim_w/x;
-my $verb_wrt = qr {
- (
- (?:
- \\begin\{$verbatim_w\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$verbatim_w\*?\})
- (?!end\{$verbatim_w\*?\})|
- (?-1)
- )*
- \\end\{$verbatim_w\*?\}
- )
- )
- }x;
-
-### The environments that will be searched for extraction
-Log('The environments that will be searched for extraction:');
-Logarray(\@extractenv);
-
-### Create a regex to extract environments
-my $environ = join q{|}, map { quotemeta } sort { length $a <=> length $b } @extractenv;
-$environ = qr/$environ/x;
-my $extr_tmp = qr {
- (
- (?:
- \\begin\{$environ\*?\}
- (?:
- (?>[^\\]+)|
- \\
- (?!begin\{$environ\*?\})
- (?!end\{$environ\*?\})|
- (?-1)
- )*
- \\end\{$environ\*?\}
- )
- )
- }x;
-
-### Hash for replace in verbatim begin -> Begin end -> END
-my %extract_env = crearhash(@extractenv);
-
-### The preview and nopreview environments are "special", need replace
-### in verbatim's environments begin -> Begin end -> END
-my @preview_env = qw(preview nopreview);
-my %preview_env = crearhash(@preview_env);
-
-Log('Making changes to verbatim/verbatim write environments before extraction');
-
-### Hash and Regex for changes, this "regex" is re-used in ALL script
-my %replace = (%extract_env, %preview_env, %changes_in, %document);
-my $find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
-
-### We go line by line and make the changes [need /p for ${^MATCH}]
-while ($document =~ /$verb_wrt | $verb_std /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- $encontrado =~ s/($find)/$replace{$1}/g;
- substr $document, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($document) = $pos_inicial + length $encontrado;
-}
-
-### Now match preview environment in <input file>
-my @env_preview = $document =~ m/(\\begin\{preview\}.+?\\end\{preview\})/gmsx;
-
-### Convert preview to nopreview environment
-if (@env_preview) {
- my $preNo = scalar @env_preview;
- Log("Found $preNo preview environments in $name$ext");
- Log("Pass all preview environments to \\begin{nopreview}\%TMP$tmp ... \\end{nopreview}\%TMP$tmp");
- $document =~ s/(?:(\\begin\{|\\end\{))(preview\})/$1no$2\%TMP$tmp/gmsx;
-}
-
-### Pass verbatim write environments to dtxtag
-Log("Pass verbatim write environments to %<*$dtxverb> ... %</$dtxverb>");
-$document =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- ($verb_wrt)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-$atbegindoc =~ s/($verb_wrt)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-
-### Pass verbatim environments to dtxtag
-Log("Pass verbatim environments to %<*$dtxverb> ... %</$dtxverb>");
-$document =~ s/\\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ($verb_std)/\%<\*$dtxverb>$1\%<\/$dtxverb>/gmsx;
-
-### Pass %CleanPST to dtxtag
-Log("Pass %CleanPST ... %CleanPST to %<*remove$tmp> ... %</remove$tmp>");
-$document =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^(?:%CleanPST) (.+?) (?:%CleanPST)/\%<\*remove$tmp>$1\%<\/remove$tmp>/gmsx;
-
-### Check plain TeX syntax for pspicture [skip PSTexample]
-Log('Convert plain \pspicture to LaTeX syntax [skip in PSTexample]');
-$document =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- \\pspicture(\*)?(.+?)\\endpspicture/\\begin\{pspicture$1\}$2\\end\{pspicture$1\}/gmsx;
-
-### Check plain TeX syntax for psgraph [skip PSTexample]
-Log('Convert plain \psgraph to LaTeX syntax [skip in PSTexample]');
-$document =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- \\psgraph(\*)?(.+?)\\endpsgraph/\\begin\{psgraph$1\}$2\\end\{psgraph$1\}/gmsx;
-
-### Pass all postscript environments [skip in PSTexample]
-Log("Pass all postscript environments to \\begin{$wrapping} ... \\end{$wrapping}");
-$document =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- (?:\\begin\{postscript\})(?:\s*\[ [^]]*? \])?
- (?<code>.+?)
- (?:\\end\{postscript\})
- /\\begin\{$wrapping\}$+{code}\\end\{$wrapping\}/gmsx;
-
-### Pass all pstricks environments to \\begin{$wrapping} ... \\end{$wrapping}");
-if ($force) {
- # Try to capture \psset{...} for pstricks and psgraph [force]
- Log('Try to capture \psset{...} for pstricks environments [force mode]');
- Log("Pass all pstricks environments to \\begin{$wrapping} ... \\end{$wrapping} [force mode]");
- $document =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{PSTexample\}.+?\\end\{PSTexample\}(*SKIP)(*F)|
- \\begin\{$wrapping\}.+?\\end\{$wrapping\}(*SKIP)(*F)|
- (?<code>
- (?:\\psset\{(?:\{.*?\}|[^\{])*\}.+?)? # if exist ...save
- \\begin\{(?<env> pspicture\*?| psgraph)\} .+? \\end\{\k<env>\}
- )
- /\\begin\{$wrapping\}$+{code}\\end\{$wrapping\}/gmsx;
-}
-else {
- Log("Pass all pstricks environments to \\begin{$wrapping} ... \\end{$wrapping}");
- $document =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\begin\{nopreview\}.+?\\end\{nopreview\}(*SKIP)(*F)|
- \\begin\{$wrapping\}.+?\\end\{$wrapping\}(*SKIP)(*F)|
- ($extr_tmp)/\\begin\{$wrapping\}$1\\end\{$wrapping\}/gmsx;
-}
-
-### All environments are now classified:
-### Extraction -> \begin{$wrapping} ... \end{$wrapping}
-### Verbatim's -> %<\*$dtxverb> ... <\/$dtxverb>
-
-### Now split document
-my ($preamble,$bodydoc,$enddoc) = $document =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
-
-### Hash for reverse changes for extract and <output file>
-my %changes_out = (
- '\PSSET' => '\psset',
- '\TIKZSET' => '\tikzset',
- '\TRICKS' => '\pspicture',
- '\ENDTRICKS' => '\endpspicture',
- '\PSGRAPHTRICKS' => '\psgraph',
- '\ENDPSGRAPHTRICKS' => '\endpsgraph',
- '\USEPACKAGE' => '\usepackage',
- '{GRAPHICX}' => '{graphicx}',
- '\GRAPHICSPATH{' => '\graphicspath{',
- '\BEGIN{' => '\begin{',
- '\END{' => '\end{',
- '\DOCUMENTCLASS' => '\documentclass',
- '\PAGESTYLE{' => '\pagestyle{',
- '\THISPAGESTYLE{' => '\thispagestyle{',
- '%PSTCLEAN' => '%CleanPST',
- );
-
-### We restore the changes in body of environments and dtxverb
-%replace = (%changes_out);
-$find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
-$bodydoc =~ s/($find)/$replace{$1}/g;
-$preamble =~ s/($find)/$replace{$1}/g;
-
-### First search PSTexample environment for extract
-my @exa_extract = $bodydoc =~ m/(?:\\begin\{$wrapping\})($BE.+?$EE)(?:\\end\{$wrapping\})/gmsx;
-my $exaNo = scalar @exa_extract;
-
-### Set vars for log and print in terminal
-my $envEXA = $exaNo > 1 ? 'PSTexample environments' : 'PSTexample environment';
-my $fileEXA = $exaNo > 1 ? 'files' : 'file';
-
-### If PSTexample environment found
-if ($exaNo!=0) {
- $PSTexa = 1;
- Log("Found $exaNo $envEXA in $name$ext");
- my $figNo = 1;
- for my $item (@exa_extract) {
- Logline("%##### PSTexample environment captured number $figNo ######%");
- Logline($item);
- $figNo++;
- }
- # Add [graphic={[...]...}] to \begin{PSTexample}[...]
- Log('Append [graphic={[...]...}] to \begin{PSTexample}[...]');
- $figNo = 1;
- while ($bodydoc =~ /\\begin\{$wrapping\}(\s*)?\\begin\{PSTexample\}(\[.+?\])?/gsm) {
- my $swpl_grap = "graphic=\{\[scale=1\]$imgdir/$name-fig-exa";
- my $corchetes = $1;
- my ($pos_inicial, $pos_final) = ($-[1], $+[1]);
- if (not $corchetes) { $pos_inicial = $pos_final = $+[0]; }
- if (not $corchetes or $corchetes =~ /\[\s*\]/) {
- $corchetes = "[$swpl_grap-$figNo}]";
- }
- else { $corchetes =~ s/\]/,$swpl_grap-$figNo}]/; }
- substr($bodydoc, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;
- pos($bodydoc) = $pos_inicial + length $corchetes;
- }
- continue { $figNo++; }
- Log('Pass PSTexample environments to \begin{nopreview} ... \end{nopreview}');
- $bodydoc =~ s/\\begin\{$wrapping\}
- (?<code>\\begin\{PSTexample\} .+? \\end\{PSTexample\})
- \\end\{$wrapping\}
- /\\begin\{nopreview\}\%$tmp$+{code}\\end\{nopreview\}\%$tmp/gmsx;
-}
-
-### Second search any pstricks environment for extract
-my @env_extract = $bodydoc =~ m/(?:$BP)(.+?)(?:$EP)/gmsx;
-my $envNo = scalar @env_extract;
-
-### Set vars for log and print in terminal
-my $envSTD = $envNo > 1 ? 'pstricks environments' : 'pstricks environment';
-my $fileSTD = $envNo > 1 ? 'files' : 'file';
-
-### If any pstricks environments found
-if ($envNo!=0) {
- $STDenv = 1;
- Log("Found $envNo $envSTD in $name$ext");
- my $fig = 1;
- for my $item (@env_extract) {
- Logline("%##### Environment pstricks captured number $fig ######%");
- Logline($item);
- $fig++;
- }
-}
-
-### Run script process only if any enviroment(s) found in <input file>
-if ($envNo == 0 and $exaNo == 0) {
- errorUsage("$scriptname can not find any environment to extract in $name$ext");
-}
-
-### Storing ALL current options of script process for .log file
-if ($zip) { $opts_cmd{boolean}{zip} = 1; }
-if ($tar) { $opts_cmd{boolean}{tar} = 1; }
-if ($shell) { $opts_cmd{boolean}{shell} = 1; }
-if ($nopdf) { $opts_cmd{boolean}{nopdf} = 1; }
-if ($norun) { $opts_cmd{boolean}{norun} = 1; }
-if ($nocrop) { $opts_cmd{boolean}{nocrop} = 1; }
-if ($srcenv) { $opts_cmd{boolean}{srcenv} = 1; }
-if ($gray) { $opts_cmd{boolean}{gray} = 1; }
-if ($force) { $opts_cmd{boolean}{force} = 1; }
-if ($noprew) { $opts_cmd{boolean}{noprew} = 1; }
-if ($runbibtex) { $opts_cmd{boolean}{bibtex} = 1; }
-if ($runbiber) { $opts_cmd{boolean}{biber} = 1; }
-if ($clear) { $opts_cmd{boolean}{clear} = 1; }
-if ($nosource) { $opts_cmd{boolean}{nosource} = 1; }
-if ($arara) { $opts_cmd{compiler}{arara} = 1; }
-if ($latexmk) { $opts_cmd{compiler}{latexmk} = 1; }
-if ($luatex) { $opts_cmd{compiler}{luatex} = 1; }
-if ($xetex) { $opts_cmd{compiler}{xetex} = 1; }
-if ($tmpverbenv) { $opts_cmd{string}{ignore} = $tmpverbenv; }
-$opts_cmd{string}{myverb} = $myverb;
-$opts_cmd{string}{dpi} = $dpi;
-$opts_cmd{string}{runs} = $runs;
-$opts_cmd{string}{margins} = $margins;
-$opts_cmd{string}{imgdir} = $imgdir;
-
-foreach my $key (keys %{$opts_cmd{boolean}}) {
- if (defined $opts_cmd{boolean}{$key}) { push @currentopt, "--$key"; }
-}
-foreach my $key (keys %{$opts_cmd{compiler}}) {
- if (defined $opts_cmd{compiler}{$key}) { push @currentopt, "--$key"; }
-}
-foreach my $key (keys %{$opts_cmd{image}}) {
- if (defined $opts_cmd{image}{$key}) { push @currentopt, "--$key"; }
-}
-foreach my $key (keys %{$opts_cmd{string}}) {
- if (defined $opts_cmd{string}{$key}) { push @currentopt, "--$key $opts_cmd{string}{$key}"; }
-}
-
-@currentopt = grep !/--pdf/, @currentopt;
-my @sorted_words = sort { length $a <=> length $b } @currentopt;
-
-Log('The script will execute the following options:');
-Logarray(\@sorted_words);
-
-### Set directory to save generated files, need full path for goog log :)
-my $imgdirpath = File::Spec->rel2abs($imgdir);
-
-if (-e $imgdir) {
- Infoline("The generated files will be saved in $imgdirpath");
-}
-else {
- Infoline("Creating the directory $imgdirpath to save the generated files");
- Infocolor('Running', "mkdir $imgdirpath");
- Logline("[perl] mkdir($imgdir,0744)");
- mkdir $imgdir,0744 or errorUsage("Can't create the directory $imgdir");
-}
-
-### Set compiler for process <input file>
-my $compiler = $xetex ? 'xelatex'
- : $luatex ? 'dvilualatex'
- : 'latex'
- ;
-
-### Set options for pdfcrop
-my $opt_crop = $xetex ? "--xetex --margins $margins"
- : $luatex ? "--luatex --margins $margins"
- : "--margins $margins"
- ;
-
-### Set options for preview package
-my $opt_prew = $xetex ? 'xetex,' : q{};
-
-### Set message in terminal
-my $msg_compiler = $xetex ? 'xelatex'
- : $luatex ? 'dvilualatex>dvips>ps2pdf'
- : 'latex>dvips>ps2pdf'
- ;
-
-### Set write18 for compiler in TeXLive and MikTeX
-if ($shell) {
- $write18 = '-shell-escape';
- $write18 = '--enable-write18' if defined $ENV{'TEXSYSTEM'} and $ENV{'TEXSYSTEM'} =~ /miktex/i;
-}
-else {
- $write18 = '-no-shell-escape';
- $write18 = '--disable-write18' if defined $ENV{'TEXSYSTEM'} and $ENV{'TEXSYSTEM'} =~ /miktex/i;
-}
-
-### Set options for compiler
-my $opt_compiler = "$write18 -interaction=nonstopmode -recorder";
-
-if (!$norun) {
- Log("The options '$opt_compiler' will be passed to $compiler");
-}
-
-### Set -q for system command line (gs, poppler-utils, dvips)
-my $quiet = $verbose ? q{} : '-q';
-
-### Set options for ghostscript
-my %opt_gs_dev = (
- pdf => '-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite',
- gray => '-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -sProcessColorModel=DeviceGray',
- png => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -r$dpi",
- bmp => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=bmp32b -r$dpi",
- jpg => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=jpeg -r$dpi -dJPEGQ=100 -dGraphicsAlphaBits=4 -dTextAlphaBits=4",
- tif => "-dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=tiff32nc -r$dpi",
- );
-
-### Set poppler-utils executables
-my %cmd_poppler = (
- eps => "pdftops",
- ppm => "pdftoppm",
- svg => "pdftocairo",
- );
-
-### Set options for poppler-utils
-my %opt_poppler = (
- eps => "$quiet -eps",
- ppm => "$quiet -r $dpi",
- svg => "$quiet -svg",
- );
-
-### Copy preamble and body for temp file with all environments
-my $atbeginout = $atbegindoc;
-my $preamout = $preamble;
-my $tmpbodydoc = $bodydoc;
-
-### Match \pagestyle and \thispagestyle in preamble
-my $style_page = qr /(?:\\)(?:this)?(?:pagestyle\{) (.+?) (?:\})/x;
-my @style_page = $preamout =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)| $style_page/gmsx;
-my %style_page = map { $_ => 1 } @style_page; # anon hash
-
-### Set \pagestyle{empty} for standalone files and process
-if (@style_page) {
- if (!exists $style_page{empty}) {
- Log("Replacing page style for generated files");
- $preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (\\(this)?pagestyle)(?:\{.+?\})/$1\{empty\}/gmsx;
- }
-}
-else {
- Log('Add \pagestyle{empty} for generated files');
- $preamout = $preamout."\\pagestyle\{empty\}\n";
-}
-
-### We created a preamble for the individual files
-my $sub_prea = "$atbeginout$preamout".'\begin{document}';
-
-### Revert changes
-$sub_prea =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
-%replace = (%changes_out);
-$find = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %replace;
-$sub_prea =~ s/($find)/$replace{$1}/g;
-$sub_prea =~ s/^(?:\%<\*remove$tmp>)(.+?)(?:\%<\/remove$tmp>)/%CleanPST$1%CleanPST/gmsx;
-
-### Write standalone files for environments
-if (!$nosource) {
- my $src_name = "$name-fig-";
- my $srcNo = 1;
- if ($srcenv) {
- Log('Extract source code of all captured environments without preamble');
- if ($STDenv) {
- if (-e "$imgdir/$name-fig-1$ext") {
- Log("Recreating $envNo $fileSTD [$ext] with source code for $envSTD in $imgdirpath");
- print "Recreating $envNo $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envSTD\r\n";
- }
- else {
- Log("Creating $envNo $fileSTD [$ext] with source code for $envSTD in $imgdirpath");
- print "Creating $envNo $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envSTD\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BP(?:\s*)?(?<env_src>.+?)(?:\s*)?$EP/gms) {
- open my $outexasrc, '>', "$imgdir/$src_name$srcNo$ext";
- print {$outexasrc} $+{'env_src'};
- close $outexasrc;
- }
- continue { $srcNo++; }
- }
- if ($PSTexa) {
- if (-e "$imgdir/$name-fig-exa-1$ext") {
- Log("Recreating $exaNo $fileEXA [$ext] with source code for $envEXA in $imgdirpath");
- print "Recreating $exaNo $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envEXA\r\n";
- }
- else {
- Log("Creating $exaNo $fileEXA [$ext] with source code for $envEXA in $imgdirpath");
- print "Creating $exaNo $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " with source code for $envEXA\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BE\[.+?(?<pst_exa_name>$imgdir\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
- open my $outstdsrc, '>', "$+{'pst_exa_name'}$ext";
- print {$outstdsrc} $+{'exa_src'};
- close $outstdsrc;
- }
- }
- }
- else {
- Log('Extract source code of all captured environments with preamble');
- if ($STDenv) {
- if (-e "$imgdir/$name-fig-1$ext") {
- Log("Recreating $envNo standalone $fileSTD [$ext] for $envSTD in $imgdirpath");
- print "Recreating $envNo standalone $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " for $envSTD\r\n";
- }
- else {
- Log("Creating $envNo standalone $fileSTD [$ext] for $envSTD in $imgdirpath");
- print "Creating $envNo standalone $fileSTD ", color('magenta'), "[$ext]",
- color('reset'), " for $envSTD\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BP(?:\s*)?(?<env_src>.+?)(?:\s*)?$EP/gms) {
- open my $outstdfile, '>', "$imgdir/$src_name$srcNo$ext";
- print {$outstdfile} "$sub_prea\n$+{'env_src'}\n\\end\{document\}";
- close $outstdfile;
- }
- continue { $srcNo++; }
- }
- if ($PSTexa) {
- if (-e "$imgdir/$name-fig-exa-1$ext") {
- Log("Recreating $exaNo standalone $fileEXA [$ext] for $envEXA in $imgdirpath");
- print "Recreating $exaNo standalone $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " for $envEXA\r\n";
- }
- else {
- Log("Creating $exaNo standalone $fileEXA [$ext] for $envEXA in $imgdirpath");
- print "Creating $exaNo standalone $fileEXA ", color('magenta'), "[$ext]",
- color('reset'), " for $envEXA\r\n";
- }
- # Write files
- while ($tmpbodydoc =~ m/$BE\[.+?(?<pst_exa_name>$imgdir\/.+?-\d+)\}\]\s*(?<exa_src>.+?)\s*$EE/gms) {
- open my $outexafile, '>', "$+{'pst_exa_name'}$ext";
- print {$outexafile} "$sub_prea\n$+{'exa_src'}\n\\end\{document\}";
- close $outexafile;
- }
- }
- }
-}
-
-### Store options for preview and pst-pdf (add at begin document)
-my $previewpkg = <<"EXTRA";
-\\PassOptionsToPackage\{inactive\}\{pst-pdf\}%
-\\AtBeginDocument\{%
-\\RequirePackage\[inactive\]\{pst-pdf\}%
-\\RequirePackage\[${opt_prew}active,tightpage\]\{preview\}%
-\\renewcommand\\PreviewBbAdjust\{-60pt -60pt 60pt 60pt\}\}%
-EXTRA
-
-### Store options for pst-pdf (add at begin document)
-my $pstpdfpkg = <<'EXTRA';
-\PassOptionsToPackage{inactive}{pst-pdf}
-\AtBeginDocument{%
-\RequirePackage[inactive]{pst-pdf}}%
-EXTRA
-
-### First match preview package in preamble (prevent option clash)
-my $REQPACK = quotemeta'\RequirePackage';
-my $USEPACK = quotemeta'\usepackage';
-my $CORCHETES = qr/\[ [^]]*? \]/x;
-
-my $PALABRAS = qr/\b (?: preview )/x;
-my $FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
-
-Log('Remove preview package in preamble [memory]');
-$preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
-$preamout =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
-$preamout =~ s/^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
-
-### Remove %<*$dtxverb> ... %</$dtxverb> in tmpbodydoc and preamout
-$tmpbodydoc =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-$preamout =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-$atbeginout =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-
-### Adjust nopreview environments
-$tmpbodydoc =~ s/\\begin\{nopreview\}\%$tmp
- (?<code> .+?)
- \\end\{nopreview\}\%$tmp
- /\\begin\{nopreview\}\n$+{code}\n\\end\{nopreview\}/gmsx;
-
-### Adjust $wrapping environments (no need realy)
-$tmpbodydoc =~ s/\\begin\{$wrapping\}
- (?<code>.+?)
- \\end\{$wrapping\}
- /\\begin\{$wrapping\}\n$+{code}\n\\end\{$wrapping\}/gmsx;
-
-### Reverse changes for temporary file with all env (no in -exa file)
-$tmpbodydoc =~ s/($find)/$replace{$1}/g;
-$tmpbodydoc =~ s/(\%TMP$tmp)//g;
-$preamout =~ s/($find)/$replace{$1}/g;
-$preamout =~ s/^(?:\%<\*remove$tmp>)(.+?)(?:\%<\/remove$tmp>)/%CleanPST$1%CleanPST/gmsx;
-$atbeginout =~ s/($find)/$replace{$1}/g;
-
-### We created a preamble for individual files with all environments
-$sub_prea = $noprew ? "$atbeginout$pstpdfpkg$preamout".'\begin{document}'
- : "$atbeginout$previewpkg$preamout"
- ;
-
-### Create a one file with "all" PSTexample environments extracted
-if ($PSTexa) {
- @exa_extract = undef;
- Log("Adding packages to $name-fig-exa-$tmp$ext [memory]");
- Logline($pstpdfpkg);
- Log('Convert plain Tex syntax for pspicture and psgraph to LaTeX syntax in PSTexample environments');
- while ($tmpbodydoc =~ m/$BE\[.+? $imgdir\/.+?-\d+\}\] .+?$EE/pgsmx ) { # search
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- $encontrado =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin\{pspicture$1\}$2\\end\{pspicture$1\}/gmsx;
- $encontrado =~ s/\\psgraph(\*)?(.+?)\\endpsgraph/\\begin\{psgraph$1\}$2\\end\{psgraph$1\}/gmsx;
- substr $tmpbodydoc, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($tmpbodydoc) = $pos_inicial + length $encontrado;
- }
- # Write file
- Infoline("Creating $name-fig-exa-$tmp$ext with $exaNo $envEXA extracted");
- while ($tmpbodydoc =~ m/$BE\[.+? $imgdir\/.+?-\d+\}\](?<exa_src>.+?)$EE/gmsx ) { # search
- push @exa_extract, $+{'exa_src'}."\\newpage\n";
- open my $allexaenv, '>', "$name-fig-exa-$tmp$ext";
- print {$allexaenv} "$atbeginout$pstpdfpkg$preamout".'\begin{document}'."@exa_extract"."\\end\{document\}";
- close $allexaenv;
- }
- # Remove [graphic={...}] in PSTexample example environments
- $tmpbodydoc =~ s/($BE)(?:\[graphic=\{\[scale=1\]$imgdir\/.+?-\d+\}\])/$1/gmsx;
- $tmpbodydoc =~ s/($BE\[.+?)(?:,graphic=\{\[scale=1\]$imgdir\/.+?-\d+\})(\])/$1$2/gmsx;
- # Moving and renaming
- if ($norun) {
- Infoline("Moving and renaming $name-fig-exa-$tmp$ext to $name-fig-exa-all$ext");
- if (-e "$imgdir/$name-fig-exa-all$ext") {
- Infocolor('Warning', "The file [$name-fig-exa-all$ext] already exists and will be rewritten");
- Log("Rewriting the file $name-fig-exa-all$ext in $imgdirpath");
- }
- else {
- Log("Writing the file $name-fig-exa-all$ext in $imgdirpath");
- }
- if ($verbose) {
- Infocolor('Running', "mv $workdir/$name-fig-exa-$tmp$ext $imgdirpath/$name-fig-exa-all$ext");
- }
- else {
- Infocolor('Running', "mv $name-fig-exa-$tmp$ext ./$imgdir/$name-fig-exa-all$ext");
- }
- Logline("[perl] move($workdir/$name-fig-exa-$tmp$ext, $imgdirpath/$name-fig-exa-all$ext)");
- move("$workdir/$name-fig-exa-$tmp$ext", "$imgdir/$name-fig-exa-all$ext")
- or die "* Error!!: Couldn't be renamed $name-fig-exa-$tmp$ext to ./$imgdir/$name-fig-exa-all$ext";
- }
-}
-
-### Create a one file with "all" standard environments extracted
-if ($STDenv) {
- if ($noprew) {
- Log("Creating $name-fig-$tmp$ext with $envNo $envSTD extracted [no preview]");
- print "Creating $name-fig-$tmp$ext with $envNo $envSTD extracted",
- color('magenta'), " [no preview]\r\n",color('reset');
- }
- else {
- Log("Creating $name-fig-$tmp$ext with $envNo $envSTD extracted [preview]");
- print "Creating $name-fig-$tmp$ext with $envNo $envSTD extracted",
- color('magenta'), " [preview]\r\n",color('reset');
- }
- open my $allstdenv, '>', "$name-fig-$tmp$ext";
- if ($noprew) {
- my @env_extract;
- while ($tmpbodydoc =~ m/(?:$BP)(?<env_src>.+?)(?:$EP)/gms) {
- push @env_extract,$+{'env_src'}."\\newpage\n";
- }
- Log("Adding packages to $name-fig-$tmp$ext");
- Logline($pstpdfpkg);
- print {$allstdenv} $sub_prea."@env_extract"."\\end{document}";
- }
- else {
- Log("Adding packages to $name-fig-$tmp$ext");
- Logline($previewpkg);
- Log("Convert $wrapping to preview environments in $name-fig-$tmp$ext");
- # Convert $wrapping to preview environments
- $tmpbodydoc =~ s/\\begin\{$wrapping\}(?<code>.+?)\\end\{$wrapping\}
- /\\begin\{preview\}\n$+{code}\n\\end\{preview\}\n/gmsx;
- print {$allstdenv} $sub_prea.$tmpbodydoc."\n\\end{document}";
- }
- close $allstdenv;
- # Moving and renaming
- if ($norun) {
- Infoline("Moving and renaming $name-fig-$tmp$ext to $name-fig-all$ext");
- if (-e "$imgdir/$name-fig-all$ext") {
- Infocolor('Warning', "The file [$name-fig-all$ext] already exists and will be rewritten");
- Log("Rewriting the file $name-fig-all$ext in $imgdirpath");
- }
- else {
- Log("Writing the file $name-fig-all$ext in $imgdirpath");
- }
- if ($verbose) {
- Infocolor('Running', "mv $workdir/$name-fig-$tmp$ext $imgdirpath/$name-fig-all$ext");
- }
- else {
- Infocolor('Running', "mv $name-fig-$tmp$ext ./$imgdir/$name-fig-all$ext");
- }
- Logline("[perl] move($workdir/$name-fig-$tmp$ext, $imgdirpath/$name-fig-all$ext)");
- move("$workdir/$name-fig-$tmp$ext", "$imgdir/$name-fig-all$ext")
- or die "* Error!!: Couldn't be renamed $name-fig-$tmp$ext to ./$imgdir/$name-fig-all$ext";
- }
-}
-
-### Compiler and generate PDF files
-if (!$norun) {
-Log('Generate a PDF file with all captured environments');
-my @compiler = (1..$runs);
-opendir (my $DIR, $workdir);
- while (readdir $DIR) {
- if (/(?<name>$name-fig(-exa)?)(?<type>-$tmp$ext)/) {
- Log("Compiling the file $+{name}$+{type} using [$msg_compiler]");
- print "Compiling the file $+{name}$+{type} using ", color('magenta'), "[$msg_compiler]\r\n",color('reset');
- # Compiling file
- for (@compiler){
- RUNOSCMD("$compiler $opt_compiler","$+{name}$+{type}",'show');
- }
- # Using dvips>ps2pdf
- if ($compiler eq 'latex' or $compiler eq 'dvilualatex') {
- RUNOSCMD("dvips $quiet -Ppdf", "-o $+{name}-$tmp.ps $+{name}-$tmp.dvi",'show');
- RUNOSCMD("ps2pdf -sPDFSETTINGS=prepress -sAutoRotatePages=None", "$+{name}-$tmp.ps $+{name}-$tmp.pdf",'show');
- }
- # Moving and renaming temp files with source code
- Infoline("Moving and renaming $+{name}$+{type} to $+{name}-all$ext");
- if (-e "$imgdir/$+{name}-all$ext") {
- Infocolor('Warning', "The file [$+{name}-all$ext] already exists and will be rewritten");
- Log("Rewriting the file $+{name}-all$ext with all source for environments in $imgdirpath");
- }
- else {
- Log("Writing the file $+{name}-all$ext with all source for environments in $imgdirpath");
- }
- if ($verbose){
- Infocolor('Running', "mv $workdir/$+{name}$+{type} $imgdirpath/$+{name}-all$ext");
- }
- else {
- Infocolor('Running', "mv $+{name}$+{type} ./$imgdir/$+{name}-all$ext");
- }
- Logline("[perl] move($workdir/$+{name}$+{type}, $imgdirpath/$+{name}-all$ext)");
- move("$workdir/$+{name}$+{type}", "$imgdir/$+{name}-all$ext")
- or die "* Error!!: Couldn't be renamed $+{name}$+{type} to $imgdir/$+{name}-all$ext";
- # pdfcrop
- if (!$nocrop) {
- Infoline("Cropping the file $+{name}-$tmp.pdf");
- RUNOSCMD("pdfcrop $opt_crop", "$+{name}-$tmp.pdf $+{name}-$tmp.pdf",'show');
- }
- # gray
- if ($gray) {
- Infoline("Creating the file $+{name}-all.pdf [gray] in $tempDir");
- RUNOSCMD("$gscmd $quiet $opt_gs_dev{gray} ","-o $tempDir/$+{name}-all.pdf $workdir/$+{name}-$tmp.pdf",'show');
- }
- else {
- Infoline("Creating the file $+{name}-all.pdf in $tempDir");
- if ($verbose){
- Infocolor('Running', "mv $workdir/$+{name}-$tmp.pdf $tempDir/$+{name}-all.pdf");
- }
- else { Infocolor('Running', "mv $+{name}-$tmp.pdf $tempDir/$+{name}-all.pdf"); }
- # Renaming pdf file
- Logline("[perl] move($workdir/$+{name}-$tmp.pdf, $tempDir/$+{name}-all.pdf)");
- move("$workdir/$+{name}-$tmp.pdf", "$tempDir/$+{name}-all.pdf")
- or die "* Error!!: Couldn't be renamed $+{name}-$tmp.pdf to $tempDir/$+{name}-all.pdf";
- }
- }
- }
-closedir $DIR;
-}
-
-### Create image formats in separate files
-if (!$norun) {
- Log("Creating the image formats: $format, working on $tempDir");
- opendir(my $DIR, $tempDir);
- while (readdir $DIR) {
- # PDF/PNG/JPG/BMP/TIFF format suported by ghostscript
- if (/(?<name>$name-fig(-exa)?)(?<type>-all\.pdf)/) {
- for my $var (qw(pdf png jpg bmp tif)) {
- if (defined $opts_cmd{image}{$var}) {
- Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $gscmd");
- print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
- RUNOSCMD("$gscmd $quiet $opt_gs_dev{$var} ", "-o $workdir/$imgdir/$+{name}-%1d.$var $tempDir/$+{name}$+{type}",'show');
- }
- }
- }
- # EPS/PPM/SVG format suported by poppler-utils
- if (/(?<name>$name-fig-exa)(?<type>-all\.pdf)/) { # pst-exa package
- for my $var (qw(eps ppm svg)) {
- if (defined $opts_cmd{image}{$var}) {
- Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $cmd_poppler{$var}");
- print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
- if (!$verbose){
- Infocolor('Running', "$cmd_poppler{$var} $opt_poppler{$var}");
- }
- for (my $epsNo = 1; $epsNo <= $exaNo; $epsNo++) {
- RUNOSCMD("$cmd_poppler{$var} $opt_poppler{$var}", "-f $epsNo -l $epsNo $tempDir/$+{name}$+{type} $workdir/$imgdir/$+{name}-$epsNo.$var",'only');
- }
- }
- }
- }
- if (/(?<name>$name-fig)(?<type>-all\.pdf)/) {
- for my $var (qw(eps ppm svg)) {
- if (defined $opts_cmd{image}{$var}) {
- Log("Generating format [$var] from file $+{name}$+{type} in $imgdirpath using $cmd_poppler{$var}");
- print 'Generating format', color('blue'), " [$var] ", color('reset'),"from file $+{name}$+{type}\r\n";
- if (!$verbose){
- Infocolor('Running', "$cmd_poppler{$var} $opt_poppler{$var}");
- }
- for (my $epsNo = 1; $epsNo <= $envNo; $epsNo++) {
- RUNOSCMD("$cmd_poppler{$var} $opt_poppler{$var}", "-f $epsNo -l $epsNo $tempDir/$+{name}$+{type} $workdir/$imgdir/$+{name}-$epsNo.$var",'only');
- }
- }
- }
- }
- } # close while
- closedir $DIR;
- # Renaming PPM image files
- if (defined $opts_cmd{image}{ppm}) {
- Log("Renaming [ppm] images in $imgdirpath");
- if ($verbose){
- print 'Renaming', color('blue'), " [ppm] ", color('reset'),"images in $imgdirpath\r\n";
- }
- opendir(my $DIR, $imgdir);
- while (readdir $DIR) {
- if (/(?<name>$name-fig(-exa)?-\d+\.ppm)(?<sep>-\d+)(?<ppm>\.ppm)/) {
- if ($verbose){
- Infocolor('Running', "mv $+{name}$+{sep}$+{ppm} $+{name}");
- }
- Logline("[perl] move($imgdirpath/$+{name}$+{sep}$+{ppm}, $imgdirpath/$+{name})");
- move("$imgdir/$+{name}$+{sep}$+{ppm}", "$imgdir/$+{name}")
- or die "* Error!!: Couldn't be renamed $+{name}$+{sep}$+{ppm} to $+{name}";
- }
- }
- closedir $DIR;
- }
-} # close run
-
-### Constant
-my $findgraphicx = 'true';
-
-### Replacing the extracted environments with \includegraphics
-Log("Convert pstricks extracted environments to \\includegraphics for $name-pdf$ext");
-my $grap = "\\includegraphics[scale=1]{$name-fig-";
-my $close = '}';
-my $imgNo = 1;
-$bodydoc =~ s/$BP.+?$EP/$grap@{[$imgNo++]}$close/msg;
-
-### Add $atbegindoc to $preamble
-$preamble = "$atbegindoc$preamble";
-
-### Remove content in preamble
-my @tag_remove_preamble = $preamble =~ m/(?:^\%<\*remove$tmp>.+?\%<\/remove$tmp>)/gmsx;
-if (@tag_remove_preamble) {
- Log("Removing the content between %CleanPST ... %CleanPST in preamble for $name-pdf$ext");
- $preamble =~ s/^\%<\*remove$tmp>\s*(.+?)\s*\%<\/remove$tmp>(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
-}
-
-### Suport for pst-exa package
-my $pstexa = qr/(?:\\ usepackage) \[\s*(.+?)\s*\] (?:\{\s*(pst-exa)\s*\} ) /x;
-my @pst_exa;
-my %pst_exa;
-
-### Search pst-exa package
-@pst_exa = $preamble =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|$pstexa/gmsx;
-%pst_exa = map { $_ => 1 } @pst_exa;
-
-### If found comment and adjust path for graphic files
-if (@pst_exa) {
- Log("Comment pst-exa package in preamble for $name-pdf$ext");
- $findgraphicx = 'false';
- $preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (\\usepackage\[)\s*(swpl|tcb)\s*(\]\{pst-exa\})/\%$1$2,pdf$3/msxg;
- # Change for [tcb] option (path for graphic files)
- if (exists $pst_exa{tcb}) {
- Log("Suport for \\usepackage[tcb,pdf]\{pst-exa\} for $name-pdf$ext");
- $bodydoc =~ s/(graphic=\{)\[(scale=\d*)\]($imgdir\/$name-fig-exa-\d*)\}/$1$2\}\{$3\}/gsmx;
- }
-}
-
-### Regex for remove (pst-?) packages in preamble
-$PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add | -pdf )? | psfrag |psgo |vaucanson-g| auto-pst-pdf(?: -lua )? )/x;
-$FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
-
-Log("Remove pstricks packages in preamble for $name-pdf$ext [no pst-exa]");
-$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
-$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- (?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
-
-### Uncomment pst-exa package
-if (@pst_exa) {
- Log("Uncomment pst-exa package in preamble for $name-pdf$ext");
- $preamble =~ s/(?:\%)(\\usepackage\[\s*)(swpl|tcb)(,pdf\s*\]\{pst-exa\})/$1$2$3/msxg;
-}
-
-Log("Remove \\psset\{...\} in preamble for $name-pdf$ext");
-$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
-
-Log("Remove \\SpecialCoor in preamble for $name-pdf$ext");
-$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- \\SpecialCoor(?:[\t ]*(?:\r?\n|\r))+//gmsx;
-
-Log("Remove empty lines in preamble for $name-pdf$ext");
-$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
-$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
- ^(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
-
-### To be sure that the package graphicx and \graphicspath is in the main
-### document and not in a verbatim write environment we make the changes
-my %tmpreplace = (
- 'graphicx' => 'TMPGRAPHICXTMP',
- 'graphicspath' => 'TMPGRAPHICSPATHTMP',
-);
-my $findtmp = join q{|}, map { quotemeta } sort { length $a <=> length $b } keys %tmpreplace;
-
-### We go line by line and make the changes [need /p for ${^MATCH}]
-while ($preamble =~ /\%<\*$dtxverb>(.+?)\%<\/$dtxverb> | $tmpcomment /pgmsx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- $encontrado =~ s/($findtmp)/$tmpreplace{$1}/g;
- substr $preamble, $pos_inicial, $pos_final-$pos_inicial, $encontrado;
- pos ($preamble) = $pos_inicial + length $encontrado;
-}
-
-### Now we're trying to capture \graphicspath{...}
-my $graphicspath= qr/\\ graphicspath \{ ((?: $llaves )+) \}/ix;
-my @graphicspath;
-@graphicspath = $preamble =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|($graphicspath)/gmsx;
-
-if (@graphicspath) {
- Log("Found \\graphicspath in preamble for $name-pdf$ext");
- $findgraphicx = 'false';
- while ($preamble =~ /$graphicspath /pgmx) {
- my ($pos_inicial, $pos_final) = ($-[0], $+[0]);
- my $encontrado = ${^MATCH};
- if ($encontrado =~ /$graphicspath/) {
- my $argumento = $1;
- if ($argumento !~ /\{$imgdir\/\}/) {
- $argumento .= "\{$imgdir/\}";
- my $cambio = "\\graphicspath{$argumento}";
- substr $preamble, $pos_inicial, $pos_final-$pos_inicial, $cambio;
- pos($preamble) = $pos_inicial + length $cambio;
- }
- }
- }
-}
-
-### Possible packages that load graphicx
-my @pkgcandidates = qw (
- rotating epsfig lyluatex xunicode parsa xepersian-hm gregoriotex teixmlslides
- teixml fotex hvfloat pgfplots grfpaste gmbase hep-paper postage schulealt
- schule utfsym cachepic abc doclicense rotating epsfig semtrans mgltex
- graphviz revquantum mpostinl cmpj cmpj2 cmpj3 chemschemex register papercdcase
- flipbook wallpaper asyprocess draftwatermark rutitlepage dccpaper-base
- nbwp-manual mandi fmp toptesi isorot pinlabel cmll graphicx-psmin ptmxcomp
- countriesofeurope iodhbwm-templates fgruler combinedgraphics pax pdfpagediff
- psfragx epsdice perfectcut upmethodology-fmt ftc-notebook tabvar vtable
- teubner pas-cv gcard table-fct pdfpages keyfloat pdfscreen showexpl simplecd
- ifmslide grffile reflectgraphics markdown bclogo tikz-page pst-uml realboxes
- musikui csbulobalka lwarp mathtools sympytex mpgraphics miniplot.sty:77
- dottex pdftricks2 feupphdteses tex4ebook axodraw2 hagenberg-thesis dlfltxb
- hu-berlin-bundle draftfigure quicktype endofproofwd euflag othelloboard
- pdftricks unswcover breqn pdfswitch latex-make figlatex repltext etsvthor
- cyber xcookybooky xfrac mercatormap chs-physics-report tikzscale ditaa
- pst-poker gmp CJKvert asypictureb hletter tikz-network powerdot-fuberlin
- skeyval gnuplottex plantslabels fancytooltips ieeepes pst-vectorian
- phfnote overpic xtuformat stubs graphbox ucs pdfwin metalogo mwe
- inline-images asymptote UNAMThesis authorarchive amscdx adjustbox
- trimclip fixmetodonotes incgraph scanpages alertmessage
- svg quiz2socrative realhats autopdf egplot decorule figsize tikzexternal
- pgfcore frontespizio textglos graphicx tikz tcolorbox
- );
-
-my $pkgcandidates = join q{|}, map { quotemeta } sort { length $a <=> length $b } @pkgcandidates;
-$pkgcandidates = qr/$pkgcandidates/x;
-my @graphicxpkg;
-
-### Now we're trying to capture graphicx package
-@graphicxpkg = $preamble =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|($pkgcandidates)/gmsx;
-
-if (@graphicxpkg and $findgraphicx ne 'false') {
- Log("Found graphicx package in preamble for $name-pdf$ext");
- $findgraphicx = 'false';
-}
-
-### Revert changes in preamble for temp <output file>
-my %tmpoutreplace = (
- 'TMPGRAPHICXTMP' => 'graphicx',
- 'TMPGRAPHICSPATHTMP' => 'graphicspath',
-);
-
-%replace = (%changes_out,%tmpoutreplace);
-$find = join q{|}, map {quotemeta} sort { length $a <=> length $b } keys %replace;
-
-### Try to capture arara:compiler in preamble of <output file>
-my @arara_engines = qw (latex pdflatex lualatex xelatex luahbtex);
-my $arara_engines = join q{|}, map { quotemeta} sort { length $a <=> length $b } @arara_engines;
-$arara_engines = qr/\b(?:$arara_engines)/x;
-my $arara_rule = qr /^(?:\%\s{1}arara[:]\s{1}) ($arara_engines) /msx;
-
-### Capture graphicx.sty in .log of LaTeX file
-if ($findgraphicx ne 'false') {
- Log("Couldn't capture the graphicx package for $name-pdf$ext in preamble");
- my $ltxlog;
- my @graphicx;
- my $null = devnull();
- # Copy preamble and revert changes
- my $preambletmp = $preamble;
- $preambletmp =~ s/($find)/$replace{$1}/g;
- $preambletmp =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
- Log("Creating $name-fig-$tmp$ext [only preamble]");
- if ($verbose) { say "Creating [$name-fig-$tmp$ext] with only preamble"; }
- open my $OUTfile, '>', "$name-fig-$tmp$ext";
- print {$OUTfile} "$preambletmp\n\\stop";
- close $OUTfile;
- # Set compiler for arara
- if ($opts_cmd{compiler}{arara}) {
- my @engine = $atbegindoc =~ m/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|$arara_rule/msx;
- my %engine = map { $_ => 1 } @engine;
- if (%engine) {
- for my $var (@arara_engines) {
- if (defined $engine{$var}) {
- Log("Found engine [$var] for arara");
- $compiler = $var;
- }
- }
- }
- else {
- Log("Not detected engine for arara, use default [pdflatex]");
- $compiler = 'pdflatex';
- }
- }
- if ($compiler eq 'latex') { $compiler = 'pdflatex'; }
- if ($compiler eq 'dvilualatex') { $compiler = 'lualatex'; }
- # Compiling file
- RUNOSCMD("$compiler $write18 -interaction=batchmode", "$name-fig-$tmp$ext >$null", 'only');
- # Restore arara compiler
- if ($arara) { $compiler = 'arara'; }
- Log("Search graphicx package in $name-fig-$tmp.log");
- open my $LaTeXlog, '<', "$name-fig-$tmp.log";
- {
- local $/;
- $ltxlog = <$LaTeXlog>;
- }
- close $LaTeXlog;
- # Try to capture graphicx
- @graphicx = $ltxlog =~ m/.+? (graphicx\.sty)/xg;
- if (@graphicx) {
- Log("Found graphicx package in $name-fig-$tmp.log");
- }
- else {
- Log("Not found graphicx package in $name-fig-$tmp.log");
- Log("Add \\usepackage\{graphicx\} to preamble of $name-pdf$ext");
- $preamble= "$preamble\\usepackage\{graphicx\}\n";
- }
-}
-
-### Add last lines
-if (!@graphicspath) {
- Log("Not found \\graphicspath in preamble for $name-pdf$ext");
- Log("Add \\graphicspath\{\{$imgdir/\}\} to preamble for $name-pdf$ext");
- $preamble= "$preamble\\graphicspath\{\{$imgdir/\}\}\n";
-}
-
-Log("Add \\usepackage\{grfext\} to preamble for $name-pdf$ext");
-$preamble = "$preamble\\usepackage\{grfext\}\n";
-Log("Add \\PrependGraphicsExtensions\*\{\.pdf\} to preamble for $name-pdf$ext");
-$preamble = "$preamble\\PrependGraphicsExtensions\*\{\.pdf\}";
-$preamble =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-
-### Create a <output file>
-my $out_file = "$preamble\n$bodydoc\n$enddoc";
-
-### Clean \psset{...} content in <output file>
-Log("Remove \\psset\{...\} in body for $name-pdf$ext");
-$out_file =~ s/\\begin\{nopreview\}\%$tmp.+?\\end\{nopreview\}\%$tmp(*SKIP)(*F)|
- \%<\*$dtxverb> .+? \%<\/$dtxverb>(*SKIP)(*F)|
- \\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))?+//gmsx;
-
-### Revert preview environments
-if (@env_preview) {
- Log("Revert \\begin{nopreview}\%TMP$tmp ... \\end{nopreview}\%TMP$tmp");
- $out_file =~ s/\\begin\{nopreview\}\%TMP$tmp
- (?<code> .+?)
- \\end\{nopreview\}\%TMP$tmp
- /\\begin\{preview\}$+{code}\\end\{preview\}/gmsx;
-}
-
-$out_file =~ s/\\begin\{nopreview\}%$tmp
- (?<code>\\begin\{PSTexample\} .+? \\end\{PSTexample\})
- \\end\{nopreview\}%$tmp
- /$+{code}/gmsx;
-
-### Remove internal mark for verbatim and verbatim write environments
-$out_file =~ s/\%<\*$dtxverb>(.+?)\%<\/$dtxverb>/$1/gmsx;
-%replace = (%changes_out,%tmpoutreplace);
-$find = join q{|}, map {quotemeta} sort { length $a <=> length $b } keys %replace;
-$out_file =~ s/($find)/$replace{$1}/g;
-
-### Write <output file>
-if (-e "$name-pdf$ext") {
- Log("Rewriting the file $name-pdf$ext in $workdir");
- Infocolor('Warning', "The file [$name-pdf$ext] already exists and will be rewritten");
-}
-else{
- Infoline("Creating the file $name-pdf$ext");
- Log("Write the file $name-pdf$ext in $workdir");
-}
-open my $OUTfile, '>', "$name-pdf$ext";
- print {$OUTfile} $out_file;
-close $OUTfile;
-
-### Set compiler for process <output file>
-$compiler = $xetex ? 'xelatex'
- : $luatex ? 'lualatex'
- : 'pdflatex'
- ;
-
-### Set options for latexmk
-my $ltxmkopt = $xetex ? "-pdfxe -silent -xelatex=\"xelatex $write18 -recorder %O %S\""
- : $luatex ? "-pdflua -silent -lualatex=\"lualatex $write18 -recorder %O %S\""
- : "-pdf -silent -pdflatex=\"pdflatex $write18 -recorder %O %S\""
- ;
-
-### Set options for compiler
-$opt_compiler = $arara ? '--log'
- : $latexmk ? "$ltxmkopt"
- : "$write18 -interaction=nonstopmode -recorder"
- ;
-
-### Set message in terminal
-$msg_compiler = $xetex ? 'xelatex'
- : $luatex ? 'lualatex'
- : 'pdflatex'
- ;
-
-### Set compiler message and compiler for arara and latexmk
-if ($arara) { $compiler = $msg_compiler = 'arara'; }
-if ($latexmk) { $compiler = $msg_compiler = 'latexmk'; }
-
-### Process <output file>
-if (!$norun) {
- Log("Compiling the file $name-pdf$ext using [$msg_compiler]");
- print "Compiling the file $name-pdf$ext using ", color('magenta'), "[$msg_compiler]\r\n",color('reset');
- RUNOSCMD("$compiler $opt_compiler", "$name-pdf$ext",'show');
- # biber
- if ($runbiber && -e "$name-pdf.bcf" && !$arara && !$latexmk) {
- RUNOSCMD("biber", "$name-pdf",'show');
- RUNOSCMD("$compiler $opt_compiler", "$name-pdf$ext",'show');
- }
- # bibtex
- if ($runbibtex && -e "$name-pdf.aux" && !$arara && !$latexmk) {
- RUNOSCMD("bibtex", "$name-pdf",'show');
- RUNOSCMD("$compiler $opt_compiler", "$name-pdf$ext",'show');
- }
-}
-
-### Remove temporary files
-my @tmpfiles;
-my @protected = qw();
-my $flsline = 'OUTPUT';
-my @flsfile;
-
-### Protect generated files
-push @protected, "$name-pdf$ext", "$name-pdf.pdf";
-
-### Find files
-find(\&aux_files, $workdir);
-sub aux_files{
- my $findtmpfiles = $_;
- if (-f $findtmpfiles && $findtmpfiles =~ m/$name-fig(-exa)?-$tmp.+?$/) { # search
- push @tmpfiles, $_;
- }
- return;
-}
-
-### Add if exists
-if (-e 'arara.log') {
- push @flsfile, 'arara.log';
-}
-if (-e "$name-fig-$tmp.fls") {
- push @flsfile, "$name-fig-$tmp.fls";
-}
-if (-e "$name-fig-exa-$tmp.fls") {
- push @flsfile, "$name-fig-exa-$tmp.fls";
-}
-if (-e "$name-pdf.fls") {
- push @flsfile, "$name-pdf.fls";
-}
-
-### Read .fls file
-for my $filename(@flsfile){
- open my $RECtmp, '<', $filename;
- push @tmpfiles, grep /^$flsline/,<$RECtmp>;
- close $RECtmp;
-}
-
-foreach (@tmpfiles) { s/^$flsline\s+|\s+$//g; }
-push @tmpfiles, @flsfile;
-
-@tmpfiles = uniq(@tmpfiles);
-@tmpfiles = array_minus(@tmpfiles, @protected);
-
-Log('The files that will be deleted are:');
-Logarray(\@tmpfiles);
-
-### Remove only if exist
-if (@tmpfiles) {
- Infoline("Remove temporary files created in $workdir");
- foreach my $tmpfiles (@tmpfiles) {
- move($tmpfiles, $tempDir);
- }
-}
-
-### Find dirs created by minted
-my @deldirs;
-my $mintdir = "\_minted\-$name-fig-$tmp";
-my $mintdirexa = "\_minted\-$name-fig-exa-$tmp";
-if (-e $mintdir) { push @deldirs, $mintdir; }
-if (-e $mintdirexa) { push @deldirs, $mintdirexa; }
-
-Log('The directory that will be deleted are:');
-Logarray(\@deldirs);
-
-### Remove only if exist
-if (@deldirs) {
- Infoline("Remove temporary directories created by minted in $workdir");
- foreach my $deldirs (@deldirs) {
- remove_tree($deldirs);
- }
-}
-
-### Compress "./images" with generated files
-my $archivetar;
-if ($zip or $tar) {
- my $stamp = strftime("%Y-%m-%d", localtime);
- $archivetar = "$imgdir-$stamp";
-
- my @savetozt;
- find(\&zip_tar, $imgdir);
- sub zip_tar{
- my $filesto = $_;
- if (-f $filesto && $filesto =~ m/$name-fig-.+?$/) { # search
- push @savetozt, $File::Find::name;
- }
- return;
- }
- Log("The files are compress found in $imgdirpath are:");
- Logarray(\@savetozt);
- if ($zip) {
- if (-e "$archivetar.zip") {
- Infocolor('Warning', "The file [$archivetar.zip] already exists and will be rewritten");
- Log("Rewriting the file $archivetar.zip in $workdir");
- }
- else{
- print "Creating the file ", color('magenta'), "[$archivetar.zip]",
- color('reset'), " with generate files in ./$imgdir\r\n";
- Log("Writen the file $archivetar.tar.gz in $workdir");
- }
- zip \@savetozt => "$archivetar.zip";
- }
- if ($tar) {
- if (-e "$archivetar.tar.gz") {
- Infocolor('Warning', "The file [$archivetar.tar.gz] already exists and will be rewritten");
- Log("Rewriting the file $archivetar.tar.gz in $workdir");
- }
- else{
- print "Creating the file ", color('magenta'), "[$archivetar.tar.gz]",
- color('reset'), " with generate files in ./$imgdir\r\n";
- Log("Writen the file $archivetar.tar.gz in $workdir");
- }
- my $imgdirtar = Archive::Tar->new();
- $imgdirtar->add_files(@savetozt);
- $imgdirtar->write( "$archivetar.tar.gz" , 9 );
- }
-}
-
-### End of script process
-if (!$norun && !$nosource) {
- Log("The image files: $format and generated files are in $imgdirpath");
-}
-if (!$norun && $nosource) {
- Log("The image files: $format are in $imgdirpath");
-}
-if ($norun && !$nosource) {
- Log("The generated files are in $imgdirpath");
-}
-Log("The output file $name-pdf$ext are in $workdir");
-
-Infocolor('Finish', "The execution of $scriptname has been successfully completed");
-
-Log("The execution of $scriptname has been successfully completed");
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-sys.sh b/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-sys.sh
deleted file mode 100755
index 4d0944572a1..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-sys.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-# kanji-config-updmap-sys:
-# copy of fmtutil-sys by Thomas Esser, public domain.
-
-# wrapper script for updmap-setup-kanji with TEXMFVAR and TEXMFCONFIG set to
-# TEXMFSYSVAR / TEXMFSYSCONFIG
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-export PATH
-
-exec kanji-config-updmap --sys ${1+"$@"}
-
diff --git a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-user.sh b/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-user.sh
deleted file mode 100755
index 8426f66e57f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap-user.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-# kanji-config-updmap-user:
-# copy of fmtutil-sys by Thomas Esser, public domain.
-
-# wrapper script for updmap-setup-kanji with TEXMFVAR and TEXMFCONFIG set to
-# TEXMFVAR / TEXMFCONFIG
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-export PATH
-
-exec kanji-config-updmap --user ${1+"$@"}
-
diff --git a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap.pl b/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap.pl
deleted file mode 100755
index eee71cf2bba..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-config-updmap.pl
+++ /dev/null
@@ -1,583 +0,0 @@
-#!/usr/bin/env perl
-# kanji-config-updmap: setup Japanese font embedding
-# Version 20201227.0
-#
-# formerly known as updmap-setup-kanji
-#
-# Copyright 2004-2006 by KOBAYASHI R. Taizo for the shell version (updmap-otf)
-# Copyright 2011-2020 by PREINING Norbert
-# Copyright 2016-2020 by Japanese TeX Development Community
-#
-# This file is licensed under GPL version 3 or any later version.
-# For copyright statements see end of file.
-#
-# For development see
-# https://github.com/texjporg/ptex-fontmaps
-#
-# For a changelog see the git log
-#
-
-$^W = 1;
-use Getopt::Long qw(:config no_autoabbrev ignore_case_always);
-use strict;
-
-my $prg = "kanji-config-updmap";
-my $version = '20201227.0';
-
-my $updmap_real = "updmap";
-my $updmap = $updmap_real;
-
-my $dry_run = 0;
-my $opt_help = 0;
-my $opt_jis = 0;
-my $opt_sys = 0;
-my $opt_user = 0;
-my $opt_old = 0;
-my $opt_force = 0;
-my @opt_mode_list;
-my $opt_mode_one;
-my $opt_mode_ja;
-my $opt_mode_sc;
-my $opt_mode_tc;
-my $opt_mode_ko;
-
-if (! GetOptions(
- "n|dry-run" => \$dry_run,
- "h|help" => \$opt_help,
- "jis2004" => \$opt_jis,
- "mode=s" => \$opt_mode_one,
- "ja=s" => \$opt_mode_ja,
- "sc=s" => \$opt_mode_sc,
- "tc=s" => \$opt_mode_tc,
- "ko=s" => \$opt_mode_ko,
- "sys" => \$opt_sys,
- "user" => \$opt_user,
- "old" => \$opt_old,
- "force" => \$opt_force,
- "version" => sub { print &version(); exit(0); }, ) ) {
- die "Try \"$0 --help\" for more information.\n";
-}
-
-if ($opt_mode_one) {
- if (defined($opt_mode_ja) || defined($opt_mode_sc) ||
- defined($opt_mode_tc) || defined($opt_mode_ko)) {
- die "Options --ja/--sc/--tc/--ko are invalid with --mode=NN!\n";
- }
- # define a corresponding option by empty string
- if ($opt_mode_one eq "ja") {
- $opt_mode_ja = '';
- } elsif ($opt_mode_one eq "sc") {
- $opt_mode_sc = '';
- } elsif ($opt_mode_one eq "tc") {
- $opt_mode_tc = '';
- } elsif ($opt_mode_one eq "ko") {
- $opt_mode_ko = '';
- } else {
- die "Unknown mode $opt_mode_one!";
- }
-}
-push @opt_mode_list, "ja" if (defined($opt_mode_ja));
-push @opt_mode_list, "sc" if (defined($opt_mode_sc));
-push @opt_mode_list, "tc" if (defined($opt_mode_tc));
-push @opt_mode_list, "ko" if (defined($opt_mode_ko));
-if (!@opt_mode_list) {
- # default mode needs to be set, define it by empty string
- $opt_mode_one = "ja";
- $opt_mode_ja = '';
- push @opt_mode_list, "ja";
-}
-
-sub win32 { return ($^O=~/^MSWin(32|64)$/i); }
-my $nul = (win32() ? 'nul' : '/dev/null') ;
-
-if (defined($ARGV[0]) && $ARGV[0] ne "status") {
- if (!($opt_user || $opt_sys)) {
- die "Either -user or -sys mode is required.";
- }
-}
-
-if ($opt_user && $opt_sys) {
- die "Only one of -user and -sys can be used!";
-}
-
-if ($opt_sys) {
- $updmap = "$updmap --sys" ;
- $updmap_real = "$updmap_real --sys" ;
-} else {
- # TeX Live 2017 requires --user option
- # try to determine the version of updmap installed
- my $updver = `updmap --version 2>&1`;
- if ($updver =~ m/^updmap version r([0-9]*) /) {
- if ($1 >= 44080) {
- $updmap = "$updmap --user" ;
- $updmap_real = "$updmap_real --user" ;
- } # else nothing to do, already set up for old updmap
- } else {
- # not recognized updmap -> assume new updmap unless --old
- if (!$opt_old) {
- $updmap = "$updmap --user" ;
- $updmap_real = "$updmap_real --user" ;
- }
- }
-}
-if ($dry_run) {
- $updmap = "echo updmap";
-}
-
-if ($opt_help) {
- Usage();
- exit(0);
-}
-
-#
-# representatives of support font families
-#
-my %representatives;
-my %ai0flags;
-my @databaselist = "ptex-fontmaps-data.dat";
-push @databaselist, "ptex-fontmaps-macos-data.dat" if (macosx_new());
-
-
-main(@ARGV);
-
-sub macosx { return ($^O=~/^darwin$/i); }
-
-sub macosx_new {
- if (macosx()) {
- my $macos_ver = `sw_vers -productVersion`;
- my $macos_ver_major = $macos_ver;
- $macos_ver_major =~ s/^(\d+)\.(\d+).*/$1/;
- my $macos_ver_minor = $macos_ver;
- $macos_ver_minor =~ s/^(\d+)\.(\d+).*/$2/;
- if ($macos_ver_major==10) {
- if ($macos_ver_minor>=11) {
- return 1;
- }
- }
- }
- return 0;
-}
-
-sub version {
- my $ret = sprintf "%s version %s\n", $prg, $version;
- return $ret;
-}
-
-sub Usage {
- my $usage = <<"EOF";
- $prg $version
- Set up embedding of Japanese/Chinese/Korean fonts via updmap.cfg.
-
- This script searches for some of the most common fonts
- for embedding into pdfs by dvipdfmx.
-
- In addition it allows to set up arbitrary font families
- to be embedded into the generated pdf files, as long
- as at least the representative map file is present.
- Other map files will be used if available:
-
- For Japanese:
- ptex-<family>.map (representative map file)
- uptex-<family>.map
- otf-<family>.map
- otf-up-<family>.map
-
- For Simplified Chinese, Traditional Chinese and Korean:
- uptex-<NN>-<family>.map (representative map file)
- otf-<NN>-<family>.map
- (NN being: sc, tc, ko)
-
- Please see the documentation of updmap for details (updmap --help).
-
- Usage: $prg [OPTION] {<fontname>|auto|nofont|status}
-
- <family> Embed an arbitrary font family <family>, at least
- the representative map file has to be available.
- auto: If the current status is noEmbed or unknown, try to embed
- one of the supported font families automatically.
- If none of them is available, fall back to nofont
- nofont: Embed no fonts (and rely on system fonts when displaying pdfs).
- If your system does not have any of the supported font
- families, this target is selected automatically.
- status: Get information about current environment and usable font maps.
-
- Options:
- -n, --dry-run Do not actually run updmap
- -h, --help Show this message and exit
- --mode=NN Setup for Japanese (NN=ja), Korean (NN=ko),
- Simplified Chinese (NN=sc), Traditional Chinese (NN=tc)
- --NN Shorthand for --mode=NN
- --jis2004 Use JIS2004 variants for default fonts of (u)pTeX
- --sys Run in sys mode, i.e., call updmap -sys
- --user Run in user mode, i.e., call updmap -user or updmap,
- by checking the version of the updmap script.
- If a non-parsable output of `updmap --version' is found,
- a new updmap with --user option is assumed.
- If this is not the case, explicitly use --old.
- --old Makes $prg call `updmap' without --user argument in user mode.
- --force Set up font embedding even if the font is not available.
- --version Show version information and exit
-
-EOF
-;
- print $usage;
- exit(0);
-}
-
-
-
-###
-### Collect Database Lines
-###
-
-sub InitDatabase {
- %representatives = ();
- %ai0flags = ();
-}
-
-sub ReadDatabase {
- my @curdbl;
- # open database
- for my $f (@databaselist) {
- my $foo = kpse_miscfont($f);
- if (!open(FDB, "<$foo")) {
- printf STDERR "Cannot find $f, skipping!\n";
- next;
- }
- @curdbl = <FDB>;
- close(FDB);
- # parse lines
- my $lineno = 0;
- chomp(@curdbl);
- push @curdbl, ""; # add a "final empty line" to easy parsing
- for my $l (@curdbl) {
- $lineno++;
- next if ($l =~ m/^\s*$/); # skip empty line
- next if ($l =~ m/^\s*#/); # skip comment line
- $l =~ s/\s*#.*$//; # skip comment after '#'
- if ($l =~ m/^JA\*\((\d+)\):\s*(.*):\s*(.*)$/) { # no -04 map
- $representatives{'ja'}{$2}{'priority'} = $1;
- $representatives{'ja'}{$2}{'file'} = $3;
- $representatives{'ja'}{$2}{'nojis04'} = 1;
- next;
- }
- if ($l =~ m/^JA\((\d+)\):\s*(.*):\s*(.*)$/) {
- $representatives{'ja'}{$2}{'priority'} = $1;
- $representatives{'ja'}{$2}{'file'} = $3;
- next;
- }
- if ($l =~ m/^SC\((\d+)\):\s*(.*):\s*(.*)$/) {
- $representatives{'sc'}{$2}{'priority'} = $1;
- $representatives{'sc'}{$2}{'file'} = $3;
- next;
- }
- if ($l =~ m/^TC\((\d+)\):\s*(.*):\s*(.*)$/) {
- $representatives{'tc'}{$2}{'priority'} = $1;
- $representatives{'tc'}{$2}{'file'} = $3;
- next;
- }
- if ($l =~ m/^KO\((\d+)\):\s*(.*):\s*(.*)$/) {
- $representatives{'ko'}{$2}{'priority'} = $1;
- $representatives{'ko'}{$2}{'file'} = $3;
- next;
- }
- if ($l =~ m/^JA-AI0\*:\s*(.*):\s*(.*)$/) { # no -04 map
- $representatives{'ja'}{$1}{'priority'} = 9999; # lowest
- $representatives{'ja'}{$1}{'file'} = $2;
- $representatives{'ja'}{$1}{'nojis04'} = 1;
- $ai0flags{'ja'}{$1} = 1;
- next;
- }
- if ($l =~ m/^JA-AI0:\s*(.*):\s*(.*)$/) {
- $representatives{'ja'}{$1}{'priority'} = 9999; # lowest
- $representatives{'ja'}{$1}{'file'} = $2;
- $ai0flags{'ja'}{$1} = 1;
- next;
- }
- if ($l =~ m/^SC-AI0:\s*(.*):\s*(.*)$/) {
- $representatives{'sc'}{$1}{'priority'} = 9999; # lowest
- $representatives{'sc'}{$1}{'file'} = $2;
- $ai0flags{'sc'}{$1} = 1;
- next;
- }
- if ($l =~ m/^TC-AI0:\s*(.*):\s*(.*)$/) {
- $representatives{'tc'}{$1}{'priority'} = 9999; # lowest
- $representatives{'tc'}{$1}{'file'} = $2;
- $ai0flags{'tc'}{$1} = 1;
- next;
- }
- if ($l =~ m/^KO-AI0:\s*(.*):\s*(.*)$/) {
- $representatives{'ko'}{$1}{'priority'} = 9999; # lowest
- $representatives{'ko'}{$1}{'file'} = $2;
- $ai0flags{'ko'}{$1} = 1;
- next;
- }
- # we are still here??
- die "Cannot parse \"$foo\" at line $lineno,
- exiting. Strange line: >>>$l<<<\n";
- }
- }
- if (!%representatives) {
- die "Candidate list is empty, cannot proceed!\n";
- }
-}
-
-sub kpse_miscfont {
- my ($file) = @_;
- my $foo = '';
- # first, prioritize GitHub repository diretory structure
- $foo = "database/$file" if (-f "database/$file");
- if ($foo eq "") {
- chomp($foo = `kpsewhich -format=miscfont $file`);
- }
- return $foo;
-}
-
-###
-### Check Installed Font
-###
-
-sub CheckInstallFont {
- for my $opt_mode (@opt_mode_list) {
- for my $k (keys %{$representatives{$opt_mode}}) {
- my $f = `kpsewhich $representatives{$opt_mode}{$k}{'file'}`;
- if ($?) {
- $representatives{$opt_mode}{$k}{'available'} = "";
- } else {
- $representatives{$opt_mode}{$k}{'available'} = chomp($f);
- }
- }
- }
-}
-
-###
-### GetStatus
-###
-
-sub check_mapfile {
- my $mapf = shift;
- my $f = `kpsewhich $mapf 2> $nul`;
- my $ret = $?;
- if (wantarray) {
- return (!$ret, $f);
- } else {
- return (!$ret);
- }
-}
-
-sub gen_mapfile {
- my $opt_mode = shift;
- my $map_base = shift;
- # returns a representative map file name
- # ptex-${map_base}.map also exists for Japanese AI0 fonts,
- # but it is a stub so we use uptex-${map_base}.map instead
- return ($opt_mode eq "ja" ?
- ($ai0flags{$opt_mode}{$map_base} ?
- "uptex-${map_base}.map" :
- "ptex-${map_base}.map") :
- "uptex-${opt_mode}-${map_base}.map");
-}
-
-sub GetStatus {
- my $opt_mode = shift;
- my $val;
- my $STATUS = "";
- my $VARIANT = "";
-
- # fetch jaEmbed/scEmbed/tcEmbed/koEmbed
- $val = `$updmap_real --quiet --showoption ${opt_mode}Embed`;
- if ($val =~ m/^${opt_mode}Embed=([^()\s]*)(\s+\()?/) {
- $STATUS = $1;
- } else {
- die "Cannot find status of current ${opt_mode}Embed setting via updmap --showoption!\n";
- }
- # fetch jaVariant
- if ($opt_mode eq "ja") {
- $val = `$updmap_real --quiet --showoption ${opt_mode}Variant`;
- if ($val =~ m/^${opt_mode}Variant=([^()\s]*)(\s+\()?/) {
- $VARIANT = $1; # should be '' or '-04'
- } else {
- die "Cannot find status of current ${opt_mode}Variant setting via updmap --showoption!\n";
- }
- }
-
- my $testmap = gen_mapfile($opt_mode, "$STATUS$VARIANT");
- $VARIANT = "<empty>" if ($VARIANT eq ""); # for printing
- if (check_mapfile($testmap)) {
- print "CURRENT family for $opt_mode: $STATUS";
- print " (variant: $VARIANT)" if ($opt_mode eq "ja");
- print " (AI0)" if ($ai0flags{$opt_mode}{$STATUS});
- print "\n";
- } else {
- print STDERR "WARNING: Currently selected map file for $opt_mode cannot be found: $testmap\n";
- }
-
- for my $k (sort keys %{$representatives{$opt_mode}}) {
- my $MAPFILE = gen_mapfile($opt_mode, $k);
- next if ($MAPFILE eq $testmap);
- if (check_mapfile($MAPFILE)) {
- if ($representatives{$opt_mode}{$k}{'available'}) {
- print "Standby family : $k";
- print " (AI0)" if ($ai0flags{$opt_mode}{$k});
- print "\n";
- }
- }
- }
- return $STATUS;
-}
-
-###
-### Setup Map files
-###
-
-sub SetupMapFile {
- my $opt_mode = shift;
- my $rep = shift;
- my $MAPFILE = gen_mapfile($opt_mode, $rep);
- if (check_mapfile($MAPFILE)) {
- print "Setting up ... $rep";
- print " (AI0)" if ($ai0flags{$opt_mode}{$rep});
- print " for $opt_mode\n";
- system("$updmap --quiet --nomkmap --nohash --setoption ${opt_mode}Embed $rep");
- if ($opt_mode eq "ja") {
- if ($opt_jis && $representatives{'ja'}{$rep}{'nojis04'}) {
- print STDERR "WARNING: No -04 map available, option --jis2004 ignored!\n";
- $opt_jis = 0;
- }
- if ($opt_jis) {
- system("$updmap --quiet --nomkmap --nohash --setoption jaVariant -04");
- } else {
- system("$updmap --quiet --nomkmap --nohash --setoption jaVariant \"\"");
- }
- }
- } else {
- die "NOT EXIST $MAPFILE\n";
- }
-}
-
-sub SetupReplacement {
- my $opt_mode = shift;
- my $rep = shift;
- if (defined($representatives{$opt_mode}{$rep})) {
- if ($representatives{$opt_mode}{$rep}{'available'} || $opt_force) {
- return SetupMapFile($opt_mode, $rep);
- } else {
- printf STDERR "$rep not available, falling back to auto!\n";
- return SetupReplacement($opt_mode, "auto");
- }
- } else {
- if ($rep eq "nofont") {
- return SetupMapFile($opt_mode, "noEmbed");
- } elsif ($rep eq "auto") {
- my $STATUS = GetStatus($opt_mode);
- # first check if we have a status set and the font is installed
- # in this case don't change anything, just make sure
- if (defined($representatives{$opt_mode}{$STATUS}) &&
- $representatives{$opt_mode}{$STATUS}{'available'}) {
- return SetupMapFile($opt_mode, $STATUS);
- } else {
- if (!($STATUS eq "noEmbed" || $STATUS eq "")) {
- # some unknown setting is set up currently, overwrite, but warn
- print STDERR "Previous setting $STATUS for $opt_mode is unknown, replacing it!\n"
- }
- # if we are in the noEmbed or nothing set case,
- # and if one of the supported fonts are present, then use them
- for my $i (sort { $representatives{$opt_mode}{$a}{'priority'}
- <=>
- $representatives{$opt_mode}{$b}{'priority'} }
- keys %{$representatives{$opt_mode}}) {
- if ($representatives{$opt_mode}{$i}{'available'}) {
- return SetupMapFile($opt_mode, $i);
- }
- }
- # still here, no map file found!
- return SetupMapFile($opt_mode, "noEmbed");
- }
- } else {
- # anything else is treated as a map file name
- return SetupMapFile($opt_mode, $rep);
- }
- }
-}
-
-###
-### MAIN
-###
-
-sub main {
- # Number of arguments allowed:
- # 0: should be only --NN=<family> lists ('=' can be omitted)
- # 1: treated as [--mode=NN] <family> ('=' can be omitted)
- # 2 or more: I can't handle!
- my ($a, $b) = @_;
- if (defined($b)) {
- die "Number of the arguments should be at most one!\n";
- }
- if ($a) {
- die "Strange argument found! >>>$a<<<\n" if (!$opt_mode_one);
- # argument is passed to defined-but-empty language mode
- if (defined($opt_mode_ja) && !$opt_mode_ja) {
- $opt_mode_ja = $a;
- } elsif (defined($opt_mode_sc) && !$opt_mode_sc) {
- $opt_mode_sc = $a;
- } elsif (defined($opt_mode_tc) && !$opt_mode_tc) {
- $opt_mode_tc = $a;
- } elsif (defined($opt_mode_ko) && !$opt_mode_ko) {
- $opt_mode_ko = $a;
- }
- } else {
- die "No family or operation is specified for $opt_mode_one!\n",
- "Try \"$0 --help\" for more information.\n" if ($opt_mode_one);
- }
-
- InitDatabase();
- ReadDatabase();
- CheckInstallFont();
-
- # if one of <family> arguments is "status", then
- # all arguments are forced into "status"
- if (($opt_mode_ja && ($opt_mode_ja eq "status")) ||
- ($opt_mode_sc && ($opt_mode_sc eq "status")) ||
- ($opt_mode_tc && ($opt_mode_tc eq "status")) ||
- ($opt_mode_ko && ($opt_mode_ko eq "status"))) {
- GetStatus("ja") if ($opt_mode_ja);
- GetStatus("sc") if ($opt_mode_sc);
- GetStatus("tc") if ($opt_mode_tc);
- GetStatus("ko") if ($opt_mode_ko);
- } else {
- SetupReplacement("ja", $opt_mode_ja) if ($opt_mode_ja);
- SetupReplacement("sc", $opt_mode_sc) if ($opt_mode_sc);
- SetupReplacement("tc", $opt_mode_tc) if ($opt_mode_tc);
- SetupReplacement("ko", $opt_mode_ko) if ($opt_mode_ko);
- system("$updmap");
- }
-}
-
-#
-#
-# Copyright statements:
-#
-# KOBAYASHI Taizo
-# email to preining@logic.at
-# Message-Id: <20120130.162953.59640143170594580.tkoba@cc.kyushu-u.ac.jp>
-# Message-Id: <20120201.105639.625859878546968959.tkoba@cc.kyushu-u.ac.jp>
-# --------------------------------------------------------
-# copyright statement ăŻç°ˇĺŤă«ä»Ąä¸‹ă§çµć§‹ă§ă™ă€‚
-#
-# Copyright 2004-2006 by KOBAYASHI Taizo
-#
-# ă§ăŻ
-# GPL version 3 or any later version
-#
-# --------------------------------------------------------
-#
-# PREINING Norbert
-# as author and maintainer of the current file
-# Licensed under GPL version 3 or any later version
-#
-### Local Variables:
-### perl-indent-level: 2
-### tab-width: 2
-### indent-tabs-mode: nil
-### End:
-# vim: set tabstop=2 expandtab autoindent:
diff --git a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-fontmap-creator.pl b/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-fontmap-creator.pl
deleted file mode 100755
index bfad277bc51..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ptex-fontmaps/kanji-fontmap-creator.pl
+++ /dev/null
@@ -1,590 +0,0 @@
-#!/usr/bin/env perl
-#
-# kanji-fontmap-creator
-# (c) 2012-2014 Norbert Preining
-# Version: 20201227.0
-# Licenced under the GPLv2 or any higher version
-#
-# gui to create map files for (kanji-config-)updmap
-#
-# ptex/uptex:
-# 2 fonts (rml/gbm)
-# 2 variants
-# (ev vertical/horizontal)
-#
-# otf/otf-up:
-#
-# 2 variants
-# fonts:
-# gothic: regular, bold, heavy, maru
-# mincho: regular, bold, light
-#
-# possible improvements:
-# - allow editing current files by reading and interpreting them
-# needs better structure of the data
-# - specify output directory, automatically write to $TEXMFLOCAL ?
-# - more checks, warnings?
-#
-
-$^W = 1;
-use strict;
-
-use Tk;
-use Tk::NoteBook;
-use Tk::Dialog;
-use Cwd;
-use Getopt::Long qw(:config no_autoabbrev);
-use Pod::Usage;
-
-my $opt_lang = "en";
-my $opt_help = 0;
-my $opt_version = 0;
-
-my $prg = "kanji-fontmap-creator";
-my $version = "20201227.0";
-
-#
-# global vars configuring operation
-my $group_name = "";
-my $do_vertical = 0;
-my $do_iso2004 = 0;
-my $do_otf = 0;
-my @f_mincho_regular; my @f_gothic_regular;
-my @f_mincho_bold; my @f_gothic_bold;
-my @f_gothic_heavy;
-my @f_gothic_maru;
-my @f_mincho_light;
-my $b_save;
-
-my $iso_i = 1;
-my $vert_i = 2;
-my $isovert_i = 3;
-my @order;
-
-my $mw;
-
-$order[0] = 'Default';
-$order[$iso_i] = 'ISO2004';
-$order[$vert_i] = 'Vertical';
-$order[$isovert_i] = 'ISO2004/Vertical';
-
-
-GetOptions(
- "lang=s" => \$opt_lang,
- "version" => \$opt_version,
- "help|?|h" => \$opt_help) or pod2usage(1);
-
-if (win32()) {
- pod2usage(-exitstatus => 0,
- -verbose => 2,
- -noperldoc => 1,
- -output => \*STDOUT) if $opt_help;
-} else {
- pod2usage(-exitstatus => 0, -verbose => 2, -file => $0) if $opt_help;
-}
-
-if ($opt_version) {
- print "$prg $version\n";
- exit 0;
-}
-
-if ($opt_lang ne "en") {
- print STDERR "$prg: languages other than en currently not implemented.\n";
-}
-
-&main();
-
-sub main {
- #
- #
- $mw = MainWindow->new;
- $mw->title("Kanji Fontmap Creator");
- $mw->optionAdd("*Button.Relief", "ridge", 20);
- my $tf = $mw->Frame;
- my $nb = $mw->NoteBook;
- my $bf = $mw->Frame;
- #
- # top frame
- #
- my $name_label = $tf->Label(-text => "Group name:");
- my $name_entry = $tf->Entry(-width => 30, -textvariable => \$group_name,
- -validate => "all", -validatecommand => \&validate_group_name);
- my $opt_label = $tf->Label(-text => "Options:");
- my $opt_vert = $tf->Checkbutton(-text => "separate vertical fonts",
- -variable => \$do_vertical);
- my $opt_iso = $tf->Checkbutton(-text => "separate ISO 2004 support",
- -variable => \$do_iso2004 );
- my $opt_otf = $tf->Checkbutton(-text => "OTF support",
- -variable => \$do_otf);
- #
- # pack the stuff
- $name_label->grid(-row => 0, -column => 0, -sticky => "e");
- $name_entry->grid(-row => 0, -column => 1, -sticky => "w");
- $opt_label->grid(-row => 1, -column => 0, -sticky => "e");
- $opt_otf->grid(-row => 1, -column => 1, -sticky => "w");
- $opt_iso->grid(-column => 1, -sticky => "w");
- $opt_vert->grid(-column => 1, -sticky => "w");
- #
- # notebook part
- my @p;
- for my $i (0..$#order) {
- $p[$i] = $nb->add($order[$i], -label => $order[$i],
- -state => ($i > 0 ? "disabled" : "normal"));
- }
- #
- # pack outer window
- $tf->pack(-expand => 1, -fill => 'x', -padx => '4m', -pady => '4m');
- $nb->pack(-expand => 1, -fill => 'both', -padx => '4m');
- $bf->pack(-expand => 1, -fill => 'x', -padx => '4m', -pady => '4m');
- #
- #
- my @l_mincho; my @l_gothic;
- my @l_regular;
- my @l_bold;
- my @l_heavy;
- my @l_light;
- my @l_maru;
- my @e_mincho_regular; my @e_gothic_regular;
- my @e_mincho_bold; my @e_gothic_bold;
- my @e_gothic_heavy;
- my @e_gothic_maru;
- my @e_mincho_light;
- my $ew = 20;
- for my $i (0..$#order) {
- $l_mincho[$i] = $p[$i]->Label(-text => "Mincho");
- $l_gothic[$i] = $p[$i]->Label(-text => "Gothic");
- #
- $l_regular[$i] = $p[$i]->Label(-text => "Regular");
- $e_mincho_regular[$i] = $p[$i]->Entry(-width => $ew,
- -textvariable => \$f_mincho_regular[$i]);
- $e_gothic_regular[$i] = $p[$i]->Entry(-width => $ew,
- -textvariable => \$f_gothic_regular[$i]);
- #
- $l_bold[$i] = $p[$i]->Label(-text => "Bold", -state => "disabled");
- $e_mincho_bold[$i] = $p[$i]->Entry(-width => $ew,
- -textvariable => \$f_mincho_bold[$i],
- -state => "disabled", -relief => "flat");
- $e_gothic_bold[$i] = $p[$i]->Entry(-width => $ew,
- -textvariable => \$f_gothic_bold[$i],
- -state => "disabled", -relief => "flat");
- #
- $l_heavy[$i] = $p[$i]->Label(-text => "Heavy", -state => "disabled");
- $l_light[$i] = $p[$i]->Label(-text => "Light", -state => "disabled");
- $l_maru[$i] = $p[$i]->Label(-text => "Maru", -state => "disabled");
- $e_gothic_heavy[$i] = $p[$i]->Entry(-width => $ew,
- -textvariable => \$f_gothic_heavy[$i],
- -state => "disabled", -relief => "flat");
- $e_gothic_maru[$i] = $p[$i]->Entry(-width => $ew,
- -textvariable => \$f_gothic_maru[$i],
- -state => "disabled", -relief => "flat");
- $e_mincho_light[$i] = $p[$i]->Entry(-width => $ew,
- -textvariable => \$f_mincho_light[$i],
- -state => "disabled", -relief => "flat");
- #
- # grid the whole stuff
- $l_mincho[$i]->grid(-row => 0, -column => 1);
- $l_gothic[$i]->grid(-row => 0, -column => 2);
- #
- $l_regular[$i]->grid(-row => 1, -column => 0, -sticky => "e");
- $e_mincho_regular[$i]->grid(-row => 1, -column => 1);
- $e_gothic_regular[$i]->grid(-row => 1, -column => 2);
- #
- $l_bold[$i]->grid(-row => 3, -column => 0, -sticky => "e");
- $e_mincho_bold[$i]->grid(-row => 3, -column => 1);
- $e_gothic_bold[$i]->grid(-row => 3, -column => 2);
- #
- $l_heavy[$i]->grid(-row => 4, -column => 0, -sticky => "e");
- $e_gothic_heavy[$i]->grid(-row => 4, -column => 1);
- $l_maru[$i]->grid(-row => 5, -column => 0, -sticky => "e");
- $e_gothic_maru[$i]->grid(-row => 5, -column => 2);
- $l_light[$i]->grid(-row => 6, -column => 0, -sticky => "e");
- $e_mincho_light[$i]->grid(-row => 6, -column => 2);
- }
- #
- # Button frame
- $b_save = $bf->Button(-text => "Save");
-
- #
- # Actions:
- #
- # activate tabs when options are selected
- $opt_vert->configure(-command => sub {
- if (!$do_vertical && ($nb->raised() =~ m/Vertical/)) {
- $nb->raise("Default");
- }
- $nb->pageconfigure("Vertical",
- -state => ($do_vertical ? "normal" : "disabled"));
- $nb->pageconfigure("ISO2004/Vertical",
- -state => (($do_vertical & $do_iso2004) ? "normal" : "disabled"))
- });
- $opt_iso->configure(-command => sub {
- if (!$do_iso2004 && ($nb->raised() =~ m/ISO2004/)) {
- $nb->raise("Default");
- }
- $nb->pageconfigure("ISO2004",
- -state => ($do_iso2004 ? "normal" : "disabled"));
- $nb->pageconfigure("ISO2004/Vertical",
- -state => (($do_vertical & $do_iso2004) ? "normal" : "disabled"))
- });
-
- # activate lower part for when otf is selected
- $opt_otf->configure(-command => sub {
- for my $i (0..$#order) {
- $l_light[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"));
- $e_mincho_light[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"),
- -relief => ($do_otf ? "sunken" : "flat"));
- #
- $l_bold[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"));
- $e_mincho_bold[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"),
- -relief => ($do_otf ? "sunken" : "flat"));
- $e_gothic_bold[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"),
- -relief => ($do_otf ? "sunken" : "flat"));
- #
- $l_heavy[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"));
- $l_maru[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"));
- $e_gothic_maru[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"),
- -relief => ($do_otf ? "sunken" : "flat"));
- $e_gothic_heavy[$i]->configure(
- -state => ($do_otf ? "normal" : "disabled"),
- -relief => ($do_otf ? "sunken" : "flat"));
- }
- });
- #
- #
- $b_save->configure(-command => \&export_font_maps, -state => "disabled");
- $b_save->pack;
-
- Tk::MainLoop();
-}
-
-sub validate_group_name {
- my ($new_val, undef, $old_val) = @_;
- $b_save->configure(-state => ($new_val eq "" ? "disabled" : "normal"));
- return 1;
-}
-
-sub addgroup {
- my ($str, $fref, $i_a, $i_b, @entries) = @_;
- my $do = 1;
- while (@entries) {
- my $tfm = shift @entries;
- my $enc = shift @entries;
- addlines($str, $tfm, $enc, ($do ? $fref->[$i_a] : $fref->[$i_b]));
- $do = !$do;
- }
-}
-
-sub addlines {
- my ($strref, @entries) = @_;
- while (@entries) {
- my $tfm = shift @entries;
- my $enc = shift @entries;
- my $fn = shift @entries;
- if (defined($fn)) {
- $$strref .= "$tfm $enc $fn\n";
- } else {
- print STDERR "target file for $tfm $enc not defined!\n";
- }
- }
-}
-
-sub export_font_maps {
- if ($group_name eq "") {
- print STDERR "That should not happen!\n";
- exit 1;
- }
-
- # indirections
- my $ii = ($do_iso2004 ? $iso_i : 0);
- my $vi = ($do_vertical ? $vert_i : 0);
- my $ivi = (($do_vertical && $do_vertical) ? $isovert_i : 0);
- #
-
- my ($ptexlines, $ptex04lines, $uptexlines, $uptex04lines);
- my ($otflines, $otfuplines);
- addlines(\$ptexlines,
- 'rml', 'H', $f_mincho_regular[0],
- 'rmlv','V', $f_mincho_regular[$vi],
- 'gbm', 'H', $f_gothic_regular[0],
- 'gbmv','V', $f_gothic_regular[$vi]);
- addlines(\$ptex04lines,
- 'rml', 'H', $f_mincho_regular[$ii],
- 'rmlv','V', $f_mincho_regular[$ivi],
- 'gbm', 'H', $f_gothic_regular[$ii],
- 'gbmv','V', $f_gothic_regular[$ivi]);
- addlines(\$uptexlines,
- 'urml', 'UniJIS-UTF16-H', $f_mincho_regular[0],
- 'urmlv', 'UniJIS-UTF16-V', $f_mincho_regular[$vi],
- 'ugbm', 'UniJIS-UTF16-H', $f_gothic_regular[0],
- 'ugbmv', 'UniJIS-UTF16-V', $f_gothic_regular[$vi],
- 'uprml-h', 'UniJIS-UTF16-H', $f_mincho_regular[0],
- 'uprml-v', 'UniJIS-UTF16-V', $f_mincho_regular[$vi],
- 'upgbm-h', 'UniJIS-UTF16-H', $f_gothic_regular[0],
- 'upgbm-v', 'UniJIS-UTF16-V', $f_gothic_regular[$vi],
- 'uprml-hq', 'UniJIS-UCS2-H', $f_mincho_regular[0],
- 'upgbm-hq', 'UniJIS-UCS2-H', $f_gothic_regular[0]);
- addlines(\$uptex04lines,
- 'urml', 'UniJIS-UTF16-H', $f_mincho_regular[$ii],
- 'urmlv', 'UniJIS-UTF16-V', $f_mincho_regular[$ivi],
- 'ugbm', 'UniJIS-UTF16-H', $f_gothic_regular[$ii],
- 'ugbmv', 'UniJIS-UTF16-V', $f_gothic_regular[$ivi],
- 'uprml-h', 'UniJIS-UTF16-H', $f_mincho_regular[$ii],
- 'uprml-v', 'UniJIS-UTF16-V', $f_mincho_regular[$ivi],
- 'upgbm-h', 'UniJIS-UTF16-H', $f_gothic_regular[$ii],
- 'upgbm-v', 'UniJIS-UTF16-V', $f_gothic_regular[$ivi],
- 'uprml-hq', 'UniJIS-UCS2-H', $f_mincho_regular[$ii],
- 'upgbm-hq', 'UniJIS-UCS2-H', $f_gothic_regular[$ii]);
-
-
- addlines(\$otflines,
- '%', 'mincho regular', '',
- 'otf-ujmr-h', 'UniJIS-UTF16-H', $f_mincho_regular[0],
- 'otf-ujmr-v', 'UniJIS-UTF16-V', $f_mincho_regular[$vi],
- 'otf-cjmr-h', 'Identity-H', $f_mincho_regular[0],
- 'otf-cjmr-v', 'Identity-V', $f_mincho_regular[$vi],
- 'hminr-h', 'H', $f_mincho_regular[0],
- 'hminr-v', 'V', $f_mincho_regular[$vi],
- '%', 'gothic regular', '',
- 'otf-ujgr-h', 'UniJIS-UTF16-H', $f_gothic_regular[0],
- 'otf-ujgr-v', 'UniJIS-UTF16-V', $f_gothic_regular[$vi],
- 'otf-cjgr-h', 'Identity-H', $f_gothic_regular[0],
- 'otf-cjgr-v', 'Identity-V', $f_gothic_regular[$vi],
- 'hgothr-h', 'H', $f_gothic_regular[0],
- 'hgothr-v', 'V', $f_gothic_regular[$vi],
- '%', 'mincho bold', '');
- addgroup(\$otflines, ($do_otf ? \@f_mincho_bold : \@f_mincho_regular),
- 0, $vi,
- 'otf-ujmb-h', 'UniJIS-UTF16-H',
- 'otf-ujmb-v', 'UniJIS-UTF16-V',
- 'otf-cjmb-h', 'Identity-H',
- 'otf-cjmb-v', 'Identity-V',
- 'hminb-h', 'H',
- 'hminb-v', 'V');
- addlines(\$otflines, '%', 'gothic bold', '');
- addgroup(\$otflines, ($do_otf ? \@f_gothic_bold : \@f_gothic_regular),
- 0, $vi,
- 'otf-ujgb-h', 'UniJIS-UTF16-H',
- 'otf-ujgb-v', 'UniJIS-UTF16-V',
- 'otf-cjgb-h', 'Identity-H',
- 'otf-cjgb-v', 'Identity-V',
- 'hgothb-h', 'H',
- 'hgothb-v', 'V');
- addlines(\$otflines, '%', 'gothic heavy', '');
- addgroup(\$otflines, ($do_otf ? \@f_gothic_heavy : \@f_gothic_regular),
- 0, $vi,
- 'hgotheb-h', 'H',
- 'hgotheb-v', 'V');
- addlines(\$otflines, '%', 'gothic maru', '');
- addgroup(\$otflines, ($do_otf ? \@f_gothic_maru : \@f_gothic_regular),
- 0, $vi,
- 'otf-ujmgr-h', 'UniJIS-UTF16-H',
- 'otf-ujmgr-v', 'UniJIS-UTF16-V',
- 'otf-cjmgr-h', 'Identity-H',
- 'otf-cjmgr-v', 'Identity-V',
- 'hmgothr-h', 'H',
- 'hmgothr-v', 'V');
- addlines(\$otflines, '%', 'mincho light', '');
- addgroup(\$otflines, ($do_otf ? \@f_mincho_light : \@f_mincho_regular),
- 0, $vi,
- 'otf-ujml-h', 'UniJIS-UTF16-H',
- 'otf-ujml-v', 'UniJIS-UTF16-V',
- 'otf-cjml-h', 'Identity-H',
- 'otf-cjml-v', 'Identity-V',
- 'hminl-h', 'H',
- 'hminl-v', 'V');
- addlines(\$otflines, '%', 'JIS 2004', '',
- 'otf-ujmrn-h', 'UniJIS2004-UTF16-H', $f_mincho_regular[$ii],
- 'otf-ujmrn-v', 'UniJIS2004-UTF16-V', $f_mincho_regular[$ivi],
- 'hminrn-h', 'H', $f_mincho_regular[$ii],
- 'hminrn-v', 'V', $f_mincho_regular[$ivi],
- '%', '', '',
- 'otf-ujgrn-h', 'UniJIS2004-UTF16-H', $f_gothic_regular[$ii],
- 'otf-ujgrn-v', 'UniJIS2004-UTF16-V', $f_gothic_regular[$ivi],
- 'hgothrn-h', 'H' , $f_gothic_regular[$ii],
- 'hgothrn-v', 'V' , $f_gothic_regular[$ivi],
- '%', '', '');
- addgroup(\$otflines, ($do_otf ? \@f_mincho_bold : \@f_mincho_regular),
- $ii, $ivi,
- 'otf-ujmbn-h', 'UniJIS2004-UTF16-H',
- 'otf-ujmbn-v', 'UniJIS2004-UTF16-V',
- 'hminbn-h', 'H',
- 'hminbn-v', 'V');
- addlines(\$otflines, '%', '', '');
- addgroup(\$otflines, ($do_otf ? \@f_gothic_bold : \@f_gothic_regular),
- $ii, $ivi,
- 'otf-ujgbn-h', 'UniJIS2004-UTF16-H',
- 'otf-ujgbn-v', 'UniJIS2004-UTF16-V',
- 'hgothbn-h', 'H',
- 'hgothbn-v', 'V');
- addlines(\$otflines, '%', '', '');
- addgroup(\$otflines, ($do_otf ? \@f_gothic_heavy : \@f_gothic_regular),
- $ii, $ivi,
- 'otf-ujmgrn-h', 'UniJIS2004-UTF16-H',
- 'otf-ujmgrn-v', 'UniJIS2004-UTF16-V',
- 'hmgothrn-h', 'H',
- 'hmgothrn-v', 'V');
- addlines(\$otflines, '%', '', '');
- addgroup(\$otflines, ($do_otf ? \@f_mincho_light : \@f_mincho_regular),
- $ii, $ivi,
- 'otf-ujmln-h', 'UniJIS2004-UTF16-H',
- 'otf-ujmln-v', 'UniJIS2004-UTF16-V',
- 'hminln-h', 'H',
- 'hminln-v', 'V');
-
- addlines(\$otfuplines,
- 'uphminr-h', 'UniJIS-UTF16-H', $f_mincho_regular[0],
- 'uphminr-v', 'UniJIS-UTF16-V', $f_mincho_regular[$vi],
- 'uphgothr-h', 'UniJIS-UTF16-H', $f_gothic_regular[0],
- 'uphgothr-v', 'UniJIS-UTF16-V', $f_gothic_regular[$vi]);
- addgroup(\$otfuplines, ($do_otf ? \@f_mincho_bold : \@f_mincho_regular),
- 0, $vi,
- 'uphminb-h', 'UniJIS-UTF16-H',
- 'uphminb-v', 'UniJIS-UTF16-V');
- addgroup(\$otfuplines, ($do_otf ? \@f_gothic_bold : \@f_gothic_regular),
- 0, $vi,
- 'uphgothb-h', 'UniJIS-UTF16-H',
- 'uphgothb-v', 'UniJIS-UTF16-V');
- addgroup(\$otfuplines, ($do_otf ? \@f_gothic_heavy : \@f_gothic_regular),
- 0, $vi,
- 'uphgotheb-h', 'UniJIS-UTF16-H',
- 'uphgotheb-v', 'UniJIS-UTF16-V');
- addgroup(\$otfuplines, ($do_otf ? \@f_gothic_maru : \@f_gothic_regular),
- 0, $vi,
- 'uphmgothr-h', 'UniJIS-UTF16-H',
- 'uphmgothr-v', 'UniJIS-UTF16-V');
- addgroup(\$otfuplines, ($do_otf ? \@f_mincho_light : \@f_mincho_regular),
- 0, $vi,
- 'uphminl-h', 'UniJIS-UTF16-H',
- 'uphminl-v', 'UniJIS-UTF16-V');
-
- # check that none of the output files are already existing:
- if (-r "ptex-$group_name.map" ||
- -r "ptex-${group_name}-04.map" ||
- -r "uptex-$group_name.map" ||
- -r "uptex-${group_name}-04.map" ||
- -r "otf-$group_name.map" ||
- -r "otf-up-$group_name.map" ||
- -r "$group_name.map" ||
- -r "${group_name}-04.map") {
- print STDERR "Some of the output files already exist in the cwd, aborting!\n";
- exit 1;
- }
-
- # generate the output files
- open (OUT, ">ptex-$group_name.map")
- or die("Cannot open ptex-$group_name.map for writing: $!");
- print OUT "% generated by $prg\n$ptexlines\n";
- close(OUT);
-
- open (OUT, ">ptex-${group_name}-04.map")
- or die("Cannot open ptex-${group_name}-04.map for writing: $!");
- print OUT "% generated by $prg\n$ptex04lines\n";
- close(OUT);
-
- open (OUT, ">uptex-$group_name.map")
- or die("Cannot open uptex-$group_name.map for writing: $!");
- print OUT "% generated by $prg\n$uptexlines\n";
- close(OUT);
-
- open (OUT, ">uptex-${group_name}-04.map")
- or die("Cannot open uptex-${group_name}-04.map for writing: $!");
- print OUT "% generated by $prg\n$uptex04lines\n";
- close(OUT);
-
- open (OUT, ">otf-$group_name.map")
- or die("Cannot open otf-$group_name.map for writing: $!");
- print OUT "% generated by $prg\n$otflines\n";
- close(OUT);
-
- open (OUT, ">otf-up-$group_name.map")
- or die("Cannot open otf-up-$group_name.map for writing: $!");
- print OUT "% generated by $prg\n$otfuplines\n";
- close(OUT);
-
- open (OUT, ">$group_name.map")
- or die("Cannot open $group_name.map for writing: $!");
- print OUT "% generated by $prg\n%\n% maps for family $group_name\n\n";
- print OUT "% ptex\n$ptexlines\n";
- print OUT "% uptex\n$uptexlines\n";
- print OUT "% otf\n$otflines\n";
- print OUT "% otf-uptex\n$otfuplines\n";
- close(OUT);
-
- open (OUT, ">${group_name}-04.map")
- or die("Cannot open ${group_name}-04.map for writing: $!");
- print OUT "% generated by $prg\n%\n% maps for family $group_name ISO2004\n\n";
- print OUT "% ptex\n$ptex04lines\n";
- print OUT "% uptex\n$uptex04lines\n";
- print OUT "% otf\n$otflines\n";
- print OUT "% otf-uptex\n$otfuplines\n";
- close(OUT);
-
- my $cwd = cwd();
-
- $mw->Dialog(-title => "Finished",
- -text => "Fontmaps have been created in the $cwd.\nPlease move them to a place where dvipdfmx can find them.",
- -buttons => [ "Finish" ])->Show();
-
- $mw->destroy;
- exit 0;
-}
-
-
-sub win32 { return ($^O =~ /^MSWin/i ? 1 : 0); }
-
-__END__
-
-=head1 NAME
-
-kanji-fontmap-creator - GUI to create map file collections for Kanji fonts
-
-=head1 SYNOPSIS
-
-kanji-fontmap-creator [I<option>]
-
-=head1 DESCRIPTION
-
-Create fontmap families for updmap's C<jaEmbed> setting. For details
-see the man page of B<updmap>(1) and the web page
-L<http://tug.org/texlive/updmap-kanji.html>
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-version>
-
-Output version information and exit.
-
-=item B<-help>, B<-?>, B<-h>
-
-Display this help and exit.
-
-=item B<-lang> I<llcode>
-
-By default, the GUI tries to deduce your language from the environment
-(on Windows via the registry, on Unix via C<LC_MESSAGES>). If that fails
-you can select a different language by giving this option with a
-language code (based on ISO 639-1). Currently supported is only
-English.
-
-=back
-
-=head1 AUTHORS AND COPYRIGHT
-
-This script and documentation was written by Norbert Preining
-and both are licensed under the GNU General Public License Version 2
-or later.
-
-=cut
-
-
-# vim:set tabstop=2 expandtab: #
diff --git a/Build/source/texk/texlive/linked_scripts/ptex2pdf/ptex2pdf.lua b/Build/source/texk/texlive/linked_scripts/ptex2pdf/ptex2pdf.lua
deleted file mode 100755
index a15075abef2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ptex2pdf/ptex2pdf.lua
+++ /dev/null
@@ -1,497 +0,0 @@
-#!/usr/bin/env texlua
-
-NAME = "ptex2pdf[.lua]"
-VERSION = "20200520.0"
-AUTHOR = "Norbert Preining"
-AUTHOREMAIL = "norbert@preining.info"
-SHORTDESC = "Convert Japanese TeX documents to pdf"
-LONGDESC = [[
-Main purpose of the script is easy support of Japanese typesetting
-engines in TeXworks. As TeXworks typesetting setup does not allow
-for multistep processing, this script runs one of the ptex based
-programs (ptex, uptex, eptex, euptex, platex, uplatex) followed
-by dvipdfmx.
-]]
-USAGE = [[
-[texlua] ptex2pdf[.lua] { option | basename[.tex] } ...
-options: -v version
- -h help
- -help print full help (installation, TeXworks setup)
- -e use eptex class of programs
- -u use uptex class of programs
- -l use latex based formats
- -ld use latex-dev based formats
- -s stop at dvi
- -i retain intermediate files
- -ot '<opts>' extra options for TeX
- -od '<opts>' extra options for dvipdfmx
- -output-directory '<dir>' directory for created files]]
-
-LICENSECOPYRIGHT = [[
-Originally based on musixtex.lua from Bob Tennent.
-
-(c) Copyright 2016-2020 Japanese TeX Development Community
-(c) Copyright 2013-2020 Norbert Preining norbert@preining.info
-(c) Copyright 2012 Bob Tennent rdt@cs.queensu.ca
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-]]
-
-INSTALLATION = [[
-Copy the file ptex2pdf.lua into a directory where scripts are found,
-that is for example
-
- `TLROOT/texmf-dist/scripts/ptex2pdf/`
-
-(where `TLROOT` is for example the root of your TeX Live installation)
-
-### Unix ###
-
-create a link in one of the bin dirs to the above file, in the
-TeX Live case:
-
- `TLROOT/bin/ARCH/ptex2pdf -> ../../texmf-dist/scripts/ptex2pdf/ptex2pdf.lua`
-
-### Windows ###
-create a copy of runscript.exe as ptex2pdf.exe, in the TeX Live case:
-
- `copy TLROOT/bin/win32/runscript.exe TLROOT/bin/win32/ptex2pdf.exe`
-]]
-
-TEXWORKS = [[
-Under Preferences > Typesetting add new entries, for example:
-
-for ptex files:
-
-| Setting | Value |
-|-------------|--------------------|
-| Name: | pTeX (ptex2pdf) |
-| Program: | ptex2pdf |
-| Arguments: | -ot |
-| | $synctexoption |
-| | $fullname |
-
-for platex files:
-
-| Setting | Value |
-|-------------|--------------------|
-| Name: | pLaTeX (ptex2pdf) |
-| Program: | ptex2pdf |
-| Arguments: | -l |
-| | -ot |
-| | $synctexoption |
-| | $fullname |
-
-for uptex files:
-
-| Setting | Value |
-|-------------|--------------------|
-| Name: | upTeX (ptex2pdf) |
-| Program: | ptex2pdf |
-| Arguments: | -u |
-| | -ot |
-| | $synctexoption |
-| | $fullname |
-
-for uplatex files:
-
-| Setting | Value |
-|-------------|--------------------|
-| Name: | upLaTeX (ptex2pdf) |
-| Program: | ptex2pdf |
-| Arguments: | -l |
-| | -u |
-| | -ot |
-| | $synctexoption |
-| | $fullname |
-
-If you need special kanji encodings for one of these programs,
-add the respective `-kanji` option with the `$synctexoption`. Example:
-
-for platex files in SJIS encoding:
-
-| Setting | Value |
-|-------------|----------------------------|
-| Name: | pLaTeX/SJIS (ptex2pdf) |
-| Program: | ptex2pdf |
-| Arguments: | -l |
-| | -ot |
-| | -kanji=sjis $synctexoption |
-| | $fullname |
-]]
-
-DEVELPLACE = "http://github.com/texjporg/ptex2pdf"
-
-
-CHANGELOG = [[
-- version 0.1 2013-03-08 NP
- Initial release on blog
-- version 0.2 2013-03-10 NP
- import into git repository
- support passing options on to tex and dvipdfm
- add README with TeXworks config options
-- version 0.3 2013-05-01 NP
- include the readme in the lua code
- fix program name for -e -u
-- version 0.4 2013-05-07 NP
- quote the filename with ", so that special chars do survive
- add an example for TeXworks for files with different kanji encoding
-- version 0.5 2014-11-05 NP
- on Windows: set command_line_encoding to utf8 when running uptex
- (patch by Akira Kakuto)
-- version 0.6 2015-03-08 NP
- cygwin didn't like the (accidentally inserted) spaces after the
- texlua in the shebang line, and stopped working with
- "no such program: "texlua " ..."
-- version 0.7 2015-04-29
- move to github as gitorious will be closed, adapt help output
- to generate github flavored markdown
- check for files using kpathsea instead of opening directly, to allow
- for input of files found by kpathsea (closes github issue 1)
-- version 0.8 2015-06-15
- file name checks: first search for arg as is, then try .tex and .ltx
- (closes github issue: 3)
-- version 0.9 2016-12-12
- allow for files in sub-directories
- add -output-directory option
- update copyright and development place (now in texjp)
- support 'flag=val' to specify option values
- only allow one (1) filename argument
-- version 20170603.0
- start version number in the format YYYYMMDD.0
- better support for cp932 windows filenames
- first replace all backslash chars to slash chars
-- version 20170622.0
- pass all non-optional arguments before filename to TeX engine
-- version 20180514.0
- Windows: for uptex use command_line_encoding=utf8, for all other turn
- it off (set to none)
-- version 20181212.0
- support directories containing dots (thanks kn1cht)
-- version 20200119.0
- check invalid PATH string beforehand on windows
-- version 20200307.0
- add -ld option to run (u)platex-dev
-- version 20200520.0
- Windows: lua mode - support non-ascii file name on recent luatex
-]]
-
-
-function usage()
- print(USAGE)
-end
-
-function makereadme()
- print("# " .. NAME .. " #")
- print()
- print("**Author:** " .. AUTHOR .. " ")
- print("**Website:** http://github.com/texjporg/ptex2pdf ")
- print("**License:** GPLv2")
- print()
- print(SHORTDESC)
- print()
- print("## Description ##")
- print()
- print(LONGDESC)
- print("## Usage ##")
- print()
- print("`````")
- print(USAGE)
- print("`````")
- print()
- print("## Installation ##")
- print()
- print(INSTALLATION)
- print("## TeXworks setup ##")
- print()
- print(TEXWORKS)
- print()
- print("## Development place ##")
- print()
- print(DEVELPLACE)
- print()
- print("## Changelog ##")
- print()
- print(CHANGELOG)
- print("## Copyright and License ##")
- print()
- print(LICENSECOPYRIGHT)
-end
-
-function help()
- print(NAME .. ": " .. SHORTDESC)
- print()
- print("Author: " .. AUTHOR)
- print()
- print(LONGDESC)
- print(USAGE)
-end
-
-function fullhelp()
- help()
- print("Installation")
- print("------------")
- print(INSTALLATION)
- print("TeXworks setup")
- print("--------------")
- print(TEXWORKS)
- print("Development place")
- print("-----------------")
- print(DEVELPLACE)
- print()
- print("Copyright and License")
- print("---------------------")
- print(LICENSECOPYRIGHT)
-end
-
-function whoami ()
- print("This is " .. NAME .. " version ".. VERSION .. ".")
-end
-
-function print_ifdebug(message) -- for debugging: accepts only one argument
- --print("DEBUG: " .. message) -- uncomment for debugging
-end
-
-function slashify(str) -- replace "\" with "/", mainly for path strings on cp932 windows
- return (tostring(str):gsub("[\x81-\x9f\xe0-\xfc]?.", { ["\\"] = "/" }))
-end
-
-if #arg == 0 then
- usage()
- os.exit(0)
-end
-
--- defaults:
-tex = "ptex"
-texopts = ""
-dvipdf = "dvipdfmx"
-dvipdfopts = ""
-intermediate = 1
-
-use_eptex = 0
-use_uptex = 0
-use_latex = 0
-use_latexdev = 0
-outputdir = "."
-prefilename = ""
-filename = ""
-bname = ""
-exit_code = 0
-narg = 1
-repeat
- this_arg = arg[narg]
- -- replace double dash by single dash at the beginning
- this_arg = string.gsub(this_arg, "^%-%-", "-")
-
- if this_arg == "-v" then
- whoami()
- os.exit(0)
- elseif this_arg == "-readme" then
- makereadme()
- os.exit(0)
- elseif this_arg == "-output-directory" then
- narg = narg+1
- outputdir = arg[narg]
- elseif (string.sub(this_arg, 1, 18) == "-output-directory=") then
- outputdir = string.sub(this_arg, 19, -1)
- elseif this_arg == "-print-version" then
- print(VERSION)
- os.exit(0)
- elseif this_arg == "-h" then
- help()
- os.exit(0)
- elseif this_arg == "-help" then
- fullhelp()
- os.exit(0)
- elseif this_arg == "-e" then
- use_eptex = 1
- elseif this_arg == "-u" then
- use_uptex = 1
- elseif this_arg == "-l" then
- use_latex = 1
- elseif this_arg == "-ld" then
- use_latex = 1
- use_latexdev = 1
- elseif this_arg == "-s" then
- dvipdf = ""
- elseif this_arg == "-i" then
- intermediate = 0
- elseif this_arg == "-ot" then
- narg = narg+1
- texopts = arg[narg]
- elseif (string.sub(this_arg, 1, 4) == "-ot=") then
- texopts = string.sub(this_arg, 5, -1)
- elseif this_arg == "-od" then
- narg = narg+1
- dvipdfopts = arg[narg]
- elseif (string.sub(this_arg, 1, 4) == "-od=") then
- dvipdfopts = string.sub(this_arg, 5, -1)
- else
- if filename == "" then
- filename = this_arg
- else
- -- when emacs tex-mode is used, this will help store "\nonstopmode\input"
- print("Multiple filename arguments? OK, I'll take the latter one.")
- prefilename = prefilename .. " \"" .. filename .. "\""
- filename = this_arg
- end
- end --if this_arg == ...
- narg = narg+1
-until narg > #arg
-
-whoami()
-
-if use_latex == 1 then
- if use_uptex == 1 then
- if use_latexdev == 1 then
- tex = "uplatex-dev"
- else
- tex = "uplatex" -- uplatex already as etex extension
- end
- else
- if use_latexdev == 1 then
- tex = "platex-dev"
- else
- tex = "platex" -- latex needs etex anyway
- end
- end
-else
- if use_eptex == 1 then
- if use_uptex == 1 then
- tex = "euptex"
- else
- tex = "eptex"
- end
- else
- if use_uptex == 1 then
- tex = "uptex"
- else
- tex = "ptex"
- end
- end
-end
-
-function is_texlivew32()
- if status.luatex_version < 112 then
- return false
- end
- if os.type == 'windows'
- and kpse.var_value('command_line_encoding') ~= nil then
- return true
- else
- return false
- end
-end
-
--- initialize kpse
-kpse.set_program_name(tex)
-
--- filename searching
--- first search for the file as is,
--- if not found, try file .tex, if that not found, file .ltx
-
-if ( filename == "" ) then
- print("No filename argument given, exiting.")
- os.exit(1)
-else
- if is_texlivew32() then
- filename = chgstrcp.syscptoutf8(filename)
- end
- filename = slashify(filename)
- if ( kpse.find_file(filename) == nil ) then
- -- try .tex extension
- if ( kpse.find_file(filename .. ".tex") == nil ) then
- -- last try .ltx
- if ( kpse.find_file(filename .. ".ltx") == nil ) then
- print("File cannot be found with kpathsea: ", filename .. "[.tex, .ltx]")
- os.exit(1)
- else
- if is_texlivew32() then
- filename = chgstrcp.utf8tosyscp(filename)
- end
- bname = filename
- filename = filename .. ".ltx"
- end
- else
- if is_texlivew32() then
- filename = chgstrcp.utf8tosyscp(filename)
- end
- bname = filename
- filename = filename .. ".tex"
- end
- else
- -- if it has already an extension, we need to drop it to get the dvi name
- if is_texlivew32() then
- filename = chgstrcp.utf8tosyscp(filename)
- end
- bname = string.gsub(filename, "^(.*)%.[^./]+$", "%1")
- end
- -- filename may contain "/", but the intermediate output is written
- -- in current directory, so we need to drop it
- -- note that all "\" has been replaced with "/"
- bname = string.gsub(bname, "^.*/(.*)$", "%1")
-end
-
--- we are still here, so we found a file
--- make sure that on Windows/uptex we are using utf8 as command line encoding
-if os.type == 'windows' then
- if use_uptex == 1 then
- os.setenv('command_line_encoding', 'utf8')
- else
- os.setenv('command_line_encoding', 'none')
- end
-end
-if (outputdir ~= ".") then
- texopts = "-output-directory \"" .. outputdir .. "\" " .. texopts
- bname = outputdir .. "/" .. bname
- dvipdfopts = "-o \"" .. bname .. ".pdf\""
-end
-print("Processing ".. filename)
-texcmd = tex .. " " .. texopts .. prefilename .. " \"" .. filename .. "\""
-tex_return = os.execute(texcmd)
--- if os.execute(texcmd) returns -1 on Windows, then
--- cmd.exe is not included in PATH, or some invalid string found before cmd.exe
-if os.type == 'windows' and tex_return == -1 then
- print("Invalid PATH setting found. Please ensure that cmd.exe can be found.\n")
-end
-dvipdfcmd = dvipdf .. " " .. dvipdfopts .. " \"" .. bname .. ".dvi" .. "\""
-if tex_return == 0 and
- (dvipdf == "" or (os.execute(dvipdfcmd) == 0)) then
- if dvipdf ~= "" then
- print(bname .. ".pdf generated by " .. dvipdf .. ".")
- end
- if intermediate == 1 then -- clean-up:
- if dvipdf ~= "" then
- os.remove( bname .. ".dvi" )
- end
- end
-else
- print("ptex2pdf processing of " .. filename .. " failed.\n")
- print_ifdebug("tex = " .. texcmd)
- print_ifdebug("dvipdf = " .. dvipdfcmd)
- os.exit(2)
-end
-
--- all done ... exit with success
-os.exit( 0 )
-
-
-
--- Local Variables:
--- lua-indent-level: 2
--- tab-width: 2
--- indent-tabs-mode: nil
--- End:
--- vim:set tabstop=2 expandtab: #
diff --git a/Build/source/texk/texlive/linked_scripts/purifyeps/purifyeps b/Build/source/texk/texlive/linked_scripts/purifyeps/purifyeps
deleted file mode 100755
index ff686227f01..00000000000
--- a/Build/source/texk/texlive/linked_scripts/purifyeps/purifyeps
+++ /dev/null
@@ -1,529 +0,0 @@
-#! /usr/bin/env perl
-
-################################################################
-# Convert an ordinary Encapsulated PostScript file (.eps) into #
-# one that works with both LaTeX+dvips and pdfLaTeX #
-# #
-# By Scott Pakin <scott+peps@pakin.org> #
-################################################################
-
-our $VERSION = "1.1";
-require 5.006_001;
-use English;
-use Getopt::Long;
-use FindBin qw($Script);
-use File::Basename;
-use File::Temp qw(tempfile);
-use File::Spec;
-use File::Which;
-use Pod::Usage;
-use Pod::Man;
-use Cwd qw(cwd chdir);
-use POSIX;
-use warnings;
-use strict;
-
-# Global variables
-my $fontmap = "mpost.fmp"; # pstoedit-style font map file
-my %TeX_to_PS; # Hash table representing the contents of the above
-my $infile = "-"; # Input file (default: stdin)
-my $outfile = "-"; # Output file (default: stdout)
-my $tempbase; # Base name of temporary files
-my @fontmappath = ( # Where to look for $fontmap
- "/usr/share/pstoedit/",
- "/usr/local/share/pstoedit/");
-
-########################################################################
-
-# At the end of the program's execution, delete all of our temporary files.
-END {
- if (defined $tempbase) {
- foreach my $tempfile ($tempbase, <$tempbase.*>) {
- unlink $tempfile;
- }
- }
-}
-
-
-# Extract the first word from the given array. A word is either a
-# single token or a quoted set of space-separated tokens. Return the
-# first word followed by the remaining tokens.
-sub extractName (@)
-{
- my @tokens = @_;
- my $firstWord;
-
- # Ensure we have a token to extract.
- return (undef, @tokens) if $#tokens==-1;
-
- # Extract the first word from the token list.
- $firstWord = shift @tokens;
- if (substr ($firstWord, 0, 1) eq '"') {
- while (substr ($firstWord, length($firstWord)-1, 1) ne '"') {
- return (undef, @tokens) if $#tokens==-1;
- $firstWord .= " " . shift @tokens;
- }
- $firstWord = substr ($firstWord, 1, length($firstWord)-2);
- }
-
- # Return the word plus the remaining tokens.
- return ($firstWord, @tokens);
-}
-
-
-# Execute a shell command, and die if it fails.
-sub executeCommand ($)
-{
- my $command = $_[0];
- if (system "$command 1>&2") {
- die "${Script}: The following command failed with exit code @{[int($?/256)]}:\n $command\n";
- }
-}
-
-
-# Generate -- and optionally clean up -- a man page.
-sub createManPage ($$$)
-{
- my $manfile = $_[0]; # Name of file to produce
- my $wantPS = $_[1]; # 1=produce PostScript, 0=produce troff
- my $section = $_[2]; # Manual section that purifyeps belongs to
-
- # Produce a (*roff) man page.
- my $parser = Pod::Man->new (center => "",
- release => "v$VERSION",
- section => $section);
- $parser->parse_from_file ($PROGRAM_NAME, $manfile);
-
- # Touch up the man page, and use groff to write
- # the result back to disk as a PostScript file.
- return unless $wantPS;
- open (MANFILE, "<$manfile") or die "${Script}: $! ($manfile)\n";
- my @manlines = <MANFILE>;
- close MANFILE;
- open (MANFILE, "|groff -man > $manfile") or die "${Script}: $! ($manfile)\n";
- foreach (@manlines) {
- s/LaTeX/L\\h'-0.36m'\\v'-0.15'\\s-2A\\s+2\\v'0.15'\\h'-0.15m'TeX/g;
- s/TeX/T\\h'-0.1667m'\\v'0.20'E\\v'-0.20'\\h'-0.125m'X/g;
- s/\\\*\(--/--/g;
- print MANFILE $_;
- }
- close MANFILE;
-}
-
-########################################################################
-
-# Initialize our base temporary filename.
-(undef, $tempbase) = tempfile ($Script . "-XXXXXXXX", DIR => File::Spec->tmpdir());
-
-# Try to determine the full filename of the font-map file.
-foreach my $dir (@fontmappath) {
- my $newfontmap = File::Spec->catfile($dir, $fontmap);
- if (-e $newfontmap) {
- $fontmap = $newfontmap;
- last;
- }
-}
-
-# Process the command line.
-my ($wanthelp, $wantman, $wantps, $wantversion);
-my $versionmsg = "purifyeps version $VERSION
-
-Copyright (C) 2010 Scott Pakin
-
-This program may be distributed and/or modified under the conditions
-of the LaTeX Project Public License, either version 1.3c of this
-license or (at your option) any later version.
-
-The latest version of this license is in:
-
- http://www.latex-project.org/lppl.txt
-
-and version 1.3c or later is part of all distributions of LaTeX
-version 2006/05/20 or later.
-";
-my $man_section = 1; # Section number of man page
-GetOptions ("fontmap=s" => \$fontmap,
- "make-man:s" => \$wantman,
- "make-ps-man:s" => \$wantps,
- "section=s" => \$man_section,
- "V|version" => \$wantversion,
- "help" => \$wanthelp) || pod2usage(2);
-do {print $versionmsg; exit 1} if $wantversion;
-pod2usage(1) if $wanthelp;
-if (defined $wantman) {
- # Create a troff manual page.
- my $filename = ($wantman eq "" ?
- basename ($PROGRAM_NAME, ".pl") . ".$man_section" :
- $wantman);
- createManPage ($filename, 0, $man_section);
- print STDERR "Wrote $filename\n";
- exit 0;
-}
-if (defined $wantps) {
- # Create a PostScript manual page.
- my $filename = ($wantps eq "" ?
- basename ($PROGRAM_NAME, ".pl") . ".ps" :
- $wantps);
- createManPage ($filename, 1, $man_section);
- print STDERR "Wrote $filename\n";
- exit 0;
-}
-$infile = shift @ARGV if $#ARGV!=-1;
-$outfile = shift @ARGV if $#ARGV!=-1;
-pod2usage(2) if $#ARGV!=-1; # Too many arguments.
-
-# Ensure that pstoedit is installed. Give a helpful error message if it isn't.
-if (!defined which("pstoedit")) {
- die "${Script}: pstoedit must be installed and must appear in the executable search path\n";
-}
-
-# Read the font map file into a hash table.
-open (FONTMAP, "<$fontmap") || die "${Script}: $! ($fontmap); specify an alternative with --fontmap\n";
-FONTMAP_LINE:
- while (<FONTMAP>) {
- # Clean up the line.
- chomp;
- s/\%.*//;
- my $origLine = $_;
- next if /^\s*$/;
- my @tokens = split " ";
-
- # Extract the PostScript name, which may be quoted and contain spaces.
- my $PSname;
- ($PSname, @tokens) = extractName @tokens;
- if (!defined $PSname) {
- warn "${fontmap}:$NR: warning: incorrect format -- ignoring line\n";
- next FONTMAP_LINE;
- }
-
- # Extract the TeX name, which may also be quoted and contain spaces.
- my $TeXname;
- ($TeXname, @tokens) = extractName @tokens;
- if (!defined $TeXname) {
- warn "${fontmap}:$NR: warning: incorrect format -- ignoring line\n";
- next FONTMAP_LINE;
- }
-
- # That should be the end of the line.
- if ($#tokens != -1) {
- warn "${fontmap}:$NR: warning: incorrect format -- ignoring line\n";
- next FONTMAP_LINE;
- }
-
- # Store the mapping in a hash table.
- # HEURISTIC: If the mapping is not unique, map the TeX
- # name to the *shortest* PostScript name.
- if (!defined $TeX_to_PS{$TeXname} ||
- length $PSname < length $TeX_to_PS{$TeXname}) {
- $TeX_to_PS{$TeXname} = $PSname;
- }
- }
-close FONTMAP;
-
-# Utilize pstoedit to convert from EPS to MetaPost.
-my $mpfile = $tempbase . ".mp";
-executeCommand "pstoedit -ssp -f mpost -fontmap \"$fontmap\" \"$infile\" \"$mpfile\"";
-
-# Utilize mpost to convert from MetaPost to MPS (stylized EPS).
-my $old_cwd = cwd();
-chdir (File::Spec->tmpdir()); # mpost always writes to the current directory.
-executeCommand "echo X | mpost $mpfile";
-chdir $old_cwd;
-
-# Post-process the MPS file into the output file.
-my $mpsfile = $tempbase . ".1";
-my @purified_eps;
-my $outfile_clean = ($outfile eq "-") ? "stdout" : $outfile;
-open (MPSFILE, "<$mpsfile") || die "${Script}: $! ($mpsfile)\n";
-while (<MPSFILE>) {
- # Process blank lines.
- chomp;
- my @tokens = split " ";
- if ($#tokens == -1) {
- push @purified_eps, "$_\n";
- next;
- }
-
- # Convert the list of document fonts.
- if ($tokens[0] eq "%%DocumentFonts:") {
- my $outputLine = shift @tokens;
- foreach my $TeXname (@tokens) {
- my $PSname = $TeX_to_PS{$TeXname};
- if (!defined $PSname) {
- warn "${outfile_clean}:$NR: warning: TeX font \"$TeXname\" does not appear in $fontmap\n";
- $outputLine .= " $TeXname";
- }
- else {
- $outputLine .= " $PSname";
- }
- }
- push @purified_eps, "$outputLine\n";
- next;
- }
-
- # Convert the font name definitions.
- if ($#tokens == 2 &&
- $tokens[0] eq $tokens[1] &&
- $tokens[2] eq "def") {
- push @purified_eps, sprintf " %s /%s def\n", $tokens[0], $TeX_to_PS{substr($tokens[1],1)};
- next;
- }
-
- # By default, output the line as is.
- push @purified_eps, "$_\n";
-}
-close MPSFILE;
-
-# Write the output file.
-open (OUTFILE, ">$outfile") || die "${Script}: $! ($outfile_clean)\n";
-print OUTFILE @purified_eps;
-close OUTFILE;
-
-# Finish up.
-print STDERR "\nFile seems to have been purified successfully.\n";
-exit 0;
-
-###########################################################################
-
-__END__
-
-
-=head1 NAME
-
-purifyeps - make an Encapsulated PostScript file work with both dvips and
-pdflatex
-
-
-=head1 SYNOPSIS
-
-purifyeps
-B<--help>
-
-purifyeps
-B<--version>
-
-purifyeps
-[B<--fontmap>=I<.fmp file>]
-[I<.eps input file> [I<.eps output file>]]
-
-purifyeps
-B<--make-man>[=I<filename>] [B<--section>=I<section>]
-
-purifyeps
-B<--make-ps-man>[=I<filename>] [B<--section>=I<section>]
-
-
-=head1 DESCRIPTION
-
-While B<pdflatex> has a number of nice features, its primary
-shortcoming relative to standard B<latex>+B<dvips> is that it is
-unable to read ordinary Encapsulated PostScript (EPS) files, the most
-common graphics format in the LaTeX world. B<pdflatex> can read only
-the following types of graphics files:
-
-=over 4
-
-=item PDF
-
-Most people who use B<pdflatex> convert their documents to PDF using a
-utility such as B<epstopdf>. This works well and preserves the vector
-nature of the original EPS. Unfortunately, B<dvips> does not read
-PDF, so two versions of the graphic must be maintained if the document
-is to be processed with both B<latex>+B<dvips> and B<pdflatex>.
-
-=item PNG
-
-PNG is a bitmap format and therefore scales poorly. Also, B<dvips>
-does not read PNG, so two versions of the graphic must be maintained
-if the document is to be processed with both B<latex>+B<dvips> and
-B<pdflatex>.
-
-=item JPEG
-
-JPEG is a bitmap format and therefore scales poorly. Also, B<dvips>
-does not read JPEG, so two versions of the graphic must be maintained
-if the document is to be processed with both B<latex>+B<dvips> and
-B<pdflatex>.
-
-=item MPS
-
-This is probably the least-used B<pdflatex>-compatible graphics
-format. MPS is actually a stylized version of EPS that MetaPost
-outputs. Like PDF, MPS is a vector format and remains as such when
-imported into a B<pdflatex> document. Also like PDF, B<dvips> does
-not read MPS, so two versions of the graphic must be maintained if the
-document is to be processed with both B<latex>+B<dvips> and
-B<pdflatex>.
-
-=back
-
-The insight behind B<purifyeps> is that there are only a few, small
-differences between MPS and EPS and that a file can be converted into
-a format that matches both the MPS and EPS specifications
-simultaneously. B<purifyeps> inputs an EPS file, uses B<pstoedit>'s
-C<mpost> filter to convert the file to MetaPost (F<.mp>), runs
-B<mpost> on the file to convert it to MPS, and finally performs some
-touchups on the result to convert the file back to EPS, while
-preserving its ability to be parsed by B<pdflatex>.
-
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<--help>
-
-Display L<"Usage"> and L<"Options"> from the B<purifyeps> documentation.
-
-=item B<-V>, B<--version>
-
-Display the B<purifyeps> version number, copyright, and license.
-
-=item B<--fontmap>=I<.fmp file>
-
-Specify the name of a file that tells B<purifyeps> how to map from TeX
-font names to PostScript font names. [Default: F<mpost.fmp>]
-
-=item B<--make-man> [=I<filename>]] [B<--section>=I<section>]
-
-Automatically create a Unix man page for B<purifyeps>. I<section>
-specifies the section [default: C<1> (User Commands)]. I<filename>
-defaults to F<purifyeps.1> or an analogous filename if I<section> is
-specified.
-
-=item B<--make-ps-man> [=I<filename>]] [B<--section>=I<section>]
-
-Automatically create a PostScript version of the B<purifyeps>
-documentation. The documentation is formatted like a Unix man page.
-I<section> specifies the section [default: C<1> (User Commands)].
-I<filename> defaults to F<purifyeps.ps>.
-
-=back
-
-In normal operation (i.e., when not run with C<--help>, C<--make-man>,
-or C<--make-ps-man>), B<purifyeps> takes the name of an input file and
-output file. The same filename can safely be used for both files. If
-the output filename is omitted, output will go to the standard output
-device. If the input filename is omitted, B<purifyeps> will read from
-the standard input device.
-
-
-=head1 EXAMPLES
-
-Create a PostScript version of the B<purifyeps> documentation, but
-call it F<happydoc.ps> instead of the default, F<purifyeps.ps>:
-
- purifyeps --make-ps-man=happydoc.ps
-
-Create a Unix man page for B<purifyeps> (in the usual roff format),
-but indicate that it belongs in section C<LOCAL> instead of the
-default of section C<1>:
-
- purifyeps --make-man --section=LOCAL
-
-Purify F<sample.eps> (F<mpost.fmp> is in the current directory):
-
- purifyeps sample.eps sample.eps
-
-Purify F<sample.eps> (F<mpost.fmp> is in a different location):
-
- purifyeps --fontmap=/usr/share/pstoedit/mpost.fmp sample.eps sample.eps
-
-Rename the purified version while purifying:
-
- purifyeps sample.eps sample-pure.eps
-
-Do the same, but in a Unix pipeline:
-
- cat sample.eps | purifyeps > sample-pure.eps
-
-When you run B<purifyeps>, you should see the output from both
-B<pstoedit> and B<mpost>, followed by a success message from
-B<purifyeps>:
-
- % cat sample.eps | purifyeps > sample-pure.eps
- pstoedit: version 3.30 / DLL interface 107 (build Mar 14 2002) :
- Copyright (C) 1993 - 2001 Wolfgang Glunz
- Interpreter finished. Return status 0
- This is MetaPost, Version 0.641 (Web2C 7.3.1)
- (/tmp/purifyeps-jdeGPkh9.mp [1] )
- 1 output file written: purifyeps-jdeGPkh9.1
- Transcript written on purifyeps-jdeGPkh9.log.
-
- File seems to have been purified successfully.
-
-
-=head1 FILES
-
-=over 4
-
-=item F<mpost.fmp>
-
-File containing mappings between TeX and PostScript font names. See
-L<"NOTES"> for a description of this file's contents.
-
-=back
-
-
-=head1 BUGS
-
-Error reporting could definitely stand to be improved. Error messages
-produced by B<pstoedit> and B<mpost> are sometimes silently ignored.
-Also, errors sometimes cause B<purifyeps> to leave temporary files
-(F<purifyeps->I<#####>) lying around.
-
-B<purifyeps> is subject to all of the limitations that affect
-B<pstoedit> and especially the C<mpost> backend to B<pstoedit>. As a
-result, B<purifyeps> ignores certain PostScript constructs, such as
-nonuniformly scaled text.
-
-
-=head1 NOTES
-
-B<purifyeps> needs a file that tells it how to map from TeX font names
-to PostScript font names. This file must contain two, space-separated
-columns. The first lists a PostScript font name, and the second lists
-the TeX equivalent. Blank lines and lines that start with C<%> are
-ignored. The following is a sample F<.fmp> file:
-
- % This is a sample font map for purifyeps.
- Times-Bold ptmb
- Times-Italic ptmri
- Times-Roman ptmr
- Helvetica phvr
- Helvetica-Bold phvb
- Helvetica-Oblique phvro
- Courier pcrr
- Courier-Bold pcrb
- Courier-Oblique pcrro
-
-Note that this is exactly the same format that B<pstoedit> uses. By
-default, B<purifyeps> looks in the current directory for a font map
-called F<mpost.fmp>. The C<--fontmap> command-line option tells
-B<purifyeps> to use a different font map, which will typically be the
-F<mpost.fmp> file that comes with B<pstoedit>.
-
-Once you create purified EPS files with B<purifyeps>, you need to
-instruct B<pdflatex> to use them. The pdfLaTeX configuration of the
-C<graphics> and C<graphicx> packages (F<pdftex.def>) normally ignores
-F<.eps> files. Putting the following LaTeX code in your document's
-preamble tells B<pdflatex> that all F<.eps> files are in MPS format:
-
- % Tell pdfLaTeX that all .eps files were produced by MetaPost.
- \usepackage{graphicx} % or graphics
- \usepackage{ifpdf}
- \ifpdf
- \DeclareGraphicsRule{.eps}{mps}{*}{}
- \makeatletter
- \g@addto@macro\Gin@extensions{,.eps}
- \makeatother
- \fi
-
-=head1 SEE ALSO
-
-dvips(1), epstopdf(1), latex(1), mpost(1), pdflatex(1), pstoedit(1)
-
-
-=head1 AUTHOR
-
-Scott Pakin, I<scott+peps@pakin.org>
diff --git a/Build/source/texk/texlive/linked_scripts/pygmentex/pygmentex.py b/Build/source/texk/texlive/linked_scripts/pygmentex/pygmentex.py
deleted file mode 100755
index 099b5a67eed..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pygmentex/pygmentex.py
+++ /dev/null
@@ -1,516 +0,0 @@
-#! /usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-"""
- PygmenTeX
- ~~~~~~~~~
-
- PygmenTeX is a converter that do syntax highlighting of snippets of
- source code extracted from a LaTeX file.
-
- :copyright: Copyright 2020 by José Romildo Malaquias
- :license: BSD, see LICENSE for details
-"""
-
-__version__ = '0.10'
-__docformat__ = 'restructuredtext'
-
-import sys
-import getopt
-import re
-from os.path import splitext
-
-from pygments import highlight
-from pygments.styles import get_style_by_name
-from pygments.lexers import get_lexer_by_name
-from pygments.formatters.latex import LatexFormatter, escape_tex, _get_ttype_name
-from pygments.util import get_bool_opt, get_int_opt
-from pygments.lexer import Lexer
-from pygments.token import Token
-from pygments.util import guess_decode
-
-###################################################
-# The following code is in >=pygments-2.0
-###################################################
-class EnhancedLatexFormatter(LatexFormatter):
- r"""
- This is an enhanced LaTeX formatter.
- """
- name = 'EnhancedLaTeX'
- aliases = []
-
- def __init__(self, **options):
- LatexFormatter.__init__(self, **options)
- self.escapeinside = options.get('escapeinside', '')
- if len(self.escapeinside) == 2:
- self.left = self.escapeinside[0]
- self.right = self.escapeinside[1]
- else:
- self.escapeinside = ''
-
- def format_unencoded(self, tokensource, outfile):
- # TODO: add support for background colors
- t2n = self.ttype2name
- cp = self.commandprefix
-
- if self.full:
- realoutfile = outfile
- outfile = StringIO()
-
- outfile.write(r'\begin{Verbatim}[commandchars=\\\{\}')
- if self.linenos:
- start, step = self.linenostart, self.linenostep
- outfile.write(',numbers=left' +
- (start and ',firstnumber=%d' % start or '') +
- (step and ',stepnumber=%d' % step or ''))
- if self.mathescape or self.texcomments or self.escapeinside:
- outfile.write(r',codes={\catcode`\$=3\catcode`\^=7\catcode`\_=8}')
- if self.verboptions:
- outfile.write(',' + self.verboptions)
- outfile.write(']\n')
-
- for ttype, value in tokensource:
- if ttype in Token.Comment:
- if self.texcomments:
- # Try to guess comment starting lexeme and escape it ...
- start = value[0:1]
- for i in range(1, len(value)):
- if start[0] != value[i]:
- break
- start += value[i]
-
- value = value[len(start):]
- start = escape_tex(start, self.commandprefix)
-
- # ... but do not escape inside comment.
- value = start + value
- elif self.mathescape:
- # Only escape parts not inside a math environment.
- parts = value.split('$')
- in_math = False
- for i, part in enumerate(parts):
- if not in_math:
- parts[i] = escape_tex(part, self.commandprefix)
- in_math = not in_math
- value = '$'.join(parts)
- elif self.escapeinside:
- text = value
- value = ''
- while len(text) > 0:
- a,sep1,text = text.partition(self.left)
- if len(sep1) > 0:
- b,sep2,text = text.partition(self.right)
- if len(sep2) > 0:
- value += escape_tex(a, self.commandprefix) + b
- else:
- value += escape_tex(a + sep1 + b, self.commandprefix)
- else:
- value = value + escape_tex(a, self.commandprefix)
- else:
- value = escape_tex(value, self.commandprefix)
- elif ttype not in Token.Escape:
- value = escape_tex(value, self.commandprefix)
- styles = []
- while ttype is not Token:
- try:
- styles.append(t2n[ttype])
- except KeyError:
- # not in current style
- styles.append(_get_ttype_name(ttype))
- ttype = ttype.parent
- styleval = '+'.join(reversed(styles))
- if styleval:
- spl = value.split('\n')
- for line in spl[:-1]:
- if line:
- outfile.write("\\%s{%s}{%s}" % (cp, styleval, line))
- outfile.write('\n')
- if spl[-1]:
- outfile.write("\\%s{%s}{%s}" % (cp, styleval, spl[-1]))
- else:
- outfile.write(value)
-
- outfile.write('\\end{Verbatim}\n')
-
- if self.full:
- realoutfile.write(DOC_TEMPLATE %
- dict(docclass = self.docclass,
- preamble = self.preamble,
- title = self.title,
- encoding = self.encoding or 'latin1',
- styledefs = self.get_style_defs(),
- code = outfile.getvalue()))
-
-class LatexEmbeddedLexer(Lexer):
- r"""
-
- This lexer takes one lexer as argument, the lexer for the language
- being formatted, and the left and right delimiters for escaped text.
-
- First everything is scanned using the language lexer to obtain
- strings and comments. All other consecutive tokens are merged and
- the resulting text is scanned for escaped segments, which are given
- the Token.Escape type. Finally text that is not escaped is scanned
- again with the language lexer.
- """
- def __init__(self, left, right, lang, **options):
- self.left = left
- self.right = right
- self.lang = lang
- Lexer.__init__(self, **options)
-
- def get_tokens_unprocessed(self, text):
- buf = ''
- for i, t, v in self.lang.get_tokens_unprocessed(text):
- if t in Token.Comment or t in Token.String:
- if buf:
- for x in self.get_tokens_aux(idx, buf):
- yield x
- buf = ''
- yield i, t, v
- else:
- if not buf:
- idx = i
- buf += v
- if buf:
- for x in self.get_tokens_aux(idx, buf):
- yield x
-
- def get_tokens_aux(self, index, text):
- while text:
- a, sep1, text = text.partition(self.left)
- if a:
- for i, t, v in self.lang.get_tokens_unprocessed(a):
- yield index + i, t, v
- index += len(a)
- if sep1:
- b, sep2, text = text.partition(self.right)
- if sep2:
- yield index + len(sep1), Token.Escape, b
- index += len(sep1) + len(b) + len(sep2)
- else:
- yield index, Token.Error, sep1
- index += len(sep1)
- text = b
-###################################################
-
-GENERIC_DEFINITIONS_1 = r'''% -*- mode: latex -*-
-
-\makeatletter
-
-\newdimen\LineNumberWidth
-'''
-
-GENERIC_DEFINITIONS_2 = r'''
-\makeatother
-'''
-
-
-INLINE_SNIPPET_TEMPLATE = r'''
-\expandafter\def\csname pygmented@snippet@%(number)s\endcsname{%%
- \pygmented@snippet@inlined{%%
-%(body)s%%
-}}
-'''
-
-DISPLAY_SNIPPET_TEMPLATE = r'''
-\expandafter\def\csname pygmented@snippet@%(number)s\endcsname{%%
- \begin{pygmented@snippet@framed}%%
-%(body)s%%
- \end{pygmented@snippet@framed}%%
-}
-'''
-
-DISPLAY_LINENOS_SNIPPET_TEMPLATE = r'''
-\expandafter\def\csname pygmented@snippet@%(number)s\endcsname{%%
- \begingroup
- \def\pygmented@alllinenos{(%(linenumbers)s)}%%
- \begin{pygmented@snippet@framed}%%
-%(body)s%%
- \end{pygmented@snippet@framed}%%
- \endgroup
-}
-'''
-
-
-def pyg(outfile, outencoding, n, opts, extra_opts, text, usedstyles, inline_delim = ''):
- try:
- lexer = get_lexer_by_name(opts['lang'])
- except ClassNotFound as err:
- sys.stderr.write('Error: ')
- sys.stderr.write(str(err))
- return ""
-
- # global _fmter
- _fmter = EnhancedLatexFormatter()
-
- escapeinside = opts.get('escapeinside', '')
- if len(escapeinside) == 2:
- left = escapeinside[0]
- right = escapeinside[1]
- _fmter.escapeinside = escapeinside
- _fmter.left = left
- _fmter.right = right
- lexer = LatexEmbeddedLexer(left, right, lexer)
-
- gobble = abs(get_int_opt(opts, 'gobble', 0))
- if gobble:
- lexer.add_filter('gobble', n=gobble)
-
- tabsize = abs(get_int_opt(opts, 'tabsize', 0))
- if tabsize:
- lexer.tabsize = tabsize
-
- lexer.encoding = ''
- # _fmter.encoding = outencoding
-
- stylename = opts['sty']
-
- _fmter.style = get_style_by_name(stylename)
- _fmter._create_stylesheet()
-
- _fmter.texcomments = get_bool_opt(opts, 'texcomments', False)
- _fmter.mathescape = get_bool_opt(opts, 'mathescape', False)
-
- if stylename not in usedstyles:
- styledefs = _fmter.get_style_defs() \
- .replace('#', '##') \
- .replace(r'\##', r'\#') \
- .replace(r'\makeatletter', '') \
- .replace(r'\makeatother', '') \
- .replace('\n', '%\n')
- outfile.write(
- '\\def\\PYstyle{0}{{%\n{1}%\n}}%\n'.format(stylename, styledefs))
- usedstyles.append(stylename)
-
- x = highlight(text, lexer, _fmter)
-
- m = re.match(r'\\begin\{Verbatim}(.*)\n([\s\S]*?)\n\\end\{Verbatim}(\s*)\Z',
- x)
- if m:
- linenos = get_bool_opt(opts, 'linenos', False)
- linenostart = abs(get_int_opt(opts, 'linenostart', 1))
- linenostep = abs(get_int_opt(opts, 'linenostep', 1))
- lines0 = m.group(2).split('\n')
- numbers = []
- lines = []
- counter = linenostart
- for line in lines0:
- line = re.sub(r'^ ', r'\\makebox[0pt]{\\phantom{Xy}} ', line)
- line = re.sub(r' ', '~', line)
- if linenos:
- if (counter - linenostart) % linenostep == 0:
- line = r'\pygmented@lineno@do{' + str(counter) + '}' + line
- numbers.append(str(counter))
- counter = counter + 1
- lines.append(line)
- if inline_delim:
- outfile.write(INLINE_SNIPPET_TEMPLATE %
- dict(number = n,
- style = stylename,
- options = extra_opts,
- body = '\\newline\n'.join(lines)))
- else:
- if linenos:
- template = DISPLAY_LINENOS_SNIPPET_TEMPLATE
- else:
- template = DISPLAY_SNIPPET_TEMPLATE
- outfile.write(template %
- dict(number = n,
- style = stylename,
- options = extra_opts,
- linenosep = opts['linenosep'],
- linenumbers = ','.join(numbers),
- body = '\\newline\n'.join(lines)))
-
-
-
-def parse_opts(basedic, opts):
- dic = basedic.copy()
- for opt in re.split(r'\s*,\s*', opts):
- x = re.split(r'\s*=\s*', opt)
- if len(x) == 2 and x[0] and x[1]:
- dic[x[0]] = x[1]
- elif len(x) == 1 and x[0]:
- dic[x[0]] = True
- return dic
-
-
-
-_re_display = re.compile(
- r'^<@@pygmented@display@(\d+)\n(.*)\n([\s\S]*?)\n>@@pygmented@display@\1$',
- re.MULTILINE)
-
-_re_inline = re.compile(
- r'^<@@pygmented@inline@(\d+)\n(.*)\n([\s\S]*?)\n>@@pygmented@inline@\1$',
- re.MULTILINE)
-
-_re_input = re.compile(
- r'^<@@pygmented@input@(\d+)\n(.*)\n([\s\S]*?)\n>@@pygmented@input@\1$',
- re.MULTILINE)
-
-def convert(code, outfile, outencoding):
- """
- Convert ``code``
- """
- outfile.write(GENERIC_DEFINITIONS_1)
-
- opts = { 'lang' : 'c',
- 'sty' : 'default',
- 'linenosep' : '0pt',
- 'tabsize' : '8',
- 'encoding' : 'guess',
- }
-
- usedstyles = [ ]
- styledefs = ''
-
- pos = 0
-
- while pos < len(code):
- if code[pos].isspace():
- pos = pos + 1
- continue
-
- m = _re_inline.match(code, pos)
- if m:
- pyg(outfile,
- outencoding,
- m.group(1),
- parse_opts(opts.copy(), m.group(2)),
- '',
- m.group(3),
- usedstyles,
- True)
- pos = m.end()
- continue
-
- m = _re_display.match(code, pos)
- if m:
- pyg(outfile,
- outencoding,
- m.group(1),
- parse_opts(opts.copy(), m.group(2)),
- '',
- m.group(3),
- usedstyles)
- pos = m.end()
- continue
-
- m = _re_input.match(code, pos)
- if m:
- opts_new = parse_opts(opts, m.group(2))
- try:
- filecontents, inencoding = read_input(m.group(3), opts_new['encoding'])
- except Exception as err:
- print('Error: cannot read input file: ', err, file=sys.stderr)
- else:
- pyg(outfile,
- outencoding,
- m.group(1),
- opts_new,
- "",
- filecontents,
- usedstyles)
- pos = m.end()
- continue
-
- sys.stderr.write('Error: invalid input file contents: ignoring')
- break
-
- outfile.write(GENERIC_DEFINITIONS_2)
-
-def read_input(filename, encoding):
- with open(filename, 'rb') as infp:
- code = infp.read()
-
- if not encoding or encoding == 'guess':
- code, encoding = guess_decode(code)
- else:
- code = code.decode(encoding)
-
- return code, encoding
-
-
-USAGE = """\
-Usage: %s [-o <output file name>] <input file name>
- %s -h | -V
-
-The input file should consist of a sequence of source code snippets, as
-produced by the `pygmentex` LaTeX package. Each code snippet is
-highlighted using Pygments, and a LaTeX command that expands to the
-highlighted code snippet is written to the output file.
-
-It also writes to the output file a set of LaTeX macro definitions the
-Pygments styles that are used in the code snippets.
-
-If no output file name is given, use `<input file name>.pygmented`.
-
-The -e option enables escaping to LaTex. Text delimited by the <left>
-and <right> characters is read as LaTeX code and typeset accordingly. It
-has no effect in string literals. It has no effect in comments if
-`texcomments` or `mathescape` is set.
-
-The -h option prints this help.
-
-The -V option prints the package version.
-"""
-
-
-def main(args = sys.argv):
- """
- Main command line entry point.
- """
- usage = USAGE % ((args[0],) * 2)
-
- try:
- popts, args = getopt.getopt(args[1:], 'e:o:hV')
- except getopt.GetoptError as err:
- sys.stderr.write(usage)
- return 2
- opts = {}
- for opt, arg in popts:
- opts[opt] = arg
-
- if not opts and not args:
- print(usage)
- return 0
-
- if opts.pop('-h', None) is not None:
- print(usage)
- return 0
-
- if opts.pop('-V', None) is not None:
- print('PygmenTeX version %s, (c) 2020 by José Romildo.' % __version__)
- return 0
-
- if len(args) != 1:
- sys.stderr.write(usage)
- return 2
- infn = args[0]
- try:
- code, inencoding = read_input(infn, "guess")
- except Exception as err:
- print('Error: cannot read input file: ', err, file=sys.stderr)
- return 1
-
- outfn = opts.pop('-o', None)
- if not outfn:
- root, ext = splitext(infn)
- outfn = root + '.pygmented'
- try:
- outfile = open(outfn, 'w')
- except Exception as err:
- print('Error: cannot open output file: ', err, file=sys.stderr)
- return 1
-
- convert(code, outfile, inencoding)
-
- return 0
-
-
-if __name__ == '__main__':
- try:
- sys.exit(main(sys.argv))
- except KeyboardInterrupt:
- sys.exit(1)
diff --git a/Build/source/texk/texlive/linked_scripts/pythontex/depythontex.py b/Build/source/texk/texlive/linked_scripts/pythontex/depythontex.py
deleted file mode 100755
index 3d48e3b1daa..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pythontex/depythontex.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-'''
-This is the depythontex wrapper script. It automatically detects the version
-of Python, and then imports the correct code from depythontex2.py or
-depythontex3.py. It is intended for use with the default Python installation
-on your system. If you wish to use a different version of Python, you could
-launch depythontex2.py or depythontex3.py directly. The version of Python
-does not matter for depythontex, since no code is executed.
-
-Copyright (c) 2013-2017, Geoffrey M. Poore
-All rights reserved.
-Licensed under the BSD 3-Clause License:
- http://www.opensource.org/licenses/BSD-3-Clause
-
-'''
-
-import sys
-if sys.version_info[0] == 2:
- import depythontex2 as depythontex
-elif sys.version_info[0] == 3:
- import depythontex3 as depythontex
diff --git a/Build/source/texk/texlive/linked_scripts/pythontex/pythontex.py b/Build/source/texk/texlive/linked_scripts/pythontex/pythontex.py
deleted file mode 100755
index 2fe6de902a2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/pythontex/pythontex.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-'''
-This is the PythonTeX wrapper script. It automatically detects the version
-of Python, and then imports the correct code from pythontex2.py or
-pythontex3.py. It is intended for use with the default Python installation
-on your system. If you wish to use a different version of Python, you could
-launch pythontex2.py or pythontex3.py directly. You should also consider the
-command-line option `--interpreter`. This allows you to specify the command
-that is actually used to execute the code from your LaTeX documents. Except
-for Python console content, it doesn't matter which version of Python is used
-to launch pythontex.py; pythontex.py just manages the execution of code from
-your LaTeX document. The interpreter setting is what determines the version
-under which your code is actually executed.
-
-Licensed under the BSD 3-Clause License:
-
-Copyright (c) 2012-2017, Geoffrey M. Poore
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the <organization> nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-
-
-import sys
-if sys.version_info.major == 2:
- if sys.version_info.minor >= 7:
- import pythontex2 as pythontex
- else:
- sys.exit('PythonTeX require Python 2.7; you are using 2.{0}'.format(sys.version_info.minor))
-elif sys.version_info.major == 3:
- if sys.version_info.minor >= 2:
- import pythontex3 as pythontex
- else:
- sys.exit('PythonTeX require Python 3.2+; you are using 3.{0}'.format(sys.version_info.minor))
-
-# The "if" statement is needed for multiprocessing under Windows; see the
-# multiprocessing documentation.
-if __name__ == '__main__':
- pythontex.main()
diff --git a/Build/source/texk/texlive/linked_scripts/rubik/rubikrotation.pl b/Build/source/texk/texlive/linked_scripts/rubik/rubikrotation.pl
deleted file mode 100755
index d9b02d5a473..00000000000
--- a/Build/source/texk/texlive/linked_scripts/rubik/rubikrotation.pl
+++ /dev/null
@@ -1,2926 +0,0 @@
-#!/usr/bin/env perl
-##
- use Carp;
- use Fatal;
- use warnings;
- ##
- our $version = "v5.0 (25 February 2018)";
- ##
- ## rubikrotation.pl
- ## VERSION 5.0
- ##
- ## Copyright February 2018,
- ## RWD Nickalls (dick@nickalls.org)
- ## A Syropoulos (asyropoulos@yahoo.com)
- ##
- ## HISTORY
- ##-------------------------------
- ## v5.0 (25 February 2018)
- ##-------------------------------
- ##
- ## 4.2h (07 February 2018)
- ## --- adjusted the no of leading dots for the gprint command
- ## when writing the up, down,.. colour state to the log file
- ## so as to make the array form a square block (ie easier to read)
- ## (in MAIN)
- ##
- ## 4.2g
- ## --- 29 October 2017 added syntax checking for (( )) /inside/ squarebrackets
- ## (in SUB checksyntax)
- ## --- 24 October 2017 changed {};--> (), in SequenceNameNew (in SUB writestate)
- ## this repairs these chars back to their original state.
- ## --- 22 October 2017 minor adjustments to syntax checking (in SUB checksyntax)
- ## to allow some extra chars in the [name] and <info> blocks.
- ## Ideally, we want to be able to use /any/ chars inside these infoblocks.
- ##
- ## 4.2f
- ## --- 05 Oct 2017 bugfix: added a ShowSequence [\space] bug fix in SUB checksyntax
- ## --- 04 Oct 2017 adjusted brackets < > error messages (lines 2643--2659)
- ##
- ## 4.2e: (29 Sept 2017)
- ## --- added a ``Western'' notation filter (provisional \& works)
- ##
- ## 4.2d: (10 August 2017)
- ## --- placed a checkstate() command inside the rotation keyword
- ## and stopped TEX writing the keyword checkstate to the rubikstate.dat file
- ##
- ## 4.2c: (2 August 2017)
- ## --- added new rubikkeyword "cubesize" to hold cube size (three or two)
- ## so we can tell which sort of cube is being processed
- ## We can use this to detect when using the TwoRotation command
- ## (for the TWOcube) vs when using the RubikRotation command
- ## (for the THREEcube); for eample with regard to random rotations
- ## (see random SUB; see RubikTwoCube.sty)
- ##
- ## 4.2b: (1 Aug 2017)
- ## --- Removed the random,0 option --> n=50 (random SUB)
- ## a zero or missing integer now generates an error message.
- ##
- ## 4.2a: (28 July 2017)
- ## --- bugfix: error if spaces in RubikRotation{random,n} string from LaTeX.
- ## Fixed to accommodate spaces, and uppercase random (lines 366 -- 388 approx)
- ##
- ##-------------------------------
- ## v4.0 (3 March 2017)
- ##-------------------------------
- ## changes in v3.6 (January 2017)
- ## --- included Jaap Rm and Rc notation
- ## --- new sub for improved expansion of mod-4 multiples of rotations (Oct 2016)
- ## --- restructured to facilitate processing arrays through the rotation sub
- ## --- included option for an <info> block
- ## --- included Randelshofer superset ENG 3x3 notation
- ## --- implemented an `inverse' mode
- ## --- improved syntax checking
- ## --- used perltidy to polish the program layout
- ## (but only when making the pdf documentation-- see file rubikrotationPL.pdf)
- ## --- included a lot of new subroutines
- ##--------------------------------
- ## changes in v3.2:
- ## v3.2h: (2 Oct 2016)
- ## improved the mod 4 routine using SUB rubikmod()
- ## improved comments to log file re: rotation processing
- ##
- ## v3.2e:(25 Sept 2016)
- ## changed some command names: use short & long for the Rubik R2 --> R,R code
- ## (more intuitive than Clean)
- ## \Sequence{} --> SecquenceShort{}
- ## \SequenceClean{} --> SecquenceLong{}
- ## removed the [ and ] around [name] variable
- ##
- ## v3.2d: changed the returned command names (removed the Rotation part to keep it simple)
- ## \Sequence{} = orig seq + NO NAME
- ## \SequenceName{} = NAME only
- ## \SequenceClean{} = clean seq + NO NAME
- ##
- ## v3.2c: added new commands:
- ## \RotationSequenceName{}
- ## \RotationSequenceClean{}
- ##
- ## v3.2a: added a \RubikSeqNEW{...} output line in the output file
- ## to facilitate typesetting the rotation sequence (works OK just now)
- ##
- ## v3.2: --- added leading ... to the comments written by the <writestate> sub
- ## (the ... code indicates that comments are written by the Perl script)
- ## --- changed the word program, prog --> script
- ##--------------------------------
- ## changes in v3.0:
- ## --- accepts command-line arguments for input (mandatory) and output (optional) filenames
- ## default output filename is: rubikOUT.txt
- ## --- included the symbols [ and ] to denote a rotation-name label (ie as well as *)
- ## --- fixed some of the variable definitions (as highlighted by <use strict> pragma)
- ##--------------------------------
- ## changes in v2.3:
- ## --- accepts a single commandline argument (datafilename)
- ## --- uses the standard modules Carp and Fatal (give extra line info on error)
- ##--------------------------------
- ## changes in v2.2:
- ## --- changed licence --> LatexPP
- ## --- included random n errors in ERROR messages (lines 492--495)
- ## --- included version number in error message
- ##------------------------------
- #
- # This file is part of the LaTeX rubikrotation package, and
- # requires rubikcube.sty and rubikrotation.sty
- #
- # rubikrotation.pl is a Perl-5 program and free software:
- # This program can be redistributed and/or modified under the terms
- # of the LaTeX Project Public License Distributed from CTAN
- # archives in directory macros/latex/base/lppl.txt; either
- # version 1 of the License, or any later version.
- #
- # rubikrotation.pl is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
-
- ##---------------------------------------------------------------------
- ## OVERVIEW
- ## This program is part of the rubikrotation package, and is complementary to
- ## the LaTeX rubikcube package. It processes Rubik rotation sequences on-the-fly.
- ## The program reads a datafile (rubikstate.dat) output by the rubikcube package
- ## and writes the new state to the file rubikstateNEW.dat, which is then input
- ## by the TeX file. Further documentation accompanies the rubikrotation package.
-
- ## Note that all possible state changing rotations of a 3x3x3 cube are
- ## either combinations of, or the inverse of, just 9 different rotations,
- ## three associated with each XYZ axis.
- ##----------------------------------------------------------------------
-
- ##==MAIN==
- ##
- ## This main module opens three files, and
- ## sets up an array for collecting all errors (%error), and sets an error flag to "",
- ## reads in the rubik state data file =rubikstate.dat (written by rubikrotation.sty),
- ## and calls subs to write the TeX_OUT_FILE,
- ## and finally closes all files.
- ## Each line of the input file (rubikstate.dat) is a comma separated list of arguments.
- ## The first argument in each line of the file rubikstate.dat is a rubikkeyword.
- ##
- ##---------------
- ## set autoflush for outputs
- ## $|=1;
- ##--------------
- our $source_file="";
- our $out_file="rubikOUT.txt"; #default
- our $argc=@ARGV;
- our $commandLineArgs = join(" ", @ARGV);
- our $showargs="\tcommandline args = $commandLineArgs\n";
- our $usage="\tUsage: rubikrotation [-h|--help|-v|--version] -i <input file> [-o <out file>]\n";
- our $rubikversion="\tVersion: this is rubikrotation version $version\n";
- #
- ## check for correct number of commandline arguments and allocate filenames
- #
- if ($argc == 0||$argc > 4 ){ # croak if 0 or more than 4 arguments
- croak $rubikversion,$showargs,
- "\tWrong no of arguments\n",
- $usage;
- }
- else {
- SWITCHES:
- while($_ = $ARGV[0]) {
- shift;
- if (/^-h$/ || /^--help$/ ) {
- die $rubikversion,$usage,
- "\twhere,\n" .
- "\t[-h|--help]\tgives this help listing\n" .
- "\t[-v|--version]\tgives version\n" .
- "\t[-i] \tcreates specified input file\n",
- "\t[-o] \tcreates specified output file\n",
- "\tFor documentation see: rubikrotation.pdf,\n",
- "\trubikrotationPL.pdf and rubikcube.pdf.\n\n";
- }
- elsif (/^-v$/ || /^--version$/ ) {die $rubikversion;}
- elsif (/^-i$/) {
- if (!@ARGV){
- croak $showargs,
- "\tNo input file specified!\n",
- $usage;
- }
- else {
- $source_file = $ARGV[0],
- shift;
- }
- }
- elsif (/^-o$/) {
- if (!@ARGV) {
- croak $showargs,
- "\tNo output file specified!\n",
- $usage;
- }
- else {
- $out_file = $ARGV[0],
- shift;
- }
- }
- elsif (/^-\w+/) {
- croak $showargs,
- "\t$_: Illegal command line switch!\n",
- $usage;
- }
- else {
- croak $showargs,
- "\tmissing filenames or ? missing -i or -o switch!\n",
- $usage;
- }
- } # end of while
- }; # end of else
-
- #================================
-
- open(IN_FILE, "<$source_file") ||croak "\tCan't open source file: $source_file\n";
- open(TeX_OUT_FILE, ">$out_file")||croak "\tCan't open output file: $out_file\n";
-
- ## create error file (for append)
- open (ERROR_OUT_FILE, ">>rubikstateERRORS.dat")||croak "ERROR: can't open file rubikstateERRORS.dat\n";
-
-
- ## use dots for Perl messages (I have used dashes for LaTeX messages in the .sty)
- ## gprint sub prints its argument (message) to both the screen and to the TeX_OUT_FILE
-
- gprint (""); # newline
- gprint ("...PERL process..................................");
- gprint ("...script = rubikrotation.pl $version");
-
- ## setup global error parameters, so we can write all the errors to a file as an array
- our %error = (); # setup an array for error messages (was %)
- our $erroralert = ""; # error flag
- our $errornumber = 0; #set number of errors to zero
-
- gprint ("...reading the current cube state (from File: $source_file)");
-
- our $dataline = "";
- our $newdataline ="";
- our $rubikkeyword = "";
- our $cubesize = ""; ## to hold the size, as three (Rubik) or two (twocube)
- our $rotationcommand = "";
- our @data=();
-
- our $Sequence=""; ## will hold the original (SHORT) sequence
- our $rotationseqNEW = ""; ## will hold the LONG sequence
- our $RotationSequenceName="";
-
- our $SequenceName="";
- our $SequenceShort="";
- our $SequenceLong="";
- our $SequenceInfo="";
-
-
- our $jrcode = 0; ## We initialise a loop counter for use in the rotation sub
- ## (see line 624)
-
- #---------inverse mode------------
- # a keyword INVERSE or inverse in an infoblock <..>
- # FLAG is set (line 400) in response to detecting an infloblock.
- # A set FLAG triggers (a) reversing rotation sequence (line 484),
- # and (b) inverting each rotation (to generate the inverse sequence).
- # Here we define direction FLAG for the INVERSE sequence of rotations.
- # The conditional test is in the SUB rotation
- our $inverse="INV";
- our $directionflag="";
- #-------------------------
-
-
- LINE: while (<IN_FILE>){
- next LINE if /^#/; #skip comments
- next LINE if /^%/; #skip comments
- next LINE if /^$/; #skip blank lines
-
-
- print " \n TOP --------- (new line)\n\n";
-
- $dataline = $_; # grab the whole line as a string
- chomp $dataline; # remove the line-ending character
-
- ## clean leading and trailing whitespace
- $dataline = cleanstring($dataline);
-
-
- #check syntax of the string
- $rotationcommand=$dataline; ## needed for error messages
- CheckSyntax($dataline);
-
- ## form an array so we can process the (rubik)keywords.
- @data=split (/,/, $dataline); # create an array called data
-
- print " dataline array = @data\n";
- #-------------------------
-
- ## we have 10 fields (0--9)
- ## check for rubikkeyword= cubesize, up,down,left,right,front,back,checkstate,rotation:
- $rubikkeyword=$data[0];
-
- ##--------------------------------
- ## RWDN 2 August 2017
- ## introduced keyword cubesize so prog can distinguish
- ## between a TWOcube and an THREEcube.
- ## Here we check for the rubikkeyword `cubesize'
- ## cubesize is currently only being used to change the array size in random SUB
- if ($rubikkeyword eq 'cubesize') {
- gprint ("...");
- $rotationcommand=$dataline; ## used in output message
- gprint ("...command = $rotationcommand");
- $cubesize = RemoveAllSpaces($data[1]);
- if ($cubesize eq "two") {gprint ("...cube = TWOcube")};
- if ($cubesize eq "three") {gprint ("...cube = THREEcube")};
- gprint ("...");
- next LINE ;
- };
- ## ------------------------------------
-
- ## RWDN 7 February 2018
- ## we vary the number of leading dots for the gprint command
- ## so as to make the array of colour codes (X,W,Y, etc) form
- ## a nice square when printed to the log file (the standard no is 3 dots)
-
- if ($rubikkeyword eq 'up') { gprint ("......$dataline");
- $Ult[0]=$data[1], $Umt[0]=$data[2],$Urt[0]=$data[3],
- $Ulm[0]=$data[4], $Umm[0]=$data[5],$Urm[0]=$data[6],
- $Ulb[0]=$data[7], $Umb[0]=$data[8],$Urb[0]=$data[9];
- next LINE;
- };
-
- if ($rubikkeyword eq 'down') { gprint ("....$dataline");
- $Dlt[0]=$data[1], $Dmt[0]=$data[2],$Drt[0]=$data[3],
- $Dlm[0]=$data[4], $Dmm[0]=$data[5],$Drm[0]=$data[6],
- $Dlb[0]=$data[7], $Dmb[0]=$data[8],$Drb[0]=$data[9];
- next LINE;
- };
-
- if ($rubikkeyword eq 'left') { gprint ("....$dataline");
- $Llt[0]=$data[1], $Lmt[0]=$data[2],$Lrt[0]=$data[3],
- $Llm[0]=$data[4], $Lmm[0]=$data[5],$Lrm[0]=$data[6],
- $Llb[0]=$data[7], $Lmb[0]=$data[8],$Lrb[0]=$data[9];
- next LINE;
- };
-
- if ($rubikkeyword eq 'right') { gprint ("...$dataline");
- $Rlt[0]=$data[1], $Rmt[0]=$data[2],$Rrt[0]=$data[3],
- $Rlm[0]=$data[4], $Rmm[0]=$data[5],$Rrm[0]=$data[6],
- $Rlb[0]=$data[7], $Rmb[0]=$data[8],$Rrb[0]=$data[9];
- next LINE;
- };
-
- if ($rubikkeyword eq 'front') { gprint ("...$dataline");
- $Flt[0]=$data[1], $Fmt[0]=$data[2],$Frt[0]=$data[3],
- $Flm[0]=$data[4], $Fmm[0]=$data[5],$Frm[0]=$data[6],
- $Flb[0]=$data[7], $Fmb[0]=$data[8],$Frb[0]=$data[9];
- next LINE;
- };
-
- if ($rubikkeyword eq 'back') { gprint ("....$dataline");
- $Blt[0]=$data[1], $Bmt[0]=$data[2],$Brt[0]=$data[3],
- $Blm[0]=$data[4], $Bmm[0]=$data[5],$Brm[0]=$data[6],
- $Blb[0]=$data[7], $Bmb[0]=$data[8],$Brb[0]=$data[9];
- next LINE;
- };
-
- ## if the rubikkeyword is `checkstate'
- ## we just check the state and write the output data to a file.
- if ($rubikkeyword eq 'checkstate') {
- gprint ("...");
- $rotationcommand=$dataline; ## used in output message
- gprint ("...command = $rotationcommand");
- checkstate();
- next LINE ;
- };
-
- ## IF the rubikkeyword is `rotation'
- ## we first check to see if the second argument=random.
- ## ---if so, then we check that the third argument is an integer,
- ## ---if it is an integer n --> random => random(n)
- ## ELSE it must be a rotation sequence --> send elements to rotation sub.
-
-
- if ($rubikkeyword eq 'rotation')
-
- { ## this IF runs down to near end of MAIN
-
- ##RWDN 10 Aug 2017
- ## moved checkstate to be inside rotation (so a next LINE will terminate prog)
- gprint ("...");
- gprint ("...rotation keyword");
- checkstate();
-
-
- gprint ("..."); ## logfile marker for begining of `rotation/random' process
-
- # we now grab a copy of the dataline, and we shall use this
- # in the ErrorMessage SUB to indicate which command
- # an error is in.
- $rotationcommand=$dataline; ## used in output message
- gprint ("...command = $rotationcommand");
-
-
- # need to check that a second argument exists (else --> ErrorMessage).
- # ---should be either `random',
- # ---or a macroname for a rotation sequence,
- # ---or the first element of a rotation sequence.
-
- if ($data[1] eq "")
- { # no second argument
- gprint ("..*missing second argument");
- ErrorMessage ("QUITTING PERL PROGRAM --- missing second argument:");
- ErrorMessage ("--- ? bad rotation macro-name");
- quitprogram();
- };
-
-
-
- ##---------keyword = random-----------------
- ## (command used for scrambling the cube)
- ## if second argument in $dataline = random
- ## THEN we also need to check if third argument is an integer;
- ## if so send integer --> random sub.
-
- ##----------------------------
- ## (28 July 2017: RWDN) : bugfix:
- ## better syntax checking required for the <random,n> command
- ## as spaces before or after commas caused errors.
- ##-----------------------------
-
-
- ## allow upper and lowercase keyword random
- if ( lc( $data[1] ) =~ m/random/ )
- {
- ## the string contains the keyword random
-
- ## now check for missing comma after the keyword
- if ( lc( RemoveAllSpaces($data[1]) ) ne "random" )
- {## error, ? missing comma
- ErrorMessage("[$data[1]] --- missing comma after `random' ");
- next LINE;
- };
-
- ## now check for the trailing integer
-
- if ( ( lc( RemoveAllSpaces($data[1]) ) eq "random") and ($data[2] eq "") )
- {
- ## missing integer
- ErrorMessage("[$data[2]] --- missing integer after `random,'");
- next LINE;
- };
-
-
- if (RemoveAllSpaces($data[2]) =~ /\D/)
- {
- ## Note that the \D operator sees , 23, as a word not an integer.
- ## so if true then cannot be a number (D matches word and space elements)
- ErrorMessage("[$data[2]] --- this is not an integer");
- next LINE;
- }
- else {## string consists of one or more integers
- ## check to see if more than one integer exists
- ## by seeing if the string changes if we remove all the spaces
- ## (note we have to use a string with the m operator)
- my $RAS = RemoveAllSpaces($data[2]);
- if ($data[2] =~ m/$RAS/ )
- {
- ## OK so this must be a single integer
- ## so we can now do n random rotations
- ## by sending the integer to the random SUB
- random($data[2]);
- next LINE;
- }
- else {## there must be spaces separating several integers;
- ErrorMessage("[$data[2]] --- only one integer allowed");
- next LINE;
- };
- }; ## end of else
- } ## end of IF
- ##-----------------------------------------------------------
-
- else {
- ## -----rotation sequence---------
- ## the line must be a rotation sequence line, so send the sequence
- # to the rotation sub;
-
- # Note that a copy of the rotation command is already held in the
- # variable rotationcommand (see above). It is used in the
- # ErrorMessage SUB.
-
-
- #----<infoblocks>---------------------------
-
- # infoblocks are strings bounded by angle brackets <..>
- # and are designed for holding metadata.
- #
- # Multiple comma separated infoblocks are allowed (but NOT nested).
- # All infoblocks are eventually concaternated into a colon separated string, and
- # returned into the OUT file (= rubikstateNEW.dat) as the macro \SequenceInfo.
- #
- # We process and then remove any infoblocks which exist.
- # infoblocks are chars delimited by <...>
- #
- # The SUB infoblockcolon replaces any commas with a colon (so as to
- # facilitate string manipulation, and allows us to distinguish between
- # a string and a data array), and returns a new string (= $newdataline).
- #
- # The RubikRotation argument allows <infoblocks> for carrying special
- # keywords, eg <inverse> which can be used to influence the process.
- # If several infoblocks exist, then we collect the contents into
- # variable SequenceInfo, and separate them with a colon;
- #
- # The SUB cutinfoblock returns TWO strings:
- # (1) the name of the new revised string = newdataline, (with infoblocks removed)
- # (2) the contents of the infoblock = $SequenceInfo
-
-
- infoblockcolon($dataline);
-
- ## rename the returned newdataline string to dataline
- ## and reinitialise the string newdataline so it can be used again.
- $dataline=$newdataline;
- $newdataline=""; ## reset the variable
-
-
- gprint ("...dataline = $dataline");
-
-
- ## now pass the string to cutinfoblock
- local @seq=();
-
-
- while ( (index $dataline, '<') !=-1 ){
-
- cutinfoblock($dataline);
- # best to use the whole word <inverse> to avoid errors
- # best to force lowercase so users can type the word as they want
-
- if ( lc($SequenceInfo) =~ m/(inverse)/) {
- ## set a FLAG
- $directionflag=$inverse;
- print " FLAG set to = $inverse\n";
- };
- # append each infoblock to an array
- push @seq, $SequenceInfo;
- $dataline = $newdataline;
- };
-
- # finally, we join the seqInfo array into a string so we can print it
- $SequenceInfo = join ("; ", @seq);
-
-
-
- #--------repeat blocks--------------------------
-
- ## there are now no more infoblocks, so we now look for repeat-blocks.
- ## these are embedded inside the rotation sequence
-
- ## we first reformulate any repeat blocks (,) --> {;} if they exist
- ## this is to allow us to process any repeat blocks as separate elements
- ## so we look for curved brackets ie indicating a repeat block, and
- ## if we find a ( we then send the dataline to the SUB fixrepeatelement()
- ## the SUB fixrepeatelement() then returns the new revised dataline string
- ## containing the FIRST repeat block which has been expanded.
- ## If there is another ( then we repeat the procedure until all
- ## repeat blocks have been expanded, and incorporated into the mail rotation string.
-
- while ( (index $dataline, '(') !=-1 ){
- fixrepeatelement ($dataline);
- $dataline=$newdataline;
- $newdataline=""; ## reset the variable
- };
-
- ## rename remaining dataline string as SequenceShortBrace
- ## since if there are any repeat blocks, they are now reformulated with braces and semicolons
- ## ie (,) --> {;} etc
- $SequenceShortBrace=$dataline;
-
-
- ## clean leading and trailing whitespace
- $SequenceShortBrace = cleanstring($SequenceShortBrace);
-
- ##----------------
- ## form a new array from $SequenceShortBrace (since we have changed the format
- ## slightly; ie some commands may have been reformulated as semicolons).
- @data=split (/,/, $SequenceShortBrace);
-
-
- ## need to remove keyword <rotation> (= first element in the array)
- ## removing it late like this is convenient for error checking purposes,
- ## as then the keyword `rotation' is on the string
- shift (@data);
-
-
-
- ## now need to recreate the string from the array @data for use later
- ## (as rotation keyword has been removed)
-
- $SequenceShortBrace = join (",", @data);
-
-
- #-----create SequenceShort, so we can output it later----
-
- # since the `rotating' keyword has been removed from the string,
- # we can replace (repair to original state) any braces or or semicolons
- # around repeat strings (if exist) and then rename it as SequenceShort
- # which we will output at the end (in SUB writestate).
-
- if ( (index $SequenceShortBrace, '{') !=-1 )
- {
- print " repairing braces and semicolon--> ()\n";
- ## swap: BBook p 138--139
- $SequenceShortBrace =~ tr/\{/(/; # swap { --> (
- $SequenceShortBrace =~ tr/\}/)/; # swap } --> )
- $SequenceShortBrace =~ tr/;/,/; # swap ; --> ,
- };
-
- #rename to SequenceShort
- $SequenceShort = $SequenceShortBrace;
-
- print " SequenceShort = $SequenceShort\n";
- ##----------------------------
-
-
- ## now we continue processing the array "data"
-
- my $n = 0; ##total no of array elements in "data"
- $n = ($#data +1);
- print " processing rotation arguments: = @data (n= $n)\n";
-
-
-
- ## --------check for state of direction flag----------------------
- ## FLAG defined in line 224.
- ## FLAG is set in line 400 on detecting <..> delimeters = infoblock
- ## if flag set (by inverse keyword) then reverse the sequence array
- if ( $directionflag eq $inverse){
- # FLAG is set, so we need to inverse the array
- gprint ("...directionFLAG set; reversing array...");
- # but before reversing, look at the first array element
- # to see if it is a square bracket element = NAME element
- # so check the first char to see if it is [
- if (substr ($data[0], 0,1) eq '[') {
- $SequenceName=$data[0];
- print " SequenceName (inv) = $SequenceName \n";
- };
-
- @data = reverse @data;
- print " processing rotation arguments: = @data (n= $n)\n";
- };
-
- # send each rotation element to the sub rotation()
- print " CALLing SUB rotation\n";
-
- foreach $element (@data) {
- ## clean leading and trailing white space
- $element = cleanstring($element);
- ## send element to rotation SUB
- rotation($element);
- };
-
- } # end of else
- }; # end of IF ( re: rotation keyword)
-
- #----------------------------------------------
- ## place any new keywords for processing here
- ##---------------------------------------------
-
- }; ## end of while
-
- ## we have now finished reading in all the lines from the source file,
- ## and processing all the rotations etc,
- ## so we now just write the new cube state
- ## to the output file = TeX_OUT_FILE (so LaTeX can read it)
- ## plus any ErrorMessages
- ## -- all these are handled by the quitprogram sub
-
- quitprogram();
-
-##==============end of main==========================
-
- sub rotation {
-
-
-print " SUB rotation\n";
-
- ## here we process the array @data (from main) consisting of all
- ## the rotation commands associated with
- ## a single RubikRotation command -- the `rotation' key word has already been removed
- ## so we start here with [name] if it exists.
-
- ##---------------------------
- ## variables used in SUBs rotation() and rubikmod()
- ## need to be defined outside the SUBs
-
- $modnumber=-1; #multiple associated with the char, eg D2 etc
- $rotcode="";
- $rotnumber=0;
- #------------------
- my @repeatcode = ();
-
- my $m=-1;
- my $originalrcode="";
- my $j; ## used with m below
- my $numberofchars; ## length of a string
- my $nfrontchars;
-
- ##-----------------
-
- ## grab the rotation code passed to this sub from MAIN
- my $rcode = $_[0];
-
-
- ## now we start a big loop processing each cs-element (= rcode),
- ## and collecting these elements into two cs-strings
- ## ($Sequence --> original string output as SHORT string (has codes like R2,L3 etc),
- ## and $rotationseqNEW --> output as LONG string -- all short codes expanded)
-
-
- ## first, clean leading and trailing white space (eg between, R ,)
- $rcode = cleanstring($rcode);
-
-
- ## grab a copy of the element (char) for use if m Mod4=0
- $originalrcode=$rcode;
-
-
- ## increment the LOOP counter
- ## (initialised using <our> in MAIN = line 226)
- ## for use in the rotation SUB.
- ## This counter is used to identify the first element (rcode)
- ## and used to grab [name] --> SequenceName.
- $jrcode=$jrcode+1; ## increment rotation element (char) counter
-
-
- ## -----check for [nameblocks]-----------------------------
- ##
- ## We look at the first character of each element in the sequence
- ## if an element has a leading [ then it is a label (not a rotation)
- ## If this is the case, then jump to next element in the array
-
- ## BUT if trailing comma is missing, then (error as next rotation will be included
- ## as part of the label) so need to trap this and
- ## make the test: is first AND last char a sq bracket?
- ## (strictly only need to look at /first/ char, as the early syntax check will have
- ## detected any unbalanced brackets already)
-
- if ( (substr ($rcode,0,1) =~ /\[/) and (substr ($rcode,-1) ) =~ /\]/) {
-
- gprint ("...$rcode is a label OK");
-
- if ($directionflag eq $inverse) {
- # do nothing
- }
-
- else{
- ## if this `label' is also the FIRST element, then label = nameblock
- if ($jrcode ==1) {$SequenceName=$rcode};
- }; # end of IF
-
- ## now get next rotation element
- next;
- }; ## end of if
-
- ##--------------
-
-
- ## the rcode must therefore be either a rotation code or a repeat-block.
-
- ##-------check for (repeatblocks)---------------------------------
- ##
- ## we have already replaced any repeat chars (,) with {;}
- ## so we now check for elements with leading { and then expand them
- ## the appropriate number of times.
- ## Note that the actual expansion is done by SUB repeat()
-
- ## Note that if there is NO comma before the {} of a {repeat block}, then
- ## the true repeat block will not be recognised by the
- ## usual test -- since the test is looking for a leading { etc.
- ## However, in this event, the string being handled (not a true element)
- ## will be processed as if it were a rotation, and an
- ## error will be thrown, so it will get picked up OK.
-
- if (substr ($rcode,0,1) =~ /\{/ )
- {
- print " repeat block found = $rcode \n";
-
- ## since we now want to send each rotation element in the repeat block to
- ## the rotation sub, we need to replace any ; with commas
- ## therefore translate ; --> , but retain the {}
- $rcode =~ tr/;/,/;
-
- print " repeat block reformulated = $rcode \n";
-
-
- #-------log file message--------
- ## log file: we want to show the repeat string in the users original form
- ## so we translate it back to the user's orig form {,} --> (,)
- $origrcode=$rcode;
- $origrcode =~ tr/\{/(/;
- $origrcode =~ tr/\}/)/;
- gprint ("...Expanding: $origrcode ...");
- #-------------
-
-
- #-----------
- ## expand the code in the repeat block
- print " CALLing SUB: repeat($rcode)\n";
-
- repeat($rcode); # this expands the repeated elements in the block
-
- ## this sub returns the expanded form as $insert
- $expanded_repeatcode=$insert;
-
- print " expanded_repeatcode = $expanded_repeatcode\n\n";
- #------------
-
- #----------------
- # process each new element in the expanded_repeatcode --> rotation
- # make expanded_repeatcode into an array, and send each element on
-
- @repeatcode = split (/,/, $expanded_repeatcode) ;
-
-
- ## -----------check for direction flag-----------------
- ## if flag set then reverse the array
- if ( $directionflag eq $inverse){@repeatcode = reverse @repeatcode};
-
-
- # send each element to rotation SUB for processing
- print " CALLing SUB rotation\n";
- foreach $E (@repeatcode) {
- print " sending repeat element $E to rotation SUB\n";
- rotation($E)
- };
-
- # when this foreach is finished, then get next rotation element from
- # the original @data array (see foreach.. near end of MAIN)
- next;
-
- }; ## end of if
-
- ##================================
-
- ## if an element has got this far, it must be a single rotation code
- ## (maybe with a trailing digit), so it needs processing as a rotation
- ## and appending the code to what will become the SequenceLONG string.
-
- ##------------------------
-
- ## CALL the sub rubikmod to process the rotation element,
- ## and to return the front code (= $rotcode), orig no = $rotnumber,
- ## and mod4 value (= $modnumber).
-
- rubikmod($rcode);
-
- ## update rcode <--- rotcode (returned by the SUB rubikmod() )
- ## collect $m <--- modnumber (returned by the SUB rubikmod() )
- $rcode = $rotcode;
- $m = $modnumber;
-
- ## we collect all the new versions of rcode into a cs-string = $SequenceLong
- ## which will finally be output as the LONG string
-
-#-----------------------
-# check with directionflag
- if ($directionflag eq $inverse) {$rcode = inverse ($rcode)};
-#-------------------------
-
- ##--------------------
- if ( $m == 0 )
- {
- ## do NOT implement the rotation code, and do NOT append to SequenceLong
- ## print the /original/ rcode (eg R4, or D0 etc)
- gprint ("..*rotation ,$originalrcode, ERROR ($rotnumber = 0 mod 4) not implemented");
- ErrorMessage(",$originalrcode, -- ($rotnumber = 0 mod 4) not implemented");
- next;
- };
-
- if ( $m == 1 )
- {
- if($rotnumber >=5)
- {gprint ("...Expanding $originalrcode ($rotnumber = $m mod 4) ...")};
- $SequenceLong=$SequenceLong.$rcode.",";
- }
- else {
- # m = 2 or 3
- if($rotnumber >=5)
- {gprint ("...Expanding $originalrcode ($rotnumber = $m mod 4) ...")}
- else {gprint ("...Expanding $originalrcode ...")};
-
- for($j=1; $j<=$m; $j++)
- {## append rcode m times to sequenceLONG
- $SequenceLong=$SequenceLong.$rcode.","
- };
- }; ## end of else
-
- ##-------------------
-
- ## if single trailing digit present,
- ## then we implement the rotation command m times.
- ## if more than one trailing digit
- ## then the error is trapped at the end (as frontstring will not be recognised
- ## ie will not be in the following list, and hence will be trapped as an error, eg R3)
-
-
-
-##-----------------------
-## RWDN Sept29 2017 testing to fix WESTERN notation problem
-## arrange for user to be able to include <western> in metadata etc
-## -- as this will mean that one can store these algorithms as a macro
-
- if ( lc($SequenceInfo) =~ m/(western)/ ) {
-
- if ($rcode eq "l") {$rcode = "Lw"; gprint ("...WESTERN NOTATION: rotation l --> Lw, OK") };
- if ($rcode eq "lp") {$rcode = "Lwp"; gprint ("...WESTERN NOTATION: rotation lp --> Lwp, OK") };
- if ($rcode eq "r") {$rcode = "Rw"; gprint ("...WESTERN NOTATION: rotation r --> Rw, OK") };
- if ($rcode eq "rp") {$rcode = "Rwp"; gprint ("...WESTERN NOTATION: rotation rp --> Rwp, OK") };
- if ($rcode eq "f") {$rcode = "Fw"; gprint ("...WESTERN NOTATION: rotation f --> Fw, OK") };
- if ($rcode eq "fp") {$rcode = "Fwp"; gprint ("...WESTERN NOTATION: rotation fp --> Fwp, OK") };
- if ($rcode eq "b") {$rcode = "Bw"; gprint ("...WESTERN NOTATION: rotation b --> Bw, OK") };
- if ($rcode eq "bp") {$rcode = "Bwp"; gprint ("...WESTERN NOTATION: rotation bp --> Bwp, OK") };
- if ($rcode eq "u") {$rcode = "Uw"; gprint ("...WESTERN NOTATION: rotation u --> Uw, OK") };
- if ($rcode eq "up") {$rcode = "Uwp"; gprint ("...WESTERN NOTATION: rotation up --> Uwp, OK") };
- if ($rcode eq "d") {$rcode = "Dw"; gprint ("...WESTERN NOTATION: rotation d --> Dw, OK") };
- if ($rcode eq "dp") {$rcode = "Dwp"; gprint ("...WESTERN NOTATION: rotation dp --> Dwp, OK") };
-
- };
-##-----------------------
-
-
-
- if ($rcode eq "L") {for($j=1;$j<=$m;$j++) {gprint ("...rotation L, OK (= Lp3)"); &rrL}}
- elsif ($rcode eq "Lp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Lp, OK"); &rrLp}}
- elsif ($rcode eq "Lw") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Lw, OK (= Lp3 + Srp)"); &rrLw}}
- elsif ($rcode eq "Lwp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Lwp, OK (= Lp + Sr)"); &rrLwp}}
- elsif ($rcode eq "Ls") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Ls, OK (= L + Rp)"); &rrLs}}
- elsif ($rcode eq "Lsp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Lsp, OK (= Lp + R)"); &rrLsp}}
- elsif ($rcode eq "La") {for($j=1;$j<=$m;$j++) {gprint ("...rotation La, OK (= L + R)"); &rrLa}}
- elsif ($rcode eq "Lap") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Lap, OK (= Lp + Rp)"); &rrLap}}
- ####
- elsif ($rcode eq "R") {for($j=1;$j<=$m;$j++) {gprint ("...rotation R, OK"); &rrR}}
- elsif ($rcode eq "Rp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Rp, OK (= R3)"); &rrRp}}
- elsif ($rcode eq "Rw") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Rw, OK (= R + Sr)"); &rrRw}}
- elsif ($rcode eq "Rwp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Rwp, OK (= Rp + Srp)"); &rrRwp}}
- elsif ($rcode eq "Rs") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Rs, OK (= R + Lp)"); &rrRs}}
- elsif ($rcode eq "Rsp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Rsp, OK (= Rp + L)"); &rrRsp}}
- elsif ($rcode eq "Ra") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Ra, OK (= R + L)"); &rrRa}}
- elsif ($rcode eq "Rap") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Rap, OK (= Rp + Lp)"); &rrRap}}
- ####
- elsif ($rcode eq "U") {for($j=1;$j<=$m;$j++) {gprint ("...rotation U, OK"); &rrU}}
- elsif ($rcode eq "Up") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Up, OK (= U3)"); &rrUp}}
- elsif ($rcode eq "Uw") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Uw, OK (= U + Su)"); &rrUw}}
- elsif ($rcode eq "Uwp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Uwp, OK (= Up + Sup)"); &rrUwp}}
- elsif ($rcode eq "Us") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Us, OK (= U + Dp)"); &rrUs}}
- elsif ($rcode eq "Usp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Usp, OK (= Up + D)"); &rrUsp}}
- elsif ($rcode eq "Ua") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Ua, OK (= U + D)"); &rrUa}}
- elsif ($rcode eq "Uap") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Uap, OK (= Up + Dp)"); &rrUap}}
- ####
- elsif ($rcode eq "D") {for($j=1;$j<=$m;$j++) {gprint ("...rotation D, OK (= Dp3)"); &rrD}}
- elsif ($rcode eq "Dp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Dp, OK "); &rrDp}}
- elsif ($rcode eq "Dw") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Dw, OK (= Dp3 + Sup)"); &rrDw}}
- elsif ($rcode eq "Dwp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Dwp, OK (= Dp + Su)"); &rrDwp}}
- elsif ($rcode eq "Ds") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Ds, OK (= D + Up)"); &rrDs}}
- elsif ($rcode eq "Dsp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Dsp, OK (= Dp + U)"); &rrDsp}}
- elsif ($rcode eq "Da") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Da, OK (= D + U)"); &rrDa}}
- elsif ($rcode eq "Dap") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Dap, OK (= Dp + Up)"); &rrDap}}
- ####
- elsif ($rcode eq "F") {for($j=1;$j<=$m;$j++) {gprint ("...rotation F, OK"); &rrF}}
- elsif ($rcode eq "Fp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Fp, OK (= F3)"); &rrFp}}
- elsif ($rcode eq "Fw") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Fw, OK (= F + Sf)"); &rrFw}}
- elsif ($rcode eq "Fwp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Fwp, OK (= Fp + Sfp)"); &rrFwp}}
- elsif ($rcode eq "Fs") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Fs, OK (= F + Bp)"); &rrFs}}
- elsif ($rcode eq "Fsp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Fsp, OK (= Fp + B)"); &rrFsp}}
- elsif ($rcode eq "Fa") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Fa, OK (= F + B)"); &rrFa}}
- elsif ($rcode eq "Fap") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Fap, OK (= Fp + Bp)"); &rrFap}}
- ####
- elsif ($rcode eq "B") {for($j=1;$j<=$m;$j++) {gprint ("...rotation B, OK (= Fp3)"); &rrB}}
- elsif ($rcode eq "Bp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Bp, OK"); &rrBp}}
- elsif ($rcode eq "Bw") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Bw, OK (= Fp3 + Sfp)"); &rrBw}}
- elsif ($rcode eq "Bwp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Bwp, OK (= Fp + Sf)"); &rrBwp}}
- elsif ($rcode eq "Bs") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Bs, OK (= B + Fp)"); &rrBs}}
- elsif ($rcode eq "Bsp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Bsp, OK (= Bp + F)"); &rrBsp}}
- elsif ($rcode eq "Ba") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Ba, OK (= B + F)"); &rrBa}}
- elsif ($rcode eq "Bap") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Bap, OK (= Bp + Fp)"); &rrBap}}
-
- #### --------------------------------------
-
- #### inner-slice (= middle slice)
- ## need to include MES (middle slice) notation
- elsif ($rcode eq "M") {for($j=1;$j<=$m;$j++) {gprint ("...rotation M, OK (= Sl) "); &rrSl}}
- elsif ($rcode eq "Mp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Mp, OK (= Sr) "); &rrSr}}
- elsif ($rcode eq "E") {for($j=1;$j<=$m;$j++) {gprint ("...rotation E, OK (= Sd) "); &rrSd}}
- elsif ($rcode eq "Ep") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Ep, OK (= Su) "); &rrSu}}
- elsif ($rcode eq "S") {for($j=1;$j<=$m;$j++) {gprint ("...rotation S, OK (= Sf) "); &rrSf}}
- elsif ($rcode eq "Sp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sp, OK (= Sb) "); &rrSb}}
-
- #### middle slice rotations (Singmaster)
- elsif ($rcode eq "Su") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Su, OK "); &rrSu}}
- elsif ($rcode eq "Sup") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sup, OK (= Su3)"); &rrSup}}
- elsif ($rcode eq "Sd") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sd, OK (= Sup)"); &rrSd}}
- elsif ($rcode eq "Sdp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sdp, OK (= Su)"); &rrSdp}}
- elsif ($rcode eq "Sl") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sl, OK (= Srp)"); &rrSl}}
- elsif ($rcode eq "Slp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Slp, OK (= Sr)"); &rrSlp}}
- elsif ($rcode eq "Sr") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sr, OK"); &rrSr}}
- elsif ($rcode eq "Srp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Srp, OK (= Sr3)"); &rrSrp}}
- elsif ($rcode eq "Sf") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sf, OK"); &rrSf}}
- elsif ($rcode eq "Sfp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sfp, OK (= Sf3)"); &rrSfp}}
- elsif ($rcode eq "Sb") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sb, OK (= Sfp)"); &rrSb}}
- elsif ($rcode eq "Sbp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation Sbp, OK (= Sf)"); &rrSbp}}
-
- ## need to include Jaap Puzzles website for middle slice notation (Lm, Lmp)
- ## also include Randelshofer website middle slice notation (ML,MLp..)
-
- elsif ($rcode eq "ML" or $rcode eq "MRp" or $rcode eq "Lm" or $rcode eq "Rmp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Lm = M = Sl) "); &rrSl}}
-
- elsif ($rcode eq "MR" or $rcode eq "MLp" or $rcode eq "Rm" or $rcode eq "Lmp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Rm = Mp = Sr) "); &rrSr}}
-
- elsif ($rcode eq "MU" or $rcode eq "MDp" or $rcode eq "Um" or $rcode eq "Dmp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Um = Ep = Su) "); &rrSu}}
-
- elsif ($rcode eq "MD" or $rcode eq "MUp" or $rcode eq "Dm" or $rcode eq "Ump")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Dm = E = Sd) "); &rrSd}}
-
- elsif ($rcode eq "MF" or $rcode eq "MBp" or $rcode eq "Fm" or $rcode eq "Bmp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Fm = S = Sf) "); &rrSf}}
-
- elsif ($rcode eq "MB" or $rcode eq "MFp" or $rcode eq "Bm" or $rcode eq "Fmp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Bm = Sp = Sb) "); &rrSb}}
- ##----------------------------------
-
- #### double outer slice (wide) notation
- #### need to include Randelshofer TL, TLp double outer slice notation
- #### (equiv to the w wide notation)
- elsif ($rcode eq "TL") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TL, OK (= Lw = Lp3 + Srp)"); &rrLw}}
- elsif ($rcode eq "TLp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TLp, OK (= Lwp = Lp + Sr)"); &rrLwp}}
- elsif ($rcode eq "TR") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TR, OK (= Rw = R + Sr)"); &rrRw}}
- elsif ($rcode eq "TRp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TRp, OK (= Rwp = Rp + Srp)"); &rrRwp}}
- elsif ($rcode eq "TU") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TU, OK (= Uw = U + Su)"); &rrUw}}
- elsif ($rcode eq "TUp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TUp, OK (= Uwp = Up + Sup)"); &rrUwp}}
- elsif ($rcode eq "TD") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TD, OK (= Dw = Dp3 + Sup)"); &rrDw}}
- elsif ($rcode eq "TDp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TDp, OK (= Dwp = Dp + Su)"); &rrDwp}}
- elsif ($rcode eq "TF") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TF, OK (= Fw = F + Sf)"); &rrFw}}
- elsif ($rcode eq "TFp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TFp, OK (= Fwp = Fp + Sfp)"); &rrFwp}}
- elsif ($rcode eq "TB") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TB, OK (= Bw = Fp3 + Sfp)"); &rrBw}}
- elsif ($rcode eq "TBp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation TBp, OK (= Bwp = Fp + Sf)"); &rrBwp}}
-
-
- ## ---------------------------
- ## opposite slice notation of Randelshofer (SR, SRp) (= standard Rs, Rsp)
- ## opposite outer slices rotated in SAME direction as the FACE
-
- elsif ($rcode eq "SL") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Ls = L + Rp)"); &rrLs}}
- elsif ($rcode eq "SLp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Lsp = Lp + R)"); &rrLsp}}
-
- elsif ($rcode eq "SR") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Rs = R + Lp)"); &rrRs}}
- elsif ($rcode eq "SRp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Rsp = Rp + L)"); &rrRsp}}
-
- elsif ($rcode eq "SU") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Us = U + Dp)"); &rrUs}}
- elsif ($rcode eq "SUp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Usp = Up + D)"); &rrUsp}}
-
- elsif ($rcode eq "SD") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Ds = D + Up)"); &rrDs}}
- elsif ($rcode eq "SDp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Dsp = Dp + U)"); &rrDsp}}
-
-
- elsif ($rcode eq "SF") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Fs = F + Bp)"); &rrFs}}
- elsif ($rcode eq "SFp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Fsp = Fp + B)"); &rrFsp}}
-
- elsif ($rcode eq "SB") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Bs = B + Fp)"); &rrBs}}
- elsif ($rcode eq "SBp") {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= Bsp = Bp + F)"); &rrBsp}}
-
-
- ## -------------------------
-
- ## whole cube rotations
- ## need to include x,y,z (upper and lowercase) and also u,d,l,r,f,b (lowercase only) equivalents
- elsif ($rcode eq "X" or $rcode eq "x" or $rcode eq "r" or $rcode eq "lp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= x = R + Sr + Lp)"); &rrR;&rrSr;&rrLp}}
- elsif ($rcode eq "Xp" or $rcode eq "xp" or $rcode eq "l" or $rcode eq "rp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= xp = Rp + Srp + L)");&rrRp;&rrSrp;&rrL}}
- elsif ($rcode eq "Y" or $rcode eq "y" or $rcode eq "u" or $rcode eq "dp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= y = U + Su + Dp)"); &rrU;&rrSu;&rrDp}}
- elsif ($rcode eq "Yp" or $rcode eq "yp" or $rcode eq "d" or $rcode eq "up")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= yp = Up + Sup + D)");&rrUp;&rrSup;&rrD}}
- elsif ($rcode eq "Z" or $rcode eq "z" or $rcode eq "f" or $rcode eq "bp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= z = F + Sf + Bp)"); &rrF;&rrSf;&rrBp}}
- elsif ($rcode eq "Zp" or $rcode eq "zp" or $rcode eq "b" or $rcode eq "fp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode, OK (= zp = Fp + Sfp + B)");&rrFp;&rrSfp;&rrB}}
-
- ## more whole cube notation
- ## need to include Jaap website whole cube Lc notation
- ## also include Randelshofer C notation (CL, CLp.)
-
- elsif ($rcode eq "CL" or $rcode eq "CRp" or $rcode eq "Lc" or $rcode eq "Rcp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Lc = xp = Rp + Srp + L)");&rrRp;&rrSrp;&rrL}}
-
- elsif ( $rcode eq "CR" or $rcode eq "CLp" or $rcode eq "Rc" or $rcode eq "Lcp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Rc = x = R + Sr + Lp)"); &rrR;&rrSr;&rrLp}}
-
- elsif ($rcode eq "CU" or $rcode eq "CDp" or $rcode eq "Uc" or $rcode eq "Dcp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Uc = y = U + Su + Dp)"); &rrU;&rrSu;&rrDp}}
-
- elsif ($rcode eq "CD" or $rcode eq "CUp" or $rcode eq "Dc" or $rcode eq "Ucp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Dc = yp = Up + Sup + D)");&rrUp;&rrSup;&rrD}}
-
- elsif ($rcode eq "CF" or $rcode eq "CBp" or $rcode eq "Fc" or $rcode eq "Bcp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Fc = z = F + Sf + Bp)"); &rrF;&rrSf;&rrBp}}
-
- elsif ($rcode eq "CB" or $rcode eq "CFp" or $rcode eq "Bc" or $rcode eq "Fcp")
- {for($j=1;$j<=$m;$j++) {gprint ("...rotation $rcode OK (= Bc = zp = Fp + Sfp + B)");&rrFp;&rrSfp;&rrB}}
-
- ## -----------------------------
-
- ## check empty string --> missing rotation
- elsif ($rcode eq "") {for($j=1;$j<=$m;$j++)
- {
- gprint ("..*rotation ,$rcode, ERROR ? typo or missing rotation");
- ErrorMessage(",$rcode, -- ? typo or missing rotation");
- }
- }
- ## finally ----------------------
- else {
- ## to fall this far then the rotation (char) must be undefined
- ## but before we can send these rotation code strings out in ErrorMessages
- ## we need to check that they are in the original format.
- ## ie., do not have any {;} chars etc. If they do, then we need to
- ## translate them back, ie {;} --> (,) etc
-
- ## we use `originalcode' in the ErrorMessage because the user needs to be
- ## shown the `bad' code as it was originally input by the RubikRotation{} command.
-
-
- ## check for code with { ; } and restore to normal syntax
- if ( $rcode =~ m/(\{|;|\}|\])/ ) {
- $rcode = restorebrackets($rcode);
- $originalrcode = restorebrackets($originalrcode);
- };
-
-
- if ( $rcode =~ m/(\(|\)|\[|\])/) {
- gprint ("..*rotation $rcode ERROR -- code not known ? missing comma or nested brackets");
- ErrorMessage("$originalrcode -- code not known ? missing comma or nested brackets");
- ## DO NOT --> (next LINE;) here as need to check /all/ the rotation codes in the string.
- }
- else{
- gprint ("..*rotation $rcode ERROR -- code not known ? typo or missing comma");
- ErrorMessage("$originalrcode -- code not known ? typo or missing comma");
- ## DO NOT --> (next LINE;) here as need to check /all/ the rotation codes in the string.
- };
-
- #-----------------------------
- next;
- }; #end of else
-
- next;
- } # end of sub
-
-
-
-#======================================
-
- sub random {
-
-print " SUB random\n";
-
-
-## scramble randomly using n rotations
-## example command = RubikRotation{random,74}
-## if no n given (second argument = ""), then use default n=50
-## if second argument is some string (not integer) then --> ERROR
-##
-## assign numbers to the minimal set of rotations to be used using a hash array list
-## (perl 5 book page 68)
-## ? maybe we should only use the 18 rotations mentioned in Rokicki 2013 paper?
-## but here I have included all the slice (Xm) ones as well.
-
-
- ## initialise the array for the random rotations
- my @rrlist = ();
-
-
- ## (RWDN 2 Aug 2017):
- ## now check to see if TWOcube or Rubikcube being used
- ## use cubesize as the filter
-
- if ($cubesize eq 'two')
- {
- ## using the TwoRotation command (from RubikTwoCube.sty)
- ## no slice rotations
- ##
- @rrlist = ("U", "Up",
- "D", "Dp",
- "L", "Lp",
- "R", "Rp",
- "F", "Fp",
- "B", "Bp");
- }
-
- else {
- ## using the RubikRotation command (from RubikRotation.sty)
- @rrlist = ("U", "Up", "Um", "Ump",
- "D", "Dp", "Dm", "Dmp",
- "L", "Lp", "Lm", "Lmp",
- "R", "Rp", "Rm", "Rmp",
- "F", "Fp", "Fm", "Fmp",
- "B", "Bp", "Bm", "Bmp");
- };
-
-
-my $rrlistnumber=$#rrlist;
-print " rrlistnumber = $rrlistnumber\n";
- gprint ("...random SUB: rrlistnumber (array size) = $rrlistnumber");
-# these are numbered 0--$rrlistnumber,
-
-## let default no of random rotations for scrambling = 50
-my $defaultn = 50; ## RWDN (1 Aug 2017): not being used any more
-my $maxn = 200;
-
- ## grab the integer passed from the random() command in main
- my $s = $_[0];
-
- if ($s >= $maxn) {$s = $maxn;
- gprint ("..*WARNING: maximum n = 200");
- ErrorMessage ("random: max n = 200 (n=200 was used)")}
- elsif ($s == 0) {## $s = $defaultn;
- gprint ("..*ERR: integer n = 0 (invalid)");
- ErrorMessage (" --- integer n = 0 (invalid)");
- next LINE;
- };
-
- my @rr; ## array to hold all the random rotations
- print " randomising the available rotations\n";
-
-
- ## set the seed for the randomisation (Perl BlackBook p 235)
- srand;
-
-## now select s numbers at random (with replacement) from range 0--listnumber+1
-## Since we are using int(rand x), and using nos from 0--lastindex number,
-## then max rand vaue = (lastindexnumber -1).99999, the integer of which
-## = (lastindexnumber -1). Therefore we need to use the range 0--(lastindexnumber+1)
-## in order to randomise all posibilities on our list.
-
-my $j;
-
-for ($j = 1; $j <=$s; $j=$j+1)
- {
- my $p= int(rand ($rrlistnumber +1));
- print "Rotation = $p, $rrlist[$p] \n";
- ## push rotation code $rrlist[$p] on to END of array @rr
- push (@rr, $rrlist[$p]);
- };
-
- ## we assume the user is starting from a solved cube (ie use the state given by user)
- gprint ("...scrambling cube using $s random rotations");
-
- ## now send the array off to the rotation sub
-
- my $E;
-
- foreach $E (@rr) { rotation($E) };
-
- } ##end of sub
-
-
-#======================================
-
- sub writestate {
-
-print " SUB writestate\n";
-
-## this writes the final state to the TeX_OUT_FILE (= rubikstateNEW.dat) will be read by latex.
-
-print (TeX_OUT_FILE "\%\% ...output datafile=$out_file\n");
-print (TeX_OUT_FILE "\%\% ...PERL script=rubikrotation.pl version $version\n");
-print (TeX_OUT_FILE "\\typeout{...writing new cube state to file $out_file}\%\n");
-print (TeX_OUT_FILE "\\RubikFaceUp\{$Ult[0]\}\{$Umt[0]\}\{$Urt[0]\}\{$Ulm[0]\}\{$Umm[0]\}\{$Urm[0]\}\{$Ulb[0]\}\{$Umb[0]\}\{$Urb[0]\}\%\n");
-print (TeX_OUT_FILE "\\RubikFaceDown\{$Dlt[0]\}\{$Dmt[0]\}\{$Drt[0]\}\{$Dlm[0]\}\{$Dmm[0]\}\{$Drm[0]\}\{$Dlb[0]\}\{$Dmb[0]\}\{$Drb[0]\}\%\n");
-print (TeX_OUT_FILE "\\RubikFaceLeft\{$Llt[0]\}\{$Lmt[0]\}\{$Lrt[0]\}\{$Llm[0]\}\{$Lmm[0]\}\{$Lrm[0]\}\{$Llb[0]\}\{$Lmb[0]\}\{$Lrb[0]\}\%\n");
-print (TeX_OUT_FILE "\\RubikFaceRight\{$Rlt[0]\}\{$Rmt[0]\}\{$Rrt[0]\}\{$Rlm[0]\}\{$Rmm[0]\}\{$Rrm[0]\}\{$Rlb[0]\}\{$Rmb[0]\}\{$Rrb[0]\}\%\n");
-print (TeX_OUT_FILE "\\RubikFaceFront\{$Flt[0]\}\{$Fmt[0]\}\{$Frt[0]\}\{$Flm[0]\}\{$Fmm[0]\}\{$Frm[0]\}\{$Flb[0]\}\{$Fmb[0]\}\{$Frb[0]\}\%\n");
-print (TeX_OUT_FILE "\\RubikFaceBack\{$Blt[0]\}\{$Bmt[0]\}\{$Brt[0]\}\{$Blm[0]\}\{$Bmm[0]\}\{$Brm[0]\}\{$Blb[0]\}\{$Bmb[0]\}\{$Brb[0]\}\%\n");
-
-##-----RWDN 2016---create four new holder commands for separate strings----------
-
-## these four names are defined in the rubikrotation.sty file so they can be renewed etc
-## SequenceInfo
-## SequenceName
-## SequenceShort
-## SequenceLong
-
-
-## ----RWDN 25 Sept 2016 ----------------------
-## now remove the first and last chars of [name] to output just NAME without [ and ]
-
-## initialise some variables we shall need
- $numberofcharsinstring=0;
- $nmiddlecharsinstring=0;
-
-
-##----------SequenceName----------------------------
-
-## the SequenceName currently includes the [..]
-## need to remove the [] before senting it to LaTeX,
-## so need to detect when NAME string itself is empty, eg []
-## so create a variable:
- $SequenceNameNew="";
-
- $numberofcharsinstring = length $SequenceName;
-
-
-## NEED to create error message if [] and empty string etc
-
-if ($numberofcharsinstring <= 2)
- {$SequenceNameNew = $SequenceName}
- else {
-
- $nmiddlecharsinstring = ($numberofcharsinstring - 2);
- ## reassign the string without first and last chars
- ### format of substr = (origstring, start possn, no of chars to use)
- $SequenceNameNew = substr($SequenceName,1,$nmiddlecharsinstring);
- };
-
- ## RWDN 24 October 2017
- ## swap char changes back before writing output string
- ## only swap the brackets
- ## (do NOT swap ; --> , as ONLY use commas /outside/ infoblocks and between rotation sequences)
- ## swap: BBook p 138--139
-
- $SequenceNameNew =~ tr/\{/(/; # swap { --> (
- $SequenceNameNew =~ tr/\}/)/; # swap } --> )
-
-
-print (TeX_OUT_FILE "\\renewcommand\\SequenceName\{$SequenceNameNew\}\%\n");
-
-print (TeX_OUT_FILE "\\typeout{...SequenceName = $SequenceNameNew}\%\n");
-#-----------------
-
-
-
-#----------SequenceInfo----------------
-## we need to preserve any {} structures in the info string (as used by Kociemba),
-## so we have to change { } --> [ ] since otherwise they will disappear
-## or cause an error when printed in LaTeX
-
- $SequenceInfo=~ tr/\{/\[/; ## swap { --> [
- $SequenceInfo=~ tr/\}/\]/; ## swap } --> ]
-
-print (TeX_OUT_FILE "\\renewcommand\\SequenceInfo\{$SequenceInfo\}\%\n");
-
-print (TeX_OUT_FILE "\\typeout{...SequenceInfo = $SequenceInfo}\%\n");
-#-----------------
-
-
-
-##---------SequenceShort------------------
-## generated in MAIN
-## SequenceShort = original argument of \RubikRotation{} /without/ any infoblocks
-## therefore it may contain square brackets
-
-print (TeX_OUT_FILE "\\renewcommand\\SequenceShort\{$SequenceShort\}\%\n");
-
-print (TeX_OUT_FILE "\\typeout{...SequenceShort = $SequenceShort}\%\n");
-##-----------------------
-
-##-----------SequenceLong-------------------
-## now prepare the new LONG rotation sequence for output =(LONG sequence + NO NAME)
-## BUT before outputting the string, we need to remove the terminal comma
-
-$numberofcharsinstring = length $SequenceLong;
-$nfrontcharsinstring = $numberofcharsinstring -1;
-## reassign the string except the terminal comma
-$SequenceLong = substr($SequenceLong,0,$nfrontcharsinstring);
-
-
-#----------
-print (TeX_OUT_FILE "\\renewcommand\\SequenceLong\{$SequenceLong\}\%\n");
-
-print (TeX_OUT_FILE "\\typeout{...SequenceLong = $SequenceLong}\%\n");
-
-
-
-##-----------------------
-
-## now include any error messages generated
-## (these are all in an array waiting to be printed out)
-
- if ($erroralert eq "YES")
- {
- ## write errors to a separate file (just for errors---we append the errrors to end of file)
- ## the error file (rubikstateERRORS.dat) was created by the TeX file
- my $ne; #number of errors
- $ne=$#error; ## number of errors= largest index num since we started at zero
-
- ## do not attach error to a <checkstate> command, since we really want
- ## to see the checkstate errors (in the ERROR file) printed AFTER the `rotation' command.
- if ($rotationcommand eq "checkstate") {}
- else {print (ERROR_OUT_FILE "*ERR cmd= $rotationcommand\n") };
-
- ## last index number or array = $#arrayname (Black book p 62)
- my $k;
-
- for ($k=0; $k<=$ne; $k=$k+1) {
-
- ## restore correct brackets etc before outputting to Latex
- my $errorstring = $error[$k];
- $errorstring = restorebrackets($errorstring);
-
- print (TeX_OUT_FILE "\\typeout{$errorstring}\%\n");
- print (ERROR_OUT_FILE "$errorstring\n");
-
- }; # end of for
- }; # end of IF
- print " Perl output file written OK\n";
-
- } #end of sub
-
-
-#======================================
-
- sub ErrorMessage {
-
- ## writes the argument as a standard error message to out file
-
- my $errormess = $_[0]; ## parameter passed to sub
-
- ## restore correct brackets etc before outputting to Latex
- $errormess = restorebrackets($errormess);
-
- $erroralert = "YES"; ## set error alert flag (for use in out message)
- $error[$errornumber] = "*ERR $errormess";
- $errornumber++; ## increment number
- };
-
-
-#======================================
-
- sub gprint {
-
-## prints argument (comments) to screen and also to TeX_OUT_FILE.
-## The typeout commands will find its way into the log file when read by latex
-## Important to include trailing % for messages written to the TeX_OUT_FILE
-## to stop extra <spaces> being seen by TeX.
-
- my $gmess=$_[0];
- print "$gmess\n";
- print (TeX_OUT_FILE "\\typeout{$gmess}\%\n");
- };
-
-
-#======================================
-
- sub checkstate{
-
-print " SUB checkstate\n";
-
-## only a simple check -- to see if wrong no of colours being used etc
-## uses the cubie colours as used by rubikcube package= ROYGBWX
-
- gprint ("...checking state of cube");
-
- my @cubies=($Ult[0],$Umt[0],$Urt[0], $Ulm[0],$Umm[0],$Urm[0], $Ulb[0],$Umb[0],$Urb[0],
- $Dlt[0],$Dmt[0],$Drt[0], $Dlm[0],$Dmm[0],$Drm[0], $Dlb[0],$Dmb[0],$Drb[0],
- $Llt[0],$Lmt[0],$Lrt[0], $Llm[0],$Lmm[0],$Lrm[0], $Llb[0],$Lmb[0],$Lrb[0],
- $Rlt[0],$Rmt[0],$Rrt[0], $Rlm[0],$Rmm[0],$Rrm[0], $Rlb[0],$Rmb[0],$Rrb[0],
- $Flt[0],$Fmt[0],$Frt[0], $Flm[0],$Fmm[0],$Frm[0], $Flb[0],$Fmb[0],$Frb[0],
- $Blt[0],$Bmt[0],$Brt[0], $Blm[0],$Bmm[0],$Brm[0], $Blb[0],$Bmb[0],$Brb[0]);
-
- my $R=0,my $O=0,my $Y=0,my $G=0,my $B=0,my $W=0,my $X=0;
-
- my $cubiecolour = "";
-
- foreach $cubiecolour (@cubies)
- {
- if ($cubiecolour eq R) {$R = $R+1}
- elsif ($cubiecolour eq O) {$O = $O+1}
- elsif ($cubiecolour eq Y) {$Y = $Y+1}
- elsif ($cubiecolour eq G) {$G = $G+1}
- elsif ($cubiecolour eq B) {$B = $B+1}
- elsif ($cubiecolour eq W) {$W = $W+1}
- elsif ($cubiecolour eq X) {$X = $X+1}
- else {
- gprint ("..*cubie-colour counting ERROR");
- }
- };
-
- my $cubiesum=0;
- $cubiesum = $R+$O+$Y+$G+$B+$W+$X;
- gprint ("...cubiesum = $cubiesum (Red=$R, Or=$O, Ye=$Y, Gr=$G, Bl=$B, Wh=$W, X=$X)");
-
- # only generate ErrorMessages if n>9 (as may be using a Grey cube)
- if ($cubiesum != 54) {
- ErrorMessage ("cubiesum not = 54");
- gprint ("..*cubiesum not = 54") };
-
- if ($R >9){
- ErrorMessage("red cubies > 9 (=$R)");
- gprint ("..*red cubies > 9 (=$R)");
- };
-
- if ($O >9){
- ErrorMessage("orange cubies > 9 (=$O)");
- gprint ("..*orange cubies > 9 (=$O)");
- };
-
- if ($Y >9){
- ErrorMessage("yellow cubies > 9 (=$Y)");
- gprint ("..*yellow cubies > 9 (=$Y)");
- # next LINE
- };
-
- if ($G >9){
- ErrorMessage("green cubies > 9 (=$G)");
- gprint ("..*green cubies > 9 (=$G)");
- };
-
- if ($B >9){
- ErrorMessage("blue cubies > 9 (=$B)");
- gprint ("..*blue cubies > 9 (=$B)");
- };
-
- if ($W >9){
- ErrorMessage("white cubies > 9 (=$W)");
- gprint ("..*white cubies > 9 (=$W)");
- };
-
- if ($X == 54){
- ErrorMessage("no colours allocated (X=54)");
- gprint ("..*no colours allocated (X=54)") };
-
- print " done\n\n";
- };
-
-
-#======================================
-
-## Overview of rotation transform subs
-
-#======================================
-## The following 9 (90 degree) rotation transformations are used
-## to generate all the rotations used in the `rotation sub'
-## each of these is a permutation for both colours and numbers
-## of the cubie facelets.
-## The following 9 subroutines are named as follows:
-## (about X-axis) rrR, rrSr, rrLp
-## (about Y-axis) rrU, rrSu, rrDp
-## (about Z-axis) rrF, rrSf, rrBp
-## see the rubikcube package documentation for full details regarding
-## rotation notation and commands.
-## METHOD & NOTATION
-## each sub (below) starts by making an array[0] for the cubie colour
-## and an array[1] for the cubie number.
-## Each of the face rotations (rrR, rrLp, rrU, rrDp, rrF, rrBp) is involved with
-## two pairs of connected but different permutations/transformations as follows:
-## (a) one pair for the 12 Side cubies (arrays = @Xs0 (for Side colours), @Xs1 (for Side numbers)), and
-## (b) one pair for the 9 Face cubies (arrays = @Xf0 (for Face colours), @Xf1 (for Face numbers)).
-## Each of the middle slice rotations (rrSr, rrSu, rrSf) is involved with just one pair of
-## permutations for the 12 Side cubies (arrays = @Xs0 (for Side colours), @Xs1 (for Side numbers)).
-## We document only the side and face of the first sub (rrR) in detail, since
-## the other subs are of similar form.
-#======================================
-
-
-#======================================
-
- sub rrR {
-
-## the RIGHT (slice + face) transform
-## R = RIGHT, s = side; 0=colour, 1= number
-## make the clockwise rotation permutation
-## In this permutation the Front-right-bottom (Frb) (side)facelet rotates to
-## the new position of Up-right-bottom (Urb) (side)facelet.
-##-----------SIDE-------
-## 12 side cubie facelets in arrays @Rs0 (colours) and @Rs1 (numbers)
-## these are the initial positions
-
-@Rs0=($Frb[0],$Frm[0],$Frt[0],
- $Urb[0],$Urm[0],$Urt[0],
- $Blt[0],$Blm[0],$Blb[0],
- $Drb[0],$Drm[0],$Drt[0]);
-
-@Rs1=($Frb[1],$Frm[1],$Frt[1],
- $Urb[1],$Urm[1],$Urt[1],
- $Blt[1],$Blm[1],$Blb[1],
- $Drb[1],$Drm[1],$Drt[1]);
-
-## now we reallocate the initial array elements to the new
-## post (90 degree clockwise) rotation position.
-## Cube is viewed from FRONT.
-## Positions of side facelets of Right slice are numbered 0-11 in clockwise direction,
-## (as seen from Right face) starting with Up-right-bottom facelet.
-## First line example:
-## variable $Urb[0] (Upface-right-bottom colour) <-- colour of first element in @Rs0 (=Frb[0])
-## variable $Urb[1] (Upface-right-bottom number) <-- number of first element in @Rs1 (=Frb[1])
-
-$Urb[0]=$Rs0[0]; $Urb[1]=$Rs1[0];
-$Urm[0]=$Rs0[1]; $Urm[1]=$Rs1[1];
-$Urt[0]=$Rs0[2]; $Urt[1]=$Rs1[2];
-
-$Blt[0]=$Rs0[3]; $Blt[1]=$Rs1[3];
-$Blm[0]=$Rs0[4]; $Blm[1]=$Rs1[4];
-$Blb[0]=$Rs0[5]; $Blb[1]=$Rs1[5];
-
-$Drb[0]=$Rs0[6]; $Drb[1]=$Rs1[6];
-$Drm[0]=$Rs0[7]; $Drm[1]=$Rs1[7];
-$Drt[0]=$Rs0[8]; $Drt[1]=$Rs1[8];
-
-$Frb[0]=$Rs0[9]; $Frb[1]=$Rs1[9];
-$Frm[0]=$Rs0[10]; $Frm[1]=$Rs1[10];
-$Frt[0]=$Rs0[11]; $Frt[1]=$Rs1[11];
-
-##-------------Right FACE---------------------
-## RIGHT FACE (9 cubies in each array)
-## (numbered in rows: 1,2,3/4,5,6/7,8,9 from top left(1) to bottom right(9))
-## R=Right, f = face; 0=colour, 1= number
-## do the Rface (90 degree) rotation transform
-## here the Right-left-bottom (Rlb) facelet rotates to the possn of Right-left-top (Rlt)
-## we start with two arrays (one for colours @Rf0, one for numbers @Rf1) with 9 elements each.
-
-@Rf0=($Rlb[0], $Rlm[0], $Rlt[0], $Rmb[0], $Rmm[0], $Rmt[0], $Rrb[0], $Rrm[0], $Rrt[0]);
-@Rf1=($Rlb[1], $Rlm[1], $Rlt[1], $Rmb[1], $Rmm[1], $Rmt[1], $Rrb[1], $Rrm[1], $Rrt[1]);
-
-## now we reallocate the array elements to the new
-## post (90 degree clockwise) rotation facelet position.
-## Right face is viewed from RIGHT.
-## First line example:
-## variable $Rlt[0] (=Right-left-top colour) <-- colour of first element in @Rf0 (=Rlb[0])
-## variable $Rlt[1] (=Right-left-top number) <-- number of first element in @Rf1 (=Rlb[1])
-
-$Rlt[0]=$Rf0[0]; $Rlt[1]=$Rf1[0];
-$Rmt[0]=$Rf0[1]; $Rmt[1]=$Rf1[1];
-$Rrt[0]=$Rf0[2]; $Rrt[1]=$Rf1[2];
-
-$Rlm[0]=$Rf0[3]; $Rlm[1]=$Rf1[3];
-$Rmm[0]=$Rf0[4]; $Rmm[1]=$Rf1[4];
-$Rrm[0]=$Rf0[5]; $Rrm[1]=$Rf1[5];
-
-$Rlb[0]=$Rf0[6]; $Rlb[1]=$Rf1[6];
-$Rmb[0]=$Rf0[7]; $Rmb[1]=$Rf1[7];
-$Rrb[0]=$Rf0[8]; $Rrb[1]=$Rf1[8];
-
-}
-
-
-#======================================
-
- sub rrSr {
-
-## Sr = RIGHT middle SLICE rotation (only 12 side facelets)
-## modified from rrR (change the U,D,F, r --> m and Back Bl-->Bm; Rs--> ?Srs)
-## change only the slice
-## s = side; 0=colour, 1= number
-## make the post rotation permutation
-
-@SRs0=($Fmb[0],$Fmm[0],$Fmt[0],
- $Umb[0],$Umm[0],$Umt[0],
- $Bmt[0],$Bmm[0],$Bmb[0],
- $Dmb[0],$Dmm[0],$Dmt[0]);
-
-@SRs1=($Fmb[1],$Fmm[1],$Fmt[1],
- $Umb[1],$Umm[1],$Umt[1],
- $Bmt[1],$Bmm[1],$Bmb[1],
- $Dmb[1],$Dmm[1],$Dmt[1]);
-
-
-$Umb[0]=$SRs0[0]; $Umb[1]=$SRs1[0];
-$Umm[0]=$SRs0[1]; $Umm[1]=$SRs1[1];
-$Umt[0]=$SRs0[2]; $Umt[1]=$SRs1[2];
-
-$Bmt[0]=$SRs0[3]; $Bmt[1]=$SRs1[3];
-$Bmm[0]=$SRs0[4]; $Bmm[1]=$SRs1[4];
-$Bmb[0]=$SRs0[5]; $Bmb[1]=$SRs1[5];
-
-$Dmb[0]=$SRs0[6]; $Dmb[1]=$SRs1[6];
-$Dmm[0]=$SRs0[7]; $Dmm[1]=$SRs1[7];
-$Dmt[0]=$SRs0[8]; $Dmt[1]=$SRs1[8];
-
-$Fmb[0]=$SRs0[9]; $Fmb[1]=$SRs1[9];
-$Fmm[0]=$SRs0[10]; $Fmm[1]=$SRs1[10];
-$Fmt[0]=$SRs0[11]; $Fmt[1]=$SRs1[11];
-
-}
-
-
-#======================================
-
- sub rrLp {
-
-## LEFT slice (side + face) anticlockwise rotation
-## s = side; 0=colour, 1= number
-##-------------side-----------
-
-@LPs0=($Flb[0],$Flm[0],$Flt[0],
- $Ulb[0],$Ulm[0],$Ult[0],
- $Brt[0],$Brm[0],$Brb[0],
- $Dlb[0],$Dlm[0],$Dlt[0]);
-
-@LPs1=($Flb[1],$Flm[1],$Flt[1],
- $Ulb[1],$Ulm[1],$Ult[1],
- $Brt[1],$Brm[1],$Brb[1],
- $Dlb[1],$Dlm[1],$Dlt[1]);
-
-
-$Ulb[0]=$LPs0[0]; $Ulb[1]=$LPs1[0];
-$Ulm[0]=$LPs0[1]; $Ulm[1]=$LPs1[1];
-$Ult[0]=$LPs0[2]; $Ult[1]=$LPs1[2];
-
-$Brt[0]=$LPs0[3]; $Brt[1]=$LPs1[3];
-$Brm[0]=$LPs0[4]; $Brm[1]=$LPs1[4];
-$Brb[0]=$LPs0[5]; $Brb[1]=$LPs1[5];
-
-$Dlb[0]=$LPs0[6]; $Dlb[1]=$LPs1[6];
-$Dlm[0]=$LPs0[7]; $Dlm[1]=$LPs1[7];
-$Dlt[0]=$LPs0[8]; $Dlt[1]=$LPs1[8];
-
-$Flb[0]=$LPs0[9]; $Flb[1]=$LPs1[9];
-$Flm[0]=$LPs0[10]; $Flm[1]=$LPs1[10];
-$Flt[0]=$LPs0[11]; $Flt[1]=$LPs1[11];
-
-
-##---------------Left FACE-------------
-## do the LEFT face transform (in rows: 1,2,3//4,5,6//7,8,9)
-## f = face; 0=colour, 1= number
-## NOTES: not same as for R
-
-@LPf0=($Lrt[0], $Lrm[0], $Lrb[0], $Lmt[0], $Lmm[0], $Lmb[0], $Llt[0], $Llm[0], $Llb[0]);
-@LPf1=($Lrt[1], $Lrm[1], $Lrb[1], $Lmt[1], $Lmm[1], $Lmb[1], $Llt[1], $Llm[1], $Llb[1]);
-
-$Llt[0]=$LPf0[0]; $Llt[1]=$LPf1[0];
-$Lmt[0]=$LPf0[1]; $Lmt[1]=$LPf1[1];
-$Lrt[0]=$LPf0[2]; $Lrt[1]=$LPf1[2];
-
-$Llm[0]=$LPf0[3]; $Llm[1]=$LPf1[3];
-$Lmm[0]=$LPf0[4]; $Lmm[1]=$LPf1[4];
-$Lrm[0]=$LPf0[5]; $Lrm[1]=$LPf1[5];
-
-$Llb[0]=$LPf0[6]; $Llb[1]=$LPf1[6];
-$Lmb[0]=$LPf0[7]; $Lmb[1]=$LPf1[7];
-$Lrb[0]=$LPf0[8]; $Lrb[1]=$LPf1[8];
-
-}
-
-
-#======================================
-
- sub rrU {
-
-## UP slice (side + face)
-## do the Uside transform
-## s = side; 0=colour, 1= number
-## ----------SIDE--------------
-
-@Us0=($Lrt[0],$Lmt[0],$Llt[0],
- $Brt[0],$Bmt[0],$Blt[0],
- $Rrt[0],$Rmt[0],$Rlt[0],
- $Frt[0],$Fmt[0],$Flt[0]);
-
-@Us1=($Lrt[1],$Lmt[1],$Llt[1],
- $Brt[1],$Bmt[1],$Blt[1],
- $Rrt[1],$Rmt[1],$Rlt[1],
- $Frt[1],$Fmt[1],$Flt[1]);
-
-
-$Brt[0]=$Us0[0]; $Brt[1]=$Us1[0];
-$Bmt[0]=$Us0[1]; $Bmt[1]=$Us1[1];
-$Blt[0]=$Us0[2]; $Blt[1]=$Us1[2];
-
-$Rrt[0]=$Us0[3]; $Rrt[1]=$Us1[3];
-$Rmt[0]=$Us0[4]; $Rmt[1]=$Us1[4];
-$Rlt[0]=$Us0[5]; $Rlt[1]=$Us1[5];
-
-$Frt[0]=$Us0[6]; $Frt[1]=$Us1[6];
-$Fmt[0]=$Us0[7]; $Fmt[1]=$Us1[7];
-$Flt[0]=$Us0[8]; $Flt[1]=$Us1[8];
-
-$Lrt[0]=$Us0[9]; $Lrt[1]=$Us1[9];
-$Lmt[0]=$Us0[10]; $Lmt[1]=$Us1[10];
-$Llt[0]=$Us0[11]; $Llt[1]=$Us1[11];
-
-##-------------Up FACE-------------------
-## do the Rface transform (in rows: 1,2,3//4,5,6//7,8,9)
-## f = face; 0=colour, 1= number
-
-@Uf0=($Ulb[0], $Ulm[0], $Ult[0], $Umb[0], $Umm[0], $Umt[0], $Urb[0], $Urm[0], $Urt[0]);
-@Uf1=($Ulb[1], $Ulm[1], $Ult[1], $Umb[1], $Umm[1], $Umt[1], $Urb[1], $Urm[1], $Urt[1]);
-
-$Ult[0]=$Uf0[0]; $Ult[1]=$Uf1[0];
-$Umt[0]=$Uf0[1]; $Umt[1]=$Uf1[1];
-$Urt[0]=$Uf0[2]; $Urt[1]=$Uf1[2];
-
-$Ulm[0]=$Uf0[3]; $Ulm[1]=$Uf1[3];
-$Umm[0]=$Uf0[4]; $Umm[1]=$Uf1[4];
-$Urm[0]=$Uf0[5]; $Urm[1]=$Uf1[5];
-
-$Ulb[0]=$Uf0[6]; $Ulb[1]=$Uf1[6];
-$Umb[0]=$Uf0[7]; $Umb[1]=$Uf1[7];
-$Urb[0]=$Uf0[8]; $Urb[1]=$Uf1[8];
-
-}
-
-
-#======================================
-
- sub rrSu {
-
-## middle slice rotation (side only 12 facelets)
-## s = side; 0=colour, 1= number
-## make the post rotation permutation
-##-----------SIDE-------------------
-
-@SUs0=($Lrm[0],$Lmm[0],$Llm[0],
- $Brm[0],$Bmm[0],$Blm[0],
- $Rrm[0],$Rmm[0],$Rlm[0],
- $Frm[0],$Fmm[0],$Flm[0]);
-
-@SUs1=($Lrm[1],$Lmm[1],$Llm[1],
- $Brm[1],$Bmm[1],$Blm[1],
- $Rrm[1],$Rmm[1],$Rlm[1],
- $Frm[1],$Fmm[1],$Flm[1]);
-
-
-$Brm[0]=$SUs0[0]; $Brm[1]=$SUs1[0];
-$Bmm[0]=$SUs0[1]; $Bmm[1]=$SUs1[1];
-$Blm[0]=$SUs0[2]; $Blm[1]=$SUs1[2];
-
-$Rrm[0]=$SUs0[3]; $Rrm[1]=$SUs1[3];
-$Rmm[0]=$SUs0[4]; $Rmm[1]=$SUs1[4];
-$Rlm[0]=$SUs0[5]; $Rlm[1]=$SUs1[5];
-
-$Frm[0]=$SUs0[6]; $Frm[1]=$SUs1[6];
-$Fmm[0]=$SUs0[7]; $Fmm[1]=$SUs1[7];
-$Flm[0]=$SUs0[8]; $Flm[1]=$SUs1[8];
-
-$Lrm[0]=$SUs0[9]; $Lrm[1]=$SUs1[9];
-$Lmm[0]=$SUs0[10]; $Lmm[1]=$SUs1[10];
-$Llm[0]=$SUs0[11]; $Llm[1]=$SUs1[11];
-
-}
-
-
-#======================================
-
- sub rrDp {
-
-## Down Face anticlockwise rotation (side and face)
-## s = side; 0=colour, 1= number
-## make the post rotation permutation
-##--------------SIDE----------------
-
-@DPs0=($Lrb[0],$Lmb[0],$Llb[0],
- $Brb[0],$Bmb[0],$Blb[0],
- $Rrb[0],$Rmb[0],$Rlb[0],
- $Frb[0],$Fmb[0],$Flb[0]);
-
-@DPs1=($Lrb[1],$Lmb[1],$Llb[1],
- $Brb[1],$Bmb[1],$Blb[1],
- $Rrb[1],$Rmb[1],$Rlb[1],
- $Frb[1],$Fmb[1],$Flb[1]);
-
-$Brb[0]=$DPs0[0]; $Brb[1]=$DPs1[0];
-$Bmb[0]=$DPs0[1]; $Bmb[1]=$DPs1[1];
-$Blb[0]=$DPs0[2]; $Blb[1]=$DPs1[2];
-
-$Rrb[0]=$DPs0[3]; $Rrb[1]=$DPs1[3];
-$Rmb[0]=$DPs0[4]; $Rmb[1]=$DPs1[4];
-$Rlb[0]=$DPs0[5]; $Rlb[1]=$DPs1[5];
-
-$Frb[0]=$DPs0[6]; $Frb[1]=$DPs1[6];
-$Fmb[0]=$DPs0[7]; $Fmb[1]=$DPs1[7];
-$Flb[0]=$DPs0[8]; $Flb[1]=$DPs1[8];
-
-$Lrb[0]=$DPs0[9]; $Lrb[1]=$DPs1[9];
-$Lmb[0]=$DPs0[10]; $Lmb[1]=$DPs1[10];
-$Llb[0]=$DPs0[11]; $Llb[1]=$DPs1[11];
-
-##---------------Down FACE-------------------
-## f = face; 0=colour, 1= number
-
-@DPf0=($Dlt[0], $Dlm[0], $Dlb[0], $Dmt[0], $Dmm[0], $Dmb[0], $Drt[0], $Drm[0], $Drb[0]);
-@DPf1=($Dlt[1], $Dlm[1], $Dlb[1], $Dmt[1], $Dmm[1], $Dmb[1], $Drt[1], $Drm[1], $Drb[1]);
-
-$Dlb[0]=$DPf0[0]; $Dlb[1]=$DPf1[0];
-$Dmb[0]=$DPf0[1]; $Dmb[1]=$DPf1[1];
-$Drb[0]=$DPf0[2]; $Drb[1]=$DPf1[2];
-
-$Dlm[0]=$DPf0[3]; $Dlm[1]=$DPf1[3];
-$Dmm[0]=$DPf0[4]; $Dmm[1]=$DPf1[4];
-$Drm[0]=$DPf0[5]; $Drm[1]=$DPf1[5];
-
-$Dlt[0]=$DPf0[6]; $Dlt[1]=$DPf1[6];
-$Dmt[0]=$DPf0[7]; $Dmt[1]=$DPf1[7];
-$Drt[0]=$DPf0[8]; $Drt[1]=$DPf1[8];
-
-}
-
-
-#======================================
-
- sub rrF {
-
-## do the Fside transform (side and face)
-## s = side; 0=colour, 1= number
-## -----------SIDE-----------------
-
-@Fs0=($Lrb[0],$Lrm[0],$Lrt[0],
- $Ulb[0],$Umb[0],$Urb[0],
- $Rlt[0],$Rlm[0],$Rlb[0],
- $Drt[0],$Dmt[0],$Dlt[0]);
-
-@Fs1=($Lrb[1],$Lrm[1],$Lrt[1],
- $Ulb[1],$Umb[1],$Urb[1],
- $Rlt[1],$Rlm[1],$Rlb[1],
- $Drt[1],$Dmt[1],$Dlt[1]);
-
-$Ulb[0]=$Fs0[0]; $Ulb[1]=$Fs1[0];
-$Umb[0]=$Fs0[1]; $Umb[1]=$Fs1[1];
-$Urb[0]=$Fs0[2]; $Urb[1]=$Fs1[2];
-
-$Rlt[0]=$Fs0[3]; $Rlt[1]=$Fs1[3];
-$Rlm[0]=$Fs0[4]; $Rlm[1]=$Fs1[4];
-$Rlb[0]=$Fs0[5]; $Rlb[1]=$Fs1[5];
-
-$Drt[0]=$Fs0[6]; $Drt[1]=$Fs1[6];
-$Dmt[0]=$Fs0[7]; $Dmt[1]=$Fs1[7];
-$Dlt[0]=$Fs0[8]; $Dlt[1]=$Fs1[8];
-
-$Lrb[0]=$Fs0[9]; $Lrb[1]=$Fs1[9];
-$Lrm[0]=$Fs0[10]; $Lrm[1]=$Fs1[10];
-$Lrt[0]=$Fs0[11]; $Lrt[1]=$Fs1[11];
-
-## -------Front FACE-------------------
-## f = face; 0=colour, 1= number
-
-@Lf0=($Flb[0], $Flm[0], $Flt[0], $Fmb[0], $Fmm[0], $Fmt[0], $Frb[0], $Frm[0], $Frt[0]);
-@Lf1=($Flb[1], $Flm[1], $Flt[1], $Fmb[1], $Fmm[1], $Fmt[1], $Frb[1], $Frm[1], $Frt[1]);
-
-$Flt[0]=$Lf0[0]; $Flt[1]=$Lf1[0];
-$Fmt[0]=$Lf0[1]; $Fmt[1]=$Lf1[1];
-$Frt[0]=$Lf0[2]; $Frt[1]=$Lf1[2];
-
-$Flm[0]=$Lf0[3]; $Flm[1]=$Lf1[3];
-$Fmm[0]=$Lf0[4]; $Fmm[1]=$Lf1[4];
-$Frm[0]=$Lf0[5]; $Frm[1]=$Lf1[5];
-
-$Flb[0]=$Lf0[6]; $Flb[1]=$Lf1[6];
-$Fmb[0]=$Lf0[7]; $Fmb[1]=$Lf1[7];
-$Frb[0]=$Lf0[8]; $Frb[1]=$Lf1[8];
-
-}
-
-
-#======================================
-
- sub rrSf {
-
-## do the FRONT middle slice Fm transform (side only)
-## s = side; 0=colour, 1= number
-##----------SIDE---------------
-
-@SFs0=($Lmb[0],$Lmm[0],$Lmt[0],
- $Ulm[0],$Umm[0],$Urm[0],
- $Rmt[0],$Rmm[0],$Rmb[0],
- $Drm[0],$Dmm[0],$Dlm[0]);
-
-@SFs1=($Lmb[1],$Lmm[1],$Lmt[1],
- $Ulm[1],$Umm[1],$Urm[1],
- $Rmt[1],$Rmm[1],$Rmb[1],
- $Drm[1],$Dmm[1],$Dlm[1]);
-
-$Ulm[0]=$SFs0[0]; $Ulm[1]=$SFs1[0];
-$Umm[0]=$SFs0[1]; $Umm[1]=$SFs1[1];
-$Urm[0]=$SFs0[2]; $Urm[1]=$SFs1[2];
-
-$Rmt[0]=$SFs0[3]; $Rmt[1]=$SFs1[3];
-$Rmm[0]=$SFs0[4]; $Rmm[1]=$SFs1[4];
-$Rmb[0]=$SFs0[5]; $Rmb[1]=$SFs1[5];
-
-$Drm[0]=$SFs0[6]; $Drm[1]=$SFs1[6];
-$Dmm[0]=$SFs0[7]; $Dmm[1]=$SFs1[7];
-$Dlm[0]=$SFs0[8]; $Dlm[1]=$SFs1[8];
-
-$Lmb[0]=$SFs0[9]; $Lmb[1]=$SFs1[9];
-$Lmm[0]=$SFs0[10]; $Lmm[1]=$SFs1[10];
-$Lmt[0]=$SFs0[11]; $Lmt[1]=$SFs1[11];
-}
-
-
-#======================================
-
- sub rrBp {
-
-## Back rotation anticlockwise (side + face)
-## do the Bp side transform
-## s = side; 0=colour, 1= number
-## --------------Side-----------------
-
-@BPs0=($Llb[0],$Llm[0],$Llt[0],
- $Ult[0],$Umt[0],$Urt[0],
- $Rrt[0],$Rrm[0],$Rrb[0],
- $Drb[0],$Dmb[0],$Dlb[0]);
-
-@BPs1=($Llb[1],$Llm[1],$Llt[1],
- $Ult[1],$Umt[1],$Urt[1],
- $Rrt[1],$Rrm[1],$Rrb[1],
- $Drb[1],$Dmb[1],$Dlb[1]);
-
-$Ult[0]=$BPs0[0]; $Ult[1]=$BPs1[0];
-$Umt[0]=$BPs0[1]; $Umt[1]=$BPs1[1];
-$Urt[0]=$BPs0[2]; $Urt[1]=$BPs1[2];
-
-$Rrt[0]=$BPs0[3]; $Rrt[1]=$BPs1[3];
-$Rrm[0]=$BPs0[4]; $Rrm[1]=$BPs1[4];
-$Rrb[0]=$BPs0[5]; $Rrb[1]=$BPs1[5];
-
-$Drb[0]=$BPs0[6]; $Drb[1]=$BPs1[6];
-$Dmb[0]=$BPs0[7]; $Dmb[1]=$BPs1[7];
-$Dlb[0]=$BPs0[8]; $Dlb[1]=$BPs1[8];
-
-$Llb[0]=$BPs0[9]; $Llb[1]=$BPs1[9];
-$Llm[0]=$BPs0[10]; $Llm[1]=$BPs1[10];
-$Llt[0]=$BPs0[11]; $Llt[1]=$BPs1[11];
-
-##-----------------Back FACE-------------
-## do the B face transform (in rows: 1,2,3/4,5,6/7,8,9)
-## f = face; 0=colour, 1= number
-
-@BPf0=($Brb[0], $Brm[0], $Brt[0], $Bmb[0], $Bmm[0], $Bmt[0], $Blb[0], $Blm[0], $Blt[0]);
-
-@BPf1=($Brb[1], $Brm[1], $Brt[1], $Bmb[1], $Bmm[1], $Bmt[1], $Blb[1], $Blm[1], $Blt[1]);
-
-$Brt[0]=$BPf0[0]; $Brt[1]=$BPf1[0];
-$Bmt[0]=$BPf0[1]; $Bmt[1]=$BPf1[1];
-$Blt[0]=$BPf0[2]; $Blt[1]=$BPf1[2];
-
-$Brm[0]=$BPf0[3]; $Brm[1]=$BPf1[3];
-$Bmm[0]=$BPf0[4]; $Bmm[1]=$BPf1[4];
-$Blm[0]=$BPf0[5]; $Blm[1]=$BPf1[5];
-
-$Brb[0]=$BPf0[6]; $Brb[1]=$BPf1[6];
-$Bmb[0]=$BPf0[7]; $Bmb[1]=$BPf1[7];
-$Blb[0]=$BPf0[8]; $Blb[1]=$BPf1[8];
-}
-
-
-#======================================
-
-
-#======================================
-
-## Overview of derivative transform subs
-
-#======================================
-
-##---------------------------------------------
-## Note that we have defined (as rotation SUBs above) just 9 primary rotation transforms:
-## (x axis): rrR, rrSr, rrLp
-## (y axis): rrU, rrSu, rrDp
-## (z axis): rrF, rrSf, rrBp
-## and since all remaining possible rotations are simply combinations of these 9
-## we now define all the other rotation subs in terms of these 9 primary rotations.
-## Do NOT use multiples here: write each rotation separately
-## ----------------
-## NB: the Sr, Su, Sf are the middle slice rotations (= Rm, Um, Fm respectively)
-## (the `m' notation is much more intuitive than the S., but too late to change notation now)
-## -------------
-
-## ----derivative subs from R and Sr and Lp----
-sub rrRp{&rrR;&rrR;&rrR}; # (=rrR3)
-sub rrRw{&rrR; &rrSr}; # (= rrR + rrSr)
-sub rrRwp{&rrR;&rrR;&rrR; &rrSr;&rrSr;&rrSr}; # (= rrRp + rrSrp)
-sub rrRs{&rrR;&rrLp};
-sub rrRsp{&rrRp;&rrL};
-sub rrRa{&rrR;&rrL};
-sub rrRap{&rrRp;&rrLp};
-
-## ---------------------
-sub rrL{&rrLp;&rrLp;&rrLp}; # (= rrLp3)
-sub rrLw{&rrLp;&rrLp;&rrLp;&rrSrp}; # (=rrLp3 + rrSrp)
-sub rrLwp{&rrLp;&rrSr};
-sub rrLs{&rrL;&rrRp};
-sub rrLsp{&rrLp;&rrR};
-sub rrLa{&rrL;&rrR};
-sub rrLap{&rrLp;&rrRp};
-
-## ----derivative subs from U ----
-sub rrUp{&rrU;&rrU;&rrU}; # (=rrU3)
-sub rrUw{&rrU;&rrSu}; #
-sub rrUwp{&rrUp;&rrSup};
-sub rrUs{&rrU;&rrDp};
-sub rrUsp{&rrUp;&rrD};
-sub rrUa{&rrU;&rrD};
-sub rrUap{&rrUp;&rrDp};
-
-## ---------------------
-sub rrD{&rrDp;&rrDp;&rrDp}; # (= rrDp3)
-sub rrDw{&rrDp;&rrDp;&rrDp;&rrSup}; # (=rrDp3 + rrSup)
-sub rrDwp{&rrDp;&rrSu};
-sub rrDs{&rrD;&rrUp};
-sub rrDsp{&rrDp;&rrU};
-sub rrDa{&rrD;&rrU};
-sub rrDap{&rrDp;&rrUp};
-
-## ----derivative subs from F ----
-sub rrFw{&rrF; &rrSf}; # (= rrF + rrSf)
-sub rrFp{ &rrF;&rrF;&rrF}; # (=rrF3)
-sub rrFwp{&rrF;&rrF;&rrF; &rrSf;&rrSf;&rrSf}; # (= rrF3 + rrSf3)
-sub rrFs{&rrF;&rrBp};
-sub rrFsp{&rrFp;&rrB};
-sub rrFa{&rrF;&rrB};
-sub rrFap{&rrFp;&rrBp};
-
-## ---------------------
-sub rrB{&rrBp;&rrBp;&rrBp}; # (= rrBp3)
-sub rrBw{&rrBp;&rrBp;&rrBp; &rrSfp}; # (=rrBp3 + rrSfp)
-sub rrBwp{&rrBp;&rrSf};
-sub rrBs{&rrB;&rrFp};
-sub rrBsp{&rrBp;&rrF};
-sub rrBa{&rrB;&rrF};
-sub rrBap{&rrBp;&rrFp};
-
-## ----bring all the S versions together ----
-sub rrSup{&rrSu;&rrSu;&rrSu}; # (=rrSu3)
-sub rrSd{&rrSup}; # (=rrSup)
-sub rrSdp{&rrSu}; # (=rrSu)
-sub rrSl{&rrSrp}; # (=rrSrp)
-sub rrSlp{&rrSr}; # (=rrSr)
-sub rrSrp{&rrSr;&rrSr;&rrSr}; # (=rrSr3)
-sub rrSfp{&rrSf;&rrSf;&rrSf}; # (=rrSf3)
-sub rrSb{&rrSfp}; # (=rrSfp)
-sub rrSbp{&rrSf}; # (=rrSf)
-
-
-
-#======================================
-
- sub rubikmod {
-
- ## for MODifying (MOD 4)
-print " SUB rubikmod\n";
- ## passing one RotationElement as a parameter, & return a modified one
- ## make local variables
-
-
- my $rot="";
- my $lencode="";
- my $char="";
- my $m4=-1;
- my $num=-1;
- my $p=0;
-
-
- # grab the parameter string
- # $code = @_[0];
- $code = $_[0]; ## Perl says this is better
-
- $lencode=length $code;
-
- ## we want to split the code string into the front (Rubikcode) and terminal number
- ## so grab 1 char sequentially starting from the end of the string
- ## and identify the position of the first non-digit char we get to
- ## example: $lastchar = substr $code,-1,1 ;
- for ($p=-1; $p>-$lencode-1; $p=$p-1){
- $char = substr $code,$p,1 ;
- if ($char =~ /\d/) {}
- else{
- ## this char is the first non-digit from the end"
- ## its position = $p
- last;
- };
- };
-
- ## now use the value of $p to split the code string
- ## into front part (= $rot) and back part (= $num)
-
- ## get $rot
- $rot = substr $code, 0, ($lencode + $p + 1);
-
- ## get $num
- $num = substr $code, $lencode +$p +1, ($lencode -(length $rot));
-
- ##--------------
- ## if no number at all (eg D) then this Rubikcode needs to be implemented just once
- ## so allocate its num to have value = 1
-
- ## if ($num == ""){$num=1}; ## BUT this gives an ErrorMessage when num="" etc
- ## so I have rewritten [if numlength --> 0 then..] then it works OK
-
- $numlength = ($lencode -(length $rot));
- if ($numlength == 0) {$num=1};
- ##---------------------
-
- ## determine mod 4 of the value num
- $m4 = $num % 4;
-
- ## now return the results
- $rotcode=$rot;
- $rotnumber=$num; ## we return this so we can use it as a check
- $modnumber=$m4;
-
- return $rotcode, $rotnumber, $modnumber;
-
- } #end of sub
-
-
-#======================================
-
- sub cleanstring {
-
- # to clean leading and trailing whitespace from a string
- # from Black Book page 147
-
- my $line="";
-
- $line = $_[0]; # copied from my RubikMOD()
-
- #clean leading & trailing whitespace
-
- $line =~ s/^\s+//; ## clean leading whitespace
- $line =~ s/\s+$//; ## clean trailing whitespace
-
- return $line;
- }
-
-
-#======================================
-
- sub cutinfoblock {
-
- ## remove each <infoblock> if any exists
-
- ## pass the whole dataline
-
- print " SUB cutinfoblock\n";
-
- my $dataline = $_[0];
-
- ## we know all brackets are balanced - as this has been checked already.
-
- print " dataline = $dataline\n";
- my $Langle=0;
- my $Rangle=0;
- my $angleblock="";
- my $lenangleblock=0;
-
- ## first see if there is a terminal infoblock
- $Langle = index $dataline, '<'; ## <
- $Rangle = index $dataline, '>'; ## <
- $lenangleblock = $Rangle - $Langle +1;
-
- ##-----------------
- ## angleblock is the whole block <...> including both angles
- ## check both angles exist
- if ( ($Langle !=-1) and ($Rangle !=-1) )
- {
-
- my $angleblock = substr ($dataline, $Langle, $lenangleblock);
- print " infoblock(s) present: first = $angleblock\n";
-
- my $lenangleblock = length $angleblock;
- my $lendataline = length $dataline;
-
-
- # now need to remove the infoblock from $dataline
- # need to get front and back strings
- my $frontstring="";
- my $newfrontstring="";
- my $backstring="";
-
- $lenbackstring= $lendataline - $Rangle -1;
- $frontstring = substr ($dataline,0, $Langle); # string before Langle
- $backstring = substr ($dataline,$Rangle +1); # string beyond Rangle
-
- print " Langle possn = $Langle\n";
- print " Rangle possn = $Rangle\n";
- print " lenangleblock (diff + 1) = $lenangleblock\n";
- print " lendataline = $lendataline\n";
- print " lenbackstring = $lenbackstring\n";
- print " frontstring = $frontstring\n";
-
- #remove the terminal comma from front string
- $newfrontstring = substr($frontstring, 0, $Langle -1);
- print " new frontstring = $newfrontstring\n";
- print " backstring = $backstring\n";
-
- ##-------
- # remove angleblock from dataline (join front and back strings)
- $newdataline =$newfrontstring.$backstring;
-
- $SequenceInfo = substr ($angleblock, 1, $lenangleblock -2);
-
- print " new dataline = $newdataline\n";
- print " SequenceInfo = $SequenceInfo\n";
- print " newdataline = $newdataline\n";
- print " done\n\n";
-
- return $SequenceInfo, $newdataline;
- }
-
- else{
- # no infoblock, so need to make newdataline same as orig dataline
- $newdataline=$dataline;
- print " no <infoblock> to remove.\n\n";
- return $newdataline;
- };
- #-----------------
-
-
- } ## end of sub
-
-
-#======================================
-
- sub fixrepeatelement {
-
- print " SUB fixrepeatelement\n";
-
- print " reformatting any repeat elements...\n";
-
- ## this sub replaces ,-->; and (--> { and ) --> } for the repeat element
- ## and inserts it back into the original rotation sequence, where it now
- ## appears as a separate rotation element.
-
- my $repeatstring="";
- my $lenrepeatstring="";
- my $newrepeatstring="";
- my $frontstring="";
- my $backstring="";
- my $p=0;
- my $q=0;
- my $len = 0;
- my $k1=0;
- my $k2 = 0;
-
-
- ## pass the whole dataline without the keyword
- my $dataline = $_[0]; # copied from my RubikMOD()
-
-
- $p = index $dataline, '(';
- $q = index $dataline, ')';
-
- print " p = $p, q = $q\n";
-
-
- $lenrepeatstring = $q -$p +1 ;
- $repeatstring = substr ($dataline, $p, $lenrepeatstring);
-
- print " first repeat string = $repeatstring\n";
- print " length of repeat string = $lenrepeatstring\n";
-
- ## translate the chars
- $repeatstring =~ tr/,/;/; ## swap , --> ; Black book page 138--139
- $repeatstring =~ tr/\(/\{/; ## swap ( --> {
- $repeatstring =~ tr/\)/\}/; ## swap ) --> }
-
- $newrepeatstring = $repeatstring;
-
- print "...new repeat string = $newrepeatstring\n";
-
- #------------
- $k1=$p; #start of cut
- $k2= $p + $lenrepeatstring; #end of cut
- $frontstring = substr ($dataline,0, $k1);
- $backstring = substr ($dataline,$k2);
- print " frontstring = $frontstring\n";
- print " backstring = $backstring\n";
-
- # add insert
- $newdataline =$frontstring.$newrepeatstring.$backstring;
- print " new dataline = $newdataline\n";
-
-
- print " done\n\n";
-
- } # end of sub
-
-
-#======================================
-
- sub repeat {
-
- print " SUB repeat\n";
-
- ## this SUB expand the repeating elements
- ## this SUB receives a repeat string in the form {L,R, }3
- ## The original () were converted (above) into {} so we can distinguish the brackets.
- ## we than extract the code sequence and the terminal repeat number
- ## Then we join n copies of the code string to form a long cs string.
- ## then we insert this new long string into the main rotation sequence without the {}
- ## Ultimately the fully expanded rotation sequence is fed into SUB rotation for processing.
-
-
-
- ## grab the whole repeatstring = {...}n
- my $repeatstring = $_[0];
-
- # the string ={code}n
- # get the code sequence and the terminal digit
-
- my $p=0;
- my $q=0;
- my $repeatnumber=0;
- my $repeatcode="";
- my $lenrepeatcode =0;
-
- $p = index $repeatstring, '{';
- $q = index $repeatstring, '}';
- $lenrepeatcode = $q - $p -1;
-
-
-
- $repeatcode = substr ($repeatstring,1,$lenrepeatcode);
- print " repeatcode = $repeatcode\n"; ## correct
-
-
- $lenrepeatstring= length $repeatstring;
-
-
- print " lenrepeatstring = $lenrepeatstring\n";
- print " lenrepeatcode = $lenrepeatcode\n";
- print " p = $p\n";
- print " q = $q\n";
-
- ##-----------------------
- ## now get the repeat number
-
- if ($lenrepeatcode == ($lenrepeatstring-2)) {
- print " there is no trailing number --> 1\n";
- $repeatnumber=1;
- print " set repeatnumber = $repeatnumber\n";
- }
- else{
- $repeatnumber= substr ($repeatstring, $q + 1); # correct
- print " repeatnumber = $repeatnumber\n";
-
- ## need to check that repeatnumber is a valid integer
- if ($repeatnumber =~ /\D/){
- # not a valid number
-
- ## renormalise brackets etc before outputting to LaTeX
- $repeatnumber= restorebrackets($repeatnumber);
-
- gprint ("..*repeat-no. ERROR: $repeatnumber not numeric");
- ErrorMessage ("repeat-no. $repeatnumber not numeric ?missing comma or nested ()");
- };
-
- }; #end of else
- ##-------------------
-
- ## now make n copies of repeatcode and name the string = $insert
- ## (which is then used by another part of the prog)
- ## we need commas only between elements (not at end)
-
- $insert=""; ## $insert = global
- $insert=$repeatcode;
- for ($t=1; $t < $repeatnumber; $t=$t+1) {$insert=$insert.",".$repeatcode};
-
- print " insert = $insert\n";
- print " done\n\n";
-
- } # end sub
-
-
-#======================================
-
- sub quitprogram {
-
- ## exiting the program cleanly
- print " closing down: writing state...\n";
- writestate(); ## write to the output files
- close; ## close all files
- exit;
- }
-
-
-#======================================
-
- sub showarray {
-
- # show the array as a string
-
- my @newarray = @_; # copied from my RubikMOD()
- my $arraystring= join (",",@newarray);
- print " the array = *$arraystring*\n\n";
- }
-
-
-#======================================
-
- sub cleanarray {
-
- # cleans array elements of leading and trailing whitespace
-
- my @cleanset=();
- my @line = @_;
- my $E;
-
- foreach $E (@line) {
- $E =~ s/^\s+//; ## clean leading whitespace
- $E =~ s/\s+$//; ## clean trailing whitespace
- push @cleanset, $E;
- };
-
- return @cleanset;
-
-}
-
-
-#======================================
-
- sub restorebrackets {
-
- my $line = $_[0];
-
- ## translate the chars
- $line =~ tr/;/,/; ## swap , --> ; Black book page 138--139
- $line =~ tr/\{/\(/; ## swap ( --> {
- $line =~ tr/\}/\)/; ## swap ) --> }
-
- return $line;
-
-}
-
-
-#======================================
-
- sub infoblockcolon {
-
- print "...SUB InfoblockColon\n";
-
- ## pass the whole dataline without the keyword
- my $line = $_[0]; # copied from my RubikMOD()
-
- if ( (index $line, '<' ) == -1) {
- # no infoblock, so need to make newdataline same as orig dataline
- print " no <infoblock> found.\n\n";
- $newdataline=$dataline;
- return $newdataline;
- }
- else{
- print " infoblock(s) present\n";
-
- print " start-string = $line\n";
-
- # look at each char
- my $j=0;
- my $char="";
-
- my $lenstring = 0;
- $lenstring= length $line;
-
- # set initial state of inout-flag
- my $inoutflag="outside";
-
- #------------------------
- for ($j=0; $j<=$lenstring; $j=$j+1) {
- $char = substr ($line,$j,1);
-
- if ( ($char eq ',') and ($inoutflag eq 'inside')) {
- # replace the char with ;
- substr ($line, $j, 1, ";");
- print " colon-string = $line\n";
- };
-
- ## need these at end of the loop
- if ($char eq '<'){$inoutflag = "inside"};
- if ($char eq '>'){$inoutflag = "outside"};
-
- }; # end of for
-
- #---------------------------
-
- # -- repeat for [ ] brackets------
- $inoutflag="outside";
-
- for ($j=0; $j<=$lenstring; $j=$j+1) {
- $char = substr ($line,$j,1);
-
- if ( ($char eq ',') and ($inoutflag eq 'inside')) {
- # replace the char with ;
- substr ($line, $j, 1, ";");
- print " colon-string = $line\n";
- };
-
- ## need these at end of the loop
- if ($char eq '['){$inoutflag = "inside"};
- if ($char eq ']'){$inoutflag = "outside"};
-
- }; # end of for
-
-
- #----------------------------------
- ## make an array from the string so we can manipulate the elements
- our @linedata=();
- @linedata= split (/,/, $line);
-
-#----------clean the array-------
- my $E;
- my @cleandata=();
-
- foreach $E (@linedata) {
- $E =~ s/^\s+//; ## clean leading whitespace
- $E =~ s/\s+$//; ## clean trailing whitespace
- push @cleandata, $E;
- };
-
- print " colon-array = @cleandata\n";
-
-#=================
-
-# Because <infoblocks> can be located inside curved brackets
-# as for example, (\sixspot)2, [\sixspot macro contains an infoblock].
-# Consequently, we need to remove
-# the <..> blocks as parts of a string, not as elements in an array.
-# --otherwise, removing the terminal infoblock associated with \sixspot
-# will result in also removing the right-hand curved bracket --> error.
-# So we return the data as a string, and then send it to sub cutinfoblock later.
-
- $newdataline = join (",", @cleandata);
- print "...done\n\n";
-
- return $newdataline;
-
- } ## end of else
- } ## end of sub
-
-
-#======================================
-
- sub RemoveAllSpaces {
-
- # remove all spaces in a string
- # from Black book page 143
-
- my $string=$_[0];
-
- $string =~ s/\s//g; # OK
-
- return $string;
-
-}
-
-#======================================
-
-sub CheckSyntax {
-
- ## this check is used at an early stage in the program, so we can terminate early
- ## if necessary. We check that all () {} <> are matched (if any exist),
- ## missing commas, illegal combinations of chars etc.
- ## if any serious errors (eg brackets not balanced), then we SET an errorflag,
- ## and terminate the program.
-
- print " SUB CheckSyntax\n";
-
- my $dataline = $_[0];
-
- ## first clean out all spaces in a string
- ## so we can then look for specific combinations of characters
- $dataline=RemoveAllSpaces($dataline);
-
- print " dataline = $dataline\n";
-
- ##-------------------------------------
- ## first we check for unbalanced brackets
- ## count brackets; Angle, Square, Curved
- my ($nleftA, $nrightA) = 0;
- my ($nleftS, $nrightS) = 0;
- my ($nleftC, $nrightC) = 0;
- my ($leftsum, $rightsum) =0;
-
- ## Blackbook p 139 - counting chars in a string
- $nleftA = ($dataline =~ tr/</</);
- $nrightA = ($dataline =~ tr/>/>/);
-
- $nleftS = ($dataline =~ tr/[/[/);
- $nrightS = ($dataline =~ tr/]/]/);
-
- $nleftC = ($dataline =~ tr/(/(/);
- $nrightC = ($dataline =~ tr/)/)/);
-
- print " left and right <> = $nleftA, $nrightA\n";
- print " left and right [] = $nleftS, $nrightS\n";
- print " left and right () = $nleftC, $nrightC\n";
-
- $leftsum = $nleftA + $nleftS + $nleftC;
- $rightsum =$nrightA + $nrightS + $nrightC;
-
- print " leftsum, rightsum = $leftsum, $rightsum\n";
-
-
- my $errorflag = "";
-
- if ($leftsum != $rightsum)
- {
-
- if ( $nleftS != $nrightS )
- ## Square brackets
- {
- gprint ("..*brackets ERROR [ ] Left [$nleftS not equal to Right ]$nrightS");
- ErrorMessage ("brackets [ ]: Left [$nleftS not equal to Right ]$nrightS");
- $errorflag="SET";
- }
-
- if ( $nleftC != $nrightC )
- ## Curved brackets
- {
- gprint ("..*brackets ERROR ( ) Left ($nleftC not equal to Right )$nrightC");
- ErrorMessage ("brackets ( ): Left ($nleftC not equal to Right )$nrightC");
- $errorflag="SET";
- }
-
- if ( $nleftA != $nrightA )
- ## Angle brackets
- {
- gprint ("..*brackets ERROR < > Left <$nleftA not equal to Right >$nrightA");
- ErrorMessage ("brackets < >: Left <$nleftA not equal to Right >$nrightA");
- $errorflag="SET";
- }
-
- };
-
- ##--------------------------
-
-
-
- ## check for other bad syntax, eg illegal pairings of characters
- ## BlackBook p136
-
- my ($char1, $char2, $charpair) = "";
- my ($j, $lenstring) = 0;
- $lenstring= length $dataline;
- print " lenstring = $lenstring\n";
-
-
- ## we set up a system which allows us to know whether or not we are
- ## inside a set of brackets. To do this we increment / decrement counters
- ## each time we pass through a bracket.
- ## If sum NOT equal to zero, then we are inside etc.
-
- ## first initialise each left and right variable.
- ## seems important that these initialisations are done separately.
-
- my $angleNumLeft = 0;
- my $angleNumRight = 0;
- my $angleNumSum = 0;
-
- my $squareNumLeft = 0;
- my $squareNumRight = 0;
- my $squareNumSum = 0;
-
- my $curvedNumLeft = 0;
- my $curvedNumRight = 0;
- my $curvedNumSum = 0;
-
-
- ## look at each char, and each pair of chars
- ## with brackets, we increment (right) and decrement (left) the count
- ## so we can tell if we are inside or outside a set of nested brackets.
- ## (we need to detect errors in the rotation sequence itself
- ## and also inside squarebrackets] since these can occur anywhere,
- ## but not in the angle infoblocks <..> where we want to be able to write anything)
-
- for ($j=0; $j<= $lenstring; $j=$j+1) {
- $charpair = substr ($dataline,$j,2);
- $char1 = substr ($dataline,$j,1);
- $char2 = substr ($dataline,$j+1,1);
-
- ## at top of FOR loop
- if ($char1 eq '<'){ $angleNumLeft = $angleNumLeft+1};
- if ($char1 eq '>'){$angleNumRight = $angleNumRight-1};
-
- if ($char1 eq '['){$squareNumLeft = $squareNumLeft+1};
- if ($char1 eq ']'){$squareNumRight = $squareNumRight-1};
-
- if ($char1 eq '('){$curvedNumLeft = $curvedNumLeft+1};
- if ($char1 eq ')'){$curvedNumRight = $curvedNumRight-1};
-
-
- $angleNumSum = $angleNumLeft + $angleNumRight;
- $squareNumSum = $squareNumLeft + $squareNumRight;
- $curvedNumSum = $curvedNumLeft + $curvedNumRight;
-
- ##RWDN 22 Oct 2017
-
- ##------------
- ## need to trap nested (( )) inside squarebrackets
-
- if ($squareNumSum != 0) {
- if ( $charpair =~ m/(\(\(|\)\))/ )
- { # nested curved brackets inside sq brackets
- gprint ("..*syntax error: $charpair -- nested ((..)) in [ ]");
- ErrorMessage("$charpair -- syntax error: nested ((..)) not allowed in [ ]");
- $errorflag="SET";
- };
- };
- ##--------------
-
- ## if outside angle brackets AND outside square brackets
- ## then we are checking ONLY the rotation sequence codes
-
- if ( ($angleNumSum == 0) and ($squareNumSum == 0) ) {
-
- ## A-Za-z< A-Za-z[ A-Za-z( )A-Za-z >A-Za-z ]A-Za-z
- ## ]< ][ ]( ]) ]< )< )[ )( >< >[ >( d( d[ d<
-
- if ( $charpair =~ m/([A-Za-z]\<|[A-Za-z]\[|[A-Za-z]\(|\)[A-Za-z]|\>[A-Za-z]|\][A-Za-z]|\]\<|\]\[|\]\(|\]\)|\]\<|\)\<|\)\[|\)\(|\>\<|\>\[|\>\(|\d\(|\d\[|\d\<|\[\[|\<\<|\(\(|\)\)|\]\]|\>\>)/ )
- {
- gprint ("..*syntax error: $charpair -- missing comma");
- ErrorMessage("$charpair -- syntax error: missing comma");
- $errorflag="SET";
- next;
- };
-
- # trap nested curved brackets (= inside)
- if ( ($char2 eq "(" ) and ($curvedNumSum != 0) ) {
- ## nested curved brackets
- gprint ("..*syntax error: $charpair -- nested ((..))");
- ErrorMessage("$charpair -- syntax error: nested ((..)) not allowed");
- $errorflag="SET";
- };
-
- #-----remove--------------------------------------
- # trap comma inside [ ] ( eq inside)
- # if ($squareNumSum != 0){
- # if ($char1 eq ",") {
- # gprint ("..*syntax error: $charpair -- comma not allowed in [ ]");
- # ErrorMessage("$charpair -- syntax error: comma not allowed in [ ]");
- # $errorflag="SET";
- # next;
- # };
- # }; # end of if
- #-------------------------------------------------
-
- ## detect end of string
- if ($j == $lenstring -1) {last};
-
-
- }; # end of if
-
- }; # end of for
- #---------------------------
-
-
- if ($errorflag eq "SET") {
-
- ## closing down
- gprint ("..*Quiting Perl program -- syntax error");
- ErrorMessage ("QUITTING PERL PROGRAM -- syntax error");
-
- ##------bug fix-----------------------
- ## RWDN 5 October 2017
- ## problem = since we are here checking syntax (ie before processing any
- ## output SequenceXX strings) all four SequenceXX strings will be empty just now.
- ## This then causes an error if the Rubik user code includes a ShowSequence command,
- ## since the ForEachX macro used by ShowSequence macro cannot handle an empty string
- ## when dealing with SequenceShort and SequenceLong.
- ## So we heve to force these two strings to be just a [\space] before they are output
- ## by the SUB writestate.
- ## ie we set SequenceShort and SequenceLong strings to \space here before
- ## CALLing the SUB quitprogram().
- ## (to avoid a Rubikcube ShowSequence{}{}{} error if argument is empty
- ## or is an expandable macro)
- ## This problem arises because the ShowSequence macro uses the ForEachX macro
- ## to process each cs element in a string.
- ## Also need to add at least one empty char or comma at end of SequenceLong string,
- ## as final char (comma) is removed when writing to the out file in SUB writestate
- ## (CALLed by SUB quitprogram) just prior to closing down.
- ## NB: if there is no extra terminal char for SequenceLong string,
- ## then \space --> \spac --> TEX error message
- ##
- ## This issue does not seem to be a problem for SequenceInfo and SequenceName,
- ## as they are not returned as cs strings.
-
- $SequenceShort="\\space";
- $SequenceLong= "\\space,";
-
- ##---------------------------
-
- print " closing down -- writing state........... OK\n";
-
- quitprogram();
-
- }
- else{
- print " syntax OK; brackets balanced OK\n";
- print " done\n\n";
- };
-
-
-} ## end sub
-
-
-
-#====================
-
-sub inverse {
-
-my $E = $_[0];
-
- my $lastchar = substr ($E, -1,1);
- my $frontchars = substr ($E, 0,-1); # correct
-
- if ($lastchar eq "2") {$newE = $E}
-
- elsif ($lastchar eq "p") { $newE = $frontchars}
-
- else { $newE = $E."p"};
-
-return $newE;
-}
-
-##======================
-##EOF
-
diff --git a/Build/source/texk/texlive/linked_scripts/scripts.lst b/Build/source/texk/texlive/linked_scripts/scripts.lst
deleted file mode 100644
index 6ea6066372e..00000000000
--- a/Build/source/texk/texlive/linked_scripts/scripts.lst
+++ /dev/null
@@ -1,190 +0,0 @@
-texmf_scripts='
-adhocfilelist/adhocfilelist.sh
-bibexport/bibexport.sh
-checklistings/checklistings.sh
-ctanbib/ctanbib
-dtxgen/dtxgen
-git-latexdiff/git-latexdiff
-installfont/installfont-tl
-latexfileversion/latexfileversion
-listbib/listbib
-listings-ext/listings-ext.sh
-ltxfileinfo/ltxfileinfo
-pdfbook2/pdfbook2
-pdfjam/pdfjam
-pdftex-quiet/pdftex-quiet
-pdfxup/pdfxup
-pst-pdf/ps4pdf
-simpdftex/simpdftex
-texlive-extra/allcm.sh
-texlive-extra/allneeded.sh
-texlive-extra/dvi2fax.sh
-texlive-extra/dvired.sh
-texlive-extra/fontinst.sh
-texlive-extra/kpsetool.sh
-texlive-extra/kpsewhere.sh
-texlive-extra/ps2frag.sh
-texlive-extra/pslatex.sh
-texlive-extra/rubibtex.sh
-texlive-extra/rumakeindex.sh
-texlive-extra/texconfig-dialog.sh
-texlive-extra/texconfig-sys.sh
-texlive-extra/texconfig.sh
-texlive-extra/texlinks.sh
-texosquery/texosquery.sh
-texosquery/texosquery-jre5.sh
-texosquery/texosquery-jre8.sh
-tikztosvg/tikztosvg
-typeoutfileinfo/typeoutfileinfo.sh
-wordcount/wordcount.sh
-a2ping/a2ping.pl
-accfonts/mkt1font
-accfonts/vpl2ovp
-accfonts/vpl2vpl
-albatross/albatross.sh
-arara/arara.sh
-attachfile2/pdfatfi.pl
-authorindex/authorindex
-bib2gls/bib2gls.sh
-bib2gls/convertgls2bib.sh
-bundledoc/arlatex
-bundledoc/bundledoc
-cachepic/cachepic.tlu
-checkcites/checkcites.lua
-chklref/chklref.pl
-cjk-gs-integrate/cjk-gs-integrate.pl
-clojure-pamphlet/pamphletangler
-cluttex/cluttex.lua
-context/perl/mptopdf.pl
-convbkmk/convbkmk.rb
-crossrefware/bbl2bib.pl
-crossrefware/bibdoiadd.pl
-crossrefware/bibmradd.pl
-crossrefware/biburl2doi.pl
-crossrefware/bibzbladd.pl
-crossrefware/ltx2crossrefxml.pl
-ctan-o-mat/ctan-o-mat.pl
-ctanify/ctanify
-ctanupload/ctanupload.pl
-de-macro/de-macro
-diadia/diadia.lua
-dosepsbin/dosepsbin.pl
-dviasm/dviasm.py
-dviinfox/dviinfox.pl
-ebong/ebong.py
-epspdf/epspdf.tlu
-epspdf/epspdftk.tcl
-epstopdf/epstopdf.pl
-exceltex/exceltex
-fig4latex/fig4latex
-findhyph/findhyph
-fontools/afm2afm
-fontools/autoinst
-fontools/ot2kpx
-fragmaster/fragmaster.pl
-getmap/getmapdl.lua
-glossaries/makeglossaries
-glossaries/makeglossaries-lite.lua
-hyperxmp/hyperxmp-add-bytecount.pl
-jfmutil/jfmutil.pl
-ketcindy/ketcindy.pl
-kotex-utils/jamo-normalize.pl
-kotex-utils/komkindex.pl
-kotex-utils/ttf2kotexfont.pl
-l3build/l3build.lua
-latex-git-log/latex-git-log
-latex-papersize/latex-papersize.py
-latex2man/latex2man
-latex2nemeth/latex2nemeth
-latexdiff/latexdiff-vc.pl
-latexdiff/latexdiff.pl
-latexdiff/latexrevise.pl
-latexindent/latexindent.pl
-latexmk/latexmk.pl
-latexpand/latexpand
-light-latex-make/llmk.lua
-lilyglyphs/lily-glyph-commands.py
-lilyglyphs/lily-image-commands.py
-lilyglyphs/lily-rebuild-pdfs.py
-ltximg/ltximg.pl
-luaotfload/luaotfload-tool.lua
-lwarp/lwarpmk.lua
-m-tx/m-tx.lua
-makedtx/makedtx.pl
-make4ht/make4ht
-match_parens/match_parens
-mathspic/mathspic.pl
-mf2pt1/mf2pt1.pl
-mkgrkindex/mkgrkindex
-mkjobtexmf/mkjobtexmf.pl
-mkpic/mkpic
-multibibliography/multibibliography.pl
-musixtex/musixflx.lua
-musixtex/musixtex.lua
-pax/pdfannotextractor.pl
-pdfcrop/pdfcrop.pl
-pdflatexpicscale/pdflatexpicscale.pl
-pedigree-perl/pedigree.pl
-perltex/perltex.pl
-petri-nets/pn2pdf
-pfarrei/a5toa4.tlu
-pfarrei/pfarrei.tlu
-pkfix-helper/pkfix-helper
-pkfix/pkfix.pl
-pmxchords/pmxchords.lua
-pst2pdf/pst2pdf.pl
-ptex-fontmaps/kanji-config-updmap-sys.sh
-ptex-fontmaps/kanji-config-updmap-user.sh
-ptex-fontmaps/kanji-config-updmap.pl
-ptex-fontmaps/kanji-fontmap-creator.pl
-ptex2pdf/ptex2pdf.lua
-purifyeps/purifyeps
-pygmentex/pygmentex.py
-pythontex/depythontex.py
-pythontex/pythontex.py
-rubik/rubikrotation.pl
-spix/spix.py
-splitindex/splitindex.pl
-srcredact/srcredact.pl
-sty2dtx/sty2dtx.pl
-svn-multi/svn-multi.pl
-tex4ebook/tex4ebook
-texcount/texcount.pl
-texdef/texdef.pl
-texdiff/texdiff
-texdirflatten/texdirflatten
-texdoc/texdoc.tlu
-texfot/texfot.pl
-texlive/fmtutil-sys.sh
-texlive/fmtutil-user.sh
-texlive/fmtutil.pl
-texlive/mktexlsr
-texlive/mktexmf
-texlive/mktexpk
-texlive/mktextfm
-texlive/rungs.tlu
-texlive/tlmgr.pl
-texlive/updmap-sys.sh
-texlive/updmap-user.sh
-texlive/updmap.pl
-texlive-extra/e2pall.pl
-texliveonfly/texliveonfly.py
-texloganalyser/texloganalyser
-texplate/texplate.sh
-thumbpdf/thumbpdf.pl
-tlcockpit/tlcockpit.sh
-tlshell/tlshell.tcl
-ulqda/ulqda.pl
-urlbst/urlbst
-vpe/vpe.pl
-webquiz/webquiz.py
-xindex/xindex.lua
-yplan/yplan
-context/stubs/unix/context
-context/stubs/unix/contextjit
-context/stubs/unix/luatools
-context/stubs/unix/mtxrun
-context/stubs/unix/mtxrunjit
-context/stubs/unix/texexec
-context/stubs/unix/texmfstart
-'
diff --git a/Build/source/texk/texlive/linked_scripts/simpdftex/simpdftex b/Build/source/texk/texlive/linked_scripts/simpdftex/simpdftex
deleted file mode 100755
index beff5ee57c3..00000000000
--- a/Build/source/texk/texlive/linked_scripts/simpdftex/simpdftex
+++ /dev/null
@@ -1,669 +0,0 @@
-#!/bin/sh
-# Script to do (la)tex->dvi->[ps->]pdf.
-#
-# Created by Gerben Wierda, May 2001
-# Rewritten by Gerben Wierda, January 2002
-# Modified by Joachim Kock, May 2003
-# Modified by Gerben Wierda, April 2007
-# Modified by Bruno Voisin and Herbert Schulz, September 2018
-
-# COPYRIGHT Gerben Wierda 2001--2018
-# This file is free software. You are free to use this file in any way you like
-# However, if you change it you should note in this file that you did and who
-# you are, you also need to change the version string if you do. That way
-# I will not get support questions for software that is not entirely mine.
-
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-# EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# This script assumes that there is a config.pdf somewhere that sets
-# the bitmap mode to something large but realistic (real mode) so that
-# unavailable pfb fonts will be included as bitmaps.
-
-# Version 1.0: added the string above for identification purposes
-# Version 1.0a: Cosmetic change: do not display dir of argv[0] all the time
-# Added calledas variable to hold command basename
-# Version 1.1: Use calledas instead of $0 which means the sed command
-# for determining format below also works when there is no dir
-# (run from dir where altpdftex resides, not very likely...)
-# Version 1.2: Force the use of tex binaries from the same directory as
-# this script
-# Version 1.3: Added --echo-version option, placed argument check after
-# switch, inside while to prevent subscript out of range error
-# Added --tex-path to override directory where this script
-# resides. Added --gs-path to override a new default gs
-# directory /usr/local/bin. Also, force gs directory at the
-# start of the path to repair for broken installations of
-# TeX, gs and such
-# Version 1.4: Moved path changes to just before calling gs so that only
-# ps2pdf is affected
-# Version 1.5: Removed some path-related redundancy from GS calling
-# Version 1.5a: Missing ${extradviopts} from echo
-# Added version to --help output
-# Added wolfram.map
-# Version 1.6: Fixed bug: --dviopts did not work because it did set
-# the wrong variable
-# Changed dviopts to dvipsopts (better name)
-# Version 1.7: Added --distiller and --distiller-filter option
-# Changed --gs-path to --distiller-path
-# Changed distiller semantics
-# Fixed bug --tex-path flag needed trailing '/'
-# Some extra quoting to be more robust for whitespace
-# in names, also internally
-# Version 1.8: Added pstill and u-psbuild info to help
-# Version 1.9: Removed textrace bbold font (textrace is broken)
-# Version 1.10: Added amstex support
-# Simplified different format support
-# Version 1.11: Do not source ~/.{t}cshrc, use the environment 'as is'
-# Version 1.11 says it is version 1.10!
-# Version 1.12: Added textrace bold font (textrace 0.48 is ok)
-# Version 1.13: Changed success message at the end
-# Echo version on by default
-# Debug option
-# Version 1.13b:Date report on version was very out of date, removed
-
-# Version 2.0: Rewritten in /bin/sh because (t)csh does not handle signals
-# very well...
-# This version works, but you need to send the SIGTERM to
-# the process group (the negative PID) to get it to work
-# Version 2.1: Small bug fixes
-# Version 2.2: Fixed bug where argument without extension was interpreted
-# as dvi file.
-# Removed dependencies on smart sh versions
-# Version 2.3: Removed map file knowledge (needs to be outside this script)
-# beyond the standard map files
-# Version 2.4: Added support for omega and lambda (use odvips)
-# Version 2.5: Changed maxpk and maxpfb implementation to recent updmap
-# Version 2.6: Use ps2pdf13 as the default distiller
-# Version 2.7: Changed help
-# Version 2.8: Checked into CVS.
-# Added handling of outdir for TeX
-# Version 2.9: Added auto-outdir flag
-# Version 2.10: Changed --outdir behaviour to mimick TEXMFOUTPUT,
-# removed --auto-outdir
-# Version 2.11: Fixed typo
-# Version 2.12: RCS changes, from now on, the version number is the RCS number
-# These notes here will become a ChangeLog.
-# 2003/05/20 Joachim's modification: write first to a pdf file in tmp,
-# and only upon completion copy the file to its final
-# destination. This is done in order to minimise the time where
-# the pdf file in current directory is in an unstable state,
-# because a PDF viewer might be tracking the file, and
-# if it finds the pdf file in an intermediate state it will
-# display a blank page until the new version is ready.
-# 2003/05/21 Joachim's modification used /bin/cp. Gerben made it truly
-# atomic by using /bin/cp in combination with /bin/mv
-# 2003/11/23 Added supportfor passing flasg to tex at the request of
-# Dick Koch.
-# 2004/09/05 Bugfix: make it work better with directories with whitespace
-# in their name
-# 2004/11/15 New calling mode: simpdftex format foo.tex
-# e.g.:
-# simpdftex latex foo.tex
-# In the future, the old modes (altpdflatex and friends) through
-# symlinks will disappear from my distribution, though they will
-# still work.
-# 2007/05/07 Added dvipdfm support with compatibility with the patched version
-# that is available on the net (simpdftex_dpmx)
-# Changed version string to date-based string
-# 2007/08/09 Protected echo command against broken builtin versions by running
-# /bin/echo explicitly. There may exist /bin/echo implementations
-# that do not support -n and this script will have to be changed
-# before it works on such a system.
-# 2018/09/19 Added --distilleropts optlist command line flag for
-# options to be added to the distiller application;
-# e.g. "-dCompatibilityLevel=1.5 -dNOSAFER".
-# Removed uses of echo -n.
-# 2018/09/24 Added -dCompatibilityLevel=15 into the distillerprog definition
-# and removed quotes around execution of ${distillerprog} so it can
-# contain options.
-
-# FEATURE: it seems -u +foo.map -u -foo.map does not work. So --extradvipsopts
-# cannot be used to remove a map from the standard list
-
-# BUG: Handling of file name extensions is not completely equialent to TeX
-# i.e. foo.bar.bla gets you foo.bar.pdf not foo.bar.bla.pdf
-# Hint: Give all extensions explicitly on the command line
-
-version='20180924'
-calledas=`basename "$0"`
-if [ "${calledas}" = "simpdftex" ]
-then
- argwithoutlead=`/bin/echo "$1"|sed 's/^--//'`
- if [ "$1" != "" -a "$1" = "${argwithoutlead}" ]
- then
- formatname="$1"
- shift
- calledas="altpdf${formatname}"
- fi
-fi
-argvbackup="$*"
-
-dviprogram="dvips" # Might be dvips, dvipdfm or dvipdfmx
-
-# maxpkdvipsopts: use only pfb's for real PS fonts, bitmaps are default for the others
-maxpkdvipsopts="-Ppk"
-# maxpfbdvipsopts: use as many pfb's as possible
-maxpfbdvipsopts="-Poutline"
-opt_dvipsopts=""
-
-# Defaults:
-# altpdftex --default is the default setting, it also works
-# when there is no config.pdf file
-extradvipsoptions=""
-dvipsoptions="$maxpfbdvipsopts"
-outputpostfix=".maxpfb"
-simplename="yes"
-keeppsfile="no"
-echoversion="yes"
-texpath=`dirname "$0"`
-# Default distiller is ps2pdf from /usr/local/bin in no filter mode
-# as the direct call to a filtering gs does not work yet for some reason
-#distillerpath=""
-#distillerprog="/usr/local/bin/gs -dCompatibility=1.3 -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=- -c save pop"
-#distillerfilter="yes"
-distillerpath="/usr/local/bin"
-#distillerprog="ps2pdf13"
-distillerprog="ps2pdf -dCompatibilityLevel=1.5"
-distillerfilter="no"
-unset outdir
-debug="no"
-dvipdfmoptions=""
-distilleroptions=""
-
-usage()
-{
- cat <<_eof_help
-This is simpdftex, $version
-
-Usage: simpdftex formatname [--mode modestring]
- [--dvipsopts dvipsoptstring] [--extradvipsopts dvipsoptstring] [--pdf]
- [--default] [--maxpk] [--maxpfb] [--extendedname] [--no-echo-version]
- [--tex-path dir] [--keep-psfile] [--distiller-path dir] [--debug]
- [--distiller prog] [--distiller-filter prog] [--distilleropts opts]
- [--help] [--outdir dir] [--extratexopts texoptsstring]
- [--dvipdfmopts dvipdfmoptstring] tex-or-dvi-file
-
-simpdftex is a way to do pdf{e}{la}tex without having pdf{e}{la}tex. It needs a
-working TeX environment and one of three ways to turn DVI file into PDF:
- - dvips + a distiller like ghostscript
- - dvipdfm
- - dvipdfmx
-Since pdf{e}{la}tex cannot handle insertion of .eps graphics, simpdftex gives an
-alternative when using dvips mode. The output for both systems is comparable.
-
-simpdftex compiles the file with {La}TeX, processes the DVI file with dvips into
-PostScript and uses gs to produce pdf (with ps2pdf). Or it uses dvipdfm or
-dvipdfmx to turn the DVI file into PDF. There is finegrained control over the
-resulting filename and the options with which dvips produces the PostScript
-intermediary file.
-
-Dvips will call Metafont to produce bitmaps or include PostScript .pfb files
-depending on the flags. See below.
-
-The default setting is normal name, maximal use of pfb's, just like pdf{la}tex,
-in other words, "pdftex file.tex" and "altpdftex file.tex" both produce an
-output file file.pdf. For pdftex, output options are controlled by pdftex.cfg,
-for altpdftext by config.ps (unless --pdf is given).
-
-Arguments:
- tex-or-dvi-file
- If a .dvi file is given, skip the TeX process. Otherwise, TeX
- the input file, dvips the resulting dvi file and ps2pdf the
- resulting ps file
- --mode
- Tell simpdftex how to go from DVI to PDF. There are three modes:
- - dvips
- - dvipdfm
- - dvipdfmx
- --dpx
- Compatibility flag with simpdftex_dpmx. Equal to --mode dvipdfmx
- --dpm
- Compatibility flag with simpdftex_dpmx. Equal to --mode dvipdfm
- --help
- Display this message and exit
- --no-echo-version
- Do not echo location and version of this script. Does not exit
- so can be used tochange info to the output of a real run
- --debug
- Add some debug output
- --extendedname
- Depending on the mode, adds intermediary extensions to the
- output filename. If the mode is --pdf, .pdfmode is added. If
- the mode is --maxpk, ,maxpk is added and if the mode is
- --maxpfb, .maxpfb is added. Example:
- tex-or-dvi-file-basename.maxpfb.pdf
- --maxpk
- Use Metafont bitmaps (pk files) when possible. Only real
- PostScript fonts (like Times Roman) are included as
- PostScript fonts. All other fonts are included as bitmaps
- for the default printer resolution. This options produces
- optimal results for the chosen printer.
- For file contents (not name) equivalent to:
- --dvipsopts "-Ppk"
- Not yet functional for the other modes.
- --maxpfb
- Use PostScript pfb files whenever possible. This produces
- optimal results for the screen.
- For file contents (not name) equivalent to:
- --dvipsopts "-Poutline"
- If any font is included as TeX pk bitmap, it is rendered
- at the default resolution.
- Not yet functional for the other modes.
- --pdf
- Select .pdfmode extension for the output file name if
- --extendedname has been set. Use printer definition
- config.pdf. For file contents (not name) equivalent to
- --dvipsopts "-Ppdf"
- Note that the default config.pdf assumes resolution 8000
- for bitmaps and bitmap generation fails at this resolution
- because there exists no known mode for that resolution.
- --default
- Select no extension for the output file name, even if
- --extendedfilename has been set. Use standard printer
- definition config.ps. For file contents (not name) equivalent
- to:
- --dvipsopts "" --noextendedname
- --dvipsopts
- Give arbitrary arguments to dvips, e.g.
- --dvipsopts "-M"
- Sets extension for --extendedfilename to .custom. --dvipsopts
- overrides other flags that set dvipsopts.
- --extratexopts
- Give extra arbitrary arguments to tex, e.g.
- --extratexopts "--interaction=nonstopmode"
- Sets extra options for the tex command that is used.
- --extradvipsopts
- Give extra arbitrary arguments to dvips, e.g.
- --extradvipsopts "-M"
- Sets extra options for dvips and does not set extension
- or override other options. Options will be added to the end
- of the options for dvips
- --keep-psfile
- After running dvips, copy the ps file over to the directory
- where the tex file is, possibly overwriting a ps file
- that is there. Use with caution, a ps file could be input
- as well.
- --tex-path
- Give path of TeX binaries, use directory of this script
- otherwise
- --distiller prog
- Use a distiller different from ps2pdf which is the default.
- Argument must be an executable or executable script that
- gets called iwth two arguments: input file (PS) and output
- file (PDF). E.g.:
- --distiller=/usr/local/alternate/bin/ps2pdf
- --distiller=pstill
- Using this flag sets the distiller filter mode to off
- This flag only makes sense in dvips mode
- --distiller-filter prog
- Use a distiller executable or executable script which is
- called with the PS input as standard input and which writes
- the PDF output to standard output. E.g.:
- --distiller-filter=u-psbuild
- This flag only makes sense in dvips mode
- --distilleropts optionlist
- special options to pass to the distiller
- --distiller-path
- Give path needed by the distiller binary. This path is added
- to the begin of you PATH environment before the distiller is
- run. The reason is that for instance ps2pdf uses the path to
- find gs and sets the path to something with /sw/bin at the
- beginning. Thus, installing gs from fink would make
- /usr/local/bin/ps2pdf find another gs than intended. By giving
- an empty path, the path is not changed before the distiller
- program is run. The default is empty.
- This flag only makes sense in dvips mode
- --dvipdfmopts
- Give arbitrary arguments to dvipdfm or dvipdfmx, e.g.
- --dvipdfmopts "-c"
- Sets extension for --extendedfilename to .custom. --dvipdfmopts
- overrides other flags that set dvipdfmopts.
- --outdir dir
- Write files here *if* our current directory is unwritable. This
- mimicks the TEXMFOUTPUT environment variable of TeX, but
- differently. The current dir becomes the value of --outdir and
- the directory where the old current dir is added to TEXINPUTS.
- This is more robust for reading and locating files.
- You can also set TEXMFOUTPUT instead, but with a disadvantage:
- you will be running TeXin the current dir. And you will not be
- able to read files in the outdir unless you also adapt
- TEXINPUTS.
-
- The defaults for the distiller are
- Path addition: "${distillerpath}"
- Filter mode: "${distillerfilter}"
- Program: "${distillerprog}"
-
- Later flags override settings of earlier flags.
-_eof_help
-}
-
-while test $# -gt 0
-do
- case $1 in
- --help)
- usage
- exit 0;;
- --dvipsopts)
- shift
- outputpostfix=".custom"
- dvipsoptions="$1"
- ;;
- --dvipdfmopts)
- outputpostfix=".custom"
- shift
- dvipdfmoptions="$1"
- ;;
- --dvipdfopts) # Compatibility with simpdftex_dpmx
- shift
- dvipdfmoptions="$1"
- ;;
- --extradvipsopts)
- shift
- extradvipsoptions="$1"
- ;;
- --extratexopts)
- shift
- extratexoptions="$1"
- ;;
- --tex-path)
- shift
- texpath="$1"
- ;;
- --pdf)
- outputpostfix=".pdfmode"
- dvipsoptions="-P pdf"
- ;;
- --default)
- outputpostfix=""
- dvipsoptions=""
- # Use the default print option in config.ps
- ;;
- --maxpk)
- outputpostfix=".maxpk"
- dvipsoptions="$maxpkdvipsopts"
- ;;
- --maxpfb)
- outputpostfix=".maxpbfb"
- dvipsoptions="$maxpfbdvipsopts"
- ;;
- --extendedname)
- simplename="no"
- ;;
- --keep-psfile)
- keeppsfile="yes"
- ;;
- --debug)
- debug="yes"
- ;;
- --distiller-path)
- shift
- distillerpath="$1"
- ;;
- --distiller)
- shift
- distillerprog="$1"
- distillerfilter="no"
- ;;
- --distilleropts)
- shift
- distilleroptions="$1"
- ;;
- --mode)
- shift
- if [ "$1" = "dvips" -o "$1" = "dvipdfm" -o "$1" = "dvipdfmx" ]
- then
- dviprogram="$1"
- else
- /bin/echo "Unknown mode $1"
- exit 1
- fi
- ;;
- --outdir)
- shift
- export TEXINPUTS=`pwd`:`kpsewhich --expand-var '$TEXINPUTS'`
- export TEXMFOUTPUT="$1"
- outdir="$1/"
- outdirset="yes"
- cd "$1"
- ;;
- --distiller-filter)
- shift
- distillerprog="$1"
- distillerfilter="yes"
- ;;
- --no-echo-version)
- echoversion="no"
- ;;
- --dpx) # Compatibility with simpdftex_dpmx
- dviprogram="dvipdfmx"
- ;;
- --dpm) # Compatibility with simpdftex_dpmx
- dviprogram="dvipdfm"
- ;;
- --*)
- /bin/echo "Unknown option $1"
- exit 1;;
- "")
- ;;
- *)
- break;;
- esac
- shift
-done
-
-if [ "${echoversion}" = "yes" -a "${debug}" = "no" ]
-then
- /bin/echo "### This is $0, Version ${version}"
-fi
-
-if [ "${debug}" = "yes" ]
-then
- /bin/echo "##### This is $0, Version ${version}"
- /bin/echo "##### Arguments: ${argvbackup}"
-fi
-
-run_dvipdfm()
-{
- /bin/echo "### ${texpath}/${dviprogram} ${dvipdfmoptions} -o ${pdffile} ${dvifile}"
- "${texpath}/${dviprogram}" ${dvipdfmoptions} -o "${pdffile}" "${dvifile}" || \
- { /bin/echo "### FAILED to generate ${pdffile} (${status})"; \
- exit 1; }
-}
-
-run_dvips()
-{
- /bin/echo "### ${texpath}/${dviprogram} -R ${dvipsoptions} ${extradvipsoptions} -o ${psfile} ${dvifile}"
- "${texpath}/${dviprogram}" -R ${dvipsoptions} ${extradvipsoptions} -o "${psfile}" "${dvifile}" || \
- { /bin/echo "### FAILED to generate ${psfile} (${status})"; \
- exit 1; }
-
- if [ "${keeppsfile}" = "yes" ]; then
- /bin/echo "### Saving intermediary ps file ${psfile} as ${savedpsfile}"
- /bin/cp "${psfile}" "${savedpsfile}" || \
- /bin/echo "### FAILED to save ${psfile} (${status})"
- fi
-
- if [ "${distillerpath}" != "" ]; then
- PATH="${distillerpath}:${PATH}";export PATH
- if [ "${debug}" = "yes" ]; then
- /bin/echo "##### PATH set to ${PATH}"
- fi
- fi
-
- if [ "${distillerfilter}" = "yes" ]; then
- /bin/echo "### ${distillerprog} ${distilleroptions} <${psfile} >${pdffile}"
- ${distillerprog} ${distilleroptions} <"${psfile}" >"${pdffile}" || \
- { /bin/echo "### FAILED to generate ${pdffile} (${status})"
- exit 1; }
- else
- /bin/echo "### ${distillerprog} ${distilleroptions} ${psfile} ${pdffile}"
- ${distillerprog} ${distilleroptions} "${psfile}" "${pdffile}" || \
- { /bin/echo "### FAILED to generate ${pdffile} (${status})"
- exit 1; }
- fi
-}
-
-cleanup()
-{
- if [ "${tmpdir}" != "" -a "${debug}" = "no" ]
- then
- rm -rf "${tmpdir}"
- fi
-}
-
-terminated()
-{
- cleanup
- exit 1;
-}
-
-trap 'terminated' 15
-
-main()
-{
- if [ "${file}" = "" ]
- then
- /bin/echo "simpdftex Empty argument: tex-or-dvi-file-name"
- exit 1
- fi
-
- # Argument handling
-
- if [ "${simplename}" = "yes" ]
- then
- outputpostfix=""
- fi
-
- startwithdvi="no"
- basename=`basename "${file}"`
- nosuffixbasename=`/bin/echo ${basename}|sed 's/\.[^.]*$//'`
- nodvisuffixbasename=`/bin/echo ${basename}|sed 's/\.[dD][vV][iI]$//'`
- if [ "${nodvisuffixbasename}" = "${nosuffixbasename}" -a \
- "${basename}" != "${nosuffixbasename}" ]
- then
- startwithdvi="yes"
- fi
-
- kpsefilename=`kpsewhich "${file}"`
- slashdirname=`dirname "${kpsefilename}"`/
-
- if [ ! -w "." ]
- then
- if [ "${TEXMFOUTPUT}" != "" ]
- then
- outdir="${TEXMFOUTPUT}/"
- outdirset="yes"
- if [ "${autoinput}" = "yes" ]
- then
- export TEXINPUTS=${TEXMFOUTPUT}:`kpsewhich --expand-var '$TEXINPUTS'`
-
- fi
- else
- /bin/echo "### Cannot write in current directory and no redirect found. Bailing out..."
- exit 1
- fi
- fi
-
- # Assume the command is called altpdf* where the rest is the actual tex
- # program to be run
- texprogram=`/bin/echo ${calledas}|sed 's/altpdf//'`
- if [ "${texprogram}" = "omega" -o "${texprogram}" = "lambda" ]
- then
- dvips="odvips"
- else
- dvips="dvips"
- fi
-
- # Handle temp dir (cleanup is called on signal)
- tmpext=$$-`/bin/date +"%s"`
- tmpdir="/tmp/altpdf${texprogram}.${tmpext}"
- # Force removal of possible existing tmpdir
- cleanup
- # Make new version
- mkdir "${tmpdir}"
-
- if [ "${startwithdvi}" = "yes" ]
- then
- dvifile="${file}"
- else
- texfile="${file}"
- dvifile="${outdir}${nosuffixbasename}.dvi"
- fi
-
- psfile="${tmpdir}/${nosuffixbasename}${outputpostfix}.ps"
- savedpsfile="${outdir}${nosuffixbasename}.ps"
- pdffile="${tmpdir}/${nosuffixbasename}${outputpostfix}.pdf"
- savedpdffile="${outdir}${nosuffixbasename}${outputpostfix}.pdf"
-
- if [ "${debug}" = "yes" ]
- then
- /bin/echo "##### TeX file: $texfile"
- /bin/echo "##### DVI file: $dvifile"
- if [ "${dviprogram}" = "dvips" ]
- then
- /bin/echo "##### PS file: $psfile"
- /bin/echo "##### Saved PS file: $savedpsfile"
- fi
- /bin/echo "##### Created PDF file: $pdffile"
- /bin/echo "##### Final PDF file: $savedpdffile"
- /bin/echo "##### Environment:"
- env | sed 's/^/##### /g'
- fi
-
- if [ "${startwithdvi}" = "yes" ]; then
- /bin/echo "### Skipping ${texprogram} ${texfile} [dvi->pdf only]"
- else
- /bin/echo "### ${texpath}/${texprogram} ${texfile}"
- "${texpath}/${texprogram}" ${extratexoptions} "${texfile}" || \
- /bin/echo "### WARNING: TeX returned non zero exit status ${status}"
- fi
-
- case "${dviprogram}" in
- "dvips")
- run_dvips;;
- "dvipdfm")
- run_dvipdfm;;
- "dvipdfmx")
- run_dvipdfm;;
- *)
- /bin/echo "### ERROR: wrong dvipdf mode ${dviprogram}"
- esac
-
- /bin/echo "### Copying/moving pdf file ${pdffile} to ${savedpdffile}"
- /bin/cp "${pdffile}" "${savedpdffile}.${tmpext}" || \
- /bin/echo "### FAILED to copy ${pdffile} (${status})"
- /bin/rm -f "${savedpdffile}"
- /bin/mv "${savedpdffile}.${tmpext}" "${savedpdffile}" || \
- /bin/echo "### FAILED to rename ${savedpdffile}.${tmpext} (${status})"
-
- if [ "${startwithdvi}" = "yes" ]; then
- if [ "${keeppsfile}" = "yes" ]; then
- /bin/echo "### Succesfully generated ${savedpdffile} and ${savedpsfile}"
- else
- /bin/echo "### Succesfully generated ${savedpdffile}"
- fi
- else
- if [ "${keeppsfile}" = "yes" ]; then
- /bin/echo "### Succesfully generated ${dvifile}, ${savedpdffile} and ${savedpsfile}"
- else
- /bin/echo "### Succesfully generated ${dvifile} and ${savedpdffile}"
- fi
- fi
-
- cleanup
-}
-
-for file in "$@"
-do
- main
-done
diff --git a/Build/source/texk/texlive/linked_scripts/spix/spix.py b/Build/source/texk/texlive/linked_scripts/spix/spix.py
deleted file mode 100755
index 1369703a7aa..00000000000
--- a/Build/source/texk/texlive/linked_scripts/spix/spix.py
+++ /dev/null
@@ -1,145 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright 2020 Louis Paternault
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-"""Compile a `.tex` file, executing commands that are set inside the file itself."""
-
-import argparse
-import logging
-import os
-import pathlib
-import re
-import subprocess
-import sys
-
-NAME = "SpiX"
-VERSION = "1.1.0"
-
-RE_EMPTY = re.compile("^ *$")
-RE_COMMENT = re.compile("^ *%")
-RE_COMMAND = re.compile(r"^%\$ ?(.*)$")
-
-
-class SpixError(Exception):
- """Exception that should be catched and nicely displayed to user."""
-
-
-def parse_lines(lines):
- """Parse line to find code snippets.
-
- :param iterable lines: Lines to parte (typically ``open("foo.tex").readlines()``.
- :return: Iterator over snippets (as strings).
- """
- snippet = None
- for line in lines:
- line = line.rstrip("\n")
- if RE_COMMAND.match(line):
- match = RE_COMMAND.match(line)
- if snippet is None:
- snippet = ""
- else:
- snippet += "\n"
- snippet += match.groups()[0]
- elif RE_EMPTY.match(line) or RE_COMMENT.match(line):
- if snippet is not None:
- yield snippet
- snippet = None
- else:
- break
- if snippet is not None:
- yield snippet
-
-
-def compiletex(filename, *, dryrun=False):
- """Read commands from file, and execute them.
-
- :param str filename: File to process.
- :param bool dryrun: If ``True``, print commands to run, but do not execute them.
- """
- env = os.environ
- filename = pathlib.Path(filename)
- env["texname"] = filename.name
- env["basename"] = filename.stem
-
- try:
- with open(filename, errors="ignore") as file:
- for snippet in parse_lines(file.readlines()):
- print(snippet)
- if dryrun:
- continue
-
- subprocess.check_call(
- ["sh", "-c", snippet, NAME, filename.name],
- cwd=(pathlib.Path.cwd() / filename).parent,
- env=env,
- )
- except subprocess.CalledProcessError:
- raise SpixError()
- except IsADirectoryError as error:
- raise SpixError(str(error))
-
-
-def commandline_parser():
- """Return a command line parser.
-
- :rtype: argparse.ArgumentParser
- """
- parser = argparse.ArgumentParser(
- prog="spix",
- description=(
- "Compile a `.tex` file, "
- "executing commands that are set inside the file itself."
- ),
- )
- parser.add_argument(
- "-n",
- "--dry-run",
- action="store_true",
- help="Print the commands that would be executed, but do not execute them.",
- )
- parser.add_argument(
- "--version",
- help="Show version and exit.",
- action="version",
- version=f"{NAME} {VERSION}",
- )
- parser.add_argument("FILE", nargs=1, help="File to process.")
-
- return parser
-
-
-def main():
- """Main function."""
- arguments = commandline_parser().parse_args()
-
- if os.path.exists(arguments.FILE[0]):
- arguments.FILE = arguments.FILE[0]
- elif os.path.exists(f"{arguments.FILE[0]}.tex"):
- arguments.FILE = f"{arguments.FILE[0]}.tex"
- else:
- logging.error("""File not found: "%s".""", arguments.FILE[0])
- sys.exit(1)
-
- try:
- compiletex(arguments.FILE, dryrun=arguments.dry_run)
- except SpixError as error:
- if str(error):
- logging.error(error)
- sys.exit(1)
-
-
-if __name__ == "__main__":
- main()
diff --git a/Build/source/texk/texlive/linked_scripts/splitindex/splitindex.pl b/Build/source/texk/texlive/linked_scripts/splitindex/splitindex.pl
deleted file mode 100755
index 70c61720c9b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/splitindex/splitindex.pl
+++ /dev/null
@@ -1,212 +0,0 @@
-#! /usr/bin/perl -w
-eval 'exec perl -S $0 ${1+"$@"}'
- if 0; #$running_under_some_shell
-
-# ======================================================================
-# splitindex.pl
-# Copyright (c) Markus Kohm, 2002-2009
-#
-# $Id: splitindex.pl,v 1.3 2009-03-20 14:55:11 mjk Exp $
-#
-# This file is part of the SplitIndex bundle.
-#
-# This work may be distributed and/or modified under the conditions of
-# the LaTeX Project Public License, version 1.3c of the license.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3c or later is part of all distributions of LaTeX
-# version 2005/12/01 or later and of this work.
-#
-# This work has the LPPL maintenance status "author-maintained".
-#
-# The Current Maintainer and author of this work is Markus Kohm.
-#
-# The list of all files belongig to the SplitIndex bundle is given in
-# in the file `manifest.txt'. Files generated by means of unpacking the
-# distribution (using, for example, the docstrip program) or by means
-# of compiling them from a source file, for example, from splitindex.c
-# or splitindex.java may be distributed at the distributor's discretion.
-# However if they are distributed then a copy of the SplitIndex bundle
-# must be distributed together with them.
-#
-# The list of derived (unpacked or compiled) files belongig to the
-# distribution and covered by LPPL is defined by the unpacking scripts
-# (with extension .ins) and the installation script (with name
-# install.sh) which are part of the distribution.
-#
-# Two often ignorred clauses from LPPL 1.3c you should not ignore:
-# ----------------------------------------------------------------
-# 2. You may distribute a complete, unmodified copy of the Work as you
-# received it. Distribution of only part of the Work is considered
-# modification of the Work, and no right to distribute such a Derived
-# Work may be assumed under the terms of this clause.
-# 3. You may distribute a Compiled Work that has been generated from a
-# complete, unmodified copy of the Work as distributed under Clause 2
-# above, as long as that Compiled Work is distributed in such a way that
-# the recipients may install the Compiled Work on their system exactly
-# as it would have been installed if they generated a Compiled Work
-# directly from the Work.
-# ======================================================================
-
-use strict;
-use Getopt::Long;
-
-my $makeindex = "makeindex";
-# my $identify = "^(.*)\\\\UseIndex *\\{([^\\}]*)\\}(.*)\$";
-my $identify = "^(\\\\indexentry)\\[([^]]*)\\](.*)\$";
-my $suffixis = "-\$2";
-my $lineis = "\$1\$3";
-my $verbose = 0; # option verbose with default value
-my $result = GetOptions(
- 'help' => sub { help() },
- 'makeindex=s' => \$makeindex,
- 'identify=s' => \$identify,
- 'resultis=s' => \$lineis,
- 'suffixis=s' => \$suffixis,
- 'verbose|v+' => \$verbose,
- 'version' => sub { version(); exit 0; }
- );
-
-usage("missing raw index file") if ( $#ARGV < 0 );
-
-my $indexinput = shift;
-my $jobname = ( $indexinput =~ /^(.*)\.idx$/ ) ? $1 : $indexinput;
-
-my %idxfile;
-my %linesatidxfile;
-
-version() if ($verbose > 0);
-
-if ( !( open (IDX,"<$indexinput") ) ) {
- if ( $indexinput ne "$jobname.idx" ) {
- open (IDX,"<$jobname.idx") ||
- die "Cannot read raw index file $indexinput nor $jobname.idx";
- $indexinput = "$jobname.idx";
- } else {
- die "Cannot read raw index file $indexinput";
- }
-}
-
-while (<IDX>) {
- my $line;
- my $suffix;
- if ( /$identify/ ) {
- my $eval = "\$line = \"$lineis\n\"";
- eval $eval;
- $eval = "\$suffix = \"$suffixis\"";
- eval $eval;
- } else {
- $line = $_;
- $suffix = "";
- $suffix .= "$1" if ( $suffixis =~ /^(.*)\$/ );
- $suffix .= "idx";
- $suffix .= "$1" if ( $suffixis =~ /\$[123456789](.*)$/ );
- }
- while ( $suffix =~ /(^[^,]+)(.*)$/ ) {
- $suffix = $2;
- writetoidx ($1,$line);
- }
-}
-
-closeallind();
-
-close(IDX);
-
-generateallind(@ARGV);
-
-exit 0;
-
-sub generateallind {
- my $name;
- my $file;
-
- if ( $makeindex ne "" ) {
- while (($name,$file) = each %idxfile) {
- system( "$makeindex @ARGV $jobname$name.idx" );
- }
- }
-}
-
-sub closeallind {
- my $name;
- my $file;
- my $lines;
- while (($name,$file) = each %idxfile) {
- print "Close $jobname$name.idx\n"
- if ( $verbose > 1 );
- close( $file );
- $idxfile{$name}=0;
- }
- if ( $verbose > 0 ) {
- print "\n";
- while (($name,$lines) = each %linesatidxfile) {
- print "$jobname$name.idx with $lines lines\n";
- }
- }
-}
-
-sub writetoidx {
- my $suffix = $_[0];
- my $line = $_[1];
- my $file = $idxfile{$suffix};
- if ( ! $file ) {
- open ( $file, ">$jobname$suffix.idx" ) ||
- die "Cannot write to file $jobname$suffix.idx";
- $idxfile{$suffix} = $file;
- $linesatidxfile{$suffix} = 0;
- print( "New index file $jobname$suffix.idx\n" )
- if ( $verbose > 1 );
- }
- print ($file $line);
- $linesatidxfile{$suffix}++;
-}
-
-sub help {
- version();
- print "\n";
- usage();
- print
- "Split a single raw index file into multiple raw index files.\n".
- "Example: splitindex.pl foo.idx.\n".
- "\n".
- "Options:\n" .
- " -h, --help " .
- "\tshow this help and terminate\n" .
- " -m, --makeindex PROGNAME\n" .
- "\t\t\tcall PROGNAME instead of default \`makeindex\'.\n" .
- " -i, --identify EXPRESSION\n" .
- "\t\t\tuse regular EXPRESSION to match entries\n".
- "\t\t\t(see also option --resultis and --suffixis).\n".
- "\t\t\tDefault is \'$identify\'.\n".
- " -r, --resultis PATTERN\n" .
- "\t\t\tcreate line to be written from PATTERN after matching\n".
- "\t\t\tlines (see also option --identify).\n".
- "\t\t\tDefault is \'$lineis\'.\n".
- " -s, --suffixis PATTERN\n" .
- "\t\t\tcreate suffix to be used from PATTERN after matching\n".
- "\t\t\tlines (see also option --identify).\n".
- "\t\t\tDefault is \'$suffixis\'.\n".
- " -v, --verbose " .
- "\tbe more verbose\n".
- "\t\t\t(can be used multiple to increase verbosity)\n" .
- " --version " .
- "\tshow version and terminate\n";
- exit 0;
-}
-
-sub version {
- print "splitindex.pl 0.1\n" .
- "Copyright (c) 2002 Markus Kohm \<kohm\@gmx.de\>\n";
-}
-
-sub usage {
- my $text = "Usage: splitindex.pl [OPTION]... RAWINDEXFILE [MAKEINDEXOPTION]...\n";
- if ( $#_ >= 0 ) {
- print STDERR @_;
- print STDERR "\n$text";
- print STDERR "Try \`splitindex.pl --help\' for more information.\n";
- exit 1;
- } else {
- print $text;
- }
-}
diff --git a/Build/source/texk/texlive/linked_scripts/srcredact/srcredact.pl b/Build/source/texk/texlive/linked_scripts/srcredact/srcredact.pl
deleted file mode 100755
index 5908bde1e20..00000000000
--- a/Build/source/texk/texlive/linked_scripts/srcredact/srcredact.pl
+++ /dev/null
@@ -1,521 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-
-my $USAGE = <<END;
-srcredact - a program for redacting the sources
-
-Usage:
-
-srcredact [OPTIONS] -e audience [full_file]
-
-srcredact [OPTIONS] -u audience full_file [redacted_file]
-
-srcredact -l [full_file]
-
-srcredact -h|-v
-
-
-srcredact is the program to extract ``redacted versions'' of the master
-file (option -e) or to incorporate the changes in the redacted versions
-into the master file (``unextract'', option -u).
-
-The master file consists of chunks intended for different audiences.
-Each audience has a name, e.g. "classified", "unclssified", "expert"
-etc. Chunks are started and stopped by guard lines. Each guard line
-has the format (for the default TeX syntax)
-
- %<name1|name2|...>
-
-or
-
- %</name1|name2|...>
-
-In the first cases the text following the guard is included for the
-audiences "name1", "name2", .... In the second case it is excluded for
-these audiences.
-
-THere is a special audience "ALL": a wild card for all audiences. Thus
-the idiom
-
- %</ALL>
- %<classified>
-
-means that the chunk is excluded for all audiences but "classified"
-
-Exactly one of the options -e (extract) or -u (unextract) must be present.
-In the redact mode the non-option argument is the name of the full file.
-If it is absent, or is "-", standard input is used. In the unextract mode
-the first non-option argument
-
-OPTIONS
- -c list of comment patterns
- Use the given pattern for comment lines to search for guards instead
- of the default "TeX" pattern. The recognized patterns are:
-
- c
- /<guard>/
-
- cpp
- //<guard>
-
- fortran
- C<guard>
-
- shell
- #<guard>
-
- TeX
- %<guard>
-
- The pattern names should be separated by commas, and the list may be
- enclosed in quotes to prevent shell expansion, e.g
-
- -c "TeX, c, shell"
-
- -d Debug mode on.
-
- -e audience
- Extract the contents for the current audience into the file file.
- The cuurent audience is guessed from the file name, if the latter
- has the structure base-audience.extension, e.g.
- "report-unclassified.tex". The key -a overrides this guess and
- should be used if the file name does not follow this pattern. The
- file name "-" means the standard output.
-
- -h Print help information and exit.
-
- -l List all audiences set in the file (one per line) and exit.
-
- -u audience
- Take a redacted file intended for the audience (the second
- non-option argument) and incorporate the changes in it into the full
- file (the first non-option argument). If the second argument is
- missing, standard input is used instead. As usual, "-" also means
- standard input. Note that only one of the two file arguments in this
- case can be standard input.
-
- -v Print version information and exit.
-
- -w on|off|1|0|true|false
- If "on", 1 or "true" (the deafult), implicitly wrap the full
- document into the guards
-
- %<ALL>
- ...
- %</ALL>
-END
-
-
- my $COPYRIGHT= <<END;
-srcredact - a program for redacting the sources
-
-Copyright (C) 2015 Boris Veytsman. Version 1.0
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA
-END
-
-
-######################################################
-# Reading arguments
-######################################################
-
-use Getopt::Std;
-use File::Temp qw/tempdir/;
-
-our %opts;
-getopts ('c:de:hlu:vw:', \%opts) or do {
- print STDERR $USAGE;
- exit(2);
-};
-
-if ($opts{h}) {
- die ($USAGE);
-}
-
-if ($opts{v}){
- die ($COPYRIGHT);
-}
-
-my $DEBUG=0;
-if ($opts{d}) {
- $DEBUG=1;
-}
-
-
-my @commentPatterns;
-if ($opts{c}) {
- @commentPatterns=GetCommentPatterns($opts{c});
-} else {
- @commentPatterns=GetCommentPatterns('TeX');
-}
-
-# We want exactly one of the modes -l, -e, -u:
-my $audience;
-my $mode;
-my $modesFound=0;
-if ($opts{l}) {
- $mode = "list";
- $modesFound++;
-}
-if ($opts{e}) {
- $mode='extract';
- $audience = $opts{e};
- $modesFound++;
-}
-if ($opts{u}) {
- $mode = "unextract";
- $audience = $opts{u};
- $modesFound++;
-}
-
-if ($modesFound != 1) {
- print STDERR
- "Exactly one of the options -l, -e, -u must be present.\n\n$USAGE";
- exit (2);
-}
-
-my $wrap=1;
-if (exists $opts{w}) {
- if ($opts{w} eq '0' || $opts{w} =~ m/^off$/i ||
- $opts{w} =~ m/^false$/i) {
- $wrap=0;
- } elsif ($opts{w} eq '1' || $opts{w} =~ m/^on$/i ||
- $opts{w} =~ m/^true$/i) {
- $wrap=0;
- } else {
- print STDERR "Unknwon value for -w option: $opts{w}.\n" .
- "Must be 0|1|on|off|true|false\n";
- exit (2);
- }
-}
-
-if ($DEBUG) {
- print STDERR "Wrapping in <ALL> is $wrap\n";
-}
-
-# Opening files
-my $fullFH;
-my $newFH;
-
-# In 'l' or 'e' mode we need one or zero non-option arguments
-if (($mode eq 'list') || ($mode eq 'extract')) {
- if (scalar(@ARGV) == 0) {
- if ($DEBUG) {
- print STDERR "Usign stdin for full file\n";
- }
- $fullFH=*STDIN;
- } elsif (scalar(@ARGV) == 1) {
- my $full = shift @ARGV;
- if ($full eq '-') {
- if ($DEBUG) {
- print STDERR "Usign stdin for full file\n";
- }
- $fullFH = *STDIN;
- } else {
- if ($DEBUG) {
- print STDERR "Usign $full for full file\n";
- }
- open ($fullFH, "<", $full) or do {
- print STDERR "Cannot open file $full\n";
- exit (2);
- };
- }
- } else {
- print STDERR
- "Options -e and -l require one or zero non-option argument\n\n";
- print STDERR $USAGE;
- exit(2);
- }
-}
-
-# In 'u' mode we need one or two arguments
-if ($mode eq 'unextract') {
- if ((scalar(@ARGV) < 1) || (scalar(@ARGV) > 2)) {
- print STDERR
- "Option -u requires one or two non-option argument\n\n";
- print STDERR $USAGE;
- exit(2);
- }
-
- my $full = shift @ARGV;
- if ($full eq '-') {
- if ($DEBUG) {
- print STDERR "Usign stdin for full file\n";
- }
- $fullFH = *STDIN;
- } else {
- if ($DEBUG) {
- print STDERR "Usign $full for full file\n";
- }
- open ($fullFH, "<", $full) or do {
- print STDERR "Cannot open file $full\n";
- exit (2);
- };
- }
-
- if (scalar(@ARGV) == 0) {
- if ($DEBUG) {
- print STDERR "Usign stdin for redacted file\n";
- }
- $newFH=*STDIN;
- } else {
- my $redacted = shift @ARGV;
- if ($redacted eq '-') {
- if ($DEBUG) {
- print STDERR "Usign stdin for redacted file\n";
- }
- $newFH = *STDIN;
- } else {
- if ($DEBUG) {
- print STDERR "Usign $redacted for redacted file\n";
- }
- open ($newFH, "<", $redacted) or do {
- print STDERR "Cannot open file $redacted\n";
- exit (2);
- };
- }
- }
-}
-
-
-
-# And the real work
-if ($mode eq 'list') {
- if ($DEBUG) {
- print STDERR "List mode\n";
- }
- my @audiences=ListAudiences($fullFH, \@commentPatterns);
- print join("\n", @audiences), "\n";
- exit (0);
-}
-
-if ($mode eq 'extract') {
- if ($DEBUG) {
- print STDERR "Extract mode\n";
- }
- ExtractText($fullFH, \*STDOUT, $audience,
- \@commentPatterns, $wrap);
- exit (0);
-}
-
-if ($mode eq 'unextract') {
- if ($DEBUG) {
- print STDERR "Unextract mode\n";
- }
-
- my $exitCode = UnextractText($fullFH, $newFH, \*STDOUT,
- $audience, \@commentPatterns, $wrap);
-
- exit ($exitCode);
-
-}
-
-##################################################
-# Extracting comment patterns
-##################################################
-
-sub GetCommentPatterns {
-
- my %knownPatterns = ( 'c' => '^/\*<([^>]*)>\*/',
- 'cpp' => '^\/\/<([^>]*)>',
- fortran => '^C<([^>]*)>',
- shell => '^#<([^>]*)>',
- tex => '^%<([^>]*)>'
- );
-
-
-
- my $input = shift;
- if ($DEBUG) {
- print STDERR "Got pattern string $input\n";
- }
- $input =~ s/^\s*//;
- $input =~ s/\s*$//;
- my @languages = split /[\s,]\s*/, $input;
- my @patterns;
-
- foreach my $lang (@languages) {
- $lang =~ s/^(.*)$/\L$1\E/;
- if ($DEBUG) {
- print STDERR "Processing language $lang... ";
- }
- if (exists $knownPatterns{$lang}) {
- push @patterns, $knownPatterns{$lang};
- if ($DEBUG) {
- print STDERR "found pattern $knownPatterns{$lang}\n";
- }
- } else {
- print STDERR
- "Unknown comment language $lang. The supported languages are ",
- join(", ", keys %knownPatterns), "\n";
- exit(2);
- }
- }
-
- return @patterns;
-}
-
-##################################################
-# List audiences
-##################################################
-
-sub ListAudiences {
- my $fh=shift;
- my $patterns=shift;
- my %foundAudiences = ('ALL' => 1);
- while (<$fh>) {
- my @result = FindAudiences ($_, $patterns);
- if (scalar @result) {
- shift @result;
- foreach my $audience (@result) {
- $foundAudiences{$audience} = 1;
- }
- }
- }
- return (sort keys %foundAudiences);
-}
-
-##################################################
-# Check whether the line is a comment
-##################################################
-# Return 0 to delete, 1 to add, and the list of
-# audiences
-sub FindAudiences {
- my $line = shift;
- my $patterns=shift;
- foreach my $pattern (@{$patterns}) {
- if ($line =~ m/$pattern/) {
- if ($DEBUG) {
- print STDERR "Line $. is a guard: $line";
- }
- my $guards = $1;
- my @result;
- if (substr($guards,0,1) eq '*') {
- push @result, 1;
- } elsif (substr($guards,0,1) eq '/') {
- push @result, 0;
- } else {
- die "Wrong guard line $line\n";
- }
- @result = (@result, split(/\|/, substr($guards,1)));
- return @result;
- }
- }
- return ();
-}
-
-##################################################
-# Extracting text for the given audience
-##################################################
-sub ExtractText {
- my $fullFH=shift;
- my $outFH=shift;
- my $audience = shift;
- my $patterns = shift;
- my $state = shift;
-
- if ($DEBUG) {
- print STDERR "Initial state $state\n";
- }
-
- while (<$fullFH>) {
- my @result = FindAudiences ($_, $patterns);
- if (scalar @result) {
- my $newstate = shift @result;
- foreach my $tryaudience (@result) {
- if (($tryaudience eq 'ALL') ||
- ($audience eq $tryaudience)) {
- $state = $newstate;
- if ($DEBUG) {
- print STDERR "Changing state to $state\n";
- }
- last;
- }
- }
- } else { # Normal line
- if ($state) {
- print $outFH $_;
- }
- }
- }
-}
-
-################################################################
-# Merge files
-################################################################
-
-sub UnextractText {
- my $fullFH=shift;
- my $newFH=shift;
- my $outFH = shift;
- my $audience = shift;
- my $patterns = shift;
- my $state = shift;
-
- # Creating tempdir. We leave the tempdir in place in
- # the debug mode
- my $tmpdir = tempdir (CLEANUP => !$DEBUG);
- if ($DEBUG) {
- print STDERR "Creating directory $tmpdir\n";
- }
-
- open (FULL, ">$tmpdir/full") or do {
- print STDERR "Cannot open temporary file $tmpdir/full\n";
- return(2);
- };
-
- print FULL <$fullFH>;
- close FULL;
-
- open (FULL, "<$tmpdir/full") or do {
- print STDERR "Cannot open temporary file $tmpdir/full\n";
- return(2);
- };
-
- open (EXTRACTED, ">$tmpdir/extracted") or do {
- print STDERR "Cannot open temporary file $tmpdir/extracted\n";
- return(2);
- };
-
- if ($DEBUG) {
- print STDERR "Extracting text\n";
- }
-
- ExtractText(\*FULL, \*EXTRACTED, $audience,
- $patterns, $wrap);
-
- close FULL;
- close EXTRACTED;
-
- open (NEW, ">$tmpdir/new") or do {
- print STDERR "Cannot open temporary file $tmpdir/new\n";
- return(2);
- };
-
- print NEW <$newFH>;
- close NEW;
-
-
- if ($DEBUG) {
- print STDERR "Merging text\n";
- }
-
- print $outFH `diff3 -m $tmpdir/full $tmpdir/extracted $tmpdir/new`;
-
- return ${^CHILD_ERROR_NATIVE};
-
-}
diff --git a/Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl b/Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl
deleted file mode 100755
index e68b667141c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl
+++ /dev/null
@@ -1,1085 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-use warnings;
-use File::Basename qw(dirname);
-
-=head1 NAME
-
-sty2dtx -- Converts a LaTeX .sty file to a documented .dtx file
-
-=head1 VERSION
-
-Version: v2.3
-
-=head1 COPYRIGHT
-
-Copyright (c) 2010-2012 Martin Scharrer <martin@scharrer-online.de>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-=head1 DESCRIPTION
-
-Converts a .sty file (LaTeX package) to .dtx format (documented LaTeX source),
-by surrounding macro definitions with 'macro' and 'macrocode' environments.
-The macro name is automatically inserted as an argument to the 'macro'
-environemnt.
-Code lines outside macro definitions are wrapped only in 'macrocode'
-environments. Empty lines are removed.
-The script is not thought to be fool proof and 100% accurate but rather
-as a good start to convert undocumented style files to .dtx files.
-
-
-=head2 Basic Usage
-
- perl sty2dtx.pl infile [infile ...] outfile
-
-or
-
- perl sty2dtx.pl < file.sty > file.dtx
-
-=head2 Supported Definitions
-
-The following macro definitions are detected when they are at the start of a
-line (can be prefixed by \global, \long, \protected and/or \outer):
-
- \def \edef \gdef \xdef
- \newcommand{\name} \newcommand*{\name}
- \newcommand\name \newcommand*\name
- \renewcommand{\name} \renewcommand*{\name}
- \renewcommand\name \renewcommand*\name
- \providecommand{\name} \providecommand*{\name}
- \providecommand\name \providecommand*\name
- \@namedef{\name} \@namedef\name
-
-The following environment definitions are detected when they are at the start
-of a line:
-
- \newenvironment{name} \renewenvironemnt{name} \provideenvironment{name}
-
-The macro and environment definition must either end at the same line or with
-a 'C<}>' on its own on a line.
-
-
-=head1 USAGE
-
- sty2dtx [<options>] [--<VAR>=<VALUE> ...] [--] [<infile(s)>] [<outfile>]
-
-=head2 Files
-
-=over 2
-
-=item *
- can be 'C<->' for STDIN or STDOUT, which is the default if no files are given
-
-=item *
- multiple input files are merged to one output file
-
-=back
-
-=head2 Variables
-
-Variables can be defined using
-
- --<VAR>=<VALUE>
-
-or
-
- --<VAR> <VALUE>
-
-and will be used for substitutions in the template file.
-
-=head3 Common variables:
-
- author, email, maintainer, year (for copyright),
- version, date, description (of package/class),
- type (either 'package' default or 'class'),
- filebase (automatically set from output or input file name),
-
-
-=head2 Options
-
-=over 8
-
-=item B<-h> S< >
- Print this help text
-
-=item B<-H> S< >
- Print extended help
-
-=item B<-V> S< >
- Print version and copyright
-
-=item B<-v> S< >
- Be verbose
-
-=item B<-o> F<output> S< >
- Use given file as output
-
-=item B<-O> S< >
- Overwrite already existing output file(s)
-
-=item B<-B> S< >
- Use basename of single input file for output file
-
-=item B<-I> S< >
- Also create .ins (install) file
-
-=item B<-c> S< >
- Only use code section (like v1.0)
-
-=item B<-r> S< >
- Remove existing 'macro', 'macrocode', etc. environments.
-
-=item B<-R> S< >
- Do not remove existing 'macro', 'macrocode', etc. environments.
-
-=item B<-i> F<ins-file> S< >
- Create .ins file with given name
-
-=item B<-t> F<template> S< >
- Use this file as template instead of the default one
-
-=item B<-T> F<template> S< >
- Use this file as template for the .ins file
-
-=item B<-e> F<file> S< >
- Export default .dtx template to file and exit
-
-=item B<-E> F<file> S< >
- Export default .ins template to file and exit
-
-=item B<-D> S< >
- Use current date as file date
-
-=item B<-F> F<file> S< >
- Read more options and variables from file.
-
-=item B<-N> S< >
- Do not read default config file; must be the first option
-
-=back
-
-
-=head2 Config files
-
-A default config file either named 'sty2dtx.cfg' or '.sty2dtx.cfg' is searched
-in the current directory, the users home directory and the directory of this
-script, in this order. The first one found is loaded. If none is found the
-'texmf' tree is searched for a 'sty2dtx.cfg' config file. As with -F files the
-config file should contain one option or variable per line.
-Lines starting with 'C<%>' or 'C<#>' are ignored.
-
-
-=head1 Examples
-
-Produce 'file.dtx' from 'file.sty':
-
- sty2dtx.pl < file.sty > file.dtx
-
-or
-
- sty2dtx.pl file.sty file.dtx
-
-or
-
- sty2dtx.pl -B file.sty
-
-Produce 'file.dtx' and 'file.ins' from 'file.sty':
-
- sty2dtx.pl -I file.sty file.dtx
-
-or
-
- sty2dtx.pl file.sty -i file.sty file.dtx
-
-or
-
- sty2dtx.pl -IB file.sty
-
-Set custom variable values:
-
- sty2dtx.pl --author Me --email me@there.com mypkg.sty mypkg.dtx
-
-Produce DTX file for a class:
-
- sty2dtx.pl --type class mycls.sty mycls.dtx
-
-=head1 AUTHOR
-
-Martin Scharrer
-
-E-mail: L<martin@scharrer-online.de>
-
-WWW: L<http://www.scharrer-online.de>
-
-=cut
-
-################################################################################
-use Pod::Usage;
-
-my $VERSION = "v2.3";
-$VERSION =~ tr/-/\//;
-
-my $TITLE = << "EOT";
- sty2dtx -- Converts a LaTeX .sty file to a documented .dtx file
- Version: $VERSION
-EOT
-
-sub usage {
- print "Version: $VERSION\n\n";
- pod2usage(-message => $TITLE, -sections => 'USAGE', -verbose=>99 );
-}
-
-my $ERROR = "sty2dtx: Error:";
-
-# Used as format string of printf so that the '%' must be doubled:
-my $macrostart = <<'EOT';
-%%
-%% \begin{macro}{\%s}
-%s%% \begin{macrocode}
-EOT
-
-my $keystart = <<'EOT';
-%%
-%% \begin{key}{%s}{%s}
-%s%% \begin{macrocode}
-EOT
-
-my $environmentstart = <<'EOT';
-%%
-%% \begin{environment}{%s}
-%s%% \begin{macrocode}
-EOT
-
-my $macrodescription = <<'EOT';
-%%
-%% \DescribeMacro{\%s}
-%%
-EOT
-
-my $keydescription = <<'EOT';
-%%
-%% \DescribeKey{\%s}{\%s}
-%%
-EOT
-
-my $envdescription = <<'EOT';
-%%
-%% \DescribeEnv{%s}
-%%
-EOT
-
-# Printed normally:
-my $macrostop = <<'EOT';
-% \end{macrocode}
-% \end{macro}
-%
-EOT
-
-my $keystop = <<'EOT';
-% \end{macrocode}
-% \end{key}
-%
-EOT
-
-my $environmentstop = <<'EOT';
-% \end{macrocode}
-% \end{environment}
-%
-EOT
-
-my $macrocodestart = <<'EOT';
-% \begin{macrocode}
-EOT
-
-my $macrocodestop = <<'EOT';
-% \end{macrocode}
-EOT
-
-my $USAGE = q(); # Store macro names for usage section
-my $IMPL = q(); # Store implementation section
-
-my $mode = 0;
-# 0 = outside of macro or macrocode environments
-# 1 = inside 'macrocode' environment
-# 2 = inside 'macro' environment
-# 3 = inside 'environment' environment
-# 4 = inside 'key' environment
-
-# RegExs for macro names and defintion:
-my $rmacroname = qr/[a-zA-Z\@:]+/xms; # Add ':' for LaTeX3 style macros
-my $renvname = qr/[a-zA-Z\@:*]+/xms; #
-my $rusermacro = qr/[a-zA-Z]+/xms; # Macros intended for users
-my $rmacrodef = qr/
- ^ # Begin of line (no whitespaces!)
- (
- (?:(?:\\global|\\long|\\protected|\\outer)\s*)* # Prefixes (maybe with whitespace between them)
- )
- \\(
- [gex]?def \s* \\ # TeX definitions
- | (?:new|renew|provide)command\s* \*? \s* {? \s* \\ # LaTeX definitions
- | \@namedef{? # Definition by name only
- )
- ($rmacroname) # Macro name without backslash
- \s* }? # Potential closing brace
- (.*) # Rest of line
- /xms;
-
-my $rkeydef = qr/
- ^ # Begin of line (no whitespaces!)
- \\
- (define\@[a-z]*key)
- \s*
- {([^}]+)} # Key family
- \s*
- {([^}]+)} # Key name
- (.*) # Rest of line
- /xms;
-
-my $renvdef = qr/
- ^ # Begin of line (no whitespaces!)
- \\(
- (?:new|renew|provide)environment\s* { \s* # LaTeX definitions
- )
- ($renvname) # Environment names follow same rules as macro names
- \s* } # closing brace
- (.*) # Rest of line
- /xms;
-
-my $comments = q();
-
-# Print end of environment, if one is open
-sub close_environment {
- if ( $mode == 1 ) {
- $IMPL .= $macrocodestop;
- }
- elsif ( $mode == 2 ) {
- # Happens only if closing brace is not on a line by its own.
- $IMPL .= $macrostop;
- }
- elsif ( $mode == 3 ) {
- $IMPL .= $environmentstop;
- }
- elsif ( $mode == 4 ) {
- $IMPL .= $keystop;
- }
-}
-
-my ( $mday, $mon, $year ) = ( localtime(time) )[ 3 .. 5 ];
-$mon = sprintf( "%02d", $mon + 1 );
-$year += 1900;
-
-my @files;
-my $outfile = q();
-my $verbose = 0;
-my $codeonly = 0;
-my $install = 0;
-my $usebase = 0;
-my $overwrite = 0;
-my $removeenvs = 0;
-my $installfile;
-my $templfile;
-my $installtempl;
-my $checksum = 0;
-my $config_file;
-
-# Holds the variables for the templates, is initiated with default values:
-my %vars = (
- type => 'package',
- class => 'ltxdoc',
- year => "$year",
-);
-
-my $template = *DATA;
-my %OUTFILES;
-
-# Handle options
-sub option {
- my $opt = shift;
- if ( $opt eq 'h' ) {
- usage();
- }
- elsif ( $opt eq 'H' ) {
- pod2usage(-message => $TITLE, -sections => 'DESCRIPTION', -verbose=>99 );
- }
- elsif ( $opt eq 'r' ) {
- $removeenvs = 1;
- }
- elsif ( $opt eq 'R' ) {
- $removeenvs = 0;
- }
- elsif ( $opt eq 'c' ) {
- $codeonly = 1;
- }
- elsif ( $opt eq 'B' ) {
- $usebase = 1;
- }
- elsif ( $opt eq 't' ) {
- $templfile = shift @ARGV;
- }
- elsif ( $opt eq 'e' ) {
- my $templ = shift @ARGV;
- if ( $templ ne '-' ) {
- die "$ERROR '$templ' already exists\n" if -e $templ;
- open( STDOUT, '>', $templ )
- or die "$ERROR Couldn't open new template file '$templ' ($!)\n";
- }
- while (<DATA>) {
- last if /^__INS__$/;
- print;
- }
- print STDERR
- "Exported default template for .dtx files to file '$templ'\n"
- if $verbose;
- exit(0);
- }
- elsif ( $opt eq 'E' ) {
- my $templ = shift @ARGV;
- if ( $templ ne '-' ) {
- die "$ERROR '$templ' already exists\n" if -e $templ;
- open( STDOUT, '>', $templ )
- or die "$ERROR Couldn't open new template file '$templ' ($!)\n";
- }
- while (<DATA>) {
- last if /^__INS__$/;
- }
- while (<DATA>) {
- print;
- }
- print STDERR
- "Exported default template for .ins files to file '$templ'\n"
- if $verbose;
- exit(0);
- }
- elsif ( $opt eq 'v' ) {
- $verbose++;
- }
- elsif ( $opt eq 'I' ) {
- $install = 1;
- }
- elsif ( $opt eq 'i' ) {
- $installfile = shift @ARGV;
- $install = 1;
- }
- elsif ( $opt eq 'T' ) {
- $installtempl = shift @ARGV;
- }
- elsif ( $opt eq 'V' ) {
- pod2usage(-message => $TITLE, -sections => 'COPYRIGHT', -verbose=>99 );
- }
- elsif ( $opt eq 'N' ) {
- print STDERR "sty2dtx warning: '-N' option used after default config file was already loaded.\n"
- if $config_file && $verbose;
- }
- elsif ( $opt eq 'F' ) {
- my $optfile = shift @ARGV;
-
- # Read more options and variables from file
- open( my $OPT, '<', $optfile )
- or die("Couldn't open options file '$optfile' ($!)!\n");
- while ( my $line = <$OPT> ) {
- chomp $line;
-
- # Skip comment lines
- next if $line =~ /^\s*[#%]/;
-
- # Handle variables
- # Split at '=' or space and add as two arguments
- if ( $line =~ /\A\s*(--[a-zA-Z0-9]+?)(?:\s+|=)(.*)/xms ) {
- my $var = $1;
- (my $val = $2) =~ s/^["']|["']$//g;
- unshift @ARGV, $var, $val;
- }
- # Handle options with and without values
- # as well sets of options
- elsif ($line =~ /\A\s*(-[a-zA-Z0-9]+)(?:\s+(.*))?/xms) {
- my $var = $1;
- my $val = $2;
- if (defined $val) {
- $val =~ s/^["']|["']$//g;
- unshift @ARGV, $var, $val;
- }
- else {
- unshift @ARGV, $var;
- }
- }
- else {
- die "$ERROR Could not recognize '$line' in '$optfile'\n";
- }
- }
- close $OPT;
- }
- elsif ( $opt eq 'D' ) {
- $vars{date} = "$year/$mon/$mday";
- }
- elsif ( $opt eq 'o' ) {
- $outfile = shift @ARGV;
- }
- elsif ( $opt eq 'O' ) {
- $overwrite = 1;
- }
- elsif ( $opt eq 'A' ) {
- $template = shift @ARGV;
- }
- elsif ( $opt eq 'a' ) {
- my $outname = shift @ARGV;
- $OUTFILES{$outname} = $template;
- }
- else {
- print STDERR "sty2dtx: unknown option '-$opt'!\n";
- exit(2);
- }
-}
-
-# Count number of backslashes in code for file checksum
-sub addtochecksum {
- my $line = shift;
- $checksum += $line =~ tr{\\}{\\};
-}
-
-################################################################################
-
-my $CONFIG_NAME = "sty2dtx.cfg";
-
-if (!@ARGV || $ARGV[0] !~ /^-[^-]*N/) {
-
-PATH:
-foreach my $path ('.', $ENV{HOME}, dirname($0)) {
- foreach my $file ($path.'/'.$CONFIG_NAME, $path.'/.'.$CONFIG_NAME) {
- if (-e $file) {
- $config_file = $file;
- last PATH;
- }
- }
-}
-if (!$config_file) {
- # Find the config file in the TeX tree.
- $config_file = `kpsewhich -must-exist $CONFIG_NAME`;
-}
-if ($config_file) {
- chomp $config_file;
- print STDERR "sty2dtx info: loading config file '$config_file'.\n"
- if ($verbose);
- unshift @ARGV, '-F', $config_file;
-}
-
-}
-
-# Parse arguments
-while (@ARGV) {
- my $arg = shift;
-
- # '--' Marks rest of arguments as files
- if ( $arg eq '--' ) {
- push @files, @ARGV;
- last;
- }
-
- # Options and variables
- elsif ( $arg =~ /^(-+)(.+)$/ ) {
- my $dashes = $1;
- my $name = $2;
-
- # Single dash => option
- if ( length($dashes) == 1 ) {
- foreach my $opt ( split //, $name ) {
- option($opt);
- }
- }
- # Douple Dash => Variable
- # Form "--var=value"
- elsif ($name =~ /^([^=]+)=(.*)$/) {
- $vars{lc($1)} = $2;
- }
- # Form "--var value"
- else {
- if ($name eq "help") {
- usage();
- }
- else {
- $vars{ lc($name) } = shift;
- }
- }
- }
- # Files
- else {
- push @files, $arg;
- }
-}
-
-
-# Last (but not only) argument is output file, except if it is '-' (=STDOUT)
-if ( $outfile || @files > 1 ) {
- $outfile = pop @files unless $outfile;
- $vars{filebase} = substr( $outfile, 0, rindex( $outfile, '.' ) )
- if not exists $vars{filebase};
-}
-elsif ( @files == 1 ) {
- my $infile = $files[0];
- $vars{filebase} = substr( $infile, 0, rindex( $infile, '.' ) )
- if not exists $vars{filebase};
- if ($usebase) {
- $outfile = $vars{filebase} . '.dtx';
- }
-}
-if ( $outfile && $outfile ne '-' ) {
- if ( !$overwrite && -e $outfile && $outfile ne '/dev/null' ) {
- die( "$ERROR output file '$outfile' does already exists!"
- . " Use the -O option to overwrite.\n" );
- }
- open( OUTPUT, '>', $outfile )
- or die("$ERROR Could not open output file '$outfile' ($!)!");
- select OUTPUT;
-}
-
-
-################################################################################
-# Read input files
-@ARGV = @files;
-while (<>) {
- # Test for macro definition command
- if (/$rmacrodef/) {
- my $pre = $1 || ""; # before command
- my $cmd = $2; # definition command
- my $name = $3; # macro name
- my $rest = $4; # rest of line
-
- MACRO:
-
- # Add to usage section if it is a user level macro
- if ( $name =~ /^$rusermacro$/i ) {
- $USAGE .= sprintf( $macrodescription, $name );
- }
-
- close_environment();
-
- # Print 'macro' environment with current line.
- $IMPL .= sprintf( $macrostart, $name, $comments );
- addtochecksum($_);
- $IMPL .= $_;
- $comments = '';
-
- # Inside macro mode
- $mode = 2;
-
- # Test for one line definitions.
- # $pre is tested to handle '{\somecatcodechange\gdef\name{short}}' lines
- my $prenrest = $pre . $rest;
- if ( $prenrest =~ tr/{/{/ == $prenrest =~ tr/}/}/ ) {
- $IMPL .= $macrostop;
- # Outside mode
- $mode = 0;
- }
- }
- elsif (/$rkeydef/) {
- my $pre = ""; # before command
- my $cmd = $1; # definition command
- my $keyfamily = $2; # macro name
- my $keyname = $3; # macro name
- my $rest = $4; # rest of line
-
- # Add to usage section if it is a user level macro
- $USAGE .= sprintf( $keydescription, $keyfamily, $keyname );
-
- close_environment();
-
- # Print 'key' environment with current line.
- $IMPL .= sprintf( $keystart, $keyfamily, $keyname, $comments );
- addtochecksum($_);
- $IMPL .= $_;
- $comments = '';
-
- # Inside key mode
- $mode = 4;
-
- # Test for one line definitions.
- # $pre is tested to handle '{\somecatcodechange\gdef\name{short}}' lines
- my $prenrest = $pre . $rest;
- if ( $prenrest =~ tr/{/{/ == $prenrest =~ tr/}/}/ ) {
- $IMPL .= $keystop;
- # Outside mode
- $mode = 0;
- }
- }
- # Test for environment definition command
- elsif (/$renvdef/) {
- my $cmd = $1; # definition command
- my $name = $2; # macro name
- my $rest = $3; # rest of line
-
- # Add to usage section if it is a user level environment
- # Can use the same RegEx as for macro names
- if ( $name =~ /^$rusermacro$/i ) {
- $USAGE .= sprintf( $envdescription, $name );
- }
-
- close_environment();
-
- # Print 'environment' environment with current line.
- $IMPL .= sprintf( $environmentstart, $name, $comments );
- addtochecksum($_);
- $IMPL .= $_;
- $comments = '';
-
- # Inside environment mode
- $mode = 3;
-
- # Test for one line definitions.
- my $nopen = ( $rest =~ tr/{/{/ );
- if ( $nopen >= 2 && $nopen == ( $rest =~ tr/}/}/ ) ) {
- $IMPL .= $environmentstop;
- # Outside mode
- $mode = 0;
- }
- }
- # Collect comment lines, might be inserted as macro or environment description
- # Real comments are either: 1) starting with a '%' at SOL or 2) are followed
- # by at least one whitespace. This exclude (most) commented out code.
- elsif (/^%|^\s*%\s/) {
- if (!$removeenvs || !/^%\s+\\(?:begin|end){(?:macro|environment|macrocode|key)}/) {
- $_ =~ s/^\s*//;
- if ($comments || !/^%\s*$/){
- $comments .= $_;
- }
- }
- if ( $mode == 1 ) {
- $IMPL .= $macrocodestop;
- $mode = 0;
- }
- }
- # Remove empty lines (mostly between macros)
- elsif (/^$/) {
- if ($comments) {
- # Flush collected outside comments
- $IMPL .= $comments . "%\n";
- $comments = '';
- }
- }
- else {
- addtochecksum($_);
- # If inside an environment
- if ($mode) {
- if ($comments) {
- $IMPL .= $macrocodestop . $comments . $macrocodestart;
- $comments = '';
- }
- $IMPL .= $_;
- # A single '}' on a line ends a 'macro' or 'environment' environment
- if ( $mode > 1 && /^\}\s*$/ ) {
- $IMPL .= ( $mode == 2 ) ? $macrostop :
- ( $mode == 3 ) ? $environmentstop : $keystop;
- $mode = 0;
- }
- }
- else {
- # Start macrocode environment
- $IMPL .= $comments . $macrocodestart . $_;
- $mode = 1;
- $comments = '';
- }
- }
-}
-
-close_environment();
-
-################################################################################
-# Set extra/auto variables
-$vars{IMPLEMENTATION} = $IMPL;
-$vars{USAGE} = $USAGE;
-$vars{type} = "\L$vars{type}";
-$vars{Type} = "\L\u$vars{type}";
-$vars{extension} = $vars{type} eq 'class' ? 'cls' : 'sty';
-$vars{checksum} = $checksum if not exists $vars{checksum}; # Allow user to overwrite
-$vars{maintainer} = $vars{author}
- if not exists $vars{maintainer} and exists $vars{author};
-
-################################################################################
-# Write DTX file
-if ($codeonly) {
- print $IMPL;
- if ($verbose) {
- print STDERR "Generated DTX file";
- print STDERR " '$outfile'" if $outfile and $outfile ne '-';
- print STDERR " (code only).\n";
- }
-}
-else {
- if ($templfile) {
- open( DTX, '<', $templfile )
- or die "$ERROR Couldn't open template file '$templfile' ($!)\n";
- }
- else {
- *DTX = *DATA;
- }
- while (<DTX>) {
- last if !$templfile and /^__INS__$/;
- # Substitute template variables
- s/<\+([^+]+)\+>/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg;
- print;
- }
-
- if ($verbose) {
- print STDERR "Generated DTX file";
- print STDERR " '$outfile'" if $outfile and $outfile ne '-';
- print STDERR " using template '$templfile'" if $templfile;
- print STDERR ".\n";
- }
-}
-select STDOUT;
-################################################################################
-# Write INS file if requested
-if ($install) {
-
- if ( ( !$outfile || $outfile eq '-' ) && !$installfile ) {
- print STDERR
- "Warning: Did not generate requested .ins file because main file\n";
- print STDERR " was written to STDOUT and no -i option was given.\n";
- exit(1);
- }
-
- if ($installtempl) {
- open( DATA, '<', $installtempl )
- or die "$ERROR Could't open template '$installtempl' for .ins file! ($!)\n";
- }
- elsif ($codeonly || $templfile) {
- # If DATA template was not used for main file go forward to correct position
- while (<DATA>) {
- last if /^__INS__$/;
- }
- }
-
- $installfile = $vars{filebase} . '.ins' unless defined $installfile;
- if ( !$overwrite && -e $installfile && $installfile ne '/dev/null' ) {
- die( "$ERROR Output file '$installfile' does already exists!"
- . " Use the -O option to overwrite.\n" );
- }
- open( INS, '>', $installfile )
- or die "$ERROR Could't open new .ins file '$installfile' ($!)\n";
-
- while (<DATA>) {
- # Substitute template variables
- s/<\+([^+]+)\+>/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg;
- print INS $_;
- }
-
- if ($verbose) {
- print STDERR "Generated INS file '$installfile'";
- print STDERR " using template '$installtempl'" if $installtempl;
- print STDERR ".\n";
- }
-
-}
-
-################################################################################
-# Write additional files if requested
-while (my ($outfile, $template) = each %OUTFILES) {
- my $TEMPLATEHANDLE;
- if (ref $template eq 'GLOB') {
- $TEMPLATEHANDLE = $template;
- }
- # TODO: add support for DTX and INS templates in DATA
- else {
- open( $TEMPLATEHANDLE, '<', $template )
- or die "$ERROR Could't open template '$template' for file '$outfile' ($!)!\n";
- }
- open( my $OUTFILEHANDLE, '>', $outfile )
- or die "$ERROR Could't create output file '$outfile' ($!)!\n";
-
- while (<$TEMPLATEHANDLE>) {
- # Substitute template variables
- s/<\+([^+]+)\+>/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg;
- print {$OUTFILEHANDLE} $_;
- }
- close $TEMPLATEHANDLE;
- close $OUTFILEHANDLE;
-
- if ($verbose) {
- print STDERR "Generated file '$outfile' using template '$template'.\n";
- }
-}
-################################################################################
-exit (0);
-################################################################################
-# The templates for the DTX file and INS file
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Adepted from the skeleton file provided by the 'dtxtut' (DTX tuturial).
-# The '<+var+>' format was choosen because it is used by the latex suite for Vim.
-# Therfore all variables which are not expanded are easily accessible to the
-# user using a certain feature in the latex suite.
-#
-# Perl modules like 'Template' were not used to support minimal Perl installation
-# for typical LaTeX installations.
-#
-__DATA__
-% \iffalse meta-comment
-%
-% Copyright (C) <+year+> by <+author+> <<+email+>>
-% ---------------------------------------------------------------------------
-% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
-% of this license or (at your option) any later version.
-% The latest version of this license is in
-% http://www.latex-project.org/lppl.txt
-% and version 1.3 or later is part of all distributions of LaTeX
-% version 2005/12/01 or later.
-%
-% This work has the LPPL maintenance status `maintained'.
-%
-% The Current Maintainer of this work is <+maintainer+>.
-%
-% This work consists of the files <+filebase+>.dtx and <+filebase+>.ins
-% and the derived filebase <+filebase+>.<+extension+>.
-%
-% \fi
-%
-% \iffalse
-%<*driver>
-\ProvidesFile{<+filebase+>.dtx}
-%</driver>
-%<<+type+>>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
-%<<+type+>>\Provides<+Type+>{<+filebase+>}
-%<*<+type+>>
- [<+date+> <+version+> <+description+>]
-%</<+type+>>
-%
-%<*driver>
-\documentclass{ltxdoc}
-\usepackage{<+filebase+>}[<+date+>]
-\EnableCrossrefs
-\CodelineIndex
-\RecordChanges
-\begin{document}
- \DocInput{<+filebase+>.dtx}
- \PrintChanges
- \PrintIndex
-\end{document}
-%</driver>
-% \fi
-%
-% \CheckSum{<+checksum+>}
-%
-% \CharacterTable
-% {Upper-case \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
-% Lower-case \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
-% Digits \0\1\2\3\4\5\6\7\8\9
-% Exclamation \! Double quote \" Hash (number) \#
-% Dollar \$ Percent \% Ampersand \&
-% Acute accent \' Left paren \( Right paren \)
-% Asterisk \* Plus \+ Comma \,
-% Minus \- Point \. Solidus \/
-% Colon \: Semicolon \; Less than \<
-% Equals \= Greater than \> Question mark \?
-% Commercial at \@ Left bracket \[ Backslash \\
-% Right bracket \] Circumflex \^ Underscore \_
-% Grave accent \` Left brace \{ Vertical bar \|
-% Right brace \} Tilde \~}
-%
-%
-% \changes{<+version+>}{<+date+>}{Converted to DTX file}
-%
-% \DoNotIndex{\newcommand,\newenvironment}
-%
-% \providecommand*{\url}{\texttt}
-% \GetFileInfo{<+filebase+>.dtx}
-% \title{The \textsf{<+filebase+>} package}
-% \author{<+author+> \\ \url{<+email+>}}
-% \date{\fileversion~from \filedate}
-%
-% \maketitle
-%
-% \section{Introduction}
-%
-% Put text here.
-%
-% \section{Usage}
-%
-% Put text here.
-%
-<+USAGE+>
-%
-% \StopEventually{}
-%
-% \section{Implementation}
-%
-% \iffalse
-%<*<+type+>>
-% \fi
-%
-<+IMPLEMENTATION+>
-%
-% \iffalse
-%</<+type+>>
-% \fi
-%
-% \Finale
-\endinput
-__INS__
-%% Copyright (C) <+year+> by <+author+> <<+email+>>
-%% --------------------------------------------------------------------------
-%% This work may be distributed and/or modified under the
-%% conditions of the LaTeX Project Public License, either version 1.3
-%% of this license or (at your option) any later version.
-%% The latest version of this license is in
-%% http://www.latex-project.org/lppl.txt
-%% and version 1.3 or later is part of all distributions of LaTeX
-%% version 2005/12/01 or later.
-%%
-%% This work has the LPPL maintenance status `maintained'.
-%%
-%% The Current Maintainer of this work is <+maintainer+>.
-%%
-%% This work consists of the files <+filebase+>.dtx and <+filebase+>.ins
-%% and the derived filebase <+filebase+>.<+extension+>.
-%%
-
-\input docstrip.tex
-\keepsilent
-
-\usedir{tex/latex/<+filebase+>}
-
-\preamble
-
-This is a generated file.
-
-Copyright (C) <+year+> by <+author+> <<+email+>>
---------------------------------------------------------------------------
-This work may be distributed and/or modified under the
-conditions of the LaTeX Project Public License, either version 1.3
-of this license or (at your option) any later version.
-The latest version of this license is in
- http://www.latex-project.org/lppl.txt
-and version 1.3 or later is part of all distributions of LaTeX
-version 2005/12/01 or later.
-
-\endpreamble
-
-\generate{\file{<+filebase+>.<+extension+>}{\from{<+filebase+>.dtx}{<+type+>}}}
-
-\obeyspaces
-\Msg{*************************************************************}
-\Msg{* *}
-\Msg{* To finish the installation you have to move the following *}
-\Msg{* file into a directory searched by TeX: *}
-\Msg{* *}
-\Msg{* <+filebase+>.<+extension+> *}
-\Msg{* *}
-\Msg{* To produce the documentation run the file <+filebase+>.dtx *}
-\Msg{* through LaTeX. *}
-\Msg{* *}
-\Msg{* Happy TeXing! *}
-\Msg{* *}
-\Msg{*************************************************************}
-
-\endbatchfile
diff --git a/Build/source/texk/texlive/linked_scripts/svn-multi/svn-multi.pl b/Build/source/texk/texlive/linked_scripts/svn-multi/svn-multi.pl
deleted file mode 100755
index 9f0b44adb04..00000000000
--- a/Build/source/texk/texlive/linked_scripts/svn-multi/svn-multi.pl
+++ /dev/null
@@ -1,372 +0,0 @@
-#!/usr/bin/perl
-# --------------------------------------------------------------
-# svn-multi.pl for the svn-multi v2.0 LaTeX package
-# version 0.1, Mar 1st, 2009
-# --------------------------------------------------------------
-#
-# Copyright (C) 2006-2012 Martin Scharrer
-# E-mail: martin@scharrer-online.de
-# Code repository: https://bitbucket.org/martin_scharrer/svn-multi
-#
-# This program works only in combination with the LaTeX package 'svn-multi' and
-# generates .svx files with '\svnidlong' macros holding Subversion keywords for
-# files declared with '\svnexternal' inside the LaTeX document.
-#
-# This program is free software under the GPL v3 and LPPL v1.3c or later.
-#
-#
-# GPL v3:
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
-# LPPL v1.3c:
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.3c
-# of this license or (at your option) any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3c or later is part of all distributions of LaTeX
-# version 2008/05/04 or later.
-#
-# This work has the LPPL maintenance status `maintained'.
-#
-# The Current Maintainer of this work is Martin Scharrer.
-#
-# This work consists of the files svn-multi.dtx, svn-multi-pl.dtx and
-# svn-multi.ins and the derived files svn-multi.sty, svnkw.sty and svn-multi.pl.
-#
-# The file 'svn-multi.pl' may be renamed to 'svn-multi' for installation
-# purposes.
-#
-#
-use strict;
-use warnings;
-use File::Basename;
-my $VERSION = "0.2";
-my ($REV,$DATE) =
- (split ' ','$Id$')[2,3];
-
-my $dollar = '$';
-my @PATH;
-my %EXCLUDE = map { $_ => 1 } qw(sty tex aux log out toc fff ttt svn svx);
-
-sub create_svxfile ($@);
-sub usage;
-
-if (!@ARGV or grep { $_ eq '--help' or $_ eq '-h' } @ARGV) {
- usage();
-}
-
-print STDOUT "This is svn-multi.pl, Version $VERSION-$REV, $DATE\n";
-
-my ($jobname, $dir, $suffix) = fileparse(shift @ARGV, qr/\.(tex|ltx|dtx|svn)$/);
-if ($dir && $dir ne './') {
- printf STDOUT "Main directory is '$dir'.\n";
- chdir($dir);
-}
-
-if ($jobname =~ /^-/) {
- usage();
-}
-my $outfile = "$jobname.svx";
-
-my %external;
-
-my $resvnexternalpath = qr/
- ^ # at begin of line
- \s* # allow for spaces
- \\\@svnexternalpath # the macro name
- \s*
- { # begin token group
- \s*
- (?: # paths:
- { # { of first path
- (.*) # everything else, e.g: 'patha}{pathb}{pathc'
- } # } of last path
- | # or nothing
- )
- \s*
- } # end token group
- \s*
- $ # end of line
- /x;
-
-my $resvnexternal = qr/
- ^ # at begin of line
- \s* # allow for spaces
- \\\@svnexternal # the macro name
- \s*
- (?: # optional:
- \[ # opening [
- ([^\]]*) # group name (everything until ])
- \] # closing ]
- )?
- \s*
- { # begin token group
- ([^}]+) # file name (everything until })
- } # end token group
- \s*
- { # begin token group
- \s*
- (?: # paths:
- { # { of first file
- (.*) # everything else, e.g: 'filea}{fileb}{filec'
- } # } of last file
- | # or nothing
- )
- \s*
- } # end token group
- \s*
- $ # end of line
- /x;
-
-if (-e "$jobname.aux" and open( my $svnfh, '<', "$jobname.aux")) {
- print STDOUT "Reading '$jobname.aux'.\n";
- while (<$svnfh>) {
- chomp;
- if (/$resvnexternalpath/) {
- push @PATH, ( split /}\s*{/, $1 );
- }
- elsif (/$resvnexternal/) {
- my ($group,$file,$list) = ($1||"",$2,$3||"");
- $file =~ s/^\.\///;
- push @{$external{$file}{$group} ||= []}, ( split /}\s*{/, $list );
- }
- }
- close ($svnfh);
-}
-else {
- warn "No .aux file found for '$jobname'!\n";
-}
-
-# Add TEXINPUTS to path
-push @PATH, map { $_ =~ s/(?<!\/)$/\//; $_ } grep { $_ }
- split(':', $ENV{'TEXINPUTS'}||"");
-
-my @mainfilepairs;
-my $maintex = "$jobname.tex";
-if (exists $external{$maintex}) {
- while ( my ($group,$list) = each %{$external{$maintex}} ) {
- push @mainfilepairs, [ $group, [ @$list ] ];
- }
- delete $external{$maintex};
-}
-
-push @mainfilepairs, parse_args(@ARGV);
-create_svxfile("$jobname.svx", @mainfilepairs )
- if @mainfilepairs;
-
-foreach my $file (keys %external) {
- my @pairs;
- my $svxfile = $file;
- $svxfile =~ s/\.(tex|ltx)$/.svx/;
- while ( my ($group,$list) = each %{$external{$file}} ) {
- push @pairs, [ $group, [ @$list ] ];
- }
- create_svxfile($svxfile, @pairs);
-}
-
-
-sub parse_args {
- my @args = @_;
- my $group = '';
- my @files;
- my $readfg;
- my @pairs;
-
- foreach my $arg (@args) {
- if ($readfg) {
- $readfg = 0;
- $group = $arg;
- $group =~ s/^["']|["']$//; # '
- }
- elsif ($arg =~ /^--group|^-?-fg/) {
- push @pairs, [ $group, [ @files ] ];
- @files = ();
- if ($arg =~ /^--group=(.*)/) {
- $group = $1;
- $group =~ s/^["']|["']$//; # '
- }
- else {
- $readfg = 1;
- }
- }
- elsif ($arg =~ /^--fls/) {
- push @files, read_fls("$jobname.fls");
- }
- else {
- push @files, $arg;
- }
- }
- push @pairs, [ $group, [ @files ] ] if @files;
- return @pairs;
-}
-
-sub path_search {
- my $file = shift;
- $file =~ s/##/#/g;
- return $file if not $file or -e $file or not @PATH;
-
- foreach my $dir (@PATH) {
- if (-e "$dir$file") {
- return "$dir$file";
- }
- }
-
- return $file;
-}
-
-sub create_svxfile ($@) {
- my ($svxfile, @fgpair) = @_;
- my $lastgroup;
- my $fgused = 0;
- my %seen;
- return if not @fgpair or not $svxfile;
-
- open(my $svxfh, '>', $svxfile) or do {
- warn "ERROR: Could not create SVX file '$svxfile'!\n";
- return;
- };
- print STDOUT "Generating .svx file '$svxfile'.\n";
- select $svxfh;
- print "% Generated by svn-multi.pl v$VERSION\n\n";
-
- while ( my ($group, $files) = @{shift @fgpair||[]}) {
- no warnings 'uninitialized';
- if ( (not defined $lastgroup and $group) or ($group ne $lastgroup) ) {
- print "\\svngroup{$group}\n";
- }
- use warnings;
- if ($group) {
- $fgused = 1;
- }
-
- foreach my $file (@$files) {
- $file = path_search($file);
-
- # Only print the file once per group and .svx file
- next if $seen{$group}{$file};
- $seen{$group}{$file} = 1;
-
- open(my $infoh, '-|', "svn info '$file' 2>/dev/null") or next;
- my %info = map { chomp; split /\s*:\s*/, $_, 2 } <$infoh>;
- close($infoh);
- if (not keys %info) {
- print "% Could not receive keywords for '$file'!\n\n";
- next;
- }
- print "% Keywords for '$file'\n";
- print svnidlong(\%info);
- print "\\svnexternalfile";
- print "[$group]" if $group;
- print "{$file}\n";
- print "\n"
- }
-
- $lastgroup = $group;
- }
- print "\n";
- close ($svxfh);
-}
-
-sub svnid {
- use Date::Parse;
- use Date::Format;
- my $href = shift;
- return "" if (not defined $href->{Name});
- my $date = time2str("%Y-%m-%d %XZ", str2time($href->{'Last Changed Date'}), 'Z');
- return <<"EOT";
-\\svnid{${dollar}Id: $href->{Name} $href->{'Last Changed Rev'} $date $href->{'Last Changed Author'} \$}
-EOT
-}
-
-sub svnidlong {
- my $href = shift;
- return <<"EOT";
-\\svnidlong
-{${dollar}HeadURL: $href->{URL} \$}
-{${dollar}LastChangedDate: $href->{'Last Changed Date'} \$}
-{${dollar}LastChangedRevision: $href->{'Last Changed Rev'} \$}
-{${dollar}LastChangedBy: $href->{'Last Changed Author'} \$}
-EOT
-}
-
-sub read_fls {
- my $fls = shift;
- my %stack;
- open (my $fh, '<', $fls) or return;
- while (<$fh>) {
- chomp;
- if (/^INPUT ([^\/].*)$/) {
- my $file = $1;
- my $ext = substr($file, rindex($file,'.')+1);
- $stack{$1} = 1 if not exists $EXCLUDE{$ext};
- }
- }
- close($fh);
- return keys %stack;
-}
-
-sub usage {
- print STDOUT <<'EOT';
-Usage:
- svn-multi.pl jobname[.tex] [--fls] [--group|-g <group name>] [input_files] ...
- ... [--group|-g <group name>] [input_files] ...
-
-Description:
- This LaTeX helper script collects Subversion keywords from non-(La)TeX files
- and provides it to the 'svn-multi' package using '.svx' files. It will first
- scan the file '<jobname>.aux' for files declared by the '\svnextern' macro but
- also allows to provide additional files including the corresponding groups. The
- keywords for the additional files will be written in the file '<jobname>.svx'.
-
-Options:
- jobname[.tex] : The LaTeX `jobname`, i.e. the basename of your main LaTeX file.
- --group <GN> : Use given group name <GN> for all following files,
- or -g <GN> including the one read by a '--fls' option, until the next
- group is specified.
- --fls : Read list of (additional) files from the file '<jobname>.fls'. This
- file is produced by LaTeX when run with the '--recorder' option and
- contains a list of all input and output files used by the LaTeX main
- file. Only input files with a relative path will be used. A
- previously selected group will be honoured.
-
-Examples:
-The main LaTeX file here is 'mymainlatexfile.tex'.
-
- svn-multi.pl mymainlatexfile
- Creates Subversion keywords for all files declared by '\svnextern' inside
- the LaTeX code.
-
- svn-multi.pl mymainlatexfile --group=FLS --fls
- Creates Subversion keywords for all files declared by '\svnextern' inside
- the LaTeX code. In addition it does the same for all relative input files
- mentioned in the .fls file which are placed in the 'FLS' group.
-
- svn-multi.pl mymainlatexfile a b c --group=B e d f
- In addition to the '\svnextern' declared files the keywords for the files
- 'a', 'b' and 'c' will be added without a specific group, i.e. the last group
- specified in the LaTeX file before the '\svnextern' macro will be used. The
- keywords for 'e', 'd', 'f' will be part of group 'B'.
-
- svn-multi.pl mymainlatexfile --group=A a --group=B b --group='' c
- File 'a' is in group 'A', 'b' is in 'B' and 'c' is not in any group.
-
-Further Information:
-See the svn-multi package manual for more information about this script.
-EOT
- exit(0);
-}
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook b/Build/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook
deleted file mode 100755
index 91df031ffb7..00000000000
--- a/Build/source/texk/texlive/linked_scripts/tex4ebook/tex4ebook
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/env texlua
--- Package tex4ebook. Author Michal Hoftich <michal.h21@gmail.com>
--- This package is subject of LPPL license, version 1.3
---
-kpse.set_program_name("luatex")
-require("lapp-mk4")
--- require("ebookutils")
-logging = require "make4ht-logging"
-if os.type == "windows" then logging.use_colors = false end
-local log = logging.new("tex4ebook")
-local ebookutils = require "mkutils"
-local mkparams = require "mkparams"
-local mk_config = require "make4ht-config"
-
--- Setting
-local latex_cmd="latex"
-local copy_cmd="copy"
-local move_cmd="move"
-local env_param="%%"
-local htlatex_call=""
--- These correspond to htlatex parameters
-local tex4ht_sty_par=""
-local tex4ht_par=""
-local t4ht_par=""
-local latex_par=""
-local output_formats={epub=true,mobi=true,epub3=true,azw=true, azw3=true}
-local executor=nil
-local tidy = false
-local include_fonts = false
-
--- message used for option parsing by the mkparams lib
-local arg_message = [[
-tex4ebook - ebook generation support for LaTeX
-Usage:
-tex4ebook [switches] filename ["tex4ht.sty op."] ["tex4ht op."] ["t4ht op"] ["latex op"]
- -a,--loglevel (default status) Set log level.
- possible values: debug, info, status, warning, error, fatal
- -c,--config (default xhtml) Custom config file
- -d,--output-dir (default nil) Output directory
- -e,--build-file (default nil) If build file is different than `filename`.mk4
- -f,--format (default epub) Output format. Supported values: epub, epub3, mobi
- -h,--help Display help message
- -j,--jobname (default nil) Set the jobname
- -l,--lua Use lualatex for document compilation
- -m,--mode (default default) Switch which can be used in the makefile
- -r,--resolution (default 167)
- -s,--shell-escape Enable shell escape in htlatex run
- -t,--tidy Run html tidy on html output. May result in wrong spacing!
- -x,--xetex Use xelatex for document compilation
- -v,--version Display version number
- ]]
-
--- options for the template used by mkparams to generate the help message
-local mkparams_parameters = {
- progname = "tex4ebook",
- issue_tracker = "https://github.com/michal-h21/tex4ebook/issues"
-}
-
--- process the command line arguments
-local args = mkparams.get_args(mkparams_parameters, arg_message)
-
-if args["filename"] == nil and args["version"] == false then
- print(arg_message)
- return
-else
- input_file=args["filename"]
-end
-
-if args.version then
- print "tex4ebook v0.3c"
- return
-end
-
-if args.lua then
- latex_cmd="dvilualatex"
-elseif args.xetex then
- latex_cmd="xelatex --no-pdf"
-end
-
-
-if args["shell-escape"] then
- latex_par = latex_par .. " -shell-escape"
-end
-
-if args["include-fonts"] then
- include_fonts = true
-end
-
-local mode = args.mode or "default"
-
-if os.type=="unix" then
- env_param="$"
- copy_cmd="cp"
- move_cmd="mv"
- t4ht_dir_format="%s/"
-else
- env_param="%%"
- copy_cmd="copy"
- move_cmd="move"
- t4ht_dir_format="%s"
-end
-
-if args.tidy then
- tidy = true
-else
- tidy = false
-end
-
-local sty_args = ""
-if args[2] then
- sty_args = "," .. args[2]
-end
-local tex4ht_sty_par = tex4ht_sty_par + sty_args --args[2]
-local tex4ht_par = tex4ht_par +args[3]
-local t4ht_par = t4ht_par + args[4]
-local latex_par = latex_par + args[5]
-
--- use default parameter processing from make4ht
--- add some needed args (is it useful anymore?)
-args.filename=input_file
-
--- let make4ht handle the common options
-local params = mkparams.process_args(args)
-local input = params.input
-log:status("Conversion started")
-log:status("Input file: ".. params.tex_file)
-
-
-local output_format = params.output_format
--- use epub as default output_format
-output_format = output_format or "epub"
--- load common_domfilters extension by default
-local extensions = ebookutils.add_extensions("+common_domfilters", params.extensions)
-extensions = ebookutils.load_extensions(extensions, output_format)
--- but also support tex4ebook!s own parameters
-local oldparams = {
- -- htlatex=latex_cmd
- -- ,input=input
- -- ,tex_file = tex_file
- format = output_format
- -- ,latex_par=latex_par
- -- ,tex4ht_sty_par=tex4ht_sty_par
- -- ,tex4ht_par=tex4ht_par
- -- ,t4ht_par=t4ht_par
- -- ,mode = mode
- ,t4ht_dir_format=t4ht_dir_format
- ,tidy = tidy
- ,include_fonts = include_fonts
- ,resolution=args.resolution
- ,packages="\\RequirePackage{tex4ebook}"
-}
-
--- extend params
-for k,v in pairs(oldparams) do
- params[k] = v
-end
-
-params.tex4ht_sty_par=params.tex4ht_sty_par .. ",charset=utf-8,"..output_format
-params.tex4ht_par= " -cmozhtf -utf8" .. params.tex4ht_par
-
-
-
--- find tex4ebook configuration file
-local configname = "tex4ebook"
-local conffile = mk_config.find_config(configname) or mk_config.find_xdg_config(configname)
-if conffile then
- log:info("Using configuration file: " .. conffile)
- ebookutils.load_config(params, conffile)
-else
- log:info "No conffile"
-end
-
-local build_file = input.. ".mk4"
-
-if args["build-file"] and args["build-file"] ~= "nil" then
- build_file = args["build-file"]
-end
-
-local config_file = ebookutils.load_config(params, build_file)
-
-params["config_file"] = config_file
-
-
-if output_formats[output_format] then
- executor=require("tex4ebook-exec_"..output_format)
- params=executor.prepare(params)
- if #extensions > 0 then
- params = ebookutils.extensions_prepare_parameters(extensions,params)
- end
-else
- log:error("Unknown output format: "..output_format)
- return
-end
---config_file.Make:run()
--- print("${htlatex} ${input} \"${tex4ht_sty_par}\" \"${tex4ht_par}\" \"${t4ht_par}\" \"${latex_par}\"" % params)
-if #extensions > 0 then
- config_file.Make = ebookutils.extensions_modify_build(extensions, config_file.Make)
-end
-
-executor.run(input,params)
-executor.writeContainer()
-executor.clean()
-log:status("Conversion finished")
---print(args[1])
diff --git a/Build/source/texk/texlive/linked_scripts/texcount/texcount.pl b/Build/source/texk/texlive/linked_scripts/texcount/texcount.pl
deleted file mode 100755
index 1dcb8adcd6b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texcount/texcount.pl
+++ /dev/null
@@ -1,4017 +0,0 @@
-#! /usr/bin/env perl
-use strict;
-use warnings;
-use utf8; # Because the script itself is UTF-8 encoded
-use Encode;
-use Text::Wrap;
-use Term::ANSIColor;
-
-# System variables
-my $terminalwidth;
-
-# Conditional package inclusion
-if ($^O=~/^MSWin/) {
- eval {
- require Win32::Console::ANSI;
- import Win32::Console::ANSI;
- };
- if ($@) {
- option_ansi_colours(0);
- print STDERR "NOTE: Package Win32::Console::ANSI required for colour coded output.\n";
- }
-}
-
-# Terminal or not
-if (-t STDOUT) { # If in terminal
- eval {
- require Term::ReadKey;
- import Term::ReadKey;
- ($terminalwidth)=GetTerminalSize();
- };
-} else {
- option_ansi_colours(0);
-}
-
-if (!defined $terminalwidth) {$terminalwidth=76;}
-elsif ($terminalwidth<60) {$terminalwidth=60;}
-elsif ($terminalwidth>120) {$terminalwidth=120;}
-
-
-##### Version information
-
-my $versionnumber="3.1.1";
-my $versiondate="2018 Oct 28";
-
-###### Set global constants and names
-
-### Global data about TeXcount
-my %GLOBALDATA=
- ('versionnumber' => $versionnumber
- ,'versiondate' => $versiondate
- ,'maintainer' => 'Einar Andreas Rodland'
- ,'copyrightyears' => '2008-2018'
- ,'website' => 'http://app.uio.no/ifi/texcount/'
- );
-
-### Named constants
-my ($INCLUDE_NONE,$INCLUDE_AFTER,$INCLUDE_MERGE)=(0,1,2); # Value of $includeTeX
-my ($HTML_NONE,$HTML_CORE,$HTML_FULL)=(0,1,2); # Value of $htmlstyle
-
-
-
-###### Set global settings and variables
-
-### Options and states
-
-# Outer object (for error reports not added by a TeX object)
-my $Main=getMain();
-
-# Global options and settings
-my $htmlstyle=$HTML_NONE; # Flag to print HTML
-my $texcodeoutput=0; # Flag to convert output to valid TeX text
-my $encoding=undef; # Selected input encoding (default will be guess)
-my @encodingGuessOrder=qw/ascii utf8 latin1/; # Encoding guessing order
-my $outputEncoding; # Encoding used for output
-my @AlphabetScripts=qw/Digit Is_alphabetic/; # Letters minus logograms: defined later
-my @LogogramScripts=qw/Ideographic Katakana Hiragana Thai Lao Hangul/; # Scripts counted as whole words
-
-# Parsing rules options
-my $includeTeX=$INCLUDE_NONE; # Flag to parse included files
-my $includeBibliography=0; # Flag to include bibliography
-my %substitutions; # Substitutions to make globally
-my %IncludedPackages; # List of included packages
-
-# Counting options
-my @sumweights; # Set count weights for computing sum
-my $optionWordFreq=0; # Count words of this frequency, or don't count if 0
-my $optionWordClassFreq=0; # Count words per word class (language) if set
-my $optionMacroStat=0; # Count macro, environment and package usage
-
-# Parsing details options
-my $strictness=0; # Flag to check for undefined environments
-my $defaultVerbosity='0'; # Specification of default verbose output style
-my $defaultprintlevel=0; # Flag indicating default level of verbose output
-my $printlevel=undef; # Flag indicating level of verbose output
-my $showstates=0; # Flag to show internal state in verbose log
-my $showcodes=1; # Flag to show overview of colour codes (2=force)
-my $showsubcounts=0; # Write subcounts if #>this, or not (if 0)
-my $separatorstyleregex='^word'; # Styles (regex) after which separator should be added
-my $separator=''; # Separator to add after words/tokens
-
-# Final summary output options
-my $showVersion=0; # Indicator that version info be included (1) or not (-1)
-my $totalflag=0; # Flag to write only total summary
-my $briefsum=0; # Flag to set brief summary
-my $outputtemplate; # Output template
-my $finalLineBreak=1; # Add line break at end
-
-# Global settings
-my $optionFast=1; # Flag inticating fast method
-
-# Global variables and internal states (for internal use only)
-my $blankline=0; # Number of blank lines printed
-my $errorcount=0; # Number of errors in parsing
-my %warnings=(); # Warnings
-my %WordFreq; # Hash for counting words
-my %MacroUsage; # Hash for counting macros, environments and packages
-
-# External sources
-my $HTMLfile; # HTML file to use as HTML output template
-my $CSSfile; # CSS file to use with HTML output
-my $CSShref; # CSS reference to use with HTML output
-my @htmlhead; # Lines to add to the HTML header
-my $htmlopen; # text used to open the HTML file
-my $htmlclose; # text used to close the HTML file
-
-# String data storage
-my $STRINGDATA;
-
-# Other constants
-my $_PARAM_='<param>'; # to identify parameter to _parse_unit
-my $STRING_PARAMETER='{_}'; # used to log macro parameters
-my $STRING_OPTIONAL_PARAM='[_]'; # used to log optional parameter
-my $STRING_GOBBLED_OPTION='[]'; # used to log gobbled macro option
-my $STRING_ERROR='<error>'; # used to log errors causing parsing to stop
-my $REGEX_NUMBER=qr/^\d+$/; # regex to recognize a number
-
-
-###### Set CMD specific settings and variables
-
-## Preset command line options
-# List of options (stings) separated by comma,
-# e.g. ('-inc','-v') to parse included files and
-# give verbose output by default.
-my @StartupOptions=();
-
-# CMD specific global variables
-my @filelist; # List of files to parse
-my $globalworkdir='./'; # Overrules workdir (default=present root)
-my $workdir; # Current directory (default=taken from filename)
-my $auxdir; # Directory for auxilary files, e.g. bbl (default=$workdir)
-my $fileFromSTDIN=0; # Flag to set input from STDIN
-my $_STDIN_='<STDIN>'; # File name to represent STDIN (must be '<...>'!)
-
-# CMD specific settings
-$Text::Wrap::columns=$terminalwidth; # Page width for wrapped output
-
-
-###### Set state identifiers and methods
-
-
-### Counter indices from 0 to $SIZE_CNT-1
-# 0: Number of files
-# 1: Text words
-# 2: Header words
-# 3: Caption words
-# 4: Number of headers
-# 5: Number of floating environments
-# 6: Number of inlined math
-# 7: Number of displayed math
-my $SIZE_CNT=8;
-my $SIZE_CNT_DEFAULT=8;
-my $CNT_FILE=0;
-my $CNT_WORDS_TEXT=1;
-my $CNT_WORDS_HEADER=2;
-my $CNT_WORDS_OTHER=3;
-my $CNT_COUNT_HEADER=4;
-my $CNT_COUNT_FLOAT=5;
-my $CNT_COUNT_INLINEMATH=6;
-my $CNT_COUNT_DISPLAYMATH=7;
-
-# Labels used to describe the counts
-my @countkey=('file','word','hword','oword','header','float','inmath','dsmath');
-my @countdesc=('Files','Words in text','Words in headers',
- 'Words outside text (captions, etc.)','Number of headers','Number of floats/tables/figures',
- 'Number of math inlines','Number of math displayed');
-
-# Map keywords to counters
-my %key2cnt;
-add_keys_to_hash(\%key2cnt,$CNT_FILE,0,'file');
-add_keys_to_hash(\%key2cnt,$CNT_WORDS_TEXT,1,'text','word','w','wd');
-add_keys_to_hash(\%key2cnt,$CNT_WORDS_HEADER,2,'headerword','hword','hw','hwd');
-add_keys_to_hash(\%key2cnt,$CNT_WORDS_OTHER,3,'otherword','other','oword','ow','owd');
-add_keys_to_hash(\%key2cnt,$CNT_COUNT_HEADER,4,'header','heading','head');
-add_keys_to_hash(\%key2cnt,$CNT_COUNT_FLOAT,5,'float','table','figure');
-add_keys_to_hash(\%key2cnt,$CNT_COUNT_INLINEMATH,6,'inline','inlinemath','imath','eq');
-add_keys_to_hash(\%key2cnt,$CNT_COUNT_DISPLAYMATH,7,'displaymath','dsmath','dmath','ds');
-
-
-### Token types
-# Set in $tex->{'type'} by call to _next_token
-my $TOKEN_SPACE=-1;
-my $TOKEN_COMMENT=0;
-my $TOKEN_WORD=1; # word (or other form of text or text component)
-my $TOKEN_SYMBOL=2; # symbol (not word, e.g. punctuation)
-my $TOKEN_MACRO=3; # macro (\name)
-my $TOKEN_BRACE=4; # curly braces: { }
-my $TOKEN_BRACKET=5; # brackets: [ ]
-my $TOKEN_MATH=6;
-my $TOKEN_LINEBREAK=9; # line break in file
-my $TOKEN_TC=666; # TeXcount instructions (%TC:instr)
-my $TOKEN_END=999; # end of line or blank line
-
-
-### Parsing states
-#
-## States for regions that should not be counted
-# IGNORE = exclude from count
-# FLOAT = float (exclude, but include captions)
-# EXCLUDE_STRONG = strong exclude, ignore environments
-# EXCLUDE_STRONGER = stronger exclude, do not parse macro parameters
-# EXCLUDE_ALL = ignore everything except end marker: even {
-# PREAMBLE = preamble (between \documentclass and \begin{document})
-## States for regions in which words should be counted
-# TEXT = text
-# TEXT_HEADER = header text
-# TEXT_FLOAT = float text
-## State change: not used in parsing, but to switch state then ignore contents
-# TO_INLINEMATH = switch to inlined math
-# TO_DISPLAYMATH = switch to displayed math
-## Other states
-# _NULL = default state to use if none other is defined
-# _OPTION = state used to indicate that the next parameter is an option
-# _EXCLUDE_ = cutoff, state <= this represents excluded text
-## NB: Presently, it is assumed that additional states is added as 8,9,...,
-## e.g. that states added through TC:newcounter correspond to the added counters.
-#
-my $STATE_IGNORE=-1;
-my $STATE_MATH=-2;
-my $STATE_FLOAT=-10;
-my $STATE_EXCLUDE_STRONG=-20;
-my $STATE_EXCLUDE_STRONGER=-30;
-my $STATE_EXCLUDE_ALL=-40;
-my $STATE_SPECIAL_ARGUMENT=-90;
-my $STATE_PREAMBLE=-99;
-my $STATE_TEXT=1;
-my $STATE_TEXT_HEADER=2;
-my $STATE_TEXT_FLOAT=3;
-my $STATE_TO_HEADER=4;
-my $STATE_TO_FLOAT=5;
-my $STATE_TO_INLINEMATH=6;
-my $STATE_TO_DISPLAYMATH=7;
-my $__STATE_EXCLUDE_=-10;
-my $__STATE_NULL=1;
-my $_STATE_OPTION=-1000;
-my $_STATE_NOOPTION=-1001;
-my $_STATE_AUTOOPTION=-1002;
-
-# Counter key mapped to STATE
-my $PREFIX_PARAM_OPTION=' '; # Prefix for parameter options/modifiers
-my %key2state;
-add_keys_to_hash(\%key2state,$STATE_TEXT,1,'text','word','w','wd');
-add_keys_to_hash(\%key2state,$STATE_TEXT_HEADER,2,'headertext','headerword','hword','hw','hwd');
-add_keys_to_hash(\%key2state,$STATE_TEXT_FLOAT,3,'otherword','other','oword','ow','owd');
-add_keys_to_hash(\%key2state,$STATE_TO_HEADER,4,'header','heading','head');
-add_keys_to_hash(\%key2state,$STATE_TO_FLOAT,5,'float','table','figure');
-add_keys_to_hash(\%key2state,$STATE_TO_INLINEMATH,6,'inline','inlinemath','imath','eq');
-add_keys_to_hash(\%key2state,$STATE_TO_DISPLAYMATH,7,'displaymath','dsmath','dmath','ds');
-add_keys_to_hash(\%key2state,$STATE_IGNORE,0,'ignore','x');
-add_keys_to_hash(\%key2state,$STATE_MATH,'ismath');
-add_keys_to_hash(\%key2state,$STATE_FLOAT,-1,'isfloat');
-add_keys_to_hash(\%key2state,$STATE_EXCLUDE_STRONG,-2,'xx');
-add_keys_to_hash(\%key2state,$STATE_EXCLUDE_STRONGER,-3,'xxx');
-add_keys_to_hash(\%key2state,$STATE_EXCLUDE_ALL,-4,'xall');
-add_keys_to_hash(\%key2state,$STATE_SPECIAL_ARGUMENT,'specarg','spescialarg','specialargument');
-add_keys_to_hash(\%key2state,$_STATE_OPTION,'[',' option',' opt',' optional');
-add_keys_to_hash(\%key2state,$_STATE_NOOPTION,'nooption','nooptions','noopt','noopts');
-add_keys_to_hash(\%key2state,$_STATE_AUTOOPTION,'autooption','autooptions','autoopt','autoopts');
-
-# When combining two states, use the first one; list must be complete!
-my @STATE_FIRST_PRIORITY=(
- $STATE_EXCLUDE_ALL,
- $STATE_EXCLUDE_STRONGER,
- $STATE_EXCLUDE_STRONG,
- $STATE_SPECIAL_ARGUMENT,
- $STATE_FLOAT,
- $STATE_MATH,
- $STATE_IGNORE,
- $STATE_PREAMBLE,
- $STATE_TO_FLOAT,
- $STATE_TO_HEADER,
- $STATE_TO_INLINEMATH,
- $STATE_TO_DISPLAYMATH);
-my @STATE_MID_PRIORITY=();
-my @STATE_LAST_PRIORITY=(
- $STATE_TEXT_FLOAT,
- $STATE_TEXT_HEADER,
- $STATE_TEXT);
-
-# Map state to corresponding word counter
-my %state2cnt=(
- $STATE_TEXT => $CNT_WORDS_TEXT,
- $STATE_TEXT_HEADER => $CNT_WORDS_HEADER,
- $STATE_TEXT_FLOAT => $CNT_WORDS_OTHER);
-
-# Transition state mapped to content state and counter
-my %transition2state=(
- $STATE_TO_HEADER => [$STATE_TEXT_HEADER,$CNT_COUNT_HEADER],
- $STATE_TO_INLINEMATH => [$STATE_MATH ,$CNT_COUNT_INLINEMATH],
- $STATE_TO_DISPLAYMATH => [$STATE_MATH ,$CNT_COUNT_DISPLAYMATH],
- $STATE_TO_FLOAT => [$STATE_FLOAT ,$CNT_COUNT_FLOAT]);
-
-# Parsing state descriptions (used for macro rule help)
-my %state2desc=(
- $STATE_IGNORE => 'ignore: do not count',
- $STATE_MATH => 'math/equation contents',
- $STATE_FLOAT => 'float (figure, etc.): ignore all but special macros',
- $STATE_EXCLUDE_STRONG => 'strong exclude: ignore environments',
- $STATE_EXCLUDE_STRONGER => 'stronger exclude: ignore environments and macro paramters',
- $STATE_EXCLUDE_ALL => 'exlude all: even {, only scan for end marker',
- $STATE_PREAMBLE => 'preamble: from \documentclass to \begin{document}',
- $STATE_SPECIAL_ARGUMENT => 'special macro argument that TeXcount may process further',
- $STATE_TEXT => 'text: count words',
- $STATE_TEXT_HEADER => 'header text: count words as header words',
- $STATE_TEXT_FLOAT => 'float text: count words as float words (e.g. captions)',
- $STATE_TO_HEADER => 'header: count header, then count words as header words',
- $STATE_TO_FLOAT => 'float: count float, then count words as float/other words',
- $STATE_TO_INLINEMATH => 'inline math: count as inline math/equation',
- $STATE_TO_DISPLAYMATH => 'displayed math: count as displayed math/equation',
- $_STATE_OPTION => 'rule for [] option follows',
- $_STATE_NOOPTION => 'no [] options allowed here',
- $_STATE_AUTOOPTION => 'automatic [] option gobbling');
-
-# Short state name for each state for use with -showstates
-my %state2key = ($STATE_PREAMBLE=>'pre');
-for my $key ('x','xx','xxx','xall','w','hw','ow','eq','ds',
- 'head','float','isfloat','ismath','specarg') {
- $state2key{$key2state{$key}}=$key;
-}
-
-# Parsing state presentation style
-my %state2style=(
- $STATE_TEXT => 'word',
- $STATE_TEXT_HEADER => 'hword',
- $STATE_TEXT_FLOAT => 'oword',
- );
-
-# State: is a text state..."include state" is more correct
-sub state_is_text {
- my $st=shift @_;
- return ($st>=$STATE_TEXT);
-}
-
-# State: is a parsed/included region, text or preamble
-sub state_is_parsed {
- my $st=shift @_;
- return ($st>=$STATE_TEXT || $st==$STATE_PREAMBLE);
-}
-
-# State: get CNT corresponding to text state (or undef)
-sub state_text_cnt {
- my $st=shift @_;
- return $state2cnt{$st};
-}
-
-# State: is an exclude state
-sub state_is_exclude {
- my $st=shift @_;
- return ($st<=$__STATE_EXCLUDE_);
-}
-
-# State: \begin and \end should be processed
-sub state_inc_envir {
- my $st=shift @_;
- return ($st>$STATE_EXCLUDE_STRONG);
-}
-
-# State as text (used with printstate)
-# TODO: Should do a conversion based on STATE values.
-sub state_to_text {
- my $st=shift @_;
- my $statename = $state2key{$st};
- if (defined $statename) {$st=$statename;}
- return $st;
-}
-
-# Style to use with text state
-sub state_to_style {
- return $state2style{shift @_};
-}
-
-# Add new counter with the given key and description
-sub add_new_counter {
- my ($key,$desc,$like)=@_;
- my $state=$SIZE_CNT;
- my $cnt=$SIZE_CNT;
- $key=lc($key);
- if (!defined $like){$like=$CNT_WORDS_OTHER;}
- $key2cnt{$key}=$cnt;
- push @countkey,$key;
- push @countdesc,$desc;
- if (defined $sumweights[$like]) {$sumweights[$cnt]=$sumweights[$like];}
- $key2state{$key}=$state;
- $state2key{$state}=$key;
- $state2cnt{$state}=$cnt;
- $state2style{$state}='altwd';
- push @STATE_MID_PRIORITY,$state;
- $SIZE_CNT++;
-}
-
-
-###### Set global definitions
-
-
-### Break points
-# Definition of macros that define break points that start a new subcount.
-# The values given are used as labels.
-my %BreakPointsOptions;
-$BreakPointsOptions{'none'}={};
-$BreakPointsOptions{'part'}={%{$BreakPointsOptions{'none'}},'\part'=>'Part'};
-$BreakPointsOptions{'chapter'}={%{$BreakPointsOptions{'part'}},'\chapter'=>'Chapter'};
-$BreakPointsOptions{'section'}={%{$BreakPointsOptions{'chapter'}},'\section'=>'Section'};
-$BreakPointsOptions{'subsection'}={%{$BreakPointsOptions{'section'}},'\subsection'=>'Subsection'};
-$BreakPointsOptions{'default'}=$BreakPointsOptions{'subsection'};
-my %BreakPoints=%{$BreakPointsOptions{'none'}};
-
-### Print styles
-# Definition of different print styles: maps of class labels
-# to ANSI codes. Class labels are as used by HTML styles.
-my %STYLES;
-my $STYLE_EMPTY=' ';
-my $STYLE_BLOCK='-';
-my $NOSTYLE=' ';
-$STYLES{'Errors'}={'error'=>'bold red','note'=>'bold white'};
-$STYLES{'Words'}={'word'=>'blue','hword'=>'bold blue','oword'=>'blue','altwd'=>'blue'};
-$STYLES{'Macros'}={'cmd'=>'green','fileinc'=>'bold green','special'=>'bold red','specarg'=>'red'};
-$STYLES{'Options'}={'option'=>'yellow','optparm'=>'green'};
-$STYLES{'Ignored'}={'ignore'=>'cyan','math'=>'magenta'};
-$STYLES{'Excluded'}={'exclcmd'=>'yellow','exclenv'=>'yellow','exclmath'=>'yellow','mathcmd'=>'yellow'};
-$STYLES{'Groups'}={'document'=>'bold red','envir'=>'red','mathgroup'=>'magenta'};
-$STYLES{'Comments'}={'tc'=>'bold yellow','comment'=>'yellow'};
-$STYLES{'Sums'}={'cumsum'=>'yellow'};
-$STYLES{'States'}={'state'=>'cyan underline'};
-$STYLES{'<core>'}={%{$STYLES{'Errors'}},$STYLE_EMPTY=>$NOSTYLE,'<printlevel>'=>1,'note'=>'bold white'};
-$STYLES{0}={%{$STYLES{'Errors'}},'<printlevel>'=>0,'note'=>'bold white'};
-$STYLES{1}={%{$STYLES{'<core>'}},%{$STYLES{'Words'}},%{$STYLES{'Groups'}},%{$STYLES{'Sums'}}};
-$STYLES{2}={%{$STYLES{1}},%{$STYLES{'Macros'}},%{$STYLES{'Ignored'}},%{$STYLES{'Excluded'}}};
-$STYLES{3}={%{$STYLES{2}},%{$STYLES{'Options'}},%{$STYLES{'Comments'}},'<printlevel>'=>2};
-$STYLES{4}={%{$STYLES{3}},%{$STYLES{'States'}}};
-$STYLES{'All'}=$STYLES{4};
-my %STYLE=%{$STYLES{$defaultVerbosity}};
-
-my @STYLE_LIST=('error','word','hword','oword','altwd',
- 'ignore','document','special','cmd','exclcmd',
- 'option','optparm','envir','exclenv','specarg',
- 'mathgroup','exclmath','math','mathcmd','comment','tc','fileinc','state','cumsum');
-my %STYLE_DESC=(
- 'error' => 'ERROR: TeXcount error message',
- 'word' => 'Text which is counted: counted as text words',
- 'hword' => 'Header and title text: counted as header words',
- 'oword' => 'Caption text and footnotes: counted as caption words',
- 'altwd' => 'Words in user specified counters: counted in separate counters',
- 'ignore' => 'Ignored text or code: excluded or ignored',
- 'document' => '\documentclass: document start, beginning of preamble',
- 'special' => 'Special macros, eg require special handling or have side-effects',
- 'cmd' => '\macro: macro not counted, but parameters may be',
- 'exclcmd' => '\macro: macro in excluded region',
- 'option' => '[Macro options]: not counted',
- 'optparm' => '[Optional parameter]: content parsed and styled as counted',
- 'specarg' => 'Special argument, eg with side-effects',
- 'envir' => '\begin{name} \end{name}: environment',
- 'exclenv' => '\begin{name} \end{name}: environment in excluded region',
- 'mathgroup' => '$ $: counted as one equation',
- 'exclmath' => '$ $: equation in excluded region',
- 'math' => '2+2=4: maths (inside $...$ etc.)',
- 'mathcmd' => '$\macro$: macros inside maths',
- 'comment' => '% Comments: not counted',
- 'tc' => '%TC:TeXcount instructions: not counted',
- 'fileinc' => 'File to include: not counted but file may be counted later',
- 'state' => '[state]: internal TeXcount state',
- 'cumsum' => '[cumsum]: cumulative sum count');
-
-
-###### Define what a word is and language options
-
-
-# Patters matching a letter. Should be a single character or
-# ()-enclosed regex for substitution into word pattern regex.
-my @LetterMacros=qw/ae AE o O aa AA oe OE ss
- alpha beta gamma delta epsilon zeta eta theta iota kappa lamda
- mu nu xi pi rho sigma tau upsilon phi chi psi omega
- Gamma Delta Theta Lambda Xi Pi Sigma Upsilon Phi Psi Omega
- /;
-my $specialchars='\\\\('.join('|',@LetterMacros).')(\{\}|\s+|\b)';
-my $modifiedchars='\\\\[\'\"\`\~\^\=](@|\{@\})';
-my %NamedLetterPattern;
-$NamedLetterPattern{'restricted'}='@';
-$NamedLetterPattern{'default'}='('.join('|','@',$modifiedchars,$specialchars).')';
-$NamedLetterPattern{'relaxed'}=$NamedLetterPattern{'default'};
-my $LetterPattern=$NamedLetterPattern{'default'};
-
-# List of regexp patterns that should be analysed as words.
-# Use @ to represent a letter, will be substituted with $LetterPattern.
-# Named patterns may replace or be appended to the original patterns.
-# Apply_Options() results in a call to apply_language_options() which
-# constructs $WordPattern based on $LetterPattern, @WordPatterns and
-# alphabet/logogram settings.
-my %NamedWordPattern;
-$NamedWordPattern{'letters'}='@';
-$NamedWordPattern{'words'}='(@+|@+\{@+\}|\{@+\}@+)([\-\'\.]?(@+|\{@+\}))*';
-my @WordPatterns=($NamedWordPattern{'words'});
-my $WordPattern; # Regex matching a word (defined in apply_language_options())
-
-### Macro option regexp list
-# List of regexp patterns to be gobbled as macro option in and after
-# a macro.
-my %NamedMacroOptionPattern;
-$NamedMacroOptionPattern{'default'}='\[[^\[\]\n]*\]';
-$NamedMacroOptionPattern{'relaxed'}='\[\n?([^\[\]\n]\n?)*\]';
-$NamedMacroOptionPattern{'restricted'}='\[(\w|[,\-\s\~\.\:\;\+\?\*\_\=])*\]';
-my $MacroOptionPattern=$NamedMacroOptionPattern{'default'};
-
-### Alternative language encodings
-my %NamedEncodingGuessOrder;
-$NamedEncodingGuessOrder{'chinese'}=[qw/utf8 gb2312 big5/];
-$NamedEncodingGuessOrder{'japanese'}=[qw/utf8 euc-jp iso-2022-jp jis shiftjis/];
-$NamedEncodingGuessOrder{'korean'}=[qw/utf8 euc-kr iso-2022-kr/];
-
-
-
-###### Define character classes (alphabets)
-
-
-### Character classes to use as Unicode properties
-
-# Character group representing digits 0-9 (more restrictive than Digits)
-sub Is_digit { return <<END;
-0030\t0039
-END
-}
-
-# Character group representing letters (excluding logograms)
-sub Is_alphabetic { return <<END;
-+utf8::Alphabetic
--utf8::Ideographic
--utf8::Katakana
--utf8::Hiragana
--utf8::Thai
--utf8::Lao
--utf8::Hangul
-END
-}
-
-# Character group representing letters (excluding logograms)
-sub Is_alphanumeric { return <<END;
-+utf8::Alphabetic
-+utf8::Digit
--utf8::Ideographic
--utf8::Katakana
--utf8::Hiragana
--utf8::Thai
--utf8::Lao
--utf8::Hangul
-END
-}
-
-# Character class for punctuation excluding special characters
-sub Is_punctuation { return <<END;
-+utf8::Punctuation
--0024\t0025
--005c
--007b\007e
-END
-}
-
-# Character group representing CJK characters
-sub Is_cjk { return <<END;
-+utf8::Han
-+utf8::Katakana
-+utf8::Hiragana
-+utf8::Hangul
-END
-}
-
-# Character group for CJK punctuation characters
-sub Is_cjkpunctuation { return <<END;
-3000\t303f
-2018\t201f
-ff01\tff0f
-ff1a\tff1f
-ff3b\tff3f
-ff5b\tff65
-END
-}
-
-
-###### Define core rules
-
-### Macros indicating package inclusion
-# Will always be assumed to take one extra parameter which is the list of
-# packages. Macro handling rule indicates parameters ignored prior to that.
-# Gets added to TeXmacro. After that, values are not used, only membership.
-# Handling is otherwise hard-coded rather than rule based.
-my %TeXpackageinc;
-add_keys_to_hash(\%TeXpackageinc,['[','ignore','specialargument'],'\usepackage','\RequirePackage');
-
-### Macros that are counted within the preamble
-# The preamble is the text between \documentclass and \begin{document}.
-# Text and macros in the preamble is ignored unless specified here. The
-# value is the states (1=text, 2=header, etc.) they should be interpreted as.
-# Note that only the first unit (token or {...} block) is counted.
-# Gets added to TeXmacro. Is used within preambles only.
-my %TeXpreamble;
-add_keys_to_hash(\%TeXpreamble,['header'],'\title');
-add_keys_to_hash(\%TeXpreamble,['other'],'\thanks');
-add_keys_to_hash(\%TeXpreamble,['xxx','xxx'],'\newcommand','\renewcommand');
-add_keys_to_hash(\%TeXpreamble,['xxx','xxx','xxx'],'\newenvironment','\renewenvironment');
-
-### In floats: include only specific macros
-# Macros used to identify caption text within floats.
-# Gets added to TeXmacro. Is used within floats only.
-my %TeXfloatinc=('\caption'=>['otherword']);
-
-### How many tokens to gobble after macro
-# Each macro is assumed to gobble up a given number of
-# tokens (or {...} groups), as well as options [...] before, within
-# and after. The %TeXmacro hash gives a link from a macro
-# (or beginNAME for environment with no the backslash)
-# to either an integer giving the number of tokens to ignore
-# or to an array (specified as [rule,rule,...]) of length N where
-# N is the number of parameters to be read with the macro. The
-# array values tell how each is to be interpreted (see the parser state
-# keywords for valid values). Thus specifying a number N is
-# equivalent to specifying an array of N 'ignore' rules.
-#
-# For macros not specified here, the default value is 0: i.e.
-# no tokens are excluded, but [...] options are.
-my %TeXmacro=(%TeXpreamble,%TeXfloatinc,%TeXpackageinc);
-add_keys_to_hash(\%TeXmacro,['text'],
- '\textnormal','\textrm','\textit','\textbf','\textsf','\texttt','\textsc','\textsl','\textup','\textmd',
- '\makebox','\mbox','\framebox','\fbox','\uppercase','\lowercase','\textsuperscript','\textsubscript',
- '\citetext');
-add_keys_to_hash(\%TeXmacro,['[','text'],
- '\item');
-add_keys_to_hash(\%TeXmacro,['[','ignore'],
- '\linebreak','\nolinebreak','\pagebreak','\nopagebreak');
-add_keys_to_hash(\%TeXmacro,0,
- '\maketitle','\indent','\noindent',
- '\centering','\raggedright','\raggedleft','\clearpage','\cleardoublepage','\newline','\newpage',
- '\smallskip','\medskip','\bigskip','\vfill','\hfill','\hrulefill','\dotfill',
- '\normalsize','\small','\footnotesize','\scriptsize','\tiny','\large','\Large','\LARGE','\huge','\Huge',
- '\normalfont','\em','\rm','\it','\bf','\sf','\tt','\sc','\sl',
- '\rmfamily','\sffamily','\ttfamily','\upshape','\itshape','\slshape','\scshape','\mdseries','\bfseries',
- '\selectfont',
- '\tableofcontents','\listoftables','\listoffigures');
-add_keys_to_hash(\%TeXmacro,1,
- '\begin','\end',
- '\documentclass','\documentstyle','\hyphenation','\pagestyle','\thispagestyle',
- '\author','\date',
- '\bibliographystyle','\bibliography','\pagenumbering','\markright',
- '\includeonly','\includegraphics','\special',
- '\label','\ref','\pageref','\bibitem',
- '\eqlabel','\eqref','\hspace','\vspace','\addvspace',
- '\newsavebox','\usebox',
- '\newlength','\newcounter','\stepcounter','\refstepcounter','\usecounter',
- '\fontfamily','\fontseries',
- '\alph','\arabic','\fnsymbol','\roman','\value',
- '\typeout', '\typein','\cline');
-add_keys_to_hash(\%TeXmacro,2,
- '\newfont','\newtheorem','\sbox','\savebox','\rule','\markboth',
- '\setlength','\addtolength','\settodepth','\settoheight','\settowidth','\setcounter',
- '\addtocontents','\addtocounter',
- '\fontsize');
-add_keys_to_hash(\%TeXmacro,3,'\addcontentsline');
-add_keys_to_hash(\%TeXmacro,6,'\DeclareFontShape');
-add_keys_to_hash(\%TeXmacro,['[','text','ignore'],
- '\cite','\nocite','\citep','\citet','\citeauthor','\citeyear','\citeyearpar',
- '\citealp','\citealt','\Citep','\Citet','\Citealp','\Citealt','\Citeauthor');
-add_keys_to_hash(\%TeXmacro,['ignore','text'],'\parbox','\raisebox');
-add_keys_to_hash(\%TeXmacro,['otherword'],'\marginpar','\footnote','\footnotetext');
-add_keys_to_hash(\%TeXmacro,['header'],
- '\title','\part','\chapter','\section','\subsection','\subsubsection','\paragraph','\subparagraph');
-add_keys_to_hash(\%TeXmacro,['xxx','xxx','text'],'\multicolumn');
-add_keys_to_hash(\%TeXmacro,['xxx','xxx'],'\newcommand','\renewcommand');
-add_keys_to_hash(\%TeXmacro,['xxx','xxx','xxx'],'\newenvironment','\renewenvironment');
-
-### Environments
-# The %TeXenvir hash provides content parsing rules (parser states).
-# Environments that are not defined will be counted as the surrounding text.
-#
-# Parameters taken by the \begin{environment} are defined in %TeXmacro.
-#
-# Note that some environments may only exist within math-mode, and
-# therefore need not be defined here: in fact, they should not as it
-# is not clear if they will be in inlined or displayed math.
-my %TeXenvir;
-add_keys_to_hash(\%TeXenvir,'ignore',
- 'titlepage','tabbing','tabular','tabular*','thebibliography','lrbox');
-add_keys_to_hash(\%TeXenvir,'text',
- 'document','letter','center','flushleft','flushright',
- 'abstract','quote','quotation','verse','minipage',
- 'description','enumerate','itemize','list',
- 'theorem','thm','lemma','definition','corollary','example','proof','pf');
-add_keys_to_hash(\%TeXenvir,'inlinemath',
- 'math');
-add_keys_to_hash(\%TeXenvir,'displaymath',
- 'displaymath','equation','equation*','eqnarray','eqnarray*','align','align*',);
-add_keys_to_hash(\%TeXenvir,'float',
- 'float','picture','figure','figure*','table','table*');
-add_keys_to_hash(\%TeXenvir,'xall',
- 'verbatim','tikzpicture');
-
-# Environment parameters
-my $PREFIX_ENVIR='begin'; # Prefix used for environment names
-add_keys_to_hash(\%TeXmacro,1,
- 'beginthebibliography','beginlrbox','beginminipage');
-add_keys_to_hash(\%TeXmacro,2,
- 'beginlist');
-add_keys_to_hash(\%TeXmacro,['ignore'],
- 'beginletter');
-add_keys_to_hash(\%TeXmacro,['xxx'],
- 'begintabular');
-add_keys_to_hash(\%TeXmacro,['ignore','xxx'],
- 'begintabular*');
-add_keys_to_hash(\%TeXmacro,['[','text'],
- 'begintheorem','beginthm','beginlemma','begindefinition','begincorollary','beginexample','beginproof','beginpf');
-add_keys_to_hash(\%TeXmacro,['nooptions'],
- 'beginverbatim');
-
-### Macros that should be counted as one or more words
-# Macros that represent text may be declared here. The value gives
-# the number of words the macro represents.
-my %TeXmacrocount=('\LaTeX'=>1,'\TeX'=>1,'beginabstract'=>['header','headerword']);
-
-### Macros for including tex files
-# Allows \macro{file} to include file; or \macro file if of type 'input'.
-# Main types are 'input' for \input, 'texfile' which adds '.tex', and
-# 'file' which adds '.tex' if missing.
-my %TeXfileinclude=('\input'=>'input','\include'=>'texfile');
-
-### Convert state keys to codes
-convert_hash(\%TeXpreamble,\&keyarray_to_state);
-convert_hash(\%TeXpackageinc,\&keyarray_to_state);
-convert_hash(\%TeXfloatinc,\&keyarray_to_state);
-convert_hash(\%TeXmacro,\&keyarray_to_state);
-convert_hash(\%TeXmacrocount,\&keyarray_to_cnt);
-convert_hash(\%TeXenvir,\&key_to_state);
-
-
-###### Define package specific rules
-
-### Package rule definitions
-
-my %PackageTeXpreamble=(); # TeXpreamble definitions per package
-my %PackageTeXpackageinc=(); # TeXpackageinc definitions per package
-my %PackageTeXfloatinc=(); # TeXfloatinc definitions per package
-my %PackageTeXmacro=(); # TeXmacro definitions per package
-my %PackageTeXmacrocount=(); # TeXmacrocount definitions per package
-my %PackageTeXenvir=(); # TeXenvir definitions per package
-my %PackageTeXfileinclude=(); # TeXfileinclude definitions per package
-my %PackageSubpackage=(); # Subpackages to include (listed in array [...])
-
-
-# Rules for bibliography inclusion
-$PackageTeXmacrocount{'%incbib'}={'beginthebibliography'=>['header','hword']};
-$PackageTeXmacro{'%incbib'}={'\bibliography'=>1};
-$PackageTeXenvir{'%incbib'}={'thebibliography'=>'text'};
-$PackageTeXfileinclude{'%incbib'}={'\bibliography'=>'<bbl>'};
-
-# Rules for package alltt
-$PackageTeXenvir{'alltt'}={
- 'alltt'=>'xall'};
-
-# Rules for package babel
-# NB: Only core macros implemented, those expected found in regular documents
-$PackageTeXenvir{'babel'}={
- 'otherlanguage'=>'text','otherlanguage*'=>'text'};
-$PackageTeXmacro{'babel'}={
- '\selectlanguage'=>1,'\foreignlanguage'=>['ignore','text'],
- 'beginotherlanguage'=>1,'beginotherlanguage*'=>1};
-
-# Rules for package comment
-$PackageTeXenvir{'comment'}={
- 'comment'=>'xxx'};
-
-# Rules for package color
-$PackageTeXmacro{'color'}={
- '\textcolor'=>['ignore','text'],'\color'=>1,'\pagecolor'=>1,'\normalcolor'=>0,
- '\colorbox'=>['ignore','text'],'\fcolorbox'=>['ignore','ignore','text'],
- '\definecolor'=>3,\'DefineNamedColor'=>4};
-
-# Rules for package endnotes
-$PackageTeXmacro{'endnotes'}={'\endnote'=>['oword'],'\endnotetext'=>['oword'],'\addtoendnotetext'=>['oword']};
-
-# Rules for package etoolbox
-$PackageTeXmacro{'etoolbox'}={'\apptocmd'=>['xxx','ignore','ignore','ignore'],
- '\pretocmd'=>['xxx','ignore','ignore','ignore'],
- '\patchcmd'=>['xxx','xxx','xxx','ignore','ignore']};
-
-# Rules for package fancyhdr
-$PackageTeXmacro{'fancyhdr'}={
- '\fancyhf'=>1,'\lhead'=>1,'\chead'=>1,'\rhead'=>1,'\lfoot'=>1,'\cfoot'=>1,'\rfoot'=>1};
-
-# Rules for package geometry
-$PackageTeXmacro{'geometry'}={
- '\geometry'=>1,'\newgeometry'=>1,'\restoregeometry'=>0,,'\savegeometry'=>1,'\loadgeometry'=>1};
-
-# Rules for package graphicx
-$PackageTeXmacro{'graphicx'}={
- '\DeclareGraphicsExtensions'=>1,'\graphicspath'=>1,
- '\includegraphics'=>['[','ignore','ignore'],
- '\includegraphics*'=>['[','ignore','[','ignore','[','ignore','ignore'],
- '\rotatebox'=>1,'\scalebox'=>1,'\reflectbox'=>1,'\resizebox'=>1};
-
-# Rules for package hyperref (urls themselves counted as one word)
-# NB: \hyperref[label]{text} preferred over \hyperref{url}{category}{name}{text}
-# NB: Macros for use in Form environments not implemented
-$PackageTeXmacro{'hyperref'}={
- '\hyperref'=>['[','ignore','text'],
- '\url'=>1,'\nolinkurl'=>1,'\href'=>['ignore','text'],
- '\hyperlink'=>['ignore','text'],'\hypertarget'=>['ignore','text'],
- '\hyperbaseurl'=>1,'\hyperimage'=>['ignore','text'],'\hyperdef'=>['ignore','ignore','text'],
- '\phantomsection'=>0,'\autoref'=>1,'\autopageref'=>1,
- '\hypersetup'=>1,'\urlstyle'=>1,
- '\pdfbookmark'=>2,'\currentpdfbookmark'=>2,'\subpdfbookmark'=>2,'\belowpdfbookmark'=>2,
- '\pdfstringref'=>2,'\texorpdfstring'=>['text','ignore'],
- '\hypercalcbp'=>1,'\Acrobatmenu'=>2};
-$PackageTeXmacrocount{'hyperref'}={
- '\url'=>1,'\nolinkurl'=>1};
-
-# Rules for package import
-$PackageTeXfileinclude{'import'}={
- '\import'=>'dir file','\subimport'=>'subdir file',
- '\inputfrom'=>'dir file','\subinputfrom'=>'subdir file',
- '\includefrom'=>'dir file','\subincludefrom'=>'subdir file'};
-
-# Rules for package inputenc
-$PackageTeXmacro{'inputenc'}={
- '\inputencoding'=>1};
-
-# Rules for package listings
-$PackageTeXenvir{'listings'}={'lstlisting'=>'xall'};
-$PackageTeXmacro{'listings'}={'\lstset'=>['ignore'],'\lstinputlisting'=>['ignore']};
-
-# Rules for package psfig
-$PackageTeXmacro{'psfig'}={'\psfig'=>1};
-
-# Rules for package sectsty
-$PackageTeXmacro{'sectsty'}={
- '\allsectionsfont'=>1,'\partfont'=>1,'\chapterfont'=>1,'\sectionfont'=>1,
- '\subsectionfont'=>1,'\subsubsectionfont'=>1,'\paragraphfont'=>1,'\subparagraphfont'=>1,
- '\minisecfont'=>1,'\partnumberfont'=>1,'\parttitlefont'=>1,'\chapternumberfont'=>1,
- '\chaptertitlefont'=>1,'\nohang'=>0};
-
-# Rules for package setspace
-$PackageTeXenvir{'setspace'}={
- 'singlespace'=>'text','singlespace*'=>'text','onehalfspace'=>'text','doublespace'=>'text',
- 'spacing'=>'text'};
-$PackageTeXmacro{'setspace'}={
- 'beginspacing'=>1,
- '\singlespacing'=>0,'\onehalfspacing'=>0,'\doublespacing'=>0,
- '\setstretch'=>1,'\SetSinglespace'=>1};
-
-# Rules for package subfiles
-$PackageTeXfileinclude{'subfiles'}={
- '\subfile'=>'file'};
-
-# Rules for package url
-# NB: \url|...| variant not implemented, only \url{...}
-# NB: \urldef{macro}{url} will not be counted
-$PackageTeXmacro{'url'}={
- '\url'=>1,'\urldef'=>2,'\urlstyle'=>1,'\DeclareUrlCommand'=>['ignore','xxx']};
-$PackageTeXmacro{'setspace'}={
- '\url'=>1};
-
-# Rules for package wrapfig
-$PackageTeXenvir{'wrapfig'}={
- 'wrapfigure'=>'float','wraptable'=>'float'};
-$PackageTeXmacro{'wrapfig'}={
- 'beginwrapfigure'=>2,'beginwraptable'=>2};
-
-# Rules for package xcolor (reimplements the color package)
-# NB: only main macros (mostly from package color) included
-$PackageTeXmacro{'xcolor'}={
- '\textcolor'=>['ignore','text'],'\color'=>1,'\pagecolor'=>1,'\normalcolor'=>0,
- '\colorbox'=>['ignore','text'],'\fcolorbox'=>['ignore','ignore','text'],
- '\definecolor'=>3,\'DefineNamedColor'=>4,
- '\colorlet'=>2};
-
-# Rules for package xparse
-$PackageSubpackage{'xparse'}=['etoolbox'];
-
-
-###### Main script
-
-
-
-###################################################
-
-MAIN(@ARGV);
-exit; # Just to make sure it ends here...
-
-###################################################
-
-
-#########
-######### Main routines
-#########
-
-# MAIN ROUTINE: Handle arguments, then parse files
-sub MAIN {
- my @args;
- push @args,@StartupOptions;
- push @args,@_;
- Initialise();
- Check_Arguments(@args);
- my @toplevelfiles=Parse_Arguments(@args);
- Apply_Options();
- if (scalar @toplevelfiles>0 || $fileFromSTDIN) {
- if ($showVersion && !$htmlstyle && !($briefsum && $totalflag)) {
- print "\n=== LaTeX word count (TeXcount version $versionnumber) ===\n\n";
- }
- conditional_print_style_list();
- my $totalcount=Parse_file_list(@toplevelfiles);
- conditional_print_total($totalcount);
- Report_Errors();
- if ($optionWordFreq || $optionWordClassFreq) {print_word_freq();}
- if ($optionMacroStat) {print_macro_stat();}
- } elsif ($showcodes>1) {
- conditional_print_style_list();
- } else {
- error($Main,'No files specified.');
- }
- Close_Output();
-}
-
-# Initialise, overrule initial settings, etc.
-sub Initialise {
- _option_subcount();
- # Windows settings
- if ($^O eq 'MSWin32') {
- } elsif ($^O=~/^MSWin/) {
- #DELETE: do not overrule colour setting
- option_ansi_colours(0);
- }
-}
-
-# Check arguments, exit on exit condition
-sub Check_Arguments {
- my @args=@_;
- if (!@args) {
- print_version();
- print_help();
- exit;
- }
- for my $arg (@args) {
- $arg=~s/^(--?(h|\?|help)|\/(\?|h))\b/-h/;
- $arg=~s/[=:]/=/;
- if ($arg=~/^-h$/) {
- print_help();
- exit;
- } elsif ($arg=~/^-(h-)?(man|manual)$/) {
- print_help_man();
- exit;
- } elsif ($arg=~/^-h-?(opt|options?)$/) {
- print_help_options();
- exit;
- } elsif ($arg=~/^-h-?(opt|options?)=(.*)$/) {
- print_help_options_subset($2);
- exit;
- } elsif ($arg=~/^-h(-rule)?=(.*)$/) {
- print_help_on_rule($2);
- exit;
- } elsif ($arg=~/^-h-styles?$/) {
- print_help_on_styles();
- exit;
- } elsif ($arg=~/^-h-styles?=(\w+)$/) {
- print_help_on_styles($1);
- exit;
- } elsif ($arg=~/^-h-(tc|(tc)?inst(ructions?))?$/) {
- print_help_tcinst();
- exit;
- } elsif ($arg=~/^--?(ver|version)$/) {
- print_version();
- exit;
- } elsif ($arg=~/^--?(lic|license|licence)$/) {
- print_license();
- exit;
- }
- }
- return 1;
-}
-
-# Parse arguments, set options (global) and return file list
-sub Parse_Arguments {
- my @args=@_;
- my @files;
- foreach my $arg (@args) {
- if ($arg=~/^\-/) {
- $arg=~s/[=:]/=/;
- if (parse_option($arg)) {next;}
- print "Invalid option $arg \n\n";
- print_help();
- exit;
- } elsif ($arg=~/^@\-/) { # ignored option
- next;
- }
- $arg=~s/\\/\//g;
- push @files,$arg;
- }
- return @files;
-}
-
-# Parse individual option parameters
-sub parse_option {
- my $arg=shift @_;
- return parse_options_preset($arg)
- || parse_options_parsing($arg)
- || parse_options_counts($arg)
- || parse_options_output($arg)
- || parse_options_format($arg)
- ;
-}
-
-# Parse presetting options
-sub parse_options_preset {
- my $arg=shift @_;
- if ($arg=~/^-(opt|option|options|optionfile)=(.*)$/) {
- _parse_optionfile($2);
- }
- else {return 0;}
- return 1;
-}
-
-# Parse parsing options
-sub parse_options_parsing {
- my $arg=shift @_;
- if ($arg eq '-') {$fileFromSTDIN=1;}
- elsif ($arg eq '-merge') {$includeTeX=$INCLUDE_MERGE;}
- elsif ($arg eq '-inc') {$includeTeX=$INCLUDE_AFTER;}
- elsif ($arg eq '-noinc') {$includeTeX=$INCLUDE_NONE;}
- elsif ($arg =~/^-(includepackage|incpackage|package|pack)=(.*)$/) {include_package($2);}
- elsif ($arg eq '-incbib') {$includeBibliography=1;}
- elsif ($arg eq '-nobib') {$includeBibliography=0;}
- elsif ($arg eq '-dir') {$globalworkdir=undef;}
- elsif ($arg=~/^-dir=(.*)$/) {
- $globalworkdir=$1;
- $globalworkdir=~s:([^\/\\])$:$1\/:;
- }
- elsif ($arg eq '-auxdir') {$auxdir=undef;}
- elsif ($arg=~/^-auxdir=(.*)$/) {
- $auxdir=$1;
- $auxdir=~s:([^\/\\])$:$1\/:;
- }
- elsif ($arg =~/^-(enc|encode|encoding)=(.+)$/) {$encoding=$2;}
- elsif ($arg =~/^-(utf8|unicode)$/) {$encoding='utf8';}
- elsif ($arg =~/^-(alpha(bets?)?)=(.*)$/) {set_script_options(\@AlphabetScripts,$3);}
- elsif ($arg =~/^-(logo(grams?)?)=(.*)$/) {set_script_options(\@LogogramScripts,$3);}
- elsif ($arg =~/^-([-a-z]+)$/ && set_language_option($1)) {}
- elsif ($arg eq '-relaxed') {
- $MacroOptionPattern=$NamedMacroOptionPattern{'relaxed'};
- $LetterPattern=$NamedLetterPattern{'relaxed'};
- }
- elsif ($arg eq '-restricted') {
- $MacroOptionPattern=$NamedMacroOptionPattern{'restricted'};
- $LetterPattern=$NamedLetterPattern{'restricted'};
- }
- else {return 0;}
- return 1;
-}
-
-# Parse count and summation options
-sub parse_options_counts {
- my $arg=shift @_;
- if ($arg =~/^-sum(=(.+))?$/) {_option_sum($2);}
- elsif ($arg =~/^-nosum/) {@sumweights=();}
- elsif ($arg =~/^-(sub|subcounts?)(=(.+))?$/) {_option_subcount($3);}
- elsif ($arg =~/^-(nosub|nosubcounts?)/) {$showsubcounts=0;}
- elsif ($arg eq '-freq') {$optionWordFreq=1;}
- elsif ($arg =~/^-freq=(\d+)$/) {$optionWordFreq=$1;}
- elsif ($arg eq '-stat') {$optionWordClassFreq=1;}
- elsif ($arg =~/^-macro-?(stat|freq)$/) {$optionMacroStat=1;}
- else {return 0;}
- return 1;
-}
-
-# Apply sum option
-sub _option_sum {
- my $arg=shift @_;
- if (!defined $arg) {
- @sumweights=(0,1,1,1,0,0,1,1);
- } elsif ($arg=~/^(\d+(\.\d*)?([,+]\d+(\.\d*)?){0,6})$/) {
- @sumweights=(0,split(/[,+]/,$arg));
- print STDERR "SUMWEIGHTS: ",join(', ',@sumweights),"\n";
- } else {
- print STDERR "Warning: Option value $arg not valid, ignoring option.\n";
- }
-}
-
-# Apply subcount options
-sub _option_subcount {
- my $arg=shift @_;
- $showsubcounts=2;
- if (!defined $arg) {
- %BreakPoints=%{$BreakPointsOptions{'default'}};
- } elsif (my $option=$BreakPointsOptions{$arg}) {
- %BreakPoints=%{$option};
- } else {
- print STDERR "Warning: Option value $arg not valid, using default instead.\n";
- %BreakPoints=%{$BreakPointsOptions{'default'}};
- }
-}
-
-# Parse output and verbosity options
-sub parse_options_output {
- my $arg=shift @_;
- if ($arg eq '-strict') {$strictness=1;}
- elsif ($arg eq '-v') {set_verbosity_options('3');}
- elsif ($arg =~/^-v([0-4=+\-].*)/) {set_verbosity_options($1);}
- elsif ($arg =~/^-showstates?$/ ) {$showstates=1;}
- elsif ($arg =~/^-(q|quiet)$/ ) {$printlevel=-1;}
- elsif ($arg =~/^-(template)=(.*)$/ ) {_set_output_template($2);}
- elsif ($arg eq '-split') {$optionFast=1;}
- elsif ($arg eq '-nosplit') {$optionFast=0;}
- elsif ($arg eq '-showver') {$showVersion=1;}
- elsif ($arg eq '-nover') {$showVersion=-1;}
- elsif ($arg =~/^-nosep(arator)?s?$/ ) {$separator='';}
- elsif ($arg =~/^-sep(arator)?s?=(.*)$/ ) {$separator=$2;}
- elsif ($arg =~/^-out=(.*)/ ) {
- close STDOUT;
- open STDOUT,'>',$1 or die "Could not open out file for writing: $1";
- }
- elsif ($arg =~/^-out-stderr/ ) {select STDERR;}
- else {return 0;}
- return 1;
-}
-
-# Set output template
-sub _set_output_template {
- my $template=shift @_;
- $outputtemplate=$template;
- if ($template=~/\{(SUM)[\?\}]/i && !@sumweights) {
- @sumweights=(0,1,1,1,0,0,1,1);
- }
- if ($template=~/\{SUB\?/i && !$showsubcounts) {
- _option_subcount();
- }
-}
-
-# Parse output formating options
-sub parse_options_format {
- my $arg=shift @_;
- if ($arg eq '-brief') {$briefsum=1;}
- elsif ($arg eq '-total') {$totalflag=1;}
- elsif ($arg eq '-0') {$briefsum=1;$totalflag=1;$printlevel=-1;$finalLineBreak=0;}
- elsif ($arg eq '-1') {$briefsum=1;$totalflag=1;$printlevel=-1;}
- elsif ($arg eq '-htmlcore' ) {option_ansi_colours(0);$htmlstyle=$HTML_CORE;}
- elsif ($arg eq '-html' ) {option_ansi_colours(0);$htmlstyle=$HTML_FULL;}
- elsif ($arg eq '-tex' ) {option_ansi_colours(0);$texcodeoutput=1;}
- elsif ($arg =~/^\-(nocol|nc$)/) {option_ansi_colours(0);}
- elsif ($arg =~/^\-(col)$/) {option_ansi_colours(1);}
- elsif ($arg eq '-codes') {$showcodes=2;}
- elsif ($arg eq '-nocodes') {$showcodes=0;}
- elsif ($arg =~/^-htmlfile=(.+)$/) {$HTMLfile=$1;}
- elsif ($arg =~/^-cssfile=(.+)$/) {$CSSfile=$1;}
- elsif ($arg =~/^-css=file:(.+)$/) {$CSSfile=$1;}
- elsif ($arg =~/^-css=(.+)$/) {$CSShref=$1;}
- else {return 0;}
- return 1;
-}
-
-# Include options from option file
-sub _parse_optionfile {
- my $filename=shift @_;
- open(FH,'<',$filename)
- || die "Option file not found: $filename\n";
- my @options=<FH>;
- close(FH);
- s/^\s*(#.*|)//s for @options;
- my $text=join('',@options);
- $text=~s/(\n|\r|\r\n)\s*\\//g;
- @options=split("\n",$text);
- foreach my $arg (@options) {
- __optionfile_tc($arg)
- || parse_option($arg)
- || die "Invalid option $arg in $filename.\n";
- }
-}
-
-# Parse option file TC options
-sub __optionfile_tc {
- my $arg=shift @_;
- if ($arg=~/^\%\%/) {return 1;}
- $arg=~s/^\%\s*// || return 0;
- if ($arg=~/^subst\s+(\\\w+)\s+(.*)$/i) {
- $substitutions{$1}=$2;
- } elsif ($arg=~/^(\w+)\s+([\\]*\w+)\s+([^\s\n]+)(\s+(\-?[0-9]+|\w+))?/i) {
- tc_macro_param_option($Main,$1,$2,$3,$5) || die "Invalid TC option: $arg\n";
- } else {
- print "Invalid TC option format: $arg\n";
- return 0;
- }
- return 1;
-}
-
-# Parse file list and return total count
-sub Parse_file_list {
- my @files=@_;
- my $listtotalcount=new_count('Total');
- foreach (@files) {
- $_='"'.$_.'"'
- }
- if (@files) {
- @files=<@files>; # For the sake of Windows: expand wildcards!
- for my $file (@files) {
- my $filetotalcount=parse_file($file);
- add_to_total($listtotalcount,$filetotalcount);
- }
- }
- if ($fileFromSTDIN) {
- my $filetotalcount=parse_file($_STDIN_);
- add_to_total($listtotalcount,$filetotalcount);
- }
- return $listtotalcount;
-}
-
-# Parse file and included files, and return total count
-sub parse_file {
- my $file=shift @_;
- if (defined ($workdir=$globalworkdir)) {}
- elsif ($file eq $_STDIN_) {$workdir='';}
- else {
- $workdir=$file;
- $workdir =~ s/^((.*[\\\/])?)[^\\\/]+$/$1/;
- }
- if ($htmlstyle && ($printlevel>0 || !$totalflag)) {print "\n<div class='filegroup'>\n";}
- my $filetotalcount=new_count('File(s) total: '.$file);
- @filelist=();
- _add_file($filetotalcount,[$file,$workdir],'File: '.$file);
- foreach my $f (@filelist) {
- _add_file($filetotalcount,$f,'Included file: '.$f->[0]);
- }
- if (!$totalflag && get_count($filetotalcount,$CNT_FILE)>1) {
- #if ($htmlstyle) {formatprint("Sum of files: $file\n",'h2');}
- print_count($filetotalcount,'sumcount',"Sum of files: $file");
- }
- if ($htmlstyle && ($printlevel>0 || !$totalflag)) {print "</div>\n\n";}
- return $filetotalcount;
-}
-
-# Parse single file, included files will be appended to @filelist.
-sub _add_file {
- my ($filetotalcount,$pathfile,$title)=@_;
- my @paths=@$pathfile;
- my $file=shift @paths;
- my $tex=TeXfile($file,$title);
- if (!defined $tex) {
- error($Main,'File not found or not readable: '.$file);
- return;
- }
- $tex->{'PATH'}=\@paths;
- parse($tex);
- my $filecount=next_subcount($tex);
- if (!$totalflag) {print_count($filecount);}
- add_to_total($filetotalcount,$filecount);
-}
-
-
-######
-###### Subroutines
-######
-
-###### CMD specific implementations
-
-
-# Add file to list of files scheduled for parsing
-sub include_file {
- my ($tex,$state,$file,$refparam)=@_;
- my %params=%$refparam;
- my $type=$params{'<type>'};
- my @paths=@{$tex->{'PATH'}};
- if ($type eq '<bbl>' && defined $auxdir) {
- $auxdir=~s/([\\\/])*$/\//;
- if (defined $globalworkdir) {@paths=[$auxdir];}
- elsif ($auxdir=~/^(\w:)?[\\\/]/) {@paths=[$auxdir];}
- else {@paths=[$workdir.$auxdir]}
- }
- foreach my $key (split(/\s+/,$type)) {
- my $value=$params{$key};
- if ($key eq 'dir') {unshift @paths,$workdir.$value;}
- elsif ($key eq 'subdir') {unshift @paths,$paths[0].$value;}
- }
- # Decide full file path
- my $filepath;
- if ($file=~/^(\w:)?[\\\/]/) {$filepath=$file;}
- else {
- $filepath=_find_file_in_path($tex,$file,\@paths,$params{'SUFFICES'}) || BLOCK {
- error($tex,'File '.$file.' not found in path ['.join(';',@paths).'].');
- return;
- };
- }
- if ($includeTeX==$INCLUDE_MERGE) {
- my $bincode=read_binary($filepath) || BLOCK {
- error($tex,"File $filepath not readable.");
- return;
- };
- flush_next($tex);
- line_return(0,$tex);
- my $texstate=texcode_insert_text($tex,$bincode,$filepath,@paths);
- parse_all($tex,$state);
- texcode_restore_state($tex,$texstate);
- } else {
- push @filelist,[$filepath,@paths];
- }
-}
-
-# Seach path list to find file
-sub _find_file_in_path {
- my ($tex,$file,$paths,$suffices)=@_;
- foreach my $suffix (@{$suffices}) {
- foreach my $path (@{$paths}) {
- if ($path && $path!~/[\\\/]$/) {$path.='/';}
- my $filepath=$path.$file.$suffix;
- if (-e $filepath && ! -d $filepath) {return $filepath;}
- # DELETE: elsif ($filepath=~/\.tex$/i) {}
- # DELETE: elsif (-e $filepath.'.tex') {return $filepath.'.tex';}
- }
- }
- return undef;
-}
-
-# Print count (total) if conditions are met
-sub conditional_print_total {
- my $sumcount=shift @_;
- if ($totalflag || number_of_subcounts($sumcount)>1) {
- if ($totalflag && $briefsum && @sumweights) {
- print get_sum_count($sumcount),"\n";
- } elsif ($htmlstyle) {
- print "<div class='sumgroup'>\n";
- formatprint('Total word count','h2');
- print_count($sumcount,'sumcount');
- print "</div>\n";
- } else {
- print_count($sumcount,'sumcount');
- }
- }
-}
-
-# Set or unset use of ANSI colours
-sub option_ansi_colours {
- my $flag=shift @_;
- $ENV{'ANSI_COLORS_DISABLED'} = $flag?undef:1;
-}
-
-# Print text using ANSI colours
-sub ansiprint {
- my ($text,$colour)=@_;
- print Term::ANSIColor::colored($text,$colour);
-}
-
-
-###### Option handling
-
-
-# Apply options to set values
-sub Apply_Options {
- apply_encoding_options();
- if ($htmlstyle==$HTML_FULL) {html_head();}
- flush_errorbuffer($Main);
- apply_language_options();
- if ($includeBibliography) {apply_include_bibliography();}
- if ($showcodes>1 && !($STYLE{'<printlevel>'})) {%STYLE=%{$STYLES{'All'}};}
- if ($showstates) {set_verbosity_options('+States');}
- if (!@sumweights) {set_verbosity_options('-Sums');}
- (defined $printlevel)
- || (defined ($printlevel=$STYLE{'<printlevel>'}))
- || ($printlevel=$defaultprintlevel);
-}
-
-# Set or add styles included in the verbose output
-sub set_verbosity_options {
- my $verb=shift @_;
- my $st;
- if ($defaultprintlevel<1) {$defaultprintlevel=1;}
- if ( $verb=~s/^([0-4])// || $verb=~s/^=([0-4])?// ) {
- my $key=$1;
- if (!defined $key) {%STYLE=(%{$STYLES{'<core>'}});}
- elsif ($st=$STYLES{$key}) {%STYLE=(%$st);}
- else {
- error($Main,"Unknown verbosity option '$key'.");
- %STYLE=(%{$STYLES{'<core>'}});
- }
- }
- while ($verb=~s/^([\+\-]?)(\w+)//) {
- my $add=!($1 eq '-');
- my $key=$2;
- if ($st=$STYLES{$key}) {
- if ($add) {@STYLE{keys %$st}=values %$st;}
- else {delete @STYLE{keys %$st};}
- } elsif ($st=$STYLES{'All'}->{$key}) {
- if ($add) {$STYLE{$key}=$st;}
- elsif ($STYLE{$key}) {delete $STYLE{$key};}
- } else {
- error($Main,"Unknown verbosity option '$key'.");
- }
- }
- if ($verb ne '') {
- error($Main,"Unknown verbosity option format: $verb");
- }
-}
-
-# Set or add scripts to array of scripts
-sub set_script_options {
- my ($scriptset,$str)=@_;
- if ($str=~s/^\+//) {} else {splice(@$scriptset,0,scalar $scriptset);}
- my @scripts=split(/[+,]/,$str);
- foreach my $scr (@scripts) {
- $scr=~tr/_/ /;
- if ($scr eq 'Alphabetic') {
- warning($Main,'Using alphabetic instead of Unicode class Alphabetic');
- $scr='alphabetic';
- }
- if ($scr=~/^[a-z]/) {$scr='Is_'.$scr;}
- if (_is_property_valid($scr)) {push @$scriptset,$scr;}
- else {error($Main,"Unknown script $scr ignored.");}
- }
-}
-
-sub _is_property_valid {
- my $script=shift @_;
- if (! $script=~/^\w+$/) {return 0;}
- eval {' '=~/\p{$script}/};
- if ($@) {return 0;} else {return 1;}
-}
-
-# Set language option, return language if applied, undef if not
-sub set_language_option {
- my $language=shift @_;
- if ($language=~/^(count\-?)all$/) {
- @AlphabetScripts=qw/Digit Is_alphabetic/;
- @LogogramScripts=qw/Ideographic Katakana Hiragana Thai Lao Hangul/;
- } elsif ($language=~/^words(-?only)?$/) {
- @LogogramScripts=();
- } elsif ($language=~/^(ch|chinese|zhongwen)(-?only)?$/) {
- @LogogramScripts=qw/Han/;
- if (defined $2) {$LetterPattern=undef;}
- @encodingGuessOrder=@{$NamedEncodingGuessOrder{'chinese'}};
- return 'chinese';
- } elsif ($language=~/^(jp|japanese)(-?only)?$/) {
- @LogogramScripts=qw/Han Hiragana Katakana/;
- if (defined $2) {$LetterPattern=undef;}
- @encodingGuessOrder=@{$NamedEncodingGuessOrder{'japanese'}};
- return 'japanese';
- } elsif ($language=~/^(kr|korean)(-?only)?$/) {
- @LogogramScripts=qw/Han Hangul/;
- if (defined $2) {$LetterPattern=undef;}
- @encodingGuessOrder=@{$NamedEncodingGuessOrder{'korean'}};
- return 'korean';
- } elsif ($language=~/^(kr|korean)-?words?(-?only)?$/) {
- if (defined $2) {
- @AlphabetScripts=qw/Hangul/;
- @LogogramScripts=qw/Han/;
- } else {
- @AlphabetScripts=qw/Digit Is_alphabetic Hangul/;
- @LogogramScripts=qw/Han Katakana Hiragana Thai Lao/;
- }
- @encodingGuessOrder=@{$NamedEncodingGuessOrder{'korean'}};
- return 'korean-words';
- } elsif ($language=~/^(char|character|letter)s?(-?only)?$/) {
- @WordPatterns=($NamedWordPattern{'letters'});
- if (defined $2) {@LogogramScripts=();}
- $countdesc[1]='Letters in text';
- $countdesc[2]='Letters in headers';
- $countdesc[3]='Letters in captions';
- return 'letter';
- } elsif ($language=~/^all-nonspace-(char|character|letter)s?$/) {
- @WordPatterns=($NamedWordPattern{'letters'});
- @AlphabetScripts=qw/Digit Is_alphabetic Is_punctuation/;
- $countdesc[1]='Characters in text';
- $countdesc[2]='Characters in headers';
- $countdesc[3]='Characters in captions';
- return 'nonspace-characters';
- } else {
- return undef;
- }
-}
-
-# Set encoding based on encoding options, guess encoding if not set
-sub apply_encoding_options {
- if (defined $encoding && $encoding eq 'guess') {$encoding=undef;}
- if (!defined $encoding) {
- } elsif (ref(find_encoding($encoding))) {
- if (!$htmlstyle) {$outputEncoding=$encoding;}
- } else {
- error($Main,"Unknown encoding $encoding ignored.");
- error_details($Main,'Valid encodings are: '.wrap('','',join(', ',Encode->encodings(':all'))));
- $encoding=undef;
- }
- if (!defined $outputEncoding) {$outputEncoding='utf8';}
- binmode STDIN;
- binmode STDOUT,':encoding('.$outputEncoding.')';
-}
-
-# Apply language options
-sub apply_language_options {
- my @tmp;
- if (defined $LetterPattern && @AlphabetScripts && scalar @AlphabetScripts>0) {
- @tmp=@AlphabetScripts;
- foreach (@tmp) {$_='\\p{'.$_.'}';}
- my $letterchars='['.join('',@tmp).']';
- my $letter=$LetterPattern;
- $letter=~s/@/$letterchars/g;
- @WordPatterns=map { s/\@/$letter/g ; qr/$_/ } @WordPatterns;
- } else {
- @WordPatterns=();
- }
- if (@LogogramScripts && scalar @LogogramScripts>0) {
- @tmp=@LogogramScripts;
- foreach (@tmp) {$_='\\p{'.$_.'}';}
- push @WordPatterns,'['.join('',@tmp).']';
- }
- if (scalar @WordPatterns==0) {
- error($Main,'No script (alphabets or logograms) defined. Using fallback mode.');
- push @WordPatterns,'\\w+';
- }
- $WordPattern=join '|',@WordPatterns;
-}
-
-# Apply incbib rule
-sub apply_include_bibliography {
- include_package('%incbib');
-}
-
-# Process TC instruction, return 1 if applied, 0 if not (e.g. error)
-sub tc_macro_param_option {
- my ($tex,$instr,$macro,$param,$option)=@_;
- if (!defined $param) {
- error($tex,'%TC:'.$instr.' requires parameter rule specification.');
- return 0;
- }
- elsif ($instr eq 'macro') {
- if (!($macro=~/^\\/)) {
- warning($tex,'%TC:macro '.$macro.': should perhaps be \\'.$macro.'?');
- }
- return _tc_macro_set_param($tex,\%TeXmacro,$instr,$macro,$param);
- }
- elsif ($instr eq 'exclude') {
- warning($tex,'%TC:exclude is deprecated. Use %TC:macro instead.');
- return _tc_macro_set_param($tex,\%TeXmacro,$instr,$macro,$param);
- }
- elsif ($instr eq 'header') {
- warning($tex,'%TC:header is deprecated. Instead use e.g. %TC:macro \\name [header].');
- $TeXmacrocount{$macro}=[$CNT_COUNT_HEADER];
- return _tc_macro_set_param($tex,\%TeXmacro,$instr,$macro,$param);
- }
- elsif ($instr eq 'preambleinclude') {
- return _tc_macro_set_param($tex,\%TeXpreamble,$instr,$macro,$param);
- }
- elsif ($instr eq 'floatinclude') {
- return _tc_macro_set_param($tex,\%TeXfloatinc,$instr,$macro,$param);
- }
- elsif ($instr=~/^(group|envir)$/) {
- if (!defined $option) {
- error($tex,'TC:'.$instr.' requires contents rule specification.');
- return 0;
- }
- defined ($option=key_to_state($option,$tex)) || return 0;
- $TeXenvir{$macro}=$option;
- return _tc_macro_set_param($tex,\%TeXmacro,$instr,$PREFIX_ENVIR.$macro,$param);
- }
- elsif ($instr=~/^(macrocount|macroword)$/) {
- return _tc_macro_set_param($tex,\%TeXmacrocount,$instr,$macro,$param,\&key_to_cnt,$REGEX_NUMBER);
- }
- elsif ($instr eq 'fileinclude') {
- # No parameter checking here, just pass on; errors reported when used instead.
- $param=~s/^\[(.*)\]$/$1/;
- $param=~s/,/ /g;
- assert($param=~/^\w+(\s\w+)*$/,$tex,'Invalid %TC:fileinclude parameter: '.$param)
- || return 0;
- $TeXfileinclude{$macro}=$param;
- }
- elsif ($instr eq 'breakmacro') {$BreakPoints{$macro}=$param;}
- else {
- error($tex,'Unknown TC command: '.$instr);
- return 0;
- }
- return 1;
-}
-
-# Convert TC command parameters and add to hash
-sub _tc_macro_set_param {
- my ($tex,$hash,$instr,$macro,$param,$keymap,$validregex)=@_;
- if (!defined $keymap) {$keymap=\&key_to_state; $validregex=$REGEX_NUMBER;}
- $param=__interpret_tc_parameter($tex,$param,$keymap,$validregex);
- if (!defined $param) {return 0;}
- $hash->{$macro}=$param;
- return 1;
-}
-
-# Convert [...] into array of states, optionally return value if a valid pattern
-sub __interpret_tc_parameter {
- my ($tex,$param,$keymap,$validregex)=@_;
- if ((defined $validregex) && ($param=~$validregex)) {
- return $param;
- } elsif ($param=~/^\[([0-9a-zA-Z,:]*)\]$/) {
- my @params;
- my $value;
- foreach my $key (split(',',$1)) {
- if ($key=~/^(\w*):(\w+)$/) {
- defined ($value=$keymap->($PREFIX_PARAM_OPTION.$1,$tex)) || return undef;
- push @params,$value;
- $key=$2;
- }
- defined ($value=$keymap->($key,$tex)) || return undef;
- push @params,$value;
- }
- return [@params];
- }
- error($tex,'Invalid TC command parameter: '.$param);
- return undef;
-}
-
-
-
-###### Macro rules handling
-
-
-# Takes hash, value, list of keys and adds mappings to hash
-sub add_keys_to_hash {
- my $hash=shift @_;
- my $value=shift @_;
- foreach (@_) {
- $hash->{$_}=$value;
- }
-}
-
-# Add source hash to target hash, optionally converting values
-sub __add_to_hash {
- my $target=shift @_;
- my $source=shift @_;
- my $convert=shift @_;
- if (!defined $convert) {$convert=&__dummy;}
- while (my ($key,$val)=each(%$source)) {
- $target->{$key}=$convert->($val,@_);
- }
-}
-
-# Convert hash by applying function to all values
-sub convert_hash {
- my $hash=shift @_;
- my $convert=shift @_;
- while (my ($key,$val)=each(%$hash)) {
- $hash->{$key}=$convert->($val,@_);
- }
-}
-
-# Convert key to parser state constant
-sub key_to_state {
- my ($key,$tex)=@_;
- return key_convert(lc($key),$tex,\%key2state,'Unknown state key {key} replaced by IGNORE.',$STATE_IGNORE);
-}
-
-# Convert key array to parser state constants
-sub keyarray_to_state {
- my ($array,$tex)=@_;
- return keyarray_convert($array,$tex,\&key_to_state);
-}
-
-# Convert key to counter constant
-sub key_to_cnt {
- my ($key,$tex)=@_;
- return key_convert(lc($key),$tex,\%key2cnt,'Unknown counter key {key} ignored.');
-}
-
-# Convert key array to counter constants
-sub keyarray_to_cnt {
- my ($array,$tex)=@_;
- return keyarray_convert($array,$tex,\&key_to_cnt);
-}
-
-# Convert key to value using map
-sub key_convert {
- my ($key,$tex,$map,$error,$default)=@_;
- my $value=$map->{$key};
- if (!defined $value) {
- if (!defined $tex) {$tex=$Main;}
- $error=~s/\{key\}/$key/g;
- error($tex,$error);
- return $default;
- }
- return $value;
-}
-
-# Convert state keys to state nos for arrays
-sub keyarray_convert {
- my ($array,$tex,$conv)=@_;
- if (ref($array) eq 'ARRAY') {
- my @ar;
- foreach my $key (@$array) {
- if (defined (my $cnt=$conv->($key,$tex))) {push @ar,$cnt;}
- }
- $array=\@ar;
- }
- return $array;
-}
-
-# Convert transition state to parsing state, and increment counter
-sub transition_to_content_state {
- my ($tex,$state)=@_;
- my $tr=$transition2state{$state};
- if (defined $tr) {
- if (my $cnt=$tr->[1]) {inc_count($tex,$tr->[1]);}
- return $tr->[0];
- }
- return $state;
-}
-
-# Remove all rules
-sub remove_all_rules {
- %TeXpackageinc=();
- %TeXpreamble=();
- %TeXfloatinc=();
- %TeXmacro=();
- %TeXmacrocount=();
- %TeXenvir=();
- %TeXfileinclude=();
- %IncludedPackages=();
-}
-
-# Process package inclusion
-sub include_package {
- my ($incpackage,$tex)=@_;
- if (defined $IncludedPackages{$incpackage}) {return;}
- $IncludedPackages{$incpackage}=1;
- # Add rules for package, preamble and float inclusion, and add to macro rules
- _add_package(\%TeXpackageinc,\%PackageTeXpackageinc,$incpackage,\&__dummy,$tex);
- _add_package(\%TeXpreamble,\%PackageTeXpreamble,$incpackage,\&keyarray_to_state,$tex);
- _add_package(\%TeXfloatinc,\%PackageTeXfloatinc,$incpackage,\&keyarray_to_state,$tex);
- _add_package(\%TeXmacro,\%PackageTeXpackageinc,$incpackage,\&keyarray_to_state,$tex);
- _add_package(\%TeXmacro,\%PackageTeXpreamble,$incpackage,\&keyarray_to_state,$tex);
- _add_package(\%TeXmacro,\%PackageTeXfloatinc,$incpackage,\&keyarray_to_state,$tex);
- # Add regular rules
- _add_package(\%TeXmacro,\%PackageTeXmacro,$incpackage,\&keyarray_to_state,$tex);
- _add_package(\%TeXmacrocount,\%PackageTeXmacrocount,$incpackage,\&keyarray_to_cnt,$tex);
- _add_package(\%TeXenvir,\%PackageTeXenvir,$incpackage,\&key_to_state,$tex);
- _add_package(\%TeXfileinclude,\%PackageTeXfileinclude,$incpackage,\&__dummy,$tex);
- if (my $subpackages=$PackageSubpackage{$incpackage}) {
- foreach my $sub (@{$subpackages}) {
- include_package($sub,$tex);
- }
- }
-}
-
-# Add package rules if defined
-sub _add_package {
- my ($target,$source,$name,$convert,$tex)=@_;
- my $sub;
- if ($sub=$source->{$name}) {
- __add_to_hash($target,$sub,$convert);
- }
-}
-
-# Dummy conversion function: returns arguments unchanged
-sub __dummy {
- return shift @_;
-}
-
-
-###### TeX code handle
-
-
-
-# Return object capable of capturing errors for use when
-# no TeXcode object is available.
-sub getMain {
- my %main=();
- $main{'errorcount'}=0;
- $main{'errorbuffer'}=[];
- $main{'warnings'}={};
- return \%main;
-}
-
-
-## Make TeX handle for LaTeX code: the main TeXcount object
-# The "TeX object" is a data containser: a hash containing
-# - filepath: path of LaTeX file being parsed
-# - filename: file name of LaTeX file
-# - dirpath: path to directory containing LaTeX file
-# - PATH: array of paths to search for included files
-# - countsum: count object with total count (incl. subcounts)
-# - subcount: count object for subcount (to be added to countsum)
-# - subcounts: list of subcounts
-# - errorcount: the number of errors reported
-# plus following elements used for the processing the LaTeX code
-# - line: the LaTeX paragraph being processed
-# - texcode: what remains of LaTeX code to process (after line)
-# - texlength: length of LaTeX code
-# - next: the next token, i.e. the one being processed
-# - type: the type of the next token
-# - style: the present output style (for verbose output)
-# - printstate: present parsing state (for verbose output only)
-# - eof: set once the end of the input is reached
-# which are passed to methods by passing the TeX object. It is used when parsing
-# the LaTeX code, and discarded once the parsing is done. During parsing, counts
-# are added to the subcount element; whenever a break point is encountered, the
-# subcount is added to the countsum (next_subcount) and a new subcount object
-# prepared. Note that this requires that the last subcount object be added to
-# the countsum once the end of the document is reached.
-sub TeXcode {
- my ($bincode,$file,$title)=@_;
- my $tex=_TeXcode_blank($file,$title);
- _TeXcode_setcode($tex,$bincode);
- more_texcode($tex);
- return $tex;
-}
-
-# Return a blank TeXcode object
-sub _TeXcode_blank {
- my ($file,$title)=@_;
- if (defined $title) {}
- elsif (defined $file) {$title='File: '.$file;}
- else {$title='Word count';}
- my %TeX=();
- $TeX{'errorcount'}=0;
- $TeX{'warnings'}={};
- $TeX{'filepath'}=$file;
- if (!defined $file) {}
- elsif ($file=~/^<.+>$/) {$TeX{'filename'}=$file;}
- elsif ($file=~/^(.*[\\\/])([^\\\/]+)$/) {
- $TeX{'dirpath'}=$1; $TeX{'filename'}=$2;
- }
- else {$TeX{'dirpath'}=''; $TeX{'filename'}=$file;}
- $TeX{'PATH'}=[];
- $TeX{'line'}='';
- $TeX{'next'}=undef;
- $TeX{'type'}=undef;
- $TeX{'style'}=undef;
- $TeX{'printstate'}=undef;
- $TeX{'eof'}=0;
- my $countsum=new_count($title);
- $TeX{'countsum'}=$countsum;
- $countsum->{'TeXcode'}=\%TeX;
- my $count=new_count('_top_');
- $TeX{'subcount'}=$count;
- inc_count(\%TeX,$CNT_FILE);
- return \%TeX;
-}
-
-# Set the texcode element of the TeXcount object
-sub _TeXcode_setcode {
- my ($tex,$bincode)=@_;
- $tex->{'texcode'}=_prepare_texcode($tex,$bincode);
- $tex->{'texlength'}=length($tex->{'texcode'});
-}
-
-# Decode and return TeX/LaTeX code
-sub _prepare_texcode {
- my ($tex,$texcode)=@_;
- $texcode=_decode_texcode($tex,$texcode);
- foreach my $key (keys %substitutions) {
- my $value=$substitutions{$key};
- $texcode=~s/(\w)\Q$key\E/$1 $value/g;
- $texcode=~s/\Q$key\E/$value/g;
- }
- return $texcode;
-}
-
-# Return text decoder
-sub _decode_texcode {
- my ($tex,$texcode)=@_;
- my $decoder;
- if (defined $encoding) {
- $decoder=find_encoding($encoding);
- eval {$texcode=$decoder->decode($texcode);};
- if ($@) {
- error($tex,'Decoding file/text using the '.$decoder->name.' encoding failed.');
- }
- } else {
- ($texcode,$decoder)=_guess_encoding($texcode);
- if (!ref($decoder)) {
- error($tex,'Failed to identify encoding or incorrect encoding specified.');
- $tex->{'encoding'}='[FAILED]';
- return $texcode;
- }
- }
- __set_encoding_name($tex,$decoder->name);
- $texcode =~ s/^\x{feff}//; # Remove BOM (relevant for UTF only)
- if ($texcode =~/\x{fffd}/ ) {
- error($tex,'File/text was not valid '.$decoder->name.' encoded.');
- }
- return $texcode;
-}
-
-# Guess the right encoding to use
-sub _guess_encoding {
- my ($texcode)=@_;
- foreach my $enc (@encodingGuessOrder) {
- my $dec=find_encoding($enc);
- if (ref($dec)) {
- eval {
- $texcode=$dec->decode($texcode,Encode::FB_CROAK)
- };
- if (!$@) {return $texcode,$dec;}
- }
- }
- return $texcode,undef;
-}
-
-# Set name of current encoding
-sub __set_encoding_name {
- my ($tex,$enc)=@_;
- my $cur=$tex->{'encoding'};
- if (!defined $enc) {$enc='[FAILED]';} # Shouldn't happen here though...
- if (!defined $cur) {}
- elsif ($enc eq 'ascii') {$enc=$cur;}
- elsif ($cur eq 'ascii') {}
- elsif ($cur ne $enc) {
- error($tex,"Mismatching encodings: $cur versus $enc.");
- }
- $tex->{'encoding'}=$enc;
-}
-
-# Apply substitution rule
-sub apply_substitution_rule {
- my ($tex,$from,$to)=@_;
- $tex->{'line'}=~s/(\w)\Q$from\E\b\s*/$1 $to/g;
- $tex->{'line'}=~s/\Q$from\E\b\s*/$to/g;
- $tex->{'texcode'}=~s/(\w)\Q$from\E\b\s*/$1 $to/g;
- $tex->{'texcode'}=~s/\Q$from\E\b\s*/$to/g;
-}
-
-## Get more TeX code from texcode buffer if possible, return 1 if done
-sub more_texcode {
- my ($tex)=@_;
- if ($tex->{'texcode'} eq '') {return 0;}
- if ( $optionFast && $tex->{'texcode'} =~ s/^(.*?(\r{2,}|\n{2,}|(\r\n){2,}))//s ) {
- $tex->{'line'}.=$1; # $1 ~ ${^MATCH}
- return 1;
- }
- $tex->{'line'}.=$tex->{'texcode'};
- $tex->{'texcode'}='';
- return 1;
-}
-
-## Prepend LaTeX code to TeXcode object
-sub prepend_code {
- my ($tex,$code,$filename)=@_;
- my $prefix="\n% --- Start of included file $filename\n";
- my $suffix="\n% --- End of included file $filename\n";
- $code=_decode_texcode($tex,$code);
- $tex->{'length'}+=length($code);
- $tex->{'texcode'}=$prefix.$code.$suffix.$tex->{'line'}.$tex->{'texcode'};
- $tex->{'line'}='';
- more_texcode($tex);
-}
-
-# Save and return TeXcode state, and replace with new text
-sub texcode_insert_text {
- my ($tex,$code,$filename,@path)=@_;
- my %texstate=(
- 'texcode'=>$tex->{'line'}.$tex->{'texcode'},
- 'eof'=>$tex->{'eof'},
- 'PATH'=>$tex->{'PATH'});
- my $prefix="\n% --- Start of included file $filename\n";
- my $suffix="\n% --- End of included file $filename\n";
- $code=_decode_texcode($tex,$code);
- $tex->{'length'}+=length($code);
- $tex->{'texcode'}=$prefix.$code.$suffix;
- $tex->{'line'}='';
- more_texcode($tex);
- return \%texstate;
-}
-
-# Restore TeXcode state
-sub texcode_restore_state {
- my ($tex,$texstate)=@_;
- while (my ($key,$value)=each %$texstate) {
- $tex->{$key}=$value;
- }
-}
-
-## Returns size of TeX code in bytes
-sub get_texsize {
- my $tex=shift @_;
- return $tex->{'texlength'}
-}
-
-
-
-###### TeX file reader
-
-
-# Read LaTeX file into TeX object
-sub TeXfile {
- my ($filename,$title)=@_;
- my ($header,$bincode);
- if ($filename eq $_STDIN_) {
- $header='File from STDIN';
- $bincode=_read_stdin();
- } else {
- defined ($bincode=read_binary($filename)) || return undef;
- $header='File: '.$filename;
- }
- if ($printlevel>0) {
- formatprint($header."\n",'h2');
- $blankline=0;
- }
- my $tex=TeXcode($bincode,$filename,$title);
- return $tex;
-}
-
-# Read file to string without regard for encoding
-sub read_binary {
- my $filename=shift @_;
- open(FH,$filename) || return undef;
- binmode(FH);
- my $bincode;
- read(FH,$bincode,-s FH);
- close(FH);
- return $bincode;
-}
-
-# Read file from STDIN
-sub _read_stdin {
- my @text=<STDIN>;
- my $latexcode=join('',@text);
- return $latexcode;
-}
-
-
-###### Error handling
-
-
-# Print note to output
-sub note {
- my ($tex,$level,$text,$prefix,$style)=@_;
- if ($printlevel>=$level) {
- $prefix=(defined $prefix)?$prefix:'%NOTE: ';
- $style=(defined $style)?$style:'note';
- $text=count_in_template($tex->{'subcount'},$text);
- flush_next($tex);
- line_return(0,$tex);
- print_style($prefix.$text,$style);
- flush_next($tex);
- $blankline=-1;
- }
-}
-
-# Compare count with expected and note if assertion fails
-sub assertion_note {
- my ($tex,$checktext,$template)=@_;
- my $count=$tex->{'subcount'};
- my @check=split(/,/,$checktext);
- my @actual;
- for (my $i=scalar @check;$i>0;$i--) {$actual[$i-1]=get_count($count,$i);}
- for (my $i=scalar @check;$i>0;$i--) {
- if ($check[$i-1] ne $actual[$i-1]) {
- my $msg=$template.' [expected:'.join('+',@check).'; found: '.join('+',@actual).']';
- note($tex,0,$msg,'%ASSERTION FAILED: ','error');
- return 1;
- }
- }
- return 0;
-}
-
-# Add warning to list of registered warnings (optionally to be reported at the end)
-sub warning {
- my ($tex,$text)=@_;
- $warnings{$text}++;
- # TODO: should only add warnings to subcount, not to TeXcode object
- $tex->{'warnings'}->{$text}++;
- if (my $count=$tex->{'subcount'}) {$count->{'warnings'}->{$text}++};
-}
-
-# Register error and print error message
-sub error {
- my ($tex,$text,$type)=@_;
- if (defined $type) {$text=$type.': '.$text;}
- $errorcount++;
- $tex->{'errorcount'}++;
- if (my $count=$tex->{'subcount'}) {$count->{'errorcount'}++};
- if (my $err=$tex->{'errorbuffer'}) {push @$err,$text;}
- else {print_error($text);}
-}
-
-# Print error details
-sub error_details {
- my ($tex,$text)=@_;
- print STDERR $text,"\n";
-}
-
-# Make assertion: i.e. report error if not true and return truthfullness
-sub assert {
- my $assertion=shift @_;
- if ($assertion) {return 1;}
- error(@_);
- return 0;
-}
-
-# Print error message
-sub print_error {
- my $text=shift @_;
- line_return(1);
- if ($printlevel<0) {
- print STDERR 'ERROR: ',$text,"\n";
- } elsif ($htmlstyle) {
- print STDERR 'ERROR: ',$text,"\n";
- print_style($text,'error');
- } else {
- print_style("!!! $text !!!",'error');
- }
- line_return(1);
-}
-
-# Print errors in buffer and delete errorbuffer
-sub flush_errorbuffer {
- my $source=shift @_;
- my $err=$source->{'errorbuffer'} || return;
- foreach (@$err) {print_error($_);}
- $source->{'errorbuffer'}=undef;
-}
-
-
-###### Parsing routines
-
-
-# Parse LaTeX document
-sub parse {
- my ($tex)=@_;
- if ($htmlstyle && $printlevel>0) {print "<div class='parse'><p>\n";}
- parse_all($tex);
- if ($htmlstyle && $printlevel>0) {print "</p></div>\n";}
-}
-
-# Parse until end
-sub parse_all {
- my ($tex,$state)=@_;
- if (!defined $state) {$state=$STATE_TEXT;}
- while (!($tex->{'eof'})) {
- _parse_unit($tex,$state);
- }
-}
-
-# Parse one block/unit with given state until end token
-# If end token is set to $_PARAM_, unit is assumed to be a parameter
-# and words parsed as individual letters (simple_token is set)
-sub _parse_unit {
- my ($tex,$state,$end)=@_;
- my $simple_token=0;
- ( assert(defined $state,$tex,'Undefined parser state!','BUG')
- && assert(!ref($state),$tex,'Invalid parser state of type '.ref($state).'!','BUG')
- ) || exit;
- $state=transition_to_content_state($tex,$state);
- _set_printstate($tex,$state,$end);
- if (defined $end && $end eq $_PARAM_) {
- $end=undef;
- $simple_token=1;
- }
- my $next;
- my @specarg;
- while (defined ($next=next_token($tex,$simple_token))) {
- # Parse next token until token matches $end
- set_style($tex,'ignore');
- if ($state==$STATE_MATH) {set_style($tex,'math');}
- if ((defined $end) && ($end eq $next)) {return @specarg;}
- # Determine how token should be interpreted
- if ($state==$STATE_PREAMBLE && $next eq '\begin' && $tex->{'line'}=~/^\{\s*document\s*\}/) {
- # \begin{document}
- $state=$STATE_TEXT;
- }
- # Pick the first matching interpretation:
- if ($state==$STATE_EXCLUDE_ALL) {
- # ignore everything
- } elsif ($tex->{'type'}==$TOKEN_SPACE) {
- # space or other code that should be passed through without styling
- flush_next($tex,' ');
- } elsif ($next eq '{') {
- # {...} group
- set_style($tex,'ignore');
- push @specarg,_parse_unit($tex,$state,'}');
- set_style($tex,'ignore');
- } elsif ($next eq '}') {
- error($tex,'Encountered } without corresponding {.');
- } elsif ($tex->{'type'}==$TOKEN_TC) {
- # parse TC instructions
- _parse_tc($tex,$next);
- } elsif ($state==$STATE_SPECIAL_ARGUMENT) {
- set_style($tex,'specarg');
- push @specarg,$next;
- } elsif ($tex->{'type'}==$TOKEN_WORD) {
- # word
- if (my $cnt=state_text_cnt($state)) {
- _process_word($tex,$next,$state);
- inc_count($tex,$cnt);
- set_style($tex,state_to_style($state));
- }
- } elsif ($state==$STATE_EXCLUDE_STRONGER) {
- # ignore remaining tokens
- set_style($tex,'ignore');
- } elsif ($next eq '\documentclass') {
- # defines document class and starts preamble
- set_style($tex,'document');
- _parse_documentclass_params($tex);
- while (!($tex->{'eof'})) {
- push @specarg,_parse_unit($tex,$STATE_PREAMBLE);
- }
- } elsif ($tex->{'type'}==$TOKEN_MACRO) {
- # macro call
- _parse_macro($tex,$next,$state);
- } elsif ($next eq '$') {
- # math inline
- _parse_math($tex,$state,$CNT_COUNT_INLINEMATH,'$');
- } elsif ($next eq '$$') {
- # math display (unless already in inlined math)
- if (!(defined $end && $end eq '$')) {
- _parse_math($tex,$state,$CNT_COUNT_DISPLAYMATH,'$$');
- }
- } elsif ($simple_token) {
- #DELETE: simple tokens should be handled properly
- #print STDERR '<',$next,'>',"\n";
- # handle as parameter that should not be counted
- set_style($tex,'ignore');
- }
- if (!defined $end) {return @specarg;}
- }
- defined $end && error($tex,'Reached end of file while waiting for '.$end.'.');
- return @specarg;
-}
-
-# Print state
-sub _set_printstate {
- my ($tex,$state,$end)=@_;
- $tex->{'printstate'}=':'.state_to_text($state).(defined $end?'>'.$end:'').':';
- flush_next($tex);
-}
-
-# Process word with a given state (>0, i.e. counted)
-sub _process_word {
- my ($tex,$word,$state)=@_;
- $WordFreq{$word}++;
-}
-
-# Parse unit when next token is a macro
-sub _parse_macro {
- my ($tex,$next,$state)=@_;
- my $substat;
- my @macro=($next);
- if (my $label=$BreakPoints{$next}) {
- if ($tex->{'line'}=~ /^[*]?(\s*\[.*?\])*\s*\{((.|\{.*\})*)\}/ ) {
- $label=$label.': '.$2;
- }
- next_subcount($tex,$label);
- }
- if ($state==$STATE_MATH) {set_style($tex,'mathcmd');}
- elsif ($state==$STATE_SPECIAL_ARGUMENT) {set_style($tex,'specarg');}
- else {set_style($tex,state_is_text($state)?'cmd':'exclcmd');}
- if ($next eq '\begin' && state_inc_envir($state)) {
- _parse_envir($tex,$state);
- push @macro,'<envir>';
- } elsif ($next eq '\end' && state_inc_envir($state)) {
- error($tex,'Encountered \end without corresponding \begin');
- push @macro,$STRING_ERROR;
- } elsif ($next eq '\verb') {
- _parse_verb_region($tex,$state);
- } elsif (state_is_parsed($state) && defined (my $substat=$TeXpackageinc{$next})) {
- # Parse macro parameters, use _parse_include_argument to process package list
- set_style($tex,'document');
- push @macro,__gobble_macro_parms($tex,$substat,$__STATE_NULL,\&_parse_include_argument);
- push @macro,'<package>';
- } elsif (state_is_parsed($state) && defined (my $def=$TeXfileinclude{$next})) {
- # include file (merge in or queue up for parsing)
- set_style($tex,'cmd');
- if (defined ($substat=$TeXmacro{'@pre'.$next})) {__gobble_macro_parms($tex,$substat,$state);}
- __count_macrocount($tex,$next,$state);
- _parse_include_file($tex,$state,$def);
- push @macro,'<filespec>';
- if (defined ($substat=$TeXmacro{'@post'.$next})) {__gobble_macro_parms($tex,$substat,$state);}
- } elsif (($state==$STATE_FLOAT) && ($substat=$TeXfloatinc{$next})) {
- # text included from float
- set_style($tex,'cmd');
- push @macro,__gobble_macro_parms($tex,$substat,$__STATE_NULL);
- } elsif ($state==$STATE_PREAMBLE && defined ($substat=$TeXpreamble{$next})) {
- # parse preamble include macros
- set_style($tex,'cmd');
- __count_macrocount($tex,$next,$STATE_TEXT);
- push @macro,__gobble_macro_parms($tex,$substat,$__STATE_NULL);
- } elsif (state_is_exclude($state)) {
- # ignore
- push @macro,__gobble_options($tex),'/*ignored*/';
- } elsif ($next eq '\(') {
- # math inline
- _parse_math($tex,$state,$CNT_COUNT_INLINEMATH,'\)');
- } elsif ($next eq '\[') {
- # math display
- _parse_math($tex,$state,$CNT_COUNT_DISPLAYMATH,'\]');
- } elsif ($next=~/^\\(def|edef|gdef|xdef)$/) {
- # ignore \def...
- $tex->{'line'} =~ s/^([^\{]*)\{/\{/;
- flush_next($tex);
- print_style($1,'ignore');
- _parse_unit($tex,$STATE_EXCLUDE_STRONG);
- push @macro,'<macro>',$STRING_PARAMETER;
- } elsif (defined ($substat=$TeXmacro{$next})) {
- # macro: exclude options
- __count_macrocount($tex,$next,$state);
- push @macro,__gobble_macro_parms($tex,$substat,$state);
- } elsif (defined __count_macrocount($tex,$next,$state)) {
- # count macro as word (or a given number of words)
- } elsif ($next =~ /^\\[^\w\_]$/) {
- # handle \<symbol> as single symbol macro
- push @macro,__gobble_options($tex),'/*symbol*/';
- } else {
- push @macro,__gobble_options($tex),'/*defaultrule*/';
- }
- $MacroUsage{join('',@macro)}++;
-}
-
-# Parse TC instruction
-sub _parse_tc {
- my ($tex,$next)=@_;
- set_style($tex,'tc');
- flush_next($tex);
- assert($next=~s/^\%+TC:\s*(\w+)\s*//i
- ,$tex,'TC command should have format %TC:instruction [[parameters]]')
- || return;
- my $instr=$1;
- $instr=~tr/[A-Z]/[a-z]/;
- if ($instr eq 'break') {next_subcount($tex,$next);
- } elsif ($instr=~/^(incbib|includebibliography)$/) {
- $includeBibliography=1;
- apply_include_bibliography();
- } elsif ($instr eq 'ignore') {__gobble_tc_ignore($tex);
- } elsif ($instr eq 'endignore') {error($tex,'%TC:endignore without corresponding %TC:ignore.');
- } elsif ($instr eq 'newtemplate') {$outputtemplate='';
- } elsif ($instr eq 'template') {$outputtemplate.=$next;
- } elsif ($instr eq 'insert') {
- $tex->{'line'}="\n".$next.$tex->{'line'};
- } elsif ($instr eq 'subst') {
- if ($next=~/^(\S+)\s*(\S.*)?$/) {
- my $from=$1;
- my $to=$2;
- $substitutions{$from}=$to;
- apply_substitution_rule($tex,$from,$to);
- } else {
- error($tex,'Invalid %TC:subst format.');
- }
- } elsif ($instr eq 'newcounter') {
- assert($next=~s/^(\w+)(=(\w+))?\s*//,$tex,'Expected format: %TC:newcounter {key}[={like-key}] {description}')
- || return;
- my $key=$1;
- my $like=$3;
- if ($next eq '') {$next=$key;}
- add_new_counter($key,$next,$like);
- } elsif ($instr eq 'log') {
- assert($next=~s/^(.*)$//,$tex,'Expected format: %TC:log {text or template}') || return;
- note($tex,1,$1);
- } elsif ($instr eq 'assert') {
- assert($next=~s/^(\d+(,\d+)*)(\s+(.*))?$//,$tex,'Expected format: %TC:assert count+count+... {text or template}')
- || return;
- my $template=$4 || 'Words counted: {w} in text, {hw} in headers, {ow} other.';
- assertion_note($tex,$1,$template);
- } elsif ($next=~/^([\\]*\S+)\s+([^\s]+)(\s+(-?\w+))?/) {
- # %TC:instr macro param option
- my $macro=$1;
- my $param=$2;
- my $option=$4;
- tc_macro_param_option($tex,$instr,$macro,$param,$option);
- } else {
- error($tex,'Invalid TC command: '.$instr);
- }
-}
-
-# Parse math formulae
-sub _parse_math {
- my ($tex,$state,$cnt,$end)=@_;
- my $localstyle;
- if (state_is_text($state)) {
- $localstyle='mathgroup';
- inc_count($tex,$cnt);
- } else {
- $localstyle='exclmath';
- }
- set_style($tex,$localstyle);
- _parse_unit($tex,$STATE_MATH,$end);
- set_style($tex,$localstyle);
-}
-
-# Parse \verb region
-sub _parse_verb_region {
- my ($tex,$state)=@_;
- #flush_next($tex);
- __gobble_macro_modifier($tex);
- set_style($tex,'ignore');
- assert($tex->{'line'} =~ s/^([^\s])//,$tex,'Invalid \verb: delimiter required.')
- || return;
- my $dlm=$1;
- print_style($dlm,'cmd');
- assert($tex->{'line'}=~s/^([^\Q$dlm\E]*)(\Q$dlm\E)//
- ,$tex,'Invalid \verb: could not find ending delimiter ('.$dlm.').')
- || return;
- print_style($1,'ignore');
- print_style($2,'cmd');
-}
-
-# Parse environment
-sub _parse_envir {
- my ($tex,$state)=@_;
- my $localstyle=state_is_text($state) ? 'envir' : 'exclenv';
- flush_next_gobble_space($tex,$localstyle,$state);
- my ($envirname,$next);
- if ($tex->{'line'} =~ s/^\{([^\{\}\s]+)\}[ \t\r\f]*//) {
- # gobble environment name
- $envirname=$1;
- my @macro=('<envir:'.$envirname.'>');
- print_style('{'.$1.'}',$localstyle);
- $next=$PREFIX_ENVIR.$envirname;
- __count_macrocount($tex,$next,$state);
- if (defined (my $def=$TeXmacro{$next})) {
- push @macro,__gobble_macro_parms($tex,$def,$__STATE_NULL);
- } else {
- push @macro,__gobble_options($tex);
- }
- $MacroUsage{join('',@macro)}++;
- } else {
- $envirname='???'; $next='???';
- error($tex,'Encountered \begin without environment name provided.');
- }
- # find new parsing state (or leave unchanged)
- my $substat=$TeXenvir{$1};
- if (!defined $substat) {
- $substat=$state;
- if ($strictness>=1) {
- warning($tex,'Using default rule for environment '.$envirname);
- }
- } else {
- $substat=__new_state($substat,$state);
- }
- if (state_inc_envir($substat)) {
- # Parse until \end arrives, and check that it matches
- _parse_unit($tex,$substat,'\end');
- flush_next_gobble_space($tex,$localstyle,$state);
- if ($tex->{'line'} =~ s/^\{([^\{\}\s]+)\}[ \t\r\f]*//) {
- # gobble environment name
- print_style('{'.$1.'}',$localstyle);
- assert($envirname eq $1,$tex,"Environment \\begin{$envirname} ended with \\end{$1}.");
- } else {
- error($tex,"Environment ended while waiting for \end{$envirname}.");
- }
- } else {
- # Keep parsing until appropriate \end arrives ignoring all else
- while (!$tex->{'eof'}) {
- _parse_unit($tex,$substat,'\end');
- if ($tex->{'line'} =~ s/^(\s*)(\{\Q$envirname\E\})[ \t\r\f]*//) {
- # gobble \end parameter and end environment
- flush_next($tex,$localstyle,$state);
- print_style($1,$localstyle);
- print_style($2,$localstyle);
- return;
- }
- }
- }
-}
-
-# Parse and process file inclusion
-sub _parse_include_file {
- my ($tex,$state,$includetype)=@_;
- my $include=state_is_parsed($state);
- my $style=$include?'fileinc':'ignore';
- my $file;
- my %params;
- flush_next($tex);
- $params{'<type>'}=$includetype;
- $params{'SUFFICES'}=[''];
- if ($includetype eq '<bbl>') {
- _parse_include_bbl($tex,$state,\%params);
- return;
- }
- elsif ($includetype eq 'input') {
- $tex->{'line'} =~ s/^(\s*\{([^\{\}\s]+)\})//
- || $tex->{'line'} =~ s/^(\s*([^\{\}\%\\\s]+))//
- || $tex->{'line'} =~ s/^(\s*\{(.+?)\})//
- || BLOCK {
- error($tex,'Failed to identify file name.');
- return;
- };
- print_style($1,$style);
- $file=$2;
- if (!($file=~/\.tex$/i)) {$params{'SUFFICES'}=['.tex',''];}
- }
- else {
- foreach my $param (split(/\s+|,/,$includetype)) {
- if ($param=~/^<.*>$/) {next;}
- $tex->{'line'} =~ s/(\s*\{)([^\{\}\%]*)(\})//|| BLOCK {
- error($tex,"Failed to identify file parameter {$param}.");
- return;
- };
- print_style($1,'ignore');
- print_style($2,$style);
- print_style($3,'ignore');
- if ($param eq 'file') {
- $file=$2;
- if (!($file=~/\.tex$/i)) {$params{'SUFFICES'}=['.tex',''];}
- } elsif ($param eq 'texfile') {
- $file=$2.'.tex';
- } else {$params{$param}=$2;}
- }
- }
- if (!defined $file) {
- error($tex,'Undefined file name.');
- }
- elsif ($includeTeX && $include) {
- include_file($tex,$state,$file,\%params);
- }
-}
-
-# Parse and process bibliography file
-sub _parse_include_bbl {
- my ($tex,$state,$params)=@_;
- if ($includeBibliography && state_is_text($state)) {
- my $filename=$tex->{'filename'};
- $filename=~s/(\.tex)?$/\.bbl/i;
- include_file($tex,$state,$filename,$params);
- }
-}
-
-# Parse and process package inclusion
-sub _parse_include_package {
- my ($tex)=@_;
- set_style($tex,'document');
- if ( $tex->{'line'}=~s/^\{(([\w\-]+)(\s*,\s*[\w\-]+)*)\}// ) {
- print_style("{$1}",'document');
- foreach (split(/\s*,\s*/,$1)) {
- $MacroUsage{"<package:$_>"}++;
- include_package($_,$tex);
- }
- } else {
- _parse_unit($tex,$STATE_IGNORE);
- error($tex,'Could not recognise package list, ignoring it instead.');
- }
-}
-
-# Extract package names from token list and include packages
-sub _parse_include_argument {
- my $tex=shift @_;
- my $args=join('',@_);
- set_style($tex,'document');
- foreach (split(/\s*,\s*/,$args)) {
- $MacroUsage{"<package:$_>"}++;
- include_package($_,$tex);
- }
-}
-
-# Parse \documentclass parameters and include rules
-sub _parse_documentclass_params {
- my ($tex)=@_;
- my $options=__gobble_option($tex);
- if ( $tex->{'line'}=~s/^(\{\s*([^\{\}\s]+)\s*\})// ) {
- print_style("$1",'document');
- $MacroUsage{"<documentclass:$2>"}++;
- include_package("class%$2",$tex);
- } else {
- _parse_unit($tex,$STATE_IGNORE);
- error($tex,'Could not identify document class.');
- }
-}
-
-# Count macrocount using given state
-sub __count_macrocount {
- my ($tex,$next,$state)=@_;
- my $def=$TeXmacrocount{$next};
- my $cnt;
- if (!defined $def) {return undef;}
- elsif (ref($def) eq 'ARRAY') {
- # TODO: Is this an appropriate style to use?
- set_style($tex,state_to_style($state));
- flush_next($tex);
- foreach $cnt (@{$def}) {
- if ($cnt==$CNT_WORDS_TEXT) {$cnt=state_text_cnt($state);}
- inc_count($tex,$cnt);
- }
- }
- elsif ($cnt=state_text_cnt($state)) {
- set_style($tex,state_to_style($state));
- flush_next($tex);
- inc_count($tex,$cnt,$def);
- }
- return $def;
-}
-
-# Gobble next option, return option or undef if none
-sub __gobble_option {
- my $tex=shift @_;
- flush_next_gobble_space($tex);
- if ($tex->{'line'}=~s/^($MacroOptionPattern)//) {
- print_style($1,'option');
- return $1;
- }
- return undef;
-}
-
-# Gobble all options, return the number of gobble options
-sub __gobble_options {
- my $n=0;
- while (__gobble_option(@_)) {$n++}
- return ($STRING_GOBBLED_OPTION)x$n;
-}
-
-# Gobble macro modifyer (e.g. following *)
-sub __gobble_macro_modifier {
- my $tex=shift @_;
- flush_next($tex);
- if ($tex->{'line'} =~ s/^(\*)//) {
- print_style($1,'option');
- return $1;
- }
- return;
-}
-
-# Gobble macro parameters as specified in parm plus options
-sub __gobble_macro_parms {
- my ($tex,$parm,$oldstat,$specarghandler)=@_;
- my $n;
- my @ret;
- if (ref($parm) eq 'ARRAY') {
- $n=scalar @{$parm};
- } else {
- $n=$parm;
- $parm=[($STATE_IGNORE)x$n];
- }
- # TODO: Optionally gobble macro modifier?
- if ($n>0) {push @ret,__gobble_macro_modifier($tex);}
- my $auto_gobble_options=1;
- for (my $j=0;$j<$n;$j++) {
- my $p=$parm->[$j];
- if ($p==$_STATE_OPTION) {
- # Parse macro option
- $p=$parm->[++$j];
- if ($tex->{'line'}=~s/^(\s*\[)//) {
- flush_next_gobble_space($tex);
- print_style($1,'optparm');
- push @ret,$STRING_OPTIONAL_PARAM;
- _parse_unit($tex,__new_state($p,$oldstat),']');
- set_style($tex,'optparm');
- }
- } elsif ($p==$_STATE_NOOPTION) {
- $auto_gobble_options=0;
- } elsif ($p==$_STATE_AUTOOPTION) {
- $auto_gobble_options=1;
- } else {
- # Parse macro parameter
- if ($auto_gobble_options) {push @ret,__gobble_options($tex);}
- push @ret,$STRING_PARAMETER;
- my @specarg=_parse_unit($tex,__new_state($p,$oldstat),$_PARAM_);
- if ($p==$STATE_SPECIAL_ARGUMENT && defined $specarghandler) {
- &$specarghandler($tex,@specarg);
- }
- }
- }
- #TODO: Drop default gobbling of option at end?
- if ($auto_gobble_options) {push @ret,__gobble_options($tex);}
- return @ret;
-}
-
-# Parse through ignored LaTeX code
-sub __gobble_tc_ignore {
- my ($tex)=@_;
- set_style($tex,'ignore');
- _parse_unit($tex,$STATE_EXCLUDE_ALL,'%TC:endignore');
- set_style($tex,'tc');
- flush_next($tex);
-}
-
-# Return new parsing state given old and substate
-sub __new_state {
- my ($substat,$oldstat)=@_;
- if (!defined $oldstat) {return $substat;}
- foreach my $st (@STATE_FIRST_PRIORITY,@STATE_MID_PRIORITY,@STATE_LAST_PRIORITY) {
- if ($oldstat==$st || $substat==$st) {return $st;}
- }
- error($Main,'Could not determine new state in __new_state!','BUG');
- return $oldstat;
-}
-
-
-
-###### Tokenisation routines
-
-
-# Get next token skipping comments and flushing output buffer
-sub next_token {
- my ($tex,$simple_token)=@_;
- if (!defined $simple_token) {$simple_token=0;}
- my ($next,$type);
- my $style=$tex->{'style'};
- if (defined $tex->{'next'}) {print_style($tex->{'next'},$tex->{'style'});}
- $tex->{'style'}=undef;
- while (defined ($next=_get_next_token($tex,$simple_token))) {
- $type=$tex->{'type'};
- if ($type==$TOKEN_COMMENT) {
- print_style($next,'comment');
- } elsif ($type==$TOKEN_LINEBREAK) {
- if ($printlevel>0) {line_return(-1,$tex);}
- } else {
- return $next;
- }
- }
- return $next;
-}
-
-# Read, interpret and return next token
-# If simple_token is set, words cannot form tokens
-sub _get_next_token {
- my ($tex,$simple_token)=@_;
- my $next;
- my $ch;
- while (!$tex->{'eof'}) {
- $ch=substr($tex->{'line'},0,1);
- if ($ch eq '') {
- if (!more_texcode($tex)) {$tex->{'eof'}=1;}
- next;
- } elsif ($ch=~/^[ \t\f]/) {
- $tex->{'line'}=~s/^([ \t\f]+)//;
- return __set_token($tex,$1,$TOKEN_SPACE);
- } elsif ($ch eq "\n" || $ch eq "\r") {
- $tex->{'line'}=~s/^(\r\n?|\n)//;
- return __set_token($tex,$1,$TOKEN_LINEBREAK);
- } elsif (!$simple_token && $tex->{'line'}=~s/^($WordPattern)//o) {
- return __set_token($tex,$1,$TOKEN_WORD);
- } elsif ($simple_token && $tex->{'line'}=~s/^(\w)//) {
- # When parsing simple tokens (not words), only include single characters
- # TODO: the handling of simple tokens should be improved
- my $match=$1;
- if ($match=~/^$WordPattern$/) {return __set_token($tex,$match,$TOKEN_WORD);}
- else {return __set_token($tex,$match,$TOKEN_SYMBOL);}
- } elsif ($ch eq '\\') {
- if ($tex->{'line'}=~s/^(\\[\{\}%])//) {return __set_token($tex,$1,$TOKEN_SYMBOL);}
- if ($tex->{'line'}=~s/^(\\([a-zA-Z@]+|[^a-zA-Z@[:^print:]]))//) {return __set_token($tex,$1,$TOKEN_MACRO);}
- return __get_chtoken($tex,$ch,$TOKEN_END);
- } elsif ($ch eq '$') {
- $tex->{'line'}=~s/^(\$\$?)//;
- return __set_token($tex,$1,$TOKEN_MATH);
- } elsif ($ch eq '{' || $ch eq '}') {
- return __get_chtoken($tex,$ch,$TOKEN_BRACE);
- } elsif ($ch eq '[' || $ch eq ']') {
- return __get_chtoken($tex,$ch,$TOKEN_BRACKET);
- } elsif ($ch=~/^['"`:.,()[]!+-*=\/^_@<>~#&]$/) {
- return __get_chtoken($tex,$ch,$TOKEN_SYMBOL);
- } elsif ($ch eq '%') {
- if ($tex->{'line'}=~s/^(\%+TC:\s*endignore\b[^\r\n]*)//i) {
- __set_token($tex,$1,$TOKEN_TC);
- return "%TC:endignore";
- }
- if ($tex->{'line'}=~s/^(\%+[tT][cC]:[^\r\n]*)//) {return __set_token($tex,$1,$TOKEN_TC);}
- if ($tex->{'line'}=~s/^(\%+[^\r\n]*)//) {return __set_token($tex,$1,$TOKEN_COMMENT);}
- return __get_chtoken($tex,$ch,$TOKEN_COMMENT);
- } else {
- return __get_chtoken($tex,$ch,$TOKEN_END);
- }
- }
- return undef;
-}
-
-# Set next token and its type
-sub __set_token {
- my ($tex,$next,$type)=@_;
- $tex->{'next'}=$next;
- $tex->{'type'}=$type;
- return $next;
-}
-
-# Set character token and remove from line
-sub __get_chtoken {
- my ($tex,$ch,$type)=@_;
- $tex->{'line'}=substr($tex->{'line'},1);
- $tex->{'next'}=$ch;
- $tex->{'type'}=$type;
- return $ch;
-}
-
-
-
-###### Count handling routines
-
-
-
-## Make new count object
-# The "count object" is a hash containing:
-# - title: the title of the count (name of file, section, ...)
-# - counts: a list of numbers (the counts: files, text words, ...)
-# - subcounts: list of count objects (used by the TeX object)
-# - warnings: list of warnings produced
-# The elements are specified by the $CONT_* constants.
-sub new_count {
- my ($title)=@_;
- my @cnt=(0) x $SIZE_CNT;
- my %count=('counts'=>\@cnt,'title'=>$title,'subcounts'=>[],'errorcount'=>0,'warnings'=>{});
- return \%count;
-}
-
-# Ensure the count array is of the right size
-sub update_count_size {
- my $count=shift @_;
- my $counts=$count->{'counts'};
- while (scalar @{$counts}<$SIZE_CNT) {push @$counts,0;}
-}
-
-# Increment TeX count for a given count type
-sub inc_count {
- my ($tex,$cnt,$value)=@_;
- my $count=$tex->{'subcount'};
- if (!defined $value) {$value=1;}
- ${$count->{'counts'}}[$cnt]+=$value;
-}
-
-# Get count value for a given count type
-sub get_count {
- my ($count,$cnt)=@_;
- my $counts=$count->{'counts'};
- if ($cnt<scalar @{$counts}) {return ${$counts}[$cnt];}
- else {return 0;}
-}
-
-# Compute sum count for a count object
-sub get_sum_count {
- my $count=shift @_;
- my $sum=0;
- for (my $i=scalar(@sumweights);$i-->1;) {
- if ($sumweights[$i]) {
- $sum+=get_count($count,$i)*$sumweights[$i];
- }
- }
- return $sum;
-}
-
-# Returns the number of subcounts
-sub number_of_subcounts {
- my $count=shift @_;
- if (my $subcounts=$count->{'subcounts'}) {
- return scalar(@{$subcounts});
- } else {
- return 0;
- }
-}
-
-# Returns the number of warnings (not distinct)
-sub number_of_warnings {
- my $count=shift @_;
- my $n=0;
- foreach my $m (values %{$count->{'warnings'}}) {$n+=$m;}
- return $n;
-}
-
-# Returns the number of distinct warnings
-sub number_of_distinct_warnings {
- my $count=shift @_;
- return scalar keys %{$count->{'warnings'}};
-}
-
-# Is a null count? (counts 1-7 zero, title starts with _)
-sub _count_is_null {
- my $count=shift @_;
- if (!$count->{'title'}=~/^_/) {return 0;}
- for (my $i=1;$i<$SIZE_CNT;$i++) {
- if (get_count($count,$i)>0) {return 0;}
- }
- if (scalar keys %{$count->{'warnings'}}) {return 0;}
- if ($count->{'errorcount'}) {return 0;}
- return 1;
-}
-
-# Add one count to another
-sub _add_to_count {
- my ($a,$b)=@_;
- update_count_size($a);
- update_count_size($b);
- for (my $i=0;$i<$SIZE_CNT;$i++) {
- ${$a->{'counts'}}[$i]+=${$b->{'counts'}}[$i];
- }
- while (my ($text,$n)=each %{$a->{'warnings'}}) {
- $a->{'warnings'}->{$text}+=$n;
- }
- $a->{'errorcount'}+=$b->{'errorcount'};
-}
-
-# Add subcount to sum count and prepare new subcount
-sub next_subcount {
- my ($tex,$title)=@_;
- add_to_total($tex->{'countsum'},$tex->{'subcount'});
- $tex->{'subcount'}=new_count($title);
- return $tex->{'countsum'};
-}
-
-# Add count to total as subcount
-sub add_to_total {
- my ($total,$count)=@_;
- _add_to_count($total,$count);
- if (_count_is_null($count)) {return;}
- push @{$total->{'subcounts'}},$count;
- $count->{'parentcount'}=$total;
-}
-
-
-###### Result output routines
-
-
-# Close the output (STDOUT), e.g. adding HTML tail
-sub Close_Output {
- if ($htmlstyle==$HTML_FULL) {
- html_tail();
- }
- close STDOUT;
-}
-
-# Report if there were any errors occurring during parsing
-sub Report_Errors {
- if (defined $outputtemplate) {return;}
- if ( !$briefsum && !$totalflag && $printlevel>=0 ) {
- foreach (keys %warnings) {formatprint($_,'p','nb');print "\n";}
- }
- if ($errorcount==0) {return;}
- if ($briefsum && $totalflag) {print ' ';}
- if ($htmlstyle) {
- print "<div class='error'><p>\n";
- print "There were $errorcount error(s) reported!\n";
- print "</p></div>\n";
- } elsif ($briefsum && $totalflag) {
- print "(errors:$errorcount)";
- } else {
- print "(errors:$errorcount)\n";
- }
-}
-
-# Print word frequencies (as text only)
-sub print_word_freq {
- my ($word,$wd,$freq,%Freq,%Word,%Class);
- my %regs;
- foreach my $cg (@AlphabetScripts,@LogogramScripts) {
- $regs{$cg}=qr/\p{$cg}/;
- }
- my $sum=0;
- for $word (keys %WordFreq) {
- $wd=lc $word;
- $Freq{$wd}+=$WordFreq{$word};
- $sum+=$WordFreq{$word};
- $Word{$wd}=__lc_merge($word,$Word{$wd});
- }
- if ($htmlstyle) {print "<table class='stat'>\n<thead>\n";}
- __print_word_freq('Word','Freq','th');
- if ($htmlstyle) {print "</thead>\n";}
- if ($optionWordClassFreq>0) {
- for $word (keys %Freq) {$Class{__word_class($word,\%regs)}+=$Freq{$word};}
- __print_sorted_freqs('langstat',\%Class);
- }
- if ($htmlstyle) {print "<tbody class='sumstat'>\n";}
- __print_word_freq('All words',$sum,'td','sum');
- if ($htmlstyle) {print "</tbody>\n";}
- if ($optionWordFreq>0) {__print_sorted_freqs('wordstat',\%Freq,\%Word,$optionWordFreq);}
- if ($htmlstyle) {print "</table>\n";}
-}
-
-# Merge to words which have the same lower case
-sub __lc_merge {
- my ($word,$w)=@_;
- if (defined $w) {
- for (my $i=length($word);$i-->0;) {
- if (substr($word,$i,1) ne substr($w,$i,1)) {
- substr($word,$i,1)=lc substr($word,$i,1);
- }
- }
- }
- return $word;
-}
-
-# Return the word class based on script groups it contains
-sub __word_class {
- my ($wd,$regs)=@_;
- my @classes;
- $wd=~s/\\\w+(\{\})?/\\{}/g;
- foreach my $name (keys %{$regs}) {
- if ($wd=~$regs->{$name}) {push @classes,$name;}
- }
- my $cl=join('+',@classes);
- if ($cl) {}
- elsif ($wd=~/\\/) {$cl='(macro)';}
- else {$cl='(unidentified)';}
- return $cl;
-}
-
-# Print table body containing word frequencies
-sub __print_sorted_freqs {
- my ($class,$Freq,$Word,$min)=@_;
- my $sum=0;
- my ($word,$wd,$freq);
- if (!defined $min) {$min=0;}
- if ($htmlstyle) {print "<tbody class='$class'>\n";}
- else {print "---\n";}
- for $wd (sort {$Freq->{$b} <=> $Freq->{$a}} keys %{$Freq}) {
- if (defined $Word) {$word=$Word->{$wd};} else {$word=$wd;}
- $freq=$Freq->{$wd};
- if ($freq>=$min) {
- $sum+=$freq;
- __print_word_freq($word,$freq);
- }
- }
- if ($min>0) {__print_word_freq('Sum of subset',$sum,'td','sum');}
- if ($htmlstyle) {print "</tbody>\n";}
-}
-
-# Print one word freq line
-sub __print_word_freq {
- my ($word,$freq,$tag,$class)=@_;
- if (!defined $tag) {$tag='td';}
- if (defined $class) {$class=" class='$class'";} else {$class='';}
- if ($htmlstyle) {
- print "<tr$class><$tag>$word</$tag><$tag>$freq</$tag></tr>\n";
- } else {
- print $word,': ',$freq,"\n";
- }
-}
-
-# Print macro usage statistics
-sub print_macro_stat {
- if ($htmlstyle) {print "<table class='stat'>\n<thead>\n";}
- __print_word_freq('Macro/envir','Freq','th');
- if ($htmlstyle) {print "</thead>\n";}
- if ($htmlstyle) {print "<tbody class='macrostat'>\n";}
- foreach my $name (sort keys %MacroUsage) {
- my $freq=$MacroUsage{$name};
- $name=text_to_printable($name);
- $name=text_to_print($name);
- if ($htmlstyle) {
- print "<tr><td>$name</td><td>$freq</td></tr>\n";
- } else {
- print $name,': ',$freq,"\n";
- }
- }
- if ($htmlstyle) {print "</tbody>\n";}
- if ($htmlstyle) {print "</table>\n";}
-}
-
-
-
-###### Printing routines
-
-
-# Print text using given style/colour
-sub print_with_style {
- my ($text,$style,$colour)=@_;
- if ($style eq $NOSTYLE) {
- print text_to_print($text);
- } elsif ($htmlstyle) {
- print "<span class='$style'>",text_to_print($text),'</span>';
- } else {
- ansiprint(text_to_print($text),$colour);
- if ($style=~/$separatorstyleregex/) {print $separator;}
- }
-}
-
-# Prepare text string for print: convert special characters
-sub text_to_print {
- my $text=join('',@_);
- if ($htmlstyle) {
- $text=~s/&/&amp;/g;
- $text=~s/</&lt;/g;
- $text=~s/>/&gt;/g;
- $text=~s/[ \t]{2}/\&nbsp; /g;
- } elsif ($texcodeoutput) {
- $text=~s/\\/\\textbackslash¤/g;
- $text=~s/([%\{\}])/\\$1/g;
- $text=~s/¤/{}/g;
- }
- return $text;
-}
-
-# Return &#xxx; code for character ;
-sub convert_to_charcode {
- my $ch=shift @_;
- return '&#'.ord($ch).';';
-}
-
-# Convert special characters to charcodes to make it printable ;
-sub text_to_printable {
- my $text=shift @_;
- $text=~s/([^[:print:]])/convert_to_charcode($1)/gse;
- return $text;
-}
-
-# Print text, using appropriate tags for HTML
-sub formatprint {
- my ($text,$tag,$class)=@_;
- my $break=($text=~s/(\r\n?|\n)$//);
- if ($htmlstyle && defined $tag) {
- print '<'.$tag;
- if ($class) {print " class='$class'";}
- print '>'.text_to_print($text)."</$tag>";
- } else {
- print text_to_print($text);
- }
- if ($break) {print "\n";}
-}
-
-# Add a line break to output
-sub linebreak {
- if ($htmlstyle) {print "<br>\n";} else {print "\n";}
-}
-
-
-###### Routines for printing count summary
-
-
-# Print count summary for a count object
-sub print_count {
- my ($count,$class,$title)=@_;
- line_return(0);
- if ($htmlstyle) {print "<div class='".($class||'count')."'>\n";}
- if (defined $title) {formatprint($title."\n",'h2');}
- if ($outputtemplate) {
- _print_count_template($count,$outputtemplate);
- } elsif ($briefsum && @sumweights) {
- _print_sum_count($count);
- } elsif ($briefsum) {
- if ($htmlstyle) {print "<p class='count'>";}
- _print_count_brief($count);
- if ($htmlstyle) {print "</p>\n";}
- } else {
- _print_count_details($count);
- }
- if ($htmlstyle) {print "</div>\n";}
-}
-
-# Return count,header,... list filling in header if missing
-sub __count_and_header {
- my $count=shift @_;
- my $header=__count_header($count);
- return $count,$header,@_;
-}
-
-# Return count title or '' if missing
-sub __count_header {
- my $count=shift @_;
- return $count->{'title'}||'';
-}
-
-# Print total count (sum) for a given count object
-sub _print_sum_count {
- my ($count,$header)=__count_and_header(@_);
- if ($htmlstyle) {print "<p class='count'>".text_to_print($header).": ";}
- print get_sum_count($count);
- if ($htmlstyle) {print "</p>\n";}
- else {print ": ".text_to_print($header);}
- print "\n";
-}
-
-# Print brief summary of count object
-sub _print_count_brief {
- my ($count,$header,$tag1,$tag2)=__count_and_header(@_);
- my @cnt=@{$count->{'counts'}};
- if ($htmlstyle && $tag1) {print '<',$tag1,'>';}
- print $cnt[$CNT_WORDS_TEXT],'+',$cnt[$CNT_WORDS_HEADER],'+',$cnt[$CNT_WORDS_OTHER];
- for (my $i=$SIZE_CNT_DEFAULT;$i<$SIZE_CNT;$i++) {
- if ($cnt[$i]) {print '+',$cnt[$i],$countkey[$i];}
- }
- print ' (',$cnt[$CNT_COUNT_HEADER],'/',$cnt[$CNT_COUNT_FLOAT],
- '/',$cnt[$CNT_COUNT_INLINEMATH],'/',$cnt[$CNT_COUNT_DISPLAYMATH],')';
- if ($htmlstyle && $tag2) {
- print '</',$tag1,'><',$tag2,'>';
- $tag1=$tag2;
- } else {print ' ';}
- print text_to_print($header);
- if ($htmlstyle && $tag1) {print '</',$tag1,'>';}
- if ($finalLineBreak) {print "\n";}
-}
-
-# Print detailed summary of count object
-sub _print_count_details {
- my ($count,$header)=__count_and_header(@_);
- if ($htmlstyle) {print "<ul class='count'>\n";}
- if ($header) {formatprint($header."\n",'li','header');}
- if (my $tex=$count->{'TeXcode'}) {
- if (!defined $encoding) {formatprint('Encoding: '.$tex->{'encoding'}."\n",'li');}
- }
- if (@sumweights) {formatprint('Sum count: '.get_sum_count($count)."\n",'li');}
- for (my $i=1;$i<$SIZE_CNT;$i++) {
- formatprint($countdesc[$i].': '.get_count($count,$i)."\n",'li');
- }
- if (get_count($count,$CNT_FILE)>1) {
- formatprint($countdesc[$CNT_FILE].': '.get_count($count,$CNT_FILE)."\n",'li');
- }
- my $subcounts=$count->{'subcounts'};
- if ($showsubcounts && defined $subcounts && scalar(@{$subcounts})>=$showsubcounts) {
- formatprint("Subcounts:\n",'li');
- if ($htmlstyle) {print "<span class='subcount'>\n";}
- formatprint(" text+headers+captions (#headers/#floats/#inlines/#displayed)\n",'li','fielddesc');
- foreach my $subcount (@{$subcounts}) {
- print ' ';
- _print_count_brief($subcount,'li');
- }
- if ($htmlstyle) {print "</span>\n";}
- }
- if ($htmlstyle) {print "</ul>\n";} else {print "\n";}
-}
-
-# Print summary of count object using template
-sub _print_count_template {
- my ($count,$header,$template)=__count_and_header(@_);
- $template=~s/\\n/\n/g;
- if ($htmlstyle) {$template=~s/\n/<br>/g;}
- my ($subtemplate,$posttemplate);
- while ($template=~/^(.*)\{SUB\?((.*?)\|)?(.*?)(\|(.*?))?\?SUB\}(.*)$/is) {
- __print_count_using_template($count,$1); # $1 ~ ${^PREMATCH}
- if (number_of_subcounts($count)>1) {
- if (defined $3) {print $3;}
- __print_subcounts_using_template($count,$4);
- if (defined $6) {print $6;}
- }
- $template=$7; # $7 ~ ${^POSTMATCH}
- }
- __print_count_using_template($count,$template);
-}
-
-# Return string with counts based on template
-sub count_in_template {
- my ($count,$template)=@_;
- while (my ($key,$cnt)=each %key2cnt) {
- $template=__process_template($template,$key,get_count($count,$cnt));
- }
- $template=~s/\{VER\}/\Q$versionnumber\E/gi;
- $template=__process_template($template,'WARN|WARNING|WARNINGS',number_of_distinct_warnings($count));
- $template=__process_template($template,'NWARN|NWARNING|NWARNINGS',number_of_warnings($count));
- $template=__process_template($template,'ERR|ERROR|ERRORS',$count->{'errorcount'});
- $template=__process_template($template,'SUM',get_sum_count($count));
- $template=__process_template($template,'TITLE',$count->{'title'}||'');
- $template=__process_template($template,'SUB',number_of_subcounts($count));
- $template=~s/\a//gis;
- return $template;
-}
-
-# Print counts using template
-sub __print_count_using_template {
- print count_in_template(@_);
-}
-
-# Print subcounts using template
-sub __print_subcounts_using_template {
- my ($count,$template)=@_;
- my $subcounts=$count->{'subcounts'};
- if ($template && defined $subcounts && scalar(@{$subcounts})>=$showsubcounts) {
- foreach my $subcount (@{$subcounts}) {
- __print_count_using_template($subcount,$template);
- }
- }
-}
-
-# Process template for specific label
-sub __process_template {
- my ($template,$label,$value)=@_;
- if ($value) {
- $template=~s/\{($label)\?(.*?)(\|(.*?))?\?(\1)\}/$2/gis;
- } else {
- $template=~s/\{($label)\?(.*?)\|(.*?)\?(\1)\}/$3/gis;
- $template=~s/\{($label)\?(.*?)\?(\1)\}//gis;
- }
- if (!defined $value) {$value='';}
- $template=~s/\{($label)\}/$value\a/gis;
- return $template;
-}
-
-
-
-###### Routines for printing parsing details
-
-
-# Print next token
-sub flush_next {
- my ($tex,$style)=@_;
- my $ret=undef;
- if (defined $style) {set_style($tex,$style);}
- if (defined $tex->{'next'}) {
- $ret=print_style($tex->{'next'},$tex->{'style'},$tex->{'printstate'});
- }
- $tex->{'printstate'}=undef;
- $tex->{'style'}=$STYLE_BLOCK;
- return $ret;
-}
-
-# Print next token and gobble following spaces (incl. line break and comments)
-sub flush_next_gobble_space {
- my ($tex,$style,$state)=@_;
- my $ret=flush_next($tex,$style);
- if (!defined $ret) {$ret=0;}
- if (!defined $state) {$state=$STATE_IGNORE;}
- my $prt=($printlevel>0);
- while (1) {
- if ($tex->{'line'}=~s/^([ \t\f]*)(\r\n|\r|\n)([ \t\f]*)//) {
- if (!$prt) {
- } elsif ($printlevel>1 || $ret) {
- print $1;
- line_return(-1,$tex);
- my $space=$3;
- if ($htmlstyle) {$space=~s/ /\&nbsp;/g;}
- print $space;
- $ret=0;
- } else {
- line_return(0,$tex);
- }
- } elsif ($tex->{'line'}=~s/^([ \t\f]+)//) {
- if ($prt) {print $1;}
- }
- if ($tex->{'line'}=~/^\%TC:/i) {return;}
- if ($tex->{'line'}=~s/^(\%+[^\r\n]*)//) {
- print_style($1,'comment');
- $ret=1;
- } else {return;}
- }
-}
-
-# Set presentation style
-sub set_style {
- my ($tex,$style)=@_;
- if (!(defined $tex->{'style'} && $tex->{'style'} eq $STYLE_BLOCK)) {$tex->{'style'}=$style;}
-}
-
-# Print text using the given style, and log state if given
-sub print_style {
- my ($text,$style,$state)=@_;
- (($printlevel>=0) && (defined $text) && (defined $style)) || return 0;
- my $colour;
- ($colour=$STYLE{$style}) || return;
- if (defined $colour && $colour ne '-') {
- print_with_style($text,$style,$colour);
- if (defined $state) {print_style($state,'state');}
- if ($style ne 'cumsum') {$blankline=-1;}
- return 1;
- } else {
- return 0;
- }
-}
-
-# Conditional line return
-sub line_return {
- my ($blank,$tex)=@_;
- if ($blank<0 && $printlevel<2) {$blank=1;}
- if ($blank<0 || $blank>$blankline) {
- if ((defined $tex) && @sumweights) {
- my $num=get_sum_count($tex->{'subcount'});
- print_style(" [$num]",'cumsum');
- }
- linebreak();
- $blankline++;
- }
-}
-
-
-###### Print help on style/colour codes
-
-
-# Print output style codes if conditions are met
-sub conditional_print_style_list {
- if ($showcodes) {_print_style_list();}
- return $showcodes;
-}
-
-# Print help on output styles
-sub _print_style_list {
- if ($printlevel<=0) {return;}
- if ($htmlstyle) {print '<div class="stylehelp"><p>';}
- formatprint('Format/colour codes of verbose output:','h2');
- print "\n\n";
- foreach my $style (@STYLE_LIST) {
- my $desc=$STYLE_DESC{$style};
- if ($desc=~/^(.*):\s+(.*)$/) {
- _help_style_line($1,$style,$2); # $1~${^PREMATCH}, $2~${^POSTMATCH}
- } else {
- _help_style_line($desc,$style);
- }
- }
- if ($htmlstyle) {print '</p></div>';}
- print "\n\n";
-}
-
-# Print one line of help
-sub _help_style_line {
- my ($text,$style,$comment)=@_;
- if (!defined $comment) {$comment='';}
- if ($htmlstyle) {$comment='&nbsp;&nbsp;....&nbsp;&nbsp;'.text_to_print($comment);}
- else {$comment=' .... '.$comment;}
- if (print_style($text,$style)) {
- print $comment;
- linebreak();
- }
-}
-
-
-###### Help routines
-
-
-# Print TeXcount version
-sub print_version {
- wprintstringdata('Version');
-}
-
-# Print TeXcount licence text
-sub print_license {
- wprintstringdata('License');
-}
-
-# Print short TeXcount help
-sub print_help {
- wprintstringdata('ShortHelp');
-}
-
-# Print main TeXcount help
-sub print_help_man {
- wprintstringdata('HelpTitle');
- wprintstringdata('HelpText');
- wprintstringdata('Reference');
-}
-
-# Print help on TC instructions
-sub print_help_tcinst {
- wprintstringdata('TCinstructions');
-}
-
-# Print TeXcount options list
-sub print_help_options {
- wprintstringdata('OptionsHead');
- wprintstringdata('Options',StringDatum('OptionsFormat'));
-}
-
-# Print TeXcount options containing substring
-sub print_help_options_subset {
- my $pattern=shift @_;
- my $data=StringData('Options');
- if (!defined $data) {
- error($Main,'No StringData Options.','BUG');
- return;
- }
- my @options;
- foreach (@$data) {
- if (/^\s*([^\s]+\s)*[^\s]*\Q$pattern\E/) {push @options,$_;}
- }
- if (scalar(@options)==0) {print "No options contained $pattern.\n";}
- else {
- print "Options containing \"$pattern\":\n\n";
- wprintlines(StringDatum('OptionsFormat'),@options);
- }
-}
-
-# Print help on specific macro or environment
-sub print_help_on_rule {
- my $arg=shift @_;
- my $def;
- my %rules=(
- '\documentclass' => 'Initiates LaTeX document preamble.',
- '\begin' => 'Treatmend depends on environment handling rules.',
- '\def' => 'Excluded from count.',
- '\verb' => 'Strong exclude for enclosed region.',
- '$' => 'Opens or closes inlined equation',
- '$$' => 'Opens or closes displayed equation.',
- '\(' => 'Opens inlined equation.',
- '\)' => 'Closes inlined equation initiated by \(.',
- '\[' => 'Opens displayed equation.',
- '\]' => 'Closes displayed equation initiated by \[.');
- if (!defined $arg || $arg=~/^\s*$/) {
- print "\nSpecify macro or environment name after the -h= option.\n";
- return;
- }
- if ($arg=~/^[\w\-\%]+:/) {
- remove_all_rules();
- %rules=();
- while ($arg=~s/^([\w\-\%]+)://) {include_package($1);}
- }
- if ($def=$rules{$arg}) {
- print "\nSpecial rule (hard coded) for $arg\n";
- print $def."\n";
- } elsif ($arg=~/^\\/) {
- my $hasrule=0;
- print "\nRule(s) for macro $arg\n";
- if ($def=$TeXmacrocount{$arg}) {
- $hasrule=1;
- }
- if ($def=$TeXfileinclude{$arg}) {
- $hasrule=1;
- print "Takes file name as parameter which is included in document.\n";
- }
- if ($def=$TeXmacro{$arg}) {
- $hasrule=1;
- _print_rule_macro($arg,$def);
- }
- if ($def=$TeXfloatinc{$arg}) {
- $hasrule=1;
- print "\nIncluded inside floats:\n";
- _print_rule_macro($arg,$def);
- }
- if (!$hasrule) {
- print "\nNo macro rule defined for $arg.\nParameters treated as surrounding text.\n";
- }
- } else {
- if ($def=$TeXenvir{$arg}) {
- print "\nRule for environment $arg\n";
- _print_rule_macrocount($PREFIX_ENVIR.$arg);
- _print_rule_envir($arg,$def);
- } else {
- print "\nNo default environment rule defined for $arg.\nContent handled as surrounding text.\n";
- }
- }
-}
-
-# Print macro handling rule
-sub _print_rule_macro {
- my ($arg,$def)=@_;
- if (!defined $def) {
- print "Takes no parameter(s).\n";
- } elsif (ref($def) eq 'ARRAY') {
- my $optionflag=0;
- print "Takes has the following parameters and parameter rules:\n";
- foreach my $state (@{$def}) {
- if ($state==$_STATE_OPTION) {$optionflag=1;}
- elsif ($state==$_STATE_NOOPTION) {print " - no [] options permitted here\n";}
- elsif ($state==$_STATE_AUTOOPTION) {}
- elsif ($optionflag) {
- $optionflag=0;
- print " + optional [] containing $state2desc{$state}\n";
- } else {
- print " + $state2desc{$state}\n";
- }
- }
- } else {
- print "Takes $def parameter(s): content ignored, i.e. not included in counts.\n";
- }
-}
-
-# Print environment handling rule
-sub _print_rule_envir {
- my ($arg,$def)=@_;
- print "Contents parsed as $state2desc{$def}\n";
- if ($def=$TeXmacro{$PREFIX_ENVIR.$arg}) {
- _print_rule_macro($arg,$def);
- } else {
- print "Takes no parameter(s).\n";
- }
-}
-
-# Print macrocount rule, return rule
-sub _print_rule_macrocount {
- my $arg=shift @_;
- my $def=$TeXmacrocount{$arg};
- if (!defined $def) {return undef;}
- if (ref($def) eq 'ARRAY') {
- my @wd=@$def;
- foreach (@wd) {$_=$countdesc[$_];}
- print 'Increments the following counters: ',join('; ',@wd),".\n";
- } else {
- print "Counted as $def word(s).\n";
- }
-}
-
-# Print style or style category summary
-sub print_help_on_styles {
- my $style=shift @_;
- if (defined $style) {
- if (my $def=$STYLES{$style}) {
- _print_help_on_style_category($style);
- print wrap('',' ',"$style = ".join(', ',grep(/^\w+$/,sort keys %$def))),".\n";
- } elsif ($def=$STYLE_DESC{$style}) {
- print $style,' = ',$def,"\n";
- } else {
- print "Unknown style or style category: $style.\n";
- }
- } else {
- print wrap('',' ','Styles: '.join(', ',@STYLE_LIST)),".\n\n";
- print wrap('',' ','Style categories: '.join(', ',sort grep(/^\w+$/,keys %STYLES))),".\n\n";
- print "Use -help-style={style} to get help on particular style or style category.\n";
- }
-}
-
-# Print help on a particular style category (optional prefix and indentation)
-sub _print_help_on_style_category {
- my ($cat,$prefix,$indent)=@_;
- if (!defined $prefix) {$prefix='';}
- if (!defined $indent) {$indent=' ';}
-}
-
-
-###### HTML routines
-
-
-# Print HTML header
-sub html_head {
- if (defined $HTMLfile) {
- if (open(FH,$HTMLfile)) {
- my $text=join('',<FH>);
- close FH;
- if ( $text=~/^(.*)<!--+\s*texcount\s*--+>(.*)$/is
- || $text=~/^(.*)\$\{texcount\}(.*)$/is
- || $text=~/^(.*)(<\/body.*)$/is
- ) {
- $htmlopen=$1;
- $htmlclose=$2;
- } else {
- error($Main,"Invalid HTML template format.");
- }
- } else {
- error($Main,"HTML template file not found: $HTMLfile");
- }
- }
- if (defined $htmlopen) {
- $htmlopen=~s/\$\{encoding\}/\Q$outputEncoding\E/g;
- $htmlopen=~s/\$\{version\}/@{[_html_version()]}/g;
- print $htmlopen;
- $htmlopen=undef;
- } else {
- print "<html>\n<head>\n";
- print "<meta http-equiv='content-type' content='text/html; charset=$outputEncoding'>\n";
- _print_html_style();
- foreach (@htmlhead) {print $_,"\n";}
- print "</head>\n\n<body>\n";
- print "\n<h1>LaTeX word count";
- if ($showVersion>0) {print ' (version ',_html_version(),')'}
- print "</h1>\n";
- }
-}
-
-# Print HTML tail
-sub html_tail {
- if (defined $htmlclose) {
- print $htmlclose;
- $htmlclose=undef;
- } else {
- print "</body>\n\n</html>\n";
- }
-}
-
-# Return version number using HTML
-sub _html_version {
- my $htmlver=$versionnumber;
- $htmlver=~s/\b(alpha|beta)\b/&$1;/g;
- return $htmlver;
-}
-
-# Print HTML STYLE element
-sub _print_html_style {
-if (defined $CSShref) {
- print "<link rel='stylesheet' href='$CSShref' type='text/css'>\n";
- return;
-}
-if (defined $CSSfile) {
- if (open(FH,$CSSfile)) {
- print "<style>\n<!---\n",<FH>,"-->\n</style>\n";
- close(FH);
- return;
- } else {
- error($Main,"CSS file not found: $CSSfile");
- }
-}
-print <<END
-<style>
-<!--
-body {width:auto;padding:5;margin:5;}
-.error {font-weight:bold;color:#f00;font-style:italic; border: solid 1px red;}
-.word,.hword,.oword,.altwd {border-left: 1px solid #CDF; border-bottom: 1px solid #CDF;}
-.word {color: #009}
-.hword {color: #009; font-weight: 700;}
-.oword {color: #009; font-style: italic;}
-.altwd {color: #00c; font-style: oblique;}
-.cmd {color: #c00;}
-.exclcmd {color: #f99;}
-.option {color: #cc0;}
-.optparm {color: #c90;}
-.envir, .document {color: #900; font-weight:bold;}
-.math {color: #6c0;}
-.mathgroup {color: #090;}
-.exclmath {color: #9f6;}
-.mathcmd {color: #6c0;}
-.ignore {color: #999;}
-.exclenv {color:#c66;}
-.special {color:#c66; font-weight: bold;}
-.specarg {color:#c66; font-weight: bold; font-style: italic;}
-.tc {color: #999; font-weight:bold;}
-.comment {color: #999; font-style: italic;}
-.state {color: #990; font-size: 70%;}
-.cumsum {color: #999; font-size: 80%;}
-.fileinc {color: #696; font-weight:bold;}
-.warning {color: #c00; font-weight: 700;}
-.note {color: #c90; font-weight: bold;}
-
-div.filegroup, div.parse, div.stylehelp, div.count, div.sumcount, div.error {
- border: solid 1px #999; margin: 4pt 0pt; padding: 4pt;
-}
-div.stylehelp {font-size: 80%; background: #fffff0; margin-bottom: 16pt;}
-div.filegroup {background: #dfd; margin-bottom: 16pt;}
-div.count {background: #ffe;}
-div.sumcount {background: #cec;}
-div.error {background: #fcc;}
-.parse {font-size: 80%; background: #f8fff8; border-bottom:none;}
-
-ul.count {list-style-type: none; margin: 4pt 0pt; padding: 0pt;}
-.count li.header {font-weight: bold; font-style: italic;}
-.subcount li.header {font-weight: normal; font-style: italic;}
-.subcount li {margin-left: 16pt; font-size: 80%;}
-.fielddesc {font-style: italic;}
-.nb {color: #900;}
-
-table.stat {border:2px solid #339; margin:0 0 8pt 0; background:#666; border-collapse:collapse;}
-table.stat tr {border:1px solid #CCC;}
-table.stat th, table.stat td {padding:1pt 4pt;}
-table.stat col {padding:4pt;}
-table.stat thead {background: #CCF;}
-table.stat tbody {border:1px solid #333;}
-table.stat tbody.sumstat {background:#FFC;}
-table.stat tbody.langstat {background:#FEE;}
-table.stat tbody.wordstat {background:#EEF;}
-table.stat tbody.macrostat {background:#EFE;}
-table.stat .sum {font-weight:bold; font-style:italic;}
--->
-</style>
-END
-}
-
-
-###### Read text data
-
-
-
-# Return the STRINGDATA hash (lazy instantiation)
-sub STRINGDATA {
- if (!defined $STRINGDATA) {
- my @DATA=<DATA>;
- foreach (@DATA) {
- $_=~s/\$\{(\w+)\}/__apply_globaldata($1)/ge;
- }
- $STRINGDATA=splitlines(':{3,}\s*(\w+)?',\@DATA);
- }
- return $STRINGDATA;
-}
-
-# Return value from STRINGDATA hash
-sub StringData {
- my $name=shift @_;
- return STRINGDATA()->{$name};
-}
-
-# First line of StringData
-sub StringDatum {
- return pop @{StringData(@_)};
-}
-
-# Insert value from GLOBALDATA
-sub __apply_globaldata {
- my $name=shift @_;
- if (my $value=$GLOBALDATA{$name}) {
- return $value;
- }
- return '[['.$name.']]';
-}
-
-# Print value from STRINGDATA using wprintlines
-sub wprintstringdata {
- my $name=shift @_;
- my $data=StringData($name);
- if (!defined $data) {
- error($Main,"No StringData $name.",'BUG');
- return;
- }
- wprintlines(@_,@$data);
-}
-
-# Divide array of lines by identifying headers
-sub splitlines {
- my ($pattern,$lines)=@_;
- if (!defined $lines) {return;}
- my $id=undef;
- my %hash;
- foreach my $line (@$lines) {
- if ($line=~/^$pattern$/) {
- $id=$1;
- if (defined $id) {
- $hash{$id}=[];
- if (defined $2) {push @{$hash{$id}},$2;}
- }
- } elsif (defined $id) {
- chomp $line;
- push @{$hash{$id}},$line;
- }
- }
- return \%hash;
-}
-
-# Print string with word wrapping and indentation using
-# wprintlines.
-sub wprint {
- my $text=shift @_;
- my @lines=split(/\n/,$text);
- wprintlines(@lines);
-}
-
-# Print with word wrapping and indentation. A line with
-# @ - :
-# sets two column tabs. A tab or multiple spaces is taken
-# to indicate indentation. If the first column value is
-# only a single '|', this is just an indication to skip
-# one tab.
-sub wprintlines {
- my @lines=@_;
- my $ind1=2;
- my $ind2=6;
- my $i;
- foreach my $line (@lines) {
- if ($line=~s/^@/ /) {
- $ind1=index($line,'-');
- $ind2=index($line,':');
- if ($ind1<1) {$ind1=$ind2;}
- next;
- }
- my $firstindent=0;
- if ($line=~s/^(\t|\s{2,})(\S)/$2/) {$firstindent=$ind1;}
- my $indent=$firstindent;
- if ($line=~/^(.*?\S)(\t|\s{2,})(.*)$/) {
- $indent=$ind2;
- if ($1 eq '|') {$line=' ';}
- else {$line=$1.' ';}
- $i=$indent-$firstindent-length($line);
- if ($i>0) {$line.=' ' x $i;}
- $line.=$3; # $3~${^POSTMATCH}
- }
- print wrap(' ' x $firstindent,' ' x $indent,$line)."\n";
- }
-}
-
-
-########################################
-##### TEXT DATA
-
-__DATA__
-
-
-::::::::::::::::::::::::::::::::::::::::
-:::::::::: Version
-TeXcount version ${versionnumber}, ${versiondate}.
-
-:::::::::: Reference
-Go to the TeXcount web page
- ${website}
-for more help and information about the script: news, updates, help, usage tips, known issues and short-comings, or to access the script as a web application. Feedback such as problems or errors can be reported to einarro@ifi.uio.no.
-
-The TeXcount script is copyright of ${maintainer} (${copyrightyears}) and published under the LaTeX Project Public Licence.
-
-:::::::::: License
-TeXcount version ${versionnumber}
-
-Copyright ${copyrightyears} ${maintainer}
-
-The TeXcount script is published under the LaTeX Project Public License (LPPL)
- http://www.latex-project.org/lppl.txt
-which grants you, the user, the right to use, modify and distribute the script. However, if the script is modified, you must change its name or use other technical means to avoid confusion.
-
-The script has LPPL status "maintained" with ${maintainer} being the current maintainer.
-
-::::::::::::::::::::::::::::::::::::::::
-:::::::::: ShortHelp
-Syntax: texcount.pl [options] files
-
-Use option -help (or just -h) to get help. For more detailed help, the following alternatives exist:
-@ - :
- -help-man, -man Manual with more extensive help
- -help-rule={macro/envir} Macro/environment handling rule (backslash needed with macros)
- -help-options (-hopt) Get list of command line options
- -help-options={substring} Help on options containing substring
- -help-styles List styles which determine how different elements (words, macros, etc) are presented in the verbose output
- -help-style={style} Describe a particular style or style category
- -help-tc, -help-instructions Help on %TC:instruction for inserting TeXcount instructions into the TeX code.
-
-Help, documentation, FAQ and updates are available from the TeXcount web page:
- ${website}
-or through running
- texdoc texcount
-on the command line.
-
-::::::::::::::::::::::::::::::::::::::::
-:::::::::: HelpTitle
-***************************************************************
-* TeXcount version ${versionnumber}, ${versiondate}
-*
-
-Count words in TeX and LaTeX files, ignoring macros, tables, formulae, etc.
-
-::::::::::::::::::::::::::::::::::::::::
-:::::::::: HelpText
-The script counts words as either words in the text, words in headers/titles or words in floats (figure/table captions). Macro options (i.e. \\macro[...]) are ignored; macro parameters (i.e. \\macro{...}) are counted or ignored depending on the macro, but by default counted. Begin-end groups are by default ignored and treated as 'floats', though some (e.g. center) are counted.
-
-Mathematical formulae are not counted as words, but are instead counted separately with separate counts for inlined formulae and displayed formulae. Similarly, the number of headers and the number of 'floats' are counted. Note that 'float' is used here to describe anything defined in a begin-end group unless explicitly recognized as text or mathematics.
-
-The verbose options (-v1, -v2, -v3, showstate) produces output indicating how the text has been interpreted. Check this to ensure that words in the text has been interpreted as such, whereas mathematical formulae and text/non-text in begin-end groups have been correctly interpreted.
-
-Summary, as well as the verbose output, may be produced as text (default) or as HTML code using the -html option. The HTML may then be sent to file which may be viewed with you favourite browser.
-
-Under UNIX, unless -nocol (or -nc) has been specified, the output will be colour coded using ANSI colour codes. Counted text is coloured blue with headers are in bold and in HTML output caption text is italicised. Use 'less -r' instead of just 'less' to view output: the '-r' option makes less treat text formating codes properly. Windows does not support ANSI colour codes, and so this is turned off by default.
-
-::::::::::::::::::::::::::::::::::::::::
-:::::::::: OptionsHead
-
-Syntax: texcount.pl [options] files
-
-Options:
-
-:::::::::: OptionsFormat
-@ - :
-:::::::::: Options
- -relaxed Uses relaxed rules for word and option handling: i.e. allows more general cases to be counted as either words or macros.
- -restricted Restricts the rules for word and option handling.
- -v Verbose (same as -v3).
- -v0 Do not present parsing details.
- -v1 Verbose: print parsed words, mark formulae.
- -v2 More verbose: also print ignored text.
- -v3 Even more verbose: include comments and options.
- -v4 Same as -v3 -showstate.
- -v=, v0=, ..., -v4= Set verbosity by adding/removing particular types of token (styles) to include in the verbose output. Use -help-style to get details of which tokens are included in each style, and of classes of tokens (style categories).
- -showstate Show internal states (with verbose).
- -brief Only prints a brief, one line summary of counts.
- -q, -quiet Quiet mode, no error messages. Use is discouraged!
- -strict Strict mode, warns against begin-end groups for which rule are not defined.
- -sum, -sum= Make sum of all word and equation counts. May also use -sum=#[,#] with up to 7 numbers to indicate how each of the counts (text words, header words, caption words, #headers, #floats, #inlined formulae, #displayed formulae) are summed. The default sum (if only -sum is used) is the same as -sum=1,1,1,0,0,1,1.
- -nosum Do not compute sum.
- -sub, -sub= Generate subcounts. Option values are none, part, chapter, section or subsection. Default (-sub) is set to subsection, whereas unset is none. (Alternative option name is -subcount.)
- -nosub Do not generate subcounts.
- -col Use ANSI colours in text output.
- -nc, -nocol No colours (colours require ANSI).
- -nosep, -noseparator No separating character/string added after each word (default).
- -sep=, -separator= Separating character or string to be added after each word.
- -html Output in HTML format.
- -htmlcore Only HTML body contents.
- -htmlfile= HTML template file to use with the -html option. Use <!-- TeXcode --> to indicate where the output from TeXcount should be inserted.
- -tex Encode TeX special characters for output into TeX code
- -cssfile= CSS file to include instead of default styles.
- -css= CSS href to include instead of default styles. Can use -css=file:{filename} instead of -cssfile={filename}.
- -opt=, -optionfile= Read options/parameters from file.
- - Read LaTeX code from STDIN.
- -inc Parse included TeX files (as separate file).
- -merge Merge included TeX files into code (in place).
- -noinc Do not include included tex files (default).
- -incbib Include bibliography in count, include bbl file if needed.
- -nobib Do not include bibliography in count (default).
- -incpackage= Include rules for the given package.
- -total Do not give sums per file, only total sum.
- -1 Same as -brief and -total. Ensures there is only one line of output. If used in conjunction with -sum, the output will only be the total number. (NB: Character is the number one, not the letter L.)
- -template= Speficy an output template. Use {1},...,{7}, {SUM} and {TITLE} to include values, {1?...?1} etc. to conditionally include sections, {1?....|...?1} etc. to specify an alternative text if zero. To include subcounts, use {SUB?...?SUB} where ... is replaced with the template to use per subcount. Line shift may be specified using \\n.
- -dir, -dir= Specify the working directory using -dir=path. Remember that the path must end with \\ or /. If only -dir is used, the directory of the provided file is used and paths (e.g. included files) are assumed to be absolute or relative to this. The default at startup is -dir=. which means that the directory from which TeXcount is run is the working directory with all paths absolute or relative to this.
- -auxdir, -auxdir= Specify directory for auxilary files, e.g. the bibliograph (.bbl) file. If only -auxdir is used, the working directory (as determined by -dir or -dir=) is assumed. If -auxdir= is used with -dir=, it sets the path to the auxilary directiry. If -auxdir= is used with -dir, the working directory is determined from the location of the provided file, and the path to the auxilary directory is assumed to be absolute or relative to this.
- -enc=, -encoding= Specify encoding (default is to guess the encoding).
- -utf8, -unicode Selects Unicode (UTF-8) for input and output. This is automatic with -chinese, and is required to handle e.g. Korean text. Note that the TeX file must be save in UTF-8 format (not e.g. GB2312 or Big5), or the result will be unpredictable.
- -alpha=, -alphabets= List of Unicode character groups (or digit, alphabetic) permitted as letters. Names are separated by ',' or '+'. If list starts with '+', the alphabets will be added to those already included. The default is Digit+alphabetic.
- -logo=, -logograms= List of Unicode character groups interpreted as whole word characters, e.g. Han for Chinese characters. Names are separated by ',' or '+'. If list starts with '+', the alphabets will be added to those already included. By default, this is set to include Ideographic, Katakana, Hiragana, Thai and Lao.
- -ch, -chinese, -zhongwen Turns on support for Chinese characters. TeXcount will then count each Chinese character as a word.
- -jp, -japanese Turns on support for Japanese characters. TeXcount will count each Japanese character (kanji, hiragana, and katakana) as one word, i.e. not do any form of word segmentation.
- -kr, -korean Turns on support for Korean. This will count hangul and han characters, i.e. with no word separation. NB: Experimental!
- -kr-words, -korean-words Turns on support for Korean words, i.e. hangul words separated by characters. Han characters are still counted as characters. NB: Experimental!
- -ch-only, ..., -korean-words-only As options -chinese, ..., -korean-words, but also excludes letter-based words or trims down the character set to the minimum.
- -char, -character, -letters Counts letters/characters instead of words. Note that spaces and punctuation is not counted.
- -char-only, ..., -letters-only Like -letters, but counts alphabetic letters only.
- -countall, -count-all The default setting in which all characters are included as either alphabets og logograms.
- -freq, -freq= Produce individual word frequency table. Optionally give minimal number of occurences to be listed.
- -stat Produce statistics on language/script usage.
- -macrostat, -macrofreq Print macro usage statistics.
- -codes Display output style code overview and explanation. This is on by default.
- -nocodes Do not display output style code overview.
- -out= Write output to file, give filename as option value.
- -out-stderr Write output to STDERR instead of STDOUT.
- -h, -?, -help, /? Help text.
- -help-man, -man Short manual.
- -h=, -help-rule= Takes a macro or group name as option and returns a description of the rules for handling this if any are defined. If handling rule is package specific, use -incpackage=package name: -incpackage must come before -h= on the command line to take effect.
- -help-options, -h-opt List all options.
- -help-options=, -h-opt= List all options containing the provided string, e.g. -h-opt=dir or -h-opt=-v (the initial - in -v causes only options starting with v to be listed).
- -help-tc, -help-inst List all TeXcount instructions insertable as %TC comments in the TeX document.
- -help-style List the styles and style categories: i.e. those permitted used with -v={styles-list}.
- -help-style= Give description of style or style category.
- -ver, -version Print version number.
- -lic, -license, -licence Licence information.
-
-::::::::::::::::::::::::::::::::::::::::
-:::::::::: TCinstructions
-Parsing instructions may be passed to TeXcount using comments in the LaTeX files on the format
-@ - :
- %TC:instruction arguments
-and are used to control how TeXcount parses the document. The following instructions are used to set parsing rules which will apply to all subsequent parsing (including other files):
- %TC:macro [macro] [param.states]
- | macro handling rule, no. of and rules for parameters
- %TC:macrocount [macro] [number]
- | macro counted as a given number of words (alternative: %TC:macroword)
- %TC:header [macro] [param.states]
- | header macro rule, as macro but counts as one header (deprecated, use instead: %TC:macro \macro [header])
- %TC:breakmacro [macro] [label]
- | macro causing subcount break point
- %TC:envir [name] [param.states] [content-state]
- | \begin-\end environment handling rule (alternative: %TC:group)
- %TC:floatinclude [macro] [param.states]
- | as macro, but also counted inside floats
- %TC:preambleinclude [macro] [param.states]
- | as macro, but also counted inside the preamble
- %TC:fileinclue [macro] [rule]
- | file include, add .tex if rule=2, not if rule=0, if missing when rule=1
-The [param.states] is used to indicate the number of parameters used by the macro and the rules of handling each of these: the format is [#,#,...,#] with # representing one number for each parameter giving the parsing state to use for that parameter, alternatively just a single number (#) indicating how many parameters to ignore (parsing state 0). The option [content-state] is used to give the parsing state to use for the contents of a begin-end group. The main parsing states are 0 to ignore and 1 to count as text.
-
-Parsing instructions which may be used anywhere are:
-@ - :
- %TC:break [title] add subcount break point here
- %TC:incbib include bibliography (same as running with -incbib)
- %TC:ignore ignore region, end with %TC:endignore
- %TC:insert [code] insert code for TeXcount to process as TeX code
- %TC:subst [from] [to] replace string thoughout document
- %TC:newtemplate start a new template, ie delete the existing one
- %TC:template [template] add another line to the template specification
-See the documentation for more details.
-
-Command line options and most %TC commands (prefixed by % rather than %TC:) may be placed in an options file. This is particularly useful for defining your own output templates and macro handling rules.
-
-::::::::::::::::::::::::::::::::::::::::
-
-
diff --git a/Build/source/texk/texlive/linked_scripts/texdef/texdef.pl b/Build/source/texk/texlive/linked_scripts/texdef/texdef.pl
deleted file mode 100755
index ac84c1f29cb..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texdef/texdef.pl
+++ /dev/null
@@ -1,950 +0,0 @@
-#!/usr/bin/env perl
-################################################################################
-# texdef -- Show definitions of TeX commands
-# Copyright (c) 2011-2020 Martin Scharrer <martin@scharrer-online.de>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-################################################################################
-use strict;
-use warnings;
-use File::Temp qw/tempdir/;
-use File::Basename;
-use Cwd;
-
-my ($scriptname) = fileparse($0, qw(\.pl \.perl));
-
-my $TEX = 'pdflatex';
-if ($scriptname =~ /^(.*)def$/) {
- $TEX = $1;
-}
-my $TEXOPTIONS = " -interaction nonstopmode ";
-my $USERTEXOPTIONS = "";
-
-## Variables for options and settings
-my $CLASS = undef;
-my $USERCLASS = 0;
-my @PACKAGES = ();
-my @OTHERDEFS = ();
-my $INPREAMBLE = 0;
-my $PRINTVERSION = 0;
-my $TMPDIR = '';
-my $SHOWVALUE = 0;
-my $ISENVIRONMENT = 0;
-my $PRINTORIGDEF = 0;
-my $FINDDEF = 0;
-my $LISTCMD = 0;
-my $LISTCMDDEF = 0;
-my $BEFORECLASS = 0;
-my $PGFKEYS = 0;
-my $PGFKEYSPLAIN = 0;
-my $FAKECMD = "\0FAKECOMMAND\0";
-my $EDIT = 0;
-my $EDITOR;
-my $EDITORCMDLN;
-my @ENVCODE = ();
-my %DEFS;
-my $LISTSTR = '@TEXDEF@LISTDEFS@'; # used as a dummy command to list definitions
-my @FILES; # List of files (sty, cls, ...)
-my @FILEORDER; # Order of files
-my %ALIAS; # list of aliases; required for registers
-my $currfile = ''; # current file name
-# Operating system:
-my $OS = $^O;
-my $WINDOWS = ($OS =~ /MSWin/);
-
-my @IGNOREDEFREG = (# List of definitions to be ignored. Can be a regex or string
- qr/^ver\@.*\.(?:sty|cls)$/,
- qr/^opt\@.*\.(?:sty|cls)$/,
- qr/^reserved\@[a-z]$/,
- qr/-h\@\@k$/,
- qr/^catcode\d+$/,
- qr/^l\@ngrel\@x$/,
- qr/^\@temp/,
- qr/^KV\@/,
- qr/^KVO\@/,
- qr/^KVOdyn\@/,
- qr/^KVS\@/,
- qr/^currfile/,
- qr/^filehook\@atbegin\@/,
- qr/^filehook\@atend\@/,
- qr/^count\d+$/,
- qr/^pgfk@\//
-);
-my %IGNOREDEF = map { $_ => 1 } qw(
- usepackage RequirePackage documentclass LoadClass @classoptionslist
- CurrentOption tracingassigns in@@ escapechar
- @unprocessedoptions @let@token @gtempa @filelist @filef@und
- @declaredoptions @currnamestack @currname @currext
- @ifdefinable default@ds ds@ @curroptions
- filename@area filename@base filename@ext
-);
-
-## Adds arguments to %IGNOREDEF
-sub addignore {
- my $opt = shift;
- my $arg = shift;
- my @args = split (/,/, $arg);
- if ($opt eq 'ignore-cmds') {
- @IGNOREDEF{@args} = (1) x scalar @args;
- }
- else {
- push @IGNOREDEFREG, map { qr/$_/ } @args;
- }
-}
-
-use Getopt::Long;
-my $data = "file.dat";
-my $length = 24;
-my $verbose;
-
-my $ISLATEX = 0;
-my $ISTEX = 0;
-my $ISCONTEXT = 0;
-
-my $BEGINENVSTR = '%s';
-my $ENDENVSTR = '%s';
-
-my $VERSION = 'Version 1.9 -- 2020/09/27';
-sub usage {
- my $option = shift;
- my $ret = ($option) ? 0 : 1;
-print << 'EOT';
-texdef -- Show definitions of TeX commands
-Version 1.9 -- 2020/09/27
-Copyright (C) 2011-2020 Martin Scharrer <martin@scharrer-online.de>
-This program comes with ABSOLUTELY NO WARRANTY;
-This is free software, and you are welcome to redistribute it under certain conditions;
-
-Usage:
- texdef [options] commandname [commandname ...]
- latexdef [options] commandname [commandname ...]
-
-Other program names are possible. See the 'tex' option. Command names do not need to start with `\`.
-
-Options:
- --tex <format>, -t <format> : Use given format of TeX: 'tex', 'latex', 'context'.
- Variations of 'tex' and 'latex', like 'luatex', 'lualatex', 'xetex', 'xelatex' are supported.
- The postfix '-dev' for develop versions of the format is also supported (e.g. 'latex-dev').
- The default is given by the used program name: 'texdef' -> 'tex', 'latexdef' -> 'latex', etc.
- --texoptions <options> : Call (La)TeX with the given options.
- --source, -s : Try to show the original source code of the command definition (L).
- --value, -v : Show value of command instead (i.e. \the\command).
- --Environment, -E : Every command name is taken as an environment name. This will show the definition of
- both \Macro\foo and \Macro\endfoo if \texttt{foo} is used as command name (L).
- --preamble, -P : Show definition of the command inside the preamble.
- --beforeclass, -B : Show definition of the command before \documentclass.
- --package <pkg>, -p <pkg> : (M) Load given tex-file, package or module depending on whether '*tex', '*latex'
- or 'context' is used. For LaTeX the <pkg> can start with `[<options>]` and end
- with `<pkgname>` or `{<pkgname>}`.
- --class <class>, -c <class> : (LaTeX only) Load given class instead of default ('article').
- The <class> can start with `[<class options>]` and end
- with `<classname>` or `{<classname>}`.
- --environment <env>, -e <env> : (M) Show definition inside the given environment <env>.
- --othercode <code>, -o <code> : (M) Add other code into the preamble before the definition is shown.
- This can be used to e.g. load PGF/TikZ libraries.
- --before <code>, -b <code> : (M) Place <code> before definition is shown.
- The <code> can be arbitray TeX code and doesn't need be be balanced.
- --after <code>, -a <code> : (M) Place <code> after definition is shown.
- The <code> can be arbitray TeX code and doesn't need be be balanced.
- --find, -f : Find file where the command sequence was defined (L).
- --Find, -F : Show full filepath of the file where the command sequence was defined (L).
- --list, -l : List user level command sequences of the given packages (L).
- --list-defs, -L : List user level command sequences and their shorten definitions of the given packages (L).
- --list-all, -ll : List all command sequences of the given packages (L).
- --list-defs-all, -LL : List all command sequences and their shorten definitions of the given packages (L).
- --ignore-cmds <cs,cs,..>, -i : Ignore the following command sequence(s) in the above lists. (M)
- --ignore-regex <regex,..>, -I : Ignore all command sequences in the above lists which match the given Perl regular expression(s). (M)
- --pgf-keys, -k : Takes commands as pgfkeys and displays their definitions. Keys must use the full path but the common '.\@cmd' prefix is applied.
- --pgf-Keys, -K : Takes commands as pgfkeys and displays their definitions. Keys must use the full path.
- --version, -V : If used alone prints version of this script.
- (L) Together with -p or -c prints version of LaTeX package(s) or class, respectively.
- --edit : Opens the file holding the macro definition. Uses --Find and --source. (L)
- If the source definition can not be found the definition is printed as normal instead.
- --editor <editor> : Can be used to set the used editor. If not used the environment variables TEXDEF_EDITOR, EDITOR and
- SELECTED_EDITOR are read in this order. If none of these are set a list of default
- editors are tried. The <editor> string can include '%f' for the filename, '%n' for
- the line number and '%%' for a literal '%'. If no '%' is used '+%n %f' is added to
- the given command.
- --tempdir <directory> : Use given existing directory for temporary files.
- --help, -h : Print this help and quit.
-
- Long option can be shorten as long the are still unique. Short options can be combined.
- If the option 'environment', 'before' and 'after' are used toegether the
- produced code will be inserted in the given order (reversed order for 'after').
- (M) = This option can be given multiple times.
- (L) = LaTeX only. Requires the packages 'filehook' and 'currfile'.
-
-Examples:
-Show the definition of '\chapter' with different classes ('article' (default), 'book' and 'scrbook'):
-
- latexdef chapter
- latexdef -c book chapter
- latexdef -c scrbook chapter
-
-Show value of `\textwidth` with different class options:
-
- latexdef -c [a4paper]{book} -v paperwidth
- latexdef -c [letter]{book} -v paperwidth
-
-Show definition of TikZ's '\draw' outside and inside a 'tikzpicture' environment:
-
- latexdef -p tikz draw
- latexdef -p tikz --env tikzpicture draw
-
-Show definition of TikZ's '\draw' inside a node, inside a 'beamer' frame in 'handout' mode:
-
- latexdef -c [handout]beamer -p tikz --env frame --env tikzpicture -b '\node {' -a '};' draw
-
-List all user level command sequences (macros) defined by the 'xspace' LaTeX package:
-
- latexdef -l -p xspace
-
-EOT
- exit ($ret);
-}
-
-sub envcode {
- my $opt = shift;
- my $arg = shift;
- push @ENVCODE, [ $opt, $arg ];
-}
-
-## Define and process options
-Getopt::Long::Configure ("bundling");
-GetOptions (
- 'value|v!' => \$SHOWVALUE,
- 'Environment|E!' => \$ISENVIRONMENT,
- 'version|V!' => \$PRINTVERSION,
- 'tempdir=s' => \$TMPDIR,
- 'find|f!' => sub { $FINDDEF = 1 },
- 'Find|F!' => sub { $FINDDEF = 2 },
- 'source|s!' => \$PRINTORIGDEF,
- 'list|l' => sub { $LISTCMD++ },
- 'list-def|L' => sub { $LISTCMDDEF++ },
- 'list-all' => sub { $LISTCMD=2 },
- 'list-def-all' => sub { $LISTCMDDEF=2 },
- 'ignore-cmds|i=s' => \&addignore,
- 'ignore-regex|I=s' => \&addignore,
- 'no-list|no-l' => sub { $LISTCMD=0; $LISTCMDDEF=0; },
- 'no-list-def|no-L' => sub { $LISTCMDDEF=0 },
- 'no-list-all|no-ll' => sub { $LISTCMD=0; $LISTCMDDEF=0; },
- 'no-list-def-all|no-LL' => sub { $LISTCMDDEF=0 },
- 'preamble|P!' => \$INPREAMBLE,
- 'beforeclass|B!' => \$BEFORECLASS,
- 'class|c=s' => \$CLASS,
- 'package|p=s' => \@PACKAGES,
- 'otherdefs|o=s' => \@OTHERDEFS,
- 'environment|e=s' => \&envcode,
- 'before|b=s' => \&envcode,
- 'after|a=s' => \&envcode,
- 'tex|t=s' => \$TEX,
- 'texoptions=s' => \$USERTEXOPTIONS,
- 'help|h' => \&usage,
- 'pgf-keys|k' => \$PGFKEYS,
- 'pgf-Keys|K' => \$PGFKEYSPLAIN,
- 'edit!' => sub { $EDIT=1; $FINDDEF = 2; $PRINTORIGDEF = 1; },
- 'editor=s' => \$EDITOR,
-) || usage();
-
-# usage() unless @ARGV;
-
-if ($EDIT && !$EDITOR) {
- $EDITOR = $ENV{'TEXDEF_EDITOR'} || $ENV{'EDITOR'} || $ENV{'SELECTED_EDITOR'};
- if (!$EDITOR) {
- if (!$WINDOWS && exists $ENV{HOME}) {
- # Check ~/.selected_editor file (Ubuntu)
- my $fn = "$ENV{HOME}/.selected_editor";
- if (-r $fn) {
- open (my $fh, '<', $fn);
- while (<$fh>) {
- s/#.*//;
- if (/^\s*SELECTED_EDITOR=(["']?)(.*)\1/) {
- $EDITOR=$2;
- }
- }
- close ($fh);
- }
- }
- }
- if (!$EDITOR) {
- warn "No editor set. Using default!\n";
- if ($WINDOWS) {
- $EDITOR = 'texworks "%f"';
- }
- else {
- for my $ed (qw(/usr/bin/vim /usr/bin/emacs /usr/bin/nano)) {
- if (-x $ed) {
- $EDITOR = $ed;
- last;
- }
- }
- if (!$EDITOR) {
- for my $ed (qw(/usr/bin/editor /usr/bin/open /bin/open)) {
- if (-x $ed) {
- $EDITOR = "$ed \"%f\"";
- last;
- }
- }
- }
- }
- }
- if (!$EDITOR) {
- warn "No suitable editor found. Disable editing!\n";
- $EDIT = 0;
- }
-}
-
-## Format specific settings
-if ($TEX =~ /latex(?:-dev)?$/) {
- $ISLATEX = 1;
- $BEGINENVSTR = '\begin{%s}' . "\n";
- $ENDENVSTR = '\end{%s}' . "\n";
-}
-elsif ($TEX =~ /tex(?:-dev)?$/) {
- $ISTEX = 1;
- $BEGINENVSTR = '\%s' . "\n";
- $ENDENVSTR = '\end%s' . "\n";
-}
-elsif ($TEX =~ /context(?:-dev)?$/) {
- $ISCONTEXT = 1;
- $BEGINENVSTR = '\start%s' . "\n";
- $ENDENVSTR = '\stop%s' . "\n";
-}
-
-if ($TEX =~ /^dvi((la)?tex)(?:-dev)?$/) {
- $TEX = $1;
- $TEXOPTIONS .= ' -output-format=dvi '
-}
-
-$USERCLASS = $CLASS;
-$CLASS = 'article' if not $CLASS;
-$CLASS =~ /^(?:\[(.*)\])?\{?(.*?)\}?$/;
-$CLASS = $2;
-my $CLASSOPTIONS = $1 || '';
-
-if ($FINDDEF == 1 && !$ISLATEX) { die "Error: The --find / -f option is only implemented for LaTeX!\n"; }
-if ($FINDDEF == 2 && !$ISLATEX) { die "Error: The --Find / -F option is only implemented for LaTeX!\n"; }
-
-my @cmds = @ARGV;
-$LISTCMD = $LISTCMDDEF if $LISTCMDDEF;
-if ($LISTCMD && !$ISLATEX) { die "Error: Listing for commands is only implemented for LaTeX!\n"; }
-if ($LISTCMD) {
- @cmds = ($LISTSTR);
-}
-
-if ($PRINTVERSION) {
- if (!@PACKAGES && !$USERCLASS) {
- print STDERR "texdef: $VERSION\n";
- exit (0) if not @cmds;
- }
- elsif (!@cmds) {
- @cmds = ($FAKECMD);
- }
-}
-
-sub print_versions {
- my @files = map { $_.'.sty' } @PACKAGES;
- unshift @files, "$USERCLASS.cls" if $USERCLASS;
-
- foreach my $file (@files) {
- print "\\message{^^J:TEXDEF: $file: \\csname ver\@$file\\endcsname^^J}%\n";
- }
- $PRINTVERSION = 0;# only print it once
-}
-
-usage() if not @cmds;
-
-my $cwd = getcwd();
-my $DIRSEP;
-if ($WINDOWS) {
- $DIRSEP = ';';
-} else {
- $DIRSEP = ':';
-}
-$ENV{TEXINPUTS} = '.' . $DIRSEP . $cwd . $DIRSEP . ($ENV{TEXINPUTS} || '');
-
-if (!$TMPDIR) {
- $TMPDIR = tempdir( 'texdef_XXXXXX', CLEANUP => 1, TMPDIR => 1 );
-}
-chdir $TMPDIR or die "Couldn't change into temporary directory '$TMPDIR'\n";
-my $TMPFILE = 'texdeftmp.tex';
-
-sub testdef {
- my $cmd = shift;
- my $def = shift;
- if ($def eq 'macro:->\@latex@error {Can be used only in preamble}\@eha ' && $cmd ne '\@notprerr') {
- unshift @cmds, '^' . $cmd;
- }
- elsif ($def =~ /^(?:\\[a-z]+ )?macro:.*?>(.*)/) {
- my $macrodef = $1;
- if ($macrodef =~ /^\\protect (.*?) ?$/) {
- my $protectedmacro = $1;
- unshift @cmds, $protectedmacro;
- }
- elsif ($macrodef =~ /^\\x\@protect (.*?) ?\\protect (.*?) ?$/) {
- my $protectedmacro = $2;
- unshift @cmds, $protectedmacro;
- }
- elsif ($macrodef =~ /^\\\@protected\@testopt \{?\\.*? \}? *(\\\\.*?) /) {
- unshift @cmds, $1;
- }
- elsif ($macrodef =~ /^\\\@testopt \{?(\\.*?) \}?/) {
- unshift @cmds, $1;
- }
- }
- elsif ($def =~ /^\\(char|mathchar)|(dimen|skip|muskip|count)\d/) {
- unshift @cmds, '#' . $cmd;
- }
-}
-
-my $bschar = 0;
-my $pcchar = 0;
-my $lbchar = 0;
-my $rbchar = 0;
-
-sub special_chars {
- return if (!$bschar && !$pcchar && !$lbchar && !$rbchar);
- print '\begingroup'."\n";
- if ($bschar) {
- print '\lccode`.=92 \lowercase{\expandafter\gdef\csname @backslashchar\endcsname{.}}'."\n";
- }
- if ($pcchar) {
- print '\lccode`.=37 \lowercase{\expandafter\gdef\csname @percentchar\endcsname{.}}'."\n";
- }
- if ($lbchar) {
- print '\lccode`.=123 \lowercase{\expandafter\gdef\csname @charlb\endcsname{.}}'."\n";
- }
- if ($rbchar) {
- print '\lccode`.=125 \lowercase{\expandafter\gdef\csname @charrb\endcsname{.}}'."\n";
- }
- print '\endgroup'."\n";
-}
-
-#######################################################################################################################
-## Loop around given commands ##
-#######################################################################################################################
-while (my $cmd = shift @cmds) {
-
-next if $cmd eq '';
-my $origcmd = $cmd;
-my $showvalue;
-my $inpreamble;
-if ($cmd ne $FAKECMD) {
-if ($PGFKEYS) {
- $cmd = "pgfk\@$cmd/.\@cmd";
- push @PACKAGES, "pgfkeys";
-}
-if ($PGFKEYSPLAIN) {
- $cmd = "pgfk\@$cmd";
- push @PACKAGES, "pgfkeys";
-}
-if (length ($cmd) > 1) {
- $cmd =~ s/^([#^])?\\?//;
- my $type = $1 || '';
- $showvalue = $type eq '#';
- $inpreamble = $type eq '^';
-}
-$bschar = $cmd =~ s/\\/\\csname\0\@backslashchar\\endcsname\0/g;
-$pcchar = $cmd =~ s/\%/\\csname\0\@percentchar\\endcsname\0/g;
-$lbchar = $cmd =~ s/\{/\\csname\0\@charlb\\endcsname\0/g;
-$rbchar = $cmd =~ s/\}/\\csname\0\@charrb\\endcsname\0/g;
-$cmd =~ s/\s/\\space /g;
-$cmd =~ s/\0/ /g;
-}
-
-open (my $tmpfile, '>', $TMPFILE);
-select $tmpfile;
-
-print "\\nonstopmode\n";
-
-if ($ISLATEX) {
- #print "\\nofiles\n";
- if ($FINDDEF || $LISTCMD || $PRINTORIGDEF) {
- # Load the 'filehook' and 'currfile' packages without 'kvoptions' by providing dummy definitions for the 'currfile' options:
- print '\makeatletter\expandafter\def\csname ver@kvoptions.sty\endcsname{0000/00/00}\let\SetupKeyvalOptions\@gobble';
- print '\newcommand\DeclareStringOption[2][]{}';
- print '\newcommand\DeclareBoolOption[2][false]{\expandafter\newif\csname ifcurrfile@#2\endcsname\csname currfile@#2#1\endcsname}';
- print '\let\DeclareVoidOption\@gobbletwo\def\ProcessKeyvalOptions{\@ifstar{}{}}';
- print '\def\currfile@mainext{tex}\def\currfile@maindir{\@currdir}\let\ifcurrfile@fink\iffalse\makeatother';
- print "\\RequirePackage{filehook}\n";
- print "\\RequirePackage{currfile}\n";
- print '\makeatletter\expandafter\let\csname ver@kvoptions.sty\endcsname\relax\let\SetupKeyvalOptions\@undefined\let\DeclareBoolOption\@undefined\let\DeclareStringOption\@undefined';
- print '\let\DeclareVoidOption\@undefined\let\ProcessKeyvalOptions\@undefined\makeatother';
- }
- if ($FINDDEF || $PRINTORIGDEF) {
- print '{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname' . "\n";
- print '\AtBeginOfFiles{{{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname\else' . "\n";
- print ' \ClearHook\AtBeginOfFiles{}\relax';
- print ' \ClearHook\AtEndOfFiles{}\relax';
- # Get parent filename
- print ' \csname currfile@pop\endcsname';
- print ' {\message{^^J:: \expandafter\string\csname '.$cmd.'\endcsname\space first defined in "\currfilename".^^J}}\fi}}', "\n";
- print ' \csname currfile@push\endcsname';
- print '\AtEndOfFiles{{{\expandafter}\expandafter\ifx\csname ' . $cmd . '\expandafter\endcsname\csname @undefined\endcsname\else' . "\n";
- print ' \ClearHook\AtBeginOfFiles{}\relax';
- print ' \ClearHook\AtEndOfFiles{}\relax';
- print ' {\message{^^J:: \expandafter\string\csname '.$cmd.'\endcsname\space first defined in "\currfilename".^^J}}\fi}}', "\n";
- print '\else'. "\n";
- print ' {\message{^^J:: \expandafter\string\csname '.$cmd.'\endcsname\space is defined by (La)TeX.^^J}}', "\n";
- print '\fi'. "\n";
- }
- if ($LISTCMD) {
- print '\AtBeginOfEveryFile{\message{^^J>> entering file "\currfilename"^^J}}'."\n";
- print '\AtEndOfEveryFile{\message{^^J<< leaving file "\currfilename"^^J}}'."\n";
- }
- if (!$BEFORECLASS) {
- print "\\documentclass[$CLASSOPTIONS]{$CLASS}\n";
- if ($LISTCMD) {
- print '\tracingonline=1\relax'. "\n";
- print '\tracingassigns=1\relax'. "\n";
- }
-
- foreach my $pkg (@PACKAGES) {
- $pkg =~ /^(?:\[(.*)\])?\{?(.*?)\}?$/;
- my ($pkgname,$pkgoptions) = ($2, $1 || '');
- print "\\usepackage[$pkgoptions]{$pkgname}\n";
- }
- {
- local $, = "\n";
- print @OTHERDEFS, '';
- }
- unless ($inpreamble || $INPREAMBLE) {
- print_versions if $PRINTVERSION;
- print '\tracingonline=0\relax'. "\n";
- print '\tracingassigns=0\relax'. "\n";
- print "\\begin{document}\n";
- }
- }
- else {
- if ($LISTCMD) {
- print '\tracingonline=1\relax'. "\n";
- print '\tracingassigns=1\relax'. "\n";
- }
- }
-}
-elsif ($ISCONTEXT) {
- foreach my $pkgname (@PACKAGES) {
- print "\\usemodule[$pkgname]\n";
- }
- {
- local $, = "\n";
- print @OTHERDEFS, '';
- }
- &special_chars();
- print "\\starttext\n" unless $inpreamble || $INPREAMBLE;
-}
-elsif ($ISTEX) {
- foreach my $pkgname (@PACKAGES) {
- print "\\input $pkgname \n";
- }
- {
- local $, = "\n";
- print @OTHERDEFS, '';
- }
- &special_chars();
-}
-
-foreach my $envc (@ENVCODE) {
- my ($envtype,$env) = @$envc;
- if ($envtype eq 'environment') {
- printf $BEGINENVSTR, $env;
- }
- elsif ($envtype eq 'before') {
- print "$env\n";
- }
-}
-
-if (!$LISTCMD && $cmd ne $FAKECMD) {
-
-print '\immediate\write0{==============================================================================}%'."\n";
-if (length ($cmd) > 1) {
-if ($showvalue || $SHOWVALUE) {
- print '\immediate\write0{\string\the\expandafter\string\csname ', $cmd, '\endcsname}%'."\n";
- print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
- print '\immediate\write0{\expandafter\the\csname ', $cmd, '\endcsname}%'."\n";
-} else {
- print '\begingroup';
- print '\immediate\write0{\expandafter\string\csname ', $cmd, '\endcsname}%'."\n";
- print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
- print '\expandafter\endgroup\expandafter\immediate\expandafter\write\expandafter0\expandafter{\expandafter\meaning\csname ', $cmd, '\endcsname}%'."\n";
-}
-}
-else {
-if ($showvalue || $SHOWVALUE) {
- print '\immediate\write0{\string\the\string\\', $cmd, '}%'."\n";
- print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
- print '\immediate\write0{\the\\', $cmd, '}%'."\n";
-} else {
- print '\immediate\write0{\string\\', $cmd, '}%'."\n";
- print '\immediate\write0{------------------------------------------------------------------------------}%'."\n";
- print '\immediate\write0{\meaning\\', $cmd, '}%'."\n";
-}
-}
-print '\immediate\write0{==============================================================================}%'."\n";
-
-}
-
-foreach my $envc (reverse @ENVCODE) {
- my ($envtype,$env) = @$envc;
- if ($envtype eq 'environment') {
- printf $ENDENVSTR, $env;
- }
- elsif ($envtype eq 'after') {
- print "$env\n";
- }
-}
-
-if ($ISLATEX) {
- print "\\documentclass[$CLASSOPTIONS]{$CLASS}\n" if $BEFORECLASS;
- if ($inpreamble || $INPREAMBLE || $BEFORECLASS) {
- print_versions if $PRINTVERSION;
- print '\tracingonline=0\relax'. "\n";
- print '\tracingassigns=0\relax'. "\n";
- print "\\begin{document}\n"
- }
- print "\\end{document}\n";
-}
-elsif ($ISCONTEXT) {
- print "\\starttext\n" if $inpreamble || $INPREAMBLE;
- print "\\stoptext\n";
-}
-elsif ($ISTEX) {
- print "\\bye\n";
-}
-
-close ($tmpfile);
-
-select STDOUT;
-
-# Removes all '{' and '}' characters which no real braces.
-sub remove_invalid_braces {
- $_[0] =~ s/\\[\\%]//g; # remove \\ and \%
- $_[0] =~ s/%.*$//; # remove line comments
- $_[0] =~ s/\\[\{\}]//g; # remove \{ and \}
-}
-
-sub env_braces {
- my $line = shift;
- remove_invalid_braces $line;
- my $level = shift || 0;
- my $count = shift || 0;
- for my $char (split //, $line) {
- if ($char eq '{') {
- $level++;
- }
- elsif ($char eq '}') {
- $level--;
- if ($level == 0) {
- $count++;
- }
- }
- }
- return ($level, $count);
-}
-
-sub call_editor {
- my $path = shift;
- my $linenumber = shift;
- print "Opening file '$path', line $linenumber.\n";
- if ($EDITOR =~ /%/) {
- $EDITOR =~ s/%%/\000/;
- $EDITOR =~ s/%f/$path/;
- $EDITOR =~ s/%n/$linenumber/;
- $EDITOR =~ s/\000/%/;
- system($EDITOR);
- }
- else {
- system($EDITOR, "+$linenumber", $path);
- }
-}
-
-sub print_orig_def {
- my $rmacroname = shift;
- my $file = shift;
- my $path = shift;
- my $linenumber;
- my $found = 0;
- open (my $fh, '<', $path) or return;
- my $rmacrodef = qr/
- ^ # Begin of line (no whitespaces!)
- (
- (?:(?:\\global|\\long|\\protected|\\outer)\s*)* # Prefixes (maybe with whitespace between them)
- )
- \\(
- (?:[gex]?def) \s* \\ # TeX definitions
- | (?:new|renew|provide)command\s* \*? \s* \{? \s* \\ # LaTeX definitions
- | (?:new|renew|provide)robustcmd\s* \*? \s* \{? \s* \\ # etoolbox definitions
- | (?:new(?:box|count|dimen|if|insert|read|skip|muskip|toks|write)) \s* \\ # TeX registers etc.
- | (?:char|count|dimen|mathchar|skip|toks)def \s* \\ # TeX chardefs etc.
- | \@namedef\{? # Definition by name only
- | Declare[a-zA-z]+ \s* \*? \s* \{? \s* \\ # Declare... definitions
- | declare[a-zA-z]+ \s* \*? \s* \{? \s* \\ # declare... definitions
- )
- $rmacroname # Macro name without backslash
- [^a-zA-Z@]
- /xms;
- my $rmacrolet = qr/
- ^ # Begin of line (no whitespaces!)
- (?:global\s*)? # Prefixes (maybe with whitespace between them)
- \\let \s* \\ # let
- $rmacroname # Macro name without backslash
- \s* =? # Optional '='
- \s* \\ ([a-zA-Z@]+) # Second macro
- /xms;
- my $renvdef = qr/
- ^ # Begin of line (no whitespaces!)
- \\(
- (?:new|renew|provide)environment\s* \{ \s* # LaTeX definitions
- )
- ($rmacroname) # Environment names follow same rules as macro names
- \s* } # closing brace
- (.*) # Rest of line
- /xms;
- while (my $line = <$fh>) {
- if ($line =~ $rmacrodef) {
- my $defcmd = $1;
- $found = 1;
- $linenumber = $.;
- if ($EDIT) {
- call_editor($path, $linenumber);
- last;
- }
- print "% $file, line $linenumber:\n";
- print $line;
- last if $defcmd =~ /^(?:new(?:box|count|dimen|if|insert|read|skip|muskip|toks|write))/;
- last if $defcmd =~ /^(?:char|count|dimen|mathchar|skip|toks)def/;
- remove_invalid_braces $line;
- my $obrace = $line =~ tr/{/{/;
- my $cbrace = $line =~ tr/}/}/;
- while ($obrace != $cbrace) {
- my $line = <$fh>;
- print $line;
- remove_invalid_braces $line;
- $obrace += $line =~ tr/{/{/;
- $cbrace += $line =~ tr/}/}/;
- }
- print "\n";
- last;
- }
- elsif ($line =~ $rmacrolet) {
- my $letcmd = $1;
- $found = 1;
- $linenumber = $.;
- if ($EDIT) {
- call_editor($path, $linenumber);
- last;
- }
- print "% $file, line $linenumber:\n";
- print $line;
- print "\n";
- unshift @cmds, $letcmd;
- last;
- }
- elsif ($line =~ $renvdef) {
- $found = 2;
- $linenumber = $.;
- if ($EDIT) {
- call_editor($path, $linenumber);
- last;
- }
- print "% $file, line $linenumber:\n";
- print $line;
- my ($level, $count) = env_braces $line;
- while ($count < 3) {
- my $line = <$fh>;
- print $line;
- ($level, $count) = env_braces $line, $level, $count;
- }
- print "\n";
- last;
- }
- }
- close($fh);
- return $found;
-}
-
-sub cleanpath {
- my $path = shift;
- chomp $path;
- if ($path =~ /[a-z]:/i) {
- $path =~ s/\//\\/g;
- }
- return $path;
-}
-
-
-open (my $texpipe, '-|', "$TEX $TEXOPTIONS $USERTEXOPTIONS \"$TMPFILE\" ");
-
-my $name = '';
-my $definition = '';
-my $errormsg = '';
-my $origdeffound = 0;
-
-while (<$texpipe>) {
- if (/^::\s*(.*)/) {
- my $line = $1;
- if ($FINDDEF == 2) {
- if ($line =~ /first defined in "(.*)"/) {
- my $path = cleanpath(`kpsewhich "$1"`);
- $line =~ s/$1/$path/;
- }
- }
- if ($PRINTORIGDEF) {
- if ($line =~ /first defined in "(.*)"/) {
- my $file = $1;
- my $path = cleanpath(`kpsewhich "$file"`);
- chomp $path;
- $origdeffound = print_orig_def($cmd, $file, $path);
- }
- elsif ($line =~ /is defined by \(La\)TeX./) {
- my $file = 'latex.ltx';
- my $path = cleanpath(`kpsewhich "$file"`);
- chomp $path;
- $file = $path if $FINDDEF > 1;
- $origdeffound = print_orig_def($cmd, $file, $path);
- }
- if (!$origdeffound) {
- print "Source code definition of '$origcmd' could not be found.\n";
- print "$line\n";
- }
- }
- else {
- print "$line\n";
- }
- next;
- }
- if (/^(:TEXDEF:\s*(.*))/) {
- my $line = $1;
- chomp ($line);
- my $text = $2;
- while (length $line >= 79) {
- $line = <$texpipe>;
- chomp ($line);
- $text .= $line;
- }
- print "$text\n";
- next;
- }
- if ($LISTCMD) {
- if (/^>> entering file "(.*)"$/) {
- push @FILES, $currfile;
- $currfile = $1;
- push @FILEORDER, $currfile if not exists $DEFS{$currfile};
- }
- elsif (/^<< leaving file "(.*)"$/) {
- $currfile = pop @FILES;
- }
- elsif (/^{(?:into|reassigning) \s*(.*)}?$/) {
- my ($cs, $def) = split (/=/, $1, 2);
- $cs =~ s/^\\//;
- $def =~ s/\}$//;
- if ($LISTCMD > 1 || $cs !~ /[@ ]/) {
- if ($def =~ /^\\((?:skip|count|toks|muskip|box|dimen)\d+)$/) {
- $ALIAS{$1} = $cs;
- }
- elsif (exists $ALIAS{$cs}) {
- $cs = $ALIAS{$cs}
- }
- $DEFS{$currfile}{$cs} = $def;
- }
- }
- }
- last if /^=+$/;
- if ($_ =~ /^!\s*(.*)/ && !$errormsg) {
- chomp;
- my $line = $1;
- $errormsg = $line;
- while (length $line >= 79) {
- $line = <$texpipe>;
- chomp $line;
- $errormsg .= $line;
- }
- }
-}
-while (<$texpipe>) {
- last if /^-+$/;
- next if /^$/;
- chomp;
- $name .= $_;
-}
-while (<$texpipe>) {
- last if /^=+$/;
- next if /^$/;
- chomp;
- $definition .= $_;
- if ($_ =~ /^!\s*(.*)/ && !$errormsg) {
- $errormsg = $1;
- }
-}
-while (<$texpipe>) {
- if ($_ =~ /^!\s*(.*)/ && !$errormsg) {
- chomp;
- my $line = $1;
- $errormsg = $line;
- while (length $line >= 79) {
- $line = <$texpipe>;
- chomp $line;
- $errormsg .= $line;
- }
- }
-}
-close ($texpipe);
-
-my $error = $? >> 8;
-
-if ($error) {
- if ( ($SHOWVALUE || $showvalue) && ($errormsg =~ /^You can't use `.*' after \\the\./) ) {
- print STDERR "\n$name:\nError: Given command sequence does not contain a value.\n\n";
- }
- else {
- print STDERR "\n$name:\nCompile error: $errormsg\n\n";
- }
- next;
-}
-
-#last if $PRINTORIGDEF && $origdeffound && $EDIT;
-
-next if $cmd eq $FAKECMD;
-if ($cmd eq $LISTSTR) {
- foreach $currfile (@FILEORDER) {
- next if not keys %{$DEFS{$currfile}};
- print "\nDefined by file '$currfile':\n";
- CMD:
- foreach my $cmd (sort keys %{$DEFS{$currfile}}) {
- next CMD if exists $IGNOREDEF{$cmd};
- foreach my $pattern (@IGNOREDEFREG) {
- next CMD if $cmd =~ $pattern;
- }
- print "\\$cmd";
- print ": $DEFS{$currfile}{$cmd}" if ($LISTCMDDEF);
- print "\n";
- }
- }
-} elsif (!$PRINTORIGDEF || !$origdeffound) {
- print "\n(in preamble)" if $inpreamble;
- print "\n$name:\n$definition\n\n";
-}
-
-if (!($PRINTORIGDEF && $origdeffound)) {
- testdef($origcmd,$definition);
-}
-if ($ISENVIRONMENT && $origdeffound < 2 && $cmd !~ /^end/) {
- unshift @cmds, 'end' . $cmd;
-}
-
-}
-
-chdir $cwd;
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/texdiff/texdiff b/Build/source/texk/texlive/linked_scripts/texdiff/texdiff
deleted file mode 100755
index 4c27fab205a..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texdiff/texdiff
+++ /dev/null
@@ -1,554 +0,0 @@
-#! /usr/bin/env perl
-#
-# See POD documentation below or use:
-#
-# $ perldoc texdiff
-#
-# to see embedded documentation. Alternatively, you can create manual
-# or HTML pages using pod2man and pod2html. Below the POD part you
-# can add your own macros to be skipped by the edit marks.
-#
-# $Id: texdiff 766 2009-09-24 19:19:38Z cengiz $
-
-=pod
-
-=head1 NAME
-
-B<texdiff> - Compares two (La)TeX documents to create a merged version showing changes, similar to that of 'Change Tracking' in some word processors.
-
-=head1 SYNOPSIS
-
-texdiff [--nofloats|-n] old.tex new.tex [diff.tex]
-
-=head1 DESCRIPTION
-
-The first two files are compared and a new TeX file is output. When
-the output file is processed with (La)TeX it marks new changes with
-blue and old text with red with a strike-through line. Furthermore,
-passages with changes are marked at the margin with grey bars by the
-LaTeX C<changebar> package (although only after running C<dvips>, in
-C<xdvi> the bars are one inch too far left to compensate the one inch
-offset inserted by TeX printer drivers).
-
-C<texdiff> uses and therefore requires the C<wdiff> command to insert
-these marks. If LaTeX macros are included in those striked out or
-underlined passages, the latex run will most likely fail. The source
-of most problems lies in C<wdiff> tearing apart pairs of
-braces. Therefore C<texdiff> is a perl script that calls C<wdiff> internally
-and fixes C<wdiff>'s output by re-pairing braces again and handling some
-commonly used LaTeX macros.
-
-For texdiff to work, the following LaTeX code must be inserted in the
-preamble of the LaTeX document:
-
- \usepackage{xcolor} \usepackage{ulem} \usepackage{changebar}
- \newcommand\TLSins[1]{\cbstart{}\textcolor{ins}{\uline{#1}}\cbend{}}
- \newcommand\TLSdel[1]{\cbdelete{}\textcolor{del}{\sout{#1}}}
-
-Define editing colors C<ins> and C<del> with existing C<xcolor> color names:
- \colorlet{ins}{blue} \colorlet{del}{red}
-
-Or from scratch:
- \definecolor{ins}{rgb}{0, 0.5, 0}
-
-These macros are NOT automatically interted at \begin{document} like
-the original scripts did (see the B<ACKNOWLEDGMENTS> section below),
-because this will not work on files of a multi-file document (those
-included by \include or \input). Furthermore, if you insert the
-macros manually, you can tune them as you like, i. e. change text
-color or position of changebars. Have a look at the documentation of
-the ulem and changebar packages on how to do this!
-
-=head1 OPTIONS
-
-=over
-
-=item B<--nofloats>, B<-n>
-
-If given, skips contents of figure environments, but does show
-insertions and deletions in the caption commands. This is done to
-avoid complex messups in subfloat or complex figure environments.
-
-=item B<--debug>, B<-d>
-
-Turns on debugging. Temporary files that contain numbered braces are
-kept and a raw difference file is written as output file name appended
-with '-wdiff.tex'. In addition, several regular expression diagnostics
-are printed. B<Warning: produces a lot of output.>
-
-=back
-
-=head1 AUTHOR
-
-Mark Doll <markdoll<AT>gmx.net>, Cengiz Gunay <cengique<AT>users.sf.net>.
-
-=head1 ACKNOWLEDGMENTS
-
-=over
-
-=item B<*>
-
-Version 0.4, by CG, 2009/09/15. Added use of GetOpt to take an optional
-parameter to skip float (e.g., figure or table) contents. Added an
-optional debug mode. Embedded POD documentation. Fixed problem
-with insertion and deletions appearing in the middle of sectioning
-commands by throwing off LaTeX.
-
-=item B<*>
-
-Version 0.3, modified by Cengiz Gunay <cengique@users.sf.net>,
-2009/06/30. Added some Latex commands that should be excluded and
-fixed handling of '\%' characters.
-
-=item B<*>
-
-Version 0.2, is a perl implementation of TeXdiff by Mark Doll
-<markdoll@gmx.net>, 2006/08/09. It was derived from the original bash
-and perl scripts created by Robert Maron <robmar@mimuw.edu.pl>,
-available at http://www.robmar.net/TexDiff/. This version of texdiff
-is available at http://mark.doll.name/texdiff/.
-
-=back
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyleft 2006-2009, Mark Doll and Cengiz Gunay
-
-This library is free software; you may redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-# TODO:
-#
-# - after removing excluded commands, unify deletions and insertions
-# if there're no other differences
-# - investigate causes of missing brace pairs
-# - put option to add preamble automatically?
-# - put option to flatten first?
-
-use Getopt::Long qw(GetOptions);
-use Pod::Usage;
-use strict;
-use re 'eval'; # CG: for RE code for skipping float contents
-
-## Problematic commands, that will be removed from deletions and moved
-## out of insertions. The array index equals the number of mandatory
-## command parameters.
-
-## INSERT YOUR HOMEBREW MACROS HERE!!!
-# Omit leading backslash and separate by '|', since this will be
-# interpreted as a regular expression.
-my @mycommands = (
- 'RCS\$[^\$]*\$',
- 'cite\w*p|citet|svnid|citep',
- 'if\w+',
- '',
- '',
- 'Abb(?:ildung)?(?:p[psw])?',
-);
-
-## standard LaTeX macros
-#FIXME: add more macros here!
-my @stdcommands = (
- '\\\\|item|\%', # will match one backslash inside regex
- 'includegraphics|begin|end|input|fancyfoot|subfig|subfloat',
-);
-
-# GetOpt::Long::
-my $nofloats = 0;
-my $help;
-my $DEBUG=0;
-
-my $result = GetOptions ("nofloats|n" => \$nofloats,
- "debug|d" => \$DEBUG,
- "help|?" => \$help );
-
-#print "Figs= $nofloats\n";
-
-pod2usage( -section => "SYNOPSIS") if ($#ARGV < 1 || $help);
-
-## allow nesting of braces (aka curly brackets) up to 10**$w-1 levels
-my $w = 2;
-
-## wdiff marker
-my $delstart = "TLSdel";
-my $delend = "TLEdel";
-my $insstart = "TLSins";
-my $insend = "TLEins";
-
-## LaTeX macros used to mark deletions/insertions in the output
-my $texdelstart = "\\protect\\TLSdel\{";
-my $texdelend = "\}";
-my $texinsstart = "\\protect\\TLSins\{";
-my $texinsend = "\}";
-
-
-## parse command line
-my ($in1,$in2,$out) = @ARGV;
-
-## create temp files from input files with all comments removed and
-## all braces numbered
-write_temp($w,$in1,'tmp1.'.$$);
-write_temp($w,$in2,'tmp2.'.$$);
-sub write_temp {
- my ($w,$file,$tmp) = @_;
-
- $_ = `cat $file`;
-
- ## mark pairs of braces with the same $w digits.
- # i. e. convert "{ { {} } {}}" to "{01 {02 {03}03 }02 {02}02}01" ($w=2).
- #
- # FIXME: marking braces before comparison makes them appear
- # as changes if depth of nesting changes.
-
- my $max=10**$w-1;
- $::cnt = 0;
- s/
- (?<!\\)
- (?:
- \{ (?{ die "Fatal: Braces nested deeper than $max!\n" if ($::cnt >= $max);
- sprintf("\{%0${w}d",++$::cnt) }) |
- \} (?{ sprintf("\}%0${w}d",$::cnt--) })
- )
- /$^R/gx;
-
- print STDERR "Warning: ".abs($::cnt)." unmatched ".($::cnt > 0 ? "opening" : "closing")
- ." brace".(abs($::cnt) == 1 ? "" : "s")."\n" if ($::cnt != 0);
-
- ## remove comments
- # also remove trailing newline and all whitespace at the
- # beginning of the following line like TeX does it
- s/(?<!\\)%.*?\n[ \t]*//g;
-
- ## output
- open(O,">$tmp") or return("Can't open $tmp: $!\n");
- print O;
- close O;
-}
-
-my $wdiff_cmd = ( "wdiff --avoid-wraps"
- . " --start-delete=\'$delstart\' --end-delete=\'$delend\'"
- . " --start-insert=\'$insstart\' --end-insert=\'$insend\'"
- . " tmp1.$$ tmp2.$$");
-$_ = `$wdiff_cmd`;
-
-if ($DEBUG) {
- ## save wdiff output
- if (open(O,">$out-wdiff.tex")) {
- print O;
- close O;
- } else {
- print STDERR "Failed to write wdiff output file $out-wdiff.tex.\n";;
- }
-}
-
-###
-### Phase I: generic processing
-###
-
-## remove paragraph boundaries (two newlines) that wdiff falsely inserted
-# FIXME: Does wdiff always insert same spacing before deletion and the
-# following insertion?!
-s/(
- ([ \t]*\n[ \t]*\n[ \t]*)
- $delstart (?!$delend)
- (?: . (?!$delend) )* .
- $delend
- )
- \2
- $insstart
- /$1\n$insstart/gsx;
-
-
-## Restore backslashed Spaces (prevents falsely escaped right braces)
-# Escaped spaces '\ ' at the end of an insertion/deletion will result in the
-# backslash before the end marker and the space after it. Therefore swap
-# whitespace and end marker. (This might falsely make the insertion/deletion
-# span the following paragraph boundary, but this will be fixed by the next
-# step below). When the end markers finally get replaced by $tex(ins|del)end,
-# which typically is a '}', without this swapping, this would result in escaped
-# right braces and LaTeX complaining about a missing right brace.
-s/(?<!\\)\\($delend|$insend)(\s+)/\\$2$1/g;
-
-
-## split up insertions and deletions that span multiple paragraphs
-while (
- s/(
- $delstart (?!$delend)
- (?: . (?! [ \t]*\n[ \t]*\n[ \t]* | $delend ) )*? .?
- )
- ([ \t]*\n[ \t]*\n[ \t]*)
- /$1$delend$2$delstart/gsx ) {}
-
-while (
- s/(
- $insstart (?!$insend)
- (?: . (?! [ \t]*\n[ \t]*\n[ \t]* | $insend ) )*? .?
- )
- ([ \t]*\n[ \t]*\n[ \t]*)
- /$1$insend$2$insstart/gsx ) {}
-
-
-## Handle unpaired braces
-# Search for all unpaired braces, meaning, they are inside a text
-# deletion or insertion passage, but their counterpart is not within
-# that passage. If they are located inside a deletion passage, simply
-# delete them. If there a inside a insertion passage, move them out
-# by placing an insertion end marker before and an insertion start
-# marker after the brace. In case that a left brace belongs to a
-# preceding LaTeX command (plus and any more zero-parameter commands
-# directly preceding that command; that's matched by a non-whitespace
-# character sequence started by a backslash), also delete resp. move
-# that/these command(s) together with the left brace.
-#
-# FIXME: why is while loop necessary here, but not for handling right braces?
-#
-# FIXME: If there's not at least one character before the character
-# sequence specified in the look-ahead negative assertion, the match
-# would stop at the second occurence of that sequence instead of the
-# first. This leads to the effect, that the following regular
-# expressions may skip $(del|ins)end if it follows directly the left
-# brace (+number). The use of *? instead of * mitigates this effect,
-# but it's not perfect.
-
-## 1. unpaired left brace inside a deletion: delete brace and any preceding LaTeX command(s)
-while (
- s/( # $1: everything till unpaired '{'
- $delstart (?!$delend) # would otherwise not detect end marker of empty deletions!
- (?: . (?!$delend))*?
- )
- ( (?<!\\) \\\S* )? # $2: optional command(s) preceding the '{'
- (?<!\\) \{([0-9]{$w}) (?!\}\3) # '{' and $3: number
- ( # $4: everything what's remaining
- (?: . (?! (?<!\\)\}\3 | $delend) )*? .? # will stop at a matching '}', too
- $delend # won't match if preceeding line found a matching '}'
- )
- /$1$4/sgx ) {} # remove the '{' with number and any preceeding command(s)
-
-## 2. unpaired left brace inside an insertion: move brace out including any preceding LaTeX command(s)
-while (
- s/(
- $insstart (?!$insend)
- (?: . (?!$insend))*?
- )
- ( \s* (?: (?<!\\) \\\S* )? ) # also move preceeding whitespace preceding out
- (?<!\\) \{([0-9]{$w}) (?!\}\3)
- (
- (?: . (?! (?<!\\)\}\3 | $insend) )*? .?
- $insend
- )
- /$1$insend$2\{$3$insstart$4/sgx ) {} # move the '{' with number and any preceeding command(s) out
-
-## 3. unpaired right brace inside a deletion: delete brace
-s/( # $1: everything till unpaired '}'
- $delstart (?!$delend) # would otherwise not detect end marker of empty deletions!
- (?> (?: ## grab all paired braces (prevent backtracking):
- (?: . (?! (?<!\\)\{[0-9]{$w} | $delend) )*? .? # any text till next (unescaped) '{'
- \{([0-9]{$w}) # '{' with $2: number
- (?: . (?! (?<!\\)\}\2 | $delend) )*? .? #any text till matching '}'
- \}\2 # '}' with same number $2
- )* ) ## end of disabled backtracking
- (?: . (?!$delend))*? # any text
- )
- ( \}[0-9]{$w} ) # $3: the (first) unpaired '}' with number
- ( # $4: everything what's remaining
- (?: . (?!$delend))*? .?
- $delend
- )
- /$1$4/sgx; # remove the unpaired '}' with number
-
-## 4. unpaired right brace inside an insertion: move brace out
-s/(
- $insstart (?! $insend)
- (?> (?:
- (?: . (?! (?<!\\)\{[0-9]{$w} | $insend ) )*? .?
- \{([0-9]{$w})
- (?: . (?! (?<!\\)\}\2 | $insend ) )*? .?
- \}\2
- )* )
- (?: . (?!$insend))*?
- )
- ( \}[0-9]{$w} \s* ) # also move whitespace following the '}' out
- (
- (?: . (?!$insend))*? .?
- $insend
- )
- /$1$insend$3$insstart$4/sgx; # move the unpaired '}' with number out
-
-
-## concatenate consecutive insertions and consecutive deletions
-# Don't concatenate over paragraph (two newlines) boundaries, since
-# the LaTeX macros used to mark changed passages can't span multiple
-# paragraphs. Run this before handling LaTeX-commands specifically to
-# allow as much of a command inside a single passage as possible.
-s/$delend([ \t]*\n?[ \t]*)$delstart/$1/g;
-s/$insend([ \t]*\n?[ \t]*)$insstart/$1/g;
-
-
-
-###
-### Phase II: LaTeX-command specific processing
-###
-
-## For COMPLETELY removed/inserted sections, move section command out.
-#
-# May create empty insertions/removals, therefore execute this before
-# the removal of empty (or whitespace only) insertions/removals!
-#
-# Partly changed section titles have been handled by the preceding
-# rules. In case of removal, prevent renumbering by using asterisk
-# form; in case of insertion, add a short form without markers to
-# prevent problems when LaTeX'ing the diff.
-my $sectionre = "chapter|section|subsection|subsubsection|paragraph";
-s/
- ( # $1: text before section command
- $delstart (?!$delend)
- (?: . (?!$delend) )*?
- )
- \\($sectionre) # '\' and $2: section command
- \{([0-9]{$w}) # '{' and $3: number
- ( (?: . (?! (?<!\\)\}\3 | $delend) )*? .? ) # $4: section command parameter (title)
- ( \}\3 \s* ) # '}' and same number plus following whitespace
- /$1$delend\\$2\*\{$3$delstart$4$delend$5$delstart/sgx;
- # move section commmand out and convert command to asterisk form
-
-s/
- ( # $1: text before section command
- $insstart (?!$insend)
- (?: . (?!$insend) )*?
- )
- \\($sectionre) # '\' and $2: section command
- \{([0-9]{$w}) # '{' and $3: number
- ( (?: . (?! (?<!\\)\}\3 | $insend) )*? .? ) # $4: section command parameter (title)
- ( \}\3 \s* ) # $5: '}' and same number plus following whitespace
- /$1$insend\\$2\[$4\]\{$3$insstart$4$insend$5$insstart/sgx;
- # move sections command out and add short form without markers
-
-s/
- \\($sectionre) # '\' and $1: section command
- (?{ $::titlecontents = ""; $::optcontents = "" }) # initialize vars
- ( (?: \[ (?: (?! \] ) . )* \] # $2: optional argument
- (?{ print "====Found \\$1 opt arg '$^N'." if $DEBUG; })
- )? )
- \{([0-9]{$w}) # '{' and $3: number
- (?: # Groups text followed by ins or del block
- ( (?! \}\3) (?: (?! \}\3 ) . )*? (?= $insstart | $delstart ) )
- (?{ print "=====Found ins\|del start before section end '$^N'!\n" if $DEBUG;
- $::titlecontents .= $^N; $::optcontents .= $^N })
- (?: ( $delstart (?: (?!$delend) . )* $delend )
- (?{ print "=====Found del end!\n" if $DEBUG;
- $::titlecontents .= $^N }) )? # dont keep deletions in opt
- (?: $insstart ( (?: (?!$insend) . )* ) $insend
- (?{ print "=====Found ins end '$^N'!\n" if $DEBUG;
- $::titlecontents .= "$insstart$^N$insend";
- $::optcontents .= $^N }) )? # keep insertions in opt
- )+ # end text + ins or del (need at least one for this to succeed)
- (?: ( (?: (?! \}\3 ) . )+ )
- (?{ print "=====Found text after ins\|del end and before section end: '$^N'!\n" if $DEBUG;
- $::titlecontents .= $^N; $::optcontents .= $^N}) )?
- (?: \}\3) # '}' and same number
- (?{ print "=====End of \\$1.\n" if $DEBUG;
- $::optcontents = ($2 ne "" ? $2 : $::optcontents ) })
- /\\$1\[$::optcontents\]\{$3$::titlecontents\}$3/sgx;
- # Add a short form with removed insertions and deletions in section commands
- # Will not add the short form if it already exists.
-
-## Remove problematic commands from deletions and move them out of insertions
-for my $num (0 .. ($#mycommands>$#stdcommands ? $#mycommands : $#stdcommands)) {
- my $command = "";
-
- $command .= $mycommands[$num] if ($mycommands[$num] );
- $command .= "|" if ($mycommands[$num] && $stdcommands[$num]);
- $command .= $stdcommands[$num] if ( $stdcommands[$num]);
-
- next if(!$command);
-
- s/
- ( # $1: anything before the command
- $delstart (?!$delend)
- (?: . (?!$delend) )*? .?
- )
- ( # $2: the command with all its parameters
- \\(?:$command) # the command itself (preceded by a '\')
- (?: \[ .*? (?<!\\)\] )* # any optional parameters (enclosed in '[]')
- (?: \{([0-9]{$w}) .*? (?<!\\)\}\3 ){$num} # $num mandatory parameters
- )
- /$1/gsx;
-
- s/(
- $insstart (?!$insend)
- (?: . (?!$insend) )*? .?
- )
- (
- \\(?:$command)
- (?: \[ .*? (?<!\\)\] )*
- (?: \{([0-9]{$w}) .*? (?<!\\)\}\3 ){$num}
- )
- /$1$insend$2$insstart/gsx;
-}
-
-## CG: optionally leave figure contents intact: remove deletions and keep
-## insertions. do not touch the caption command
-## => tested with multiple figures
-## => tested with multi-captions and no captions. should work with subfig and subfloat
-
-s/( \\begin\{[0-9]{$w}\s*((?:figure|table)\*?)(?{ $::floatname = $^N })\s*\}[0-9]{$w} ) # begin figure or table line
- (?{ print "=====Found figure!\n" if $DEBUG;
- $::figcontents=$^N }) # Save into variable
- (?: # Groups BLOCK + caption command
- (?: # BLOCK of insert and delete commands until caption
- ( (?! \\caption) (?: (?! $insstart | $delstart | \\caption | \\end\{[0-9]{$w}\s*figure ) . )* )
- (?{ print "=====Found ins\|del start or caption '$^N'!\n" if $DEBUG;
- $::figcontents .= $^N })
- (?: $delstart (?: (?!$delend) . )* $delend
- (?{ print "=====Found del end!\n" if $DEBUG; }) )? # dont keep deletions
- (?: $insstart ( (?: (?!$insend) . )* ) $insend
- (?{ print "=====Found ins end '$^N'!\n" if $DEBUG; $::figcontents .= $^N }) )? # keep insertions
- )*? # end BLOCK
- (?: (\\caption (?: \[ (?: (?! (?<!\\) \]) . )* \])? \s*
- \{ ([0-9]{$w}) (?{ $::captiondepth=$^N })
- (?: (?! \}(??{ $::captiondepth })) . )* \}(??{$::captiondepth}) )
- (?{ print "=====" . pos() . ": Found caption ($::captiondepth) '$^N'!\n" if $DEBUG; $::figcontents .= $^N }) )? # caption
- )*? # end BLOCK + caption
- ( \\end\{[0-9]{$w}\s*figure\*?\s*\}[0-9]{$w} )
- (?{ print "=====Found figure end '$^N'!\n" if $DEBUG; $::figcontents .= $^N })
- /$::figcontents/gsx;
-
-###
-### Phase III: cleaup, conversion, output
-###
-
-## remove insertions and removals that are empty or only mark whitespace
-s/$delstart(\s*)$delend/$1/g;
-s/$insstart(\s*)$insend/$1/g;
-
-
-## remove brace numbers
-s/(?<!\\)(?:(\{|\})[0-9]{$w})/$1/g;
-
-
-## substitute final LaTeX macro code
-s/$delstart/$texdelstart/g;
-s/$delend/$texdelend/g;
-s/$insstart/$texinsstart/g;
-s/$insend/$texinsend/g;
-
-
-## output
-if ($out ne "") {
- if (open(O,">$out")) {
- print O;
- close O;
- } else {
- print STDERR "Failed to write output file $out.\n";
- }
-} else {
- print ;
-}
-
-## remove temp files
-if (!$DEBUG) {
- unlink('tmp1.'.$$);
- unlink('tmp2.'.$$);
-}
diff --git a/Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten b/Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten
deleted file mode 100644
index e820e182a44..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten
+++ /dev/null
@@ -1,411 +0,0 @@
-#! /usr/bin/env perl
-
-# Use:
-# $ perldoc texdirflatten
-# to see embedded documentation. Alternatively, you can create manual
-# or HTML pages using pod2man and pod2html.
-
-=pod
-
-=head1 NAME
-
-B<texdirflatten> - Collects all components of a (La)TeX file in a
-single output directory -- i.e., flattens its hierarchy.
-
-=head1 SYNOPSIS
-
-texdirflatten [-1|--onetex] [-f|--file input.tex] [-o outputdir]
- [--imgexts .ext1,.ext2,...] [--debug] [-V|--version] [-?|--help]
-
-=head1 DESCRIPTION
-
-This Perl script parses a LaTeX file recursively, scanning all child
-files, and collects details of any included and other data files, such
-as graphics and BiBTeX bibliography files. These component files, are
-then all put into a single directory (thus "flattening" the document's
-directory tree). This is useful in distributing manuscripts to
-collaborators or in submitting to journals.
-
-=for comment
-Run without parameters to see usage.
-
-=head1 OPTIONS
-
-=over
-
-=item B<--file>, B<-f> I<input.tex>
-
-Specifies input (La)TeX file.
-
-=item B<--onetex>, B<-1>
-
-If specified, produces a single TeX file by expanding all \input and
-\include commands in place.
-
-=item B<--output>, B<-o> I<outputdir>
-
-Directory to collect all files. B<texdirflatten> will copy each source
-file, graphics and bibliography file to this directory. It will be
-created if it is unexistent. If unspecified, it defaults to C<flat/>.
-
-=item B<--imgexts> I<.ext1,.ext2[,...]>
-
-Prepends to the prioritized list of image extensions to search when
-trying to find the image to copy to output folder. The first file with
-the extension found will be copied and search stopped. Default order
-is C<"", ".eps", ".pdf", ".pstex"> (note that it includes files with
-no extension). If using pdflatex, one may want to add PDF before EPS
-with C<--imgexts .pdf>. Don't forget the dot before the extension!
-
-=item B<--debug>
-
-Enables copious amounts of debugging output - useful if something is going wrong.
-
-=item B<--version>, B<-V>
-
-Displays the current version number and the usage and exits.
-
-=item B<--help>, B<-?>
-
-Show this manual page.
-
-=back
-
-=head1 EXAMPLES
-
-The following example scans C<manuscript.tex> in the current directory
-and gathers it and all its components in the C<submit_01/> directory:
-
- $ texdirflatten -f manuscript.tex -o submit_01
-
-=head1 CAVEATS
-
-Please take backups before running this command. No warranties
-whatsoever provided.
-
-You may need to run C<epstopdf> on EPS files if you are using C<pdflatex>:
-
- $ for i in *.eps; do epstopdf $i; done
-
-=head1 BUGS
-
-Bug reports and patches are welcome.
-
-=head1 AUTHOR
-
-Cengiz Gunay <cengique<AT>users.sf.net>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyleft 2003-2017, Cengiz Gunay
-
-This library is free software; you may redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-# TODO:
-# - parse BIBINPUTS environment variable and search figures and such
-# there as well.
-# - also copy bibtex style file
-
-package texdirflatten;
-
-use Getopt::Long qw(GetOptions);
-use Pod::Usage;
-use strict;
-use warnings;
-use re 'eval';
-
-# Global
-my $outputdir = "flat"; # Output directory
-my $file = ""; # File to read
-my @imgexts = ("", ".eps", ".pdf", ".pstex"); # Ordered list of image extensions to search and copy
-my $imgexts_pre; # Prepend to @imgexts
-my $onetex = 0; # Indicates all input and include commands be expanded
-my $version = "1.3"; # 2017-02-02
-my $DEBUG = 0; # Enable debugging output
-my $help;
-
-# parse helpers
-my %texfiles;
-
-# GetOpt::Long::
-my $result = GetOptions ("output|o=s" => \$outputdir,
- "onetex|1" => \$onetex,
- "file|f=s" => \$file,
- "imgexts=s" => \$imgexts_pre,
- "debug" => \$DEBUG,
- "version|V" => sub { print "texdirflatten version $version\n";
- pod2usage( -section => "SYNOPSIS"); },
- "help|?" => \$help );
-
-# regexp for none or an even number of backslashes (\):
-my $unescaped =
- '(?<! \\\\)(?(?= \\\\) (?: \\\\\\\\)* )?';
-
-# counter for files translated (like LyX does)
-$::filecount = 0;
-
-pod2usage( -verbose => 2 ) if ($help);
-
-pod2usage( -section => "SYNOPSIS") if ($file eq "");
-
-if ($imgexts_pre) {
- unshift(@imgexts, split(/,/, $imgexts_pre));
- print "imgexts: ". join(",", @imgexts) . "\n" if $DEBUG;
-}
-
-system "mkdir $outputdir" if (not -d $outputdir);
-
-# start recursing
-parseTeX($file, "", popfile($file), 0);
-
-sub parseTeX {
- my $file = shift;
- my $inputdir = shift;
- my $outfile = "$outputdir/" . shift;
- my $level = shift;
-
- # Add a proper TeX suffix if it's missing
- $outfile .= '.tex' if ! ($outfile =~ /\.tex\s*$/i );
-
- my @flats;
- my @longs;
- my $popped;
-
- open my $FILE, $file or die "Cannot find file to read $file\n";
-
- # Read to whole file first, and then scan for regexps
- my $contents = "";
- while(<$FILE>) {
- $contents = $contents . $_;
- }
- close $FILE;
-
- ## First, remove comments so that input commands inside are ignored.
- # Also remove trailing newline and all whitespace at the beginning
- # of the following line like TeX does it. Only for %'s following
- # the proper backslash pattern.
- $contents =~ s/( $unescaped )\%.*?\n[ \t]*/$1/gx;
-
- # Look for graphics include statement
- if ($contents =~ /\\input\@path\{\{([^}]*)\}\}/) {
- $inputdir = $1;
- print "Found input directory: $inputdir\n" if $DEBUG;
- }
-
- print "Parsing '$file' in directory '$inputdir'\n";
-
- # Default value
- #$inputdir = './' if (-z $inputdir);
-
- # three cases: graphics, inputs and bibs
-
- # an \includegraphics statement
- @::flats = ();
- @::longs = ();
- #$::popped = "";
-
- $contents =~
- s/\\includegraphics(\[[^\]]*\])?\{([^}]*)\}
- (?{ $::popped = flattenfilename($2);
- push @::longs, $2; push @::flats, $::popped })
- /\\includegraphics$1\{$::popped\}/gmx;
-
- if ($#::flats > -1) {
- my ($long, $flat);
-
- foreach $long (@::longs) {
- $flat = shift @::flats;
-
- # convert LyX directory dots
- $long =~ s/\\lyxdot /./g;
- $flat =~ s/\\lyxdot /./g;
-
- print "Looking for graphics: '$long'\n" if $DEBUG;
-
- my @dirs = ("", "$inputdir", $inputdir . '../figures/');
-
- seekfile($long, $flat, \@imgexts,
- ["", "$inputdir", $inputdir . '../figures/']);
-
- }
- }
-
- # Must do bibs before input commands because, when expanded, they
- # add new bibs inside.
- replacebibs(\$contents, $inputdir);
-
- # an \input or \include statement
- @flats = ();
- @longs = ();
- $contents =~
- s/\\(input|include)\{([^}]*)\}/"\\${1}\{" .
- ($popped = flattenfilename($2) and push @longs, $2 and push @flats,$popped and $popped)
- . "\}"/egm;
-
- if ($#flats > -1) {
- #print "Found " . scalar @longs . " items on line: '@flats'.\n";
-
- my ($long, $flat);
-
- foreach $long (@longs) {
- $flat = shift @flats;
- print "Found Input/Include: '$long'\n" if $DEBUG;
- # recurse to parse that tex file unless it's done already
-
- if (not exists $texfiles{$flat}) {
- if (! -r $long ) {
- if (-r $inputdir . $long) {
- $long = $inputdir . $long;
- } elsif (-r "$long.tex") {
- $long .= '.tex';
- }
- }
- $texfiles{$flat} = $long;
- my $newcontents = parseTeX($long, basedir($long), $flat, $level + 1); #later
- if ( $onetex ) {
- # If specified, expand inclusion directives
- die "Failed to find input/include to expand for '$flat'!\n"
- if (! ( $contents =~
- s/\\(input|include) \{ \Q$flat\E \}
- (?{ print "===Found \\$1\{$flat\} to expand.\n" if $DEBUG; })
- / ($1 eq 'include' ? "\\clearpage\n" : '') . "$newcontents"/gxem ) );
- }
- }
- }
- }
-
- #print "Writing to \"$outfile\"\n" .
- # "----------------------------------------\n" .
- # "$contents\n" .
- # "----------------------------------------\n";
-
- if (! $onetex || $level == 0) { # do output at zero recurse level
- # open flat output file
- open my $COPY, ">$outfile" or die "Cannot write file $outfile\n";
-
- # write to flat copy
- print $COPY $contents;
-
- close $COPY;
- } else {
- return $contents;
- }
-}
-
-# Look for file to copy
-sub seekfile {
- my ($file, $dest, $exts, $dirs) = @_;
- my @exts = @$exts;
- my @dirs = @$dirs;
-
- OUT: foreach my $dir (@dirs) {
- foreach my $ext (@exts) {
- my $tryfile = "$dir$file$ext";
- if (-r $tryfile) {
- # add the extension to $dest only if it hasn't have any dots
- #(! ($dest =~ /\./)) ? $ext : ""; => better not to have this
- my $dext = $ext;
-
- if (system("cp $tryfile $outputdir/$dest$dext") != 0) {
- die "Cannot copy $tryfile!\n";
- }
- # If we found it, then get out of the loop
- print "Copied: '$tryfile' (ext: $ext) -> '$dest$dext'\n" if $DEBUG;
- last OUT;
- }
- }
- }
-}
-
-# Return everything after the last /
-sub popfile {
- my $file = shift (@_);
-
- my @a = split /\//, $file;
-
- #print "Popping $file... split: @a ($#a), pop: " . pop(@a) . "\n";
- pop @a;
-}
-
-# Make a new file by flattening directory names
-sub flattenfilename {
- local $_ = shift;
-
- # convert slashes to pluses, dots to Xs
- tr|/|+|;
- tr|\.|X|;
-
- # add a unique number at the beginning so files don't start with a
- # dot
- $_ = sprintf("%03d_", ++$::filecount) . "$_";
-
- print "===Flattened file to '$_'\n" if $DEBUG;
-
- return $_;
-}
-
-sub basedir {
- my $file = shift (@_);
-
- my @a = split /\//, $file;
-
- #print "Popping $file... split: @a ($#a), pop: " . pop(@a) . "\n";
- pop @a; # remove file part
- my $basedir = join('/', @a); # combine the rest with /'s
- $basedir .= '/' if (! $basedir =~ /^$/); # add a trailing / if not empty
- $basedir;
-}
-
-# get the bibliography files
-sub replacebibs {
- my ($contentsref, $inputdir) = @_;
- #my $contents = $$contentsref;
- my $popped;
-
- #print "bib contents: $contents\n";
-
- local @::flats = ();
- local @::longs = ();
- local @::refs;
-
- $" = ','; # set list item separator
- # search for \bibliography statements
- $$contentsref =~
- s/\\bibliography(\[[^\]]*\])? {
- (?{ @::refs = (); #print "Found bibliography!\n"; #initialize ref list
- }) (?: \s* ([^}, ]+)(?=[,}]),?
- (?{ # for each word do:
- #local (@_flats, @_longs, @_refs);
- #print "Word: \"$+\", ";
- $popped = flattenfilename($+); push @::longs, $+;
- push @::flats,$popped; push @::refs, $popped;
- }) )+ \s* }
- (?{ #print "\n+++ $#::flats; $#::refs; $#::longs\n";
- #push @::flats, @_flats; push @longs, @_longs; push @refs, @_refs;
- #print "Refs: @::refs\n";
- })/"\\bibliography" . ($1 || "") . "{@::refs}"/egmx;# &&
- #print "bib contents: $$contentsref\n";
- #print "\n*** $#::flats; $#::refs; $#::longs\n";
- $" = ' '; # restore list item separator
-
- if ($#::flats > -1) {
- #print "Found " . scalar @::longs . " items on line: '@::flats'.\n";
-
- my ($long, $flat);
-
- foreach $long (@::longs) {
- $flat = shift @::flats;
- print "Found bib. file: '$long'\n" if $DEBUG;
- # recurse to parse that tex file unless it's done already
-
- # convert LyX directory dots
- $long =~ s/\\lyxdot /./g;
-
- seekfile($long, "$flat", [".bib"],
- ["", "$inputdir"]);
- }
- }
-}
diff --git a/Build/source/texk/texlive/linked_scripts/texdoc/texdoc.tlu b/Build/source/texk/texlive/linked_scripts/texdoc/texdoc.tlu
deleted file mode 100755
index e16f2e4eb1a..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texdoc/texdoc.tlu
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env texlua
-
--- texdoc.tlu: the main program of texdoc
---
--- The TeX Live Team, GPLv3, see texdoclib.tlu for details
-
--- Note: we keep this file small as much as possible so that make it easier
--- to install a new version of texdoc in TEXMFHOME.
-
-local lfs = require 'lfs'
-local kpse = require 'kpse'
-
--- setup kpse library
-kpse.set_program_name(arg[-1], 'texdoc')
-
--- get realpath of this file
-local function realpath(p)
- if os.type == 'unix' then
- local e = os.execute('which realpath >/dev/null 2>&1')
- if e == 0 then
- local h = io.popen(string.format("realpath '%s'", p))
- local r = h:read('*a')
- h:close()
- return r:gsub('\n$', '')
- end
- end
- return ''
-end
-local file = realpath(arg[0])
-
--- if the file is not in TEXMFMAIN, set temporal TEXMFAUXTREES and TEXMFDIST
-local texmf = file:match('^(.*/texmf[^/]*)/scripts/texdoc/texdoc.tlu$')
-if texmf ~= nil then
- if texmf ~= kpse.var_value('TEXMFMAIN') then
- io.stderr:write('Info: ' ..
- 'Running Texdoc not installed in the current TEXMFMAIN.\n')
- os.setenv('TEXMFAUXTREES', texmf .. ',')
- os.setenv('TEXMFDIST', ',')
- end
-end
-
--- load the library and execute
-local texdoc = require 'texdoclib'
-assert(texdoc.cli, 'Internal error: Texdoc is not installed properly.')
-texdoc.cli.exec()
-
--- vim: ft=lua:
diff --git a/Build/source/texk/texlive/linked_scripts/texfot/texfot.pl b/Build/source/texk/texlive/linked_scripts/texfot/texfot.pl
deleted file mode 100755
index e49d5f1efc9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texfot/texfot.pl
+++ /dev/null
@@ -1,422 +0,0 @@
-#!/usr/bin/env perl
-# $Id: texfot,v 1.40 2020/03/10 22:35:15 karl Exp $
-# Invoke a TeX command, filtering all but interesting terminal output;
-# do not look at the log or check any output files.
-# Exit status is that of the subprogram.
-# Tee the complete (unfiltered) standard output and standard error to
-# (by default) /tmp/fot.
-#
-# Public domain. Originally written 2014 by Karl Berry.
-
-my $ident = '$Id: texfot,v 1.40 2020/03/10 22:35:15 karl Exp $';
-(my $prg = $0) =~ s,^.*/,,;
-select STDERR; $| = 1; # no buffering
-select STDOUT; $| = 1;
-
-use IPC::Open3; # control what happens with stderr from the child.
-use IO::File; # use new_tmpfile for that stderr.
-
-# require_order because we don't want getopt to permute anything;
-# arguments to the tex invocation must remain in order, not handled by us.
-use Getopt::Long qw(:config require_order);
-use Pod::Usage;
-
-my $opt_debug = 0;
-my @opt_ignore = ();
-my $opt_interactive = 0;
-my $opt_quiet = 0;
-my $opt_stderr = 1;
-my $opt_tee = ($ENV{"TMPDIR"} || "/tmp") . "/fot";
-my $opt_version = 0;
-my $opt_help = 0;
-
-exit (&main ());
-
-
-#
-sub main {
- my $ret = GetOptions (
- "debug!" => \$opt_debug,
- "ignore=s" => \@opt_ignore,
- "interactive!" => \$opt_interactive,
- "quiet!" => \$opt_quiet,
- "stderr!" => \$opt_stderr,
- "tee=s" => \$opt_tee,
- "version" => \$opt_version,
- "help|?" => \$opt_help) || pod2usage (2);
-
- # --help, --version
- pod2usage ("-exitstatus" => 0, "-verbose" => 2)
- if $opt_help;
- #
- if ($opt_version) {
- print "$ident\n";
- return 0;
- }
-
- die "$prg: missing TeX command, i.e., a non-option argument\n"
- . "Try --help if you need it."
- if ! @ARGV;
-
- # guess we're going to run something. typically no interaction.
- close (STDIN) unless $opt_interactive;
-
- local *FOTTMP;
- $FOTTMP = ">$opt_tee";
- open (FOTTMP) || die "$prg: aborting, open($FOTTMP) failed: $!";
-
- # We need to separate stderr from stdout. Otherwise they are randomly
- # merged, not always at line breaks, hence we can lose useful messages.
- print "$0: invoking: @ARGV\n" unless $opt_quiet;
-
- # In order to avoid deadlock when there is lots of stuff on stderr,
- # we must write it to a temporary file
- # http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command
- local *TEXERR = IO::File->new_tmpfile
- || die "IO::File->new_tmpfile failed: $!";
-
- # But we can process stdout as it comes.
- local *TEXOUT;
- my $pid = open3 (undef, \*TEXOUT, ">&TEXERR", @ARGV)
- || die "$prg: fork(TeX) failed: $! [cmd=@ARGV]\n";
- &debug ("open3() returned pid $pid [cmd=@ARGV]");
-
- # It's not ideal to read all of stdout and then all of stderr; it would
- # be better to intermix them in the original order of child output.
- # But this is simpler than other ways of avoiding possible deadlock (such
- # as select, sysread, etc.).
- &debug ("processing stdout from child");
- &process_output (\*TEXOUT, "");
-
- # Be sure everything is drained.
- &debug ("starting waitpid() for $pid") ;
- waitpid ($pid, 0) || die "$prog: waitpid($pid) failed: $!\n";
- my $child_exit_status = $? >> 8;
- &debug ("child exit status = $exit_status\n");
-
- &debug ("processing stderr from child");
- seek (TEXERR, 0, 0) || warn "seek(stderr) failed: $!";
- &process_output (\*TEXERR, "[stderr] ");
- close (TEXERR) || warn "close(stderr tmpfile) failed: $!";
-
- return $child_exit_status;
-}
-
-
-
-# Read filehandle $FH, printing lines that we want to stdout,
-# prefixed by $PREFIX.
-# If $PREFIX is null (happens for processing stdout), omit lines by default;
-# if $PREFIX is non-null (processing stderr), print lines by default.
-#
-sub process_output {
- my ($fh,$prefix) = @_;
-
- my $print_next = 0;
- LINE: while (<$fh>) {
- my $line = $_;
- print FOTTMP $line; # tee everything
-
- warn "\n" if $opt_debug; # get blank line without texfot: prefix
- &debug ("looking at line: $_");
-
- &debug ("checking if have print_next (= $print_next)\n");
- if ($print_next) {
- &debug (" printing next ($print_next)\n");
- print $prefix;
- print $line;
- $print_next = 0;
- next;
- }
-
- &debug ("checking ignores\n");
- next if /^(
- LaTeX\ Warning:\ You\ have\ requested\ package
- |LaTeX\ Font\ Warning:\ Some\ font\ shapes
- |LaTeX\ Font\ Warning:\ Size\ substitutions
- |Package\ caption\ Warning:\ Un(supported|known)\ document\ class
- |Package\ fixltx2e\ Warning:\ fixltx2e\ is\ not\ required
- |Package\ layouts\ Warning:\ Layout\ scale
- |Package\ frenchb?\.ldf\ Warning:\ (Figures|The\ definition)
- |\*\*\*\ Reloading\ Xunicode\ for\ encoding # spurious ***
- |This\ is\ `?(epsf\.tex|.*\.sty|TAP) # so what
- |pdfTeX\ warning:.*inclusion:\ fou #nd PDF version ...
- |pdfTeX\ warning:.*inclusion:\ mul #tiple pdfs with page group
- |libpng\ warning:\ iCCP:\ Not\ recognizing
- |!\ $
- )/x;
-
- # don't anchor user ignores, leave it up to them.
- for my $user_ignore (@opt_ignore) {
- &debug ("checking user ignore '$user_ignore'\n");
- next LINE if /${user_ignore}/;
- }
-
- &debug ("checking for print_next\n");
- if (/^(
- .*?:[0-9]+: # usual file:lineno: form
- |! # usual ! form
- |>\ [^<] # from \show..., but not "> <img.whatever"
- |.*pdfTeX\ warning # pdftex complaints often cross lines
- |LaTeX\ Font\ Warning:\ Font\ shape
- |Package\ hyperref\ Warning:\ Token\ not\ allowed
- |removed\ on\ input\ line # hyperref
- |Runaway\ argument
- )/x) {
- &debug (" found print_next ($1)\n");
- print $prefix;
- print $line;
- $print_next = 1;
- next;
- }
-
- &debug ("checking for showing\n");
- if (/^(
- This\ is
- |Output\ written
- |No\ pages\ of\ output
- |\(.*end\ occurred\ inside\ a\ group
- |(Und|Ov)erfull
- |(LaTeX|Package|Class).*(Error|Warning)
- |.*Citation.*undefined
- |.*\ Error # as in \Url Error ->...
- |Missing\ character: # good to show (need \tracinglostchars=1)
- |\\endL.*problem # XeTeX?
- |\*\*\*\s # *** from some packages or subprograms
- |l\.[0-9]+\ # line number marking
- |all\ text\ was\ ignored\ after\ line
- |.*Fatal\ error
- |.*for\ symbol.*on\ input\ line
- )/x) {
- &debug (" matched for showing ($1)\n");
- print $prefix;
- print $line;
- next;
- }
-
- &debug ("done with all checks\n");
-
- if ($prefix && $opt_stderr) {
- &debug ("prefix (stderr), showing line by default: $_");
- print $prefix;
- print $line;
- } else {
- &debug ("no prefix (stdout) or no stderr, ignoring line by default: $_");
- }
- }
-}
-
-
-sub debug { warn ("$prg: ", @_) if $opt_debug; }
-
-
-__END__
-
-=head1 NAME
-
-texfot - run TeX, filtering online transcript for interesting messages
-
-=head1 SYNOPSIS
-
-texfot [I<option>]... I<texcmd> [I<texarg>...]
-
-=head1 DESCRIPTION
-
-C<texfot> invokes I<texcmd> with the given I<texarg> arguments,
-filtering the online output for ``interesting'' messages. Its exit
-value is that of I<texcmd>. Examples:
-
- # Sample basic invocation:
- texfot pdflatex file.tex
-
- # Ordinarily all output is copied to /tmp/fot before filtering,
- # but that can be omitted:
- texfot --tee=/dev/null lualatex file.tex
-
- # Example of more complex engine invocation:
- texfot xelatex --recorder '\nonstopmode\input file'
-
-Aside from its own options, described below, C<texfot> just runs the
-given command with the given arguments (same approach to command line
-syntax as C<env>, C<nice>, C<time>, C<timeout>, etc.). Thus, C<texfot>
-works with any engine and any command line options.
-
-C<texfot> does not look at the log file or any other possible output
-file(s); it only looks at the standard output and standard error from
-the command. stdout is processed first, then stderr. Lines from stderr
-have an identifying prefix. C<texfot> writes all accepted lines to its
-stdout.
-
-The messages shown are intended to be those which likely need action by
-the author: error messages, overfull and underfull boxes, undefined
-citations, missing characters from fonts, etc.
-
-=head1 FLOW OF OPERATION
-
-Here is the order in which lines of output are checked:
-
-=over 4
-
-=item 1.
-
-If the ``next line'' needs to be printed (see below), print it.
-
-=item 2.
-
-Otherwise, if the line matches the built-in list of regexps to ignore,
-or any user-supplied list of regexps to ignore (given with C<--ignore>,
-see below), in that order, ignore it.
-
-=item 3.
-
-Otherwise, if the line matches the list of regexps for which the next
-line (two lines in all) should be shown, show this line and set the
-``next line'' flag for the next time around the loop. Examples are the
-common C<!> and C<filename:lineno:> error messages, which are generally
-followed by a line with specific detail about the error.
-
-=item 4.
-
-Otherwise, if the line matches the list of regexps to show, show it.
-
-=item 5.
-
-Otherwise, the default: if the line came from stdout, ignore it; if the
-line came from stderr, print it (to stdout). This distinction is made
-because TeX engines write relatively few messages to stderr, and it's
-likely that any such should be considered.
-
-It would be easy to add more options to allow for user additions to the
-various regex lists, if that ever seems useful. Or email me (see end).
-
-=back
-
-Once a particular check matches, the program moves on to process the
-next line.
-
-Don't hesitate to peruse the source to the script, which is essentially
-a straightforward loop matching against the different lists as above.
-You can see the exact regexps being matched in the different categories
-in the source.
-
-Incidentally, although nothing in this basic operation is specific to
-TeX engines, all the regular expressions included in the program are
-specific to TeX. So in practice the program isn't useful except with
-TeX engines, although it would be easy enough to adapt it (if there was
-anything else as verbose as TeX to make that useful).
-
-=head1 OPTIONS
-
-The following are the options to C<texfot> itself (not the TeX engine
-being invoked; consult the TeX documentation or the engine's C<--help>
-output for that).
-
-The first non-option terminates C<texfot>'s option parsing, and the
-remainder of the command line is invoked as the TeX command, without
-further parsing. For example, C<texfot --debug tex
---debug> will output debugging information from both C<texfot> and
-C<tex>.
-
-Options may start with either - or --, and may be unambiguously
-abbreviated. It is best to use the full option name in scripts, though,
-to avoid possible collisions with new options in the future.
-
-=over 4
-
-=item C<--debug>
-
-=item C<--no-debug>
-
-Output (or not) what is being done on standard error. Off by default.
-
-=item C<--ignore> I<regexp>
-
-Ignore lines in the TeX output matching (Perl) I<regexp>. Can be
-repeated. Adds to the default set of ignore regexps rather than
-replacing. These regexps are not automatically anchored (or otherwise
-altered), simply used as-is.
-
-=item C<--interactive>
-
-=item C<--no-interactive>
-
-By default, standard input to the TeX process is closed so that TeX's
-interactive mode (waiting for input upon error, the C<*> prompt, etc.)
-is never entered. Giving C<--interactive> allows interaction to happen.
-
-=item C<--quiet>
-
-=item C<--no-quiet>
-
-By default, the TeX command being invoked is reported on standard output.
-C<--quiet> omits that reporting. To get a completely silent run,
-redirect standard output: S<C<texfot ... E<gt>/dev/null>>. (The only
-messages to standard error should be errors from C<texfot> itself, so it
-shouldn't be necessary to redirect that, but of course that can be done
-as well.)
-
-=item C<--stderr>
-
-=item C<--no-stderr>
-
-The default is for C<texfot> to report everything written to stderr by
-the TeX command (on stdout). C<--no-stderr> omits that reporting.
-(Some programs, C<dvisvgm> is one, can be rather verbose on stderr.)
-
-=item C<--tee> I<file>
-
-By default, the output being filtered is C<tee>-ed, before filtering, to
-C<$TMPDIR/fot> (C</tmp/fot> if C<TMPDIR> is not set), to make it easy to
-check the full output when the filtering seems suspect. This option
-allows specifying a different file. Use S<C<--tee /dev/null>> if you don't
-want the original output at all.
-
-=item C<--version>
-
-Output version information and exit successfully.
-
-=item C<--help>
-
-Display this help and exit successfully.
-
-=back
-
-=head1 RATIONALE
-
-I wrote this because, in my work as a TUGboat editor
-(L<http://tug.org/TUGboat>, journal submissions always welcome!), I run
-and rerun many documents, many times each. It was too easy to lose
-warnings I needed to see in the mass of unvarying and uninteresting
-output from TeX, such as style files being read and fonts being used. I
-wanted to see all and only those messages which needed some action by
-me.
-
-I found some other programs of a similar nature, the LaTeX package
-C<silence>, and plenty of other (La)TeX wrappers, but it seemed none of
-them did what I wanted. Either they read the log file (I wanted the
-online output only), or they output more or less than I wanted, or they
-required invoking TeX differently (I wanted to keep my build process
-exactly the same, most critically the TeX invocation, which can get
-complicated). Hence I wrote this.
-
-Here are some keywords if you want to explore other options:
-texloganalyser, pydflatex, logfilter, latexmk, rubber, arara, and
-searching for C<log> at L<https://ctan.org/search>.
-
-C<texfot> is written in Perl, and runs on Unix, and does not work on
-Windows.
-
-The name comes from the C<trip.fot> and C<trap.fot> files that are part
-of Knuth's trip and trap torture tests, which record the online output
-from the programs. I am not sure what "fot" stands for in trip and
-trap, but I can pretend that it stands for "filter online transcript" in
-the present S<case :).>
-
-=head1 AUTHORS AND COPYRIGHT
-
-This script and its documentation were written by Karl Berry and both
-are released to the public domain. Email C<karl@freefriends.org> with
-bug reports. It has no home page beyond the package on CTAN:
-L<https://ctan.org/pkg/texfot>.
-
-=cut
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/allcm.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/allcm.sh
deleted file mode 100755
index 945c7c88457..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/allcm.sh
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/sh
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-progname=`basename $0`
-tmpdir=${TMPDIR-${TEMP-${TMP-/tmp}}}/$progname.$$
-
-case "$progname" in
- allec)
- encoding=T1;;
- *)
- encoding=OT1;;
-esac
-
-case "$1" in
- -r)
- DVIPS=dvired
- shift
- ;;
- *)
- DVIPS=dvips
- ;;
-esac
-
-body()
-{
- cat <<-'eof'
- \pagestyle{empty}
- \parindent0in
- \hfuzz=\maxdimen
- \hbadness=10000
- \textheight9.5in
- \textwidth6.5in
- \newcommand{\myformula}{\sum a_{b_{c_d}} = c}
- \newcommand{\mytext}{text $\mathcal{\myformula}\mathrm{\myformula}
- \mathbf{\myformula}\mathsf{\myformula}\mathtt{\myformula}
- \mathnormal{\myformula}\mathit{\myformula}$}
-
- \newcommand{\TestSizes}{{%
- \tiny \mytext\scriptsize \mytext\footnotesize \mytext\small \mytext
- \normalsize \mytext
- \large \mytext\Large \mytext\LARGE \mytext\huge \mytext\Huge \mytext}}
- \newcommand{\TestRM}{rm-family: {\rmfamily\TestSizes}\newline}
- \newcommand{\TestSF}{sf-family: {\sffamily\TestSizes}\newline}
- \newcommand{\TestTT}{tt-family: {\ttfamily\TestSizes}\newline}
- \newcommand{\TestFamilies}{\TestRM\TestSF\TestTT\newline}
- \newcommand{\TestMD}{md-series: {\mdseries\TestFamilies}}
- \newcommand{\TestBF}{bf-series: {\bfseries\TestFamilies}}
- \newcommand{\TestSeries}{\TestBF\TestMD\par}
- \newcommand{\TestUP}{up-shape: {\upshape\TestSeries}\par}
- \newcommand{\TestIT}{it-shape: {\itshape\TestSeries}\par}
- \newcommand{\TestSL}{sl-shape: {\slshape\TestSeries}\par}
- \newcommand{\TestSC}{sc-shape: {\scshape\TestSeries}\par}
- \newcommand{\TestShapes}{\TestUP\TestIT\TestSL\TestSC}
- \begin{document}
- \TestShapes
- \end{document}
-eof
-}
-
-head()
-{
- echo '\documentclass['$1'pt]{article}'
- echo '\usepackage['$encoding']{fontenc}'
-}
-
-# before we create the tmpdir, set trap for cleanup
-trap '
- rm -rf $tmpdir
- exit 1
-' 1 2 3 7 13 15
-
-(umask 077; mkdir "$tmpdir") || {
- echo "$progname: failed to create temp directory." >&2
- exit 1
-}
-
-cd $tmpdir || exit 1
-echo >&2
-echo "---------------------------------------------------------------------" >&2
-echo ">>>>>>>>>>> Generating testfiles for 10pt, 11pt and 12pt. <<<<<<<<<<" >&2
-echo "---------------------------------------------------------------------" >&2
-head 10 > allcm10.tex
-head 11 > allcm11.tex
-head 12 > allcm12.tex
-body >> allcm10.tex
-body >> allcm11.tex
-body >> allcm12.tex
-
-echo >&2
-echo "---------------------------------------------------------------------" >&2
-echo ">>>>>>>>>>> Calling latex... <<<<<<<<<<" >&2
-echo "---------------------------------------------------------------------" >&2
-latex allcm10 >/dev/null
-latex allcm11 >/dev/null
-latex allcm12 >/dev/null
-
-echo >&2
-echo "---------------------------------------------------------------------" >&2
-echo ">>>>>>>>>>> Now, calling $DVIPS to make missing fonts... <<<<<<<<<<" >&2
-echo "---------------------------------------------------------------------" >&2
-$DVIPS ${1+"$@"} -V -f allcm10 > /dev/null
-$DVIPS ${1+"$@"} -V -f allcm11 > /dev/null
-$DVIPS ${1+"$@"} -V -f allcm12 > /dev/null
-
-cd /
-rm -rf $tmpdir
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/allneeded.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/allneeded.sh
deleted file mode 100755
index 15c62c84adb..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/allneeded.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-progname=`basename $0`
-dvired=false
-
-case $1 in
--r) DVIPS="dvips -x707"
- shift;;
-*) DVIPS=dvips;;
-esac
-
-case $# in
-0) echo "Usage: $progname [-r] files ..." >&2
- exit ;;
-esac
-
-findopt=
-dvipsopt=
-
-for i
-do
- if [ -f $i ] || [ -d $i ]; then
- findopt="$findopt $i"
- else
- dvipsopt="$dvipsopt $i"
- fi
-done
-
-find $findopt -name \*.dvi -type f -print |
- while true; do
- read i
- test -z "$i" && exit
- echo "processing file '$i' ..."
- $DVIPS $dvipsopt -f "$i" >/dev/null
- echo
- done
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/dvi2fax.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/dvi2fax.sh
deleted file mode 100755
index fdfa83211eb..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/dvi2fax.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-# options for dvips are passwd down
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-progname=`basename "$0"`
-help()
-{
- echo "Usage: $progname [-hi|-lo] file[.dvi] [options for dvips]"
- echo " -hi: use high fax resolution (204x196) (default)"
- echo " -lo: use low fax resolution (204x98)"
- echo
- echo "Example: $progname foo -l 2"
-}
-
-dvipsconf=dfaxhigh; gsdev=dfaxhigh
-case $1 in
- -hi) gsdev=dfaxhigh; shift;;
- -lo) gsdev=dfaxlow; shift;;
-esac
-
-case $# in
- 0) help >&2
- exit 1
- ;;
-esac
-
-NAME=`basename "$1" .dvi`
-dvips "$@" -P$dvipsconf -f |
- gs -q -dSAFER -sDEVICE=$gsdev -sOutputFile="$NAME-%03d.fax" -sNOPAUSE -
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/dvired.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/dvired.sh
deleted file mode 100755
index 4eb3586119d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/dvired.sh
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/bin/sh
-#==============================================================================
-# Version: 0.3
-# Module: dvired
-# Purpose: Translate dvi-file into postscript with reduced output size.
-# Two logical pages will be put on onto each physical sheet of
-# paper.
-# System: Linux. UNIX(tm) systems may work as well :-)
-# Requires: pstops (http://www.dcs.ed.ac.uk/home/ajcd/psutils/), dvips
-# Created: 19.11.1992
-# Last Change: 13.08.1999
-# Language: sh
-# Author: Thomas Esser
-# Address: te@dbs.uni-hannover.de
-# Copyright: (c) 1994, 1999 by Thomas Esser
-# Copying: GNU GENERAL PUBLIC LICENSE
-#==============================================================================
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-help()
-{
- cat <<eof
-
-Usage: dvired [options] file
-
-This programm behaves like dvips, execpt fot the fact that two logical
-pages will be put on onto each physical sheet of paper.
-
-For options see dvips(1). This program only interprets the options
--o, -P and -f. All other options will directly be passed to dvips.
-
-If your paper is not in A4 format, you need to adjust the dimensions
-in this program.
-
-Examples: (it is assumed that the PRINTER-variable is set)
- dvired -Plw foo send output to printer lw
- dvired -o foo.ps foo send output to file foo.ps
- dvired -pp4-7 foo send 4 output-pages to printer
- dvired foo -f | ghostview - preview output with ghostview
-eof
-}
-
-case $# in
-0) help ; exit 1 ; ;;
-esac
-
-# This will work for A4 paper.
-paper=a4 ; pstopsopt='2:0(7.44mm,7.44mm)+1(7.44mm,-141.06mm)'
-
-# The following are *UNTESTED*. Please let me know whether they work
-# or not, if you can test them.
-#paper=a3 ; pstopsopt='2:0(7.44mm,7.44mm)+1(7.44mm,-202.56mm)'
-#paper=letter ; pstopsopt='2:0(7.44mm,7.44mm)+1(7.44mm,-132.26mm)'
-#paper=legal ; pstopsopt='2:0(7.44mm,7.44mm)+1(7.44mm,-170.36mm)'
-#paper=ledger ; pstopsopt='2:0(7.44mm,7.44mm)+1(7.44mm,-132.26mm)'
-#paper=tabloid ; pstopsopt='2:0(7.44mm,7.44mm)+1(7.44mm,-208.46mm)'
-
-of=""
-lpr_opt=""
-
-case "$PRINTER" in
-"") dvips_pre="" ;;
-*) dvips_pre="-P$PRINTER" ;;
-esac
-
-dvips_pre="$dvips_pre -t $paper -t landscape"
-
-while [ ! -z "$1" ] ; do
- case $1 in
- -P) of="" ; dvips_pre="$dvips_pre -P$2" ; lpr_opt="-P$2"
- shift ;;
- -P*) of="" ; dvips_pre="$dvips_pre $1" ; lpr_opt="$1" ;;
- -o) of="$2"
- shift ;;
- -o*) of="`echo $1| sed 's/..//'`" ;;
- -f) of="-" ;;
- *) opt="$opt $1"
- esac
- shift
-done
-
-case "$of" in
-"") dvips -x707 $dvips_pre $opt -f | pstops -q $pstopsopt | lpr $lpr_opt
- ;;
-"-") dvips -x707 $dvips_pre $opt -f | pstops -q $pstopsopt
- ;;
-*) dvips -x707 $dvips_pre $opt -f | pstops -q $pstopsopt > "$of"
- ;;
-esac
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/e2pall.pl b/Build/source/texk/texlive/linked_scripts/texlive-extra/e2pall.pl
deleted file mode 100755
index 2997f8b1102..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/e2pall.pl
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env perl
-
-# Author: Jody Klymak <jklymak@apl.washington.edu>, publisted by a posting
-# to the pdftex mailinglist.
-
-# recursively finds all your eps files. Looks down \input{fname}.
-# CAVEATS:
-# 1) cannot handle \input{fname} split over more than one line.
-# 1.5) cannot handle multiple \input{} or \includegraphics{} on one line.
-# 2) Must be run from same directory as the Latex file.
-# 3) Does not look down $TEXINPUTS or anything fancy like that...
-# 4) Handling of \include is untested (though I guess its trivial)
-# 5) Assumes *all* your graphics inclusions are [e]ps. But don't
-# fret, because if they are not epstopdf dies anyhow....
-# 6) Does not distinguish between percent (\%) and comment (%).
-
-# Changelog:
-# 20030103 -- Lachlan Andrew <lha@users.sourceforge.net>
-# * Only append '.tex' if $fname doesn't exist.
-# * Correctly handle lines with '}' after the \includegraphics{}
-# * Allow multiple extensions for graphics files. .eps -> .ps -> none
-# (Should try them in the same order as \includegraphics does
-# -- given by \DeclareGraphicsExtensions{}?)
-# * Allow \include the same way as \input
-# * Allow \includegraphics{} to be split over multiple lines
-# * Check that commands begin with '\', and allow spaces before arguments
-
-# EDIT these two lines for your system....
-
-$Eps2PdfCom = "epstopdf";
-$ThisFunCom = "e2pall";
-
-$fname=$ARGV[0];
-
-# check for a *.tex at the end...
-if ((-f "$fname")=="" && $fname !~ /.tex$/){
- $fname = "$fname.tex";
-}
-
-open(TEXFILE,$fname) or die "Cannot open file $fname";
-# print "Finding *.eps files in $fname\n";
-
-$seekingArg = 0;
-while($line=<TEXFILE>){
- # truncate $line after % sign....
- $line=~s/%.*//;
- # check for /input....
- if ($line=~/\\input *{([^}]*)}/){
- print `$ThisFunCom $1`;
- }
- # check for /include....
- if ($line=~/\\include *{([^}]*)}/){
- print `$ThisFunCom $1`;
- }
-
- $base = "";
- if ($line=~/\\includegraphics.*{([^}]*)}/){
- $base = $1;
- }
- elsif ($seekingArg==1 && ($line=~/{([^}]*)}/)){
- $base = $1;
- }
- elsif ($line=~/\\includegraphics/){
- $seekingArg = 1;
- }
-
- if ($base ne "") {
- $seekingArg = 0;
- if ((-f "$base.eps")!="") {
- $srcfile = "$base.eps";
- }
- elsif ((-f "$base.ps")!=""){
- $srcfile = "$base.ps";
- }
- else {
- $srcfile = $base;
- }
- # check that the [e]ps version is newer than the pdf version....
- if ((-M "$base.pdf")=="" || (-M "$base.pdf") >= (-M "$srcfile")){
- print "Constructing \t $base.pdf from $srcfile\n";
- print `$Eps2PdfCom $srcfile`;
- }
- else{
- print "$base.pdf \t is up to date with $srcfile\n";
- }
-
- };
-}
-close(TEXFILE);
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/fontinst.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/fontinst.sh
deleted file mode 100755
index 7d1271517ad..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/fontinst.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-tex -progname=fontinst \&tex ${1+"$@"}
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/kpsetool.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/kpsetool.sh
deleted file mode 100755
index 463097fd4a9..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/kpsetool.sh
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/sh
-
-# kpsetool. Script to make teTeX-style kpsetool, kpsexpand and kpsepath
-# available. Web2C's kpsewhich offers a superset of the functionality.
-# For compatibilty with old versions of teTeX, this script provides the
-# old command line interface of kpsetool, kpsexpand and kpsepath. All the
-# real work is done inside Web2C's kpsewhich.
-# Thomas Esser <te@dbs.uni-hannover.de>, Mar 1997, public domain.
-
-export PATH
-
-usage="
-Usage: kpsexpand [options] string
-Usage: kpsetool -w [options] pathtype filename
-Usage: kpsepath [options] pathtype
-
-Valid options are the following:
- -n progname : pretend to be progname to kpathsea
- -m mode : set Metafont mode
- -w : locate files (similar to kpsewhich)
- -p : act like kpsepath
- -v : act like kpsexpand
-
-Valid pathtypes are:
- gf : generic font bitmap
- pk : packed bitmap font
- base : Metafont memory dump
- bib : BibTeX bibliography source
- bst : BibTeX style files
- cnf : Kpathsea runtime configuration files
- fmt : TeX memory dump
- mem : MetaPost memory dump
- mf : Metafont source
- mfpool : Metafont program strings
- mp : MetaPost source
- mppool : MetaPost program strings
- mpsupport : MetaPost support files
- pict : Other kinds of figures
- tex : TeX source
- texpool : TeX program strings
- tfm : TeX font metrics
- vf : virtual font
- dvips_config : dvips config files
- dvips_header : dvips header files
- troff_font : troff fonts
-"
-
-action=kpsexpand
-case $0 in
- */kpsewhich) action=kpsewhich;;
- */kpsepath) action=kpsepath;;
-esac
-
-progname=`echo $0 | sed 's@.*/@@'`
-flags=''
-
-while true; do
- case x"$1" in
- x-n)
- if test $# = 1; then
- echo "$progname: missing argument for -n."
- echo "$usage"; exit 1
- else
- flags="$flags -progname=$2"; shift; shift
- fi;;
- x-m)
- if test $# = 1; then
- echo "$progname: missing argument for -m."
- echo "$usage"; exit 1
- else
- flags="$flags -mode=$2"; shift; shift
- fi;;
- x-w) action=kpsewhich; shift;;
- x-p) action=kpsepath; shift;;
- x-v) action=kpsexpand; shift;;
- *) break;;
- esac
-done
-
-case "$action" in
- kpsewhich|kpsepath)
- case "$1" in
- gf) format='gf';;
- pk) format='pk';;
- base) format='.base';;
- bib) format='.bib';;
- bst) format='.bst';;
- cnf) format='.cnf';;
- fmt) format='.fmt';;
- mem) format='.mem';;
- mf) format='.mf';;
- mfpool) format='.pool';;
- mp) format='.mp';;
- mppool) format='.pool';;
- mpsupport) format='MetaPost support';;
- pict) format='.eps';;
- tex) format='.tex';;
- texpool) format='.pool';;
- tfm) format='.tfm';;
- vf) format='.vf';;
- dvips_config) format='dvips config';;
- dvips_header) format='.pro';;
- troff_font) format='Troff fonts';;
- *) echo "$progname: $1: unknown format"; echo "$usage"; exit 1;;
- esac
- shift;;
-esac
-
-case "$action" in
- kpsewhich)
- test $# = 1 || { echo "$progname: missing filename"; echo "$usage"; exit 1; }
- kpsewhich $flags -format="$format" "$1";;
- kpsepath)
- kpsewhich $flags -show-path="$format";;
- kpsexpand)
- test $# = 1 || { echo "$progname: missing string"; echo "$usage"; exit 1; }
- kpsewhich $flags -expand-var="$1";;
-esac
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/kpsewhere.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/kpsewhere.sh
deleted file mode 100755
index 51088ee80d6..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/kpsewhere.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-#
-# Thomas Esser, Hans Fredrik Nordhaug, 2003, 2004.
-# Public domain.
-#
-# kpsewhere is an extension to kpsewhich (as where is for which in tcsh).
-# The intention is to provide a way to check for conflicts/shadowed
-# files.
-#
-# Original version by Hans Fredrik Nordhaug <hans.fredrik@nordhaug.no>
-#
-# Bugs / limitations:
-# conflicts/shadowed files whithin each texmf tree are not found.
-#
-
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-export PATH
-
-help='Usage: kpsewhere [OPTION]... [FILENAME]...
- Expanding kpsewhich to iterate over each texmf tree listed in $TEXMF
- separately.
-
- See kpsewhich for help on options.
-
- --help show this help'
-
-options=
-while
- case $1 in
- -h|-help|--help)
- echo "$help" >&2
- exit 0;;
- -*) options="${options} '${1}'";;
- *) break;;
- esac
-do shift; done
-
-case $# in
- 0)
- echo "$help" >&2
- exit 1
- ;;
-esac
-
-IFS=':'
-for file
-do
- for path in `kpsewhich --expand-path='$TEXMF'`
- do
- eval TEXMF=\$path kpsewhich $options \"\$file\"
- done
-done
-exit 0
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/ps2frag.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/ps2frag.sh
deleted file mode 100755
index b8e673be087..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/ps2frag.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-tty -s && {
- echo
- echo "Warning: the ps2frag script is not needed with this version of psfrag."
- echo "Please read the manpage ps2frag(1) and the documentation of the"
- echo "psfrag package."
- echo
-} >&2
-
-exit 0
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/pslatex.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/pslatex.sh
deleted file mode 100755
index 4badef0ec12..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/pslatex.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-# Copyright 1994 David Carlisle
-# This file may be redistributed and/or modified under the terms of the
-# LaTeX Project Public License distributed from CTAN archives in directory
-# macros/latex/base/lppl.txt; either version 1 of the License, or (at
-# your option) any later version.
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-# we want to be able to use options to latex:
-while :; do
- case $1 in
- -*)
- latexoptions="$latexoptions \"$1\""
- shift;;
- *)
- break;;
- esac
-done
-
-echo
-echo "*************************************"
-echo "* Using LaTeX, with pslatex package *"
-echo "*************************************"
-echo
-
-# messing around with \PSLATEXTMP is for AUCTeX which calls
-# documents via latex \nonstopmode \input{file}
-
-latex $latexoptions \
- "\AtBeginDocument{\RequirePackage{pslatex}}"\
- "\def\PSLATEXTMP{\futurelet\PSLATEXTMP\PSLATEXTMPB}"\
- "\def\PSLATEXTMPB{\ifx\PSLATEXTMP\nonstopmode\else\input\fi}"\
- "\PSLATEXTMP" ${1+"$@"}
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/rubibtex.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/rubibtex.sh
deleted file mode 100755
index 373e6e1194d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/rubibtex.sh
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/bin/sh
-
-# rubibtex, based on the original version contained in the t2 bundle.
-# Thomas Esser, Public Domain.
-
-progname=rubibtex
-tmpdir=${TMPDIR-${TEMP-${TMP-/tmp}}}/$progname.$$
-job=$1
-backup="$tmpdir/orig.aux"
-
-case $job in
- "")
- echo "usage: $progname file" >&2
- exit 1
-esac
-
-if test ! -f "$job.aux"; then
- echo "$progname: file \`$job.aux' does not exist." >&2
- exit 1
-fi
-
-trap '
- rm -rf "$tmpdir"
- exit 1
-' 1 2 3 7 13 15
-(umask 077; mkdir "$tmpdir") \
- || { echo "$progname: could not create directory \`$tmpdir'" >&2; exit 1; }
-
-cat <"$job.aux" >"$backup" || {
- echo "$progname: could not create backup of file \`$job.aux' as \`$backup'." >&2
- rm -rf "$tmpdir"
- exit 1
-}
-
-sed '
- /^\\citation/ {
- s/\\IeC {\\CYRA }/á/g
- s/\\IeC {\\CYRB }/â/g
- s/\\IeC {\\CYRV }/÷/g
- s/\\IeC {\\CYRG }/ç/g
- s/\\IeC {\\CYRD }/ä/g
- s/\\IeC {\\CYRE }/ĺ/g
- s/\\IeC {\\CYRYO }/ł/g
- s/\\IeC {\\CYRZH }/ö/g
- s/\\IeC {\\CYRZ }/ú/g
- s/\\IeC {\\CYRI }/é/g
- s/\\IeC {\\CYRISHRT }/ę/g
- s/\\IeC {\\CYRK }/ë/g
- s/\\IeC {\\CYRL }/ě/g
- s/\\IeC {\\CYRM }/í/g
- s/\\IeC {\\CYRN }/î/g
- s/\\IeC {\\CYRO }/ď/g
- s/\\IeC {\\CYRP }/đ/g
- s/\\IeC {\\CYRR }/ň/g
- s/\\IeC {\\CYRS }/ó/g
- s/\\IeC {\\CYRT }/ô/g
- s/\\IeC {\\CYRU }/ő/g
- s/\\IeC {\\CYRF }/ć/g
- s/\\IeC {\\CYRH }/č/g
- s/\\IeC {\\CYRC }/ă/g
- s/\\IeC {\\CYRCH }/ţ/g
- s/\\IeC {\\CYRSH }/ű/g
- s/\\IeC {\\CYRSHCH }/ý/g
- s/\\IeC {\\CYRHRDSN }/˙/g
- s/\\IeC {\\CYRERY }/ů/g
- s/\\IeC {\\CYRSFTSN }/ř/g
- s/\\IeC {\\CYREREV }/ü/g
- s/\\IeC {\\CYRYU }/ŕ/g
- s/\\IeC {\\CYRYA }/ń/g
- s/\\IeC {\\cyra }/Á/g
- s/\\IeC {\\cyrb }/Â/g
- s/\\IeC {\\cyrv }/×/g
- s/\\IeC {\\cyrg }/Ç/g
- s/\\IeC {\\cyrd }/Ä/g
- s/\\IeC {\\cyre }/Ĺ/g
- s/\\IeC {\\cyryo }/Ł/g
- s/\\IeC {\\cyrzh }/Ö/g
- s/\\IeC {\\cyrz }/Ú/g
- s/\\IeC {\\cyri }/É/g
- s/\\IeC {\\cyrishrt }/Ę/g
- s/\\IeC {\\cyrk }/Ë/g
- s/\\IeC {\\cyrl }/Ě/g
- s/\\IeC {\\cyrm }/Í/g
- s/\\IeC {\\cyrn }/Î/g
- s/\\IeC {\\cyro }/Ď/g
- s/\\IeC {\\cyrp }/Đ/g
- s/\\IeC {\\cyrr }/Ň/g
- s/\\IeC {\\cyrs }/Ó/g
- s/\\IeC {\\cyrt }/Ô/g
- s/\\IeC {\\cyru }/Ő/g
- s/\\IeC {\\cyrf }/Ć/g
- s/\\IeC {\\cyrh }/Č/g
- s/\\IeC {\\cyrc }/Ă/g
- s/\\IeC {\\cyrch }/Ţ/g
- s/\\IeC {\\cyrsh }/Ű/g
- s/\\IeC {\\cyrshch }/Ý/g
- s/\\IeC {\\cyrhrdsn }/ß/g
- s/\\IeC {\\cyrery }/Ů/g
- s/\\IeC {\\cyrsftsn }/Ř/g
- s/\\IeC {\\cyrerev }/Ü/g
- s/\\IeC {\\cyryu }/Ŕ/g
- s/\\IeC {\\cyrya }/Ń/g
- }
-' <"$backup" >"$job.aux"
-
-bibtex "$job"
-
-cat "$backup" > "$job.aux"
-rm -rf "$tmpdir"
-exit 0
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/rumakeindex.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/rumakeindex.sh
deleted file mode 100755
index b7b0c072729..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/rumakeindex.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/bin/sh
-
-BASE=`basename "$1" .idx`
-IDX=$BASE.idx
-IND=$BASE.ind
-ILG=$BASE.ilg
-
-sed '
-/^\\indexentry{/ {
-s/\\IeC {\\CYRA }/ľ/g
-s/\\IeC {\\cyra }/ż/g
-s/\\IeC {\\CYRB }/Ŕ/g
-s/\\IeC {\\cyrb }/Á/g
-s/\\IeC {\\CYRV }/Â/g
-s/\\IeC {\\cyrv }/Ă/g
-s/\\IeC {\\CYRG }/Ä/g
-s/\\IeC {\\cyrg }/Ĺ/g
-s/\\IeC {\\CYRD }/Ć/g
-s/\\IeC {\\cyrd }/Ç/g
-s/\\IeC {\\CYRE }/Č/g
-s/\\IeC {\\cyre }/É/g
-s/\\IeC {\\CYRYO }/Ę/g
-s/\\IeC {\\cyryo }/Ë/g
-s/\\IeC {\\CYRZH }/Ě/g
-s/\\IeC {\\cyrzh }/Í/g
-s/\\IeC {\\CYRZ }/Î/g
-s/\\IeC {\\cyrz }/Ď/g
-s/\\IeC {\\CYRI }/Đ/g
-s/\\IeC {\\cyri }/Ń/g
-s/\\IeC {\\CYRISHRT }/Ň/g
-s/\\IeC {\\cyrishrt }/Ó/g
-s/\\IeC {\\CYRK }/Ô/g
-s/\\IeC {\\cyrk }/Ő/g
-s/\\IeC {\\CYRL }/Ö/g
-s/\\IeC {\\cyrl }/×/g
-s/\\IeC {\\CYRM }/Ř/g
-s/\\IeC {\\cyrm }/Ů/g
-s/\\IeC {\\CYRN }/Ú/g
-s/\\IeC {\\cyrn }/Ű/g
-s/\\IeC {\\CYRO }/Ü/g
-s/\\IeC {\\cyro }/Ý/g
-s/\\IeC {\\CYRP }/Ţ/g
-s/\\IeC {\\cyrp }/ß/g
-s/\\IeC {\\CYRR }/ŕ/g
-s/\\IeC {\\cyrr }/á/g
-s/\\IeC {\\CYRS }/â/g
-s/\\IeC {\\cyrs }/ă/g
-s/\\IeC {\\CYRT }/ä/g
-s/\\IeC {\\cyrt }/ĺ/g
-s/\\IeC {\\CYRU }/ć/g
-s/\\IeC {\\cyru }/ç/g
-s/\\IeC {\\CYRF }/č/g
-s/\\IeC {\\cyrf }/é/g
-s/\\IeC {\\CYRH }/ę/g
-s/\\IeC {\\cyrh }/ë/g
-s/\\IeC {\\CYRC }/ě/g
-s/\\IeC {\\cyrc }/í/g
-s/\\IeC {\\CYRCH }/î/g
-s/\\IeC {\\cyrch }/ď/g
-s/\\IeC {\\CYRSH }/đ/g
-s/\\IeC {\\cyrsh }/ń/g
-s/\\IeC {\\CYRSHCH }/ň/g
-s/\\IeC {\\cyrshch }/ó/g
-s/\\IeC {\\CYRHRDSN }/ô/g
-s/\\IeC {\\cyrhrdsn }/ő/g
-s/\\IeC {\\CYRERY }/ö/g
-s/\\IeC {\\cyrery }/÷/g
-s/\\IeC {\\CYRSFTSN }/ř/g
-s/\\IeC {\\cyrsftsn }/ů/g
-s/\\IeC {\\CYREREV }/ú/g
-s/\\IeC {\\cyrerev }/ű/g
-s/\\IeC {\\CYRYU }/ü/g
-s/\\IeC {\\cyryu }/ý/g
-s/\\IeC {\\CYRYA }/ţ/g
-s/\\IeC {\\cyrya }/˙/g
-}' $IDX | makeindex -t $ILG | tr 'ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙' \
- 'áÁâÂ÷×çÇäÄĺĹłŁöÖúÚéÉęĘëËěĚíÍîÎďĎđĐňŇóÓôÔőŐćĆčČăĂţŢűŰýÝ˙ßůŮřŘüÜŕŔńŃ' > $IND
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig-dialog.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig-dialog.sh
deleted file mode 100755
index 449d2342d72..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig-dialog.sh
+++ /dev/null
@@ -1,496 +0,0 @@
-#!/bin/sh
-# $Id: texconfig-dialog.sh 53554 2020-01-26 23:58:37Z karl $
-# texconfig-dialog
-# Originally written by Thomas Esser. Public domain.
-# Now maintained as part of TeX Live; correspondence to tex-live@tug.org.
-
-# invoke the right shell:
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-# the version string
-version='$Id: texconfig-dialog.sh 53554 2020-01-26 23:58:37Z karl $'
-
-: ${PAGER=more}
-progname=texconfig-dialog
-tmpdir=${TMPDIR-${TEMP-${TMP-/tmp}}}/tcdtmp.$$
-log=$tmpdir/log
-tmpmenu=$tmpdir/tmpmenu
-needsCleanup=false
-
-###############################################################################
-# cleanup()
-# clean up the temp area and exit with proper exit status
-###############################################################################
-cleanup()
-{
- rc=$1
- $needsCleanup && test -n "$tmpdir" && test -d "$tmpdir" \
- && { cd / && rm -rf "$tmpdir"; }
- # use clear rather than reset since we cannot easily save and restore
- # the terminal settings, which is what would be ideal. See thread
- # starting at http://tug.org/pipermail/tex-live/2016-March/037852.html.
- termCtl clear
- (exit $rc); exit $rc
-}
-
-###############################################################################
-# setupTmpDir()
-# set up a temp directory and a trap to remove it
-###############################################################################
-setupTmpDir()
-{
- case $needsCleanup in
- true) return;;
- esac
-
- trap 'cleanup 1' 1 2 3 7 13 15
- needsCleanup=true
- (umask 077; mkdir "$tmpdir") \
- || abort "could not create directory \`$tmpdir'"
-}
-
-###############################################################################
-# abort(errmsg)
-# print `errmsg' to stderr and exit with error code 1
-###############################################################################
-abort()
-{
- echo "$progname: $1." >&2
- cleanup 1
-}
-
-logexec()
-{
- (echo; echo ">>> Executing \`$@' <<<") >> $log
- "$@" 2>&1 | tee -a $log
-}
-
-###############################################################################
-# runDialog(args, ...)
-# execute the right dialog program with the right default parameters
-###############################################################################
-runDialog()
-{
- if test -n "$DIALOG_PROG"; then
- termCtl clear
- $DIALOG_PROG --title "TeX setup utility" ${1+"$@"}
- runDialogRc=$?
- termCtl clear
- else
- abort "could not find dialog or whiptail program to run"
- fi
- (exit $runDialogRc)
- return $runDialogRc
-}
-
-###############################################################################
-# findDialog(void)
-# set DIALOG_PROG to the system dialog program, or the empty string.
-###############################################################################
-findDialog()
-{
- for bin in whiptail dialog
- do
- binLoc=`texconfig findprog $bin`
- case $binLoc in
- "") DIALOG_PROG="";;
- *) DIALOG_PROG=$binLoc; break;;
- esac
- done
-}
-
-###############################################################################
-# mktexdir(args)
-# call mktexdir script, disable all features (to prevent sticky directories)
-###############################################################################
-mktexdir()
-{
- MT_FEATURES=none "$TEXMFMAIN/web2c/mktexdir" "$@" >&2
-}
-
-###############################################################################
-# termCtl(arg)
-# some convenience utilities for terminal control
-###############################################################################
-termCtl()
-{
- case $1 in
- clear)
- test -n "$NO_CLEAR" && return
- tty >/dev/null 2>&1 && clear
- ;;
- reset)
- test -n "$NO_CLEAR" && return
- reset 2>/dev/null
- stty sane 2>/dev/null
- reset 2>/dev/null
- termCtl clear
- ;;
- readln)
- echo
- echo "press return to continue..."
- read a
- ;;
- esac
-}
-
-###############################################################################
-# menuMain(void)
-# the main menu
-###############################################################################
-menuMain()
-{
- cat <<-'eof'
- The interactive texconfig utility will be started now. Make sure
- your screen has at least 24 rows and 80 columns. If texconfig
- crashes now, you can still set up your TeX system using the
- batch mode of texconfig. Try 'texconfig help' to get a list
- of options.
-
- The interactive mode works best with a real vt100 terminal or
- inside an xterm window.
-
- More likely these days, you're better off using tlmgr.
- See http://tug.org/texlive/tlmgr.html.
-eof
- termCtl readln
-
- while :; do
- logMessage='view logfile'
-
- runDialog \
- --menu "
-Hint: all output of external commands (e.g. tex) is logged into
-a file. You can look at this file using "LOG". If cursor keys make
-trouble, you may have more luck with +/- and TAB.
-" \
- 23 80 14 \
- EXIT 'exit' \
- PAPER 'default paper: A4 or letter (us)' \
- MODE 'default metafont mode and resolution' \
- REHASH 'rebuild filename databases' \
- FORMATS 'edit format definitions' \
- HYPHENATION 'customize hyphenation' \
- DVIPS 'dvips configuration' \
- FAQ 'view frequently asked questions + answers' \
- CONF 'show configuration' \
- LOG "$logMessage" \
- 2>"$tmpmenu" || break
-
- case `cat "$tmpmenu"` in
- EXIT)
- break
- ;;
- PAPER)
- menuPaper
- ;;
- MODE)
- menuMode
- ;;
- REHASH)
- logexec texconfig rehash
- termCtl readln
- ;;
- FORMATS)
- texconfig formats
- termCtl readln
- ;;
- HYPHENATION)
- menuHyphenation
- ;;
- DVIPS)
- menuDvips
- ;;
- FAQ)
- texconfig faq
- termCtl readln
- ;;
- CONF)
- logexec texconfig conf
- termCtl readln
- ;;
- LOG)
- <"$log" eval $PAGER
- termCtl readln
- ;;
- esac
- done
-}
-
-menuGetMode()
-{
- # we need eval to get the command line right... :-(
- eval \
- runDialog \
- --menu \""
-Chosse a mode to be used when metafont generates font bitmaps. The resolution is the most important point, but there might
-be differences between modes of the same resolution. See the comments in the file modes.mf for more details.
-\"" \
- 23 80 14 \
- `texconfig mode-list` 2>"$tmpmenu"
-}
-
-menuMode()
-{
- menuGetMode
- mode=`cat "$tmpmenu"`
-
- if test -n "$mode"; then
- logexec texconfig mode "$mode"
- termCtl readln
- fi
-}
-
-menuDvips()
-{
- menuDvipsDest=ps
-
- while :; do
- case $menuDvipsDest in
- ps)
- menuDvipsPrinterOpt=
- menuDvipsMsg="
-dvips GLOBAL section. Define the most common default settings (config.ps).
-To define settings for a specific printer, first ADD a printer definition,
-then CHANGE it.
-"
- ;;
- *)
- menuDvipsPrinterOpt="-P $menuDvipsDest"
- menuDvipsMsg="
-dvips settings for printer $menuDvipsDest (config.$menuDvipsDest). Define
-local settings for this printer. To switch back to global settings mode,
-select GLOBAL.
-"
- ;;
- esac
-
- runDialog \
- --menu "$menuDvipsMsg
-You can use dvips for non PostScript printers, if you can setup your
-printing system to convert PostScript to a format that your printer can
-handle. Maybe, you can use GhostScript to do the conversion (if your
-printer is supported)." \
- 23 80 9 \
- RETURN 'back to the main menu' \
- DEST 'define default destination of the generated Postscript' \
- MODE 'change metafont mode/resolution' \
- OFFSET 'shift output by some offset' \
- PAPER 'define the default paper' \
- GLOBAL 'change global settings (config.ps)' \
- CHANGE 'change printer settings (config.$PRINTER)' \
- ADD 'add a printer configuration' \
- DEL 'remove a printer configuration' \
- 2>"$tmpmenu" || break
-
- menuDvipsAns=`cat "$tmpmenu"`
- case $menuDvipsAns in
- RETURN)
- break
- ;;
- DEST)
- runDialog --inputbox "Enter the command to print.
-
-In general, you need a command like 'lpr' or 'lpr -Pfoo'.
-
-NOTE: If you just press return, printing will be disabled and the output saved to a file by default.
-" 23 80 2>"$tmpmenu"
- if test $? = 0; then
- menuDvipsAns=`cat "$tmpmenu"`
- case $menuDvipsAns in
- "")
- menuDvipsPrintOpt=-
- ;;
- *)
- menuDvipsPrintOpt=$menuDvipsAns
- ;;
- esac
- logexec texconfig dvips $menuDvipsPrinterOpt printcmd "$menuDvipsPrintOpt"
- termCtl readln
- fi
- ;;
- MODE)
- menuGetMode
- mode=`cat "$tmpmenu"`
-
- if test -n "$mode"; then
- logexec texconfig dvips $menuDvipsPrinterOpt mode "$mode"
- termCtl readln
- fi
- ;;
- OFFSET)
- runDialog --inputbox "Enter a dimension pair (a rightwards offset and a downwards
-offset), e.g. 2mm,-0.5in (right 2mm and up .5in):" 23 80 2>"$tmpmenu"; menuDvipsAns=`cat "$tmpmenu"`
- case $menuDvipsAns in
- "") : ;;
- *)
- logexec texconfig dvips $menuDvipsPrinterOpt offset "$menuDvipsAns"
- termCtl readln
- ;;
- esac
- ;;
- PAPER)
- eval runDialog \
- --menu \'\\n\\nChoose the default papersize definition for dvips.\\n\\n\' \
- 23 80 8 `texconfig dvips paper-list` \
- 2>"$tmpmenu"
- paper=`cat "$tmpmenu"`
- if test -n "$paper"; then
- logexec texconfig dvips paper "$paper"
- termCtl readln
- fi
- ;;
- GLOBAL)
- menuDvipsDest=ps
- ;;
- CHANGE)
- runDialog --inputbox "Printer name (for future settings of DEST / MODE / OFFSET)" 23 80 2>"$tmpmenu"
- menuDvipsAns=`cat $tmpmenu`
- case $menuDvipsAns in
- "") : ;;
- *) menuDvipsDest=$menuDvipsAns;;
- esac
- ;;
- ADD)
- runDialog --inputbox "Printer name (for printer to add)" 23 80 2>"$tmpmenu"
- menuDvipsAns=`cat $tmpmenu`
- case $menuDvipsAns in
- "") : ;;
- *)
- logexec texconfig dvips add $menuDvipsAns
- termCtl readln
- ;;
- esac
- ;;
- DEL)
- runDialog --inputbox "Printer name (for printer to delete)" 23 80 2>"$tmpmenu"
- menuDvipsAns=`cat $tmpmenu`
- case $menuDvipsAns in
- "") : ;;
- *)
- logexec texconfig dvips del $menuDvipsAns
- termCtl readln
- ;;
- esac
- ;;
- esac
- done
-}
-
-menuPaper()
-{
- runDialog \
- --menu "
-Select your default paper format.
-" \
- 23 80 14 \
- RETURN 'return to the main menu' \
- A4 'ISO A4 (210x297mm)' \
- LETTER 'US (8.5x11in)' 2>"$tmpmenu"
-
- p=`cat "$tmpmenu"`
- case $p in
- A4)
- logexec texconfig paper a4
- termCtl readln
- ;;
- LETTER)
- logexec texconfig paper letter
- termCtl readln
- ;;
- esac
-}
-
-menuHyphenation()
-{
- runDialog \
- --menu "
-Choose format to set up hyphenation for.
-" \
- 23 80 14 \
- `texconfig hyphen-list | sed 's@\(.*\)@\1 \1@'` 2>"$tmpmenu"
- p=`cat "$tmpmenu"`
- case $p in
- "")
- return
- ;;
- *)
- texconfig hyphen "$p"
- termCtl readln
- esac
-}
-
-# main()
-
-case $1 in
- help|--help)
- cat <<-eof
- Usage: $progname [--help|--version]
-eof
- exit 0
- ;;
- --version)
- cat <<-eof
- $progname version $version.
-eof
- exit 0
- ;;
-esac
-
-
-: ${TEXMFCONFIG=`kpsewhich -var-value=TEXMFCONFIG`}
-: ${TEXMFVAR=`kpsewhich -var-value=TEXMFVAR`}
-: ${TEXMFMAIN=`kpsewhich -var-value=TEXMFMAIN`}
-export TEXMFCONFIG TEXMFVAR TEXMFMAIN
-
-setupTmpDir
-echo "$progname: started `date`" > $log
-findDialog
-
-test -d "$TEXMFCONFIG" \
- || mktexdir "$TEXMFCONFIG" >/dev/null 2>&1 \
- || echo "$progname: directory \`$TEXMFCONFIG' (from TEXMFCONFIG variable) does not exist and cannot be created" >&2
-
-canWriteConfig=false
-if test -d "$TEXMFCONFIG"; then
- if test -w "$TEXMFCONFIG"; then
- canWriteConfig=true
- else
- echo "$progname: directory \`$TEXMFCONFIG' (from TEXMFCONFIG variable) is not writable."
- echo "$progname: configuration data cannot be changed." >&2
- fi
-fi
-
-test -d "$TEXMFVAR" \
- || mktexdir "$TEXMFVAR" >/dev/null 2>&1 \
- || echo "$progname: directory \`$TEXMFVAR' (from TEXMFVAR variable) does not exist and cannot be created" >&2
-
-canWriteVardata=false
-if test -d "$TEXMFVAR"; then
- if test -w "$TEXMFVAR"; then
- canWriteVardata=true
- else
- echo "$progname: directory \`$TEXMFVAR' (from TEXMFVAR variable) is not writable."
- echo "$progname: cached variable runtime data files cannot be written." >&2
- fi
-fi
-
-menuMain
-cleanup 0
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig-sys.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig-sys.sh
deleted file mode 100755
index bffc42bfebc..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig-sys.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-# $Id: texconfig-sys.sh 53554 2020-01-26 23:58:37Z karl $
-# texconfig-sys: Thomas Esser, public domain.
-
-# wrapper script for texconfig with TEXMFVAR and TEXMFCONFIG set to
-# TEXMFSYSVAR / TEXMFSYSCONFIG
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-v=`kpsewhich -var-value TEXMFSYSVAR`
-c=`kpsewhich -var-value TEXMFSYSCONFIG`
-
-TEXMFVAR="$v"
-TEXMFCONFIG="$c"
-export TEXMFVAR TEXMFCONFIG
-
-exec texconfig ${1+"$@"}
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig.sh
deleted file mode 100755
index 93c660d6983..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/texconfig.sh
+++ /dev/null
@@ -1,1449 +0,0 @@
-#!/bin/sh
-# $Id: texconfig.sh 53554 2020-01-26 23:58:37Z karl $
-# texconfig version 3.0
-# Originally written by Thomas Esser. Public domain.
-# Now maintained as part of TeX Live; correspondence to tex-live@tug.org.
-
-# invoke the right shell:
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-# initializations...
-progname=texconfig
-
-# the version string
-version='$Id: texconfig.sh 53554 2020-01-26 23:58:37Z karl $'
-
-envVars="
- AFMFONTS BIBINPUTS BSTINPUTS CMAPFONTS CWEBINPUTS ENCFONTS GFFONTS
- GLYPHFONTS INDEXSTYLE LIGFONTS MFBASES MFINPUTS MFPOOL MFTINPUTS
- MISCFONTS MPINPUTS MPMEMS MPPOOL MPSUPPORT OCPINPUTS OFMFONTS
- OPENTYPEFONTS OPLFONTS OTPINPUTS OVFFONTS OVPFONTS PDFTEXCONFIG PKFONTS
- PSHEADERS SFDFONTS T1FONTS T1INPUTS T42FONTS TEXBIB TEXCONFIG TEXDOCS
- TEXFONTMAPS TEXFONTS TEXFORMATS TEXINDEXSTYLE TEXINPUTS TEXMFCNF
- TEXMFDBS TEXMFINI TEXMFSCRIPTS TEXPICTS TEXPKS TEXPOOL TEXPSHEADERS
- TEXSOURCES TFMFONTS TRFONTS TTFONTS VFFONTS WEB2C WEBINPUTS
-"
-tmpdir=${TMPDIR-${TEMP-${TMP-/tmp}}}/tctmp.$$
-needsCleanup=false
-lastUpdatedFile=
-
-#
-###############################################################################
-# setupFMT(void) - find a suitable version of fmt / adjust
-#
-setupFMT()
-{
- case $FMT in
- "")
- FMT=fmt
- test ! -x /bin/fmt && test ! -f /usr/bin/fmt &&
- { test -x /bin/adjust || test -x /usr/bin/adjust; } && FMT=adjust
- ;;
- *)
- return
- ;;
- esac
-}
-
-###############################################################################
-# myFmt(args) - run $FMT
-#
-myFmt()
-{
- setupFMT
- $FMT ${1+"$@"}
-}
-
-###############################################################################
-# echoShowVariable(args ...)
-# show environment variables which names are as args and their values
-#
-echoShowVariable()
-{
- for esv
- do
- var=$esv
- eval val=\"\${$var+=}\${$var- is unset}\"
- echo "$var$val"
- done | grep -v 'is unset$'
-}
-
-###############################################################################
-# echoShowKpseVariable(args ...)
-# show kpathsea variables which names are as args and their values
-#
-echoShowKpseVariable()
-{
- for eskv
- do
- var=$eskv
- val=`kpsewhich -var-value="$eskv"`
- echo "$var=$val"
- done
-}
-
-###############################################################################
-# echoLocateBinary(args ...) - show where programs actually exist
-#
-echoLocateBinary()
-{
- for elb
- do
- elbLoc=`checkForBinary "$elb"`
- if test -n "$ELB_PATH_ONLY"; then
- test -n "$elbLoc" && echo "$elbLoc"
- else
- case $elbLoc in
- "") echo "$elb: not found";;
- *) echo "$elb: $elbLoc";;
- esac
- fi
- done
-}
-
-###############################################################################
-# echoLocateCfgfile(args ...) - show where files actually exist
-#
-echoLocateCfgfile()
-{
- for elc
- do
- case $elc in
- texmf.cnf) elcLoc=`kpsewhich $elc`;;
- *) elcLoc=`tcfmgr --cmd find --file "$elc"`;;
- esac
- case $elcLoc in
- "") echo "$elc: not found";;
- *) echo "$elcLoc";;
- esac
- done
-}
-
-###############################################################################
-# checkForBinary(prog) - echo full path of prog
-#
-checkForBinary()
-{
- cfbBinary=$1
-
- OLDIFS=$IFS
- IFS=:
- set x `echo "$PATH" | sed 's/^:/.:/; s/:$/:./; s/::/:.:/g'`; shift
- found=false
- for pathElem
- do
- case $pathElem in
- "") continue;;
- *) test -f "$pathElem/$cfbBinary" && { echo "$pathElem/$cfbBinary"; found=true; break; }
- esac
- done
- IFS=$OLDIFS
- case $found in
- true) (exit 0); return 0;;
- false) (exit 1); return 1;;
- esac
-}
-
-###############################################################################
-# cleanup() - clean up the temp area and exit with proper exit status
-#
-cleanup()
-{
- rc=$1
- $needsCleanup && test -n "$tmpdir" && test -d "$tmpdir" \
- && { cd / && rm -rf "$tmpdir"; }
- (exit $rc); exit $rc
-}
-
-###############################################################################
-# setupTmpDir() - set up a temp directory and a trap to remove it
-#
-setupTmpDir()
-{
- case $needsCleanup in
- true) return;;
- esac
-
- trap 'cleanup 1' 1 2 3 7 13 15
- needsCleanup=true
- (umask 077; mkdir "$tmpdir") \
- || abort "could not create directory \`$tmpdir'"
-}
-
-###############################################################################
-# setupTexmfroot() - get value for MT_TEXMFROOT (with caching)
-#
-setupTexmfroot()
-{
- case $MT_TEXMFROOT in
- "") MT_TEXMFROOT=`kpsewhich -var-value=TEXMFROOT`;;
- *) return;;
- esac
-}
-
-
-###############################################################################
-# setupTexmfmain() - get value for MT_TEXMFMAIN (with caching)
-#
-setupTexmfmain()
-{
- case $MT_TEXMFMAIN in
- "") MT_TEXMFMAIN=`kpsewhich -var-value=TEXMFMAIN`;;
- *) return;;
- esac
-}
-
-###############################################################################
-# setupTexmfmain() - get value for MT_TEXMFDIST (with caching)
-#
-setupTexmfdist()
-{
- case $MT_TEXMFDIST in
- "") MT_TEXMFDIST=`kpsewhich -var-value=TEXMFDIST`;;
- *) return;;
- esac
-}
-
-###############################################################################
-# setupTexmfvar() - get value for MT_TEXMFVAR (with caching)
-#
-setupTexmfvar()
-{
- case $MT_TEXMVAR in
- "") MT_TEXMVAR=`kpsewhich -var-value=TEXMFVAR`;;
- *) return;;
- esac
-}
-
-###############################################################################
-# setupSystexmf() - get value for MT_SYSTEXMF (with caching)
-#
-setupSystexmf()
-{
- case $MT_SYSTEXMF in
- "") MT_SYSTEXMF=`kpsewhich -var-value=SYSTEXMF`;;
- *) return;;
- esac
-}
-
-###############################################################################
-# abort(errmsg)
-# print `errmsg' to stderr and exit with error code 1
-#
-abort()
-{
- echo "$progname: $1." >&2
- cleanup 1
-}
-
-###############################################################################
-# mktexdir(args)
-# call mktexdir script, disable all features (to prevent sticky directories)
-#
-mktexdir()
-{
- setupTexmfmain
- MT_FEATURES=none "$MT_TEXMFMAIN/web2c/mktexdir" "$@" >&2
-}
-
-###############################################################################
-# tcfmgr(args) - call tcfmgr script
-#
-tcfmgr()
-{
- setupTexmfmain
- "$MT_TEXMFMAIN/texconfig/tcfmgr" "$@"
-}
-
-###############################################################################
-# mktexupd(args) - call mktexupd script
-#
-mktexupd()
-{
- setupTexmfmain
- "$MT_TEXMFMAIN/web2c/mktexupd" "$@"
-}
-
-###############################################################################
-# getRelDir(file)
-# matches file against SYSTEXMF. Returns relative directory of file within
-# a texmf tree in variable relPart.
-#
-getRelDir()
-{
- file=$1
- relPart=
-
- setupSystexmf
- OLDIFS=$IFS
- IFS='
-'
- set x `echo "$MT_SYSTEXMF" | tr : '
-'`; shift
- IFS=$OLDIFS
-
- # now loop over all components of SYSTEXMF
- for dir
- do
- test -n "$dir" || continue
- case "$file" in
- $dir/*)
- relPart=`echo "$file" | sed "s%$dir/*%%"`
- break
- ;;
- esac
- done
-
- # now check for success / failure
- case $relPart in
- ""|$file)
- # empty or full filename -> getRelDir failed!
- (exit 1); return 1
- ;;
- *)
- # relPart should just have the "dirname" part:
- relPart=`echo "$relPart" | sed 's%/*[^/]*$%%'`
- (exit 0); return 0
- ;;
- esac
-}
-
-###############################################################################
-# configReplace(file pattern line)
-# The first line in file that matches pattern gets replaced by line.
-# line will be added at the end of the file if pattern does not match.
-#
-configReplace()
-{
- configReplaceFile=$1; configReplacePat=$2; configReplaceLine=$3
-
- if grep "$configReplacePat" "$configReplaceFile" >/dev/null; then
- ed "$configReplaceFile" >/dev/null 2>&1 <<-eof
- /$configReplacePat/c
- $configReplaceLine
- .
- w
- q
-eof
- else
- echo "$configReplaceLine" >> $configReplaceFile
- fi
-}
-
-###############################################################################
-# fmgrConfigReplace (file regex value)
-# replaces line matching regex by value in file
-#
-fmgrConfigReplace()
-{
- fmgrConfigReplaceChanged=false
-
- moreArgs=""
- while
- case $1 in
- --*) moreArgs="$moreArgs $1 $2";;
- *) break;;
- esac
- do shift; shift; done
- fmgrConfigReplaceFile=$1
- fmgrConfigReplaceRegex=$2
- fmgrConfigReplaceValue=$3
-
- setupTmpDir
- co=`tcfmgr $moreArgs --tmp $tmpdir --cmd co --file $fmgrConfigReplaceFile`
- if test $? != 0; then
- echo "$progname: fmgrConfigReplace co failed for \`$fmgrConfigReplaceFile'" >&2
- (exit 1); return 1
- fi
- set x $co; shift
- fmgrConfigReplaceID=$1; fmgrConfigReplaceCfgFile=$3; fmgrConfigReplaceOrigFile=$4
- configReplace "$fmgrConfigReplaceCfgFile" "$fmgrConfigReplaceRegex" "$fmgrConfigReplaceValue"
- ci=`tcfmgr --tmp $tmpdir --cmd ci --id "$fmgrConfigReplaceID"`
- if test $? != 0; then
- echo "$progname: fmgrConfigReplace ci failed for \`$fmgrConfigReplaceFile'" >&2
- (exit 1); return 1
- fi
- case $ci in
- "") :;;
- $lastUpdatedFile)
- fmgrConfigReplaceChanged=true;;
- *) echo "$progname: updated configuration saved as file \`$ci'" >&2
- fmgrConfigReplaceChanged=true
- lastUpdatedFile=$ci;;
- esac
- (exit 0); return 0
-}
-
-###############################################################################
-# setupDvipsPaper(paper)
-# rearranges config.ps to make paper the first paper definition
-#
-setupDvipsPaper()
-{
- setupDvipsPaperChanged=false
- setupDvipsPaperFile=config.ps
- setupDvipsPaperDftPaper=$1
-
- setupTmpDir
- co=`tcfmgr --tmp $tmpdir --cmd co --file $setupDvipsPaperFile`
- if test $? != 0; then
- echo "$progname: setupDvipsPaper co failed for \`$setupDvipsPaperFile'" >&2
- (exit 1); return 1
- fi
- set x $co; shift
- setupDvipsPaperID=$1; setupDvipsPaperCfgFile=$3; setupDvipsPaperOrigFile=$4
-
- ed "$setupDvipsPaperCfgFile" > /dev/null 2>&1 <<-eof
- /@ /ka
- \$a
- @
- .
- /@ $setupDvipsPaperDftPaper /;/@ /-1m'a-1
- \$d
- w
- q
-eof
-
- ci=`tcfmgr --tmp $tmpdir --cmd ci --id "$setupDvipsPaperID"`
- if test $? != 0; then
- echo "$progname: setupDvipsPaper ci failed for \`$setupDvipsPaperFile'" >&2
- (exit 1); return 1
- fi
- case $ci in
- "") :;;
- $lastUpdatedFile)
- setupDvipsPaperChanged=true;;
- *) echo "$progname: updated configuration saved as file \`$ci'" >&2
- setupDvipsPaperChanged=true
- lastUpdatedFile=$ci;;
- esac
- (exit 0); return 0
-}
-
-###############################################################################
-# setupModesMfFile(void) - find modes.mf file (with caching)
-#
-setupModesMfFile()
-{
- case $modesMfFile in
- "")
- modesMfFile=`tcfmgr --cmd find --file modes.mf`
- ;;
- *)
- return
- ;;
- esac
-}
-
-###############################################################################
-# locateConfigPsFile(void) - find config.ps file (with caching)
-#
-locateConfigPsFile()
-{
- case $configPsFile in
- "")
- configPsFile=`tcfmgr --cmd find --file config.ps`
- ;;
- *)
- return
- ;;
- esac
-}
-
-###############################################################################
-# listMfModes(file) - list modes from modes.mf file
-#
-listMfModes()
-{
- grep mode_def "$modesMfFile" |
- sed -e "s/mode_def //" \
- -e "s/ .*%[^ ]* / '/" \
- -e "s/\$/' /" |
- egrep -v "^(help|%)" | sort
-}
-
-###############################################################################
-# listDvipsPapers(void) - list paper definitions from config.ps
-#
-listDvipsPapers()
-{
- grep '@ ' $configPsFile | sed "s/..//;s/ / '/;s/\$/' /"
-}
-
-###############################################################################
-# getFormatsForHyphen(void)
-# list all formats which have customizable hyphenation
-#
-getFormatsForHyphen()
-{
- fmtutil --catcfg | awk '$3 != "-" {print $1}' | sort
-}
-
-###############################################################################
-# getRes(mode) - print resolution (both X and Y axis) to metafont mode
-#
-getRes()
-{
- getResMode=$1
- (
- cd $tmpdir
- cat >mftmp.mf <<-'eof'
- let myexit = primitive_end_;
- mode_setup;
- string xdpi;
- xdpi := decimal round pixels_per_inch;
- message "XDPI = " & xdpi;
- string ydpi;
- ydpi := decimal round (pixels_per_inch * aspect_ratio);
- message "YDPI = " & ydpi;
- fontmaking := 0;
- myexit;
-eof
- mf '\mode='"$getResMode"'; \input ./mftmp' </dev/null \
- | awk '$1 == "XDPI" || $1 == "YDPI" { print $3 }'
- )
-}
-
-###############################################################################
-# checkElemInList(elem, list)
-# check if element exists in list
-###############################################################################
-checkElemInList()
-{
- checkElemInListElem=$1; shift
- checkElemInListFound=false
- for checkElemInListIter
- do
- case "x$checkElemInListElem" in
- x$checkElemInListIter)
- checkElemInListFound=true
- break
- ;;
- esac
- done
- case $checkElemInListFound in
- true) (exit 0); return 0;;
- esac
- (exit 1); return 1
-}
-
-
-# show version information from the distribution, if we have any.
-showDistVersionInfo()
-{
- # TeX Live file.
- setupTexmfroot
- test -f $MT_TEXMFROOT/release-texlive.txt \
- && sed 1q $MT_TEXMFROOT/release-texlive.txt
-
- # no harm in continuing to look for the teTeX files.
- test -f $MT_TEXMFMAIN/release-tetex-src.txt \
- && "teTeX-src release: `cat $MT_TEXMFMAIN/release-tetex-src.txt`"
- test -f $MT_TEXMFDIST/release-tetex-texmf.txt \
- && "teTeX-texmf release: `cat $MT_TEXMFDIST/release-tetex-texmf.txt`"
-}
-
-#
-###############################################################################
-# tcBatch(args)
-# handle batch mode
-###############################################################################
-tcBatch()
-{
- help="texconfig supports adjusting and updating many aspects of
-the TeX installation.
-
-Usage: $progname conf (show configuration information)
- $progname dvipdfmx paper PAPER (dvipdfmx paper size)
- $progname dvips [OPTION...] (dvips options)
- $progname faq (show pointer to TeX Live docs)
- $progname findprog PROG... (show locations of PROGs, a la which)
- $progname font vardir DIR
- $progname font ro
- $progname font rw
- $progname formats (edit fmtutil.cnf)
- $progname help (or --help; show this help)
- $progname hyphen FORMAT (edit hyphenation config for FORMAT)
- $progname init [FORMAT]... (rebuild FORMATs, or all formats
- plus run texlinks and updmap)
- $progname mode MODE (set Metafont MODE)
- $progname paper PAPER (set default paper size to PAPER)
- $progname pdftex [OPTION]... (pdftex options)
- $progname rehash (rebuild ls-R files with mktexlsr)
- $progname version (or --version; show version info)
- $progname xdvi paper PAPER (xdvi paper size)
-
-Get more help with:
- $progname dvipdfmx
- $progname dvips
- $progname font
- $progname hyphen
- $progname mode
- $progname paper
- $progname pdftex
- $progname xdvi
-
-Report bugs to: tex-k@tug.org
-TeX Live home page: <http://tug.org/texlive/>
-"
-
- case $1 in
- # texconfig conf
- conf|confall)
- setupTexmfmain
- setupTexmfdist
- echo '=========================== version information =========================='
- showDistVersionInfo
- echo
- echo '==================== binaries found by searching $PATH ==================='
- echo "PATH=$PATH"
- echoLocateBinary kpsewhich updmap fmtutil texconfig tex pdftex mktexpk dvips dvipdfmx
- echo
- echo '=========================== active config files =========================='
- echoLocateCfgfile texmf.cnf updmap.cfg fmtutil.cnf config.ps mktex.cnf XDvi pdftexconfig.tex | sort -k 2
- echo
- echo '============================= font map files ============================='
- for m in psfonts.map pdftex.map ps2pk.map; do
- echo "$m: `kpsewhich $m`"
- done
- echo
- echo '=========================== kpathsea variables ==========================='
- echoShowKpseVariable TEXMFMAIN TEXMFDIST TEXMFLOCAL TEXMFSYSVAR TEXMFSYSCONFIG TEXMFVAR TEXMFCONFIG TEXMFHOME VARTEXFONTS TEXMF SYSTEXMF TEXMFDBS WEB2C TEXPSHEADERS TEXCONFIG ENCFONTS TEXFONTMAPS
-
- echo
- echo '==== kpathsea variables from environment only (ok if no output here) ===='
- echoShowVariable $envVars
- ;;
-
- # texconfig dvipdfmx
- dvipdfmx)
- help="Usage: $progname dvipdfmx paper PAPER
-
-Valid PAPER settings:
- letter legal ledger tabloid a4 a3"
- case $2 in
- # texconfig dvipdfmx paper
- paper-list)
- for p in letter legal ledger tabloid a4 a3; do echo $p; done
- ;;
- paper)
- case $3 in
- letter|legal|ledger|tabloid|a4|a3)
- tlmgr dvipdfmx paper $3
- ;;
- # fmgrConfigReplace dvipdfmx.cfg '^p' "p $3";;
- "") echo "$help" >&2; rc=1;;
- *)
- echo "$progname: unknown PAPER \`$3' given as argument for \`$progname dvipdfmx paper'" >&2
- echo "$progname: try \`$progname dvipdfmx paper' for help" >&2
- rc=1 ;;
- esac ;;
- # texconfig dvipdfmx ""
- "")
- echo "$help" >&2; rc=1 ;;
- # texconfig dvipdfmx <unknown>
- *)
- echo "$progname: unknown option \`$2' given as argument for \`$progname dvipdfmx'" >&2
- echo "$progname: try \`$progname dvipdfmx' for help" >&2
- rc=1
- ;;
- esac
- ;;
-
- # texconfig dvips
- dvips)
- shift
- help="Usage: $progname dvips add PRINTER
- $progname dvips del PRINTER
- $progname dvips paper PAPER
- $progname dvips [-P PRINTER] mode MODE
- $progname dvips [-P PRINTER] offset OFFSET
- $progname dvips [-P PRINTER] printcmd CMD"
- case $1 in
- -P)
- case $2 in
- "")
- echo "$progname: missing arg for parameter -P" >&2
- rc=1; (exit $rc); return $rc
- ;;
- *)
- otherPrinter=true
- otherPrinterName=$2
- otherPrinterFile=`kpsewhich -format='dvips config' "config.$otherPrinterName"`
- case $otherPrinterFile in
- "")
- echo "$progname: configuration file \`config.$otherPrinterName' for printer \`$otherPrinterName' not found" >&2
- rc=1; (exit $rc); return $rc
- ;;
- *) shift; shift;;
- esac
- ;;
- esac
- ;;
- *)
- otherPrinter=false
- ;;
- esac
- case $otherPrinter in
- true)
- tcBatchDvipsPrinter=$otherPrinterName
- moreFmgrArgs="--reldir dvips/config --infile $otherPrinterFile"
- ;;
- *)
- tcBatchDvipsPrinter=ps
- ;;
- esac
- case $1 in
- add)
- case $2 in
- "")
- echo "Usage: $progname dvips add PRINTER" >&2
- rc=1
- ;;
- *)
- printerName=$2
- pFile=`kpsewhich -format='dvips config' "config.$printerName"`
- case $pFile in
- "")
- setupTmpDir
- tcfRet=`tcfmgr --emptyinfile --reldir dvips/config --cmd co --tmp $tmpdir --file "config.$printerName"`
- if test $? != 0; then
- echo "$progname: failed to add new configuration file \`config.$printerName'" >&2
- rc=1
- else
- set x $tcfRet; shift
- tcBatchDvipsAddID=$1; tcBatchDvipsAddFile=$3
- echo "% file config.$printerName; added by texconfig" > "$tcBatchDvipsAddFile"
- tcfRet=`tcfmgr --tmp $tmpdir --id "$tcBatchDvipsAddID" --cmd ci`
- if test $? != 0; then
- echo "$progname: failed to add new configuration file \`config.$printerName'" >&2
- rc=1
- else
- echo "$progname: file $tcfRet added" >&2
- fi
- fi
- ;;
- *)
- echo "$progname: configuration file for printer \`$printerName' already exists (\`$pFile')" >&2
- rc=1
- ;;
- esac
- ;;
- esac
- ;;
- del)
- case $2 in
- "")
- echo "Usage: $progname dvips del PRINTER" >&2
- rc=1
- ;;
- *)
- printerName=$2
- pFile=`kpsewhich -format='dvips config' "config.$printerName"`
- case $pFile in
- "")
- echo "$progname: configuration file for printer \`$printerName' (config.$printerName) not found" >&2
- rc=1
- ;;
- *)
- if rm "$pFile"; then
- echo "$progname: file \`$pFile' removed" >&2
- else
- echo "$progname: failed to remove file \`$pFile'" >&2
- rc=1
- fi
- ;;
- esac
- ;;
- esac
- ;;
- paper-list)
- locateConfigPsFile
- listDvipsPapers
- ;;
- paper)
- case $2 in
- "")
- echo "Usage: $progname dvips paper PAPER" >&2
- echo >&2; echo "Valid PAPER settings:" >&2
- locateConfigPsFile
- listDvipsPapers | sed 's@ .*@@; s@^@ @' | myFmt
- rc=1
- ;;
- *)
- tcBatchDvipsPaper=$2
- locateConfigPsFile
- case "$configPsFile" in
- "")
- echo "$progname: file config.ps not found" >&2; rc=1
- ;;
- *)
- if grep "@ $tcBatchDvipsPaper " $configPsFile >/dev/null 2>&1; then
- tlmgr dvips paper $tcBatchDvipsPaper
- # setupDvipsPaper "$tcBatchDvipsPaper"
- else
- echo "$progname: paper \`$tcBatchDvipsPaper' not found in file \`$configPsFile'" >&2; rc=1
- fi
- ;;
- esac
- ;;
- esac
- ;;
- mode)
- case $2 in
- "")
- echo "Usage: $progname dvips mode MODE
-
-Valid MODE settings:"
- setupModesMfFile
- listMfModes | sed 's@ .*@@; s@^@ @' | myFmt
- rc=1
- ;;
- *)
- tcBatchDvipsMode=$2
- setupTmpDir
- setupModesMfFile
- if checkElemInList "$tcBatchDvipsMode" `listMfModes | sed 's@ .*@@'`; then
- set x `getRes "$tcBatchDvipsMode"`; shift
- resX=$1; resY=$2
- fmgrConfigReplace $moreFmgrArgs config.$tcBatchDvipsPrinter '^M' "M $tcBatchDvipsMode"
- fmgrConfigReplace $moreFmgrArgs config.$tcBatchDvipsPrinter '^D' "D $resX"
- fmgrConfigReplace $moreFmgrArgs config.$tcBatchDvipsPrinter '^X' "X $resX"
- fmgrConfigReplace $moreFmgrArgs config.$tcBatchDvipsPrinter '^Y' "Y $resY"
- else
- echo "$progname: unknown MODE \`$tcBatchDvipsMode' given as argument for \`$progname dvips mode'" >&2
- echo "$progname: try \`$progname dvips mode' for help" >&2
- rc=1
- fi
- ;;
- esac
- ;;
- offset)
- offset=$2
- case $offset in
- "")
- echo "Usage: $progname dvips offset OFFSET"
- rc=1
- ;;
- *)
- fmgrConfigReplace $moreFmgrArgs config.$tcBatchDvipsPrinter '^O' "O $offset"
- esac
- ;;
- printcmd)
- printcmd=$2
- case $printcmd in
- "")
- echo "Usage: $progname dvips printcmd CMD"
- rc=1
- ;;
- -)
- fmgrConfigReplace $moreFmgrArgs config.$tcBatchDvipsPrinter '^o' o
- ;;
- *)
- fmgrConfigReplace $moreFmgrArgs config.$tcBatchDvipsPrinter '^o' "o |$printcmd"
- ;;
- esac
- ;;
- "")
- echo "$help" >&2; rc=1
- ;;
- *)
- echo "$progname: unknown option \`$1' given as argument for \`$progname dvips'" >&2
- echo "$progname: try \`$progname dvips' for help" >&2
- rc=1
- ;;
- esac
- ;;
-
- faq)
- echo "Please see https://tug.org/texlive/doc/ for the documentation"
- echo "available in TeX Live."
- ;;
- # setupTexmfmain
- # if test -f $MT_TEXMFMAIN/doc/tetex/teTeX-FAQ; then
- # <$MT_TEXMFMAIN/doc/tetex/teTeX-FAQ eval ${PAGER-more}
- # else
- # echo "$progname: faq not found (usually in \$TEXMFMAIN/doc/tetex/teTeX-FAQ)" >&2
- # rc=1
- # fi
- # ;;
-
- findprog)
- shift
- ELB_PATH_ONLY=1 echoLocateBinary "$@"
- ;;
-
- # handle "texconfig font"
- font)
- setupTexmfroot
- help="Usage: $progname font vardir DIR
- $progname font ro
- $progname font rw
-
-The vardir option changes the VARTEXFONTS variable in the texmf.cnf file.
-
-The rw option makes the VARTEXFONTS directory (and subtrees pk, tfm,
-source) world writable and sets the features appendonlydir:varfonts
-in mktex.cnf.
-
-The ro option makes the VARTEXFONTS directory (and subtrees pk, tfm,
-source) writable for the owner only and sets the feature texmfvar in
-mktex.cnf.
-
-For more information about these \`features', consult the teTeX manual
-(e.g. by running \`texdoc TETEXDOC')."
-
- case $2 in
- vardir)
- case $3 in
- "")
- echo "$help" >&2
- rc=1
- ;;
- *)
- tcBatchFontVardir=$3
- # tfc=`kpsewhich texmf.cnf`
- tfc="$MT_TEXMFROOT/texmf.cnf"
- touch "$tfc"
- if test -n "$tfc"; then
- if test -w "$tfc"; then
- configReplace "$tfc" '^VARTEXFONTS' "VARTEXFONTS = $tcBatchFontVardir"
- else
- echo "$progname: setting up vardir failed. Reason: no permission to write file \`$tfc'" >&2
- rc=1
- fi
- else
- echo "$progname: setting up vardir failed. Reason: failed to find file texmf.cnf" >&2
- rc=1
- fi
- ;;
- esac
- ;;
- rw)
- MT_VARTEXFONTS=`kpsewhich -var-value VARTEXFONTS`
- if test -z "$MT_VARTEXFONTS"; then
- echo "$progname: failed to set \`font rw'; reason: could not determine VARTEXFONTS variable." >&2; rc=1
- return
- fi
- test -d "$MT_VARTEXFONTS" || mktexdir "$MT_VARTEXFONTS"
- if test ! -d "$MT_VARTEXFONTS"; then
- echo "$progname: failed to set \`font rw'; reason: directory \`$MT_VARTEXFONTS' does not exist." >&2; rc=1
- return
- fi
- chmod 1777 "$MT_VARTEXFONTS" || {
- echo "$progname: failed to modify permissions in \`$MT_VARTEXFONTS'." >&2; rc=1
- return;
- }
- (
- cd "$MT_VARTEXFONTS" || exit
- echo "$progname: modifying permissions in \`$MT_VARTEXFONTS' ..." >&2
- for d in pk tfm source; do
- test -d "$d" && find $d -type d -exec chmod 1777 '{}' \;
- done
- echo "$progname: all permissions set." >&2
- )
- setupTmpDir
- fmgrConfigReplace mktex.cnf '^: ..MT_FEATURES=' ": \${MT_FEATURES=appendonlydir:varfonts}"
- ;;
- ro)
- MT_VARTEXFONTS=`kpsewhich -var-value VARTEXFONTS`
- if test -z "$MT_VARTEXFONTS"; then
- echo "$progname: failed to set \`font ro'; reason: could not determine VARTEXFONTS variable." >&2; rc=1
- return
- fi
- test -d "$MT_VARTEXFONTS" || mktexdir "$MT_VARTEXFONTS"
- if test ! -d "$MT_VARTEXFONTS"; then
- echo "$progname: failed to set \`font ro'; reason: directory \`$MT_VARTEXFONTS' does not exist." >&2; rc=1
- return
- fi
- chmod 755 "$MT_VARTEXFONTS" || {
- echo "$progname: failed to modify permissions in \`$MT_VARTEXFONTS'." >&2; rc=1
- return;
- }
- (
- cd "$MT_VARTEXFONTS" || exit
- echo "$progname: modifying permissions in \`$MT_VARTEXFONTS' ..." >&2
- for d in pk tfm source; do
- test -d "$d" && find "$d" -type d -exec chmod 755 '{}' \;
- done
- echo "$progname: all permissions set." >&2
- )
- setupTmpDir
- fmgrConfigReplace mktex.cnf '^: ..MT_FEATURES=' ": \${MT_FEATURES=texmfvar}"
- ;;
- "") echo "$help" >&2; rc=1;;
- *) echo "$progname: unknown option \`$2' given as argument for \`$progname font'" >&2
- echo "$progname: try \`$progname font' for help" >&2
- rc=1
- ;;
- esac
- ;;
-
- formats)
- cat >&2 <<EOM
-texconfig formats is no longer supported, because manual edits of
-fmtutil.cnf will be overwritten by the new TeX Live package manager,
-tlmgr, which regenerates that file as needed upon package changes.
-Thus, to add or remove formats, the recommended method is to use tlmgr
-to add or remove the appropriate package.
-
-If you need to make manual additions, you can edit the file
-fmtutil-local.cnf under TEXMFLOCAL. Further information with
-tlmgr --help and at http://tug.org/texlive/tlmgr.html.
-
-Exiting.
-EOM
- exit 1 # but leave the real code for posterity
-
- setupTmpDir
- echo "$progname: analyzing old configuration..." >&2
- fmtutil --catcfg > $tmpdir/pre
- fmtutil --edit
- echo "$progname: analyzing new configuration..." >&2
- fmtutil --catcfg > $tmpdir/post
-
- if cmp $tmpdir/pre $tmpdir/post >/dev/null 2>&1; then
- echo "$progname: no new/updated formats available ..." >&2
- else
- echo "$progname: updating formats ..." >&2
- comm -13 $tmpdir/pre $tmpdir/post > $tmpdir/addOrChange
- for i in `awk '{print $1}' $tmpdir/addOrChange`; do
- fmtutil --byfmt "$i" || rc=1
- done
- texlinks --multiplatform || rc=1
- fi
- ;;
-
- help|--help|-h)
- echo "$help"
- ;;
-
- # "hyphen FORMAT"
- hyphen)
- cat >&2 <<EOM
-texconfig hyphen is no longer supported, because manual edits of
-language.dat (or language.def) will be overwritten by the new TeX Live
-package manager, tlmgr, which regenerates those configuration files as
-needed upon package changes. Thus, to add or remove hyphenation
-patterns, the recommended method is to use tlmgr to add or remove the
-appropriate package.
-
-If you need to make manual additions, you can edit the files
-language-local.dat and language-local.def under TEXMFLOCAL. Further
-information with tlmgr --help and at http://tug.org/texlive/tlmgr.html.
-
-Exiting.
-EOM
- exit 1 # but leave the real code for posterity
-
- tcBatchHyphenFormat=$2
- formatsForHyphen=`getFormatsForHyphen`
- formatsForHyphenFmt=`echo "$formatsForHyphen" | myFmt | sed 's@^@ @'`
- help="Usage: $progname hyphen FORMAT
-
-Valid FORMATs are:
-$formatsForHyphenFmt"
- case $tcBatchHyphenFormat in
- "")
- echo "$help" >&2; rc=1
- ;;
- *)
- if checkElemInList "$tcBatchHyphenFormat" $formatsForHyphen; then
-
- tcBatchHyphenFile=`fmtutil --showhyphen "$tcBatchHyphenFormat"`
- case $tcBatchHyphenFile in
- "")
- echo "$progname: could not find hyphen setup file for format \`$tcBatchHyphenFormat'" >&2
- rc=1
- return
- ;;
- esac
-
- getRelDir "$tcBatchHyphenFile"
- case $relPart in
- "")
- # edit tcBatchHyphenFile directly
- tcBatchHFID=
- setupTmpDir
- tcBatchHFEdit=$tcBatchHyphenFile
- tcBatchHFOrig=$tmpdir/hforig
- cp "$tcBatchHyphenFile" "$tcBatchHFOrig"
- ;;
- *)
- # use tcfmgr
- tcBatchHyphenFileBasename=`echo "$tcBatchHyphenFile" | sed 's@.*/@@'`
- setupTmpDir
- co=`tcfmgr --tmp $tmpdir --cmd co --file "$tcBatchHyphenFileBasename" --reldir "$relPart" --infile "$tcBatchHyphenFile"`
- if test $? != 0; then
- echo "$progname: failed to check out file \`$tcBatchHyphenFile'" >&2
- rc=1
- return 1
- else
- set x $co; shift
- tcBatchHFID=$1; tcBatchHFEdit=$3; tcBatchHFOrig=$4
- fi
- ;;
- esac
- ${VISUAL-${EDITOR-vi}} "$tcBatchHFEdit"
- if cmp "$tcBatchHFEdit" "$tcBatchHFOrig" >/dev/null 2>&1; then
- echo "$progname: configuration unchanged." >&2
- else
- case $tcBatchHFID in
- "")
- tcBatchHFOut=$tcBatchHFEdit
- echo "$progname: updated configuration saved as file \`$tcBatchHFOut'" >&2
- lastUpdatedFile=$ci
- ;;
- *)
- ci=`tcfmgr --tmp $tmpdir --cmd ci --id "$tcBatchHFID"`
- if test $? != 0; then
- echo "$progname: failed to check in file \`$tcBatchHyphenFileBasename'" >&2
- rc=1
- return
- else
- tcBatchHFOut=$ci
- echo "$progname: updated configuration saved as file \`$tcBatchHFOut'" >&2
- lastUpdatedFile=$ci
- fi
- ;;
- esac
- fmtutil --byhyphen "$tcBatchHFOut"
- fi
- else
- echo "$progname: invalid format \`$tcBatchHyphenFormat' specified as argument for \`$progname hyphen'" >&2
- echo "$progname: for getting help, try \`$progname hyphen'" >&2
- rc=1
- fi
- ;;
- esac
- ;;
-
- hyphen-list)
- getFormatsForHyphen
- ;;
-
- init)
- case $2 in
- "")
- if fmtutil --all \
- && texlinks --multiplatform \
- && updmap; then
- :
- else
- rc=1
- fi
- ;;
- *)
- shift 1
- for i in "$@"; do
- fmtutil --byfmt "$i" || rc=1
- done
- ;;
- esac
- ;;
-
- mode-list)
- setupModesMfFile
- listMfModes
- ;;
-
- mode)
- case $2 in
- "")
- echo "Usage: $progname mode MODE
-
-Valid MODE settings:"
- setupModesMfFile
- listMfModes | sed 's@ .*@@; s@^@ @' | myFmt
- rc=1
- ;;
- *)
- tcBatchMode=$2
- setupModesMfFile
- if checkElemInList $tcBatchMode `listMfModes | sed 's@ .*@@'`; then
-
- # modify mktex.cnf
- setupTmpDir
- fmgrConfigReplace mktex.cnf '^: ..MODE=' ": \${MODE=$tcBatchMode}"
- set x `getRes "$tcBatchMode"`; shift
- tcBatchRes=$1
- fmgrConfigReplace mktex.cnf '^: ..BDPI=' ": \${BDPI=$tcBatchRes}"
-
- if checkForBinary dvips >/dev/null && tcfmgr --cmd find --file config.ps >/dev/null 2>&1; then
- tcBatch dvips mode "$tcBatchMode"
- fi
- if checkForBinary pdftex >/dev/null && tcfmgr --cmd find --file pdftexconfig.tex >/dev/null 2>&1; then
- tcBatch pdftex mode "$tcBatchMode"
- fi
- else
- echo "$progname: unknown mode \`$tcBatchMode' specified as argument for \`$progname mode'" >&2; rc=1
- fi
- ;;
- esac
- ;;
-
- paper)
- help="Usage: $progname paper PAPER
-
-Valid PAPER settings:
- letter a4"
-
- p=$2; pDvips=$2
- case $2 in
- letter|a4) ;;
- "") echo "$help" >&2; rc=1; return;;
- *)
- echo "$progname: unknown PAPER \`$2' given as argument for \`$progname paper'" >&2
- echo "$progname: try \`$progname paper' for help" >&2
- rc=1
- return;;
- esac
- if checkForBinary dvips >/dev/null && tcfmgr --cmd find --file config.ps >/dev/null 2>&1; then
- tcBatch dvips paper $pDvips
- fi
- if checkForBinary dvipdfmx >/dev/null && tcfmgr --cmd find --file dvipdfmx.cfg >/dev/null 2>&1; then
- tcBatch dvipdfmx paper $p
- fi
- if checkForBinary xdvi >/dev/null && tcfmgr --cmd find --file XDvi >/dev/null 2>&1; then
- tcBatch xdvi paper $p
- fi
- if checkForBinary pdftex >/dev/null && tcfmgr --cmd find --file pdftexconfig.tex >/dev/null 2>&1; then
- tcBatch pdftex paper $p
- fi
- ;;
-
- pdftex)
- help="Usage: $progname pdftex paper PAPER
-
-Valid PAPER settings:
- a4 letter"
- case $2 in
-
- mode)
- case $3 in
- "")
- echo "Usage: $progname pdftex mode MODE"
- rc=1
- ;;
- *)
- tcBatchPdftexMode=$3
- setupTmpDir
- setupModesMfFile
- if checkElemInList "$tcBatchPdftexMode" `listMfModes | sed 's@ .*@@'`; then
- set x `getRes "$tcBatchPdftexMode"`; shift
- fmgrConfigReplace pdftexconfig.tex 'pdfpkresolution' "\\pdfpkresolution=$1"
- if $fmgrConfigReplaceChanged; then
- fmtutil --refresh
- fi
- else
- echo "$progname: unknown MODE \`$tcBatchPdftexMode' given as argument for \`$progname pdftex mode'" >&2
- rc=1
- fi
- ;;
- esac
- ;;
-
- paper)
- case $3 in
- letter|a4)
- tlmgr pdftex paper $3
- ;;
- #letter)
- # w="8.5 true in"; h="11 true in"
- # setupTmpDir
- # fmgrConfigReplace pdftexconfig.tex pdfpagewidth '\pdfpagewidth='"$w"
- # wChanged=$fmgrConfigReplaceChanged
- # fmgrConfigReplace pdftexconfig.tex pdfpageheight '\pdfpageheight='"$h"
- # if $wChanged || $fmgrConfigReplaceChanged; then
- # fmtutil --refresh
- # fi
- # ;;
- #a4)
- # w="210 true mm"; h="297 true mm"
- # fmgrConfigReplace pdftexconfig.tex pdfpagewidth '\pdfpagewidth='"$w"
- # wChanged=$fmgrConfigReplaceChanged
- # fmgrConfigReplace pdftexconfig.tex pdfpageheight '\pdfpageheight='"$h"
- # if $wChanged || $fmgrConfigReplaceChanged; then
- # fmtutil --refresh
- # fi
- # ;;
- "") echo "$help" >&2; rc=1;;
- *)
- echo "$progname: unknown PAPER \`$3' given as argument for \`$progname pdftex paper'" >&2
- echo "$progname: try \`$progname pdftex paper' for help" >&2
- rc=1 ;;
- esac ;;
- "")
- echo "$help" >&2; rc=1;;
- *)
- echo "$progname: unknown option \`$2' given as argument for \`$progname pdftex'" >&2
- echo "$progname: try \`$progname pdftex' for help" >&2
- rc=1
- ;;
- esac
- ;;
-
- rehash)
- mktexlsr
- ;;
-
- #
- version|--version)
- echo "$progname version $version"
- setupTexmfmain
- setupTexmfdist
- showDistVersionInfo
- (exit 0); exit 0;;
-
- # handle "xdvi paper PAPER"
- xdvi)
- tcBatchXdviPapers='us "8.5x11"
-letter "8.5x11"
-ledger "17x11"
-tabloid "11x17"
-usr "11x8.5"
-legal "8.5x14"
-legalr "14x8.5"
-foolscap "13.5x17.0"
-foolscapr "17.0x13.5"
-a0 "84.1x118.9cm"
-a1 "59.4x84.1cm"
-a2 "42.0x59.4cm"
-a3 "29.7x42.0cm"
-a4 "21.0x29.7cm"
-a5 "14.8x21.0cm"
-a6 "10.5x14.8cm"
-a7 "7.4x10.5cm"
-a8 "5.2x7.4cm"
-a9 "3.7x5.2cm"
-a10 "2.6x3.7cm"
-a0r "118.9x84.1cm"
-a1r "84.1x59.4cm"
-a2r "59.4x42.0cm"
-a3r "42.0x29.7cm"
-a4r "29.7x21.0cm"
-a5r "21.0x14.8cm"
-a6r "14.8x10.5cm"
-a7r "10.5x7.4cm"
-a8r "7.4x5.2cm"
-a9r "5.2x3.7cm"
-a10r "3.7x2.6cm"
-b0 "100.0x141.4cm"
-b1 "70.7x100.0cm"
-b2 "50.0x70.7cm"
-b3 "35.3x50.0cm"
-b4 "25.0x35.3cm"
-b5 "17.6x25.0cm"
-b6 "12.5x17.6cm"
-b7 "8.8x12.5cm"
-b8 "6.2x8.8cm"
-b9 "4.4x6.2cm"
-b10 "3.1x4.4cm"
-b0r "141.4x100.0cm"
-b1r "100.0x70.7cm"
-b2r "70.7x50.0cm"
-b3r "50.0x35.3cm"
-b4r "35.3x25.0cm"
-b5r "25.0x17.6cm"
-b6r "17.6x12.5cm"
-b7r "12.5x8.8cm"
-b8r "8.8x6.2cm"
-b9r "6.2x4.4cm"
-b10r "4.4x3.1cm"
-c0 "91.7x129.7cm"
-c1 "64.8x91.7cm"
-c2 "45.8x64.8cm"
-c3 "32.4x45.8cm"
-c4 "22.9x32.4cm"
-c5 "16.2x22.9cm"
-c6 "11.4x16.2cm"
-c7 "8.1x11.4cm"
-c8 "5.7x8.1cm"
-c9 "4.0x5.7cm"
-c10 "2.8x4.0cm"
-c0r "129.7x91.7cm"
-c1r "91.7x64.8cm"
-c2r "64.8x45.8cm"
-c3r "45.8x32.4cm"
-c4r "32.4x22.9cm"
-c5r "22.9x16.2cm"
-c6r "16.2x11.4cm"
-c7r "11.4x8.1cm"
-c8r "8.1x5.7cm"
-c9r "5.7x4.0cm"
-c10r "4.0x2.8cm"'
- help="Usage: $progname xdvi paper PAPER
-
-Valid PAPER settings:
- a0 a0r a1 a1r a2 a2r a3 a3r a4 a4r a5 a5r a6 a6r a7 a7r a8 a8r a9 a9r a10 a10r
- b0 b0r b1 b1r b2 b2r b3 b3r b4 b4r b5 b5r b6 b6r b7 b7r b8 b8r b9 b9r b10 b10r
- c0 c0r c1 c1r c2 c2r c3 c3r c4 c4r c5 c5r c6 c6r c7 c7r c8 c8r c9 c9r c10 c10r
- us letter ledger tabloid usr legal legalr foolscap foolscapr"
- case $2 in
- paper-list)
- echo "$tcBatchXdviPapers"
- ;;
- paper)
- case $3 in
- [abc][0-9]|[abc]10|[abc][0-9]r|[abc]10r|us|letter|ledger|tabloid|usr|legal|legalr|foolscap|foolscapr)
- tlmgr xdvi paper $3
- # fmgrConfigReplace XDvi paper: "*paper: $3"
- ;;
- "") echo "$help" >&2; rc=1;;
- *)
- echo "$progname: unknown PAPER \`$3' given as argument for \`$progname xdvi paper'" >&2
- echo "$progname: try \`$progname xdvi paper' for help" >&2
- rc=1 ;;
- esac ;;
- "")
- echo "$help" >&2; rc=1;;
- *)
- echo "$progname: unknown option \`$2' given as argument for \`$progname xdvi'" >&2
- echo "$progname: try \`$progname xdvi' for help" >&2
- rc=1
- ;;
- esac
- ;;
- *)
- echo "$progname: unknown option \`$1' given as argument for \`$progname'" >&2
- echo "$progname: try \`$progname help' for help" >&2
- rc=1
- esac
-}
-
-###############################################################################
-# tcInteractive(void)
-# handle interactive mode
-###############################################################################
-tcInteractive()
-{
- texconfig-dialog
-}
-
-###############################################################################
-# main()
-###############################################################################
-rc=0
-case $# in
- 0) tcInteractive;;
- *) tcBatch "$@";;
-esac
-
-cleanup $rc
diff --git a/Build/source/texk/texlive/linked_scripts/texlive-extra/texlinks.sh b/Build/source/texk/texlive/linked_scripts/texlive-extra/texlinks.sh
deleted file mode 100755
index 1f0e3c1ead2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive-extra/texlinks.sh
+++ /dev/null
@@ -1,333 +0,0 @@
-#!/bin/sh
-# $Id: texlinks.sh 53554 2020-01-26 23:58:37Z karl $
-
-# Thomas Esser, 1999, 2002, 2003. public domain.
-
-# texlinks: script to maintain symlinks from format to engine. Interprets
-# the lines given in fmtutil.cnf.
-
-# History:
-# (Further changes in ChangeLog.)
-# Tue Oct 9 14:23:01 BST 2007
-# Added unlink option (-u) to aid OpenBSD package uninstall
-# Edd Barrett <vext01@gmail.com>
-# Sun Aug 28 21:41:06 CEST 2005
-# remove special cases for csplain,cslatex,pdfcslatex,pdfcsplain
-# Fr Apr 8 19:15:05 CEST 2005
-# cleanup now has an argument for the return code
-# So Mar 27 18:52:06 CEST 2005
-# honor $TMPDIR, $TEMP and $TMP, not just $TMP
-# Mon May 10 20:52:48 CEST 2004
-# kpseaccess instead of access
-# Thu Dec 25 22:11:53 CET 2003, te:
-# add version string
-# Tue Apr 9 22:46:34 CEST 2002, te:
-# do not create symlinks for cont-??, metafun and mptopdf
-
-test -f /bin/sh5 && test -z "$RUNNING_SH5" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
-unset RUNNING_SH5
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-export PATH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-version='$Id: texlinks.sh 53554 2020-01-26 23:58:37Z karl $'
-progname=texlinks
-cnf=fmtutil.cnf # name of the config file
-
-usage='Usage: texlinks [OPTION]... [DIRECTORY]...
-
-Create symbolic links format -> engine according to fmtutil setup.
-
-Mandatory arguments to long options are mandatory for short options too.
- -e, --exeext EXT append EXT to symlink targets (default: none)
- -f, --cnffile FILE use FILE as config file (default: fmtutil.cnf)
- -m, --multiplatform operate in all platform specific directories
- (default: operate only in directory for this platform)
- -q, --quiet silently skip existing scripts / binaries
- (default: issue warning)
- -s, --silent same as -q
- -u, --unlink remove symlinks created by texlinks
- -v, --verbose enable verbose messages (default: off)
- -h, --help show this help text
- --version show version string
-
-The DIRECTORY arguments are an optional list of directories in which to
-operate. If no directories are specified and --multiplatform is
-likewise not specified, the directory of this script itself is used.
-With --multiplatform, all child dirs of an upper-level bin/ dir are used.
-
-Report bugs to: tex-k@tug.org
-TeX Live home page: <http://tug.org/texlive/>
-'
-
-# print `errmsg' to stderr and exit with error code 1:
-abort() { errmsg "texlinks: $1."; cleanup 1; }
-
-# error message to stderr:
-errmsg() { echo "$@" >&2; }
-
-# give message to stderr only if "verbose" mode is on:
-verbose_echo() { $verbose && errmsg "$@"; }
-
-# in verbose mode: show command that is executed:
-verbose_do() { verbose_echo "$@"; "$@"; }
-
-# clean up the temp area and exit with proper exit status:
-cleanup()
-{
- rc=$1
- $needsCleanup && test -n "$tmpdir" && test -d "$tmpdir" \
- && { rm -f "$tmpdir"/*; cd /; rmdir "$tmpdir"; }
- exit $rc
-}
-
-###############################################################################
-# setupTmpDir()
-# set up a temp directory and a trap to remove it
-###############################################################################
-setupTmpDir()
-{
- $needsCleanup && return
-
- trap 'cleanup 1' 1 2 3 7 13 15
- needsCleanup=true
- (umask 077; mkdir "$tmpdir") \
- || abort "could not create directory \`$tmpdir'"
-}
-
-
-# search a binary along $PATH:
-check_for_binary()
-{
- testbin=$1
- set x `echo "$PATH" | sed 's/^:/.:/; s/:$/:./; s/::/:.:/g; s/:/ /g'`; shift
- for i
- do
- if [ -x "$i/$testbin" ]; then
- echo "$i/$testbin"
- return 0
- fi
- done
- return 1
-}
-
-
-###############################################################################
-# install_link(dest src)
-# create a symlink like ln -s dest src, but make sure that src is not
-# an existing binary, possibly adding the executable extension if
-# passed on the command.
-###############################################################################
-install_link()
-{
- # make symlink src -> dest
- dest=$1; src=$2
-
- case $src in
- */mf)
- if test "$dest" = mf-nowin; then
- if test -f $selfautoloc/mfw; then
- dest=mfw # name for windows-enabled mf, once upon a time
- verbose_echo "both mfw and mf-nowin exists, $src linked to $dest"
- fi
- if test -f $selfautoloc/mf && test -f $selfautoloc/mf-nowin; then
- # have both mf and mf-nowin binaries. no link.
- verbose_echo "skipped metafont symlink $src -> $dest (special case)"
- return
- fi
- fi
- ;;
- esac
-
- # append .exe if supplied (for cygwin).
- test -n "$exeext" && dest="$dest$exeext"
-
- case $src in
- */cont-??|*/mptopdf)
- # context includes wrapper scripts that create/run these.
- verbose_echo "skipped ConTeXtish symlink $src -> $dest (special case)"
- ;;
- *)
- test "x$src" != "x`(ls -ld $src | awk '{print $NF}') 2>/dev/null`" &&
- rm -f "$src"
-
- if test -f "$src"; then
- if $silent; then :; else
- # i.e., the rm failed.
- errmsg "install_link $src -> $dest failed: file already exists."
- fi
- else
- if echo "$src" | grep '/pdfcsplain$' >/dev/null; then
- # at p.olsak insistence: we have three pdfcsplain entries in
- # fmtutil.cnf with different engines, but the executable link
- # must point to pdftex.
- verbose_echo "forcing pdfcsplain destination to be pdftex"
- dest=pdftex$exeext
- fi
- verbose_do ln -s "$dest" "$src"
- fi
- ;;
- esac
-}
-
-###############################################################################
-# search_symlinkdir()
-# look if $PATH has only symlinks to the real binaries and find that
-# directory. Also check if this directory is writable.
-###############################################################################
-search_symlinkdir()
-{
- kpsewhich=`check_for_binary kpsewhich`
- test -z "$kpsewhich" && return 1
- symlinkdir=`echo $kpsewhich | sed 's@/*kpsewhich$@@'`
- kpseaccess -w "$symlinkdir" || return 1
- touch "$symlinkdir/tl$$"
- if test -f "$selfautoloc/tl$$"; then
- rm -f "$symlinkdir/tl$$"
- return 1
- else
- rm -f "$symlinkdir/tl$$"
- return 0
- fi
-}
-
-###############################################################################
-# upd_symlinkdir()
-# if $PATH has only symlinks to the real binaries, update that directory
-# that holds the symlinks
-###############################################################################
-upd_symlinkdir()
-{
- search_symlinkdir || return 0
- for i in `sed 's@ .*@@' cnf_file_ln.$$`; do
- install_link "$selfautoloc/$i" "$symlinkdir/$i"
- done
-}
-
-###############################################################################
-# rm_link()
-# Delete a previously installed link
-###############################################################################
-rm_link()
-{
- link=$1;
- if test -e $link; then
- if test -h $link; then
- verbose_do rm -Rf $link
- else
- verbose_echo "kept $link, since not a symlink"
- fi
- else
- verbose_echo "skipped $link, non-existent"
- fi
-}
-
-###############################################################################
-# main()
-# parse commandline arguments, initialize variables,
-# switch into temp. direcrory, execute desired command
-###############################################################################
-main()
-{
- cnf_file= # global variable: full name of the config file
- dirs=
- needsCleanup=false
-
- exeext=
- multiplatform=false
- verbose=false
- unlink=false
- silent=false
- thisdir=`pwd`
- : ${KPSE_DOT=$thisdir}; export KPSE_DOT
- selfautoloc=`kpsewhich --expand-var='$SELFAUTOLOC'`
- while
- case $1 in
- --h*|-h)
- echo "$usage"; exit 0;;
- --version)
- echo "$progname version $version"; exit 0;;
- --cnffile|-f)
- shift; cnf_file=$1;;
- --e*|-e) shift; exeext=$1;;
- --m*|-m) multiplatform=true;;
- --s*|-s|--q*|-q) silent=true;;
- --u*|-u) unlink=true;;
- --v*|-v) verbose=true;;
- -*) errmsg "fmtutil: unknown option \`$1' ignored.";;
- *) break;;
- esac
- do test $# -gt 0 && shift; done
- dirs="$*"
-
- # if no cnf_file from command-line, look it up with kpsewhich:
- test -z "$cnf_file" && cnf_file=`kpsewhich --format='web2c files' $cnf`
- test -f "$cnf_file" || abort "config file \`$cnf' not found"
-
-
- tmpdir=${TMPDIR-${TEMP-${TMP-/tmp}}}/texlinks.$$
- setupTmpDir
- cd "$tmpdir" || cleanup 1
-
- sed '/^[ ]*#/d; /^[ ]*$/d' $cnf_file \
- | awk '{print $1, $2}' > cnf_file_ln.$$
-
- if test -z "$dirs"; then
- if test $multiplatform = true; then
- case $selfautoloc in
- */bin) dirs=$selfautoloc;;
- *) parent=`kpsewhich --expand-var='$SELFAUTODIR'`
- dirs=`find $parent -type f -name kpsewhich -print \
- | sed 's@/kpsewhich$@@'`;;
- esac
- else
- dirs=$selfautoloc
- fi
- fi
-
- for d in $dirs; do
- kpseaccess -w $d \
- || { errmsg "$d: no write permissions. Skipping..."; continue; }
- # cnf_file_ln.$$ has lines with "format engine" pairs
- set x `cat cnf_file_ln.$$`; shift
- while test $# != 0; do
- fmt=$1; engine=$2; shift; shift
-
- # Some broken shells destroy the positional arguments when calling a
- # shellfunction. Therefore, we save and restore them "by hand" in the
- # main_args_while variable.
- main_args_while="$@"
-
- test "x$fmt" = "x$engine" && continue
- if test -f "$d/$engine$exeext"; then
- case $unlink in
- true)
- rm_link "$d/$fmt";;
- *)
- install_link "$engine" "$d/$fmt";;
- esac
- else
- verbose_echo "skipped $d/$engine, engine does not exist"
- fi
-
- # restore positional arguments:
- set x $main_args_while; shift
-
- done
- done
- upd_symlinkdir
-}
-
-main ${1+"$@"}
-
-# set successful return code
-cleanup 0
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil-sys.sh b/Build/source/texk/texlive/linked_scripts/texlive/fmtutil-sys.sh
deleted file mode 100755
index 11949ab7f46..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil-sys.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-# $Id: fmtutil-sys.sh 36962 2015-04-20 01:48:35Z preining $
-# fmtutil-sys - arrange for fmtutil to affect system directories.
-# Maintained in Master/texmf-dist/scripts/texlive/
-# Public domain. Originally written by Thomas Esser.
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-exec fmtutil --sys ${1+"$@"}
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil-user.sh b/Build/source/texk/texlive/linked_scripts/texlive/fmtutil-user.sh
deleted file mode 100755
index 032f917310d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil-user.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-# $Id: fmtutil-user.sh 51911 2019-08-19 20:59:22Z karl $
-# fmtutil-user - arrange for fmtutil to affect user directories.
-# Maintained in Master/texmf-dist/scripts/texlive/
-# Public domain. Originally written by Thomas Esser.
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-exec fmtutil --user ${1+"$@"}
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl b/Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl
deleted file mode 100755
index 60d72e60c90..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl
+++ /dev/null
@@ -1,1488 +0,0 @@
-#!/usr/bin/env perl
-# $Id: fmtutil.pl 56682 2020-10-17 06:08:28Z preining $
-# fmtutil - utility to maintain format files.
-# (Maintained in TeX Live:Master/texmf-dist/scripts/texlive.)
-#
-# Copyright 2014-2020 Norbert Preining
-# This file is licensed under the GNU General Public License version 2
-# or any later version.
-#
-# History:
-# Original shell script (C) 2001 Thomas Esser, public domain
-
-my $TEXMFROOT;
-
-BEGIN {
- $^W = 1;
- $TEXMFROOT = `kpsewhich -var-value=TEXMFROOT`;
- if ($?) {
- die "$0: kpsewhich -var-value=TEXMFROOT failed, aborting early.\n";
- }
- chomp($TEXMFROOT);
- unshift(@INC, "$TEXMFROOT/tlpkg", "$TEXMFROOT/texmf-dist/scripts/texlive");
- require "mktexlsr.pl";
- TeX::Update->import();
-}
-
-my $svnid = '$Id: fmtutil.pl 56682 2020-10-17 06:08:28Z preining $';
-my $lastchdate = '$Date: 2020-10-17 08:08:28 +0200 (Sat, 17 Oct 2020) $';
-$lastchdate =~ s/^\$Date:\s*//;
-$lastchdate =~ s/ \(.*$//;
-my $svnrev = '$Revision: 56682 $';
-$svnrev =~ s/^\$Revision:\s*//;
-$svnrev =~ s/\s*\$$//;
-my $version = "r$svnrev ($lastchdate)";
-
-use strict;
-use Getopt::Long qw(:config no_autoabbrev ignore_case_always);
-use File::Basename;
-use File::Copy;
-use File::Spec;
-use Cwd;
-
-# don't import anything automatically, this requires us to explicitly
-# call functions with TeXLive::TLUtils prefix, and makes it easier to
-# find and if necessary remove references to TLUtils
-use TeXLive::TLUtils qw();
-
-require TeXLive::TLWinGoo if TeXLive::TLUtils::win32;
-
-# numerical constants
-my $FMT_NOTSELECTED = 0;
-my $FMT_DISABLED = 1;
-my $FMT_FAILURE = 2;
-my $FMT_SUCCESS = 3;
-my $FMT_NOTAVAIL = 4;
-
-my $nul = (win32() ? 'nul' : '/dev/null');
-my $sep = (win32() ? ';' : ':');
-
-my @deferred_stderr;
-my @deferred_stdout;
-
-(our $prg = basename($0)) =~ s/\.pl$//;
-
-# make sure that the main binary path is available at the front
-TeXLive::TLUtils::prepend_own_path();
-
-# sudo sometimes does not reset the home dir of root, check on that
-# see more comments at the definition of the function itself
-# this function checks by itself whether it is running on windows or not
-reset_root_home();
-
-chomp(our $TEXMFDIST = `kpsewhich --var-value=TEXMFDIST`);
-chomp(our $TEXMFVAR = `kpsewhich -var-value=TEXMFVAR`);
-chomp(our $TEXMFSYSVAR = `kpsewhich -var-value=TEXMFSYSVAR`);
-chomp(our $TEXMFCONFIG = `kpsewhich -var-value=TEXMFCONFIG`);
-chomp(our $TEXMFSYSCONFIG = `kpsewhich -var-value=TEXMFSYSCONFIG`);
-chomp(our $TEXMFHOME = `kpsewhich -var-value=TEXMFHOME`);
-
-# make sure that on windows *everything* is in lower case for comparison
-if (win32()) {
- $TEXMFDIST = lc($TEXMFDIST);
- $TEXMFVAR = lc($TEXMFVAR);
- $TEXMFSYSVAR = lc($TEXMFSYSVAR);
- $TEXMFCONFIG = lc($TEXMFCONFIG);
- $TEXMFSYSCONFIG = lc($TEXMFSYSCONFIG);
- $TEXMFROOT = lc($TEXMFROOT);
- $TEXMFHOME = lc($TEXMFHOME);
-}
-
-#
-# these need to be our since they are used from the
-# functions in TLUtils.pm
-our $texmfconfig = $TEXMFCONFIG;
-our $texmfvar = $TEXMFVAR;
-our $alldata;
-# command line options with defaults
-# 20160623 - switch to turn on strict mode
-our %opts = ( quiet => 0 , strict => 1 );
-
-# make a list of all the commands (as opposed to options), so we can
-# reasonably check for multiple commands being (erroneously) given.
-my @cmdline_cmds = ( # in same order as help message
- "all",
- "missing",
- "refresh",
- "byengine=s",
- "byfmt=s",
- "byhyphen=s",
- "enablefmt=s",
- "disablefmt=s",
- "listcfg",
- "showhyphen=s",
-);
-
-our @cmdline_options = ( # in same order as help message
- "sys",
- "user",
- "cnffile=s@",
- "fmtdir=s",
- "no-engine-subdir",
- "no-error-if-no-engine=s",
- "no-error-if-no-format",
- "nohash",
- "recorder",
- "strict!",
- "quiet|silent|q",
- "catcfg",
- "dolinks",
- "force",
- "test",
-#
- @cmdline_cmds,
- "version",
- "help|h",
-#
- "edit", # omitted from help to discourage use
- "_dumpdata", # omitted from help, data structure dump for debugging
- );
-
-my $updLSR;
-my $mktexfmtMode = 0;
-# make sure we echo only *one* line in mktexfmt mode
-my $mktexfmtFirst = 1;
-
-my $status = &main();
-print_info("exiting with status $status\n");
-exit $status;
-
-
-#
-sub main {
- if ($prg eq "mktexfmt") {
- # mktexfmtMode: if called as mktexfmt, set to true. Will echo the
- # first generated filename after successful generation to stdout then
- # (and nothing else), since kpathsea can only deal with one.
- $mktexfmtMode = 1;
-
- # TODO TODO
- # which mode are we running in?
- # what happens if root runs mktexfmt?
- $opts{'user'} = 1;
-
- GetOptions ( "help" => \$opts{'help'}, "version" => \$opts{'version'} )
- || die "$prg: Unknown option in mktexfmt command line arguments.\n";
- if ($ARGV[0]) {
- if ($ARGV[0] =~ m/^(.*)\.(fmt|mem|base?)$/) {
- $opts{'byfmt'} = $1;
- } elsif ($ARGV[0] =~ m/\./) {
- die "unknown format type: $ARGV[0]";
- } else {
- $opts{'byfmt'} = $ARGV[0];
- }
- } else {
- die "missing argument to mktexfmt";
- }
- } else {
- # fmtutil mode.
- GetOptions(\%opts, @cmdline_options)
- || die "Try \"$prg --help\" for more information.\n";
- if (@ARGV) {
- die "$0: Unexpected non-option argument(s): @ARGV\n"
- . "Try \"$prg --help\" for more information.\n";
- }
- }
-
- help() if $opts{'help'};
- if ($opts{'version'}) {
- print version();
- exit 0; # no final print_info
- }
-
- { # if two commands were given, complain and give up.
- my @cmds = ();
- for my $c (@cmdline_cmds) {
- $c =~ s,=.*$,,; # remove =s getopt spec
- push(@cmds, $c) if exists $opts{$c}; # remember if getopt found it
- # we could save/report the specified arg too, but maybe not worth it.
- }
- if (@cmds > 1) {
- print_error("multiple commands found: @cmds\n"
- . "Try $prg --help if you need it.\n");
- return 1;
- } elsif (@cmds == 0) {
- print_error("no command specified; try $prg --help if you need it.\n");
- return 1;
- }
- }
-
- # these two functions should go to TLUtils (for use in updmap)
- ($texmfconfig, $texmfvar) =
- TeXLive::TLUtils::setup_sys_user_mode($prg, \%opts,
- $TEXMFCONFIG, $TEXMFSYSCONFIG, $TEXMFVAR, $TEXMFSYSVAR);
-
- determine_config_files("fmtutil.cnf");
- my $changes_config_file = $alldata->{'changes_config'};
- # we do changes always in the used config file with the highest priority
- my $bakFile = $changes_config_file;
- $bakFile =~ s/\.cfg$/.bak/;
- my $changed = 0;
-
- read_fmtutil_files(@{$opts{'cnffile'}});
-
- unless ($opts{"nohash"}) {
- # should be replaced by new mktexlsr perl version
- $updLSR = new TeX::Update;
- $updLSR->mustexist(0);
- }
-
- my $cmd;
- if ($opts{'edit'}) {
- if ($opts{"dry-run"}) {
- printf STDERR "No, are you joking, you want to edit with --dry-run?\n";
- return 1;
- }
- # it's not a good idea to edit fmtutil.cnf manually these days,
- # but for compatibility we'll silently keep the option.
- $cmd = 'edit';
- my $editor = $ENV{'VISUAL'} || $ENV{'EDITOR'};
- $editor ||= (&win32 ? "notepad" : "vi");
- if (-r $changes_config_file) {
- &copyFile($changes_config_file, $bakFile);
- } else {
- touch($bakFile);
- touch($changes_config_file);
- }
- system($editor, $changes_config_file);
- $changed = files_are_different($bakFile, $changes_config_file);
-
- } elsif ($opts{'showhyphen'}) {
- my $f = $opts{'showhyphen'};
- if ($alldata->{'merged'}{$f}) {
- my @all_engines = keys %{$alldata->{'merged'}{$f}};
- for my $e (sort @all_engines) {
- my $hf = $alldata->{'merged'}{$f}{$e}{'hyphen'};
- next if ($hf eq '-');
- my $ff = `kpsewhich -progname='$f' -format=tex '$hf'`;
- chomp($ff);
- if ($ff ne "") {
- if ($#all_engines > 0) {
- printf "$f/$e: ";
- }
- printf "$ff\n";
- } else {
- print_warning("hyphenfile (for $f/$e) not found: $hf\n");
- return 1;
- }
- }
- }
-
- } elsif ($opts{'listcfg'}) {
- return callback_list_cfg();
-
- } elsif ($opts{'disablefmt'}) {
- return callback_enable_disable_format($changes_config_file,
- $opts{'disablefmt'}, 'disabled');
- } elsif ($opts{'enablefmt'}) {
- return callback_enable_disable_format($changes_config_file,
- $opts{'enablefmt'}, 'enabled');
- } elsif ($opts{'byengine'}) {
- return callback_build_formats('byengine', $opts{'byengine'});
-
- } elsif ($opts{'byfmt'}) {
- # for this option, allow/ignore an extension.
- (my $fmtname = $opts{'byfmt'}) =~ s,\.(fmt|mem|base?)$,,;
- return callback_build_formats('byfmt', $fmtname);
-
- } elsif ($opts{'byhyphen'}) {
- return callback_build_formats('byhyphen', $opts{'byhyphen'});
-
- } elsif ($opts{'refresh'}) {
- return callback_build_formats('refresh');
-
- } elsif ($opts{'missing'}) {
- return callback_build_formats('missing');
-
- } elsif ($opts{'all'}) {
- return callback_build_formats('all');
-
- } elsif ($opts{'_dumpdata'}) {
- dump_data();
-
- } else {
- # redundant with check above, but just in case ...
- print_error("missing command; try $prg --help if you need it.\n");
- return 1;
- }
-
- unless ($opts{'nohash'}) {
- # TODO should only do this if built something, e.g., not --listcfg
- print_info("updating ls-R files\n");
- $updLSR->exec() unless $opts{"dry-run"};
- }
-
- # some simpler options
- return 0;
-}
-
-sub dump_data {
- require Data::Dumper;
- $Data::Dumper::Indent = 1;
- $Data::Dumper::Indent = 1;
- print Data::Dumper::Dumper($alldata);
-}
-
-
-# callback_build_formats - (re)builds the formats as selected,
-# returns exit status or dies. Exit status is always zero unless
-# --strict is specified, in which case it's the number of failed builds
-# (presumably always less than 256 :).
-#
-sub callback_build_formats {
- my ($what, $whatarg) = @_;
-
- # set up a tmp dir
- # On W32 it seems that File::Temp creates restrictive permissions (ok)
- # that are copied over with the files created inside it (not ok).
- # So make our own temp dir.
- my $tmpdir;
- if (win32()) {
- my $foo;
- my $tmp_deflt = File::Spec->tmpdir;
- for my $i (1..5) {
- # $foo = "$texmfvar/temp.$$." . int(rand(1000000));
- $foo = (($texmfvar =~ m!^//!) ? $tmp_deflt : $texmfvar)
- . "/temp.$$." . int(rand(1000000));
- if (! -d $foo) {
- TeXLive::TLUtils::mkdirhier($foo);
- sleep 1;
- if (-d $foo) {
- $tmpdir = $foo;
- last;
- }
- }
- }
- if (! $tmpdir) {
- die "Cannot get a temporary directory after five iterations ... sorry!";
- }
- if ($texmfvar =~ m!^//!) {
- # used File::Spec->tmpdir; fix permissions
- TeXLive::TLWinGoo::maybe_make_ro ($tmpdir);
- }
- } else {
- $tmpdir = File::Temp::tempdir(CLEANUP => 1);
- }
- # set up destination directory
- $opts{'fmtdir'} ||= "$texmfvar/web2c";
- TeXLive::TLUtils::mkdirhier($opts{'fmtdir'}) if (! -d $opts{'fmtdir'});
- if (! -w $opts{'fmtdir'}) {
- print_error("format directory not writable: $opts{fmtdir}\n");
- exit 1;
- }
- # since the directory does not exist, we can make it absolute with abs_path
- # without any trickery around non-existing dirs
- $opts{'fmtdir'} = Cwd::abs_path($opts{'fmtdir'});
- # for safety, check again
- die "abs_path failed, strange: $!" if !$opts{'fmtdir'};
- print_info("writing formats under $opts{fmtdir}\n"); # report
-
- # code taken over from the original shell script for KPSE_DOT etc
- my $thisdir = cwd();
- $ENV{'KPSE_DOT'} = $thisdir;
-
- # due to KPSE_DOT, we don't search the current directory, so include
- # it explicitly for formats that \write and later on \read
- $ENV{'TEXINPUTS'} ||= "";
- $ENV{'TEXINPUTS'} = "$tmpdir$sep$ENV{TEXINPUTS}";
- #
- # for formats that load other formats (e.g., jadetex loads latex.fmt),
- # add the current directory to TEXFORMATS, too. Currently unnecessary
- # for MFBASES and MPMEMS.
- $ENV{'TEXFORMATS'} ||= "";
- $ENV{'TEXFORMATS'} = "$tmpdir$sep$ENV{TEXFORMATS}";
-
- # switch to temporary directory for format generation
- chdir($tmpdir) || die "Cannot change to directory $tmpdir: $!";
-
- # we rebuild formats in two rounds:
- # round 1: only formats with the same name as engine (pdftex/pdftex)
- # round 2: all other formats
- # reason: later formats might need earlier formats to be already
- # initialized, e.g., xmltex.
- my $suc = 0;
- my $err = 0;
- my @err = ();
- my $disabled = 0;
- my $nobuild = 0;
- my $notavail = 0;
- my $total = 0;
- for my $swi (qw/format=engine format!=engine/) {
- for my $fmt (keys %{$alldata->{'merged'}}) {
- for my $eng (keys %{$alldata->{'merged'}{$fmt}}) {
- next if ($swi eq "format=engine" && $fmt ne $eng);
- next if ($swi eq "format!=engine" && $fmt eq $eng);
- $total++;
- my $val = select_and_rebuild_format($fmt, $eng, $what, $whatarg);
- if ($val == $FMT_DISABLED) { $disabled++; }
- elsif ($val == $FMT_NOTSELECTED) { $nobuild++; }
- elsif ($val == $FMT_FAILURE) { $err++; push (@err, "$eng/$fmt"); }
- elsif ($val == $FMT_SUCCESS) { $suc++; }
- elsif ($val == $FMT_NOTAVAIL) { $notavail++; }
- else { print_error("callback_build_format (round 1): unknown return "
- . "from select_and_rebuild.\n"); }
- }
- }
- }
-
- # if the user asked to rebuild something, but we did nothing, report
- # unless we tried to rebuild only missing formats.
- if ($what ne "missing") {
- if ($err + $suc == 0) {
- if ($what eq "all") {
- print_warning("You seem to have no formats defined in your fmtutil.cnf files!\n");
- } else {
- print_info("Did not find entry for $what=" . ($whatarg?$whatarg:"") . " skipped\n");
- }
- }
- }
- my $stdo = ($mktexfmtMode ? \*STDERR : \*STDOUT);
- for (@deferred_stdout) { print $stdo $_; }
- for (@deferred_stderr) { print STDERR $_; }
- #
- print_info("disabled formats: $disabled\n") if ($disabled);
- print_info("successfully rebuilt formats: $suc\n") if ($suc);
- print_info("not selected formats: $nobuild\n") if ($nobuild);
- print_info("not available formats: $notavail\n") if ($notavail);
- print_info("failed to build: $err (@err)\n") if ($err);
- print_info("total formats: $total\n");
- chdir($thisdir) || warn "chdir($thisdir) failed: $!";
- if (win32()) {
- # try to remove the tmpdir with all files
- TeXLive::TLUtils::rmtree($tmpdir);
- }
- # return
- return $opts{"strict"} ? $err : 0;
-}
-
-# select_and_rebuild_format
-# check condition and rebuild the format if selected
-# return values: $FMT_*
-#
-sub select_and_rebuild_format {
- my ($fmt, $eng, $what, $whatarg) = @_;
- return $FMT_DISABLED
- if ($alldata->{'merged'}{$fmt}{$eng}{'status'} eq 'disabled');
-
- my ($kpsefmt, $destdir, $fmtfile, $logfile) = compute_format_destination($fmt, $eng);
-
- my $doit = 0;
- # we just identify 'all', 'refresh', 'missing'
- # I don't see much point in keeping all of them
- $doit = 1 if ($what eq 'all');
- $doit = 1 if ($what eq 'refresh' && -r "$destdir/$fmtfile");
- $doit = 1 if ($what eq 'missing' && ! -r "$destdir/$fmtfile");
- $doit = 1 if ($what eq 'byengine' && $eng eq $whatarg);
- $doit = 1 if ($what eq 'byfmt' && $fmt eq $whatarg);
- # TODO
- # original fmtutil.sh was stricter about existence of the hyphen file
- # not sure how we proceed here; let's implicitly ignore.
- #
- # original fmtutil.sh seemed to have accepted full path to the hyphen
- # file, so that one could give
- # --byhyphen /full/path/to/the/hyphen/file
- # but this does not work anymore (see Debian bug report #815416)
- if ($what eq 'byhyphen') {
- my $fmthyp = (split(/,/ , $alldata->{'merged'}{$fmt}{$eng}{'hyphen'}))[0];
- if ($fmthyp ne '-') {
- if ($whatarg =~ m!^/!) {
- # $whatarg is a full path, we need to expand $fmthyp, too
- chomp (my $fmthyplong = `kpsewhich -progname=$fmt -engine=$eng $fmthyp`) ;
- if ($fmthyplong) {
- $fmthyp = $fmthyplong;
- } else {
- # we might have searched language.dat --engine=tex --progname=tex
- # which will not work. Search again without engine/format
- chomp ($fmthyplong = `kpsewhich $fmthyp`) ;
- if ($fmthyplong) {
- $fmthyp = $fmthyplong;
- } else {
- # don't give warnings or errors, it might be that the hyphen
- # file is not existing at all. See TODO above
- #print_deferred_warning("hyphen $fmthyp for $fmt/$eng cannot be expanded.\n");
- }
- }
- }
- if ($whatarg eq $fmthyp) {
- $doit = 1;
- }
- }
- }
- if ($doit) {
- return rebuild_one_format($fmt,$eng,$kpsefmt,$destdir,$fmtfile,$logfile);
- } else {
- return $FMT_NOTSELECTED;
- }
-}
-
-# compute_format_destination
-# takes fmt/eng and returns the locations where format and log files
-# should be saved, that is, a list: (dump file full path, log file full path)
-#
-sub compute_format_destination {
- my ($fmt, $eng) = @_;
- my $enginedir;
- my $fmtfile = $fmt;
- my $kpsefmt;
- my $destdir;
-
- if ($eng eq "mpost") {
- $fmtfile .= ".mem" ;
- $kpsefmt = "mp" ;
- $enginedir = "metapost"; # the directory, not the executable
- } elsif ($eng =~ m/^mf(lua(jit)?)?(w|-nowin)?$/) {
- $fmtfile .= ".base" ;
- $kpsefmt = "mf" ;
- $enginedir = "metafont" ;
- } else {
- $fmtfile .= ".fmt" ;
- $kpsefmt = "tex" ;
- $enginedir = $eng;
- # strip final -dev from enginedir to support engines like luatex-dev
- $enginedir =~ s/-dev$//;
- }
- if ($opts{'no-engine-subdir'}) {
- $destdir = $opts{'fmtdir'};
- } else {
- $destdir = "$opts{'fmtdir'}/$enginedir";
- }
- return($kpsefmt, $destdir, $fmtfile, "$fmt.log");
-}
-
-
-# rebuild_one_format
-# takes fmt/eng and rebuilds it, irrelevant of any setting;
-# copies generated log file
-# return value FMT_*
-#
-sub rebuild_one_format {
- my ($fmt,$eng,$kpsefmt,$destdir,$fmtfile,$logfile) = @_;
- print_info("--- remaking $fmt with $eng\n");
-
- # get variables
- my $hyphen = $alldata->{'merged'}{$fmt}{$eng}{'hyphen'};
- my $addargs = $alldata->{'merged'}{$fmt}{$eng}{'args'};
-
- # running parameters
- my $jobswitch = "-jobname=$fmt";
- my $prgswitch = "-progname=" ;
- my $recorderswitch = ($opts{'recorder'} ? "-recorder" : "");
- my $pool;
- my $tcx = "";
- my $tcxflag = "";
- my $localpool = 0;
- my $texargs;
-
- unlink glob "*.pool";
-
- # addargs processing:
- # can contain:
- # nls stuff (pool/tcx) see below
- # ini file (last argument)
- my $inifile = $addargs;
- $inifile = (split(' ', $addargs))[-1];
- # get rid of leading * in inifiles
- $inifile =~ s/^\*//;
-
- if ($fmt eq "metafun") { $prgswitch .= "mpost"; }
- elsif ($fmt eq "mptopdf") { $prgswitch .= "context"; }
- elsif ($fmt =~ m/^cont-..$/) { $prgswitch .= "context"; }
- else { $prgswitch .= $fmt; }
-
- # check for existence of ini file before doing anything else
- if (system("kpsewhich -progname=$fmt -format=$kpsefmt $inifile >$nul 2>&1") != 0) {
- # we didn't find the ini file, skip
- print_deferred_warning("inifile $inifile for $fmt/$eng not found.\n");
- # The original script just skipped it but in TeX Live we expect that
- # all activated formats are also buildable, thus return failure.
- return $FMT_FAILURE;
- }
-
- #
- # If the 4th field in fmtutil.cnf contains
- # -progname=...
- # then we do not add our own progname!
- if ($addargs =~ /-progname=/) {
- $prgswitch = '';
- }
-
- # NLS support
- # Example (for fmtutil.cnf):
- # mex-pl tex mexconf.tex nls=tex-pl,il2-pl mex.ini
- # The nls parameter (pool,tcx) can only be specified as the first argument
- # inside the 4th field in fmtutil.cnf.
- if ($addargs =~ m/^nls=([^\s]+)\s+(.*)$/) {
- $texargs = $2;
- ($pool, $tcx) = split(',', $1);
- $tcx || ($tcx = '');
- } else {
- $texargs = $addargs;
- }
- if ($pool) {
- chomp (my $poolfile = `kpsewhich -progname=$eng $pool.pool 2>$nul`);
- if ($poolfile && -f $poolfile) {
- print_verbose("attempting to create localized format "
- . "using pool=$pool and tcx=$tcx.\n");
- File::Copy::copy($poolfile, "$eng.pool");
- $tcxflag = "-translate-file=$tcx" if ($tcx);
- $localpool = 1;
- }
- }
-
- # Check for infinite recursion before running the iniengine:
- # We do this check only if we are running in mktexfmt mode
- # otherwise double format definitions will create an infinite loop, too
- if ($mktexfmtMode) {
- if ($ENV{'mktexfmt_loop'}) {
- if ($ENV{'mktexfmt_loop'} =~ m!:$fmt/$eng:!) {
- die "$prg: infinite recursion detected in $fmt/$eng, giving up!";
- }
- } else {
- $ENV{'mktexfmt_loop'} = '';
- }
- $ENV{'mktexfmt_loop'} .= ":$fmt/$eng:";
- }
-
- #
- # check for existence of $engine
- # we do *NOT* use the return value but rely on execution of the shell
- if (!TeXLive::TLUtils::which($eng)) {
- if ($opts{'no-error-if-no-engine'} &&
- ",$opts{'no-error-if-no-engine'}," =~ m/,$eng,/) {
- return $FMT_NOTAVAIL;
- } else {
- print_deferred_error("not building $fmt due to missing engine: $eng\n");
- return $FMT_FAILURE;
- }
- }
-
- my $cmdline = "$eng -ini $tcxflag $recorderswitch $jobswitch "
- . "$prgswitch $texargs";
- print_verbose("running \`$cmdline' ...\n");
-
- {
- my $texpool = $ENV{'TEXPOOL'};
- if ($localpool) {
- $ENV{'TEXPOOL'} = cwd() . $sep . ($texpool ? $texpool : "");
- }
-
- # in mktexfmtMode we must redirect *all* output to stderr
- $cmdline .= " >&2" if $mktexfmtMode;
- $cmdline .= " <$nul";
- my $retval = system($cmdline);
-
- # report error if it failed.
- if ($retval != 0) {
- $retval /= 256 if ($retval > 0);
- print_deferred_error("running \`$cmdline' return status: $retval\n");
- }
-
- # Copy the log file after the program is run, so that the log file
- # is available to inspect even on failure. So we need the dest dir tree.
- TeXLive::TLUtils::mkdirhier($destdir);
- #
- # Here and in the following we use copy instead of move
- # to make sure that in SElinux enabled cases the rules of
- # the destination directory are applied.
- # See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=900580
- if (File::Copy::copy($logfile, "$destdir/$logfile")) {
- print_info("log file copied to: $destdir/$logfile\n");
- } else {
- print_deferred_error("cannot copy log $logfile to: $destdir\n");
- }
-
- # original shell script did *not* check the return value
- # we keep this behavior, but add an option --strict that
- # errors out on all failures.
- if ($retval != 0 && $opts{'strict'}) {
- print_deferred_error("returning error due to option --strict\n");
- return $FMT_FAILURE;
- }
-
- if ($localpool) {
- if ($texpool) {
- $ENV{'TEXPOOL'} = $texpool;
- } else {
- delete $ENV{'TEXPOOL'};
- }
- }
- }
-
- # check and install of fmt and log files
- if (! -f $fmtfile) {
- print_deferred_error("\`$cmdline' failed (no $fmtfile)\n");
- return $FMT_FAILURE;
- }
-
- if (! -f $logfile) {
- print_deferred_error("no log file generated for $fmt/$eng, strange\n");
- return $FMT_FAILURE;
- }
-
- open (LOGFILE, "<$logfile")
- || print_deferred_warning("cannot open $logfile, strange: $!\n");
- my @logfile = <LOGFILE>;
- close LOGFILE;
- if (grep(/^!/, @logfile) > 0) {
- print_deferred_error("\`$cmdline' had errors.\n");
- }
-
- if ($opts{'recorder'}) {
- # the recorder output is used by tl-check-fmttriggers to determine
- # package dependencies for each format. Unfortunately omega-based
- # engines gratuitiously changed the extension from .fls to .ofl.
- my $recfile = $fmt . ($fmt =~ m/^(aleph|lamed)$/ ? ".ofl" : ".fls");
- if (!File::Copy::copy($recfile, "$destdir/$recfile")) {
- print_deferred_error("cannot copy recorder $recfile to: $destdir\n");
- }
- }
-
- my $destfile = "$destdir/$fmtfile";
- if (File::Copy::copy($fmtfile, $destfile )) {
- print_info("$destfile installed.\n");
- #
- # original fmtutil.sh did some magic trick for mplib-luatex.mem
- #
- # nowadays no mplib mem is created and all files loaded
- # so we comment and do not convert this
- #
- # As a special special case, we create mplib-luatex.mem for use by
- # the mplib embedded in luatex if it doesn't already exist. (We
- # never update it if it does exist.)
- #
- # This is used by the luamplib package. This way, an expert user
- # who wants to try a new version of luatex (hence with a new
- # version of mplib) can manually update mplib-luatex.mem without
- # having to tamper with mpost itself.
- #
- # if test "x$format" = xmpost && test "x$engine" = xmpost; then
- # mplib_mem_name=mplib-luatex.mem
- # mplib_mem_file=$fulldestdir/$mplib_mem_name
- # if test \! -f $mplib_mem_file; then
- # verboseMsg "$progname: copying $destfile to $mplib_mem_file"
- # if cp "$destfile" "$mplib_mem_file" </dev/null; then
- # mktexupd "$fulldestdir" "$mplib_mem_name"
- # else
- # # failure to copy merits failure handling: e.g., full file system.
- # log_failure "cp $destfile $mplib_mem_file failed."
- # fi
- # else
- # verboseMsg "$progname: $mplib_mem_file already exists, not updating."
- # fi
- # fi
-
- if ($mktexfmtMode && $mktexfmtFirst) {
- print "$destfile\n";
- $mktexfmtFirst = 0;
- }
-
- unless ($opts{'nohash'}) {
- $updLSR->add($destfile);
- $updLSR->exec();
- $updLSR->reset();
- }
-
- return $FMT_SUCCESS;
-
- } else {
- print_deferred_error("cannot copy format $fmtfile to: $destfile\n");
- if (-f $destfile) {
- # remove the empty file possibly left over if near-full file system.
- print_verbose("removing partial file after copy failure: $destfile\n");
- unlink($destfile)
- || print_deferred_error("unlink($destfile) failed: $!\n");
- }
- return $FMT_FAILURE;
- }
-
- print_deferred_error("we should not be here! $fmt/$eng\n");
- return $FMT_FAILURE;
-}
-
-
-#
-# enable_disable_format_engine
-# assumes that format/engine is already defined somewhere,
-# i.e., it $alldata->{'merged'}{$fmt}{$eng} is defined
-#
-# Return values:
-# 1 - success with changes
-# 0 - no changes done
-# -1 - error appeared
-sub enable_disable_format_engine {
- my ($tc, $fmt, $eng, $mode) = @_;
- if ($mode eq 'enabled' || $mode eq 'disabled') {
- if ($alldata->{'merged'}{$fmt}{$eng}{'status'} eq $mode) {
- print_info("Format/engine combination $fmt/$eng already $mode.\n");
- print_info("No changes done.\n");
- return 0;
- } else {
- my $origin = $alldata->{'merged'}{$fmt}{$eng}{'origin'};
- if ($origin ne $tc) {
- $alldata->{'fmtutil'}{$tc}{'formats'}{$fmt}{$eng} =
- {%{$alldata->{'fmtutil'}{$origin}{'formats'}{$fmt}{$eng}}};
- $alldata->{'fmtutil'}{$tc}{'formats'}{$fmt}{$eng}{'line'} = -1;
- }
- $alldata->{'fmtutil'}{$tc}{'formats'}{$fmt}{$eng}{'status'} = $mode;
- $alldata->{'fmtutil'}{$tc}{'changed'} = 1;
- $alldata->{'merged'}{$fmt}{$eng}{'status'} = $mode;
- $alldata->{'merged'}{$fmt}{$eng}{'origin'} = $tc;
- # dump_data();
- return save_fmtutil($tc);
- }
- } else {
- print_error("enable_disable_format_engine: unknown mode $mode\n");
- exit 1;
- }
-}
-
-#
-# enable a format named
-# format[/engine]
-# where the engine part is optional
-# Case 1: no "engine" given:
-# - if format is defined and has only one engine instance -> activate
-# - if format is defined and has more than one engine -> error
-# Case 2: engine given:
-# - if format/engine is defined -> activate
-# - if format/engine is not defined -> error
-#
-# Return values:
-# 1 - success with changes
-# 0 - no changes done
-# -1 - error appeared
-sub callback_enable_disable_format {
- my ($tc, $fmtname, $mode) = @_;
- my ($fmt, $eng) = split('/', $fmtname, 2);
- if ($mode ne 'enabled' && $mode ne 'disabled') {
- print_error("callback_enable_disable_format: unknown mode $mode.\n");
- exit 1;
- }
- if ($eng) {
- if ($alldata->{'merged'}{$fmt}{$eng}) {
- return enable_disable_format_engine($tc, $fmt, $eng, $mode);
- } else {
- print_warning("Format/engine combination $fmt/$eng is not defined.\n");
- print_warning("Cannot (de)activate it.\n");
- return -1;
- }
- } else {
- # no engine given, check the number of entries
- if ($alldata->{'merged'}{$fmt}) {
- my @engs = keys %{$alldata->{'merged'}{$fmt}};
- if (($#engs > 0) || ($#engs == -1)) {
- print_warning("Selected format $fmt not uniquely defined;\n");
- print_warning("possible format/engine combinations:\n");
- for my $e (@engs) {
- print_warning(" $fmt/$e (currently "
- . $alldata->{'merged'}{$fmt}{$e}{'status'} . ")\n");
- }
- print_warning("Please select one by fully specifying $fmt/ENGINE\n");
- print_warning("No changes done.\n");
- return 0;
- } else {
- # only one engine, enable it if necessary!
- return enable_disable_format_engine($tc, $fmt, $engs[0], $mode);
- }
- } else {
- print_warning("Format $fmt is not defined;\n");
- print_warning("cannot (de)activate it.\n");
- return -1;
- }
- }
-}
-
-
-sub callback_list_cfg {
- my @lines;
- for my $f (keys %{$alldata->{'merged'}}) {
- for my $e (keys %{$alldata->{'merged'}{$f}}) {
- my $orig = $alldata->{'merged'}{$f}{$e}{'origin'};
- my $hyph = $alldata->{'merged'}{$f}{$e}{'hyphen'};
- my $stat = $alldata->{'merged'}{$f}{$e}{'status'};
- my $args = $alldata->{'merged'}{$f}{$e}{'args'};
- push @lines,
- [ "$f/$e/$hyph",
- "$f (engine=$e) $stat\n hyphen=$hyph, args=$args\n origin=$orig\n" ];
- }
- }
- # sort lines
- @lines = map { $_->[1] } sort { $a->[0] cmp $b->[0] } @lines;
- print "List of all formats:\n";
- print @lines;
-
- return @lines == 0; # only return failure if no formats.
-}
-
-
-# sets %alldata.
-#
-sub read_fmtutil_files {
- my (@l) = @_;
- for my $l (@l) { read_fmtutil_file($l); }
- # in case the changes_config is a new one read it in and initialize it here
- # the file might be already readable but not in ls-R so not found by
- # kpsewhich. That means we need to check that it is readable and whether
- # the lines entry is already defined
- my $cc = $alldata->{'changes_config'};
- if ((! -r $cc) || (!$alldata->{'fmtutil'}{$cc}{'lines'}) ) {
- $alldata->{'fmtutil'}{$cc}{'lines'} = [ ];
- }
- #
- $alldata->{'order'} = \@l;
- #
- # determine the origin of all formats
- for my $fn (reverse @l) {
- my @format_names = keys %{$alldata->{'fmtutil'}{$fn}{'formats'}};
- for my $f (@format_names) {
- for my $e (keys %{$alldata->{'fmtutil'}{$fn}{'formats'}{$f}}) {
- $alldata->{'merged'}{$f}{$e}{'origin'} = $fn;
- $alldata->{'merged'}{$f}{$e}{'hyphen'} =
- $alldata->{'fmtutil'}{$fn}{'formats'}{$f}{$e}{'hyphen'} ;
- $alldata->{'merged'}{$f}{$e}{'status'} =
- $alldata->{'fmtutil'}{$fn}{'formats'}{$f}{$e}{'status'} ;
- $alldata->{'merged'}{$f}{$e}{'args'} =
- $alldata->{'fmtutil'}{$fn}{'formats'}{$f}{$e}{'args'} ;
- }
- }
- }
-}
-
-#
-sub read_fmtutil_file {
- my $fn = shift;
- open(FN, "<$fn") || die "Cannot read $fn: $!";
- #
- # we count lines from 0 ..!!!!?
- my $i = -1;
- my $printline = 0; # but not in error messages
- my @lines = <FN>;
- chomp(@lines);
- $alldata->{'fmtutil'}{$fn}{'lines'} = [ @lines ];
- close(FN) || warn("$prg: Cannot close $fn: $!");
- for (@lines) {
- $i++;
- $printline++;
- chomp;
- my $orig_line = $_;
- next if /^\s*#?\s*$/; # ignore empty and all-blank and just-# lines
- next if /^\s*#[^!]/; # ignore whole-line comment that is not a disable
- s/#[^!].*//; # remove within-line comment that is not a disable
- s/#$//; # remove # at end of line
- my ($a,$b,$c,@rest) = split (' '); # special split rule, leading ws ign
- if (! $b) { # as in: "somefmt"
- print_warning("no engine specified for format $a, ignoring "
- . "(file $fn, line $printline)\n");
- next;
- }
- if (! $c) { # as in: "somefmt someeng"
- print_warning("no pattern argument specified for $a/$b, ignoring line: "
- . "$orig_line (file $fn, line $printline)\n");
- next;
- }
- if (@rest == 0) { # as in: "somefmt someeng somepat"
- print_warning("no inifile argument(s) specified for $a/$b, ignoring line: "
- . "$orig_line (file $fn, line $printline)\n");
- next;
- }
- my $disabled = 0;
- if ($a eq "#!") {
- # we cannot feasibly determine whether a line is a proper fmtline or
- # not, so we have to assume that it is as long as we have four args.
- my $d = shift @rest;
- if (!defined($d)) {
- print_warning("apparently not a real disable line, ignoring: "
- . "$orig_line (file $fn, line $printline)\n");
- next;
- } else {
- $disabled = 1;
- $a = $b; $b = $c; $c = $d;
- }
- }
- if (defined($alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b})) {
- print_warning("double mention of $a/$b in $fn\n");
- } else {
- $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'hyphen'} = $c;
- $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'args'} = "@rest";
- $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'status'}
- = ($disabled ? 'disabled' : 'enabled');
- $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'line'} = $i;
- }
- }
-}
-
-
-
-#
-# FUNCTIONS THAT SHOULD GO INTO TLUTILS.PM
-# and also be reused in updmap.pl!!!
-
-
-# sets global $alldata->{'changes_config'} to the config file to be
-# changed if requested.
-#
-sub determine_config_files {
- my $fn = shift;
-
- # config file for changes
- my $changes_config_file;
-
- # determine which config files should be used
- # we also determine here where changes will be saved to
- if ($opts{'cnffile'}) {
- my @tmp;
- for my $f (@{$opts{'cnffile'}}) {
- if (! -f $f) {
- # if $f is a pure file name, that is dirname $f == ".",
- # then try to find it via kpsewhich
- if (dirname($f) eq ".") {
- chomp(my $kpfile = `kpsewhich $f`);
- if ($kpfile ne "") {
- $f = $kpfile;
- } else {
- die "$prg: Config file \"$f\" cannot be found via kpsewhich";
- }
- } else {
- die "$prg: Config file \"$f\" not found";
- }
- }
- push @tmp, (win32() ? lc($f) : $f);
- }
- @{$opts{'cnffile'}} = @tmp;
- # in case that config files are given on the command line, the first
- # in the list is the one where changes will be written to.
- ($changes_config_file) = @{$opts{'cnffile'}};
- } else {
- my @all_files = `kpsewhich -all $fn`;
- chomp(@all_files);
- my @used_files;
- for my $f (@all_files) {
- push @used_files, (win32() ? lc($f) : $f);
- }
- #
- my $TEXMFLOCALVAR;
- my @TEXMFLOCAL;
- if (win32()) {
- chomp($TEXMFLOCALVAR =`kpsewhich --expand-path=\$TEXMFLOCAL`);
- @TEXMFLOCAL = map { lc } split(/;/ , $TEXMFLOCALVAR);
- } else {
- chomp($TEXMFLOCALVAR =`kpsewhich --expand-path='\$TEXMFLOCAL'`);
- @TEXMFLOCAL = split /:/ , $TEXMFLOCALVAR;
- }
- #
- # search for TEXMFLOCAL/web2c/$fn
- my @tmlused;
- for my $tml (@TEXMFLOCAL) {
- my $TMLabs = Cwd::abs_path($tml);
- next if (!$TMLabs);
- if (-r "$TMLabs/web2c/$fn") {
- push @tmlused, "$TMLabs/web2c/$fn";
- }
- }
- #
- # user mode (no -sys):
- # ====================
- # TEXMFCONFIG $HOME/.texliveYYYY/texmf-config/web2c/$fn
- # TEXMFVAR $HOME/.texliveYYYY/texmf-var/web2c/$fn
- # TEXMFHOME $HOME/texmf/web2c/$fn
- # TEXMFSYSCONFIG $TEXLIVE/YYYY/texmf-config/web2c/$fn
- # TEXMFSYSVAR $TEXLIVE/YYYY/texmf-var/web2c/$fn
- # TEXMFLOCAL $TEXLIVE/texmf-local/web2c/$fn
- # TEXMFDIST $TEXLIVE/YYYY/texmf-dist/web2c/$fn
- #
- # root mode (--sys):
- # ==================
- # TEXMFSYSCONFIG $TEXLIVE/YYYY/texmf-config/web2c/$fn
- # TEXMFSYSVAR $TEXLIVE/YYYY/texmf-var/web2c/$fn
- # TEXMFLOCAL $TEXLIVE/texmf-local/web2c/$fn
- # TEXMFDIST $TEXLIVE/YYYY/texmf-dist/web2c/$fn
- #
- @{$opts{'cnffile'}} = @used_files;
- #
- # determine the config file that we will use for changes
- # if in the list of used files contains either one from
- # TEXMFHOME or TEXMFCONFIG (which is TEXMFSYSCONFIG in the -sys case)
- # then use the *top* file (which will be either one of the two),
- # if none of the two exists, create a file in TEXMFCONFIG and use it
- my $use_top = 0;
- for my $f (@used_files) {
- if ($f =~ m!(\Q$TEXMFHOME\E|\Q$texmfconfig\E)/web2c/$fn!) {
- $use_top = 1;
- last;
- }
- }
- if ($use_top) {
- ($changes_config_file) = @used_files;
- } else {
- # add the empty config file
- my $dn = "$texmfconfig/web2c";
- $changes_config_file = "$dn/$fn";
- }
- }
- if (!$opts{'quiet'}) {
- print_verbose("$prg is using the following $fn files"
- . " (in precedence order):\n");
- for my $f (@{$opts{'cnffile'}}) {
- print_verbose(" $f\n");
- }
- print_verbose("$prg is using the following $fn file"
- . " for writing changes:\n");
- print_verbose(" $changes_config_file\n");
- }
- if ($opts{'listfiles'}) {
- # we listed it above, so be done
- exit 0;
- }
-
- $alldata->{'changes_config'} = $changes_config_file;
-}
-
-
-
-# returns 1 if actually saved due to changes
-sub save_fmtutil {
- my $fn = shift;
- return if $opts{'dry-run'};
- my %fmtf = %{$alldata->{'fmtutil'}{$fn}};
- if ($fmtf{'changed'}) {
- TeXLive::TLUtils::mkdirhier(dirname($fn));
- open (FN, ">$fn") || die "$prg: can't write to $fn: $!";
- my @lines = @{$fmtf{'lines'}};
- if (!@lines) {
- print_verbose ("Creating new config file $fn\n");
- unless ($opts{"nohash"}) {
- # update lsR database
- $updLSR->add($fn);
- $updLSR->exec();
- $updLSR->reset();
- }
- }
- # collect the lines with data
- my %line_to_fmt;
- my @add_fmt;
- if (defined($fmtf{'formats'})) {
- for my $f (keys %{$fmtf{'formats'}}) {
- for my $e (keys %{$fmtf{'formats'}{$f}}) {
- if ($fmtf{'formats'}{$f}{$e}{'line'} == -1) {
- push @add_fmt, [ $f, $e ];
- } else {
- $line_to_fmt{$fmtf{'formats'}{$f}{$e}{'line'}} = [ $f, $e ];
- }
- }
- }
- }
- for my $i (0..$#lines) {
- if (defined($line_to_fmt{$i})) {
- my $f = $line_to_fmt{$i}->[0];
- my $e = $line_to_fmt{$i}->[1];
- my $mode = $fmtf{'formats'}{$f}{$e}{'status'};
- my $args = $fmtf{'formats'}{$f}{$e}{'args'};
- my $hyph = $fmtf{'formats'}{$f}{$e}{'hyphen'};
- my $p = ($mode eq 'disabled' ? "#! " : "");
- print FN "$p$f $e $hyph $args\n";
- } else {
- print FN "$lines[$i]\n";
- }
- }
- # add the new settings and maps
- for my $m (@add_fmt) {
- my $f = $m->[0];
- my $e = $m->[1];
- my $mode = $fmtf{'formats'}{$f}{$e}{'status'};
- my $args = $fmtf{'formats'}{$f}{$e}{'args'};
- my $hyph = $fmtf{'formats'}{$f}{$e}{'hyphen'};
- my $p = ($mode eq 'disabled' ? "#! " : "");
- print FN "$p$f $e $hyph $args\n";
- }
- close(FN) || warn("$prg: Cannot close file handle for $fn: $!");
- delete $alldata->{'fmtutil'}{$fn}{'changed'};
- return 1;
- }
- return 0;
-}
-
-
-#
-# $HOME and sudo and updmap-sys horror
-# some instances of sudo do not reset $HOME to the home of root
-# as an effect of "sudo updmap" creates root owned files in the home
-# of a normal user, and "sudo updmap-sys" uses map files and updmap.cfg
-# files from the directory of a normal user, but creating files
-# in TEXMFSYSCONFIG. This is *all* wrong.
-# we check: if we are running as UID 0 (root) on Unix and the
-# ENV{HOME} is NOT the same as the one of root, then give a warning
-# and reset it to the real home dir of root.
-
-sub reset_root_home {
- if (!win32() && ($> == 0)) { # $> is effective uid
- my $envhome = $ENV{'HOME'};
- # if $HOME isn't an existing directory, we don't care.
- if (defined($envhome) && (-d $envhome)) {
- # we want to avoid calling getpwuid as far as possible, so if
- # $envhome is one of some usual values we accept it without worrying.
- if ($envhome =~ m,^(/|/root|/var/root)/*$,) {
- return;
- }
- # $HOME is defined, check what is the home of root in reality
- my (undef,undef,undef,undef,undef,undef,undef,$roothome) = getpwuid(0);
- if (defined($roothome)) {
- if ($envhome ne $roothome) {
- print_warning("resetting \$HOME value (was $envhome) to root's "
- . "actual home ($roothome).\n");
- $ENV{'HOME'} = $roothome;
- } else {
- # envhome and roothome do agree, nothing to do, that is the good case
- }
- } else {
- print_warning("home of root not defined, strange!\n");
- }
- }
- }
-}
-
-# printing to stdout (in mktexfmtMode also going to stderr!)
-# print_info can be suppressed with --quiet
-# print_verbose cannot be suppressed
-# printing to stderr
-# print_warning can be suppressed with --quiet
-# print_error cannot be suppressed
-#
-sub print_info {
- if ($mktexfmtMode) {
- print STDERR "$prg [INFO]: ", @_ if (!$opts{'quiet'});
- } else {
- print STDOUT "$prg [INFO]: ", @_ if (!$opts{'quiet'});
- }
-}
-sub print_verbose {
- if ($mktexfmtMode) {
- print STDERR "$prg: ", @_;
- } else {
- print STDOUT "$prg: ", @_;
- }
-}
-sub print_warning {
- print STDERR "$prg [WARNING]: ", @_ if (!$opts{'quiet'})
-}
-sub print_error {
- print STDERR "$prg [ERROR]: ", @_;
-}
-#
-# same with deferred
-sub print_deferred_info {
- push @deferred_stdout, "$prg [INFO]: @_" if (!$opts{'quiet'});
-}
-sub print_deferred_verbose {
- push @deferred_stdout, "$prg: @_";
-}
-sub print_deferred_warning {
- push @deferred_stderr, "$prg [WARNING]: @_" if (!$opts{'quiet'})
-}
-sub print_deferred_error {
- push @deferred_stderr, "$prg [ERROR]: @_";
-}
-
-
-# copied from TeXLive::TLUtils to reduce dependencies
-sub win32 {
- if ($^O =~ /^MSWin/i) {
- return 1;
- } else {
- return 0;
- }
-}
-
-
-
-# version, help.
-
-sub version {
- my $ret = sprintf "%s version %s\n", $prg, $version;
- return $ret;
-}
-
-sub help {
- my $usage = <<"EOF";
-Usage: $prg [-user|-sys] [OPTION] ... [COMMAND]
- or: $prg-sys [OPTION] ... [COMMAND]
- or: $prg-user [OPTION] ... [COMMAND]
- or: mktexfmt FORMAT.fmt|BASE.base|FMTNAME.EXT
-
-Rebuild and manage TeX fmts and Metafont bases, collectively called
-"formats" here. (MetaPost no longer uses the past-equivalent "mems".)
-
-If the command name ends in mktexfmt, only one format can be created.
-The only options supported are --help and --version, and the command
-line must be either a format name, with extension, or a plain name that
-is passed as the argument to --byfmt (see below). The full name of the
-generated file (if any) is written to stdout, and nothing else.
-
-If not operating in mktexfmt mode, exactly one command must be given,
-extensions should generally not be specified, no non-option arguments
-are allowed, and multiple formats can be generated, as follows.
-
-By default, the return status is zero if all formats requested are
-successfully built, else nonzero.
-
-Options:
- --sys use TEXMFSYS{VAR,CONFIG}
- --user use TEXMF{VAR,CONFIG}
- --cnffile FILE read FILE instead of fmtutil.cnf
- (can be given multiple times, in which case
- all the files are used)
- --fmtdir DIR write formats under DIR instead of TEXMF[SYS]VAR
- --no-engine-subdir don't use engine-specific subdir of the fmtdir
- --no-error-if-no-format exit successfully if no format is selected
- --no-error-if-no-engine=ENGINE1,ENGINE2,...
- exit successfully even if a required engine
- is missing, if it is included in the list.
- --no-strict exit successfully even if a format fails to build
- --nohash don't update ls-R files
- --recorder pass the -recorder option and save .fls files
- --quiet be silent
- --catcfg (does nothing, exists for compatibility)
- --dolinks (does nothing, exists for compatibility)
- --force (does nothing, exists for compatibility)
- --test (does nothing, exists for compatibility)
-
-Commands:
- --all recreate all format files
- --missing create all missing format files
- --refresh recreate only existing format files
- --byengine ENGINE (re)create formats built with ENGINE
- --byfmt FORMAT (re)create format FORMAT
- --byhyphen HYPHENFILE (re)create formats that depend on HYPHENFILE
- --enablefmt FORMAT[/ENGINE] enable FORMAT, as built with ENGINE
- --disablefmt FORMAT[/ENGINE] disable FORMAT, as built with ENGINE
- If multiple formats have the same name and
- different engines, /ENGINE specifier is required.
- --listcfg list (enabled and disabled) configurations,
- filtered to available formats
- --showhyphen FORMAT print name of hyphen file for FORMAT
- --version show version information and exit
- --help show this message and exit
-
-Explanation of trees and files normally used:
-
- If --cnffile is specified on the command line (possibly multiple
- times), its value(s) are used. Otherwise, fmtutil reads all the
- fmtutil.cnf files found by running \`kpsewhich -all fmtutil.cnf', in the
- order returned by kpsewhich. Files passed in via --cnffile are
- first tried to be loaded directly, and if not found and the file names
- don't contain directory parts, are searched via kpsewhich.
-
- In any case, if multiple fmtutil.cnf files are found, all the format
- definitions found in all the fmtutil.cnf files are merged.
-
- Thus, if fmtutil.cnf files are present in all trees, and the default
- layout is used as shipped with TeX Live, the following files are
- read, in the given order.
-
- For fmtutil-sys:
- TEXMFSYSCONFIG \$TEXLIVE/YYYY/texmf-config/web2c/fmtutil.cnf
- TEXMFSYSVAR \$TEXLIVE/YYYY/texmf-var/web2c/fmtutil.cnf
- TEXMFLOCAL \$TEXLIVE/texmf-local/web2c/fmtutil.cnf
- TEXMFDIST \$TEXLIVE/YYYY/texmf-dist/web2c/fmtutil.cnf
-
- For fmtutil-user:
- TEXMFCONFIG \$HOME/.texliveYYYY/texmf-config/web2c/fmtutil.cnf
- TEXMFVAR \$HOME/.texliveYYYY/texmf-var/web2c/fmtutil.cnf
- TEXMFHOME \$HOME/texmf/web2c/fmtutil.cnf
- TEXMFSYSCONFIG \$TEXLIVE/YYYY/texmf-config/web2c/fmtutil.cnf
- TEXMFSYSVAR \$TEXLIVE/YYYY/texmf-var/web2c/fmtutil.cnf
- TEXMFLOCAL \$TEXLIVE/texmf-local/web2c/fmtutil.cnf
- TEXMFDIST \$TEXLIVE/YYYY/texmf-dist/web2c/fmtutil.cnf
-
- (where YYYY is the TeX Live release version).
-
- According to the actions, fmtutil might write to one of the given files
- or create a new fmtutil.cnf, described further below.
-
-Where formats are written:
-
- By default, format files are (re)written in TEXMFSYSVAR/ENGINE by
- fmtutil-sys, and TEXMFVAR/ENGINE by fmtutil, where /ENGINE is a
- subdirectory named for the engine used, such as "pdftex".
-
- If the --fmtdir=DIR option is specified, DIR is used instead of
- TEXMF[SYS]VAR, but the /ENGINE subdir is still used by default.
-
- In any case, if the --no-engine-subdir option is specified, the
- /ENGINE subdir is omitted.
-
-Where configuration changes are saved:
-
- If config files are given on the command line, then the first one
- given will be used to save any changes from --enable or --disable.
- If the config files are taken from kpsewhich output, then the
- algorithm is more complex:
-
- 1) If \$TEXMFCONFIG/web2c/fmtutil.cnf or \$TEXMFHOME/web2c/fmtutil.cnf
- appears in the list of used files, then the one listed first by
- kpsewhich --all (equivalently, the one returned by kpsewhich
- fmtutil.cnf), is used.
-
- 2) If neither of the above two are present and changes are made, a
- new config file is created in \$TEXMFCONFIG/web2c/fmtutil.cnf.
-
- In general, the idea is that if a given config file is not writable, a
- higher-level one can be used. That way, the distribution's settings
- can be overridden system-wide using TEXMFLOCAL, and system settings
- can be overridden again in a particular user's TEXMFHOME.
-
-Resolving multiple definitions of a format:
-
- If a format is defined in more than one config file, then the definition
- coming from the first-listed fmtutil.cnf is used.
-
-Disabling formats:
-
- fmtutil.cnf files with higher priority (listed earlier) can disable
- formats in lower priority (listed later) fmtutil.cnf files by
- writing a line like
- \#! <fmtname> <enginename> <hyphen> <args>
- in the higher-priority fmtutil.cnf file. The \#! must be at the
- beginning of the line, with at least one space or tab afterward, and
- there must be whitespace between each word on the list.
-
- For example, you can disable the luajitlatex format by creating
- the file \$TEXMFCONFIG/web2c/fmtutil.cnf with the line
- #! luajitlatex luajittex language.dat,language.dat.lua lualatex.ini
- (As it happens, the luajittex-related formats are precisely why the
- --no-error-if-no-engine option exists, since luajittex cannot be
- compiled on all platforms.)
-
-fmtutil-user (fmtutil -user) vs. fmtutil-sys (fmtutil -sys):
-
- When fmtutil-sys is run or the command line option -sys is used,
- TEXMFSYSCONFIG and TEXMFSYSVAR are used instead of TEXMFCONFIG and
- TEXMFVAR, respectively. This is the primary difference between
- fmtutil-sys and fmtutil-user.
-
- See http://tug.org/texlive/scripts-sys-user.html for details.
-
- Other locations may be used if you give them on the command line, or
- these trees don't exist, or you are not using the original TeX Live.
-
-Supporting development binaries
-
- If an engine name ends with "-dev", formats are created in
- the respective directory with the -dev stripped. This allows for
- easily running development binaries in parallel with the released
- binaries.
-
-Report bugs to: tex-live\@tug.org
-TeX Live home page: <http://tug.org/texlive/>
-EOF
-;
- print &version();
- print $usage;
- exit 0; # no final print_info
-}
-
-### Local Variables:
-### perl-indent-level: 2
-### tab-width: 2
-### indent-tabs-mode: nil
-### End:
-# vim:set tabstop=2 expandtab: #
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/mktexlsr b/Build/source/texk/texlive/linked_scripts/texlive/mktexlsr
deleted file mode 100755
index 47a69c48d07..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/mktexlsr
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/bin/sh
-# original mktexlsr -- create or rebuild ls-R.
-#
-# (If you change or delete the word `original' on the previous line,
-# installation won't write this script over yours.)
-#
-# Suitable for calling from cron, as in:
-# 0 * * * * cd /your/texmf/root && /usr/local/texlive/bin/mktexlsr
-#
-# Originally written as `texhash' by Thomas Esser, Okt., 1994.
-# Public domain.
-
-version='$Id: mktexlsr 56842 2020-11-02 23:00:54Z karl $'
-progname=`echo $0 | sed 's%.*/%%'`
-
-usage="Usage: $progname [OPTION]... [DIR]...
-
-Rebuild ls-R filename databases used by TeX. If one or more arguments
-DIRS are given, these are used as the directories in which to build
-ls-R. Else all directories in the search path for ls-R files
-(\$TEXMFDBS) are used.
-
-Options:
- --dry-run do not actually update anything
- --help display this help and exit
- --quiet cancel --verbose
- --silent same as --quiet
- --verbose explain what is being done
- --version output version information and exit
-
-If standard input is a terminal, --verbose is on by default.
-
-For more information, see the \`Filename database' section of
-Kpathsea manual available at http://tug.org/kpathsea.
-
-Report bugs to: tex-k@tug.org
-TeX Live home page: <http://tug.org/texlive/>
-"
-
-# The simple PATH-prepending approach we take in other scripts doesn't
-# handle DOS/Windows, but we don't use the shell scripts on Windows
-# anyway, and does anyone want current TL on DOS or DJGPP? Maybe they
-# can maintain their own changes if so. Leaving this code though, since
-# it's always been here ...
-
-# MS-DOS and MS-Windows define $COMSPEC or $ComSpec and use `;' to separate
-# directories in path lists whereas Unix uses `:'. Make an exception for
-# Cygwin, which pretends to be UNIX.
-# Create a variable that holds the right character to be used by the scripts.
-DOSISH=no
-case `uname -s` in
- CYGWIN*|Cygwin*|cygwin*) ;;
- *) if test -n "$COMSPEC" || test -n "$ComSpec"; then DOSISH=yes; fi
-esac
-if test "$DOSISH" = "no"; then SEP=':'; else SEP=';';fi
-
-# Add the location of the script to the PATH if necessary. This must
-# be done before kpsewhich can be called, and thus cannot be put into
-# mktex.opt.
-dirname=`echo $0 | sed 's%/*[^/][^/]*$%%'`
-case $dirname in
- "") # Do nothing
- ;;
- /* | [A-z]:/*) # Absolute name
- PATH="$dirname$SEP$PATH"
- export PATH ;;
- *) # Relative name
- PATH="`pwd`/$dirname$SEP$PATH"
- export PATH ;;
-esac
-
-if tty -s >/dev/null 2>&1; then verbose=true; else verbose=false; fi
-dry_run=false
-trees=
-
-# initialize treefile by either mktemp or some random name
-# code taken from pdfjam and adjusted
-{
- treefile=`
- (umask 077 && mktemp "${TMPDIR-/tmp}/mktexlsrtrees.XXXXXXXXXX") 2>/dev/null
- ` && test -n "$treefile" && test -f "$treefile"
-} || {
- ## We'll use awk to make random number, for portability
- random=`awk 'END { srand(); printf ("%d\n", rand()*1000000); }' /dev/null`
- treefile="${TMPDIR-/tmp}/mktexlsrtrees$$.$random"
-} || exit $?
-
-trap 'cd /; rm -f $treefile; test -z "$db_dir_tmp" || rm -rf "$db_dir_tmp";
- exit' 0 1 2 3 7 13 15
-
-# A copy of some stuff from mktex.opt, so we can run in the presence of
-# terminally damaged ls-R files.
-while test $# -gt 0; do
- if test "x$1" = x--help || test "x$1" = x-help; then
- echo "$usage"
- exit 0
- elif test "x$1" = x--version || test "x$1" = x-version; then
- echo "`basename $0` $version"
- kpsewhich --version
- exit 0
- elif test "x$1" = x--verbose || test "x$1" = x-verbose; then
- verbose=true
- elif test "x$1" = x--dry-run || test "x$1" = x-n; then
- dry_run=true
- elif test "x$1" = x--quiet || test "x$1" = x--silent \
- || test "x$1" = x-quiet || test "x$1" = x-silent ; then
- verbose=false
- elif test "x$1" = x--; then
- :
- elif echo "x$1" | grep '^x-' >/dev/null; then
- echo "$progname: unknown option \`$1', try --help if you need it." >&2
- exit 1
- else
- if test ! -d "$1"; then
- echo "$progname: $1: not a directory, skipping." >&2
- shift
- continue
- fi
- # By saving the argument in a file, we can later get it back while
- # supporting spaces in the name. This still doesn't support
- # newlines in the directory names, but nobody ever complains about
- # that, and it seems much too much trouble to use \0 terminators.
- (umask 077
- if echo "$1" >>"$treefile"; then :; else
- echo "$progname: $treefile: could not append to arg file, goodbye." >&2
- exit 1
- fi
- )
- fi
- shift
-done
-
-# mktexupd and mktexlsr make sure they're coordinated via this. A copy
-# is found mktex.opt.
-ls_R_magic='% ls-R -- filename database for kpathsea; do not change this line.'
-# The old string, which should continue to work.
-old_ls_R_magic='% ls-R -- maintained by MakeTeXls-R; do not change this line.'
-
-{
- # Get list of directories from the explicit arguments (now saved in
- # $treefile), or $TEXMFDBS if no explicit args. Eliminate duplicates.
- saveIFS=$IFS # break only at newline
- IFS='
-'
- if test -s "$treefile"; then
- set x `sort "$treefile" | uniq`
- else
- set x `kpsewhich --show-path=ls-R | tr : '
-' | sort | uniq`
- fi
- IFS=$saveIFS
- shift
-}
-
-for TEXMFLS_R in "$@"; do
- # Prepend cwd if the directory was relative.
- case "$TEXMFLS_R" in
- "") continue ;; # Strictly speaking, it is an error if this case is taken.
- /* | [A-z]:/*) ;;
- *) TEXMFLS_R="`pwd`/$TEXMFLS_R"
- esac
- # Allow for either ls-R and ls-r to exist. But create ls-R if we're
- # working from scratch.
- if test -f "$TEXMFLS_R/ls-R"; then
- db_file="$TEXMFLS_R/ls-R"
- elif test -f "$TEXMFLS_R/ls-r"; then
- db_file="$TEXMFLS_R/ls-r"
- else
- db_file="$TEXMFLS_R/ls-R"
- fi
- # Follow a possible symlink to get the right filesystem.
- # The '|| true' construct prevents an sh -e aborting.
- db_readlink=`kpsereadlink "$TEXMFLS_R/ls-R" 2>/dev/null` || true
- case "$db_readlink" in
- "") ;;
- /* | [A-z]:/*) db_file="$db_readlink" ;;
- *) db_file="$TEXMFLS_R/$db_readlink"
- esac
- db_dir=`echo "$db_file" | sed 's%/[^/][^/]*$%%'` # can't rely on dirname
-
- # want to be silent if the directory doesn't exist, since the ls-R
- # path ordinarily contains many nonexistent directories.
- test -d "$db_dir" || continue
- test -w "$db_dir" || { echo "$progname: $db_dir: directory not writable. Skipping..." >&2; continue; }
-
- if test ! -f "$db_file"; then
- cp /dev/null "$db_file"
- # Use same permissions as parent directory, minus x,s, or t bits.
- chmod `kpsestat -xst "$db_dir"` "$db_file"
- elif test -s "$db_file" \
- && test "x`sed '1s/ $//;1q' \"$db_file\"`" != "x$ls_R_magic" \
- && test "x`sed '1s/ $//;1q' \"$db_file\"`" != "x$old_ls_R_magic"; then
- echo "$progname: $db_file: no magic string, skipping..." >&2
- continue
- fi
-
- # Skip if we cannot write the file:
- kpseaccess -w "$db_file" || { echo "$progname: $db_file: no write permission, skipping..." >&2; continue; }
-
- db_dir_tmp="$db_dir/lsR$$.tmp"
- (umask 077 && mkdir "$db_dir_tmp" ) \
- || { echo "$progname: $db_dir_tmp: could not create directory, skipping..." >&2; continue; }
- db_file_tmp="$db_dir_tmp/lsR$$.tmp"
- rm -f "$db_file_tmp"
-
- $verbose && echo "$progname: Updating $db_file... "
- $dry_run && continue
-
- echo "$ls_R_magic" >"$db_file_tmp"
-
- # The main task. We put ./: in the output, so top-level files can be
- # found via ls-R. Probably irrelevant in practice. The sed command
- # inserts the leading ./ for directory names, and removes ., .., and
- # version control entries from the list. Also omit contents of any
- # the version directories; sed apparently requires that we do that
- # operation in a separate invocation. We do not try to support colons
- # in directory names.
- #
- echo "./:" >>"$db_file_tmp"
- vc_dirs='\.\(bzr\|git\|hg\|svn\)\|_darcs'
- (cd "$TEXMFLS_R" && \ls -LRa 2>/dev/null) \
- | sed -e '/^$/{n;s%^\./%%;s%^%./%;}; /^\.$/d; /^\.\.$/d; /^'$vc_dirs'$/d;' \
- -e '/^[\.\/]*lsR[0-9]*\.tmp:*$/d' \
- | sed -e /$vc_dirs'.*:$/,/^$/d' \
- >>"$db_file_tmp"
-
- # To be really safe, a loop.
- until PERMS=`kpsestat = "$db_file"`; do sleep 1; done
- chmod $PERMS "$db_file_tmp"
- rm -f "$db_file"
- mv "$db_file_tmp" "$db_file"
- rm -rf "$db_dir_tmp"
-done
-
-$verbose && echo "$progname: Done."
-exit 0
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/mktexmf b/Build/source/texk/texlive/linked_scripts/texlive/mktexmf
deleted file mode 100755
index 5d6d24a5e42..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/mktexmf
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/sh
-# original mktexmf -- make a new MF file, because one wasn't found.
-#
-# (If you change or delete the word `original' on the previous line,
-# installation won't write this script over yours.)
-#
-# Originally written by Thomas Esser.
-# Public domain.
-
-version='$Id: mktexmf 53254 2019-12-29 19:18:55Z karl $'
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-usage="Usage: $0 FONT.
-
-Makes the Metafont source file for FONT, if possible. For example,
-\`ecr12' or \`cmr11'.
-
-Report bugs to: tex-k@tug.org
-TeX Live home page: <http://tug.org/texlive/>
-"
-
-# Common code for all scripts.
-: ${MT_TEXMFMAIN=`kpsewhich --expand-path='$TEXMFMAIN'`}
-: ${MT_MKTEX_OPT=`kpsewhich --format='web2c files' mktex.opt`}
-test -n "$MT_MKTEX_OPT" || MT_MKTEX_OPT="$MT_TEXMFMAIN/web2c/mktex.opt"
-if test ! -f "$MT_MKTEX_OPT"; then
- echo "$progname: Cannot find mktex.opt; check your installation." >&2
- exit 1
-fi
-
-. "$MT_MKTEX_OPT"
-
-(
-# See comments in mktexpk.
-name="`echo $1 | sed 's%.*/%%; s%\.mf$%%'`"
-rootname=`echo "$name" | sed 's/[0-9]*$//'`
-pointsize=`echo "$name" | sed "s/^$rootname//"`
-
-sauterroot=`kpsewhich b-$rootname.mf 2>/dev/null`
-if test -n "$sauterroot"; then
- rootfile=$sauterroot
- rootname=b-$rootname
-else
- case $name in
- # csso12[0-5][0-9] from CJK package; unsupported by mktexmf
- csso12[0-5][0-9])
- rootfile=;;
- *)
- case $rootname in
- cs*|lcsss*|icscsc*|icstt*|ilcsss*)
- rootfile=`kpsewhich cscode.mf`;;
- wn[bcdfirstuv]*|rx[bcdfiorstuvx][bcfhilmostx]|l[abcdhl][bcdfiorstuvx]*)
- lhprefix=`echo "$name" | sed 's/^\(..\).*/\1/'`
- rootfile=`kpsewhich ${lhprefix}codes.mf 2>/dev/null`;;
- *)
- rootfile=`kpsewhich $rootname.mf 2>/dev/null`;;
- esac;;
- esac
-fi
-{ test -z "$rootfile" || test ! -f "$rootfile"; } && exit 1
-
-#if test -z "$MT_MFNAME"; then
-OIFS=$IFS; IFS=$SEP
-set x `"$MT_MKTEXNAM" $name`; shift
-IFS=$OIFS
-MT_MFNAME="$3"
-#fi
-
-destdir=`echo "$MT_MFNAME" | sed 's%/[^/][^/]*$%%'`
-test -d "$destdir" || "$MT_MKTEXDIR" "$destdir" || exit 1
-cd "$destdir" || exit 1
-
-case "$pointsize" in
- "") echo "$progname: no pointsize."; exit 1;;
- 11) realsize=10.95;; # \magstephalf
- 14) realsize=14.4;; # \magstep2
- 17) realsize=17.28;; # \magstep3
- 20) realsize=20.74;; # \magstep4
- 25) realsize=24.88;; # \magstep5
- 30) realsize=29.86;; # \magstep6
- 36) realsize=35.83;; # \magstep7
- # The new convention is to have three or four letters for the
- # font name and four digits for the pointsize. The number is
- # pointsize * 100. We effectively divide by 100 by ignoring the
- # last two digits.
- ????|?????) realsize=`echo "$pointsize" | sed 's/\(..\)$/.\1/'`;;
- *) realsize="$pointsize";;
-esac
-
-mfname="$name.mf"
-if test -r "$mfname"; then
- echo "$progname: $destdir/$mfname already exists."
- echo "$destdir/$mfname" >$STDOUT
- "$MT_MKTEXUPD" "$destdir" "$mfname"
- exit 0
-fi
-
-case "$name" in
- ec*|tc*)
- cat > "mf$$.tmp" <<END
-if unknown exbase: input exbase fi;
-gensize:=$realsize;
-generate $rootname;
-END
- ;;
- dc*)
- cat > "mf$$.tmp" <<END
-if unknown dxbase: input dxbase fi;
-gensize:=$realsize;
-generate $rootname;
-END
- ;;
- cs*|lcsss*|icscsc*|icstt*|ilcsss*)
- cat > "mf$$.tmp" <<END
-input cscode
-use_driver;
-END
- ;;
- wn[bcdfirstuv]*|rx[bcdfiorstuvx][bcfhilmostx]*|l[abcdhl][bcdfiorstuvx]*)
- cat > "mf$$.tmp" <<END
-input fikparm;
-END
- ;;
- g[lmorst][bijmtwx][cilnoru]*)
- # A small superset of the names of the cbgreek fonts.
- cat > "mf$$.tmp" <<END
-% generated by mktexmf
-input cbgreek;
-END
- ;;
- *)
- cat > "mf$$.tmp" <<END
-design_size := $realsize;
-input $rootname;
-END
- ;;
-esac
-
-chmod `kpsestat -xst,go-w .` "mf$$.tmp"
-rm -f "$mfname"
-mv "mf$$.tmp" "$mfname"
-
-echo "$destdir/$mfname" >$STDOUT
-echo "$progname: $destdir/$mfname: successfully generated." >&2
-"$MT_MKTEXUPD" "$destdir" "$mfname"
-exit 0
-) 1>&2 </dev/null
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/mktexpk b/Build/source/texk/texlive/linked_scripts/texlive/mktexpk
deleted file mode 100755
index f185c933c6d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/mktexpk
+++ /dev/null
@@ -1,284 +0,0 @@
-#!/bin/sh
-# original mktexpk -- make a new PK font, because one wasn't found.
-#
-# (If you change or delete the word `original' on the previous line,
-# installation won't write this script over yours.)
-#
-# Originally written by Thomas Esser, Karl Berry, and Olaf Weber.
-# Public domain.
-
-version='$Id: mktexpk 53602 2020-01-30 22:18:33Z karl $'
-progname=`echo $0 | sed 's%.*/%%'`
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-usage="Usage: $progname [OPTIONS] NAME [REDIRECT],
- Create a PK font.
-
---dpi DPI use resolution DPI.
---bdpi BDPI use base resolution BDPI.
---mag MAG use magnification MAG.
---mfmode MODE use MODE as the METAFONT mode.
---destdir DESTDIR write fonts in DESTDIR.
-
-Try to create a bitmap PK file for NAME at resolution DPI, with an
-assumed device base resolution of BDPI, and a Metafont \`mag' of
-MAG. Use MODE for the METAFONT mode. Use DESTDIR for the root of where
-to install into, either the absolute directory name to use (if it starts
-with a /) or relative to the default DESTDIR (if not). REDIRECT, if
-supplied, is a string of the form '>&n', where n is the number of the
-file descriptor which is to receive, instead of stdout, the name of the
-newly created pk file.
-
-If you expected the font to be available as an outline, and thus this
-script does not work and should not have been called, most likely the
-font's .tfm name is missing from the relevant map file (i.e.,
-psfonts.map for dvips-syntax programs, pdftex.map for pdftex-syntax
-programs). These map files are typically maintained using updmap; q.v.
-
-For step-by-step instructions on making new fonts known to TeX, see
-https://tug.org/fonts/fontinstall.html.
-
-Report bugs to: tex-k@tug.org
-TeX Live home page: <https://tug.org/texlive/>
-"
-
-# Handle non-positional options, except for --version/--help
-while test $# -gt 0; do
- case "$1" in
- --destdir) shift; DEST="$1"; shift ;;
- --destdir=*) DEST=`echo "$1" | sed 's/--destdir=//'`; shift ;;
- --dpi) shift; DPI="$1"; shift ;;
- --dpi=*) DPI=`echo "$1" | sed 's/--dpi=//'`; shift ;;
- --bdpi) shift; BDPI="$1"; shift ;;
- --bdpi=*) BDPI=`echo "$1" | sed 's/--bdpi=//'`; shift ;;
- --mfmode) shift; test "x$1" != "x/" && MODE="$1"; shift ;;
- --mfmode=*) test "x$1" != "x--mfmode/" \
- && MODE=`echo "$1" | sed 's/--mfmode=//'`; shift ;;
- --mag) shift; MAG="$1"; shift;;
- --mag=*) MAG=`echo "$1" | sed '/s--mag=//'`; shift;;
- --version|-version) break ;;
- --help|-help) break ;;
- *) break ;;
- esac
-done
-
-if test "x$2" != x; then
- tail="`echo \"x$2\" | sed 's/^x>&//' | grep '^[0-9]*$'`"
- if test -z "$tail"; then
- echo "$progname: argument '$2' ignored - bad file number" >&2
- elif test "$tail" != 1; then
- eval 'exec 1>&$tail'
- fi
-fi
-
-mt_max_args=2
-
-# Common code for all scripts.
-: ${MT_TEXMFMAIN=`kpsewhich --expand-path='$TEXMFMAIN'`}
-: ${MT_MKTEX_OPT=`kpsewhich --format='web2c files' mktex.opt`}
-test -n "$MT_MKTEX_OPT" || MT_MKTEX_OPT="$MT_TEXMFMAIN/web2c/mktex.opt"
-if test ! -f "$MT_MKTEX_OPT"; then
- echo "$progname: Cannot find mktex.opt; check your installation." >&2
- exit 1
-fi
-
-. "$MT_MKTEX_OPT"
-
-# Where do potential driver files belong?
-case "$MT_FEATURES" in
- *nomfdrivers*)
- : ${MT_MFDESTDIR=`pwd`}
- export MT_MFDESTDIR;;
-esac
-
-# Since we want to pass the generated filename and only that filename
-# back to the caller on standard output, we do some redirections so
-# regular echo's will end up on stderr, and do an echo >$STDOUT at the end.
-# Then the contents of $STDOUT will be echoed to stdout by a trap.
-
-# start of redirection stdout -> stderr, stdin <- /dev/null
-(
-
-NAME=$1
-
-if kpsewhich $NAME.mf >/dev/null 2>&1 || mktexmf $NAME >/dev/null 2>&1; then
- # determine the progname of metafont to use; prefer mf-nowin.
- if (mf-nowin --version) >/dev/null 2>&1; then
- MF="mf-nowin -progname=mf"
- else
- MF=mf
- fi
-
- # Check that $BDPI and $MODE are consistent; if not, ignore the mode and
- # hope we can correctly guess it from bdpi. (People like to specify the
- # resolution on the command line, not the mode so much.)
- if test -n "$MODE"; then
- mf_bdpi=`$MF \
-'\mode:='$MODE';mode_setup;message"BDPI= "&decimal round pixels_per_inch;end.'\
- </dev/null \
- | awk '/DPI=/ {print $2}'`
- if test "x$mf_bdpi" != x$BDPI; then
- echo "$progname: Mismatched mode $MODE and resolution $BDPI; ignoring mode." >&2
- MODE=
- fi
- fi
-
- # If an explicit mode is not supplied, try to guess. You can get a
- # list of extant modes from ftp://ftp.tug.org/tex/modes.mf.
- if test -z "$MODE" || test "x$MODE" = xdefault; then
- case "$BDPI" in
- 85) MODE=sun;;
- 100) MODE=nextscrn;;
- 180) MODE=toshiba;;
- 300) MODE=cx;;
- 360) MODE=epstylus;;
- 400) MODE=nexthi;;
- 600) MODE=ljfour;;
- 720) MODE=epscszz;;
- 1200) MODE=ultre;;
- 1270) MODE=linoone;;
- 8000) MODE=dpdfezzz;;
- *) echo "$progname: Can't guess mode for $BDPI dpi devices." >&2
- echo "$progname: Use a config file or option to specify the mode; see:" >&2
- echo "$progname: https://tug.org/texinfohtml/kpathsea.html#Unable-to-generate-fonts" >&2
- exit 1
- esac
- fi
-
- # Run Metafont. Always use plain Metafont, since reading cmbase.mf
- # does not noticeably slow things down.
- cmd="$MF \mode:=$MODE; mag:=$MAG; nonstopmode; input $NAME"
-else
- MODE=modeless
- # ps_to_pk is set in mktex.opt
- case $ps_to_pk in
- gsftopk)
- if $ps_to_pk -t "$NAME"; then
- cmd="$ps_to_pk $NAME $DPI"
- fi;;
- ps2pk)
- # grep for the font in $PSMAPFILE. These are base font names, such as
- # rpplr (the original) or pplr0 (an interim step) or pplr8r (current).
- : ${PSMAPFILE=`kpsewhich --format=map psfonts.map ps2pk.map`}
- pattern="^$NAME"'([ ]|$)'
- psline=`egrep "$pattern" $PSMAPFILE | tail -1`
- if test -n "$psline"; then
- set x `echo "$psline" | sed 's%[<["]%%g'`
- shift; shift; shift;
- encoding=; psname=; slant=; extend=
- while test ! -z "$1"; do
- case "$1" in
- *.enc) encoding="-e $1";;
- *.pf[ab]) psname="$1";;
- *SlantFont) slant="-S $lastopt";;
- *ExtendFont) extend="-E $lastopt";;
- esac
- lastopt="$1"
- shift
- done
- # Guessing the name of the type1 font file as fallback:
- ANAME=`echo $NAME | sed 's/8r$/8a/'`
- for i in $NAME.pfa $NAME.pfb $ANAME.pfa $ANAME.pfb; do
- if kpsewhich $i >/dev/null 2>&1; then
- psname=$i
- break
- fi
- done
-
- if [ -n "$psname" ]; then
- cmd="ps2pk -v -X$DPI -R$BDPI $slant $extend $encoding $psname $NAME.${DPI}pk"
- else
- if gsftopk -t "$NAME"; then
- echo "$progname: cannot find $NAME.pfa or $NAME.pfb. Trying gsftopk." >&2
- cmd="gsftopk $NAME $DPI"
- fi
- fi
- fi;;
- esac
-
- # unsupported by $ps_to_pk, try other conversions:
- if test -z "$cmd"; then
- if (ttf2pk -t -q $NAME) >/dev/null 2>&1; then
- cmd="ttf2pk -q $NAME $DPI"
- elif (hbf2gf -t -q $NAME) >/dev/null 2>&1; then
- cmd="hbf2gf -q -p $NAME $DPI"
- else
- echo "$progname: don't know how to create bitmap font for $NAME." >&2
- echo "$progname: perhaps $NAME is missing from the map file." >&2
- exit 1
- fi
- fi
-fi
-
-OIFS=$IFS; IFS=$SEP
-set x `"$MT_MKTEXNAM" $NAME $DPI $MODE $DEST`; shift
-IFS=$OIFS
-
-PKDEST="$1"
-PKDESTDIR=`echo "$PKDEST" | sed 's%/[^/][^/]*$%%'` # can't rely on dirname
-PKNAME=`basename "$PKDEST"`
-GFNAME=$NAME.${DPI}gf
-
-if test -r "$PKDESTDIR/$PKNAME"; then
- echo "$progname: $PKDESTDIR/$PKNAME already exists." >&2
- echo "$PKDESTDIR/$PKNAME" >$STDOUT
- "$MT_MKTEXUPD" "$PKDESTDIR" $PKNAME
- exit 0
-fi
-
-"$MT_MKTEXDIR" "$PKDESTDIR"
-if test ! -d "$PKDESTDIR"; then
- echo "$progname: $MT_MKTEXDIR $PKDESTDIR failed." >&2
- exit 1
-fi
-
-echo "$progname: Running $cmd"
-$cmd </dev/null || {
- # Don't abort if only "Strange path", "bad pos" or "angle(0,0)"
- # errors occurr.
- grep '^!' $NAME.log | sort >$$.errs 2>/dev/null
- grep '^! Strange path' $$.errs >$$.strange 2>/dev/null
- grep '^! bad pos.' $$.errs >$$.badpos 2>/dev/null
- grep '^! angle(0,0) is taken as zero.' $$.errs >$$.angle 2>/dev/null
- cat $$.badpos $$.strange $$.angle | sort > $$.errs_accept
- if cmp $$.errs $$.errs_accept >/dev/null 2>&1; then
- test -s $$.strange >/dev/null 2>&1 \
- && echo "$progname: warning: \`$cmd' caused strange path errors." >&2
- test -s $$.badpos >/dev/null 2>&1 \
- && echo "$progname: warning: \`$cmd' caused bad pos errors." >&2
- test -s $$.angle >/dev/null 2>&1 \
- && echo "$progname: warning: \`$cmd' caused angle(0,0) errors." >&2
- else
- echo "$progname: \`$cmd' failed." >&2
- test -s $NAME.log && mv -f $NAME.log "$KPSE_DOT"
- exit 1;
- fi
-}
-
-test -r $GFNAME && { gftopk ./$GFNAME $PKNAME || exit 1; }
-test ! -f $PKNAME && test -f $NAME.${DPI}pk && mv $NAME.${DPI}pk $PKNAME
-if test ! -s $PKNAME; then
- echo "$progname: \`$cmd' failed to make $PKNAME." >&2
- exit 1
-fi
-
-# Install the PK file carefully, since others may be working simultaneously.
-# Use cp when mv fails, since DOS will fail mv for deeply-nested directories.
-mv $PKNAME "$PKDESTDIR/pk$$.tmp" 2>/dev/null \
- || cp $PKNAME "$PKDESTDIR/pk$$.tmp" || exit 1
-cd "$PKDESTDIR" || exit 1
-chmod `kpsestat -xst,go-w .` pk$$.tmp
-test -r $PKNAME || mv pk$$.tmp $PKNAME || exit 1
-
-# Update ls-R if necessary.
-"$MT_MKTEXUPD" "$PKDESTDIR" $PKNAME
-
-# If this line (or an equivalent) is not present, dvipsk/xdvik/dviljk
-# will think mktexpk failed. Any other output to stdout will also lose.
-echo "$PKDESTDIR/$PKNAME" >$STDOUT
-echo "$progname: $PKDESTDIR/$PKNAME: successfully generated." >&2
-) 1>&2 </dev/null
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/mktextfm b/Build/source/texk/texlive/linked_scripts/texlive/mktextfm
deleted file mode 100755
index 25ca508918b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/mktextfm
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/bin/sh
-# original mktextfm -- make a new TFM file, because one wasn't found.
-#
-# (If you change or delete the word `original' on the previous line,
-# installation won't write this script over yours.)
-#
-# Primarily written by Thomas Esser, Karl Berry, and Olaf Weber.
-# Public domain.
-
-version='$Id: mktextfm 53602 2020-01-30 22:18:33Z karl $'
-progname=`echo $0 | sed 's%.*/%%'`
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-usage="Usage: $progname [--destdir DESTDIR] FONT.
-
-Makes a TFM file for FONT, if possible. Use DESTDIR for the root of where
-to install into, either the absolute directory name to use (if it starts
-with a /) or relative to the default DESTDIR (if not).
-
-See the mktexpk and updmap help messages for more general information on
-making fonts available.
-
-If the environment variable MF_MODE_EXTRA_INFO is non-empty, the
-codingscheme and other so-called Xerox-world information will be
-included in the tfm file.
-
-Report bugs to: tex-k@tug.org
-TeX Live home page: <https://tug.org/texlive/>
-"
-
-# Handle non-positional options, except for --version/--help
-while test $# -gt 0; do
- case "$1" in
- --destdir|-destdir) shift; DEST="$1"; shift ;;
- --destdir=*|-destdir=*) DEST=`echo "$1" | sed 's/--*destdir=//'`; shift ;;
- --version|-version) break ;;
- --help|-help) break ;;
- *) break ;;
- esac
-done
-
-# Common code for all scripts.
-: ${MT_TEXMFMAIN=`kpsewhich --expand-path='$TEXMFMAIN'`}
-: ${MT_MKTEX_OPT=`kpsewhich --format='web2c files' mktex.opt`}
-test -n "$MT_MKTEX_OPT" || MT_MKTEX_OPT="$MT_TEXMFMAIN/web2c/mktex.opt"
-if test ! -f "$MT_MKTEX_OPT"; then
- echo "$progname: Cannot find mktex.opt; check your installation." >&2
- exit 1
-fi
-
-. "$MT_MKTEX_OPT"
-
-# Where do potential mf driver files go?
-case "$MT_FEATURES" in
- *nomfdrivers*)
- : ${MT_MFDESTDIR=`pwd`}
- export MT_MFDESTDIR;;
-esac
-
-# start of redirection stdout -> stderr, stdin <- /dev/null
-(
-
-NAME=`basename "$1" .tfm`
-MAG=1 # mag=0 fails with larm1000.mf
-#DEST="$2"
-DPI=$BDPI
-
-OIFS=$IFS; IFS=$SEP
-set x `"$MT_MKTEXNAM" $NAME $DPI $MODE $DEST`; shift
-IFS=$OIFS
-
-PKDEST="$1"
-TFMDEST="$2"
-PKDESTDIR=`echo "$PKDEST" | sed 's%/[^/][^/]*$%%'` # can't rely on dirname
-TFMDESTDIR=`echo "$TFMDEST" | sed 's%/[^/][^/]*$%%'`
-PKNAME=`basename "$PKDEST"`
-TFMNAME=$NAME.tfm
-GFNAME=$NAME.$DPI'gf'
-
-if test -r "$TFMDESTDIR/$TFMNAME"; then
- echo "$progname: $TFMDESTDIR/$TFMNAME already exists." >&2
- echo "$TFMDESTDIR/$TFMNAME" >$STDOUT
- "$MT_MKTEXUPD" "$TFMDESTDIR" $TFMNAME
- exit
-fi
-
-# Try to create the destdir first. Do not create fonts, if this fails.
-"$MT_MKTEXDIR" "$TFMDESTDIR"
-if test ! -d "$TFMDESTDIR"; then
- echo "$progname: mktexdir $TFMDESTDIR failed."
- exit 1
-fi
-
-# Check if this font is supported by hbf2gf else use metafont.
-if (hbf2gf -q -t $NAME) >/dev/null 2>&1; then
- cmd="hbf2gf -g $NAME $DPI"
-else
- # determine the progname of metafont to use; prefer mf-nowin.
- if (mf-nowin --version) >/dev/null 2>&1; then
- MF="mf-nowin -progname=mf"
- else
- MF=mf
- fi
-
- # The idea here is to provide a programmatic way to get the
- # codingscheme and other so-called Xerox-world information into the
- # tfm: if the envvar MF_MODE_EXTRA_INFO is set, then modes.mf (as of
- # the 3.9 release in January 2020) will arrange for that. We do not
- # do this by default because Knuth objected.
- #
- if test -n "$MF_MODE_EXTRA_INFO"; then
- mf_extra_info="if known mode_include_extra_info_available: "
- mf_extra_info="$mf_extra_info mode_include_extra_info fi"
- else
- mf_extra_info=""
- fi
-
- cmd="$MF \mode:=$MODE; mag:=$MAG; $mf_extra_info; nonstopmode; input $NAME"
-fi
-
-echo "$progname: Running $cmd"
-$cmd </dev/null || {
- # Don't abort if only "Strange path", "bad pos" or "angle(0,0)"
- # errors occurr.
- grep '^!' $NAME.log | sort >$$.errs 2>/dev/null
- grep '^! Strange path' $$.errs >$$.strange 2>/dev/null
- grep '^! bad pos.' $$.errs >$$.badpos 2>/dev/null
- grep '^! angle(0,0) is taken as zero.' $$.errs >$$.angle 2>/dev/null
- cat $$.badpos $$.strange $$.angle | sort > $$.errs_accept
- if cmp $$.errs $$.errs_accept >/dev/null 2>&1; then
- test -s $$.strange >/dev/null 2>&1 \
- && echo "$progname: warning: \`$cmd' caused strange path errors." >&2
- test -s $$.badpos >/dev/null 2>&1 \
- && echo "$progname: warning: \`$cmd' caused bad pos errors." >&2
- test -s $$.angle >/dev/null 2>&1 \
- && echo "$progname: warning: \`$cmd' caused angle(0,0) errors." >&2
- else
- echo "$progname: \`$cmd' failed." >&2
- test -s $NAME.log && mv -f $NAME.log "$KPSE_DOT"
- exit 1;
- fi
-}
-
-# hbf2gf just produces a .pl file:
-test -r ./$NAME.pl && pltotf ./$NAME.pl $TFMNAME
-test -r $TFMNAME || { echo "$progname: \`$cmd' failed to make $TFMNAME."; exit 1; }
-
-# Install the TFM file carefully, since others may be working simultaneously.
-# Use cp when mv fails, since DOS will fail mv for deeply-nested directories.
-mv $TFMNAME "$TFMDESTDIR/tfm$$.tmp" 2>/dev/null \
- || cp $TFMNAME "$TFMDESTDIR/tfm$$.tmp" || exit 1
-cd "$TFMDESTDIR" || exit 1
-chmod `kpsestat -xst,go-w .` tfm$$.tmp
-test -r $TFMNAME || mv tfm$$.tmp $TFMNAME || exit 1
-
-# OK, success with the TFM.
-"$MT_MKTEXUPD" "$TFMDESTDIR" $TFMNAME
-echo "$TFMDESTDIR/$TFMNAME" >$STDOUT
-echo "$progname: $TFMDESTDIR/$TFMNAME: successfully generated." >&2
-
-# Since we probably made a GF(->PK) file, too, may as well install it if
-# it's needed.
-cd $TEMPDIR
-if test -r $GFNAME && test ! -f "$PKDESTDIR/$PKNAME"; then
- gftopk ./$GFNAME $PKNAME || exit 1
- "$MT_MKTEXDIR" "$PKDESTDIR"
- mv $PKNAME "$PKDESTDIR/pk$$.tmp" 2>/dev/null \
- || cp $PKNAME "$PKDESTDIR/pk$$.tmp" || exit 1
- cd "$PKDESTDIR" || exit 1
- if test -f $PKNAME; then
- rm -f pk$$.tmp
- else
- chmod `kpsestat -xst,go-w .` pk$$.tmp
- mv pk$$.tmp $PKNAME
- "$MT_MKTEXUPD" "$PKDESTDIR" $PKNAME
- fi
-fi
-) 1>&2 </dev/null
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/rungs.tlu b/Build/source/texk/texlive/linked_scripts/texlive/rungs.tlu
deleted file mode 100755
index b9d4caf34ef..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/rungs.tlu
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env texlua
---*-Lua-*-
--- $Id: rungs.tlu 30101 2013-04-25 17:29:00Z karl $
--- rungs - Run Ghostscript (gs on Unix, gswin32c on Windows)
--- (Maintained in TeX Live:Master/texmf-dist/scripts/texlive.)
-
--- Copyright (C) 2008-2013 Reinhard Kotucha.
--- You may freely use, modify and/or distribute this file.
-
-function fixwin(args_unix)
- if os.type == 'windows' then
- local args_win={} -- new table
- args_win[0]=args_unix[1]
- for i=1, #args_unix do
- args_win[i]='"'..args_unix[i]..'"'
- end
- return args_win
- else
- return args_unix
- end
-end
-
-if os.type == 'windows' then
- command={'gswin32c'}
-else
- command={'gs'}
-end
-
-for i=1, #arg do
- command[#command+1]=arg[i]
-end
-
-command=fixwin(command)
-
---[[ prepend an additional hyphen to activate this code
-for i=0, #command do
- print (command[i])
-end
-os.exit(ret)
---]]
-
-ret=os.spawn(command)
-os.exit(ret)
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl b/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
deleted file mode 100755
index 13d5e83641f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
+++ /dev/null
@@ -1,10130 +0,0 @@
-#!/usr/bin/env perl
-# $Id: tlmgr.pl 57772 2021-02-17 19:01:36Z karl $
-#
-# Copyright 2008-2021 Norbert Preining
-# This file is licensed under the GNU General Public License version 2
-# or any later version.
-
-my $svnrev = '$Revision: 57772 $';
-my $datrev = '$Date: 2021-02-17 20:01:36 +0100 (Wed, 17 Feb 2021) $';
-my $tlmgrrevision;
-my $tlmgrversion;
-my $prg;
-my $bindir;
-if ($svnrev =~ m/: ([0-9]+) /) {
- $tlmgrrevision = $1;
-} else {
- $tlmgrrevision = "unknown";
-}
-$datrev =~ s/^.*Date: //;
-$datrev =~ s/ \(.*$//;
-$tlmgrversion = "$tlmgrrevision ($datrev)";
-
-our $Master;
-our $ismain;
-our $loadmediasrcerror;
-our $packagelogfile;
-our $packagelogged;
-our $commandlogfile;
-our $tlmgr_config_file;
-our $pinfile;
-our $action; # for the pod2usage -sections call
-our %opts;
-our $allowed_verify_args_regex = qr/^(none|main|all)$/i;
-
-END {
- if ($opts{"pause"}) {
- print "Press Enter to exit the program.\n";
- <STDIN>;
- }
-}
-
-BEGIN {
- $^W = 1;
- $ismain = (__FILE__ eq $0);
- # WARNING
- # The only use anticipated for tlmgr.pl as library for the 2009 release
- # is the Windows w32client prototype script.
- # Unix-specific problems with use as library will probably go undetected.
-
- # make subprograms (including kpsewhich) have the right path:
- my $kpsewhichname;
- if ($^O =~ /^MSWin/i) {
- # on w32 $0 and __FILE__ point directly to tlmgr.pl; they can be relative
- $Master = __FILE__;
- $Master =~ s!\\!/!g;
- $Master =~ s![^/]*$!../../..!
- unless ($Master =~ s!/texmf-dist/scripts/texlive/tlmgr\.pl$!!i);
- $bindir = "$Master/bin/win32";
- $kpsewhichname = "kpsewhich.exe";
- # path already set by wrapper batchfile
- } else {
- $Master = __FILE__;
- $Master =~ s,/*[^/]*$,,;
- if ($ismain) {
- $bindir = $Master;
- $Master = "$Master/../..";
- } else {
- # for the time being, this code will not be used or tested
- $Master = "$Master/../../..";
- # no code yet for $bindir; would have to detect platform
- }
- # make subprograms (including kpsewhich) have the right path:
- $ENV{"PATH"} = "$bindir:$ENV{PATH}";
- $kpsewhichname = "kpsewhich";
- }
- if (-r "$bindir/$kpsewhichname") {
- # if not in bootstrapping mode => kpsewhich exists, so use it to get $Master
- chomp($Master = `kpsewhich -var-value=SELFAUTOPARENT`);
- }
-
- # if we have no directory in which to find our modules,
- # no point in going on.
- if (! $Master) {
- die ("Could not determine directory of tlmgr executable, "
- . "maybe shared library woes?\nCheck for error messages above");
- }
-
- $::installerdir = $Master; # for config.guess et al., see TLUtils.pm
-
- # make Perl find our packages first:
- unshift (@INC, "$Master/tlpkg");
- unshift (@INC, "$Master/texmf-dist/scripts/texlive");
-}
-
-use Cwd qw/abs_path/;
-use File::Find;
-use File::Spec;
-use Pod::Usage;
-use Getopt::Long qw(:config no_autoabbrev permute);
-use strict;
-
-use TeXLive::TLConfig;
-use TeXLive::TLPDB;
-use TeXLive::TLPOBJ;
-use TeXLive::TLUtils;
-use TeXLive::TLWinGoo;
-use TeXLive::TLDownload;
-use TeXLive::TLConfFile;
-use TeXLive::TLCrypto;
-TeXLive::TLUtils->import(qw(member info give_ctan_mirror win32 dirname
- mkdirhier copy debug tlcmp repository_to_array));
-use TeXLive::TLPaper;
-
-#
-# set up $prg for warning messages
-$prg = TeXLive::TLUtils::basename($0);
-# for usage in various Perl modules
-$::prg = $prg;
-
-binmode(STDOUT, ":utf8");
-binmode(STDERR, ":utf8");
-
-our %config; # hash of config settings from config file
-our $remotetlpdb;
-our $location; # location from which the new packages come
-our $localtlpdb; # local installation which we are munging
-
-# flags for machine-readable form
-our $FLAG_REMOVE = "d";
-our $FLAG_FORCIBLE_REMOVED = "f";
-our $FLAG_UPDATE = "u";
-our $FLAG_REVERSED_UPDATE = "r";
-our $FLAG_AUTOINSTALL = "a";
-our $FLAG_INSTALL = "i";
-our $FLAG_REINSTALL = "I";
-
-# keep in sync with install-tl.
-our $common_fmtutil_args =
- "--no-error-if-no-engine=$TeXLive::TLConfig::PartialEngineSupport";
-
-# option variables
-$::gui_mode = 0;
-$::machinereadable = 0;
-
-my %action_specification = (
- '_include_tlpobj' => {
- "run-post" => 0,
- "function" => \&action_include_tlpobj
- },
- "backup" => {
- "options" => {
- "all" => 1,
- "backupdir" => "=s",
- "clean" => ":-99",
- "dry-run|n" => 1
- },
- "run-post" => 1,
- "function" => \&action_backup
- },
- "candidates" => {
- "run-post" => 0,
- "function" => \&action_candidates
- },
- "check" => {
- "options" => { "use-svn" => 1 },
- "run-post" => 1,
- "function" => \&action_check
- },
- "conf" => {
- "options" => {
- "conffile" => "=s",
- "delete" => 1,
- },
- "run-post" => 0,
- "function" => \&action_conf
- },
- "dump-tlpdb" => {
- "options" => { local => 1, remote => 1 },
- "run-post" => 0,
- "function" => \&action_dumptlpdb
- },
- "generate" => {
- "options" => {
- "dest" => "=s",
- "localcfg" => "=s",
- "rebuild-sys" => 1
- },
- "run-post" => 1,
- "function" => \&action_generate
- },
- "get-mirror" => {
- "run-post" => 0,
- "function" => \&action_get_mirror
- },
- "gui" => {
- "options" => {
- "load" => 1,
- # Tk::CmdLine options
- "background" => "=s",
- "class" => "=s",
- "display" => "=s",
- "font" => "=s",
- "foreground" => "=s",
- "geometry" => "=s",
- "iconic" => 1,
- "motif" => 1,
- "name" => "=s",
- "screen" => "=s",
- "synchronous" => 1,
- "title" => "=s",
- "xrm" => "=s",
- },
- "run-post" => 1,
- "function" => \&action_gui
- },
- "info" => {
- "options" => {
- "data" => "=s",
- "all" => 1,
- "list" => 1,
- "only-installed" => 1,
- "only-remote" => 1
- },
- "run-post" => 0,
- "function" => \&action_info
- },
- "init-usertree" => {
- "run-post" => 0,
- "function" => \&action_init_usertree
- },
- "install" => {
- "options" => {
- "dry-run|n" => 1,
- "file" => 1,
- "force" => 1,
- "no-depends" => 1,
- "no-depends-at-all" => 1,
- "reinstall" => 1,
- "with-doc" => 1,
- "with-src" => 1,
- },
- "run-post" => 1,
- "function" => \&action_install
- },
- "key" => {
- "run-post" => 0,
- "function" => \&action_key
- },
- "option" => {
- "run-post" => 1,
- "function" => \&action_option
- },
- "paper" => {
- "options" => { "list" => 1 },
- "run-post" => 1,
- "function" => \&action_paper
- },
- "path" => {
- "options" => { "w32mode" => "=s" },
- "run-post" => 0,
- "function" => \&action_path
- },
- "pinning" => {
- "options" => { "all" => 1 },
- "run-post" => 1,
- "function" => \&action_pinning
- },
- "platform" => {
- "options" => { "dry-run|n" => 1 },
- "run-post" => 1,
- "function" => \&action_platform
- },
- "postaction" => {
- "options" => {
- "all" => 1,
- "fileassocmode" => "=i",
- "w32mode" => "=s",
- },
- "run-post" => 0,
- "function" => \&action_postaction
- },
- "recreate-tlpdb" => {
- "options" => { "platform|arch" => "=s" },
- "run-post" => 0,
- "function" => \&action_recreate_tlpdb
- },
- "remove" => {
- "options" => {
- "all" => 1,
- "backup" => 1,
- "backupdir" => "=s",
- "dry-run|n" => 1,
- "force" => 1,
- "no-depends" => 1,
- "no-depends-at-all" => 1,
- },
- "run-post" => 1,
- "function" => \&action_remove
- },
- repository => {
- "options" => { "with-platforms" => 1 },
- "run-post" => 1,
- "function" => \&action_repository
- },
- "restore" => {
- "options" => {
- "all" => 1,
- "backupdir" => "=s",
- "dry-run|n" => 1,
- "force" => 1
- },
- "run-post" => 1,
- "function" => \&action_restore
- },
- "search" => {
- "options" => {
- "all" => 1,
- "file" => 1,
- "global" => 1,
- "word" => 1,
- },
- "run-post" => 1,
- "function" => \&action_search
- },
- "shell" => {
- "function" => \&action_shell
- },
- "update" => {
- "options" => {
- "all" => 1,
- "backup" => 1,
- "backupdir" => "=s",
- "dry-run|n" => 1,
- "exclude" => "=s@",
- "force" => 1,
- "list" => 1,
- "no-auto-install" => 1,
- "no-auto-remove" => 1,
- "no-depends" => 1,
- "no-depends-at-all" => 1,
- "no-restart" => 1,
- "reinstall-forcibly-removed" => 1,
- "self" => 1,
- },
- "run-post" => 1,
- "function" => \&action_update
- },
- "version" => { }, # handled separately
-);
-
-my %globaloptions = (
- "gui" => 1,
- "gui-lang" => "=s",
- "debug-json-timing" => 1,
- "debug-translation" => 1,
- "h|?" => 1,
- "help" => 1,
- "json" => 1,
- "location|repository|repo" => "=s",
- "machine-readable" => 1,
- "no-execute-actions" => 1,
- "package-logfile" => "=s",
- "command-logfile" => "=s",
- "persistent-downloads" => "!",
- "pause" => 1,
- "pin-file" => "=s",
- "print-platform|print-arch" => 1,
- "print-platform-info" => 1,
- "usermode|user-mode" => 1,
- "usertree|user-tree" => "=s",
- "verify-repo" => "=s",
- "verify-downloads" => "!",
- "require-verification" => "!",
- "version" => 1,
-);
-
-main() if $ismain;
-
-
-### main ##################################################################
-
-sub main {
- my %options; # TL options from local tlpdb
-
- my %optarg;
- for my $k (keys %globaloptions) {
- if ($globaloptions{$k} eq "1") {
- $optarg{$k} = 1;
- } else {
- $optarg{"$k" . $globaloptions{$k}} = 1;
- }
- }
- for my $v (values %action_specification) {
- if (defined($v->{'options'})) {
- my %opts = %{$v->{'options'}};
- for my $k (keys %opts) {
- if ($opts{$k} eq "1") {
- $optarg{$k} = 1;
- } else {
- $optarg{"$k" . $opts{$k}} = 1;
- }
- }
- }
- }
-
- # save command line options for later restart, if necessary
- @::SAVEDARGV = @ARGV;
-
- TeXLive::TLUtils::process_logging_options();
-
- GetOptions(\%opts, keys(%optarg)) or pod2usage(2);
-
- $::debug_translation = 0;
- $::debug_translation = 1 if $opts{"debug-translation"};
-
- $::machinereadable = $opts{"machine-readable"}
- if (defined($opts{"machine-readable"}));
-
- $action = shift @ARGV;
- if (!defined($action)) {
- if ($opts{"gui"}) { # -gui = gui
- $action = "gui";
- } elsif ($opts{"print-platform"}) {
- $action = "print-platform";
- } elsif ($opts{"print-platform-info"}) {
- $action = "print-platform-info";
- } else {
- $action = "";
- }
- }
- $action = lc($action);
-
- $action = "platform" if ($action eq "arch");
-
- ddebug("action = $action\n");
- for my $k (keys %opts) {
- ddebug("$k => $opts{$k}\n");
- }
- ddebug("arguments: @ARGV\n") if @ARGV;
-
- if ($opts{"version"} || (defined $action && $action eq "version")) {
- if ($::machinereadable) {
- # give_version already is machinereadable aware
- print give_version();
- } else {
- info(give_version());
- }
- exit(0);
- }
-
- if (defined($action) && $action eq "help") {
- $opts{"help"} = 1;
- $action = undef; # an option not an action
- }
-
- if (defined($action) && $action eq "print-platform") {
- print TeXLive::TLUtils::platform(), "\n";
- exit 0;
- }
-
- if (defined($action) && $action eq "print-platform-info") {
- print "config.guess ", `$::installerdir/tlpkg/installer/config.guess`;
- my $plat = TeXLive::TLUtils::platform();
- print "platform ", $plat, "\n";
- print "platform_desc ", TeXLive::TLUtils::platform_desc($plat), "\n";
- exit 0;
- }
-
- # ACTION massaging
- # for backward compatibility and usability
-
- # unify arguments so that the $action contains paper in all cases
- # and push the first arg back to @ARGV for action_paper processing
- if (defined $action
- && $action =~ /^(paper|xdvi|psutils|pdftex|dvips|dvipdfmx?|context)$/) {
- unshift(@ARGV, $action);
- $action = "paper";
- }
-
- # backward compatibility with action "show" and "list" from before
- if (defined $action && $action =~ /^(show|list)$/) {
- $action = "info";
- }
- # merge actions remove and uninstall
- if (defined $action && $action eq "uninstall") {
- $action = "remove";
- }
-
- #
- # check for correctness of verify-repo argument
- if (defined($opts{"verify-repo"}) &&
- ($opts{"verify-repo"} !~ m/$allowed_verify_args_regex/)) {
- tldie("$prg: unknown value for --verify-repo: $opts{'verify-repo'}\n");
- }
- # convert command line crypto options
- $opts{"verify-repo"}
- = convert_crypto_options($opts{"verify-downloads"},
- $opts{"require-verification"},
- $opts{"verify-repo"});
- if (defined($opts{"verify-downloads"})
- || defined($opts{"require-verification"})) {
- tlwarn("$prg: please use -verify-repo options instead of verify-downloads/require-verification\n" .
- "$prg: adjusting to --verify-repo=$opts{'verify-repo'}\n");
- }
- delete $opts{"require-verification"};
- delete $opts{"verify-downloads"};
-
- # now $action should be part of %actionoptions, otherwise this is
- # an error
- if (defined($action) && $action && !exists $action_specification{$action}) {
- die "$prg: unknown action: $action; try --help if you need it.\n";
- }
-
- if ((!defined($action) || !$action) && !$opts{"help"} && !$opts{"h"}) {
- die "$prg: no action given; try --help if you need it.\n";
- }
-
- if ($opts{"help"} || $opts{"h"}) {
- # perldoc does ASCII emphasis on the output, and runs it through
- # $PAGER, so people want it. But not all Unix platforms have it,
- # and on Windows our Config.pm can apparently interfere, so always
- # skip it there. Or if users have NOPERLDOC set in the environment.
- my @noperldoc = ();
- if (win32() || $ENV{"NOPERLDOC"}) {
- @noperldoc = ("-noperldoc", "1");
- } else {
- if (!TeXLive::TLUtils::which("perldoc")) {
- @noperldoc = ("-noperldoc", "1");
- } else {
- # checking only for the existence of perldoc is not enough
- # because Debian/Ubuntu unfortunately ship a stub that does nothing;
- # try to check for that, too.
- my $ret = system("perldoc -V >/dev/null 2>&1");
- if ($ret == 0) {
- debug("working perldoc found, using it\n");
- } else {
- tlwarn("$prg: perldoc seems to be non-functional, not using it.\n");
- @noperldoc = ("-noperldoc", "1");
- }
- }
- }
- # less can break control characters and thus the output of pod2usage
- # is broken. We add/set LESS=-R in the environment and unset
- # LESSPIPE and LESSOPEN to try to help.
- #
- if (defined($ENV{'LESS'})) {
- $ENV{'LESS'} .= " -R";
- } else {
- $ENV{'LESS'} = "-R";
- }
- delete $ENV{'LESSPIPE'};
- delete $ENV{'LESSOPEN'};
- if ($action && ($action ne "help")) {
- # 1) Must use [...] form for -sections arg because otherwise the
- # /$action subsection selector applies to all sections.
- # https://rt.cpan.org/Public/Bug/Display.html?id=102116
- # 2) Must use "..." for that so the $action value is interpolated.
- pod2usage(-exitstatus => 0, -verbose => 99,
- -sections => [ 'NAME', 'SYNOPSIS', "ACTIONS/$::action.*" ],
- @noperldoc);
- } else {
- if ($opts{"help"}) {
- pod2usage(-exitstatus => 0, -verbose => 2, @noperldoc);
- } else {
- # give a short message about usage
- print "
-tlmgr revision $tlmgrversion
-usage: tlmgr OPTION... ACTION ARGUMENT...
-where ACTION is one of:\n";
- for my $k (sort keys %action_specification) {
- # don't print internal options
- next if ($k =~ m/^_/);
- print " $k\n";
- }
- print "\nUse\n tlmgr ACTION --help
-for more details on a specific option, and
- tlmgr --help
-for the full story.\n";
- exit 0;
- }
- }
- }
-
- # --machine-readable is only supported by update.
- if ($::machinereadable &&
- $action ne "update" && $action ne "install" && $action ne "option" && $action ne "shell" && $action ne "remove") {
- tlwarn("$prg: --machine-readable output not supported for $action\n");
- }
-
- #
- # bail out of it is unknown action
- if (!defined($action_specification{$action})) {
- tlwarn("$prg: action unknown: $action\n");
- exit ($F_ERROR);
- }
-
- # check on supported arguments
- #
- my %suppargs;
- %suppargs = %{$action_specification{$action}{'options'}}
- if defined($action_specification{$action}{'options'});
- my @notvalidargs;
- for my $k (keys %opts) {
- my @allargs = keys %suppargs;
- push @allargs, keys %globaloptions;
- my $found = 0;
- for my $ok (@allargs) {
- my @variants = split '\|', $ok;
- if (TeXLive::TLUtils::member($k, @variants)) {
- $found = 1;
- last;
- }
- }
- push @notvalidargs, $k if !$found;
- }
- if (@notvalidargs) {
- my $msg = "The action $action does not support the following option(s):\n";
- for my $c (@notvalidargs) {
- $msg .= " $c";
- }
- tlwarn("$prg: $msg\n");
- tldie("$prg: Try --help if you need it.\n");
- }
-
- #
- # the main tree we will be working on
- $::maintree = $Master;
- if ($opts{"usermode"}) {
- # we could also try to detect that we don't have write permissions
- # and switch to user mode automatically
- if (defined($opts{"usertree"})) {
- $::maintree = $opts{"usertree"};
- } else {
- chomp($::maintree = `kpsewhich -var-value TEXMFHOME`);
- }
- }
-
- # besides doing normal logging if -logfile is specified, we try to log
- # package related actions (install, remove, update) to
- # the package-log file TEXMFSYSVAR/web2c/tlmgr.log
- $packagelogged = 0; # how many msgs we logged
- chomp (my $texmfsysvar = `kpsewhich -var-value=TEXMFSYSVAR`);
- $packagelogfile = $opts{"package-logfile"};
- if ($opts{"usermode"}) {
- $packagelogfile ||= "$::maintree/web2c/tlmgr.log";
- } else {
- $packagelogfile ||= "$texmfsysvar/web2c/tlmgr.log";
- }
- #
- # Try to open the packagelog file, but do NOT die when that does not work
- if (!open(PACKAGELOG, ">>$packagelogfile")) {
- debug("Cannot open package log file for appending: $packagelogfile\n");
- debug("Will not log package installation/removal/update for this run\n");
- $packagelogfile = "";
- } else {
- debug("appending to package log file: $packagelogfile\n");
- }
-
- # output of executed commands are put into -command-logfile
- $commandlogfile = $opts{"command-logfile"};
- if ($opts{"usermode"}) {
- $commandlogfile ||= "$::maintree/web2c/tlmgr-commands.log";
- } else {
- $commandlogfile ||= "$texmfsysvar/web2c/tlmgr-commands.log";
- }
- # Try to open the packagelog file, but do NOT die when that does not work
- if (!open(COMMANDLOG, ">>$commandlogfile")) {
- debug("Cannot open command log file for appending: $commandlogfile\n");
- debug("Will not log output of executed commands for this run\n");
- $commandlogfile = "";
- } else {
- debug("appending to command log file: $commandlogfile\n");
- }
-
- $loadmediasrcerror = "Cannot load TeX Live database from ";
-
- # load the config file and set the config options
- # load it BEFORE starting downloads as we set persistent-downloads there!
- load_config_file();
-
- # in system mode verify that the selected action is allowed
- if (!$opts{"usermode"} && $config{'allowed-actions'}) {
- if (!TeXLive::TLUtils::member($action, @{$config{'allowed-actions'}})) {
- tlwarn("$prg: action not allowed in system mode: $action\n");
- exit ($F_ERROR);
- }
- }
-
- # set global variable if execute actions should be suppressed
- $::no_execute_actions = 1 if (defined($opts{'no-execute-actions'}));
-
- # if we are asked to use persistent connections try to start it here
- ddebug("tlmgr:main: do persistent downloads = $opts{'persistent-downloads'}\n");
- if ($opts{'persistent-downloads'}) {
- TeXLive::TLUtils::setup_persistent_downloads() ;
- }
- if (!defined($::tldownload_server)) {
- debug("tlmgr:main: ::tldownload_server not defined\n");
- } else {
- if ($::opt_verbosity >= 1) {
- debug(debug_hash_str("$prg:main: ::tldownload_server hash:",
- $::tldownload_server));
- }
- }
-
- my $ret = execute_action($action, @ARGV);
-
- # close the special log file
- if ($packagelogfile && !$::gui_mode) {
- info("$prg: package log updated: $packagelogfile\n") if $packagelogged;
- close(PACKAGELOG);
- }
-
- # F_ERROR stops processing immediately, and prevents postactions from
- # being run (e.g., untar fails). F_WARNING continues on, including
- # postactions (e.g., user tries to install 10 packages and the
- # checksum fails for one, but the others are ok), but still ends the
- # program by exiting unsuccessfully. So call them both "errors"
- # as far as the user is concerned.
- if ($ret & ($F_ERROR | $F_WARNING)) {
- tlwarn("$prg: An error has occurred. See above messages. Exiting.\n");
- }
-
- # end of main program, returns also error codes
- exit ($ret);
-
-} # end main
-
-sub give_version {
- if (!defined($::version_string)) {
- $::version_string = "";
- $::mrversion = "";
- $::version_string .= "tlmgr revision $tlmgrversion\n";
- $::mrversion .= "revision $tlmgrrevision\n";
- $::version_string .= "tlmgr using installation: $Master\n";
- $::mrversion .= "installation $Master\n";
- if (open (REL_TL, "$Master/release-texlive.txt")) {
- # print first, which has the TL version info.
- my $rel_tl = <REL_TL>;
- $::version_string .= $rel_tl;
- # for machine readable we only want the last word which is the version
- my @foo = split(' ', $rel_tl);
- $::mrversion .= "tlversion $foo[$#foo]\n";
- close (REL_TL);
- }
- #
- # add the list of revisions
- if ($::opt_verbosity > 0) {
- $::version_string .= "Revisions of TeXLive:: modules:";
- $::version_string .= "\nTLConfig: " . TeXLive::TLConfig->module_revision();
- $::version_string .= "\nTLUtils: " . TeXLive::TLUtils->module_revision();
- $::version_string .= "\nTLPOBJ: " . TeXLive::TLPOBJ->module_revision();
- $::version_string .= "\nTLPDB: " . TeXLive::TLPDB->module_revision();
- $::version_string .= "\nTLPaper: " . TeXLive::TLPaper->module_revision();
- $::version_string .= "\nTLWinGoo: " . TeXLive::TLWinGoo->module_revision();
- $::version_string .= "\n";
- }
- $::mrversion .= "TLConfig " . TeXLive::TLConfig->module_revision();
- $::mrversion .= "\nTLUtils " . TeXLive::TLUtils->module_revision();
- $::mrversion .= "\nTLPOBJ " . TeXLive::TLPOBJ->module_revision();
- $::mrversion .= "\nTLPDB " . TeXLive::TLPDB->module_revision();
- $::mrversion .= "\nTLPaper " . TeXLive::TLPaper->module_revision();
- $::mrversion .= "\nTLWinGoo " . TeXLive::TLWinGoo->module_revision();
- $::mrversion .= "\n";
- }
- if ($::machinereadable) {
- return $::mrversion;
- } else {
- return $::version_string;
- }
-}
-
-
-sub execute_action {
- my ($action, @argv) = @_;
-
- # we have to set @ARGV to the @argv since many of the action_* subs
- # use GetOption
- @ARGV = @argv;
-
- # actions which shouldn't have any lasting effects, such as search or
- # list, end by calling finish(0), which skips postinstall actions.
- if (!defined($action_specification{$action})) {
- tlwarn ("$prg: unknown action: $action; try --help if you need it.\n");
- return ($F_ERROR);
- }
-
- if (!defined($action_specification{$action}{"function"})) {
- tlwarn ("$prg: action $action defined, but no way to execute it.\n");
- return $F_ERROR;
- }
-
- my $ret = $F_OK;
- my $foo = &{$action_specification{$action}{"function"}}();
- if (defined($foo)) {
- if ($foo & $F_ERROR) {
- # report of bad messages are given at the top level.
- return $foo;
- }
- if ($foo & $F_WARNING) {
- tlwarn("$prg: action $action returned an error; continuing.\n");
- $ret = $foo;
- }
- } else {
- $ret = $F_OK;
- tlwarn("$prg: no value returned from action $action, assuming ok.\n");
- }
- my $run_post = 1;
- if ($ret & $F_NOPOSTACTION) {
- # clear the postaction bit
- $ret ^= $F_NOPOSTACTION;
- $run_post = 0;
- }
- if (!$action_specification{$action}{"run-post"}) {
- $run_post = 0;
- }
-
- return ($ret) if (!$run_post);
-
- # run external programs.
- $ret |= &handle_execute_actions();
-
- return $ret;
-}
-
-
-
-# run CMD with notice to the user and if exit status is nonzero, complain.
-# return exit status.
-#
-sub do_cmd_and_check {
- my $cmd = shift;
- # we output the pre-running notice on a separate line so that
- # tlmgr front ends (MacOSX's TeX Live Utility) can read it
- # and show it to the user before the possibly long delay.
- info("running $cmd ...\n");
- logcommand("running $cmd");
- my ($out, $ret);
- if ($opts{"dry-run"}) {
- $ret = $F_OK;
- $out = "";
- } elsif (win32() && (! -r "$Master/bin/win32/luatex.dll")) {
- # deal with the case where only scheme-infrastructure is installed
- # on Windows, thus no luatex.dll is available and the wrapper cannot be started
- tlwarn("Cannot run wrapper due to missing luatex.dll\n");
- $ret = $F_OK;
- $out = "";
- } else {
- ($out, $ret) = TeXLive::TLUtils::run_cmd("$cmd 2>&1");
- }
- $out =~ s/\n+$//; # trailing newlines don't seem interesting
- my $outmsg = "output:\n$out\n--end of output of $cmd.\n";
- if ($ret == $F_OK) {
- info("done running $cmd.\n");
- logcommand("success, $outmsg");
- ddebug("$cmd $outmsg");
- return ($F_OK);
- } else {
- info("\n");
- tlwarn("$prg: $cmd failed (status $ret), output:\n$out\n");
- logcommand("error, status: $ret, $outmsg");
- return ($F_ERROR);
- }
-}
-
-# run external programs (mktexlsr, updmap-sys, etc.) as specified by the
-# keys in the RET hash. We return the number of unsuccessful runs, zero
-# if all ok.
-#
-# If the "map" key is specified, the value may be a reference to a list
-# of map command strings to pass to updmap, e.g., "enable Map=ascii.map".
-#
-sub handle_execute_actions {
- my $errors = 0;
-
- my $sysmode = ($opts{"usermode"} ? "-user" : "-sys");
- my $invoke_fmtutil = "fmtutil$sysmode $common_fmtutil_args";
-
- if ($::files_changed) {
- $errors += do_cmd_and_check("mktexlsr");
- if (defined($localtlpdb->get_package('context'))
- && (-x "$bindir/texlua" || -x "$bindir/texlua.exe")) {
- $errors += do_cmd_and_check("mtxrun --generate");
- }
- $::files_changed = 0;
- }
-
- chomp(my $TEXMFSYSVAR = `kpsewhich -var-value=TEXMFSYSVAR`);
- chomp(my $TEXMFSYSCONFIG = `kpsewhich -var-value=TEXMFSYSCONFIG`);
- chomp(my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`);
- chomp(my $TEXMFDIST = `kpsewhich -var-value=TEXMFDIST`);
-
- # maps handling
- {
- my $updmap_run_needed = 0;
- for my $m (keys %{$::execute_actions{'enable'}{'maps'}}) {
- $updmap_run_needed = 1;
- }
- for my $m (keys %{$::execute_actions{'disable'}{'maps'}}) {
- $updmap_run_needed = 1;
- }
- my $dest = $opts{"usermode"} ? "$::maintree/web2c/updmap.cfg"
- : "$TEXMFDIST/web2c/updmap.cfg";
- if ($updmap_run_needed) {
- TeXLive::TLUtils::create_updmap($localtlpdb, $dest);
- }
- $errors += do_cmd_and_check("updmap$sysmode") if $updmap_run_needed;
- }
-
- # format relevant things
- # we first have to check if the config files, that is fmtutil.cnf
- # or one of the language* files have changed, regenerate them
- # if necessary, and then run the necessary fmtutil calls.
- {
- # first check for language* files
- my $regenerate_language = 0;
- for my $m (keys %{$::execute_actions{'enable'}{'hyphens'}}) {
- $regenerate_language = 1;
- last;
- }
- for my $m (keys %{$::execute_actions{'disable'}{'hyphens'}}) {
- $regenerate_language = 1;
- last;
- }
- if ($regenerate_language) {
- for my $ext ("dat", "def", "dat.lua") {
- my $lang = "language.$ext";
- info("regenerating $lang\n");
- my $arg1 = "$TEXMFSYSVAR/tex/generic/config/language.$ext";
- my $arg2 = "$TEXMFLOCAL/tex/generic/config/language-local.$ext";
- if ($ext eq "dat") {
- TeXLive::TLUtils::create_language_dat($localtlpdb, $arg1, $arg2);
- } elsif ($ext eq "def") {
- TeXLive::TLUtils::create_language_def($localtlpdb, $arg1, $arg2);
- } else {
- TeXLive::TLUtils::create_language_lua($localtlpdb, $arg1, $arg2);
- }
- }
- }
-
- # format-regenerate is used when the paper size changes. In that
- # case, if option("create_formats") is set, we simply want to generate
- # all formats
- #
- my %done_formats;
- my %updated_engines;
- my %format_to_engine;
- my %do_enable;
- my $do_full = 0;
- for my $m (keys %{$::execute_actions{'enable'}{'formats'}}) {
- $do_full = 1;
- $do_enable{$m} = 1;
- # here we check whether an engine is updated
- my %foo = %{$::execute_actions{'enable'}{'formats'}{$m}};
- if (!defined($foo{'name'}) || !defined($foo{'engine'})) {
- tlwarn("$prg: Very strange error, please report ", %foo);
- } else {
- $format_to_engine{$m} = $foo{'engine'};
- if ($foo{'name'} eq $foo{'engine'}) {
- $updated_engines{$m} = 1;
- }
- }
- }
- for my $m (keys %{$::execute_actions{'disable'}{'formats'}}) {
- $do_full = 1;
- }
- my $opt_fmt = $localtlpdb->option("create_formats");
- if ($do_full) {
- info("regenerating fmtutil.cnf in $TEXMFDIST\n");
- TeXLive::TLUtils::create_fmtutil($localtlpdb,
- "$TEXMFDIST/web2c/fmtutil.cnf");
- }
- if ($opt_fmt && !$::regenerate_all_formats) {
- # first regenerate all formats --byengine
- for my $e (keys %updated_engines) {
- debug ("updating formats based on $e\n");
- $errors += do_cmd_and_check
- ("$invoke_fmtutil --no-error-if-no-format --byengine $e");
- }
- # now rebuild all other formats
- for my $f (keys %do_enable) {
- next if defined($updated_engines{$format_to_engine{$f}});
- # ignore disabled formats
- next if !$::execute_actions{'enable'}{'formats'}{$f}{'mode'};
- debug ("(re)creating format dump $f\n");
- $errors += do_cmd_and_check ("$invoke_fmtutil --byfmt $f");
- $done_formats{$f} = 1;
- }
- }
-
- # now go back to the hyphenation patterns and regenerate formats
- # based on the various language files
- # this of course will in some cases duplicate fmtutil calls,
- # but it is much easier than actually checking which formats
- # don't need to be updated
-
- if ($regenerate_language) {
- for my $ext ("dat", "def", "dat.lua") {
- my $lang = "language.$ext";
- if (! TeXLive::TLUtils::win32()) {
- # Use full path for external command, except on Windows.
- $lang = "$TEXMFSYSVAR/tex/generic/config/$lang";
- }
- if ($localtlpdb->option("create_formats")
- && !$::regenerate_all_formats) {
- $errors += do_cmd_and_check ("$invoke_fmtutil --byhyphen \"$lang\"");
- }
- }
- }
- }
-
- #
- if ($::regenerate_all_formats) {
- info("Regenerating all formats, this may take some time ...");
- $errors += do_cmd_and_check("$invoke_fmtutil --all");
- info("done\n");
- $::regenerate_all_formats = 0;
- }
-
- # undefine the global var, otherwise in GUI mode the actions
- # are accumulating
- undef %::execute_actions;
-
- if ($errors > 0) {
- # should we return warning here?
- return $F_ERROR;
- } else {
- return $F_OK;
- }
-}
-
-
-# GET_MIRROR
-#
-# just return a mirror
-sub action_get_mirror {
- my $loc = give_ctan_mirror();
- print "$loc\n";
- return ($F_OK | $F_NOPOSTACTION);
-}
-
-#
-# includes a .tlpobj in the db, also searchers for sub-tlpobj
-# for doc and source files
-#
-
-# _INCLUDE_TLPOBJ
-#
-# includes a .tlpobj in the db, also searchers for sub-tlpobj
-# for doc and source files
-#
-sub action_include_tlpobj {
- # this is an internal function that should not be used outside
- init_local_db();
- for my $f (@ARGV) {
- my $tlpobj = TeXLive::TLPOBJ->new;
- $tlpobj->from_file($f);
- # we now have to check whether that is a .doc or .src package, so shipping
- # src or doc files from a different package.
- # We should have that package already installed ...
- my $pkg = $tlpobj->name;
- if ($pkg =~ m/^(.*)\.(source|doc)$/) {
- # got a .src or .doc package
- my $type = $2;
- my $mothership = $1;
- my $mothertlp = $localtlpdb->get_package($mothership);
- if (!defined($mothertlp)) {
- tlwarn("$prg: We are trying to add ${type} files to a nonexistent package $mothership!\n");
- tlwarn("$prg: Trying to continue!\n");
- # the best we can do is rename that package to $mothername and add it!
- $tlpobj->name($mothership);
- # add the src/docfiles tlpobj under the mothership name
- $localtlpdb->add_tlpobj($tlpobj);
- } else {
- if ($type eq "source") {
- $mothertlp->srcfiles($tlpobj->srcfiles);
- $mothertlp->srcsize($tlpobj->srcsize);
- } else {
- # must be "doc"
- $mothertlp->docfiles($tlpobj->docfiles);
- $mothertlp->docsize($tlpobj->docsize);
- }
- # that make sure that the original entry is overwritten
- $localtlpdb->add_tlpobj($mothertlp);
- }
- } else {
- # completely normal package, just add it
- $localtlpdb->add_tlpobj($tlpobj);
- }
- $localtlpdb->save;
- }
- # no error checking here for now
- return ($F_OK);
-}
-
-
-# REMOVE
-#
-# tlmgr remove foo bar baz
-# will remove the packages foo bar baz itself
-# and will remove all .ARCH dependencies, too
-# and if some of them are collections it will also remove the
-# depending packages which are NOT Collections|Schemes.
-# if some of them are referenced somewhere they will not be removed
-# unless --force given
-#
-# tlmgr remove --no-depends foo bar baz
-# will remove the packages foo bar baz itself without any dependencies
-# but it will still remove all .ARCH dependency
-# if some of them are referenced somewhere they will not be removed
-# unless --force given
-#
-# tlmgr remove --no-depends-at-all foo bar baz
-# will absolutely only install foo bar baz not even taking .ARCH into
-# account
-#
-
-sub backup_and_remove_package {
- my ($pkg, $autobackup) = @_;
- my $tlp = $localtlpdb->get_package($pkg);
- if (!defined($tlp)) {
- info("$pkg: package not present, cannot remove\n");
- return($F_WARNING);
- }
- if ($opts{"backup"}) {
- $tlp->make_container($::progs{'compressor'}, $localtlpdb->root,
- destdir => $opts{"backupdir"},
- relative => $tlp->relocated,
- user => 1);
- if ($autobackup) {
- # in case we do auto backups we remove older backups
- clear_old_backups($pkg, $opts{"backupdir"}, $autobackup);
- }
- }
- return($localtlpdb->remove_package($pkg));
-}
-
-sub action_remove {
- # if --all is given, pass on to uninstall_texlive
- if ($opts{'all'}) {
- if (@ARGV) {
- tlwarn("$prg: No additional arguments allowed with --all: @ARGV\n");
- return($F_ERROR);
- }
- exit(uninstall_texlive());
- }
- # we do the following:
- # - (not implemented) order collections such that those depending on
- # other collections are first removed, and then those which only
- # depend on packages. Otherwise
- # remove collection-latex collection-latexrecommended
- # will not succeed
- # - first loop over all cmd line args and consider only the collections
- # - for each to be removed collection:
- # . check that no other collections/scheme asks for that collection
- # . remove the collection
- # . remove all dependencies
- # - for each normal package not already removed (via the above)
- # . check that no collection/scheme still depends on this package
- # . remove the package
- #
- $opts{"no-depends"} = 1 if $opts{"no-depends-at-all"};
- my %already_removed;
- my @more_removal;
- init_local_db();
- return($F_ERROR) if !check_on_writable();
- info("$prg remove: dry run, no changes will be made\n") if $opts{"dry-run"};
-
- my ($ret, $autobackup) = setup_backup_directory();
- return ($ret) if ($ret != $F_OK);
-
- my @packs = @ARGV;
- #
- # we have to be careful not to remove too many packages. The idea is
- # as follows:
- # - let A be the set of all packages to be removed from the cmd line
- # - let A* be the set of A with all dependencies expanded
- # - let B be the set of all packages
- # - let C = B \ A*, ie the set of all packages without those packages
- # in the set of A*
- # - let C* be the set of C with all dependencies expanded
- # - let D = A* \ C*, ie the set of all packages to be removed (A*)
- # without all the package that are still needed (C*)
- # - remove all package in D
- # - for any package in A (not in A*, in A, ie on the cmd line) that is
- # also in C* (so a package that was asked for to be removed on the
- # cmd line, but it isn't because someone else asks for it), warn the
- # user that it is still needed
- #
- # remove all .ARCH dependencies, too, unless $opts{"no-depends-at-all"}
- @packs = $localtlpdb->expand_dependencies("-only-arch", $localtlpdb, @packs)
- unless $opts{"no-depends-at-all"};
- # remove deps unless $opts{"no-depends"}
- @packs = $localtlpdb->expand_dependencies("-no-collections", $localtlpdb, @packs) unless $opts{"no-depends"};
- my %allpacks;
- for my $p ($localtlpdb->list_packages) { $allpacks{$p} = 1; }
- for my $p (@packs) { delete($allpacks{$p}); }
- my @neededpacks = $localtlpdb->expand_dependencies($localtlpdb, keys %allpacks);
- my %packs;
- my %origpacks;
- my @origpacks = $localtlpdb->expand_dependencies("-only-arch", $localtlpdb, @ARGV) unless $opts{"no-depends-at-all"};
- for my $p (@origpacks) { $origpacks{$p} = 1; }
- for my $p (@packs) { $packs{$p} = 1; }
- for my $p (@neededpacks) {
- if (defined($origpacks{$p})) {
- # that package was asked for to be removed on the cmd line
- my @needed = $localtlpdb->needed_by($p);
- if ($opts{"force"}) {
- info("$prg: $p is needed by " . join(" ", @needed) . "\n");
- info("$prg: removing it anyway, due to --force\n");
- } else {
- delete($packs{$p});
- tlwarn("$prg: not removing $p, needed by " .
- join(" ", @needed) . "\n");
- $ret |= $F_WARNING;
- }
- } else {
- delete($packs{$p});
- }
- }
- @packs = keys %packs;
-
- my %sizes = %{$localtlpdb->sizes_of_packages(
- $localtlpdb->option("install_srcfiles"),
- $localtlpdb->option("install_docfiles"), undef, @packs)};
- defined($sizes{'__TOTAL__'}) || ($sizes{'__TOTAL__'} = 0);
- my $totalsize = $sizes{'__TOTAL__'};
- my $totalnr = $#packs;
- my $currnr = 1;
- my $starttime = time();
- my $donesize = 0;
-
- print "total-bytes\t$sizes{'__TOTAL__'}\n" if $::machinereadable;
- print "end-of-header\n" if $::machinereadable;
-
- foreach my $pkg (sort @packs) {
- my $tlp = $localtlpdb->get_package($pkg);
- next if defined($already_removed{$pkg});
- if (!defined($tlp)) {
- info("$pkg: package not present, cannot remove\n");
- $ret |= $F_WARNING;
- } else {
- my ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
- $donesize, $starttime);
-
- # in the first round we only remove collections, nothing else
- # but removing collections will remove all dependencies, too
- # save the information of which packages have already been removed
- # into %already_removed.
- if ($tlp->category eq "Collection") {
- my $foo = 0;
- if ($::machinereadable) {
- machine_line($pkg, "d", $tlp->revision, "-", $sizes{$pkg}, $estrem, $esttot);
- } else {
- # info ("$prg: removing $pkg\n");
- info("[$currnr/$totalnr, $estrem/$esttot] remove: $pkg\n");
- }
- if (!$opts{"dry-run"}) {
- $foo = backup_and_remove_package($pkg, $autobackup);
- logpackage("remove: $pkg");
- }
- $currnr++;
- $donesize += $sizes{$pkg};
- if ($foo) {
- # removal was successful, so the return is at least 0x0001 mktexlsr
- # remove dependencies, too
- $already_removed{$pkg} = 1;
- }
- } else {
- # save all the other packages into the @more_removal list to
- # be removed at the second state. Note that if a package has
- # already been removed due to a removal of a collection
- # it will be marked as such in %already_removed and not tried again
- push (@more_removal, $pkg);
- }
- }
- }
- foreach my $pkg (sort @more_removal) {
- my $tlp = $localtlpdb->get_package($pkg);
- if (!defined($already_removed{$pkg})) {
- my ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
- $donesize, $starttime);
- # info ("$prg: removing package $pkg\n");
- if ($::machinereadable) {
- machine_line($pkg, "d", $tlp->revision, "-", $sizes{$pkg}, $estrem, $esttot);
- } else {
- # info ("$prg: removing $pkg\n");
- info("[$currnr/$totalnr, $estrem/$esttot] remove: $pkg\n");
- }
- $currnr++;
- $donesize += $sizes{$pkg};
- if (!$opts{"dry-run"}) {
- if (backup_and_remove_package($pkg, $autobackup)) {
- # removal was successful
- logpackage("remove: $pkg");
- $already_removed{$pkg} = 1;
- }
- }
- }
- }
- print "end-of-updates\n" if $::machinereadable;
- if ($opts{"dry-run"}) {
- # stop here, don't do any postinstall actions
- return ($ret | $F_NOPOSTACTION);
- } else {
- $localtlpdb->save;
- my @foo = sort keys %already_removed;
- if (@foo) {
- info("$prg: ultimately removed these packages: @foo\n")
- if (!$::machinereadable);
- } else {
- info("$prg: no packages removed.\n")
- if (!$::machinereadable);
- }
- }
- return ($ret);
-}
-
-
-# PAPER
-#
-# ARGV can look like:
-# paper a4
-# paper letter
-# [xdvi|...|context] paper [help|papersize|--list]
-#
-sub action_paper {
- init_local_db();
- my $texmfconfig;
- if ($opts{"usermode"}) {
- tlwarn("$prg: action `paper' not supported in usermode\n");
- return ($F_ERROR);
- }
- chomp($texmfconfig = `kpsewhich -var-value=TEXMFSYSCONFIG`);
- $ENV{"TEXMFCONFIG"} = $texmfconfig;
-
- my $action = shift @ARGV;
- if (!$action) {
- # can only happen in shell mode, because otherwise we push paper onto the stack before
- # going into the action_paper
- $action = "paper";
- }
-
- if ($action =~ m/^paper$/i) { # generic paper
- my $newpaper = shift @ARGV;
- if ($opts{"list"}) { # tlmgr paper --list => complain.
- tlwarn("$prg: ignoring paper setting to $newpaper with --list\n")
- if $newpaper; # complain if they tried to set, too.
- tlwarn("$prg: please specify a program before paper --list, ",
- "as in: tlmgr pdftex paper --list\n");
- return($F_ERROR)
-
- } elsif (!defined($newpaper)) { # tlmgr paper => show all current sizes.
- my $ret = $F_OK;
- if ($opts{'json'}) {
- my @foo;
- for my $prog (keys %TeXLive::TLPaper::paper) {
- my $pkg = $TeXLive::TLPaper::paper{$prog}{'pkg'};
- if ($localtlpdb->get_package($pkg)) {
- my $val = TeXLive::TLPaper::do_paper($prog,$texmfconfig,"--json");
- push @foo, $val;
- }
- }
- my $json = TeXLive::TLUtils::encode_json(\@foo);
- print "$json\n";
- return $ret;
- }
- for my $prog (sort keys %TeXLive::TLPaper::paper) {
- my $pkg = $TeXLive::TLPaper::paper{$prog}{'pkg'};
- if ($localtlpdb->get_package($pkg)) {
- $ret |= TeXLive::TLPaper::do_paper($prog,$texmfconfig,undef);
- }
- }
- return($ret);
- # return TeXLive::TLPaper::paper_all($texmfconfig,undef);
-
- } elsif ($newpaper !~ /^(a4|letter)$/) { # tlmgr paper junk => complain.
- $newpaper = "the empty string" if !defined($newpaper);
- tlwarn("$prg: expected `a4' or `letter' after paper, not $newpaper\n");
- return($F_ERROR);
-
- } else { # tlmgr paper {a4|letter} => do it.
- return ($F_ERROR) if !check_on_writable();
- if ($opts{'json'}) {
- tlwarn("$prg: option --json not supported with other arguments\n");
- return ($F_ERROR);
- }
- my $ret = $F_OK;
- for my $prog (sort keys %TeXLive::TLPaper::paper) {
- my $pkg = $TeXLive::TLPaper::paper{$prog}{'pkg'};
- if ($localtlpdb->get_package($pkg)) {
- $ret |= TeXLive::TLPaper::do_paper($prog,$texmfconfig,$newpaper);
- }
- }
- return($ret);
- # return (TeXLive::TLPaper::paper_all($texmfconfig,$newpaper));
- }
-
- } else { # program-specific paper
- if ($opts{'json'}) {
- tlwarn("$prg: option --json not supported with other arguments\n");
- return ($F_ERROR);
- }
- my $prog = $action; # first argument is the program to change
- my $pkg = $TeXLive::TLPaper::paper{$prog}{'pkg'};
- if (!$pkg) {
- tlwarn("Unknown paper configuration program $prog!\n");
- return ($F_ERROR);
- }
- if (!$localtlpdb->get_package($pkg)) {
- tlwarn("$prg: package $prog is not installed - cannot adjust paper size!\n");
- return ($F_ERROR);
- }
- my $arg = shift @ARGV; # get "paper" argument
- if (!defined($arg) || $arg ne "paper") {
- $arg = "the empty string." if ! $arg;
- tlwarn("$prg: expected `paper' after $prog, not $arg\n");
- return ($F_ERROR);
- }
- # the do_paper progs check for the argument --list, so if given
- # restore it to the cmd line.
- if (@ARGV) {
- return ($F_ERROR) if !check_on_writable();
- }
- unshift(@ARGV, "--list") if $opts{"list"};
- return(TeXLive::TLPaper::do_paper($prog,$texmfconfig,@ARGV));
- }
- # we should not come here anyway
- return($F_OK);
-}
-
-
-# PATH
-#
-sub action_path {
- if ($opts{"usermode"}) {
- tlwarn("$prg: action `path' not supported in usermode!\n");
- exit 1;
- }
- my $what = shift @ARGV;
- if (!defined($what) || ($what !~ m/^(add|remove)$/i)) {
- $what = "" if ! $what;
- tlwarn("$prg: action path requires add or remove, not: $what\n");
- return ($F_ERROR);
- }
- init_local_db();
- my $winadminmode = 0;
- if (win32()) {
- #
- # for w32 we do system wide vs user setting detection as follows:
- # - if --w32mode is NOT given,
- # - if admin
- # --> honor opt_w32_multi_user setting in tlpdb
- # - if not admin
- # - if opt_w32_multi_user == NO
- # --> do user path adjustment
- # - if opt_w32_multi_user == YES
- # --> do nothing, warn that the setting is on, suggest --w32mode user
- # - if --w32mode admin
- # - if admin
- # --> ignore opt_w32_multi_user and do system path adjustment
- # - if non-admin
- # --> do nothing but warn that user does not have privileges
- # - if --w32mode user
- # - if admin
- # --> ignore opt_w32_multi_user and do user path adjustment
- # - if non-admin
- # --> ignore opt_w32_multi_user and do user path adjustment
- if (!$opts{"w32mode"}) {
- $winadminmode = $localtlpdb->option("w32_multi_user");
- if (!TeXLive::TLWinGoo::admin()) {
- if ($winadminmode) {
- tlwarn("The TLPDB specifies system wide path adjustments\nbut you don't have admin privileges.\nFor user path adjustment please use\n\t--w32mode user\n");
- # and do nothing
- return ($F_ERROR);
- }
- }
- } else {
- # we are in the block where a --w32mode argument is given
- # we reverse the tests:
- if (TeXLive::TLWinGoo::admin()) {
- # in admin mode we simply use what is given on the cmd line
- if ($opts{"w32mode"} eq "user") {
- $winadminmode = 0;
- } elsif ($opts{"w32mode"} eq "admin") {
- $winadminmode = 1;
- } else {
- tlwarn("$prg: unknown --w32admin mode: $opts{w32mode}, should be 'admin' or 'user'\n");
- return ($F_ERROR);
- }
- } else {
- # we are non-admin
- if ($opts{"w32mode"} eq "user") {
- $winadminmode = 0;
- } elsif ($opts{"w32mode"} eq "admin") {
- tlwarn("$prg: You don't have the privileges to work in --w32mode admin\n");
- return ($F_ERROR);
- } else {
- tlwarn("$prg: unknown --w32admin mode: $opts{w32mode}, should be 'admin' or 'user'\n");
- return ($F_ERROR);
- }
- }
- }
- }
- my $ret = $F_OK;
- if ($what =~ m/^add$/i) {
- if (win32()) {
- $ret |= TeXLive::TLUtils::w32_add_to_path(
- $localtlpdb->root . "/bin/win32",
- $winadminmode);
- # ignore this return value, since broadcase_env might return
- # nothing in case of errors, and there is no way around it.
- # $ret |= TeXLive::TLWinGoo::broadcast_env();
- } else {
- $ret |= TeXLive::TLUtils::add_symlinks($localtlpdb->root,
- $localtlpdb->platform(),
- $localtlpdb->option("sys_bin"),
- $localtlpdb->option("sys_man"),
- $localtlpdb->option("sys_info"));
- }
- } elsif ($what =~ m/^remove$/i) {
- if (win32()) {
- $ret |= TeXLive::TLUtils::w32_remove_from_path(
- $localtlpdb->root . "/bin/win32",
- $winadminmode);
- # ignore this return value, since broadcase_env might return
- # nothing in case of errors, and there is no way around it.
- # $ret |= TeXLive::TLWinGoo::broadcast_env();
- } else {
- # remove symlinks
- $ret |= TeXLive::TLUtils::remove_symlinks($localtlpdb->root,
- $localtlpdb->platform(),
- $localtlpdb->option("sys_bin"),
- $localtlpdb->option("sys_man"),
- $localtlpdb->option("sys_info"));
- }
- } else {
- tlwarn("\n$prg: Should not happen, action_path what=$what\n");
- return ($F_ERROR);
- }
- # we should not need to run any post actions here, since
- # that changes only integrations, but no rebuild of formats etc etc
- # is needed
- return ($ret | $F_NOPOSTACTION);
-}
-
-# DUMP-TLPDB
-#
-sub action_dumptlpdb {
- init_local_db();
-
- # we are basically doing machine-readable output.
- my $savemr = $::machinereadable;
- $::machinereadable = 1;
-
- if ($opts{"local"} && !$opts{"remote"}) {
- if ($opts{"json"}) {
- print $localtlpdb->as_json;
- } else {
- # for consistency we write out the location of the installation,
- # too, in the same format as when dumping the remote tlpdb
- print "location-url\t", $localtlpdb->root, "\n";
- $localtlpdb->writeout;
- }
-
- } elsif ($opts{"remote"} && !$opts{"local"}) {
- init_tlmedia_or_die(1);
- if ($opts{"json"}) {
- print $remotetlpdb->as_json;
- } else {
- $remotetlpdb->writeout;
- }
-
- } else {
- tlwarn("$prg dump-tlpdb: need exactly one of --local and --remote.\n");
- return ($F_ERROR);
- }
-
- $::machinereadable = $savemr;
- return ($F_OK | $F_NOPOSTACTION);
-}
-
-# INFO
-#
-sub action_info {
- if ($opts{'only-installed'} && $opts{'only-remote'}) {
- tlwarn("Are you joking? --only-installed and --only-remote cannot both be specified!\n");
- return($F_ERROR);
- }
- init_local_db();
- my ($what,@todo) = @ARGV;
- my $ret = $F_OK | $F_NOPOSTACTION;
- my @datafields;
- my $fmt = "list";
- if ($opts{'data'} && $opts{'json'}) {
- tlwarn("Preferring json output over data output!\n");
- delete($opts{'data'});
- }
- if ($opts{'json'}) {
- $fmt = 'json';
- # the 1 is the silent mode!
- init_tlmedia_or_die(1);
- } elsif ($opts{'data'}) {
- # output format is changed to csv with " as quotes
- # we need to determine the fields
- @datafields = split(',', $opts{'data'});
- # check for correctness of data fields and whether remote is necessary
- my $load_remote = 0;
- for my $d (@datafields) {
- $load_remote = 1 if ($d eq "remoterev");
- if ($d !~ m/^(name|category|localrev|remoterev|shortdesc|longdesc|size|installed|relocatable|depends|[lr]?cat-version|[lr]?cat-date|[lr]?cat-license|[lr]?cat-contact-.*)$/) {
- tlwarn("unknown data field: $d\n");
- return($F_ERROR);
- }
- }
- $fmt = "csv";
- if ($load_remote) {
- if ($opts{"only-installed"}) {
- tlwarn("requesting only-installed with data field remoterev, loading remote anyway!\n");
- $opts{"only-installed"} = 0;
- }
- # loading of tlpdb is done below
- }
- } elsif (!$what || $what =~ m/^(collections|schemes)$/i) {
- $fmt = "list";
- } else {
- $fmt = "detail";
- }
- my $tlm;
- if ($opts{"only-installed"}) {
- $tlm = $localtlpdb;
- } else {
- # silent mode
- init_tlmedia_or_die(1);
- $tlm = $remotetlpdb;
- }
-
- #
- # tlmgr info
- # tlmgr info collection
- # tlmgr info scheme
- # these commands just list the packages/collections/schemes installed with
- # a short list
- my @whattolist;
- $what = ($what || "-all");
- if ($what =~ m/^collections$/i) {
- @whattolist = $tlm->collections;
- } elsif ($what =~ m/^schemes$/i) {
- @whattolist = $tlm->schemes;
- } elsif ($what =~ m/^-all$/i) {
- if ($tlm->is_virtual) {
- @whattolist = $tlm->list_packages("-all");
- } else {
- @whattolist = $tlm->list_packages;
- }
- if (!$opts{'only-remote'}) {
- # add also the local packages
- TeXLive::TLUtils::push_uniq(\@whattolist, $localtlpdb->list_packages);
- }
- } else {
- @whattolist = ($what, @todo);
- }
- my @adds;
- if ($opts{'data'}) {
- @adds = @datafields;
- }
- # TIMING OF JSON IMPLEMENTATIONS
- my ($startsec, $startmsec);
- if ($opts{'debug-json-timing'}) {
- require Time::HiRes;
- ($startsec, $startmsec) = Time::HiRes::gettimeofday();
- }
- print "[" if ($fmt eq "json");
- my $first = 1;
- foreach my $ppp (@whattolist) {
- next if ($ppp =~ m/^00texlive\./);
- print "," if ($fmt eq "json" && !$first);
- $first = 0;
- $ret |= show_one_package($ppp, $fmt, @adds);
- }
- print "]\n" if ($fmt eq "json");
- if ($opts{'debug-json-timing'}) {
- my ($endsec, $endmsec) = Time::HiRes::gettimeofday();
- if ($endmsec < $startmsec) {
- $endsec -= 1;
- $endmsec += 1000000;
- }
- print STDERR "JSON (", $TeXLive::TLUtils::jsonmode, ") generation took ", $endsec - $startsec, ".", substr($endmsec - $startmsec,0,2), " sec\n";
- }
- return ($ret);
-}
-
-
-# SEARCH
-#
-sub action_search {
- my ($r) = @ARGV;
- my $tlpdb;
- # check the arguments
- my $search_type_nr = 0;
- $search_type_nr++ if $opts{"file"};
- $search_type_nr++ if $opts{"all"};
- if ($search_type_nr > 1) {
- tlwarn("$prg: please specify only one thing to search for\n");
- return ($F_ERROR);
- }
- #
- if (!defined($r) || !$r) {
- tlwarn("$prg: nothing to search for.\n");
- return ($F_ERROR);
- }
-
- init_local_db();
- if ($opts{"global"}) {
- init_tlmedia_or_die();
- $tlpdb = $remotetlpdb;
- } else {
- $tlpdb = $localtlpdb;
- }
-
- my ($foundfile, $founddesc) = search_tlpdb($tlpdb, $r,
- $opts{'file'} || $opts{'all'},
- (!$opts{'file'} || $opts{'all'}),
- $opts{'word'});
-
- print $founddesc;
- print $foundfile;
-
- return ($F_OK | $F_NOPOSTACTION);
-}
-
-sub search_tlpdb {
- my ($tlpdb, $what, $dofile, $dodesc, $inword) = @_;
- my $retfile = '';
- my $retdesc = '';
- foreach my $pkg ($tlpdb->list_packages) {
- my $tlp = $tlpdb->get_package($pkg);
-
- # --file or --all -> search (full) file names
- if ($dofile) {
- my @ret = search_pkg_files($tlp, $what);
- if (@ret) {
- $retfile .= "$pkg:\n";
- foreach (@ret) {
- $retfile .= "\t$_\n";
- }
- }
- }
- #
- # no options or --all -> search package names/descriptions
- if ($dodesc) {
- next if ($pkg =~ m/\./);
- my $matched = search_pkg_desc($tlp, $what, $inword);
- $retdesc .= "$matched\n" if ($matched);
- }
- }
- return($retfile, $retdesc);
-}
-
-sub search_pkg_desc {
- my ($tlp, $what, $inword) = @_;
- my $pkg = $tlp->name;
- my $t = "$pkg\n";
- $t = $t . $tlp->shortdesc . "\n" if (defined($tlp->shortdesc));
- $t = $t . $tlp->longdesc . "\n" if (defined($tlp->longdesc));
- $t = $t . $tlp->cataloguedata->{'topics'} . "\n" if (defined($tlp->cataloguedata->{'topics'}));
- my $pat = $what;
- $pat = '\W' . $what . '\W' if ($inword);
- my $matched = "";
- if ($t =~ m/$pat/i) {
- my $shortdesc = $tlp->shortdesc || "";
- $matched .= "$pkg - $shortdesc";
- }
- return $matched;
-}
-
-sub search_pkg_files {
- my ($tlp, $what) = @_;
- my @files = $tlp->all_files;
- if ($tlp->relocated) {
- for (@files) { s:^$RelocPrefix/:$RelocTree/:; }
- }
- my @ret = grep(m;$what;, @files);
- return @ret;
-}
-
-# RESTORE
-#
-# read the directory and check what files/package/rev are available
-# for restore
-sub get_available_backups {
- my $bd = shift;
- my $do_stat = shift;
- # initialize the hash(packages) of hash(revisions)
- my %backups;
- opendir (DIR, $bd) || die "opendir($bd) failed: $!";
- my @dirents = readdir (DIR);
- closedir (DIR) || warn "closedir($bd) failed: $!";
- #
- # see below for explanation, this has effects only on W32
- my $oldwsloppy = ${^WIN32_SLOPPY_STAT};
- ${^WIN32_SLOPPY_STAT} = 1;
- #
- my $pkg;
- my $rev;
- my $ext;
- for my $dirent (@dirents) {
- $pkg = "";
- $rev = "";
- $ext = "";
- next if (-d $dirent);
- if ($dirent =~ m/^(.*)\.r([0-9]+)\.tar\.$CompressorExtRegexp$/) {
- $pkg = $1;
- $rev = $2;
- $ext = $3;
- } else {
- next;
- }
- if (!$do_stat) {
- $backups{$pkg}->{$rev} = 1;
- next;
- }
- my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- $atime,$mtime,$ctime,$blksize,$blocks) = stat("$bd/$dirent");
- # times: as we want to be portable we try the following times:
- # - first choice is ctime which hopefully works nicely
- # - on UFS (OSX) ctime is not supported, so use mtime
- # furthermore, if we are on W32 we want to be fast and make only
- # a sloppy stat
- # for more on that please see man perlport
- my $usedt = $ctime;
- if (!$usedt) {
- # can happen on
- $usedt = $mtime;
- }
- if (!$usedt) {
- # stat failed, set key to -1 as a sign that there is a backup
- # but we cannot stat it
- $backups{$pkg}->{$rev} = -1;
- } else {
- $backups{$pkg}->{$rev} = $usedt;
- }
- }
- # reset the original value of the w32 sloppy mode for stating files
- ${^WIN32_SLOPPY_STAT} = $oldwsloppy;
- return %backups;
-}
-
-sub restore_one_package {
- my ($pkg, $rev, $bd) = @_;
- # first remove the package, then reinstall it
- # this way we get rid of useless files
- my $restore_file;
- for my $ext (map {$Compressors{$_}{'extension'}}
- sort {$Compressors{$a}{'priority'} <=> $Compressors{$a}{'priority'}}
- keys %Compressors) {
- if (-r "$bd/${pkg}.r${rev}.tar.$ext") {
- $restore_file = "$bd/${pkg}.r${rev}.tar.$ext";
- last;
- }
- }
- if (!$restore_file) {
- tlwarn("$prg: cannot find restore file $bd/${pkg}.r${rev}.tar.*, no action taken\n");
- return ($F_ERROR);
- }
- $localtlpdb->remove_package($pkg);
- # the -1 force the TLUtils::unpack to NOT warn about missing checksum/sizes
- TeXLive::TLPDB->_install_data($restore_file , 0, [], $localtlpdb, "-1", "-1");
- logpackage("restore: $pkg ($rev)");
- # now we have to read the .tlpobj file and add it to the DB
- my $tlpobj = TeXLive::TLPOBJ->new;
- $tlpobj->from_file($localtlpdb->root . "/tlpkg/tlpobj/$pkg.tlpobj");
- $localtlpdb->add_tlpobj($tlpobj);
- TeXLive::TLUtils::announce_execute_actions("enable",
- $localtlpdb->get_package($pkg));
- check_announce_format_triggers($pkg);
- $localtlpdb->save;
- # TODO_ERRORCHECKING we should check the return values of the
- # various calls above
- return ($F_OK);
-}
-
-sub setup_backup_directory {
- my $ret = $F_OK;
- my $autobackup = 0;
- # check for the tlpdb option autobackup, and if present and true (!= 0)
- # assume we are doing backups
- if (!$opts{"backup"}) {
- $autobackup = $localtlpdb->option("autobackup");
- if ($autobackup) {
- # check the format, we currently allow only natural numbers, and -1
- if ($autobackup eq "-1") {
- debug ("Automatic backups activated, keeping all backups.\n");
- $opts{"backup"} = 1;
- } elsif ($autobackup eq "0") {
- debug ("Automatic backups disabled.\n");
- } elsif ($autobackup =~ m/^[0-9]+$/) {
- debug ("Automatic backups activated, keeping $autobackup backups.\n");
- $opts{"backup"} = 1;
- } else {
- tlwarn ("$prg: Option autobackup value can only be an integer >= -1.\n");
- tlwarn ("$prg: Disabling auto backups.\n");
- $localtlpdb->option("autobackup", 0);
- $autobackup = 0;
- $ret |= $F_WARNING;
- }
- }
- }
-
- # cmd line --backup, we check for --backupdir, and if that is not given
- # we try to get the default from the tlpdb. If that doesn't work, exit.
- if ($opts{"backup"}) {
- my ($a, $b) = check_backupdir_selection();
- if ($a & $F_ERROR) {
- # in all these cases we want to terminate in the non-gui mode
- tlwarn($b);
- return ($F_ERROR, $autobackup);
- }
- }
-
- # finally, if we have --backupdir, but no --backup, just enable it
- $opts{"backup"} = 1 if $opts{"backupdir"};
-
- my $saving_verb = $opts{"dry-run"} || $opts{"list"} ? "would save" :"saving";
- info("$prg: $saving_verb backups to $opts{'backupdir'}\n")
- if $opts{"backup"} && !$::machinereadable;
-
- return ($ret, $autobackup);
-}
-
-sub check_backupdir_selection {
- my $warntext = "";
- if ($opts{"backupdir"}) {
- my $ob = abs_path($opts{"backupdir"});
- $ob && ($opts{"backupdir"} = $ob);
- if (! -d $opts{"backupdir"}) {
- $warntext .= "$prg: backupdir argument\n";
- $warntext .= " $opts{'backupdir'}\n";
- $warntext .= "is not a directory.\n";
- return ($F_ERROR, $warntext);
- }
- } else {
- # no argument, check for presence in TLPDB
- init_local_db(1);
- $opts{"backupdir"} = norm_tlpdb_path($localtlpdb->option("backupdir"));
- if (!$opts{"backupdir"}) {
- return (0, "$prg: cannot determine backupdir.\n");
- }
- # we are still here, there is something set in tlpdb
- my $ob = abs_path($opts{"backupdir"});
- $ob && ($opts{"backupdir"} = $ob);
- if (! -d $opts{"backupdir"}) {
- $warntext = "$prg: backupdir as set in tlpdb\n";
- $warntext .= " $opts{'backupdir'}\n";
- $warntext .= "is not a directory.\n";
- return ($F_ERROR, $warntext);
- }
- }
- return $F_OK;
-}
-
-sub action_restore {
- # tlmgr restore [--backupdir dir] --all
- # restores of all packages found in backupdir the latest version
- # tlmgr restore --backupdir dir
- # lists all packages with all revisions
- # tlmgr restore --backupdir dir pkg
- # lists all revisions of pkg
- # tlmgr restore --backupdir dir pkg rev
- # restores pkg to revision rev
- # check the backup dir argument
-
- {
- my ($a, $b) = check_backupdir_selection();
- if ($a & $F_ERROR) {
- # in all these cases we want to terminate in the non-gui mode
- tlwarn($b);
- return ($F_ERROR);
- }
- }
- info("$prg restore: dry run, no changes will be made\n") if $opts{"dry-run"};
-
- # initialize the hash(packages) of hash(revisions), do stat files! (the 1)
- my %backups = get_available_backups($opts{"backupdir"}, 1);
- my ($pkg, $rev) = @ARGV;
- if (defined($pkg) && $opts{"all"}) {
- tlwarn("$prg: Specify either --all or individual package(s) ($pkg)\n");
- tlwarn("$prg: to restore, not both. Terminating.\n");
- return ($F_ERROR);
- }
- if ($opts{"all"}) {
- init_local_db(1);
- return ($F_ERROR) if !check_on_writable();
- if (!$opts{"force"}) {
- print "Do you really want to restore all packages to the latest revision found in\n\t$opts{'backupdir'}\n===> (y/N): ";
- my $yesno = <STDIN>;
- if ($yesno !~ m/^y(es)?$/i) {
- print "Ok, cancelling the restore!\n";
- return ($F_OK | $F_NOPOSTACTION);
- }
- }
- for my $p (sort keys %backups) {
- my @tmp = sort {$b <=> $a} (keys %{$backups{$p}});
- my $rev = $tmp[0];
- print "Restoring $p, $rev from $opts{'backupdir'}/${p}.r${rev}.tar.*\n";
- if (!$opts{"dry-run"}) {
- # first remove the package, then reinstall it
- # this way we get rid of useless files
- # TODO_ERRORCHECK needs check for return values!!
- restore_one_package($p, $rev, $opts{"backupdir"});
- }
- }
- # localtlpdb already saved, so we are finished
- return ($F_OK);
- }
- #
- # intermediate sub
- sub report_backup_revdate {
- my $p = shift;
- my $mode = shift;
- my %revs = @_;
- my @rs = sort {$b <=> $a} (keys %revs);
- my @outarr;
- for my $rs (@rs) {
- my %jsonkeys;
- $jsonkeys{'name'} = $p;
- my $dstr;
- if ($revs{$rs} == -1) {
- $dstr = "unknown";
- } else {
- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
- localtime($revs{$rs});
- # localtime returns dates starting from 1900, and the month is 0..11
- $dstr = sprintf "%04d-%02d-%02d %02d:%02d",
- $year+1900, $mon+1, $mday, $hour, $min;
- }
- if ($mode eq "json") {
- $jsonkeys{'rev'} = "$rs";
- $jsonkeys{'date'} = $dstr;
- push @outarr, \%jsonkeys;
- } else {
- push @outarr, "$rs ($dstr)";
- }
- }
- if ($mode eq "json") {
- return @outarr;
- } else {
- return ( join(" ", @outarr));
- }
- }
- # end sub
- if (!defined($pkg)) {
- if (keys %backups) {
- if ($opts{'json'}) {
- my @bla = map { report_backup_revdate($_, "json", %{$backups{$_}}) } keys %backups;
- my $str = TeXLive::TLUtils::encode_json(\@bla);
- print "$str\n";
- } else {
- print "Available backups:\n";
- foreach my $p (sort keys %backups) {
- print "$p: ";
- print(report_backup_revdate($p, "text", %{$backups{$p}}));
- print "\n";
- }
- }
- } else {
- if ($opts{'json'}) {
- print "[]\n";
- } else {
- print "No backups available in $opts{'backupdir'}\n";
- }
- }
- return ($F_OK | $F_NOPOSTACTION);
- }
- if (!defined($rev)) {
- if ($opts{'json'}) {
- my @bla = report_backup_revdate($pkg, "json", %{$backups{$pkg}});
- my $str = TeXLive::TLUtils::encode_json(\@bla);
- print "$str\n";
- } else {
- print "Available backups for $pkg: ";
- print(report_backup_revdate($pkg, "text", %{$backups{$pkg}}));
- print "\n";
- }
- return ($F_OK | $F_NOPOSTACTION);
- }
- # we did arrive here, so we try to restore ...
- if (defined($backups{$pkg}->{$rev})) {
- return if !check_on_writable();
- if (!$opts{"force"}) {
- print "Do you really want to restore $pkg to revision $rev (y/N): ";
- my $yesno = <STDIN>;
- if ($yesno !~ m/^y(es)?$/i) {
- print "Ok, cancelling the restore!\n";
- return ($F_OK | $F_NOPOSTACTION);
- }
- }
- print "Restoring $pkg, $rev from $opts{'backupdir'}/${pkg}.r${rev}.tar.xz\n";
- if (!$opts{"dry-run"}) {
- init_local_db(1);
- # first remove the package, then reinstall it
- # this way we get rid of useless files
- restore_one_package($pkg, $rev, $opts{"backupdir"});
- }
- # TODO_ERRORCHECKING check return value of restore_one_package
- return ($F_OK);
- } else {
- print "revision $rev for $pkg is not present in $opts{'backupdir'}\n";
- return ($F_ERROR);
- }
-}
-
-sub action_backup {
- init_local_db(1);
- # --clean argument
- # can be either -1 ... don't clean
- # 0 ... remove all backups
- # N ... keep only N backups
- # that parallels the value of autoclean in the configuration
- # we have to be careful, because if simply --clean is given, we should
- # check for the value saved in the tlpdb, and if that is not present
- # do nothing.
- # We have set clean to clean:-99 which makes -99 the default value
- # if only --clean is given without any argument
- # !defined($opts{"clean"}) -> no --clean given
- # $opts{"clean"} = -99 -> --clean without argument given, check tlpdb
- # $opts{"clean"} = -1, 0, N -> --clean=N given, check argument
- #
- my $clean_mode = 0;
- $clean_mode = 1 if defined($opts{"clean"});
- if ($clean_mode) {
- if ($opts{"clean"} == -99) {
- # we need to check the tlpdb
- my $tlpdb_option = $localtlpdb->option("autobackup");
- if (!defined($tlpdb_option)) {
- tlwarn ("$prg: --clean given without an argument, but no default clean\n");
- tlwarn ("$prg: mode specified in the tlpdb.\n");
- return ($F_ERROR);
- }
- $opts{"clean"} = $tlpdb_option;
- }
- # now $opts{"clean"} is something, but maybe not a number, check for
- # validity
- if ($opts{"clean"} =~ m/^(-1|[0-9]+)$/) {
- # get rid of leading zeros etc etc
- $opts{"clean"} = $opts{"clean"} + 0;
- } else {
- tlwarn ("$prg: clean mode as specified on the command line or as given by default\n");
- tlwarn ("$prg: must be an integer larger or equal than -1, terminating.\n");
- return($F_ERROR);
- }
- }
- # check the backup dir argument
- {
- my ($a, $b) = check_backupdir_selection();
- if ($a & $F_ERROR) {
- # in all these cases we want to terminate in the non-gui mode
- tlwarn($b);
- return($F_ERROR);
- }
- }
-
- # if we do --clean --all we also want to remove packages that
- # are not present anymore in the tlpdb, so use the readdir mode
- # to determine backups
- if ($opts{"all"} && $clean_mode) {
- # initialize the hash(packages) of hash(revisions)
- # no need to stat the files
- my %backups = get_available_backups($opts{"backupdir"}, 0);
- init_local_db(1);
- for my $p (sort keys %backups) {
- clear_old_backups ($p, $opts{"backupdir"}, $opts{"clean"}, $opts{"dry-run"}, 1);
- }
- info("no action taken due to --dry-run\n") if $opts{"dry-run"};
- return ($F_OK | $F_NOPOSTACTION);
- }
-
- # in case we are not cleaning or cleaning only specific packages
- # use the one-by-one mode
- my @todo;
- if ($opts{"all"}) {
- @todo = $localtlpdb->list_packages;
- } else {
- @todo = @ARGV;
- @todo = $localtlpdb->expand_dependencies("-only-arch", $localtlpdb, @todo);
- }
- if (!@todo) {
- printf "tlmgr backup takes either a list of packages or --all\n";
- return ($F_ERROR);
- }
- foreach my $pkg (@todo) {
- if ($clean_mode) {
- clear_old_backups ($pkg, $opts{"backupdir"}, $opts{"clean"}, $opts{"dry-run"}, 1);
- } else {
- # for now default to xz and allow overriding with env var
- my $compressorextension = $Compressors{$::progs{'compressor'}}{'extension'};
- my $tlp = $localtlpdb->get_package($pkg);
- my $saving_verb = $opts{"dry-run"} ? "would save" : "saving";
- info("$saving_verb current status of $pkg to $opts{'backupdir'}/${pkg}.r"
- . $tlp->revision . ".tar.$compressorextension\n");
- if (!$opts{"dry-run"}) {
- $tlp->make_container($::progs{'compressor'}, $localtlpdb->root,
- destdir => $opts{"backupdir"},
- user => 1);
- }
- }
- }
- info("no action taken due to --dry-run\n") if $opts{"dry-run"};
- # TODO_ERRORCHECKING needs checking of the above
- return ($F_OK);
-}
-
-# =====================================================================
-# INFRASTRUCTURE UPDATE ON WINDOWS
-# =====================================================================
-# Infrastructure files cannot be updated directly from the
-# tlmgr.pl script due to file locking problem on Windows - files that
-# are in use (either open or executing) cannot be removed or replaced.
-# For that reason the update process is performed by a batch script
-# outside of tlmgr.pl.
-# There are three pieces involved in the update: tlmgr.bat
-# launcher, write_w32_updater subroutine below and a batch
-# updater script. Their roles are as follows:
-# * tlmgr.bat is a watchdog, it launches tlmgr.pl and watches for
-# the updater script that is to be executed. If the updater script
-# exists before tlmgr.pl is launched, it will be removed or
-# tlmgr.bat will abort if it fails to do so. This means that the
-# updater script has to be created by the current invocation of
-# tlmgr.pl. Furthermore, the updater script is renamed from
-# updater-w32 to updater-w32.bat just before it is run, and thus
-# it can be executed only once.
-# * write_w32_updater subroutine in tlmgr.pl prepares the update
-# and writes the updater script. Packages in .xz archives are
-# downloaded/copied and uncompressed to .tar files. Also .tar
-# backups of the current packages are made. If everything is
-# successful, the update script is created from the template.
-# Otherwise the update is aborted.
-# * updater-w32[.bat] batch script, triggers and executes the actual
-# update. It first restarts itself in a separate instance of cmd.exe
-# (and in a new console window in gui mode) and runs the update
-# from there. The update is run with echo on and all output is
-# logged to a file (or stderr in verbose mode). After successful
-# infrastructure update, tlmgr is optionally restarted if update
-# of other packages is asked for.
-# The infrastructure update itself proceeds as follows:
-# (1) untar all package archives
-# (2) include .tlpobj files into tlpdb
-# (3) print update info to console
-# Any error during (1) or (2) triggers the rollback sequence:
-# (1) print failed update info to console
-# (2) untar all package backups
-# (3) include .tlpobj files (from backup) into tlpdb
-# (4) print restore info to console
-# Any error during (2) or (3) and we go into panic state. At this
-# point there is no guarantee that the installation is still working.
-# There is not much we can do but to print failed restore info and
-# give instructions to download and run 'update-tlmgr-latest.exe'
-# to repair the installation.
-# =====================================================================
-#
-sub write_w32_updater {
- my ($restart_tlmgr, $ref_files_to_be_removed, @w32_updated) = @_;
- my @infra_files_to_be_removed = @$ref_files_to_be_removed;
- # TODO do something with these files TODO
- my $media = $remotetlpdb->media;
- # we have to download/copy also the src/doc files if necessary!
- my $container_src_split = $remotetlpdb->config_src_container;
- my $container_doc_split = $remotetlpdb->config_doc_container;
- # get options about src/doc splitting from $totlpdb
- # TT: should we use local options to decide about install of doc & src?
- my $opt_src = $localtlpdb->option("install_srcfiles");
- my $opt_doc = $localtlpdb->option("install_docfiles");
- my $root = $localtlpdb->root;
- my $temp = "$root/temp";
- TeXLive::TLUtils::mkdirhier($temp);
- tlwarn("$prg: Backup option not implemented for infrastructure update.\n") if ($opts{"backup"});
- if ($media eq 'local_uncompressed') {
- tlwarn("$prg: Creating updater from local_uncompressed currently not implemented!\n");
- tlwarn("$prg: But it should not be necessary!\n");
- return 1; # abort
- }
- my (@upd_tar, @upd_tlpobj, @upd_info, @rst_tar, @rst_tlpobj, @rst_info);
- foreach my $pkg (@w32_updated) {
- my $repo;
- my $mediatlp;
- # need to update the media type to the original, as it is
- # reset below
- $media = $remotetlpdb->media;
- if ($media eq "virtual") {
- my $maxtlpdb;
- (undef, undef, $mediatlp, $maxtlpdb) =
- $remotetlpdb->virtual_candidate($pkg);
- $repo = $maxtlpdb->root . "/$Archive";
- # update the media type of the used tlpdb
- # otherwise later on we stumble when preparing the updater
- $media = $maxtlpdb->media;
- } else {
- $mediatlp = $remotetlpdb->get_package($pkg);
- $repo = $remotetlpdb->root . "/$Archive";
- }
- my $localtlp = $localtlpdb->get_package($pkg);
- my $oldrev = $localtlp->revision;
- my $newrev = $mediatlp->revision;
- # we do install documentation files for category Documentation even if
- # option("install_docfiles") is false
- my $opt_real_doc = ($mediatlp->category =~ m/documentation/i) ? 1 : $opt_doc;
- my @pkg_parts = ($pkg);
- push(@pkg_parts, "$pkg.source") if ($container_src_split && $opt_src && $mediatlp->srcfiles);
- push(@pkg_parts, "$pkg.doc") if ($container_doc_split && $opt_real_doc && $mediatlp->docfiles);
- foreach my $pkg_part (@pkg_parts) {
- push (@upd_tar, "$pkg_part.tar");
- push (@upd_tlpobj, "tlpkg\\tlpobj\\$pkg_part.tlpobj");
- }
- push (@upd_info, "$pkg ^($oldrev -^> $newrev^)");
- push (@rst_tar, "__BACKUP_$pkg.r$oldrev.tar");
- push (@rst_tlpobj, "tlpkg\\tlpobj\\$pkg.tlpobj");
- push (@rst_info, "$pkg ^($oldrev^)");
- next if ($opts{"dry-run"});
- # create backup; make_container expects filename in format:
- # some-name.r[0-9]+
- my ($size, undef, $fullname) = $localtlp->make_container("tar", $root,
- destdir => $temp,
- containername => "__BACKUP_$pkg",
- user => 1);
- if ($size <= 0) {
- tlwarn("$prg: creation of backup container failed for: $pkg\n");
- return 1; # backup failed? abort
- }
- my $decompressor = $::progs{$DefaultCompressorFormat};
- my $compressorextension = $Compressors{$DefaultCompressorFormat}{'extension'};
- my @decompressorArgs = @{$Compressors{$DefaultCompressorFormat}{'decompress_args'}};
- foreach my $pkg_part (@pkg_parts) {
- my $dlcontainer = "$temp/$pkg_part.tar.$compressorextension";
- if ($media eq 'local_compressed') {
- copy("$repo/$pkg_part.tar.$compressorextension", "$temp");
- } else { # net
- TeXLive::TLUtils::download_file("$repo/$pkg_part.tar.$compressorextension", $dlcontainer);
- }
- # now we should have the file present
- if (!-r $dlcontainer) {
- tlwarn("$prg: couldn't get $pkg_part.tar.$compressorextension, that is bad\n");
- return 1; # abort
- }
- # unpack xz archive
- my $sysret = system("$decompressor @decompressorArgs < \"$dlcontainer\" > \"$temp/$pkg_part.tar\"");
- if ($sysret) {
- tlwarn("$prg: couldn't unpack $pkg_part.tar.$compressorextension\n");
- return 1; # unpack failed? abort
- }
- unlink($dlcontainer); # we don't need that archive anymore
- }
- }
-
- # prepare updater script
- my $respawn_cmd = "cmd.exe /e:on/v:off/d/c";
- $respawn_cmd = "start /wait $respawn_cmd" if ($::gui_mode);
- my $gui_pause = ($::gui_mode ? "pause" : "rem");
- my $upd_log = ($::opt_verbosity ? "STDERR" : '"%~dp0update-self.log"');
- my $std_handles_redir = ($::opt_verbosity ? "1^>^&2" : "2^>$upd_log 1^>^&2");
- my $pkg_log = ($packagelogfile ? "\"$packagelogfile\"" : "nul");
- my $post_update_msg = "You may now close this window.";
- my $rerun_tlmgr = "rem";
- if ($restart_tlmgr) {
- $post_update_msg = "About to restart tlmgr to complete update ...";
- # quote all arguments for tlmgr restart in case of spaces
- $rerun_tlmgr = join (" ", map ("\"$_\"", @::SAVEDARGV) );
- $rerun_tlmgr = "if not errorlevel 1 tlmgr.bat $rerun_tlmgr";
- }
- my $batch_script = <<"EOF";
-:: This file is part of an automated update process of
-:: infrastructure files and should not be run standalone.
-:: For more details about the update process see comments
-:: in tlmgr.pl (subroutine write_w32_updater).
-
- if [%1]==[:doit] goto :doit
- if not exist "%~dp0tar.exe" goto :notar
- $respawn_cmd call "%~f0" :doit $std_handles_redir
- $rerun_tlmgr
- goto :eof
-
-:notar
- echo %~nx0: cannot run without "%~dp0tar.exe"
- findstr "^::" <"%~f0"
- exit /b 1
-
-:doit
- set prompt=TL\$G
- title TeX Live Manager $TeXLive::TLConfig::ReleaseYear Update
- set PERL5LIB=$root/tlpkg/tlperl/lib
- >con echo DO NOT CLOSE THIS WINDOW!
- >con echo TeX Live infrastructure update in progress ...
- >con echo Detailed command logging to $upd_log
- pushd "%~dp0.."
- if not errorlevel 1 goto :update
- >con echo Could not change working directory to "%~dp0.."
- >con echo Aborting infrastructure update, no changes have been made.
- >con $gui_pause
- popd
- exit /b 1
-
-:update
- for %%I in (@upd_tar) do (
- temp\\tar.exe -xmf temp\\%%I
- if errorlevel 1 goto :rollback
- )
- tlpkg\\tlperl\\bin\\perl.exe .\\texmf-dist\\scripts\\texlive\\tlmgr.pl _include_tlpobj @upd_tlpobj
- if errorlevel 1 goto :rollback
- >>$pkg_log echo [%date% %time%] self update: @upd_info
- >con echo self update: @upd_info
- del "%~dp0*.tar" "%~dp0tar.exe"
- >con echo Infrastructure update finished successfully.
- >con echo $post_update_msg
- >con $gui_pause
- popd
- exit /b 0
-
-:rollback
- >>$pkg_log echo [%date% %time%] failed self update: @upd_info
- >con echo failed self update: @upd_info
- >con echo Rolling back to previous version ...
- for %%I in (@rst_tar) do (
- temp\\tar.exe -xmf temp\\%%I
- if errorlevel 1 goto :panic
- )
- tlpkg\\tlperl\\bin\\perl.exe .\\texmf-dist\\scripts\\texlive\\tlmgr.pl _include_tlpobj @rst_tlpobj
- if errorlevel 1 goto :panic
- >>$pkg_log echo [%date% %time%] self restore: @rst_info
- >con echo self restore: @rst_info
- >con echo Infrastructure update failed. Previous version has been restored.
- >con $gui_pause
- popd
- exit /b 1
-
-:panic
- >>$pkg_log echo [%date% %time%] failed self restore: @rst_info
- >con echo failed self restore: @rst_info
- >con echo FATAL ERROR:
- >con echo Infrastructure update failed and backup recovery failed too.
- >con echo To repair your TeX Live installation download and run:
- >con echo $TeXLive::TLConfig::TeXLiveURL/update-tlmgr-latest.exe
- >con $gui_pause
- popd
- exit /b 666
-EOF
-
- ddebug("\n:: UPDATER BATCH SCRIPT ::\n$batch_script\n:: END OF FILE ::\n");
- if ($opts{"dry-run"}) {
- my $upd_info = "self update: @upd_info";
- $upd_info =~ s/\^//g;
- info($upd_info);
- } else {
- copy("$root/tlpkg/installer/tar.exe", "$temp");
- # make sure copied tar is working
- if (system("\"$temp/tar.exe\" --version >nul")) {
- tlwarn("$prg: could not copy tar.exe, that is bad.\n");
- return 1; # abort
- }
- open UPDATER, ">$temp/updater-w32" or die "Cannot create updater script: $!";
- print UPDATER $batch_script;
- close UPDATER;
- }
- return 0;
-}
-
-
-# UPDATE
-
-# compute the list of auto-install, auto-remove, forcibly-removed
-# packages from the list of packages to be installed
-# the list of packages passed in is already expanded
-sub auto_remove_install_force_packages {
- my @todo = @_;
- my %removals_full;
- my %forcermpkgs_full;
- my %newpkgs_full;
- my %new_pkgs_due_forcerm_coll;
- # check for new/removed/forcibly removed packages.
- # we start from the list of installed collections in the local tlpdb
- # which are also present in the remote database
- # and expand this list once with expand_dependencies in the local tlpdb
- # and once in the tlmedia tlpdb. Then we compare the lists
- # let A = set of local expansions
- # B = set of remote expansions
- # then we should(?) have
- # B \ A set of new packages
- # A \ B set of packages removed on the server
- # A \cup B set of packages which should be checked for forcible removal
- #
- my @all_schmscolls = ();
- for my $p ($localtlpdb->schemes) {
- push (@all_schmscolls, $p) if defined($remotetlpdb->get_package($p));
- }
- for my $p ($localtlpdb->collections) {
- push (@all_schmscolls, $p) if defined($remotetlpdb->get_package($p));
- }
- my @localexpansion_full =
- $localtlpdb->expand_dependencies($localtlpdb, @all_schmscolls);
- my @remoteexpansion_full =
- $remotetlpdb->expand_dependencies($localtlpdb, @all_schmscolls);
-
- # compute new/remove/forcerm based on the full expansions
- for my $p (@remoteexpansion_full) {
- $newpkgs_full{$p} = 1;
- }
- for my $p (@localexpansion_full) {
- delete($newpkgs_full{$p});
- $removals_full{$p} = 1;
- }
- for my $p (@remoteexpansion_full) {
- delete($removals_full{$p});
- }
- # in a first round we check only for forcibly removed collections
- # this is necessary to NOT declare a package that is contained
- # in a forcibly removed collections as auto-install since it appears
- # in the @remoteexpansion_full, but not in @localexpansion_full.
- for my $p (@localexpansion_full) {
- # intersection, don't check A\B and B\A
- next if $newpkgs_full{$p};
- next if $removals_full{$p};
- my $remotetlp = $remotetlpdb->get_package($p);
- if (!defined($remotetlp)) {
- tlwarn("$prg: Strange, $p mentioned but not found anywhere!\n");
- next;
- }
- next if ($remotetlp->category ne "Collection");
- my $tlp = $localtlpdb->get_package($p);
- if (!defined($tlp)) {
- if ($opts{"reinstall-forcibly-removed"}) {
- $newpkgs_full{$p} = 1;
- } else {
- $forcermpkgs_full{$p} = 1;
- }
- }
- }
- # now we have in %forcermpkgs_full only collections that have been
- # forcibly removed. Again, expand those against the remote tlpdb
- # and remove the expanded packages from the list of localexpansion.
- my @pkgs_from_forcerm_colls =
- $remotetlpdb->expand_dependencies($localtlpdb, keys %forcermpkgs_full);
- #
- # the package in @pkgs_from_forcerm_colls would be auto-installed, so
- # check for that:
- for my $p (keys %newpkgs_full) {
- if (member($p, @pkgs_from_forcerm_colls)) {
- delete $newpkgs_full{$p};
- $new_pkgs_due_forcerm_coll{$p} = 1;
- }
- }
- #
- # now create the final list of forcerm packages by checking against
- # all packages
- for my $p (@localexpansion_full) {
- # intersection, don't check A\B and B\A
- next if $newpkgs_full{$p};
- next if $removals_full{$p};
- my $tlp = $localtlpdb->get_package($p);
- if (!defined($tlp)) {
- if ($opts{"reinstall-forcibly-removed"}) {
- $newpkgs_full{$p} = 1;
- } else {
- $forcermpkgs_full{$p} = 1;
- }
- }
- }
- #
- # for some packages (texworks, psview, ...) we only have w32 packages
- # in the repository, but it is possible that alternative repositories
- # ship binaries for some platforms (like texworks for GNU/Linux on tlcontrib)
- # currently updating from tlnet will remove these alternative .ARCH
- # packages because they are not listed anywhere locally, so they
- # are considered as disappearing.
- # We remove here packages PKG.ARCH if the main package PKG is found
- # here and is *not* disappearing, from the removal hash
- for my $p (keys %removals_full) {
- if ($p =~ m/^([^.]*)\./) {
- my $mpkg = $1;
- if (!defined($removals_full{$mpkg})) {
- delete($removals_full{$p});
- }
- }
- }
- #
- # now take only the subset of packages that is in @todo
- # note that @todo is already expanded in action_update according
- # to the --no-depends and --no-depends-at-all options
- #
- my %removals;
- my %forcermpkgs;
- my %newpkgs;
- for my $p (@todo) {
- $removals{$p} = 1 if defined($removals_full{$p});
- $forcermpkgs{$p} = 1 if defined($forcermpkgs_full{$p});
- $newpkgs{$p} = 1 if defined($newpkgs_full{$p});
- }
- debug ("$prg: new pkgs: " . join("\n\t",keys %newpkgs) . "\n");
- debug ("$prg: deleted : " . join("\n\t",keys %removals) . "\n");
- debug ("$prg: forced : " . join("\n\t",keys %forcermpkgs) . "\n");
-
- return (\%removals, \%newpkgs, \%forcermpkgs, \%new_pkgs_due_forcerm_coll);
-}
-
-# tlmgr update foo
-# if foo is of type Package|Documentation it will update only foo
-# and the respective .ARCH dependencies
-# if foo is of type Collection|Scheme it will update itself AND
-# will check all depending packs of type NOT(Collection|Scheme)
-# for necessary updates
-#
-# tlmgr update --no-depends foo
-# as above, but will not check for depends of Collections/Schemes
-# but it will still update .ARCH deps
-#
-# tlmgr update --no-depends-at-all foo
-# will absolutely only update foo not even taking .ARCH into account
-#
-# TLPDB->install_package INSTALLS ONLY ONE PACKAGE, no deps whatsoever
-# anymore. That has all to be done by hand.
-#
-sub machine_line {
- my ($flag1) = @_;
- my $ret = 0;
- if ($flag1 eq "-ret") {
- $ret = 1;
- shift;
- }
- my ($pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag, $lcv, $rcv) = @_;
- $lrev ||= "-";
- $rrev ||= "-";
- $flag ||= "?";
- $size ||= "-";
- $runtime ||= "-";
- $esttot ||= "-";
- $tag ||= "-";
- $lcv ||= "-";
- $rcv ||= "-";
- my $str = join("\t", $pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag, $lcv, $rcv);
- $str .= "\n";
- return($str) if $ret;
- print $str;
-}
-
-sub upd_info {
- my ($pkg, $kb, $lrev, $mrev, $txt) = @_;
- my $flen = 25;
- my $kbstr = ($kb >= 0 ? " [${kb}k]" : "");
- my $kbstrlen = length($kbstr);
- my $pkglen = length($pkg);
- my $is = sprintf("%-9s ", "$txt:");
- if ($pkglen + $kbstrlen > $flen) {
- $is .= "$pkg$kbstr: ";
- } else {
- $is .= sprintf ('%*2$s', $pkg, -($flen-$kbstrlen));
- $is .= "$kbstr: ";
- }
- $is .= sprintf("local: %8s, source: %8s",
- $lrev, $mrev);
- info("$is\n");
-}
-
-sub action_update {
- init_local_db(1);
- $opts{"no-depends"} = 1 if $opts{"no-depends-at-all"};
-
- # make a quick check on command line arguments to avoid loading
- # the remote db uselessly.
- # we require:
- # if no --list is given: either --self or --all or <pkgs>
- # if --list is given: nothing
- # other options just change the behavior
- if (!($opts{"list"} || @ARGV || $opts{"all"} || $opts{"self"})) {
- if ($opts{"dry-run"}) {
- $opts{"list"} = 1; # update -n same as update -n --list
- } else {
- tlwarn("$prg update: specify --list, --all, --self, or a list of package names.\n");
- return ($F_ERROR);
- }
- }
-
- init_tlmedia_or_die();
- info("$prg update: dry run, no changes will be made\n") if $opts{"dry-run"};
-
- my @excluded_pkgs = ();
- if ($opts{"exclude"}) {
- @excluded_pkgs = @{$opts{"exclude"}};
- } elsif ($config{'update-exclude'}) {
- @excluded_pkgs = @{$config{'update-exclude'}};
- }
-
- if (!$opts{"list"}) {
- return ($F_ERROR) if !check_on_writable();
- }
-
- # check for updates to tlmgr and die unless either --force or --list or --self
- # is given
- my @critical;
- if (!$opts{"usermode"}) {
- @critical = check_for_critical_updates($localtlpdb, $remotetlpdb);
- }
- my $dry_run_cont = $opts{"dry-run"} && ($opts{"dry-run"} < 0);
- if ( !$dry_run_cont && !$opts{"self"} && @critical) {
- critical_updates_warning() if (!$::machinereadable);
- if ($opts{"force"}) {
- tlwarn("$prg: Continuing due to --force.\n");
- } elsif ($opts{"list"}) {
- # do not warn here
- } else {
- return($F_ERROR);
- }
- }
-
- my ($ret, $autobackup) = setup_backup_directory();
- return ($ret) if ($ret != $F_OK);
-
- # these two variables are used throughout this function
- my $root = $localtlpdb->root;
- my $temp = TeXLive::TLUtils::tl_tmpdir();
-
- # remove old _BACKUP packages that have piled up in temp
- # they can be recognized by their name starting with __BACKUP_
- for my $f (<$temp/__BACKUP_*>) {
- unlink($f) unless $opts{"dry-run"};
- }
-
-
- my @todo;
- if ($opts{"list"}) {
- if ($opts{"all"}) {
- @todo = $localtlpdb->list_packages;
- } elsif ($opts{"self"}) {
- @todo = @critical;
- } else {
- if (@ARGV) {
- @todo = @ARGV;
- } else {
- @todo = $localtlpdb->list_packages;
- }
- }
- } elsif ($opts{"self"} && @critical) {
- @todo = @critical;
- } elsif ($opts{"all"}) {
- @todo = $localtlpdb->list_packages;
- } else {
- @todo = @ARGV;
- }
- if ($opts{"self"} && !@critical) {
- info("$prg: no self-updates for tlmgr available\n");
- }
- # don't do anything if we have been invoked in a strange way
- if (!@todo && !$opts{"self"}) {
- tlwarn("$prg update: please specify a list of packages, --all, or --self.\n");
- return ($F_ERROR);
- }
-
- if (!($opts{"self"} && @critical) || ($opts{"self"} && $opts{"list"})) {
- # update all .ARCH dependencies, too, unless $opts{"no-depends-at-all"}:
- @todo = $remotetlpdb->expand_dependencies("-only-arch", $localtlpdb, @todo)
- unless $opts{"no-depends-at-all"};
- #
- # update general deps unless $opts{"no-depends"}:
- @todo = $remotetlpdb->expand_dependencies("-no-collections",$localtlpdb,@todo)
- unless $opts{"no-depends"};
- #
- # filter out critical packages
- @todo = grep (!m/$CriticalPackagesRegexp/, @todo)
- unless $opts{"list"};
- }
-
- my ($remref, $newref, $forref, $new_due_to_forcerm_coll_ref) =
- auto_remove_install_force_packages(@todo);
- my %removals = %$remref;
- my %forcermpkgs = %$forref;
- my %newpkgs = %$newref;
- my %new_due_to_forcerm_coll = %$new_due_to_forcerm_coll_ref;
-
- # check that the --exclude options do not conflict with the
- # options --no-auto-remove, --no-auto-install, --reinstall-forcibly-removed
- my @option_conflict_lines = ();
- my $in_conflict = 0;
- if (!$opts{"no-auto-remove"} && $config{"auto-remove"}) {
- for my $pkg (keys %removals) {
- for my $ep (@excluded_pkgs) {
- if ($pkg eq $ep || $pkg =~ m/^$ep\./) {
- push @option_conflict_lines, "$pkg: excluded but scheduled for auto-removal\n";
- $in_conflict = 1;
- last; # of the --exclude for loop
- }
- }
- }
- }
- if (!$opts{"no-auto-install"}) {
- for my $pkg (keys %newpkgs) {
- for my $ep (@excluded_pkgs) {
- if ($pkg eq $ep || $pkg =~ m/^$ep\./) {
- push @option_conflict_lines, "$pkg: excluded but scheduled for auto-install\n";
- $in_conflict = 1;
- last; # of the --exclude for loop
- }
- }
- }
- }
- if ($opts{"reinstall-forcibly-removed"}) {
- for my $pkg (keys %forcermpkgs) {
- for my $ep (@excluded_pkgs) {
- if ($pkg eq $ep || $pkg =~ m/^$ep\./) {
- push @option_conflict_lines, "$pkg: excluded but scheduled for reinstall\n";
- $in_conflict = 1;
- last; # of the --exclude for loop
- }
- }
- }
- }
- if ($in_conflict) {
- tlwarn("$prg: Conflicts have been found:\n");
- for (@option_conflict_lines) { tlwarn(" $_"); }
- tlwarn("$prg: Please resolve these conflicts!\n");
- return ($F_ERROR);
- }
-
- #
- # we first collect the list of packages to be actually updated or installed
- my %updated;
- my @new;
- my @addlines;
-
- TODO: foreach my $pkg (sort @todo) {
- next if ($pkg =~ m/^00texlive/);
- for my $ep (@excluded_pkgs) {
- if ($pkg eq $ep || $pkg =~ m/^$ep\./) {
- info("$prg: skipping excluded package: $pkg\n");
- next TODO;
- }
- }
- my $tlp = $localtlpdb->get_package($pkg);
- if (!defined($tlp)) {
- # if the user has forcibly removed (say) bin-makeindex, then the
- # loop above has no way to add bin-makeindex.ARCH into the
- # %forcermpkgs hash, but the .ARCH will still be in the dependency
- # expansion. So try both with and without the .ARCH extension.
- (my $pkg_noarch = $pkg) =~ s/\.[^.]*$//;
- my $forcerm_coll = $forcermpkgs{$pkg} || $forcermpkgs{$pkg_noarch};
-
- # similarly for new packages. If latexmk is new, latexmk.ARCH
- # will be in the dependency expansion, and we want it.
- my $newpkg_coll = $newpkgs{$pkg} || $newpkgs{$pkg_noarch};
- if ($forcerm_coll) {
- if ($::machinereadable) {
- # TODO should we add a revision number
- push @addlines,
- # $pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag, $lcv, $rcv
- machine_line("-ret", $pkg, $FLAG_FORCIBLE_REMOVED);
- } else {
- info("$prg: skipping forcibly removed package: $pkg\n");
- }
- next;
- } elsif ($newpkg_coll) {
- # do nothing here, it will be reported below.
- } elsif (defined($removals{$pkg})) {
- # skipping this package, it has been removed due to server removal
- # and has already been removed
- next;
- } elsif (defined($new_due_to_forcerm_coll{$pkg})) {
- debug("$prg: $pkg seems to be contained in a forcibly removed" .
- " collection, not auto-installing it!\n");
- next;
- } else {
- tlwarn("\n$prg: $pkg mentioned, but neither new nor forcibly removed");
- tlwarn("\n$prg: perhaps try tlmgr search or tlmgr info.\n");
- next;
- }
- # install new packages
- my $mediatlp = $remotetlpdb->get_package($pkg);
- if (!defined($mediatlp)) {
- tlwarn("\n$prg: Should not happen: $pkg not found in $location\n");
- $ret |= $F_WARNING;
- next;
- }
- my $mediarev = $mediatlp->revision;
- push @new, $pkg;
- next;
- }
- my $rev = $tlp->revision;
- my $lctanvers = $tlp->cataloguedata->{'version'};
- my $mediatlp;
- my $maxtag;
- if ($remotetlpdb->is_virtual) {
- ($maxtag, undef, $mediatlp, undef) =
- $remotetlpdb->virtual_candidate($pkg);
- } else {
- $mediatlp = $remotetlpdb->get_package($pkg);
- }
- if (!defined($mediatlp)) {
- ddebug("$pkg cannot be found in $location\n");
- next;
- }
- my $rctanvers = $mediatlp->cataloguedata->{'version'};
- my $mediarev = $mediatlp->revision;
- my $mediarevstr = $mediarev;
- my @addargs = ();
- if ($remotetlpdb->is_virtual) {
- push @addargs, $maxtag;
- $mediarevstr .= "\@$maxtag";
- } else {
- push @addargs, undef;
- }
- push @addargs, $lctanvers, $rctanvers;
- if ($rev < $mediarev) {
- $updated{$pkg} = 0; # will be changed to one on successful update
- } elsif ($rev > $mediarev) {
- if ($::machinereadable) {
- # $pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag, $lcv, $rcv
- push @addlines,
- machine_line("-ret", $pkg, $FLAG_REVERSED_UPDATE, $rev, $mediarev, "-", "-", "-", @addargs);
- } else {
- if ($opts{"list"}) {
- # not issuing anything if we keep a package
- upd_info($pkg, -1, $rev, $mediarevstr, "keep");
- }
- }
- }
- }
- my @updated = sort keys %updated;
- for my $i (sort @new) {
- debug("$i new package\n");
- }
- for my $i (@updated) {
- debug("$i upd package\n");
- }
-
- # number calculation
- # without w32 special packages, those are dealt with in the updater batch
- # script
- my $totalnr = $#updated + 1;
- my @alltodo = @updated;
- my $nrupdated = 0;
- my $currnr = 1;
-
- # we have to remove all the stuff before we install other packages
- # to support moving of files from one package to another.
- # remove the packages that have disappeared:
- # we add that only to the list of total packages do be worked on
- # when --all is given, because we remove packages only on --all
- if (!$opts{"no-auto-remove"} && $config{"auto-remove"}) {
- my @foo = keys %removals;
- $totalnr += $#foo + 1;
- }
- if (!$opts{"no-auto-install"}) {
- $totalnr += $#new + 1;
- push @alltodo, @new;
- }
-
- # sizes_of_packages returns the sizes of *all* packages if nothing
- # is passed over, so if @new and @updated both are empty we will
- # get something wrong back, namely the total size of all packages
- # the third argument is undef to compute *all* platforms
- my %sizes;
- if (@alltodo) {
- %sizes = %{$remotetlpdb->sizes_of_packages(
- $localtlpdb->option("install_srcfiles"),
- $localtlpdb->option("install_docfiles"), undef, @alltodo)};
- } else {
- $sizes{'__TOTAL__'} = 0;
- }
-
- print "total-bytes\t$sizes{'__TOTAL__'}\n" if $::machinereadable;
- print "end-of-header\n" if $::machinereadable;
-
- # print deferred machine-readable lines after the header
- for (@addlines) { print; }
-
- #
- # compute the list of moved files from %removals, @new, @updated
- #
- my %do_warn_on_move;
- {
- # keep all these vars local to this block
- my @removals = keys %removals;
- my %old_files_to_pkgs;
- my %new_files_to_pkgs;
- # first save for each file in the currently installed packages
- # to be updated the packages it is contained it (might be more!)
- #
- # TODO WHY WHY is there the next so that all the file move checks
- # are actually disabled?!?!?!
- for my $p (@updated, @removals) {
- my $pkg = $localtlpdb->get_package($p);
- tlwarn("$prg: Should not happen: $p not found in local tlpdb\n") if (!$pkg);
- next;
- for my $f ($pkg->all_files) {
- push @{$old_files_to_pkgs{$f}}, $p;
- }
- }
- for my $p (@updated, @new) {
- my $pkg = $remotetlpdb->get_package($p);
- tlwarn("$prg: Should not happen: $p not found in $location\n") if (!$pkg);
- next;
- for my $f ($pkg->all_files) {
- if ($pkg->relocated) {
- $f =~ s:^$RelocPrefix/:$RelocTree/:;
- }
- push @{$new_files_to_pkgs{$f}}, $p;
- }
- }
- #
- # the idea of suppressing warnings is simply that if a file is present
- # in more than one package either in the beginning or after a full
- # update then this should give a warning. In all other cases
- # the warning should be suppressed.
- for my $f (keys %old_files_to_pkgs) {
- my @a = @{$old_files_to_pkgs{$f}};
- $do_warn_on_move{$f} = 1 if ($#a > 0)
- }
- for my $f (keys %new_files_to_pkgs) {
- my @a = @{$new_files_to_pkgs{$f}};
- $do_warn_on_move{$f} = 1 if ($#a > 0)
- }
- }
-
- # parameters for field width
- my $totalnrdigits = length("$totalnr");
-
- #
- # ORDER OF PACKAGE ACTIONS
- # 1. removals
- # 2. updates
- # 3. auto-install
- # that way if a file has been moved from one to another package it
- # removing the old version after the new package has been installed
- # will not give a warning about files being included somewhere else
- #
-
- #
- # REMOVALS
- #
- for my $p (keys %removals) {
- if ($opts{"no-auto-remove"} || !$config{"auto-remove"}) {
- info("not removing $p due to -no-auto-remove or config file option (removed on server)\n");
- } else {
- &ddebug("removing package $p\n");
- my $pkg = $localtlpdb->get_package($p);
- if (! $pkg) {
- # This happened when a collection was removed by the user,
- # and then renamed on the server, e.g., collection-langarab ->
- # collection-langarabic; Luecking report 20 July 2009.
- &ddebug(" get_package($p) failed, ignoring");
- next;
- }
- my $rev = $pkg->revision;
- my $lctanvers = $pkg->cataloguedata->{'version'};
- if ($opts{"list"}) {
- if ($::machinereadable) {
- # $pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag, $lcv, $rcv
- machine_line($p, $FLAG_REMOVE, $rev, "-", "-", "-", "-", "-", $lctanvers);
- } else {
- upd_info($p, -1, $rev, "<absent>", "autorm");
- }
- $currnr++;
- } else {
- # new we are sure that:
- # - $opts{"no-auto-remove"} is *not* set
- # - $opts{"list"} is *not* set
- # we have to check in addition that
- # - $opts{"dry-run"} is not set
- if ($::machinereadable) {
- # $pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag, $lcv, $rcv
- machine_line($p, $FLAG_REMOVE, $rev, "-", "-", "-", "-", "-", $lctanvers);
- } else {
- info("[" . sprintf ('%*2$s', $currnr, $totalnrdigits) .
- "/$totalnr] auto-remove: $p ... ");
- }
- if (!$opts{"dry-run"}) {
- # older tlmgr forgot to clear the relocated bit when saving a tlpobj
- # into the local tlpdb, although the paths were rewritten.
- # We have to clear this bit otherwise the make_container calls below
- # for creating the backup will create some rubbish!
- # Same as further down in the update part!
- if ($pkg->relocated) {
- debug("$prg: warn, relocated bit set for $p, but that is wrong!\n");
- $pkg->relocated(0);
- }
- # TODO we do not check return value here!
- backup_and_remove_package($p, $autobackup);
- logpackage("remove: $p");
- }
- info("done\n") unless $::machinereadable;
- $currnr++;
- }
- }
- }
-
-
- my $starttime = time();
- my $donesize = 0;
- my $totalsize = $sizes{'__TOTAL__'};
-
-
- #
- # UPDATES AND NEW PACKAGES
- #
- # order:
- # - update normal packages
- # - install new normal packages
- # - update collections
- # - install new collections
- # - update schemes
- # - install new schemes (? will not happen?)
- #
- # this makes sure that only if all depending packages are installed
- # the collection is updated, which in turn makes sure that
- # if the installation of a new package does break it will not be
- # counted as forcibly removed later on.
- #
- my @inst_packs;
- my @inst_colls;
- my @inst_schemes;
- for my $pkg (@updated) {
- # we do name checking here, not to load all tlpobj again and again
- if ($pkg =~ m/^scheme-/) {
- push @inst_schemes, $pkg;
- } elsif ($pkg =~ m/^collection-/) {
- push @inst_colls, $pkg;
- } else {
- push @inst_packs, $pkg;
- }
- }
- @inst_packs = sort packagecmp @inst_packs;
-
- my @new_packs;
- my @new_colls;
- my @new_schemes;
- for my $pkg (sort @new) {
- # we do name checking here, not to load all tlpobj again and again
- if ($pkg =~ m/^scheme-/) {
- push @new_schemes, $pkg;
- } elsif ($pkg =~ m/^collection-/) {
- push @new_colls, $pkg;
- } else {
- push @new_packs, $pkg;
- }
- }
- @new_packs = sort packagecmp @new_packs;
- my %is_new;
- for my $pkg (@new_packs, @new_colls, @new_schemes) {
- $is_new{$pkg} = 1;
- }
-
- #
- # TODO idea
- # currently this big loop contains a long if then for new packages
- # and updated package. That *could* be merged into one so that
- # some things like the logging has not been written two times.
- # OTOH, the control flow in the "new package" part is much simpler
- # and following it after the change would make it much harder
- #
- foreach my $pkg (@inst_packs, @new_packs, @inst_colls, @new_colls, @inst_schemes, @new_schemes) {
-
- if (!$is_new{$pkg}) {
- # skip this loop if infra update on w32
- next if ($pkg =~ m/^00texlive/);
- my $tlp = $localtlpdb->get_package($pkg);
- # we checked already that this package is present!
- # but our checks seem to be wrong, no idea why
- # ahhh, it seems that it can happen due to a stupid incident, a bug
- # on the server:
- # - remove a package from a collection
- # - at the same time increase its version number
- # then what happens is:
- # - first the package is removed (auto-remove!)
- # - then it is tried to be updated here, which is not working!
- # report that and ask for report
- if (!defined($tlp)) {
- my %servers = repository_to_array($location);
- my $servers = join("\n ", values(%servers));
- tlwarn("$prg: inconsistency on (one of) the server(s): $servers\n");
- tlwarn("$prg: tlp for package $pkg cannot be found, please report.\n");
- $ret |= $F_WARNING;
- next;
- }
- my $unwind_package;
- my $remove_unwind_container = 0;
- my $rev = $tlp->revision;
- my $lctanvers = $tlp->cataloguedata->{'version'};
- my $mediatlp;
- my $maxtag;
- if ($remotetlpdb->is_virtual) {
- ($maxtag, undef, $mediatlp, undef) =
- $remotetlpdb->virtual_candidate($pkg);
- } else {
- $mediatlp = $remotetlpdb->get_package($pkg);
- }
- if (!defined($mediatlp)) {
- debug("$pkg cannot be found in $location\n");
- next;
- }
- my $rctanvers = $mediatlp->cataloguedata->{'version'};
- my $mediarev = $mediatlp->revision;
- my $mediarevstr = $mediarev;
- my @addargs = ();
- if ($remotetlpdb->is_virtual) {
- push @addargs, $maxtag;
- $mediarevstr .= "\@$maxtag";
- } else {
- push @addargs, undef;
- }
- push @addargs, $lctanvers, $rctanvers;
- $nrupdated++;
- if ($opts{"list"}) {
- if ($::machinereadable) {
- # $pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag, $lcv, $rcv
- machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, "-", "-", @addargs);
- } else {
- my $kb = int($sizes{$pkg} / 1024) + 1;
- upd_info($pkg, $kb, $rev, $mediarevstr, "update");
- if ($remotetlpdb->is_virtual) {
- my @cand = $remotetlpdb->candidates($pkg);
- shift @cand; # remove the top element
- if (@cand) {
- print "\tother candidates: ";
- for my $a (@cand) {
- my ($t,$r) = split(/\//, $a, 2);
- print $r . '@' . $t . " ";
- }
- print "\n";
- }
- }
- }
- $updated{$pkg} = 1;
- next;
- } elsif (win32() && ($pkg =~ m/$CriticalPackagesRegexp/)) {
- # we pretend that the update happened
- # in order to calculate file changes properly
- $updated{$pkg} = 1;
- next;
- }
-
- # older tlmgr forgot to clear the relocated bit when saving a tlpobj
- # into the local tlpdb, although the paths were rewritten.
- # We have to clear this bit otherwise the make_container calls below
- # for creating an unwind container will create some rubbish
- # TODO for user mode we should NOT clear this bit!
- if ($tlp->relocated) {
- debug("$prg: warn, relocated bit set for $pkg, but that is wrong!\n");
- $tlp->relocated(0);
- }
-
- if ($opts{"backup"} && !$opts{"dry-run"}) {
- my $compressorextension = $Compressors{$::progs{'compressor'}}{'extension'};
- $tlp->make_container($::progs{'compressor'}, $root,
- destdir => $opts{"backupdir"},
- relative => $tlp->relocated,
- user => 1);
- $unwind_package =
- "$opts{'backupdir'}/${pkg}.r" . $tlp->revision . ".tar.$compressorextension";
-
- if ($autobackup) {
- # in case we do auto backups we remove older backups
- clear_old_backups($pkg, $opts{"backupdir"}, $autobackup);
- }
- }
-
- my ($estrem, $esttot);
- if (!$opts{"list"}) {
- ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
- $donesize, $starttime);
- }
-
- if ($::machinereadable) {
- machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, $estrem, $esttot, @addargs);
- } else {
- my $kb = int ($sizes{$pkg} / 1024) + 1;
- info("[" . sprintf ('%*2$s', $currnr, $totalnrdigits) .
- "/$totalnr, $estrem/$esttot] update: $pkg [${kb}k] ($rev -> $mediarevstr)");
- }
- $donesize += $sizes{$pkg};
- $currnr++;
-
- if ($opts{"dry-run"}) {
- info("\n") unless $::machinereadable;
- $updated{$pkg} = 1;
- next;
- } else {
- info(" ... ") unless $::machinereadable; # more to come
- }
-
- if (!$unwind_package) {
- # no backup was made, so let us create a temporary .tar file
- # of the package
- my $tlp = $localtlpdb->get_package($pkg);
- my ($s, undef, $fullname) = $tlp->make_container("tar", $root,
- destdir => $temp,
- containername => "__BACKUP_${pkg}",
- relative => $tlp->relocated,
- user => 1);
- if ($s <= 0) {
- tlwarn("\n$prg: creation of backup container failed for: $pkg\n");
- tlwarn("$prg: continuing to update other packages, please retry...\n");
- $ret |= $F_WARNING;
- # we should try to update other packages at least
- next;
- }
- $remove_unwind_container = 1;
- $unwind_package = "$fullname";
- }
- # first remove the package, then reinstall it
- # this way we get rid of useless files
- # force the deinstallation since we will reinstall it
- #
- # the remove_package should also remove empty dirs in case
- # a dir is changed into a file
- if ($pkg =~ m/$CriticalPackagesRegexp/) {
- debug("Not removing critical package $pkg\n");
- } else {
- $localtlpdb->remove_package($pkg,
- "remove-warn-files" => \%do_warn_on_move);
- }
- if ($remotetlpdb->install_package($pkg, $localtlpdb)) {
- # installation succeeded because we got a reference
- logpackage("update: $pkg ($rev -> $mediarevstr)");
- unlink($unwind_package) if $remove_unwind_container;
- # remember successful update
- $updated{$pkg} = 1;
- #
- # if we updated a .ARCH package we have to announce the postactions
- # of the parent package so that formats are rebuild
- if ($pkg =~ m/^([^.]*)\./) {
- my $parent = $1;
- if (!TeXLive::TLUtils::member($parent, @inst_packs, @new_packs, @inst_colls, @new_colls, @inst_schemes, @new_schemes)) {
- # ok, nothing happens with the parent package, so we have to
- # find it and execute the postactions
- my $parentobj = $localtlpdb->get_package($parent);
- if (!defined($parentobj)) {
- # well, in this case we might have hit a package that only
- # has .ARCH package, like psv.win32, so do nothing
- debug("$prg: .ARCH package without parent, not announcing postaction\n");
- } else {
- debug("$prg: announcing parent execute action for $pkg\n");
- TeXLive::TLUtils::announce_execute_actions("enable", $parentobj);
- }
- }
- }
- } else {
- # install_package returned a scalar, so error.
- # now in fact we should do some cleanup, removing files and
- # dirs from the new package before re-installing the old one.
- # TODO
- logpackage("failed update: $pkg ($rev -> $mediarevstr)");
- tlwarn("$prg: Installation of new version of $pkg failed, trying to unwind.\n");
- if (win32()) {
- # w32 is notorious for not releasing a file immediately
- # we experienced permission denied errors
- my $newname = $unwind_package;
- $newname =~ s/__BACKUP/___BACKUP/;
- copy ("-f", $unwind_package, $newname);
- # try to remove the file if has been created by us
- unlink($unwind_package) if $remove_unwind_container;
- # and make sure that the temporary file is removed in any case
- $remove_unwind_container = 1;
- $unwind_package = $newname;
- }
-
- # the -1 force the TLUtils::unpack to NOT warn about missing checksum/sizes
- my ($instret, $msg) = TeXLive::TLUtils::unpack("$unwind_package",
- $localtlpdb->root, checksum => "-1", checksize => "-1");
- if ($instret) {
- # now we have to include the tlpobj
- my $tlpobj = TeXLive::TLPOBJ->new;
- $tlpobj->from_file($root . "/tlpkg/tlpobj/$pkg.tlpobj");
- $localtlpdb->add_tlpobj($tlpobj);
- $localtlpdb->save;
- logpackage("restore: $pkg ($rev)");
- $ret |= $F_WARNING;
- tlwarn("$prg: Restoring old package state succeeded.\n");
- } else {
- logpackage("failed restore: $pkg ($rev)");
- tlwarn("$prg: Restoring of old package did NOT succeed.\n");
- tlwarn("$prg: Error message from unpack: $msg\n");
- tlwarn("$prg: Most likely repair: run tlmgr install $pkg and hope.\n");
- # TODO_ERRORCHECKING
- # should we return F_ERROR here??? If we would do this, then
- # no postactions at all would run? Maybe better only to give
- # a warning
- $ret |= $F_WARNING;
- }
- unlink($unwind_package) if $remove_unwind_container;
- }
- info("done\n") unless $::machinereadable;
- } else { # $is_new{$pkg} is true!!!
- #
- # NEW PACKAGES
- #
- if ($opts{"no-auto-install"}) {
- info("not auto-installing $pkg due to -no-auto-install (new on server)\n")
- unless $::machinereadable;
- } else {
- # install new packages
- my $mediatlp;
- my $maxtag;
- if ($remotetlpdb->is_virtual) {
- ($maxtag, undef, $mediatlp, undef) =
- $remotetlpdb->virtual_candidate($pkg);
- } else {
- $mediatlp = $remotetlpdb->get_package($pkg);
- }
- if (!defined($mediatlp)) {
- tlwarn("\n$prg: Should not happen: $pkg not found in $location\n");
- $ret |= $F_WARNING;
- next;
- }
- my $mediarev = $mediatlp->revision;
- my $mediarevstr = $mediarev;
- my @addargs;
- if ($remotetlpdb->is_virtual) {
- $mediarevstr .= "\@$maxtag";
- push @addargs, $maxtag;
- }
- my ($estrem, $esttot);
- if (!$opts{"list"}) {
- ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
- $donesize, $starttime);
- }
- if ($::machinereadable) {
- my @maargs = ($pkg, $FLAG_AUTOINSTALL, "-", $mediatlp->revision, $sizes{$pkg});
- if (!$opts{"list"}) {
- push @maargs, $estrem, $esttot;
- } else {
- push @maargs, undef, undef;
- }
- machine_line(@maargs, @addargs);
- } else {
- my $kb = int($sizes{$pkg} / 1024) + 1;
- if ($opts{"list"}) {
- upd_info($pkg, $kb, "<absent>", $mediarevstr, "autoinst");
- } else {
- info("[" . sprintf ('%*2$s', $currnr, $totalnrdigits) .
- "/$totalnr, $estrem/$esttot] auto-install: $pkg ($mediarevstr) [${kb}k] ... ");
- }
- }
- $currnr++;
- $donesize += $sizes{$pkg};
- next if ($opts{"dry-run"} || $opts{"list"});
- if ($remotetlpdb->install_package($pkg, $localtlpdb)) {
- # installation succeeded because we got a reference
- logpackage("auto-install new: $pkg ($mediarevstr)");
- $nrupdated++;
- info("done\n") unless $::machinereadable;
- } else {
- tlwarn("$prg: couldn't install new package $pkg\n");
- }
- }
- }
- }
-
- #
- # special check for depending format updates:
- # if one of latex or tex has been updated, we rebuild the formats
- # defined in packages *depending* on these packages.
- check_announce_format_triggers(@inst_packs, @new_packs)
- if (!$opts{"list"});
-
- print "end-of-updates\n" if $::machinereadable;
-
- #
- # check that if updates to the critical packages are present all of
- # them have been successfully updated
- my $infra_update_done = 1;
- my @infra_files_to_be_removed;
- if ($opts{"list"}) {
- $infra_update_done = 0;
- } else {
- for my $pkg (@critical) {
- next unless (defined($updated{$pkg}));
- $infra_update_done &&= $updated{$pkg};
- my $oldtlp;
- my $newtlp;
- if ($updated{$pkg}) {
- $oldtlp = $localtlpdb->get_package($pkg);
- $newtlp = $remotetlpdb->get_package($pkg);
- } else {
- # update failed but we could introduce new files, that
- # should be removed now as a part of restoring backup
- $oldtlp = $remotetlpdb->get_package($pkg);
- $newtlp = $localtlpdb->get_package($pkg);
- }
- die ("That shouldn't happen: $pkg not found in tlpdb") if !defined($newtlp);
- die ("That shouldn't happen: $pkg not found in tlpdb") if !defined($oldtlp);
- my @old_infra_files = $oldtlp->all_files;
- my @new_infra_files = $newtlp->all_files;
- my %del_files;
- @del_files{@old_infra_files} = ();
- delete @del_files{@new_infra_files};
- for my $k (keys %del_files) {
- my @found_pkgs = $localtlpdb->find_file($k);
- if ($#found_pkgs >= 0) {
- my $bad_file = 1;
- if (win32()) {
- # on w32 the packages have not been removed already,
- # so we check that the only package listed in @found_pkgs
- # is the one we are working on ($pkg)
- if ($#found_pkgs == 0 && $found_pkgs[0] =~ m/^$pkg:/) {
- # only one package has been returned and it
- # matches the current package followed by a colon
- # remember the TLPDB->find_file returns
- # $pkg:$file
- # in this case we can ignore it
- $bad_file = 0;
- }
- }
- if ($bad_file) {
- tlwarn("$prg: The file $k has disappeared from the critical" .
- " package $pkg but is still present in @found_pkgs\n");
- $ret |= $F_WARNING;
- } else {
- push @infra_files_to_be_removed, $k;
- }
- } else {
- push @infra_files_to_be_removed, $k;
- }
- }
- }
-
- if (!win32()) {
- for my $f (@infra_files_to_be_removed) {
- # TODO actually unlink the stuff
- #unlink("$Master/$f");
- debug("removing disappearing file $f\n");
- }
- }
- } # end of if ($opts{"list"}) ... else part
-
- # check if any additional updates are asked for
- my $other_updates_asked_for = 0;
- if ($opts{"all"}) {
- $other_updates_asked_for = 1;
- } else {
- foreach my $p (@ARGV) {
- if ($p !~ m/$CriticalPackagesRegexp/) {
- $other_updates_asked_for = 1;
- last;
- }
- }
- }
-
- my $restart_tlmgr = 0;
- if ($opts{"self"} && @critical && !$opts{'no-restart'} &&
- $infra_update_done && $other_updates_asked_for) {
- # weed out the --self argument from the saved arguments
- @::SAVEDARGV = grep (!m/^-?-self$/, @::SAVEDARGV);
- $restart_tlmgr = 1;
- }
-
- # infra update and tlmgr restart on w32 is done by the updater batch script
- if (win32() && $opts{'self'} && !$opts{"list"} && @critical) {
- info("$prg: Preparing TeX Live infrastructure update...\n");
- for my $f (@infra_files_to_be_removed) {
- debug("file scheduled for removal $f\n");
- }
- my $ret = write_w32_updater($restart_tlmgr,
- \@infra_files_to_be_removed, @critical);
- if ($ret) {
- tlwarn ("$prg: Aborting infrastructure update.\n");
- $ret |= $F_ERROR;
- $restart_tlmgr = 0 if ($opts{"dry-run"});
- }
- }
-
- # only when we are not dry-running we restart the program
- if (!win32() && $restart_tlmgr && !$opts{"dry-run"} && !$opts{"list"}) {
- info("$prg: Restarting to complete update ...\n");
- debug("restarting tlmgr @::SAVEDARGV\n");
- # cleanup temp files before re-exec-ing tlmgr
- File::Temp::cleanup();
- exec("tlmgr", @::SAVEDARGV);
- # we need warn here, otherwise perl gives warnings!
- warn("$prg: cannot restart tlmgr, please retry update\n");
- return($F_ERROR);
- }
-
- # for --dry-run we cannot restart tlmgr (no way to fake successful
- # infra update) instead we call action_update() again and signal this
- # by $opts{"dry-run"} = -1
- if ($opts{"dry-run"} && !$opts{"list"} && $restart_tlmgr) {
- $opts{"self"} = 0;
- $opts{"dry-run"} = -1;
- $localtlpdb = undef;
- $remotetlpdb = undef;
- info ("$prg --dry-run: would restart tlmgr to complete update ...\n");
- $ret |= action_update();
- return ($ret);
- }
-
- # if a real update from default disk location didn't find anything,
- # warn if nothing is updated. Unless they said --self, in which case
- # we've already reported it.
- # But if --self --all was given, and *no* update available for
- # critical packages, then we should report it, too!
- if (!(@new || @updated) && ( !$opts{"self"} || @todo )) {
- if (!$::machinereadable) {
- info("$prg: no updates available\n");
- if ($remotetlpdb->media ne "NET"
- && $remotetlpdb->media ne "virtual"
- && !$opts{"dry-run"}
- && !$opts{"repository"}
- && !$ENV{"TEXLIVE_INSTALL_ENV_NOCHECK"}
- ) {
- tlwarn(<<END_DISK_WARN);
-$prg: Your installation is set up to look on the disk for updates.
-To install from the Internet for this one time only, run:
- tlmgr -repository $TeXLiveURL ACTION ARG...
-where ACTION is install, update, etc.; see tlmgr -help if needed.
-
-To change the default for all future updates, run:
- tlmgr option repository $TeXLiveURL
-END_DISK_WARN
- }
- }
- }
- return ($ret);
-}
-
-
-sub check_announce_format_triggers {
- # we treat new and updated packages the same as updated
- # when it comes to triggers
- my %updpacks = map { $_ => 1 } @_;
-
- # search all format definitions in the tlpdb
- FMTDEF: for my $fmtdef ($localtlpdb->format_definitions) {
- # if by default they are activated, check the whether the
- # trigger packages appear in the list of updated/new packages
- if (($fmtdef->{'mode'} == 1) && $fmtdef->{'fmttriggers'}) {
- for my $trigger (@{$fmtdef->{'fmttriggers'}}) {
- if ($updpacks{$trigger}) {
- TeXLive::TLUtils::announce_execute_actions("rebuild-format",
- 0, $fmtdef);
- next FMTDEF;
- }
- }
- }
- }
-}
-
-# INSTALL
-#
-# tlmgr install foo bar baz
-# will create the closure under dependencies of {foo,bar,baz}, i.e. all
-# dependencies recursively down to the last package, and install all
-# the packages that are necessary
-#
-# tlmgr install --no-depends foo bar baz
-# will *only* install these three packages (if they are not already installed
-# but it will STILL INSTALL foo.ARCH if they are necessary.
-#
-# tlmgr install --no-depends-at-all foo bar baz
-# will absolutely only install these three packages, and will not even
-# take .ARCH deps into account
-#
-# tlmgr install --reinstall ...
-# behaves exactly like without --reinstall BUT the following two
-# differences:
-# . dependencies are not expanded from collection to collection, so
-# if you reinstall a collection then all its dependencies of type
-# Package will be reinstalled, too, but not the dependencies on
-# other collection, because that would force the full reinstallation
-# of the whole installation
-# . it does not care for whether a package seems to be installed or
-# not (that is the --reinstall)
-#
-# TLPDB->install_package does ONLY INSTALL ONE PACKAGE, no deps whatsoever
-# anymore! That has all to be done by the caller.
-#
-sub action_install {
- init_local_db(1);
- my $ret = $F_OK;
- return ($F_ERROR) if !check_on_writable();
-
- # installation from a .tar.xz
- if ($opts{"file"}) {
- if ($localtlpdb->install_package_files(@ARGV)) {
- return ($ret);
- } else {
- return ($F_ERROR);
- }
- }
-
- # if we are still here, we are installing from some repository
- # initialize the TLPDB from $location
- $opts{"no-depends"} = 1 if $opts{"no-depends-at-all"};
- init_tlmedia_or_die();
-
- # check for updates to tlmgr itself, and die unless --force is given
- if (!$opts{"usermode"}) {
- if (check_for_critical_updates( $localtlpdb, $remotetlpdb)) {
- critical_updates_warning() if (!$::machinereadable);
- if ($opts{"force"}) {
- tlwarn("$prg: Continuing due to --force\n");
- } else {
- if ($::gui_mode) {
- # return here and don't do any updates
- return ($F_ERROR);
- } else {
- die "$prg: Terminating; please see warning above!\n";
- }
- }
- }
- }
-
- $opts{"no-depends"} = 1 if $opts{"no-depends-at-all"};
- info("$prg install: dry run, no changes will be made\n") if $opts{"dry-run"};
-
- my @packs = @ARGV;
- # first expand the .ARCH dependencies unless $opts{"no-depends-at-all"}
- @packs = $remotetlpdb->expand_dependencies("-only-arch", $localtlpdb, @ARGV)
- unless $opts{"no-depends-at-all"};
- #
- # if no-depends, we're done; else get rest of deps.
- unless ($opts{"no-depends"}) {
- if ($opts{"reinstall"} || $opts{"usermode"}) {
- # if reinstall or usermode, omit collection->collection deps
- @packs = $remotetlpdb->expand_dependencies("-no-collections",
- $localtlpdb, @packs);
- } else {
- @packs = $remotetlpdb->expand_dependencies($localtlpdb, @packs);
- }
- }
- #
- # expand dependencies returns a list pkg@tag in case of a virtual
- # remote db.
- my %packs;
- for my $p (@packs) {
- my ($pp, $aa) = split('@', $p);
- $packs{$pp} = (defined($aa) ? $aa : 0);
- }
- #
- # installation order of packages:
- # first all normal packages, then collections, then schemes
- # isn't already installed, but the collection already updated, it will
- # be reported as forcibly removed.
- my @inst_packs;
- my @inst_colls;
- my @inst_schemes;
- for my $pkg (sort keys %packs) {
- # we do name checking here, not to load all tlpobj again and again
- if ($pkg =~ m/^scheme-/) {
- push @inst_schemes, $pkg;
- } elsif ($pkg =~ m/^collection-/) {
- push @inst_colls, $pkg;
- } else {
- push @inst_packs, $pkg;
- }
- }
- @inst_packs = sort packagecmp @inst_packs;
-
- my $starttime = time();
- # count packages
- my $totalnr = 0;
- my %revs;
- my @todo;
- for my $pkg (@inst_packs, @inst_colls, @inst_schemes) {
- my $pkgrev = 0;
- # if the package name is asked from a specific repository, use
- # that one, otherwise leave the decision to $remotetlpdb by not
- # giving a final argument
- my $mediatlp = $remotetlpdb->get_package($pkg,
- ($packs{$pkg} ? $packs{$pkg} : undef));
- if (!defined($mediatlp)) {
- tlwarn("$prg install: package $pkg not present in repository.\n");
- $ret |= $F_WARNING;
- next;
- }
- if (defined($localtlpdb->get_package($pkg))) {
- if ($opts{"reinstall"}) {
- $totalnr++;
- $revs{$pkg} = $mediatlp->revision;
- push @todo, $pkg;
- } else {
- # debug msg that we have this one.
- debug("already installed: $pkg\n");
- # if explicitly requested by user (not a dep), tell them.
- info("$prg install: package already present: $pkg\n")
- if grep { $_ eq $pkg } @ARGV;
- }
- } else {
- $totalnr++;
- $revs{$pkg} = $mediatlp->revision;
- push (@todo, $pkg);
- }
- }
- # return if there is nothing to install!
- return ($ret) if (!@todo);
-
- my $orig_do_src = $localtlpdb->option("install_srcfiles");
- my $orig_do_doc = $localtlpdb->option("install_docfiles");
- if (!$opts{"dry-run"}) {
- $localtlpdb->option("install_srcfiles", 1) if $opts{'with-src'};
- $localtlpdb->option("install_docfiles", 1) if $opts{'with-doc'};
- }
-
- my $currnr = 1;
- # undef here is a ref to array of platforms, if undef all are used
- my %sizes = %{$remotetlpdb->sizes_of_packages(
- $localtlpdb->option("install_srcfiles"),
- $localtlpdb->option("install_docfiles"), undef, @todo)};
- defined($sizes{'__TOTAL__'}) || ($sizes{'__TOTAL__'} = 0);
- my $totalsize = $sizes{'__TOTAL__'};
- my $donesize = 0;
-
- print "total-bytes\t$sizes{'__TOTAL__'}\n" if $::machinereadable;
- print "end-of-header\n" if $::machinereadable;
-
- foreach my $pkg (@todo) {
- my $flag = $FLAG_INSTALL;
- my $re = "";
- my $tlp = $remotetlpdb->get_package($pkg);
- my $rctanvers = $tlp->cataloguedata->{'version'};
- if (!defined($tlp)) {
- info("$prg: unknown package: $pkg\n");
- next;
- }
- if (!$tlp->relocated && $opts{"usermode"}) {
- info("$prg: package $pkg is not relocatable, cannot install it in user mode!\n");
- next;
- }
- my $lctanvers;
- if (defined($localtlpdb->get_package($pkg))) {
- my $lctanvers = $localtlpdb->get_package($pkg)->cataloguedata->{'version'};
- if ($opts{"reinstall"}) {
- $re = "re";
- $flag = $FLAG_REINSTALL;
- } else {
- debug("already installed (but didn't we say that already?): $pkg\n");
- next;
- }
- }
- my ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
- $donesize, $starttime);
- my $kb = int($sizes{$pkg} / 1024) + 1;
- my @addargs = ();
- my $tagstr = "";
- if ($remotetlpdb->is_virtual) {
- if ($packs{$pkg} ne "0") {
- push @addargs, $packs{$pkg};
- $tagstr = " \@" . $packs{$pkg};
- } else {
- my ($maxtag,undef,undef,undef) = $remotetlpdb->virtual_candidate($pkg);
- push @addargs, $maxtag;
- $tagstr = " \@" . $maxtag;
- }
- }
- push @addargs, $lctanvers, $rctanvers;
- if ($::machinereadable) {
- machine_line($pkg, $flag, "-", $revs{$pkg}, $sizes{$pkg}, $estrem, $esttot, @addargs);
- } else {
- info("[$currnr/$totalnr, $estrem/$esttot] ${re}install: $pkg$tagstr [${kb}k]\n");
- }
- if (!$opts{"dry-run"}) {
- if ($remotetlpdb->install_package($pkg, $localtlpdb,
- ($packs{$pkg} ? $packs{$pkg} : undef) )) {
- logpackage("${re}install: $pkg$tagstr");
- } else {
- logpackage("failed ${re}install: $pkg$tagstr");
- }
- }
- $donesize += $sizes{$pkg};
- $currnr++;
- }
- print "end-of-updates\n" if $::machinereadable;
-
-
- if ($opts{"dry-run"}) {
- # stop here, don't do any postinstall actions
- return($ret | $F_NOPOSTACTION);
- } else {
- # reset option if --with-src argument was given
- $localtlpdb->option("install_srcfiles", $orig_do_src) if $opts{'with-src'};
- $localtlpdb->option("install_docfiles", $orig_do_doc) if $opts{'with-doc'};
- $localtlpdb->save if ($opts{'with-src'} || $opts{'with-doc'});
- }
- return ($ret);
-}
-
-sub show_one_package {
- my ($pkg, $fmt, @rest) = @_;
- my $ret;
- if ($fmt eq "list") {
- $ret = show_one_package_list($pkg, @rest);
- } elsif ($fmt eq "detail") {
- $ret = show_one_package_detail($pkg, @rest);
- } elsif ($fmt eq "csv") {
- $ret = show_one_package_csv($pkg, @rest);
- } elsif ($fmt eq "json") {
- $ret = show_one_package_json($pkg);
- } else {
- tlwarn("$prg: show_one_package: unknown format: $fmt\n");
- return($F_ERROR);
- }
- return($ret);
-}
-
-sub show_one_package_json {
- my ($p) = @_;
- my @out;
- my $loctlp = $localtlpdb->get_package($p);
- my $remtlp = $remotetlpdb->get_package($p);
- my $is_installed = (defined($loctlp) ? 1 : 0);
- my $is_available = (defined($remtlp) ? 1 : 0);
- if (!($is_installed || $is_available)) {
- # output proper JSON for unavailable packages
- print "{ \"name\":\"$p\", \"available\":false }";
- #tlwarn("$prg: package $p not found neither locally nor remote!\n");
- #return($F_WARNING);
- return($F_OK);
- }
- # prefer local TLPs as they have RELOC replaced by proper paths
- my $tlp = ($is_installed ? $loctlp : $remtlp);
- #my $tlp = ($is_available ? $remtlp : $loctlp);
- # add available, installed, lrev, rrev fields and remove revision field
- my $str = $tlp->as_json(available => ($is_available ? TeXLive::TLUtils::True() : TeXLive::TLUtils::False()),
- installed => ($is_installed ? TeXLive::TLUtils::True() : TeXLive::TLUtils::False()),
- lrev => ($is_installed ? $loctlp->revision : 0),
- rrev => ($is_available ? $remtlp->revision : 0),
- rcataloguedata => ($is_available ? $remtlp->cataloguedata : {}),
- revision => undef);
- print $str;
- return($F_OK);
-}
-
-
-sub show_one_package_csv {
- my ($p, @datafields) = @_;
- my @out;
- my $loctlp = $localtlpdb->get_package($p);
- my $remtlp = $remotetlpdb->get_package($p) unless ($opts{'only-installed'});
- my $is_installed = (defined($loctlp) ? 1 : 0);
- my $is_available = (defined($remtlp) ? 1 : 0);
- if (!($is_installed || $is_available)) {
- if ($opts{'only-installed'}) {
- tlwarn("$prg: package $p not locally!\n");
- } else {
- tlwarn("$prg: package $p not found neither locally nor remote!\n");
- }
- return($F_WARNING);
- }
- my $tlp = ($is_installed ? $loctlp : $remtlp);
- for my $d (@datafields) {
- if ($d eq "name") {
- push @out, $p;
- } elsif ($d eq "category") {
- push @out, $tlp->category || "";
- } elsif ($d eq "shortdesc") {
- my $str = $tlp->shortdesc;
- if (defined $tlp->shortdesc) {
- $str =~ s/"/\\"/g;
- push @out, "\"$str\"";
- } else {
- push @out, "";
- }
- } elsif ($d eq "longdesc") {
- my $str = $tlp->longdesc;
- if (defined $tlp->shortdesc) {
- $str =~ s/"/\\"/g;
- $str =~ s/\n/\\n/g;
- push @out, "\"$str\"";
- } else {
- push @out, "";
- }
- } elsif ($d eq "installed") {
- push @out, $is_installed;
- } elsif ($d eq "relocatable") {
- push @out, ($tlp->relocated ? 1 : 0);
- } elsif ($d eq "cat-version") {
- push @out, ($tlp->cataloguedata->{'version'} || "");
- } elsif ($d eq "lcat-version") {
- push @out, ($is_installed ? ($loctlp->cataloguedata->{'version'} || "") : "");
- } elsif ($d eq "rcat-version") {
- push @out, ($is_available ? ($remtlp->cataloguedata->{'version'} || "") : "");
- } elsif ($d eq "cat-date") {
- push @out, ($tlp->cataloguedata->{'date'} || "");
- } elsif ($d eq "lcat-date") {
- push @out, ($is_installed ? ($loctlp->cataloguedata->{'date'} || "") : "");
- } elsif ($d eq "rcat-date") {
- push @out, ($is_available ? ($remtlp->cataloguedata->{'date'} || "") : "");
- } elsif ($d eq "cat-license") {
- push @out, ($tlp->cataloguedata->{'license'} || "");
- } elsif ($d eq "lcat-license") {
- push @out, ($is_installed ? ($loctlp->cataloguedata->{'license'} || "") : "");
- } elsif ($d eq "rcat-license") {
- push @out, ($is_available ? ($remtlp->cataloguedata->{'license'} || "") : "");
- } elsif ($d =~ m/^cat-(contact-.*)$/) {
- push @out, ($tlp->cataloguedata->{$1} || "");
- } elsif ($d =~ m/^lcat-(contact-.*)$/) {
- push @out, ($is_installed ? ($loctlp->cataloguedata->{$1} || "") : "");
- } elsif ($d =~ m/^rcat-(contact-.*)$/) {
- push @out, ($is_available ? ($remtlp->cataloguedata->{$1} || "") : "");
- } elsif ($d eq "localrev") {
- push @out, ($is_installed ? $loctlp->revision : 0);
- } elsif ($d eq "remoterev") {
- push @out, ($is_available ? $remtlp->revision : 0);
- } elsif ($d eq "depends") {
- push @out, (join(":", $tlp->depends));
- } elsif ($d eq "size") {
- # tlp->*size is in 4k blocks!
- my $srcsize = $tlp->srcsize * $TeXLive::TLConfig::BlockSize;
- my $docsize = $tlp->docsize * $TeXLive::TLConfig::BlockSize;
- my $runsize = $tlp->runsize * $TeXLive::TLConfig::BlockSize;
- my $binsize = 0;
- my $binsizes = $tlp->binsize;
- for my $a (keys %$binsizes) { $binsize += $binsizes->{$a} ; }
- $binsize *= $TeXLive::TLConfig::BlockSize;
- my $totalsize = $srcsize + $docsize + $runsize + $binsize;
- push @out, $totalsize;
- } else {
- tlwarn("$prg: unknown data field $d\n");
- return($F_WARNING);
- }
- }
- print join(",", @out), "\n";
- return($F_OK);
-}
-
-sub show_one_package_list {
- my ($p, @rest) = @_;
- my @out;
- my $loctlp = $localtlpdb->get_package($p);
- my $remtlp = $remotetlpdb->get_package($p) unless ($opts{'only-installed'});
- my $is_installed = (defined($loctlp) ? 1 : 0);
- my $is_available = (defined($remtlp) ? 1 : 0);
- if (!($is_installed || $is_available)) {
- if ($opts{'only-installed'}) {
- tlwarn("$prg: package $p not locally!\n");
- } else {
- tlwarn("$prg: package $p not found neither locally nor remote!\n");
- }
- return($F_WARNING);
- }
- my $tlp = ($is_installed ? $loctlp : $remtlp);
- my $tlm;
- if ($opts{"only-installed"}) {
- $tlm = $localtlpdb;
- } else {
- $tlm = $remotetlpdb;
- }
- if ($is_installed) {
- print "i ";
- } else {
- print " ";
- }
- if (!$tlp) {
- if ($remotetlpdb->is_virtual) {
- # we might have the case that a package is present in a
- # subsidiary repository, but not pinned, so it will
- # not be found by ->get_package
- # In this case we list all repositories shipping it,
- # but warn that it is not pinned and thus not reachable.
- my @cand = $remotetlpdb->candidates($p);
- if (@cand) {
- my $first = shift @cand;
- if (defined($first)) {
- tlwarn("$prg: strange, we have a first candidate but no tlp: $p\n");
- return($F_WARNING);
- }
- # already shifted away the first element
- if ($#cand >= 0) {
- print "$p: --- no installable candidate found, \n";
- print " but present in subsidiary repositories without a pin.\n";
- print " This package is not reachable without pinning.\n";
- print " Repositories containing this package:\n";
- for my $a (@cand) {
- my ($t,$r) = split(/\//, $a, 2);
- my $tlp = $remotetlpdb->get_package($p, $t);
- my $foo = $tlp->shortdesc;
- print " $t: ", defined($foo) ? $foo : "(shortdesc missing)" , "\n";
- }
- return($F_WARNING);
- } else {
- tlwarn("$prg: strange, package listed but no residual candidates: $p\n");
- return($F_WARNING);
- }
- } else {
- tlwarn("$prg: strange, package listed but no candidates: $p\n");
- return($F_WARNING);
- }
- } else {
- tlwarn("$prg: strange, package cannot be found in remote tlpdb: $p\n");
- return($F_WARNING);
- }
- }
- my $foo = $tlp->shortdesc;
- print "$p: ", defined($foo) ? $foo : "(shortdesc missing)" , "\n";
- return($F_OK);
-}
-
-sub show_one_package_detail {
- my ($ppp, @rest) = @_;
- my $ret = $F_OK;
- my ($pkg, $tag) = split ('@', $ppp, 2);
- my $tlpdb = $localtlpdb;
- my $source_found;
- my $tlp = $localtlpdb->get_package($pkg);
- my $installed = 0;
- if (!$tlp) {
- if ($opts{"only-installed"}) {
- print "package: $pkg\n";
- print "installed: No\n";
- return($F_OK);
- }
- if (!$remotetlpdb) {
- init_tlmedia_or_die(1);
- }
- if (defined($tag)) {
- if (!$remotetlpdb->is_virtual) {
- tlwarn("$prg: specifying implicit tags not allowed for non-virtual databases!\n");
- return($F_WARNING);
- } else {
- if (!$remotetlpdb->is_repository($tag)) {
- tlwarn("$prg: no such repository tag defined: $tag\n");
- return($F_WARNING);
- }
- }
- }
- $tlp = $remotetlpdb->get_package($pkg, $tag);
- if (!$tlp) {
- if (defined($tag)) {
- # we already searched for the package in a specific tag, don't retry
- # all candidates!
- tlwarn("$prg: cannot find package $pkg in repository $tag\n");
- return($F_WARNING);
- }
- my @cand = $remotetlpdb->candidates($pkg);
- if (@cand) {
- # if @cand is not empty, then we have a virtual database
- # we might have a package that is available in a
- # subsidiary repository, but not installable
- # because it is not pinned
- # we will list it but warn about this fact
- # useless test, @cand will always be defined because $remotetlpdb is virtual
- my $first = shift @cand;
- if (defined($first)) {
- tlwarn("$prg: strange, we have a first candidate but no tlp: $pkg\n");
- return($F_WARNING);
- }
- # already shifted away the first element
- if ($#cand >= 0) {
- # recursively showing all tags, but warn
- print "package: ", $pkg, "\n";
- print "WARNING: This package is not pinned but present in subsidiary repositories\n";
- print "WARNING: As long as it is not pinned it is not installable.\n";
- print "WARNING: Listing all available copies of the package.\n";
- my @aaa;
- for my $a (@cand) {
- my ($t,$r) = split(/\//, $a, 2);
- push @aaa, "$pkg" . '@' . $t;
- }
- $ret |= action_info(@aaa);
- return($ret);
- }
- }
- # we didn't find a package like this, so use search
- info("$prg: cannot find package $pkg, searching for other matches:\n");
- my ($foundfile, $founddesc) = search_tlpdb($remotetlpdb,$pkg,1,1,0);
- print "\nPackages containing \`$pkg\' in their title/description:\n";
- print $founddesc;
- print "\nPackages containing files matching \`$pkg\':\n";
- print $foundfile;
- return($ret);
- }
- # we want to also show the source if it is known
- if (defined($tag)) {
- $source_found = $tag;
- } else {
- if ($remotetlpdb->is_virtual) {
- my ($firsttag, @cand) = $remotetlpdb->candidates($pkg);
- $source_found = $firsttag;
- } else {
- # might be single user repository, don't mention anything
- }
- }
- $tlpdb = $remotetlpdb;
- } else {
- $installed = 1;
- }
- my @colls;
- if ($tlp->category ne "Collection" && $tlp->category ne "Scheme") {
- @colls = $localtlpdb->needed_by($pkg);
- if (!@colls) {
- if (!$opts{"only-installed"}) {
- # not referenced in the local tlpdb, so try the remote here, too
- init_tlmedia_or_die() if (!$remotetlpdb);
- @colls = $remotetlpdb->needed_by($pkg);
- }
- }
- }
- # {
- # require Data::Dumper;
- # print Data::Dumper->Dump([\$tlp], [qw(tlp)]);
- # }
- # some packages might depend on other packages, so do not
- # include arbitrary packages in the list of collections, but
- # only collections:
- @colls = grep {m;^collection-;} @colls;
- print "package: ", $tlp->name, "\n";
- print "repository: ", $source_found, "\n" if (defined($source_found));
- print "category: ", $tlp->category, "\n";
- print "shortdesc: ", $tlp->shortdesc, "\n" if ($tlp->shortdesc);
- print "longdesc: ", $tlp->longdesc, "\n" if ($tlp->longdesc);
- print "installed: ", ($installed ? "Yes" : "No"), "\n";
- print "revision: ", $tlp->revision, "\n" if ($installed);
- #
- # size computation: for normal packages give src/run/doc/bin sizes
- # for scheme/collection accumulated (including deps) sizes
- my $sizestr = "";
- if ($tlp->category ne "Collection" && $tlp->category ne "Scheme") {
- my $srcsize = $tlp->srcsize * $TeXLive::TLConfig::BlockSize;
- $sizestr = sprintf("%ssrc: %dk", $sizestr, int($srcsize / 1024) + 1)
- if ($srcsize > 0);
- my $docsize = $tlp->docsize * $TeXLive::TLConfig::BlockSize;
- $sizestr .= sprintf("%sdoc: %dk",
- ($sizestr ? ", " : ""), int($docsize / 1024) + 1)
- if ($docsize > 0);
- my $runsize = $tlp->runsize * $TeXLive::TLConfig::BlockSize;
- $sizestr .= sprintf("%srun: %dk",
- ($sizestr ? ", " : ""), int($runsize / 1024) + 1)
- if ($runsize > 0);
- # check for .ARCH expansions
- my $do_archs = 0;
- for my $d ($tlp->depends) {
- if ($d =~ m/^(.*)\.ARCH$/) {
- $do_archs = 1;
- last;
- }
- }
- if ($do_archs) {
- my @a = $localtlpdb->available_architectures;
- my %binsz = %{$tlp->binsize};
- my $binsize = 0;
- for my $a (@a) {
- $binsize += $binsz{$a} if defined($binsz{$a});
- my $atlp = $tlpdb->get_package($tlp->name . ".$a");
- if (!$atlp) {
- tlwarn("$prg: cannot find depending package" . $tlp->name . ".$a\n");
- return($F_WARNING);
- }
- my %abinsz = %{$atlp->binsize};
- $binsize += $abinsz{$a} if defined($abinsz{$a});
- }
- $binsize *= $TeXLive::TLConfig::BlockSize;
- $sizestr .= sprintf("%sbin: %dk",
- ($sizestr ? ", " : ""), int($binsize / 1024) + 1)
- if ($binsize > 0);
- }
- } else {
- # case of collection or scheme
- my $foo = $tlpdb->sizes_of_packages_with_deps ( 1, 1, undef, $pkg);
- if (defined($foo->{$pkg})) {
- $sizestr = sprintf("%dk", int($foo->{$pkg} / 1024) + 1);
- }
- }
- print "sizes: ", $sizestr, "\n";
- print "relocatable: ", ($tlp->relocated ? "Yes" : "No"), "\n";
- print "cat-version: ", $tlp->cataloguedata->{'version'}, "\n"
- if $tlp->cataloguedata->{'version'};
- print "cat-date: ", $tlp->cataloguedata->{'date'}, "\n"
- if $tlp->cataloguedata->{'date'};
- print "cat-license: ", $tlp->cataloguedata->{'license'}, "\n"
- if $tlp->cataloguedata->{'license'};
- print "cat-topics: ", $tlp->cataloguedata->{'topics'}, "\n"
- if $tlp->cataloguedata->{'topics'};
- print "cat-related: ", $tlp->cataloguedata->{'also'}, "\n"
- if $tlp->cataloguedata->{'also'};
- # print all the contact-* keys
- for my $k (keys %{$tlp->cataloguedata}) {
- if ($k =~ m/^contact-/) {
- print "cat-$k: ", $tlp->cataloguedata->{$k}, "\n";
- }
- }
- print "collection: ", @colls, "\n" if (@colls);
- if ($opts{"list"}) {
- if ($tlp->category eq "Collection" || $tlp->category eq "Scheme") {
- # in the case of collections of schemes we list the deps
- my @deps = $tlp->depends;
- if (@deps) {
- print "depends:\n";
- for my $d (@deps) {
- print "\t$d\n";
- }
- }
- }
- print "Included files, by type:\n";
- # if the package has a .ARCH dependency we also list the files for
- # those packages
- my @todo = $tlpdb->expand_dependencies("-only-arch", $tlpdb, ($pkg));
- for my $d (sort @todo) {
- my $foo = $tlpdb->get_package($d);
- if (!$foo) {
- tlwarn ("$prg: Should not happen, no dependent package $d\n");
- return($F_WARNING);
- }
- if ($d ne $pkg) {
- print "depending package $d:\n";
- }
- if ($foo->runfiles) {
- print "run files:\n";
- for my $f (sort $foo->runfiles) { print " $f\n"; }
- }
- if ($foo->srcfiles) {
- print "source files:\n";
- for my $f (sort $foo->srcfiles) { print " $f\n"; }
- }
- if ($foo->docfiles) {
- print "doc files:\n";
- for my $f (sort $foo->docfiles) {
- print " $f";
- my $dfd = $foo->docfiledata;
- if (defined($dfd->{$f})) {
- for my $k (keys %{$dfd->{$f}}) {
- print " $k=\"", $dfd->{$f}->{$k}, '"';
- }
- }
- print "\n";
- }
- }
- # in case we have them
- if ($foo->allbinfiles) {
- print "bin files (all platforms):\n";
- for my $f (sort $foo->allbinfiles) { print " $f\n"; }
- }
- }
- }
- print "\n";
- return($ret);
-}
-
-# PINNING
-#
-# this action manages the pinning file
-# of course it can be edited by hand, but we want to make this
-# easier for people to use
-# tlmgr pinning show
-# tlmgr pinning check
-# tlmgr pinning add <repo> <pkgglob> [<pkgglob> ...]
-# tlmgr pinning remove <repo> <pkgglob> [<pkgglob> ...]
-# tlmgr pinning remove <repo> --all
-sub action_pinning {
- my $what = shift @ARGV;
- $what || ($what = 'show');
- init_local_db();
- init_tlmedia_or_die();
- if (!$remotetlpdb->is_virtual) {
- tlwarn("$prg: only one repository configured, "
- . "pinning actions not supported.\n");
- return $F_WARNING;
- }
- my $pinref = $remotetlpdb->virtual_pindata();
- my $pf = $remotetlpdb->virtual_pinning();
-
- if ($what =~ m/^show$/i) {
- my @pins = @$pinref;
- if (!@pins) {
- tlwarn("$prg: no pinning data present.\n");
- return $F_OK;
- }
- info("$prg: this pinning data is defined:\n");
- for my $p (@pins) {
- info(" ", $p->{'repo'}, ":", $p->{'glob'}, "\n");
- }
- return $F_OK;
-
- } elsif ($what =~ m/^check$/i) {
- tlwarn("$prg: not implemented yet, sorry!\n");
- return $F_WARNING;
-
- } elsif ($what =~ m/^add$/i) {
- # we need at least two more arguments
- if (@ARGV < 2) {
- tlwarn("$prg: need at least two arguments to pinning add\n");
- return $F_ERROR;
- }
- my $repo = shift @ARGV;
- my @new = ();
- my @ov = $pf->value($repo);
- for my $n (@ARGV) {
- if (member($n, @ov)) {
- info("$prg: already pinned to $repo: $n\n");
- } else {
- push (@ov, $n);
- push (@new, $n);
- }
- }
- $pf->value($repo, @ov);
- $remotetlpdb->virtual_update_pins();
- $pf->save;
- info("$prg: new pinning data for $repo: @new\n") if @new;
- return $F_OK;
-
- } elsif ($what =~ m/^remove$/i) {
- my $repo = shift @ARGV;
- if (!defined($repo)) {
- tlwarn("$prg: missing repository argument to pinning remove\n");
- return $F_ERROR;
- }
- if ($opts{'all'}) {
- if (@ARGV) {
- tlwarn("$prg: additional argument(s) not allowed with --all: @ARGV\n");
- return $F_ERROR;
- }
- $pf->delete_key($repo);
- $remotetlpdb->virtual_update_pins();
- $pf->save;
- info("$prg: all pinning data removed for repository $repo\n");
- return $F_OK;
- }
- # complicated case, we want to remove only one setting
- my @ov = $pf->value($repo);
- my @nv;
- for my $pf (@ov) {
- push (@nv, $pf) if (!member($pf, @ARGV));
- }
- if ($#ov == $#nv) {
- info("$prg: no changes in pinning data for $repo\n");
- return $F_OK;
- }
- if (@nv) {
- $pf->value($repo, @nv);
- } else {
- $pf->delete_key($repo);
- }
- $remotetlpdb->virtual_update_pins();
- $pf->save;
- info("$prg: removed pinning data for repository $repo: @ARGV\n");
- return $F_OK;
-
- } else {
- tlwarn("$prg: unknown argument for pinning action: $what\n");
- return $F_ERROR;
- }
- # $pin{'repo'} = $repo;
- # $pin{'glob'} = $glob;
- # $pin{'re'} = $re;
- # $pin{'line'} = $line; # for debug/warning purpose
- return $F_ERROR;
-}
-
-# REPOSITORY
-#
-# this action manages the list of repositories
-# tlmgr repository list -> lists repositories
-# tlmgr repository list path|tag -> lists content of repo path|tag
-# tlmgr repository add path [tag] -> add repository with optional tag
-# tlmgr repository remove [path|tag] -> removes repository or tag
-# tlmgr repository set path[#tag] [path[#tag] ...] -> sets the list
-#
-
-sub array_to_repository {
- my %r = @_;
- my @ret;
- my @k = keys %r;
- if ($#k == 0) {
- # only one repo, don't write any tag
- return $r{$k[0]};
- }
- for my $k (keys %r) {
- my $v = $r{$k};
- if ($k ne $v) {
- $v = "$v#$k";
- }
- # encode spaces and % in the path and tags
- $v =~ s/%/%25/g;
- $v =~ s/ /%20/g;
- push @ret, $v;
- }
- return "@ret";
-}
-sub merge_sub_packages {
- my %pkgs;
- for my $p (@_) {
- if ($p =~ m/^(.*)\.([^.]*)$/) {
- my $n = $1;
- my $a = $2;
- if ($p eq "texlive.infra") {
- push @{$pkgs{$p}}, "all";
- } else {
- push @{$pkgs{$n}}, $a;
- }
- } else {
- push @{$pkgs{$p}}, "all";
- }
- }
- return %pkgs;
-}
-sub action_repository {
- init_local_db();
- my $what = shift @ARGV;
- $what = "list" if !defined($what);
- my %repos = repository_to_array($localtlpdb->option("location"));
- if ($what =~ m/^list$/i) {
- if (@ARGV) {
- # list what is in a repository
- for my $repo (@ARGV) {
- my $loc = $repo;
- if (defined($repos{$repo})) {
- $loc = $repos{$repo};
- }
- my ($tlpdb, $errormsg) = setup_one_remotetlpdb($loc);
- if (!defined($tlpdb)) {
- tlwarn("$prg: cannot get TLPDB from location $loc\n\n");
- } else {
- print "Packages at $loc:\n";
- my %pkgs = merge_sub_packages($tlpdb->list_packages);
- for my $p (sort keys %pkgs) {
- next if ($p =~ m/00texlive/);
- print " $p";
- if (!$opts{'with-platforms'}) {
- print "\n";
- } else {
- my @a = @{$pkgs{$p}};
- if ($#a == 0) {
- if ($a[0] eq "all") {
- # no further information necessary
- print "\n";
- } else {
- print ".$a[0]\n";
- }
- } else {
- print " (@{$pkgs{$p}})\n";
- }
- }
- }
- }
- }
- } else {
- print "List of repositories (with tags if set):\n";
- for my $k (keys %repos) {
- my $v = $repos{$k};
- print "\t$v";
- if ($k ne $v) {
- print " ($k)";
- }
- print "\n";
- }
- }
- return ($F_OK);
- }
- if ($what eq "add") {
- my $p = shift @ARGV;
- if (!defined($p)) {
- tlwarn("$prg: no repository given (to add)\n");
- return ($F_ERROR);
- }
- # check if it is either url or absolute path
- if (($p !~ m!^(https?|ftp)://!i) && ($p !~ m!$TeXLive::TLUtils::SshURIRegex!) &&
- !File::Spec->file_name_is_absolute($p)) {
- tlwarn("$prg: neither https?/ftp/ssh/scp/file URI nor absolute path, no action: $p\n");
- return ($F_ERROR);
- }
- my $t = shift @ARGV;
- $t = $p if (!defined($t));
- if (defined($repos{$t})) {
- tlwarn("$prg: repository or its tag already defined, no action: $p\n");
- return ($F_ERROR);
- }
- # TODO more checks needed?
- # if there was till now only *one* repository and that without
- # a tag, we give that one the "main" tag which is necessary
- # for proper operation!
- my @tags = keys %repos;
- if ($#tags == 0) {
- # we have only one repository, check if it has the main tag
- my $maintag = $tags[0];
- if ($maintag ne 'main') {
- $repos{'main'} = $repos{$maintag};
- delete $repos{$maintag};
- }
- }
- $repos{$t} = $p;
- $localtlpdb->option("location", array_to_repository(%repos));
- $localtlpdb->save;
- if ($t eq $p) {
- print "$prg: added repository: $p\n";
- } else {
- print "$prg: added repository with tag $t: $p\n";
- }
- return ($F_OK);
- }
- if ($what eq "remove") {
- my $p = shift @ARGV;
- if (!defined($p)) {
- tlwarn("$prg: no repository given (to remove)\n");
- return ($F_ERROR);
- }
- my $found = 0;
- for my $k (keys %repos) {
- if ($k eq $p || $repos{$k} eq $p) {
- $found = 1;
- delete $repos{$k};
- }
- }
- if (!$found) {
- tlwarn("$prg: repository not defined, cannot remove: $p\n");
- return ($F_ERROR);
- } else {
- $localtlpdb->option("location", array_to_repository(%repos));
- $localtlpdb->save;
- print "$prg: removed repository: $p\n";
- return ($F_OK);
- }
- # no reached
- return ($F_OK);
- }
- if ($what eq "set") {
- # TODO TODO
- # we have to make sure that there is ONE main repository!!!
- %repos = repository_to_array("@ARGV");
- $localtlpdb->option("location", array_to_repository(%repos));
- $localtlpdb->save;
- return ($F_OK);
- }
- if ($what eq "status") {
- if (!defined($remotetlpdb)) {
- init_tlmedia_or_die();
- }
- if (!$remotetlpdb->is_virtual) {
- my $verstat = $remotetlpdb->verification_status;
- print "main ", $remotetlpdb->location, " ",
- ($::machinereadable ? "$verstat " : ""),
- $VerificationStatusDescription{$verstat}, "\n";
- return ($F_OK);
- } else {
- for my $t ($remotetlpdb->virtual_get_tags()) {
- my $tlpdb = $remotetlpdb->virtual_get_tlpdb($t);
- my $verstat = $tlpdb->verification_status;
- print "$t ", $tlpdb->location, " ",
- ($::machinereadable ? "$verstat " : ""),
- $VerificationStatusDescription{$verstat}, "\n";
- }
- return($F_OK);
- }
- }
- # we are still here, unknown command to repository
- tlwarn("$prg: unknown subaction for tlmgr repository: $what\n");
- return ($F_ERROR);
-}
-
-sub action_candidates {
- my $what = shift @ARGV;
- if (!defined($what)) {
- tlwarn("$prg: candidates needs a package name as argument\n");
- return ($F_ERROR);
- }
- init_local_db();
- init_tlmedia_or_die();
- my @cand = $remotetlpdb->candidates($what);
- if (@cand) {
- my $first = shift @cand;
- if (defined($first)) {
- my ($t,$r) = split(/\//, $first, 2);
- print "Install candidate for $what from $t ($r)\n";
- } else {
- print "No install candidate for $what found.\n";
- }
- # already shifted away the first element
- if ($#cand >= 0) {
- print "Other repositories providing this package:\n";
- for my $a (@cand) {
- my ($t,$r) = split(/\//, $a, 2);
- print "$t ($r)\n";
- }
- }
- } else {
- print "Package $what not found.\n";
- return ($F_WARNING);
- }
- return ($F_OK);;
-}
-
-# OPTION
-#
-sub action_option {
- my $what = shift @ARGV;
- $what = "show" unless defined($what);
- init_local_db();
- my $ret = $F_OK;
- my %json;
- if ($what =~ m/^show$/i) {
- if ($opts{'json'}) {
- my $json = $localtlpdb->options_as_json();
- print("$json\n");
- return($ret);
- }
- for my $o (sort keys %{$localtlpdb->options}) {
- # ignore generate_update which is no longer used or needed.
- next if ($o eq "generate_updmap");
- # ignore some things which are w32 specific
- next if ($o eq "desktop_integration" && !win32());
- next if ($o eq "file_assocs" && !win32());
- next if ($o eq "w32_multi_user" && !win32());
- #
- if (win32()) {
- next if ($o =~ m/^sys_/);
- }
- if (defined $TLPDBOptions{$o}) {
- if ($::machinereadable) {
- print "$TLPDBOptions{$o}->[2]\t", $localtlpdb->option($o), "\n";
- } else {
- info("$TLPDBOptions{$o}->[3] ($TLPDBOptions{$o}->[2]): " .
- $localtlpdb->option($o) . "\n");
- }
- } else {
- tlwarn ("$prg: option $o not supported\n");
- $ret |= $F_WARNING;
- }
- }
- } elsif ($what =~ m/^(showall|help)$/i) {
- if ($opts{'json'}) {
- my $json = $localtlpdb->options_as_json();
- print("$json\n");
- return($ret);
- }
- my %loc = %{$localtlpdb->options};
- for my $o (sort keys %TLPDBOptions) {
- if ($::machinereadable) {
- print "$TLPDBOptions{$o}->[2]\t",
- (defined($loc{$o}) ? $loc{$o} : "(not set)"), "\n";
- } else {
- info("$TLPDBOptions{$o}->[3] ($TLPDBOptions{$o}->[2]): " .
- (defined($loc{$o}) ? $loc{$o} : "(not set)") . "\n");
- }
- }
- } else {
- if ($what eq "location" || $what eq "repo") {
- # silently rewrite location|repo -> repository
- $what = "repository";
- }
- my $found = 0;
- for my $opt (keys %TLPDBOptions) {
- if (($what eq $TLPDBOptions{$opt}->[2]) || ($what eq $opt)) {
- $found = 1;
- # the option argument matches the name
- my $val = shift @ARGV;
- if (defined($val)) {
- return ($F_ERROR) if !check_on_writable();
- # set new value
- # here we have to care for some special cases
- if ($what eq $TLPDBOptions{"location"}->[2]) {
- # support "ctan" on the cmd line
- if ($val =~ m/^ctan$/i) {
- $val = "$TeXLive::TLConfig::TeXLiveURL";
- }
- info("$prg: setting default package repository to $val\n");
- $localtlpdb->option($opt, $val);
- } elsif ($what eq $TLPDBOptions{"backupdir"}->[2]) {
- info("$prg: setting option $what to $val.\n");
- if (! -d $val) {
- info("$prg: the directory $val does not exists, it has to be created\n");
- info("$prg: before backups can be done automatically.\n");
- }
- $localtlpdb->option($opt, $val);
- } elsif ($what eq $TLPDBOptions{"w32_multi_user"}->[2]) {
- # when running w32 do not allow that a non-admin users sets
- # this from false to true
- my $do_it = 0;
- if (win32()) {
- if (admin()) {
- $do_it = 1;
- } else {
- if ($val) {
- # non admin and tries to set to true, warn
- tlwarn("$prg: non-admin user cannot set $TLPDBOptions{'w32_multi_user'}->[2] option to true\n");
- } else {
- $do_it = 1;
- }
- }
- } else {
- $do_it = 1;
- }
- if ($do_it) {
- if ($val) {
- info("$prg: setting option $what to 1.\n");
- $localtlpdb->option($opt, 1);
- } else {
- info("$prg: setting option $what to 0.\n");
- $localtlpdb->option($opt, 0);
- }
- }
- } else {
- # default case, switch for different types
- if ($TLPDBOptions{$opt}->[0] eq "b") {
- if ($val) {
- info("$prg: setting option $what to 1.\n");
- $localtlpdb->option($opt, 1);
- } else {
- info("$prg: setting option $what to 0.\n");
- $localtlpdb->option($opt, 0);
- }
- } elsif ($TLPDBOptions{$opt}->[0] eq "p") {
- info("$prg: setting option $what to $val.\n");
- $localtlpdb->option($opt, $val);
- } elsif ($TLPDBOptions{$opt}->[0] eq "u") {
- info("$prg: setting option $what to $val.\n");
- $localtlpdb->option($opt, $val);
- } elsif ($TLPDBOptions{$opt}->[0] =~ m/^n(:((-)?\d+)?..((-)?\d+)?)?$/) {
- my $isgood = 1;
- my $n = int($val);
- my $low;
- my $up;
- if (defined($1)) {
- # range given
- if (defined($2)) {
- # lower border
- if ($2 > $n) {
- tlwarn("$prg: value $n for $what out of range ($TLPDBOptions{$opt}->[0])\n");
- $isgood = 0;
- }
- }
- if (defined($4)) {
- # upper border
- if ($4 < $n) {
- tlwarn("$prg: value $n for $what out of range ($TLPDBOptions{$opt}->[0])\n");
- $isgood = 0;
- }
- }
- }
- if ($isgood) {
- info("$prg: setting option $what to $n.\n");
- $localtlpdb->option($opt, $n);
- }
- } else {
- tlwarn ("$prg: unknown type of option $opt: $TLPDBOptions{$opt}->[0]\n");
- return ($F_ERROR);
- }
- }
- my $local_location = $localtlpdb->location;
- info("$prg: updating $local_location\n");
- $localtlpdb->save;
- # now also save the TLPOBJ of 00texlive.installation
- my $tlpo = $localtlpdb->get_package("00texlive.installation");
- if ($tlpo) {
- if (open(TOFD, ">$::maintree/tlpkg/tlpobj/00texlive.installation.tlpobj")) {
- $tlpo->writeout(\*TOFD);
- close(TOFD);
- } else {
- tlwarn("$prg: Cannot save 00texlive.installation to $::maintree/tlpkg/tlpobj/00texlive.installation.tlpobj\n");
- $ret |= $F_WARNING;
- }
- }
- } else {
- # show current value
- if ($::machinereadable) {
- print "$TLPDBOptions{$opt}->[2]\t", $localtlpdb->option($opt), "\n";
- } else {
- info ("$TLPDBOptions{$opt}->[3] ($TLPDBOptions{$opt}->[2]): " .
- $localtlpdb->option($opt) . "\n");
- }
- }
- last;
- }
- }
- if (!$found) {
- tlwarn("$prg: option $what not supported!\n");
- return ($F_ERROR);
- }
- }
- return ($ret);
-}
-
-
-# PLATFORM (was ARCH)
-#
-sub action_platform {
- my $ret = $F_OK;
- my @extra_w32_packs = qw/tlperl.win32 tlgs.win32 tlpsv.win32
- collection-wintools
- dviout.win32 wintools.win32/;
- if ($^O =~ /^MSWin/i) {
- warn("action `platform' not supported on Windows\n");
- # return an error here so that we don't go into post-actions
- return ($F_ERROR);
- }
- if ($opts{"usermode"}) {
- tlwarn("$prg: action `platform' not supported in usermode\n");
- return ($F_ERROR);
- }
- my $what = shift @ARGV;
- init_local_db(1);
- info("$prg platform: dry run, no changes will be made\n") if $opts{"dry-run"};
- $what || ($what = "list");
- if ($what =~ m/^list$/i) {
- # list the available platforms
- # initialize the TLPDB from $location
- init_tlmedia_or_die();
- my @already_installed_arch = $localtlpdb->available_architectures;
- print "Available platforms:\n";
- foreach my $a ($remotetlpdb->available_architectures) {
- if (member($a,@already_installed_arch)) {
- print "(i) $a\n";
- } else {
- print " $a\n";
- }
- }
- print "Already installed platforms are marked with (i)\n";
- print "You can add new platforms with: tlmgr platform add PLAT1 PLAT2...\n";
- print "You can remove platforms with: tlmgr platform remove PLAT1 PLAT2...\n";
- print "You can set the active platform with: tlmgr platform set PLAT\n";
- return ($F_OK | $F_NOPOSTACTION);
-
- } elsif ($what =~ m/^add$/i) {
- return ($F_ERROR) if !check_on_writable();
- init_tlmedia_or_die();
- my @already_installed_arch = $localtlpdb->available_architectures;
- my @available_arch = $remotetlpdb->available_architectures;
- my @todoarchs;
- foreach my $a (@ARGV) {
- if (TeXLive::TLUtils::member($a, @already_installed_arch)) {
- info("$prg: platform already installed: $a\n");
- next;
- }
- if (!TeXLive::TLUtils::member($a, @available_arch)) {
- info("$prg: platform `$a' not available; see tlmgr platform list\n");
- next;
- }
- push @todoarchs, $a;
- }
- foreach my $pkg ($localtlpdb->list_packages) {
- next if ($pkg =~ m/^00texlive/);
- my $tlp = $localtlpdb->get_package($pkg);
- foreach my $dep ($tlp->depends) {
- if ($dep =~ m/^(.*)\.ARCH$/) {
- # we have to install something
- foreach my $a (@todoarchs) {
- if ($remotetlpdb->get_package("$pkg.$a")) {
- info("install: $pkg.$a\n");
- if (!$opts{'dry-run'}) {
- if (! $remotetlpdb->install_package("$pkg.$a", $localtlpdb)) {
- $ret |= $F_ERROR;
- }
- }
- } else {
- tlwarn("$prg: action platform add, cannot find package $pkg.$a\n");
- $ret |= $F_WARNING;
- }
- }
- }
- }
- }
- if (TeXLive::TLUtils::member('win32', @todoarchs)) {
- # install the necessary w32 stuff
- for my $p (@extra_w32_packs) {
- info("install: $p\n");
- if (!$opts{'dry-run'}) {
- if (! $remotetlpdb->install_package($p, $localtlpdb)) {
- $ret |= $F_ERROR;
- }
- }
- }
- }
- # update the option("available_architectures") list of installed archs
- if (!$opts{"dry-run"}) {
- my @larchs = $localtlpdb->setting("available_architectures");
- push @larchs, @todoarchs;
- $localtlpdb->setting("available_architectures",@larchs);
- $localtlpdb->save;
- }
-
- } elsif ($what =~ m/^remove$/i) {
- return ($F_ERROR) if !check_on_writable();
- my @already_installed_arch = $localtlpdb->available_architectures;
- my @todoarchs;
- my $currentarch = $localtlpdb->platform();
- foreach my $a (@ARGV) {
- if (!TeXLive::TLUtils::member($a, @already_installed_arch)) {
- tlwarn("$prg: Platform $a not installed, use 'tlmgr platform list'!\n");
- $ret |= $F_WARNING;
- next;
- }
- if ($currentarch eq $a) {
- info("$prg: You are running on platform $a, you cannot remove that one!\n");
- $ret |= $F_WARNING;
- next;
- }
- push @todoarchs, $a;
- }
- foreach my $pkg ($localtlpdb->list_packages) {
- next if ($pkg =~ m/^00texlive/);
- my $tlp = $localtlpdb->get_package($pkg);
- if (!$tlp) {
- # that is a package foobar.$a that has already been remove but
- # is still in the list above, so ignore that
- next;
- }
- foreach my $dep ($tlp->depends) {
- if ($dep =~ m/^(.*)\.ARCH$/) {
- # we have to install something
- foreach my $a (@todoarchs) {
- if ($localtlpdb->get_package("$pkg.$a")) {
- info("remove: $pkg.$a\n");
- # assume that this works out
- $localtlpdb->remove_package("$pkg.$a") if (!$opts{"dry-run"});
- }
- }
- }
- }
- }
- if (TeXLive::TLUtils::member('win32', @todoarchs)) {
- for my $p (@extra_w32_packs) {
- info("remove: $p\n");
- $localtlpdb->remove_package($p) if (!$opts{"dry-run"});
- }
- }
- if (!$opts{"dry-run"}) {
- # try to remove bin/$a dirs
- for my $a (@todoarchs) {
- if (!rmdir("$Master/bin/$a")) {
- tlwarn("$prg: failed to rmdir $Master/bin/$a: $!\n");
- $ret |= $F_WARNING;
- }
- }
- # update the option("available_architectures") list of installed archs
- my @larchs = $localtlpdb->setting("available_architectures");
- my @newarchs;
- for my $a (@larchs) {
- push @newarchs, $a if !member($a, @todoarchs);
- }
- $localtlpdb->setting("available_architectures",@newarchs);
- $localtlpdb->save;
- }
-
- } elsif ($what =~ m/^set$/i) {
- return if !check_on_writable();
- my $arg = shift @ARGV;
- die "Missing argument to platform set" unless defined($arg);
- my @already_installed_arch = $localtlpdb->available_architectures;
- if ($arg =~ m/^auto$/i) {
- info("Setting platform detection to auto mode.\n");
- $localtlpdb->setting('-clear', 'platform');
- $localtlpdb->save;
- } else {
- if (!TeXLive::TLUtils::member($arg, @already_installed_arch)) {
- tlwarn("$prg: cannot set platform to a not installed one.\n");
- return ($F_ERROR);
- }
- $localtlpdb->setting('platform', $arg);
- $localtlpdb->save;
- }
- } else {
- tlwarn("$prg: Unknown option for platform: $what\n");
- $ret |= $F_ERROR;
- }
- return ($ret);
-}
-
-
-# GENERATE
-#
-sub action_generate {
- if ($opts{"usermode"}) {
- tlwarn("$prg: action `generate' not supported in usermode!\n");
- return $F_ERROR;
- }
- my $what = shift @ARGV;
- if (!defined($what)) {
- tlwarn("$prg: action `generate' requires an argument!\n");
- return ($F_ERROR);
- }
- init_local_db();
-
- # we create fmtutil.cnf, language.dat, language.def in TEXMFSYSVAR and
- # updmap.cfg in TEXMFDIST. The reason is that we are now using an
- # implementation of updmap that supports multiple updmap files.
- # Local adaptions should not be made there, but only in TEXMFLOCAL
- # or TEXMF(SYS)CONFIG updmap.cfg
- #
- chomp (my $TEXMFSYSVAR = `kpsewhich -var-value=TEXMFSYSVAR`);
- chomp (my $TEXMFSYSCONFIG = `kpsewhich -var-value=TEXMFSYSCONFIG`);
- chomp (my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`);
- chomp (my $TEXMFDIST = `kpsewhich -var-value=TEXMFDIST`);
-
- # we do generate all config files, treat $opts{"dest"} as pattern
- # and make it append the respective extensions
- my $append_extension = (($opts{"dest"} && ($what eq "language")) ? 1 : 0);
-
- if ($what =~ m/^language(\.dat|\.def|\.dat\.lua)?$/i) {
- #
- # if --rebuild-sys is given *and* --dest we warn that this might not
- # work if the destination is not the default one
- if ($opts{"rebuild-sys"} && $opts{"dest"}) {
- tlwarn("$prg generate $what: warning: both --rebuild-sys and --dest\n",
- "given; the call to fmtutil-sys can fail if the given\n",
- "destination is different from the default.\n");
- }
- #
- # we have to set TEXMFVAR, TEXMFCONFIG in the environment so that
- # searching for language.(dat/def) does search in the right place
- if ($what =~ m/^language(\.dat\.lua)?$/i) {
- my $dest = $opts{"dest"} ||
- "$TEXMFSYSVAR/tex/generic/config/language.dat.lua";
- $dest .= ".dat.lua" if $append_extension;
- my $localcfg = $opts{"localcfg"} ||
- "$TEXMFLOCAL/tex/generic/config/language-local.dat.lua";
- debug("$prg: writing language.dat.lua data to $dest\n");
- TeXLive::TLUtils::create_language_lua($localtlpdb, $dest, $localcfg);
- if ($opts{"rebuild-sys"}) {
- do_cmd_and_check
- ("fmtutil-sys $common_fmtutil_args --byhyphen \"$dest\"");
- } else {
- info("To make the newly-generated language.dat.lua take effect,"
- . " run fmtutil-sys --byhyphen $dest.\n");
- }
- }
- if ($what =~ m/^language(\.dat)?$/i) {
- my $dest = $opts{"dest"} ||
- "$TEXMFSYSVAR/tex/generic/config/language.dat";
- $dest .= ".dat" if $append_extension;
- my $localcfg = $opts{"localcfg"} ||
- "$TEXMFLOCAL/tex/generic/config/language-local.dat";
- debug ("$prg: writing language.dat data to $dest\n");
- TeXLive::TLUtils::create_language_dat($localtlpdb, $dest, $localcfg);
- if ($opts{"rebuild-sys"}) {
- do_cmd_and_check
- ("fmtutil-sys $common_fmtutil_args --byhyphen \"$dest\"");
- } else {
- info("To make the newly-generated language.dat take effect,"
- . " run fmtutil-sys --byhyphen $dest.\n");
- }
- }
- if ($what =~ m/^language(\.def)?$/i) {
- my $dest = $opts{"dest"} ||
- "$TEXMFSYSVAR/tex/generic/config/language.def";
- $dest .= ".def" if $append_extension;
- my $localcfg = $opts{"localcfg"} ||
- "$TEXMFLOCAL/tex/generic/config/language-local.def";
- debug("$prg: writing language.def data to $dest\n");
- TeXLive::TLUtils::create_language_def($localtlpdb, $dest, $localcfg);
- if ($opts{"rebuild-sys"}) {
- do_cmd_and_check
- ("fmtutil-sys $common_fmtutil_args --byhyphen \"$dest\"");
- } else {
- info("To make the newly-generated language.def take effect,"
- . " run fmtutil-sys --byhyphen $dest.\n");
- }
- }
-
- } elsif ($what =~ m/^fmtutil$/i) {
- tlwarn("$prg: generate fmtutil is no longer needed or supported.\n");
- tlwarn("$prg: Please read the documentation of the `fmtutil' program.\n");
- tlwarn("$prg: Goodbye.\n");
- return $F_ERROR;
-
- } elsif ($what =~ m/^_fmtutil$/i) {
- my $dest = $opts{"dest"} || "$TEXMFDIST/web2c/fmtutil.cnf";
- debug("$prg: writing new fmtutil.cnf to $dest\n");
- TeXLive::TLUtils::create_fmtutil($localtlpdb, $dest);
-
- if ($opts{"rebuild-sys"}) {
- do_cmd_and_check("fmtutil-sys $common_fmtutil_args --all");
- } else {
- info("To make the newly-generated fmtutil.cnf take effect,"
- . " run fmtutil-sys --all.\n");
- }
-
- } elsif ($what =~ m/^updmap$/i) {
- tlwarn("$prg: generate updmap is no longer needed or supported.\n");
- tlwarn("$prg: Please read the documentation of the `updmap' program.\n");
- tlwarn("$prg: Goodbye.\n");
- return $F_ERROR;
-
- } elsif ($what =~ m/^_updmap$/i) {
- my $dest = $opts{"dest"} || "$TEXMFDIST/web2c/updmap.cfg";
- debug("$prg: writing new updmap.cfg to $dest\n");
- TeXLive::TLUtils::create_updmap($localtlpdb, $dest);
-
- if ($opts{"rebuild-sys"}) {
- do_cmd_and_check("updmap-sys");
- } else {
- info("To make the newly-generated updmap.cfg take effect,"
- . " run updmap-sys.\n");
- }
-
- } else {
- tlwarn("$prg: Unknown option for generate: $what; try --help if you need it.\n");
- return $F_ERROR;
- }
-
- return $F_OK;
-}
-
-
-# GUI
-#
-sub action_gui {
- eval { require Tk; };
- if ($@) {
- # that didn't work out, give some usefull error message and stop
- my $tkmissing = 0;
- if ($@ =~ /^Can\'t locate Tk\.pm/) {
- $tkmissing = 1;
- }
- if ($tkmissing) {
- if ($^O =~ /^MSWin/i) {
- # that should not happen, we are shipping Tk!!
- require Win32;
- my $msg = "Cannot load Tk, that should not happen as we ship it!\nHow did you start tlmgrgui??\n(Error message: $@)\n";
- Win32::MsgBox($msg, 1|Win32::MB_ICONSTOP(), "Warning");
- } else {
- printf STDERR "
-$prg: Cannot load Tk, thus the GUI cannot be started!
-The Perl/Tk module is not shipped with the TeX Live installation.
-You have to install it to get the tlmgr GUI working.
-(INC = @INC)
-
-See https://tug.org/texlive/distro.html#perltk for more details.
-Goodbye.
-";
- }
- } else {
- printf STDERR "$prg: unexpected problem loading Tk: $@\n";
- }
- exit 1;
- }
-
- # now check that we can actually create a top level window,
- # on darwin the X server might not be started, or on unix we are working
- # on a console, or whatever.
- eval { my $foo = Tk::MainWindow->new; $foo->destroy; };
- if ($@) {
- printf STDERR "perl/Tk unusable, cannot create main windows.
-That could be a consequence of not having X Windows installed or started!
-Error message from creating MainWindow:
- $@
-";
- exit 1;
- }
-
- # be sure that sub actions do *not* finish
- $::gui_mode = 1;
- # also unset the $opts{"gui"} to make recursive calls to action_* not starting
- # another GUI instance (or better trying to ...)
- $opts{"gui"} = 0;
-
- require("tlmgrgui.pl");
- # should not be reached
- exit(1);
-}
-
-
-# UNINSTALL
-# Return zero if successful, nonzero if failure.
-#
-sub uninstall_texlive {
- if (win32()) {
- printf STDERR "Please use \"Add/Remove Programs\" from the Control Panel to removing TeX Live!\n";
- return ($F_ERROR);
- }
- return if !check_on_writable();
-
- init_local_db(0);
- my $force = defined($opts{"force"}) ? $opts{"force"} : 0;
- if (!$force) {
- print("If you answer yes here the whole TeX Live installation here,\n",
- "under ", $localtlpdb->root, ", will be removed!\n");
- print "Remove TeX Live (y/N): ";
- my $yesno = <STDIN>;
- if ($yesno !~ m/^y(es)?$/i) {
- print "Ok, cancelling the removal!\n";
- return ($F_OK | $F_NOPOSTACTION);
- }
- }
- print ("Ok, removing the whole installation:\n");
- TeXLive::TLUtils::remove_symlinks($localtlpdb->root,
- $localtlpdb->platform(),
- $localtlpdb->option("sys_bin"),
- $localtlpdb->option("sys_man"),
- $localtlpdb->option("sys_info"));
- # now remove the rest
- system("rm", "-rf", "$Master/texmf-dist");
- system("rm", "-rf", "$Master/texmf-doc");
- system("rm", "-rf", "$Master/texmf-var");
- system("rm", "-rf", "$Master/tlpkg");
- system("rm", "-rf", "$Master/bin");
- system("rm", "-rf", "$Master/readme-html.dir");
- system("rm", "-rf", "$Master/readme-txt.dir");
- for my $f (qw/doc.html index.html install-tl
- LICENSE.CTAN LICENSE.TL README README.usergroups
- release-texlive.txt texmf.cnf texmfcnf.lua/) {
- system("rm", "-f", "$Master/$f");
- }
- if (-d "$Master/temp") {
- finddepth(sub { rmdir; }, "$Master/temp");
- }
- unlink("$Master/install-tl.log");
- # if they want removal, give them removal. Hopefully they know how to
- # regenerate any changed config files.
- system("rm", "-rf", "$Master/texmf-config");
- finddepth(sub { rmdir; }, "$Master");
-
- return -d "$Master";
-}
-
-
-# RECREATE-TLPDB
-#
-sub action_recreate_tlpdb {
- return if !check_on_writable();
- my $tlpdb = TeXLive::TLPDB->new;
- $tlpdb->root($Master);
- my $inst = TeXLive::TLPOBJ->new;
- $inst->name("00texlive.installation");
- $inst->category("TLCore");
- my @deps;
- # options are done further down with $tlpdb->reset_options()
- #for my $k (keys %TeXLive::TLConfig::TLPDBOptions) {
- # push @deps, "opt_$k:" . $TeXLive::TLConfig::TLPDBOptions{k}->[1];
- #}
- # find list of available archs
- my @archs;
- opendir (DIR, "$Master/bin") || die "opendir($Master/bin) failed: $!";
- my @dirents = readdir (DIR);
- closedir (DIR) || warn "closedir($Master/bin) failed: $!";
- for my $dirent (@dirents) {
- next if $dirent eq ".";
- next if $dirent eq "..";
- next unless -d "$Master/bin/$dirent";
- if (-r "$Master/bin/$dirent/kpsewhich" || -r "$Master/bin/$dirent/kpsewhich.exe") {
- push @archs, $dirent;
- debug("$prg: skipping directory $Master/bin/$dirent, no kpsewhich there\n");
- }
- }
- push @deps, "setting_available_architectures:" . join(" ",@archs);
- # we have to find out the default arch
- # if there is only one dir in $Master/bin then we are settled,
- # otherwise we expect the user to pass a correct arch string
- if (!TeXLive::TLUtils::member(TeXLive::TLUtils::platform(), @archs)) {
- # hmm that is bad, the platform as detected is not in the list
- # of installed platforms, so the option --arch has to be given
- # if only one is installed use that one
- if ($#archs == 0) {
- # only one arch available, fine, use it as default
- push @deps, "setting_platform:$archs[0]";
- } else {
- if (defined($opts{"platform"})) {
- if (member($opts{"platform"}, @archs)) {
- push @deps, "setting_platform:" . $opts{"platform"};
- } else {
- tlwarn("$prg: The platform you passed in with --platform is not present in $Master/bin\n");
- tlwarn("$prg: Please specify one of the available ones: @archs\n");
- exit(1);
- }
- } else {
- tlwarn("$prg: More than one platform available: @archs\n");
- tlwarn("$prg: Please pass one as the default you are running on with --platform=...\n");
- exit(1);
- }
- }
- }
- $inst->depends(@deps);
- # now we have all the stuff for 00texlive.installation done
- $tlpdb->add_tlpobj($inst);
- # reset the options to default values
- $tlpdb->add_default_options();
- # check for location == _MASTER_
- if ($tlpdb->option("location") eq "__MASTER__") {
- $tlpdb->option("location", $TeXLive::TLConfig::TeXLiveURL);
- }
- # add the other stuff in $Master/tlpkg/tlpobj/*.tlpobj
- # we can ignore *.{source,doc}.tlpobj because they are already
- # included in the *.tlpobj parent one at install time
- # (TODO: we should actually REMOVE the *.{source,doc}.tlpobj files
- # at package install time)
- opendir (DIR, "$Master/tlpkg/tlpobj") or die "opendir($Master/tlpkg/tlpobj) failed: $!";
- my @tlps = readdir(DIR);
- closedir (DIR) || warn "closedir($Master/tlpkg/tlpobj) failed: $!";
- for my $t (@tlps) {
- next if -d $t; # also does . and ..
- next if ($t !~ m/\.tlpobj$/i);
- # ignore .source and .doc tlpobjs
- next if ($t =~ m/\.(source|doc)\.tlpobj$/i);
- my $tlp = TeXLive::TLPOBJ->new;
- $tlp->from_file("$Master/tlpkg/tlpobj/$t");
- $tlpdb->add_tlpobj($tlp);
- }
- # writeout the re-created tlpdb to stdout
- $tlpdb->writeout;
- return;
-}
-
-
-# CHECK
-#
-sub init_tltree {
- my ($svn) = @_;
-
- # if we are on W32, die (no find).
- my $arch = $localtlpdb->platform();
- if ($arch eq "win32") {
- tldie("$prg: sorry, cannot check this on Windows.\n");
- }
-
- my $Master = $localtlpdb->root;
- my $tltree = TeXLive::TLTREE->new ("svnroot" => $Master);
- if ($svn) {
- debug("Initializing TLTREE from svn\n");
- $tltree->init_from_svn;
- } else {
- debug("Initializing TLTREE from find\n");
- $tltree->init_from_files;
- }
- return($tltree);
-}
-
-sub action_check {
- my $svn = defined($opts{"use-svn"}) ? $opts{"use-svn"} : 0;
- my $what = shift @ARGV;
- $what || ($what = "all");
- $what =~ s/^ *//;
- $what =~ s/ *$//;
- init_local_db();
- my $ret = 0;
- if ($what =~ m/^all$/i) {
- my $tltree = init_tltree($svn);
- print "Running check files:\n"; $ret |= check_files($tltree);
- print "Running check depends:\n"; $ret |= check_depends();
- print "Running check executes:\n"; $ret |= check_executes();
- print "Running check runfiles:\n"; $ret |= check_runfiles();
- print "Running check texmfdbs\n"; $ret |= check_texmfdbs();
- } elsif ($what =~ m/^files$/i) {
- my $tltree = init_tltree($svn);
- $ret |= check_files($tltree);
- } elsif ($what =~ m/^collections$/i) {
- tlwarn("$prg: \"collections\" check has been replaced by \"depends\".\n");
- $ret |= check_depends();
- } elsif ($what =~ m/^depends$/i) {
- $ret |= check_depends();
- } elsif ($what =~ m/^runfiles$/i) {
- $ret |= check_runfiles();
- } elsif ($what =~ m/^executes$/i) {
- $ret |= check_executes();
- } elsif ($what =~ m/^texmfdbs$/i) {
- $ret |= check_texmfdbs();
- } else {
- tlwarn("$prg: No idea how to check: $what\n");
- $ret = 1;
- }
- if ($ret) {
- return ($F_ERROR);
- } else {
- return ($F_OK);
- }
-}
-
-# check file coverage in both direction.
-#
-sub check_files {
- my $tltree = shift;
- my $ret = 0;
- my %filetopacks;
- my $Master = $localtlpdb->root;
- debug("Collecting all files of all packages\n");
- for my $p ($localtlpdb->list_packages()) {
- # ignore files in the installer
- next if ($p eq "00texlive.installer");
- my $tlp = $localtlpdb->get_package($p);
- my @files = $tlp->all_files;
- if ($tlp->relocated) {
- for (@files) { s:^$RelocPrefix/:$RelocTree/:; }
- }
- for my $f (@files) {
- push @{$filetopacks{$f}}, $p;
- }
- }
- my @multiple = ();
- my @missing = ();
- debug("Checking for occurrences and existence of all files\n");
- for (keys %filetopacks) {
- push @missing, $_ if (! -r "$Master/$_");
- my @foo = @{$filetopacks{$_}};
- if ($#foo < 0) {
- warn "that shouldn't happen #foo < 0: $_";
- } elsif ($#foo > 0) {
- push @multiple, $_;
- }
- }
- if ($#multiple >= 0) {
- $ret = 1;
- print "\f Multiple included files (relative to $Master):\n";
- for (sort @multiple) {
- my @foo = @{$filetopacks{$_}};
- print " $_ (@foo)\n";
- }
- print "\n";
- }
- if ($#missing >= 0) {
- $ret = 1;
- print "\f Files mentioned in tlpdb but missing (relative to $Master):\n";
- for my $m (@missing) {
- print "\t$m\n";
- }
- print "\n";
- }
-
- # check that all files in the trees are covered, along with
- # 00texlive.image, q.v. The ones here are not included in the
- # archival source/ tarball;
- my @IgnorePatterns = qw!
- release-texlive.txt source/
- texmf-dist/ls-R$ texmf-doc/ls-R$
- tlpkg/archive tlpkg/backups tlpkg/installer
- tlpkg/texlive.tlpdb tlpkg/tlpobj tlpkg/texlive.profile
- texmf-config/ texmf-var/
- texmf.cnf texmfcnf.lua install-tl.log
- !;
- my %tltreefiles = %{$tltree->{'_allfiles'}};
- my @tlpdbfiles = keys %filetopacks;
- my @nohit;
- for my $f (keys %tltreefiles) {
- # if it is mentioned in the tlpdb or is ignored it is considered
- # as covered, thus, otherwise we push it onto the nothit list
- if (!defined($filetopacks{$f})) {
- my $ignored = 0;
- for my $p (@IgnorePatterns) {
- if ($f =~ m/^$p/) {
- $ignored = 1;
- last;
- }
- }
- if (!$ignored) {
- push @nohit, $f;
- }
- }
- }
- if (@nohit) {
- $ret = 1;
- print "\f Files present but not covered (relative to $Master):\n";
- for my $f (sort @nohit) {
- print " $f\n";
- }
- print "\n";
- }
- return($ret);
-}
-
-# Check for runtime files with the same name but different contents.
-#
-sub check_runfiles {
- my $Master = $localtlpdb->root;
-
- # build a list of all runtime files associated with normal packages.
- (my $omit_pkgs = `ls "$Master/bin"`) =~ s/\n/\$|/g; # binaries
- $omit_pkgs .= '^0+texlive|^bin-|^collection-|^scheme-|^texlive-|^texworks';
- $omit_pkgs .= '|^pgf$'; # intentionally duplicated .lua
- $omit_pkgs .= '|^latex-.*-dev$'; # intentionally duplicated base latex
- my @runtime_files = ();
- #
- foreach my $tlpn ($localtlpdb->list_packages) {
- next if $tlpn =~ /$omit_pkgs/;
- #
- my $tlp = $localtlpdb->get_package($tlpn);
- my @files = $tlp->runfiles;
- if ($tlp->relocated) {
- for (@files) {
- s!^$TeXLive::TLConfig::RelocPrefix/!$TeXLive::TLConfig::RelocTree/!;
- }
- }
- # special case for koma-script where doc/src files are in runfiles section
- if ($tlpn eq "koma-script") {
- @files = grep {!m;^texmf-dist/source/latex/koma-script/;} @files;
- @files = grep {!m;^texmf-dist/doc/latex/koma-script/;} @files;
- }
- push @runtime_files, @files;
- }
-
- # build the duplicates list.
- my @duplicates = (""); # just to use $duplicates[-1] freely
- my $prev = "";
- foreach my $f (sort map { TeXLive::TLUtils::basename($_) } @runtime_files) {
- push (@duplicates, $f) if (($f eq $prev) and not ($f eq $duplicates[-1]));
- $prev = $f;
- }
- shift @duplicates; # get rid of the fake 1st value
-
- # check if duplicates are different files.
- foreach my $f (@duplicates) {
- # assume tex4ht, xdy, afm stuff is ok, and don't worry about
- # Changes, README et al. Other per-format versions, etc.
- next if $f =~ /\.(afm|cfg|dll|exe|4hf|htf|pm|xdy)$/;
- next if $f
- =~ /^((czech|slovak)\.sty
- |Changes
- |LICENSE.*
- |Makefile
- |README.*
- |a_.*\.enc
- |cid2code\.txt
- |context\.json
- |etex\.src
- |fithesis.*
- |u?kinsoku\.tex
- |language\.dat
- |language\.def
- |local\.mf
- |m-tex4ht\.tex
- |metatex\.tex
- |.*-noEmbed\.map
- |ps2mfbas\.mf
- |pstricks\.con
- |readme.*
- |sample\.bib
- |tex4ht\.env
- |test\.mf
- |texutil\.rb
- |tlmgrgui\.pl
- )$/x;
- # For the a_.* line above: source*pro has .enc files which differ
- # only in comments, hence the otftotfm-hashed name is the same.
- # Seems like it could happen more or at random with other fonts too.
- # Most font packagers nowadays insert a prefix to avoid this,
- # but older ones are not getting changed.
-
- # the files here were supposedly being dealt with in the next
- # release of their respective packages, but the releases are not
- # forthcoming, so just ignore them. They apparently make no
- # practical difference (maybe because of kpse's optimization of
- # preferring same-directory results). Latest report:
- # https://tug.org/pipermail/tex-live/2019-December/044530.html
- next if $f
- =~ /^( afoot\.sty
- |gamma\.mf
- |lexer\.lua
- |ligature\.mf
- |md-utrma\.pfb
- |ot1\.cmap
- |t1\.cmap
- )$/x;
-
- my @copies = grep (/\/$f$/, @runtime_files);
- # map files can be duplicated between (but not within) formats.
- if ($f =~ /\.map$/) {
- my $need_check = 0;
- my $prev_dir = "";
- my @cop = @copies; # don't break the outside list
- map { s#^texmf-dist/fonts/map/(.*?)/.*#$1# } @cop;
- foreach my $dir (sort @cop ) {
- last if ($need_check = ($dir eq $prev_dir));
- $prev_dir = $dir;
- }
- next unless $need_check;
- }
- # if all copies are identical, ok, else, complain
- my $diff = 0;
- for (my $i = 1; $i < scalar(@copies); $i++) {
- if ($diff = tlcmp("$Master/$copies[$i-1]", "$Master/$copies[$i]")) {
- print "# $f\ndiff $Master/$copies[$i-1] $Master/$copies[$i]\n";
- last;
- }
- }
- print join ("\n", @copies), "\n" if ($diff and (scalar(@copies) > 2));
- }
-}
-
-# check executes
-#
-sub check_executes {
- my $Master = $localtlpdb->root;
- my (%maps,%langcodes,%fmtlines);
- for my $pkg ($localtlpdb->list_packages) {
- for my $e ($localtlpdb->get_package($pkg)->executes) {
- if ($e =~ m/add(Mixed|Kanji)?Map\s+(.*)$/) {
- my $foo = $2;
- chomp($foo);
- if ($foo !~ m/\@(kanji|ja|tc|sc|ko)Embed@/) {
- push @{$maps{$foo}}, $pkg;
- }
- } elsif ($e =~ m/AddFormat\s+(.*)$/) {
- my $foo = $1;
- chomp($foo);
- push @{$fmtlines{$foo}}, $pkg;
- } elsif ($e =~ m/AddHyphen\s+.*\s+file=(\S+)(\s*$|\s+.*)/) {
- my $foo = $1;
- chomp($foo);
- push @{$langcodes{$foo}}, $pkg;
- } else {
- tlwarn("$prg: unmatched execute in $pkg: $e\n");
- }
- }
- }
- my %badmaps;
- foreach my $mf (keys %maps) {
- my @pkgsfound = @{$maps{$mf}};
- if ($#pkgsfound > 0) {
- tlwarn("$prg: map file $mf is referenced in the executes of @pkgsfound\n");
- } else {
- # less then 1 occurrences is not possible, so we have only one
- # package that contains the reference to that map file
- my $pkgfoundexecute = $pkgsfound[0];
- my @found = $localtlpdb->find_file($mf);
- if ($#found < 0) {
- $badmaps{$mf} = $maps{$mf};
- } elsif ($#found > 0) {
- # we want to check for multiple inclusions
- my %mapfn;
- foreach my $foo (@found) {
- $foo =~ m/^(.*):(.*)$/;
- push @{$mapfn{$2}}, $1;
- }
- foreach my $k (keys %mapfn) {
- my @bla = @{$mapfn{$k}};
- if ($#bla > 0) {
- tlwarn("$prg: map file $mf occurs multiple times (in pkgs: @bla)!\n");
- }
- }
- } else {
- # only one occurrence found, we check that the map is also contained
- # in the right package!
- my ($pkgcontained) = ( $found[0] =~ m/^(.*):.*$/ );
- if ($pkgcontained ne $pkgfoundexecute) {
- tlwarn("$prg: map file $mf: execute in $pkgfoundexecute, map file in $pkgcontained\n");
- }
- }
- }
- }
- if (keys %badmaps) {
- tlwarn("$prg: mentioned map file not present in any package:\n");
- foreach my $mf (keys %badmaps) {
- print "\t$mf (execute in @{$badmaps{$mf}})\n";
- }
- }
- my %badhyphcodes;
- my %problemhyphen;
- foreach my $lc (keys %langcodes) {
- next if ($lc eq "zerohyph.tex");
- my @found = $localtlpdb->find_file("texmf-dist/tex/generic/hyph-utf8/loadhyph/$lc");
- if ($#found < 0) {
- # try again this time search all packages
- my @found = $localtlpdb->find_file("$lc");
- if ($#found < 0) {
- $badhyphcodes{$lc} = $langcodes{$lc};
- } else {
- $problemhyphen{$lc} = [ @found ];
- }
- }
- }
- if (keys %badhyphcodes) {
- print "\f mentioned hyphen loaders without file:\n";
- foreach my $mf (keys %badhyphcodes) {
- print "\t$mf (execute in @{$badhyphcodes{$mf}})\n";
- }
- }
- # disable the echoing of problematic hyphens
- #if (keys %problemhyphen) {
- # print "hyphen files with possible problematic location:\n";
- # foreach my $mf (keys %problemhyphen) {
- # print "\t$mf (@{$problemhyphen{$mf}})\n";
- # }
- #}
- #
- # what should be checked for the executes? we could check
- # - the existence of the engine in bin/i386-linux or all $arch
- # - the existence of the format name link/bat
- # - parse the options parameter and check for the inifile
- # - rework the format definition that we have inifile=pdflatex.ini
- # isn't the * unnecessary?
- my %missingbins;
- my %missingengines;
- my %missinginis;
- my @archs_to_check = $localtlpdb->available_architectures;
- for (keys %fmtlines) {
- my %r = TeXLive::TLUtils::parse_AddFormat_line("$_");
- if (defined($r{"error"})) {
- die "$r{'error'}, parsing $_, package(s) @{$fmtlines{$_}}";
- }
- my $opt = $r{"options"};
- my $engine = $r{"engine"};
- my $name = $r{"name"};
- my $mode = $r{"mode"};
- ddebug("check_executes: fmtline name=$name engine=$engine"
- . " mode=$mode opt=$opt\n");
- next if ($name eq "cont-en"); # too confusing
- # we check that the name exist in bin/$arch
- if (",$TeXLive::TLConfig::PartialEngineSupport," =~ /,$engine,/) {
- # luajit[hb]tex is special since it is not available on all architectures
- # due to inherent reasons (machine code);
- #
- # We do not want to have error messages here, so we do the following:
- # * if tlpkg/tlpsrc/luajittex.tlpsrc is available, then load it
- # and filter away those archs that are excluded with f/!...
- # * similarly for the other partial-support engines; too much
- # trouble to reverse-map to package names, so just hardwire;
- # * if tlpkg/tlpsrc/<engine>.tlpsrc is *not* available (i.e., not
- # the development tree) we just ignore it completely.
- my $pkg;
- if ($engine =~ /luajit(hb)?tex/) {
- $pkg = "luajittex";
- } elsif ($engine eq "mfluajit") {
- $pkg = "mflua";
- } else {
- die "unknown partial engine $engine, goodbye"; # should not happen
- }
- my $tlpsrc_file = $localtlpdb->root . "/tlpkg/tlpsrc/$pkg.tlpsrc";
- if (-r $tlpsrc_file) {
- ddebug("check_executes: found $tlpsrc_file\n");
- require TeXLive::TLPSRC;
- my $tlpsrc = new TeXLive::TLPSRC;
- $tlpsrc->from_file($tlpsrc_file);
- my @binpats = $tlpsrc->binpatterns;
- my @negarchs = ();
- for my $p (@binpats) {
- if ($p =~ m%^(\w+)/(!?[-_a-z0-9,]+)\s+(.*)$%) {
- my $pt = $1;
- my $aa = $2;
- my $pr = $3;
- if ($pr =~ m!/$engine$!) {
- # bingo, get the negative patterns
- if ($aa =~ m/^!(.*)$/) {
- @negarchs = split(/,/,$1);
- ddebug("check_executes: negative arches: @negarchs\n");
- }
- }
- }
- }
- my @new_archs = ();
- for my $a (@archs_to_check) {
- push (@new_archs, $a) unless grep { $a eq $_ } @negarchs;
- }
- @archs_to_check = @new_archs;
- } else {
- @archs_to_check = (); # no tlpsrc, check nothing.
- }
- ddebug("check_executes: final arches to check: @archs_to_check\n");
- }
- for my $a (@archs_to_check) {
- my $f = "$Master/bin/$a/$name";
- if (!check_file($a, $f)) {
- push @{$missingbins{$_}}, "bin/$a/${name}[engine=$engine]" if $mode;
-# # unfortunately there are too many exceptions to this check:
-# # cygwin symlinks pointing to .exe names, pdcsplain extras, mptopdf,
-# # *latex-dev pointing to *latex instead of the binary. Instead of
-# # writing all those error-prone tests, just give up.
-# } elsif (-l $f) {
-# my $linktarget = readlink($f);
-# #ddebug("check_executes: linktarget $linktarget, $name->$engine\n");
-# if ($linktarget ne $engine) {
-# print "\t bin/$a/$name: symlink to $linktarget, not $engine\n";
-# }
-# } else {
-# ; #ddebug("check_executes: $f readable file, not a link\n");
- }
- if (!check_file($a, "$Master/bin/$a/$engine")) {
- push @{$missingengines{$_}}, "bin/$a/${engine}[fmt=$name]" if $mode;
- }
- }
- # check for the existence of the .ini file
- # by using the last word in the options value
- my $inifile = $opt;
- # $inifile now contains "bla bla bla *file.ini"
- # strip initial and trailing "
- $inifile =~ s/^"(.*)"$/$1/;
- # remove everything before the last space
- $inifile =~ s/^.* ([^ ]*)$/$1/;
- # remove the optional leading *
- $inifile =~ s/^\*//;
- my @found = $localtlpdb->find_file("$inifile");
- if ($#found < 0) {
- $missinginis{$_} = "$inifile";
- }
- }
- if (keys %missinginis) {
- print "\f mentioned ini files that cannot be found:\n";
- for my $i (sort keys %missinginis) {
- print "\t $missinginis{$i} (execute: $i)\n";
- }
- }
- if (keys %missingengines) {
- print "\f mentioned engine files that cannot be found:\n";
- for my $i (sort keys %missingengines) {
- print "\t @{$missingengines{$i}}\n";
- }
- }
- if (keys %missingbins) {
- print "\f mentioned bin files that cannot be found:\n";
- for my $i (sort keys %missingbins) {
- print "\t @{$missingbins{$i}}\n";
- }
- }
-}
-
-sub check_file {
- my ($a, $f) = @_;
- if (-r $f) {
- return 1;
- } else {
- # not -r, so check for the extensions .bat and .exe on windoze-ish.
- if ($a =~ /win[0-9]|.*-cygwin/) {
- if (-r "$f.exe" || -r "$f.bat") {
- return 1;
- }
- }
- return 0;
- }
-}
-
-# check depends
-#
-sub check_depends {
- my $ret = 0;
- my $Master = $localtlpdb->root;
- my %presentpkg;
- for my $pkg ($localtlpdb->list_packages) {
- $presentpkg{$pkg} = 1;
- }
- # list of collections.
- my @colls = $localtlpdb->collections;
- my @coll_deps
- = $localtlpdb->expand_dependencies("-no-collections", $localtlpdb, @colls);
- my %coll_deps;
- @coll_deps{@coll_deps} = (); # initialize hash with keys from list
-
- my (%wrong_dep, @no_dep);
- for my $pkg ($localtlpdb->list_packages) {
- # do not check any package starting with 00texlive.
- next if $pkg =~ m/^00texlive/;
-
- # For each package, check that it is a dependency of some collection.
- if (! exists $coll_deps{$pkg}) {
- # Except that schemes and our ugly Windows packages are ok.
- push (@no_dep, $pkg) unless $pkg =~/^scheme-|\.win32$/;
- }
-
- # For each dependency, check that we have a package.
- for my $d ($localtlpdb->get_package($pkg)->depends) {
- next if ($d =~ m/\.ARCH$/);
- if (!defined($presentpkg{$d})) {
- push (@{$wrong_dep{$d}}, $pkg);
- }
- }
- }
-
- # check whether packages are included more than one time in a collection
- my %pkg2mother;
- for my $c (@colls) {
- for my $p ($localtlpdb->get_package($c)->depends) {
- next if ($p =~ /^collection-/);
- push @{$pkg2mother{$p}}, $c;
- }
- }
- my @double_inc_pkgs;
- for my $k (keys %pkg2mother) {
- if (@{$pkg2mother{$k}} > 1) {
- push @double_inc_pkgs, $k;
- }
- }
-
- if (keys %wrong_dep) {
- $ret++;
- print "\f DEPENDS WITHOUT PACKAGES:\n";
- for my $d (keys %wrong_dep) {
- print "$d in: @{$wrong_dep{$d}}\n";
- }
- }
-
- if (@no_dep) {
- $ret++;
- print "\f PACKAGES NOT IN ANY COLLECTION: @no_dep\n";
- }
-
- if (@double_inc_pkgs) {
- $ret++;
- print "\f PACKAGES IN MORE THAN ONE COLLECTION: @double_inc_pkgs\n";
- }
-
- return $ret;
-}
-
-# check texmfdbs -- that !! paths have an ls-R and are in TEXMFDBS,
-# and that trees with an ls-R specify !!.
-#
-sub check_texmfdbs {
- my $texmfdbs = `kpsewhich -var-value TEXMFDBS`;
- my @tfmdbs = glob $texmfdbs;
- my $tfms = `kpsewhich -var-value TEXMF`;
- my @tfms = glob $tfms;
- my %tfmdbs;
- my $ret = 0;
-
- debug("Checking TEXMFDBS\n");
- for my $p (@tfmdbs) {
- debug(" $p\n");
- if ($p !~ m/^!!/) {
- tlwarn("$prg: item $p in TEXMFDBS does not have leading !!\n");
- $ret++;
- }
- $p =~ s/^!!//;
- $tfmdbs{$p} = 1;
- if (-d $p && ! -r "$p/ls-R") {
- tlwarn("$prg: item $p in TEXMFDBS does not have an associated ls-R file\n");
- $ret++;
- }
- }
-
- debug("Checking TEXMF\n");
- for my $p (@tfms) {
- debug(" $p\n");
- my $pnobang = $p;
- $pnobang =~ s/^!!//;
- if (! $tfmdbs{$pnobang}) {
- if ($p =~ m/^!!/) {
- tlwarn("$prg: tree $p in TEXMF not in TEXMFDBS, but has !!\n");
- $ret++;
- }
- if (-r "$pnobang/ls-R") {
- tlwarn("$prg: tree $p in TEXMF not in TEXMFDBS, but has ls-R file\n");
- $ret++;
- }
- }
- }
- return($ret);
-}
-
-# POSTACTION
-#
-# explicitly run the various post actions, e.g.,
-# on a client system or overriding global settings.
-#
-# tlmgr postaction [--w32mode=user|admin] [--fileassocmode=1|2] [--all]
-# [install|remove] [shortcut|fileassoc|script] [<pkg>...]
-
-sub action_postaction {
- my $how = shift @ARGV;
- if (!defined($how) || ($how !~ m/^(install|remove)$/i)) {
- tlwarn("$prg: action postaction needs at least two arguments, first being either 'install' or 'remove'\n");
- return;
- }
- my $type = shift @ARGV;
- my $badtype = 0;
- if (!defined($type)) {
- $badtype = 1;
- } elsif ($type !~ m/^(shortcut|fileassoc|script)$/i) {
- $badtype = 1;
- }
- if ($badtype) {
- tlwarn("$prg: action postaction needs as second argument one from 'shortcut', 'fileassoc', 'script'\n");
- return;
- }
- if (win32()) {
- if ($opts{"w32mode"}) {
- if ($opts{"w32mode"} eq "user") {
- if (TeXLive::TLWinGoo::admin()) {
- debug("Switching to user mode on user request\n");
- TeXLive::TLWinGoo::non_admin();
- }
- # in user mode we also switch TEXMFSYSVAR to TEXMFVAR since
- # xetex.pl, but maybe others are writing to TEXMFSYSVAR
- chomp($ENV{"TEXMFSYSVAR"} = `kpsewhich -var-value TEXMFVAR`);
- } elsif ($opts{"w32mode"} eq "admin") {
- if (!TeXLive::TLWinGoo::admin()) {
- tlwarn("$prg: you don't have the permissions for --w32mode=admin\n");
- return;
- }
- } else {
- tlwarn("$prg: action postaction --w32mode can only be 'admin' or 'user'\n");
- return;
- }
- }
- }
- my @todo;
- if ($opts{"all"}) {
- init_local_db();
- @todo = $localtlpdb->list_packages;
- } else {
- if ($#ARGV < 0) {
- tlwarn("$prg: action postaction: need either --all or a list of packages\n");
- return;
- }
- init_local_db();
- @todo = @ARGV;
- @todo = $localtlpdb->expand_dependencies("-only-arch", $localtlpdb, @todo);
- }
- if ($type =~ m/^shortcut$/i) {
- if (!win32()) {
- tlwarn("$prg: action postaction shortcut only works on windows.\n");
- return;
- }
- for my $p (@todo) {
- my $tlp = $localtlpdb->get_package($p);
- if (!defined($tlp)) {
- tlwarn("$prg: $p is not installed, ignoring it.\n");
- } else {
- # run all shortcut actions, desktop and menu integration
- TeXLive::TLUtils::do_postaction($how, $tlp, 0, 1, 1, 0);
- }
- }
- } elsif ($type =~ m/^fileassoc$/i) {
- if (!win32()) {
- tlwarn("$prg: action postaction fileassoc only works on windows.\n");
- return;
- }
- my $fa = $localtlpdb->option("file_assocs");
- if ($opts{"fileassocmode"}) {
- if ($opts{"fileassocmode"} < 1 || $opts{"fileassocmode"} > 2) {
- tlwarn("$prg: action postaction: value of --fileassocmode can only be 1 or 2\n");
- return;
- }
- $fa = $opts{"fileassocmode"};
- }
- for my $p (@todo) {
- my $tlp = $localtlpdb->get_package($p);
- if (!defined($tlp)) {
- tlwarn("$prg: $p is not installed, ignoring it.\n");
- } else {
- TeXLive::TLUtils::do_postaction($how, $tlp, $fa, 0, 0, 0);
- }
- }
- } elsif ($type =~ m/^script$/i) {
- for my $p (@todo) {
- my $tlp = $localtlpdb->get_package($p);
- if (!defined($tlp)) {
- tlwarn("$prg: $p is not installed, ignoring it.\n");
- } else {
- TeXLive::TLUtils::do_postaction($how, $tlp, 0, 0, 0, 1);
- }
- }
- } else {
- tlwarn("$prg: action postaction needs one of 'shortcut', 'fileassoc', 'script'\n");
- return;
- }
-}
-
-
-# INIT-USERTREE
-#
-# sets up the user tree for tlmgr in user mode
-sub action_init_usertree {
- # init_local_db but do not die if localtlpdb is not found!
- init_local_db(2);
- my $tlpdb = TeXLive::TLPDB->new;
- my $usertree;
- if ($opts{"usertree"}) {
- $usertree = $opts{"usertree"};
- } else {
- chomp($usertree = `kpsewhich -var-value TEXMFHOME`);
- }
- if (-r "$usertree/$InfraLocation/$DatabaseName") {
- tldie("$prg: user mode database already set up in\n$prg: $usertree/$InfraLocation/$DatabaseName\n$prg: not overwriting it.\n");
- }
- $tlpdb->root($usertree);
- # copy values from main installation over
- my $maininsttlp;
- my $inst;
- if (defined($localtlpdb)) {
- $maininsttlp = $localtlpdb->get_package("00texlive.installation");
- $inst = $maininsttlp->copy;
- } else {
- $inst = TeXLive::TLPOBJ->new;
- $inst->name("00texlive.installation");
- $inst->category("TLCore");
- }
- $tlpdb->add_tlpobj($inst);
- # remove all available architectures
- $tlpdb->setting( "available_architectures", "");
- $tlpdb->option( "location", $TeXLive::TLConfig::TeXLiveURL);
- # specify that we are in user mode
- $tlpdb->setting( "usertree", 1 );
- $tlpdb->save;
- #
- # we need to create web2c dir for TLMedia to succeed setting up
- # and for tlmgr.log file
- mkdir ("$usertree/web2c");
- mkdir ("$usertree/tlpkg/tlpobj");
- return ($F_OK);
-}
-
-
-# CONF
-#
-# tries to mimic texconfig conf but can also set values for both tlmgr
-# and texmf conf files.
-#
-sub action_conf {
- my $arg = shift @ARGV;
- my $ret = $F_OK;
-
- if (!defined($arg)) {
- texconfig_conf_mimic();
-
- } elsif ($arg !~ /^(tlmgr|texmf|updmap|auxtrees)$/) {
- warn "$prg: unknown conf arg: $arg (try tlmgr or texmf or updmap or auxtrees)\n";
- return($F_ERROR);
-
- } else {
- my ($fn,$cf);
- if ($opts{'conffile'}) {
- $fn = $opts{'conffile'} ;
- }
- if ($arg eq "tlmgr") {
- chomp (my $TEXMFCONFIG = `kpsewhich -var-value=TEXMFCONFIG`);
- $fn || ( $fn = "$TEXMFCONFIG/tlmgr/config" ) ;
- $cf = TeXLive::TLConfFile->new($fn, "#", "=");
- } elsif ($arg eq "texmf" || $arg eq "auxtrees") {
- $fn || ( $fn = "$Master/texmf.cnf" ) ;
- $cf = TeXLive::TLConfFile->new($fn, "[%#]", "=");
- } elsif ($arg eq "updmap") {
- $fn || ( chomp ($fn = `kpsewhich updmap.cfg`) ) ;
- $cf = TeXLive::TLConfFile->new($fn, '(#|(Mixed)?Map)', ' ');
- } else {
- die "Should not happen, conf arg=$arg";
- }
- my ($key,$val) = @ARGV;
- # make sure that in case of tlmgr conf auxtrees (without anything else)
- # we add the "show" argument which makes it easier to do stuff.
- $key = "show" if ($arg eq "auxtrees" && !defined($key));
-
- if (!defined($key)) {
- # show all settings (not auxtrees case!)
- if ($cf) {
- info("$arg configuration values (from $fn):\n");
- for my $k ($cf->keys) {
- info("$k = " . $cf->value($k) . "\n");
- }
- } else {
- info("$prg: $arg config file $fn not present\n");
- return($F_WARNING);
- }
- } else {
- if ($arg eq "auxtrees") {
- my $tmfa = 'TEXMFAUXTREES';
- my $tv = $cf->value($tmfa);
- if (!$key || $key eq "show") {
- if (defined($tv)) {
- $tv =~ s/^\s*//;
- $tv =~ s/\s*$//;
- $tv =~ s/,$//;
- my @foo = split(',', $tv);
- print "List of auxiliary texmf trees:\n" if (@foo);
- for my $f (@foo) {
- print " $f\n";
- }
- return($F_OK);
- } else {
- print "$prg: no auxiliary texmf trees defined.\n";
- return($F_OK);
- }
- } elsif ($key eq "add") {
- if (defined($val)) {
- if (defined($tv)) {
- $tv =~ s/^\s*//;
- $tv =~ s/\s*$//;
- $tv =~ s/,$//;
- my @foo = split(',', $tv);
- my @new;
- my $already = 0;
- for my $f (@foo) {
- if ($f eq $val) {
- tlwarn("$prg: already registered auxtree: $val\n");
- return ($F_WARNING);
- } else {
- push @new, $f;
- }
- }
- push @new, $val;
- $cf->value($tmfa, join(',', @new) . ',');
- } else {
- $cf->value($tmfa, $val . ',');
- }
- } else {
- tlwarn("$prg: missing argument for auxtrees add\n");
- return($F_ERROR);
- }
- } elsif ($key eq "remove") {
- if (defined($val)) {
- if (defined($tv)) {
- $tv =~ s/^\s*//;
- $tv =~ s/\s*$//;
- $tv =~ s/,$//;
- my @foo = split(',', $tv);
- my @new;
- my $removed = 0;
- for my $f (@foo) {
- if ($f ne $val) {
- push @new, $f;
- } else {
- $removed = 1;
- }
- }
- if ($removed) {
- if ($#new >= 0) {
- $cf->value($tmfa, join(',', @new) . ',');
- } else {
- $cf->delete_key($tmfa);
- }
- } else {
- tlwarn("$prg: not defined as auxiliary texmf tree: $val\n");
- return($F_WARNING);
- }
- } else {
- tlwarn("$prg: no auxiliary texmf trees defined, "
- . "so nothing removed\n");
- return($F_WARNING);
- }
- } else {
- tlwarn("$prg: missing argument for auxtrees remove\n");
- return($F_ERROR);
- }
- } else {
- tlwarn("$prg: unknown auxtrees operation: $key\n");
- return($F_ERROR);
- }
- } elsif (!defined($val)) {
- if (defined($opts{'delete'})) {
- if (defined($cf->value($key))) {
- info("$prg: removing setting $arg $key value: " . $cf->value($key)
- . "from $fn\n");
- $cf->delete_key($key);
- } else {
- info("$prg: $arg $key not defined, cannot remove ($fn)\n");
- $ret = $F_WARNING;
- }
- } else {
- if (defined($cf->value($key))) {
- info("$prg: $arg $key value: " . $cf->value($key) . " ($fn)\n");
- } else {
- info("$prg: $key not defined in $arg config file ($fn)\n");
- if ($arg eq "texmf") {
- # not in user-specific file, show anything kpsewhich gives us.
- chomp (my $defval = `kpsewhich -var-value $key`);
- if ($? != 0) {
- info("$prg: $arg $key default value is unknown");
- } else {
- info("$prg: $arg $key default value: $defval");
- }
- info(" (from kpsewhich -var-value)\n");
- }
- }
- }
- } else {
- if (defined($opts{'delete'})) {
- tlwarn("$arg --delete and value for key $key given, don't know what to do!\n");
- $ret = $F_ERROR;
- } else {
- info("$prg: setting $arg $key to $val (in $fn)\n");
- $cf->value($key, $val);
- }
- }
- }
- if ($cf->is_changed) {
- $cf->save;
- }
- }
- return($ret);
-}
-
-# output various values in same form as texconfig conf.
-sub texconfig_conf_mimic {
- my $PATH = $ENV{'PATH'};
- info("=========================== version information ==========================\n");
- info(give_version());
- info("==================== executables found by searching PATH =================\n");
- info("PATH: $PATH\n");
- for my $cmd (sort(qw/kpsewhich updmap fmtutil tlmgr tex pdftex luatex xetex
- mktexpk dvips dvipdfmx/)) {
- info(sprintf("%-10s %s\n", "$cmd:", TeXLive::TLUtils::which($cmd)));
- }
- info("=========================== active config files ==========================\n");
- for my $m (sort(qw/fmtutil.cnf config.ps mktex.cnf pdftexconfig.tex/)) {
- info(sprintf("%-17s %s", "$m:", `kpsewhich $m`));
- }
- for my $m (qw/texmf.cnf updmap.cfg/) {
- for my $f (`kpsewhich -all $m`) {
- info(sprintf("%-17s %s", "$m:", $f));
- }
- }
-
- #tlwarn("$prg: missing finding of XDvi, config!\n");
-
- info("============================= font map files =============================\n");
- for my $m (sort(qw/psfonts.map pdftex.map ps2pk.map kanjix.map/)) {
- info(sprintf("%-12s %s", "$m:", `kpsewhich $m`));
- }
-
- info("=========================== kpathsea variables ===========================\n");
- for my $v (sort(qw/TEXMFMAIN TEXMFDIST TEXMFLOCAL TEXMFSYSVAR TEXMFSYSCONFIG TEXMFVAR TEXMFCONFIG TEXMFHOME VARTEXFONTS TEXMF SYSTEXMF TEXMFDBS WEB2C TEXPSHEADERS TEXCONFIG ENCFONTS TEXFONTMAPS/)) {
- info("$v=" . `kpsewhich -var-value=$v`);
- }
-
- info("==== kpathsea variables from environment only (ok if no output here) ====\n");
- my @envVars = qw/
- AFMFONTS BIBINPUTS BSTINPUTS CMAPFONTS CWEBINPUTS ENCFONTS GFFONTS
- GLYPHFONTS INDEXSTYLE LIGFONTS MFBASES MFINPUTS MFPOOL MFTINPUTS
- MISCFONTS MPINPUTS MPMEMS MPPOOL MPSUPPORT OCPINPUTS OFMFONTS
- OPENTYPEFONTS OPLFONTS OTPINPUTS OVFFONTS OVPFONTS PDFTEXCONFIG PKFONTS
- PSHEADERS SFDFONTS T1FONTS T1INPUTS T42FONTS TEXBIB TEXCONFIG TEXDOCS
- TEXFONTMAPS TEXFONTS TEXFORMATS TEXINDEXSTYLE TEXINPUTS TEXMFCNF
- TEXMFDBS TEXMFINI TEXMFSCRIPTS TEXPICTS TEXPKS TEXPOOL TEXPSHEADERS
- TEXSOURCES TFMFONTS TRFONTS TTFONTS VFFONTS WEB2C WEBINPUTS
- /;
- for my $v (@envVars) {
- if (defined($ENV{$v})) {
- info("$v=$ENV{$v}\n");
- }
- }
-}
-
-
-# KEY
-#
-# gpg key management:
-# tlmgr key list
-# tlmgr key add <filename>
-# tlmgr key remove <keyid>
-#
-sub action_key {
- my $arg = shift @ARGV;
-
- if (!defined($arg)) {
- tlwarn("missing arguments to action `key'\n");
- return $F_ERROR;
- }
-
- $arg = lc($arg);
- if ($arg =~ /^(add|remove|list)$/) {
- handle_gpg_config_settings();
- if (!$::gpg) {
- tlwarn("gnupg is not found or not set up, cannot continue with action `key'\n");
- return $F_ERROR;
- }
- chomp (my $TEXMFSYSCONFIG = `kpsewhich -var-value=TEXMFSYSCONFIG`);
- my $local_keyring = "$Master/tlpkg/gpg/repository-keys.gpg";
- if ($arg eq 'list') {
- debug("running $::gpg --list-keys\n");
- system("$::gpg --list-keys");
- return $F_OK;
- } elsif ($arg eq 'remove') {
- my $what = shift @ARGV;
- if (!$what) {
- tlwarn("missing argument to `key remove'\n");
- return $F_ERROR;
- }
- # we need to make sure that $local_keyring exists.
- if (! -r $local_keyring) {
- tlwarn("no local keyring available, cannot remove!\n");
- return $F_ERROR;
- }
- debug("running: $::gpg --primary-keyring repository-keys.gpg --delete-key $what\n");
- my ($out, $ret) =
- TeXLive::TLUtils::run_cmd("$::gpg --primary-keyring repository-keys.gpg --delete-key \"$what\" 2>&1");
- if ($ret == 0) {
- info("$prg: key successfully removed\n");
- return $F_OK;
- } else {
- tlwarn("$prg: key removal failed, output:\n$out\n");
- return $F_ERROR;
- }
-
- } elsif ($arg eq 'add') {
- my $what = shift @ARGV;
- if (!$what) {
- tlwarn("$prg: missing argument to `key add'\n");
- return $F_ERROR;
- }
- # we need to make sure that $local_keyring is existent!
- if (! -r $local_keyring) {
- open(FOO, ">$local_keyring") || die("Cannot create $local_keyring: $!");
- close(FOO);
- }
- debug("running: $::gpg --primary-keyring repository-keys.gpg --import $what\n");
- my ($out, $ret) =
- TeXLive::TLUtils::run_cmd("$::gpg --primary-keyring repository-keys.gpg --import \"$what\" 2>&1");
- if ($ret == 0) {
- info("$prg: key successfully imported\n");
- return $F_OK;
- } else {
- tlwarn("$prg: key import failed, output:\n$out\n");
- return $F_ERROR;
- }
- } else {
- tldie("$prg: should not be reached: tlmgr key $arg\n");
- }
-
- } else {
- tlwarn("$prg: unknown directive `$arg' to action `key'\n");
- return $F_ERROR;
- }
- return $F_OK;
-}
-
-
-# SHELL
-# interactive shell.
-#
-sub action_shell {
- my $protocol = 1;
- my $default_prompt = "tlmgr>";
- # keys which can be set/get and are also settable via global cmdline opts
- my @valid_bool_keys
- = qw/debug-translation machine-readable no-execute-actions
- verify-repo json/;
- my @valid_string_keys = qw/repository prompt/;
- my @valid_keys = (@valid_bool_keys, @valid_string_keys);
- # set auto flush unconditionally in action shell
- $| = 1;
- # we need to do an anonymous sub here otherwise the $default_prompt will get
- # only fixed once and remain forever. With anonymous subs it is rebound
- # on every call!
- my $do_prompt;
- $do_prompt = sub {
- my $prompt = "";
- my @options;
- my @guarantee;
- my @savedargs = @_;
- my $did_prompt = 0;
- while (defined(my $arg = shift @_)) {
- if ($arg =~ m/^-prompt$/) {
- # only do allow for prompt rewriting in case of ! machine readable!
- if (!$::machinereadable) {
- print shift @_, " ";
- $did_prompt = 1;
- }
- } elsif ($arg =~ m/^-menu$/) {
- my $options = shift @_;
- @options = @$options;
- print "\n";
- my $c = 1;
- for my $o (@options) {
- print " $c) $o\n";
- $c++;
- }
- } elsif ($arg =~ m/^-guarantee$/) {
- my $guarantee = shift @_;
- @guarantee = @$guarantee;
- } elsif ($arg =~ m/^-/) {
- print "ERROR unsupported prompt command, please report: $arg!\n";
- } else {
- # only do allow for prompt rewriting in case of ! machine readable!
- if (!$::machinereadable) {
- print $arg, " ";
- $did_prompt = 1;
- }
- }
- }
- print "$default_prompt " if (!$did_prompt);
- # to make sure that flushing is done properly, we ship out
- # a new line in buffer mode:
- print "\n" if $::machinereadable;
- my $ans = <STDIN>;
- if (!defined($ans)) {
- # we got Ctrl-D, just break out
- return;
- }
- chomp($ans);
- if (@options) {
- if ($ans =~ /^[0-9]+$/ && 0 <= $ans - 1 && $ans - 1 <= $#options) {
- $ans = $options[$ans - 1];
- } else {
- print "ERROR invalid answer $ans\n";
- # return empty string so caller knows not to continue
- $ans = "";
- }
- }
- if (@guarantee) {
- my $isok = 0;
- for my $g (@guarantee) {
- if ($ans eq $g) {
- $isok = 1;
- last;
- }
- }
- if (!$isok) {
- print("Please answer one of: @guarantee\n");
- print "\n" if $::machinereadable;
- return(&$do_prompt(@savedargs));
- }
- }
- return($ans);
- };
-
- print "protocol $protocol\n";
- while (1) {
- my $ans = &$do_prompt($default_prompt);
- return $F_OK if !defined($ans); # done if eof
-
- my ($cmd, @args) = TeXLive::TLUtils::quotewords('\s+', 0, $ans);
- next if (!defined($cmd));
- if ($cmd eq "protocol") {
- print "protocol $protocol\n";
- } elsif ($cmd eq "help") {
- print "Please see tlmgr help or https://tug.org/texlive/tlmgr.html.\n";
- } elsif ($cmd eq "version") {
- print give_version();
- } elsif ($cmd =~ m/^(quit|end|bye(bye)?)$/i) {
- return $F_OK;
- } elsif ($cmd eq "setup-location") {
- my $dest = shift @args;
- print "ERROR not implemented: $cmd\n";
- } elsif ($cmd eq "restart") {
- exec("tlmgr", @::SAVEDARGV);
-
- } elsif ($cmd =~ m/^(set|get)$/) {
- #
- my $key = shift @args;
- my $val = shift @args;
- if (!$key) {
- $key = &$do_prompt('Choose one of...', -menu => \@valid_keys, '>');
- }
- if (!$key) {
- print("ERROR missing key argument for get/set\n");
- next;
- }
- if ($cmd eq "get" && defined($val)) {
- print("ERROR argument not allowed for get: $val\n");
- next;
- }
- if ($cmd eq "set" && !defined($val)) {
- if ($key eq "repository") {
- $val = &$do_prompt('Enter repository:');
- } elsif ($key eq "prompt") {
- $val = &$do_prompt('Enter new prompt:');
- } else {
- $val = &$do_prompt('Enter 1 for on, 0 for off:', -guarantee => [0,1]);
- }
- # deal with Ctrl-D
- if (!defined($val)) {
- print("ERROR missing value for set\n");
- next;
- }
- }
-
- if ($key eq "repository") {
- if ($cmd eq "set") {
- $location = scalar($val);
- } else {
- if (defined($location) && $location) {
- print "repository = $location\n";
- } else {
- print "repository = <UNDEFINED>\n";
- }
- }
- print "OK\n";
- } elsif ($key eq "prompt") {
- if ($cmd eq "set") {
- $default_prompt = scalar($val);
- } else {
- print "Current prompt: $default_prompt (but you know that, or?)\n";
- }
- print "OK\n";
- } elsif (TeXLive::TLUtils::member($key, @valid_bool_keys)) {
- if ($cmd eq "set") {
- if ($val eq "0") {
- $opts{$key} = 0;
- } elsif ($val eq "1") {
- $opts{$key} = 1;
- } else {
- print "ERROR invalid value $val for key $key\n";
- next;
- }
- # special cases
- $::debug_translation = $opts{"debug-translation"};
- $::machinereadable = $opts{"machine-readable"};
- $::no_execute_actions = $opts{'no-execute-actions'};
- } else {
- print "$key = ", ($opts{$key} ? 1 : 0), "\n";
- }
- print "OK\n";
- } else {
- print "ERROR unknown get/set key $key\n";
- }
- } elsif ($cmd eq "load") {
- my $what = shift @args;
- if (!defined($what)) {
- $what = &$do_prompt("Choose...", -menu => ['local', 'remote'], '>');
- }
- if ($what eq "local") {
- init_local_db();
- print "OK\n";
- } elsif ($what eq "remote") {
- my ($ret, $err) = init_tlmedia();
- if ($ret) {
- print("OK\n");
- } else {
- if ($::machinereadable) {
- # replace \n with \\n to get single line
- $err =~ s/\n/\\n/g;
- }
- print("ERROR $err\n");
- }
- } else {
- print "ERROR can only load 'local' or 'remote', not $what\n";
- }
- } elsif ($cmd eq "save") {
- $localtlpdb->save;
- print "OK\n";
- } elsif (defined($action_specification{$cmd})) {
- # an action
- if (!defined($action_specification{$cmd}{"function"})) {
- print "ERROR undefined action function $cmd\n";
- next;
- }
- # redo the option parsing
- my %optarg;
- for my $k (@valid_bool_keys) {
- if ($globaloptions{$k} eq "1") {
- $optarg{$k} = 1;
- } else {
- $optarg{"$k" . $globaloptions{$k}} = 1;
- }
- }
- if (defined($action_specification{$cmd}{'options'})) {
- my %actopts = %{$action_specification{$cmd}{'options'}};
- for my $k (keys %actopts) {
- if ($actopts{$k} eq "1") {
- $optarg{$k} = 1;
- } else {
- $optarg{"$k" . $actopts{$k}} = 1;
- }
- }
- }
- # save command line options for later restart, if necessary
- @ARGV = @args;
- my %savedopts = %opts;
- %opts = ();
- # stuff global options back into the %opts array
- for my $k (@valid_keys) {
- $opts{$k} = $savedopts{$k} if (exists($savedopts{$k}));
- }
- if (!GetOptions(\%opts, keys(%optarg))) {
- print "ERROR unsupported arguments\n";
- next;
- }
- my $ret = execute_action($cmd, @ARGV);
- if ($ret & $F_ERROR) {
- print "ERROR\n";
- } elsif ($ret & $F_WARNING) {
- print "OK\n";
- } else {
- print "OK\n";
- }
- # make sure that we restart after having called update --self!
- if (($cmd eq 'update') && $opts{'self'} && !$opts{'no-restart'}) {
- print "tlmgr has been updated, restarting!\n";
- exec("tlmgr", @::SAVEDARGV);
- }
- %opts = %savedopts;
- } else {
- print "ERROR unknown command $cmd\n";
- }
- }
-}
-
-
-
-# Subroutines galore.
-#
-# set global $location variable.
-#
-# argument $should_i_die specifies what is required
-# to succeed during initialization.
-#
-# undef or false: TLPDB needs to be found and initialized, but
-# support programs need not be found
-# 1 : TLPDB initialized and support programs must work
-# 2 : not even TLPDB needs to be found
-# if we cannot read tlpdb, die if arg SHOULD_I_DIE is true.
-#
-sub init_local_db {
- my ($should_i_die) = @_;
- defined($should_i_die) or ($should_i_die = 0);
- # if the localtlpdb is already defined do simply return here already
- # to make sure that the settings in the local tlpdb do not overwrite
- # stuff changed via the GUI
- return if defined $localtlpdb;
- $localtlpdb = TeXLive::TLPDB->new ( root => $::maintree );
- if (!defined($localtlpdb)) {
- if ($should_i_die == 2) {
- return undef;
- } else {
- die("cannot setup TLPDB in $::maintree");
- }
- }
- # setup the programs, for w32 we need the shipped wget/xz etc, so we
- # pass the location of these files to setup_programs.
- if (!setup_programs("$Master/tlpkg/installer", $localtlpdb->platform)) {
- tlwarn("$prg: Couldn't set up the necessary programs.\nInstallation of packages is not supported.\nPlease report to texlive\@tug.org.\n");
- if (defined($should_i_die) && $should_i_die) {
- die("$prg: no way to continue!\n");
- } else {
- tlwarn("$prg: Continuing anyway ...\n");
- return ($F_WARNING);
- }
- }
- # let cmd line options override the settings in localtlpdb
- my $loc = norm_tlpdb_path($localtlpdb->option("location"));
- if (defined($loc)) {
- $location = $loc;
- }
- if (defined($opts{"location"})) {
- $location = $opts{"location"};
- }
- if (!defined($location)) {
- die("$prg: No installation source found: neither in texlive.tlpdb nor on command line.\n$prg: Please specify one!");
- }
- if ($location =~ m/^ctan$/i) {
- $location = "$TeXLive::TLConfig::TeXLiveURL";
- }
- # we normalize the path only if it is
- # - a url starting with neither http or ftp
- # - if we are on Windows, it does not start with Drive:[\/]
- if (! ( $location =~ m!^(https?|ftp)://!i ||
- $location =~ m!$TeXLive::TLUtils::SshURIRegex!i ||
- (win32() && (!(-e $location) || ($location =~ m!^.:[\\/]!) ) ) ) ) {
- # seems to be a local path, try to normalize it
- my $testloc = abs_path($location);
- # however, if we were given a url, that will get "normalized" to the
- # empty string, it not being a path. Restore the original value if so.
- $location = $testloc if $testloc;
- }
-}
-
-sub handle_gpg_config_settings {
- # setup gpg if available
- # by default we setup gpg
- # default value
- my $do_setup_gpg = "main";
- # the value is set in the config file
- if (defined($config{'verify-repo'})) {
- $do_setup_gpg = $config{'verify-repo'};
- }
- # command line
- if (defined($opts{'verify-repo'})) {
- $do_setup_gpg = $opts{'verify-repo'};
- }
- # now we know whether we setup gpg or not
- if ($do_setup_gpg ne "none") {
- if (TeXLive::TLCrypto::setup_gpg($Master)) {
- debug("will verify cryptographic signatures\n")
- } else {
- my $prefix = "$prg: No gpg found"; # just to shorten the strings
- if (defined($opts{'verify-repo'}) && $opts{'verify-repo'} eq "all") {
- # verification requested on the command line, but did not succeed: die
- tldie("$prefix, verification explicitly requested on command line, quitting.\n");
- }
- if (defined($config{'verify-repo'}) && $config{'verify-repo'} eq "all") {
- # verification explicitly requested in config file, but not gpg, die
- tldie("$prefix, verification explicitly requested in config file, quitting.\n");
- }
- # it was requested via the default setting, so just debug it
- # the list of repositories will contain verified/not verified statements
- debug ("$prefix, verification implicitly requested, "
- . "continuing without verification\n");
- }
- } else {
- # we do not setup gpg: when explicitly requested, be silent, otherwise info
- my $prefix = "$prg: not setting up gpg";
- if (defined($opts{'verify-repo'})) {
- # log normally is *NOT* logged to a file
- # tlmgr does by default *NOT* set up a log file (cmd line option)
- # user requested it, so don't bother with output
- debug("$prefix, requested on command line\n");
- } elsif (defined($config{'verify-repo'})) {
- debug("$prefix, requested in config file\n");
- } else {
- tldie("$prg: how could this happen? gpg setup.\n");
- }
- }
-}
-
-# initialize the global $remotetlpdb object, or die.
-# uses the global $location.
-#
-sub init_tlmedia_or_die {
- my $silent = shift;
- $silent = ($silent ? 1 : 0);
- my ($ret, $err) = init_tlmedia($silent);
- if (!$ret) {
- tldie("$prg: $err\n");
- }
-}
-
-sub init_tlmedia {
- my $silent = shift;
- # first check if $location contains multiple locations
- # in this case we go to virtual mode
- #my %repos = repository_to_array($localtlpdb->option("location"));
- my %repos = repository_to_array($location);
- my @tags = keys %repos;
- # if we have only one repo, but this one contains a name tag #....
- # then we remove it and save the local tlpdb
- if ($#tags == 0 && ($location =~ m/#/)) {
- $location = $repos{$tags[0]};
- $localtlpdb->option("location", $location);
- $localtlpdb->save;
- %repos = repository_to_array($location);
- }
-
- # checksums and gpg stuff
- if (TeXLive::TLCrypto::setup_checksum_method()) {
- # it is only possible to do gpg verification if we can
- # find a checksum method
- # do the gpg stuff only when loading the remote tlpdb
- handle_gpg_config_settings();
- } else {
- if (!$config{'no-checksums'}) {
- tlwarn(<<END_NO_CHECKSUMS);
-$prg: warning: Cannot find a checksum implementation.
-Please install Digest::SHA (from CPAN), openssl, or sha512sum.
-To silence this warning, set no-checksums in the tlmgr configuration
-file, e.g., by running:
- tlmgr conf tlmgr no-checksums 1
-Continuing without checksum verifications ...
-
-END_NO_CHECKSUMS
- }
- }
-
- # check if we are only one tag/repo
- if ($#tags == 0) {
- # go to normal mode
- return _init_tlmedia($silent);
- }
- # we are still here, so we have more tags
-
- # check that there is a main repository
- if (!TeXLive::TLUtils::member('main', @tags)) {
- return(0, "Cannot find main repository, you have to tag one as main!");
- }
-
- # TODO TODO
- # - abstract the set up of a single media tlpdb
- # - make clear how to check for a already loaded remotetlpdb
- $remotetlpdb = TeXLive::TLPDB->new();
- $remotetlpdb->make_virtual;
-
- my $locstr = $repos{'main'};
- my ($tlmdb, $errormsg) = setup_one_remotetlpdb($locstr, 'main');
- if (!defined($tlmdb)) {
- return (0, $errormsg);
- }
- $remotetlpdb->virtual_add_tlpdb($tlmdb, "main");
- for my $t (@tags) {
- if ($t ne 'main') {
- my ($tlmdb, $errormsg) = setup_one_remotetlpdb($repos{$t});
- if (!defined($tlmdb)) {
- return(0, $errormsg);
- }
- $remotetlpdb->virtual_add_tlpdb($tlmdb, $t);
- $locstr .= " $repos{$t}";
- }
- }
-
- # now check/setup pinning
- if (!$opts{"pin-file"}) {
- # check for pinning file in TEXMFLOCAL/tlpkg/pinning.txt
- chomp (my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`);
- debug("trying to load pinning file $TEXMFLOCAL/tlpkg/pinning.txt\n");
- # since we use TLConfFile it does not matter if the file
- # is not existing, it will be treated properly in TLConfFile
- $opts{"pin-file"} = "$TEXMFLOCAL/tlpkg/pinning.txt";
- }
- $pinfile = TeXLive::TLConfFile->new($opts{"pin-file"}, "#", ":", 'multiple');
- $remotetlpdb->virtual_pinning($pinfile);
- # this "location-url" line should not be changed since GUI programs
- # depend on it:
- if ($::machinereadable && !$silent) {
- print "location-url\t$locstr\n";
- return 1;
- }
- if ($silent) {
- return 1;
- }
- # from here on only in non-machine-readable mode and not silent
- info("$prg: package repositories\n");
- my $show_verification_page_link = 0;
- my $verstat = "";
- if (!$remotetlpdb->virtual_get_tlpdb('main')->is_verified) {
- $show_verification_page_link = 1;
- $verstat = ": ";
- $verstat .= $VerificationStatusDescription{$remotetlpdb->virtual_get_tlpdb('main')->verification_status};
- }
- info("\tmain = " . $repos{'main'} . " (" .
- ($remotetlpdb->virtual_get_tlpdb('main')->is_verified ? "" : "not ") .
- "verified$verstat)\n");
- for my $t (@tags) {
- if ($t ne 'main') {
- $verstat = "";
- if (!$remotetlpdb->virtual_get_tlpdb($t)->is_verified) {
- my $tlpdb_ver_stat = $remotetlpdb->virtual_get_tlpdb($t)->verification_status;
- $verstat = ": ";
- $verstat .= $VerificationStatusDescription{$tlpdb_ver_stat};
- # if the db is not verified *but* was signed, give the page link info
- if ($tlpdb_ver_stat != $VS_UNSIGNED) {
- $show_verification_page_link = 1;
- }
- }
- info("\t$t = " . $repos{$t} . " (" .
- ($remotetlpdb->virtual_get_tlpdb($t)->is_verified ? "" : "not ") .
- "verified$verstat)\n");
- }
- }
- if ($show_verification_page_link) {
- info("For more about verification, see https://texlive.info/verification.html.\n");
- }
- return 1;
-}
-
-sub _init_tlmedia {
- my $silent = shift;
- # if we are already initialized to the same location, nothing
- # needs to be done.
- # if we are initialized to a virtual tlpdb, then we have to
- # do in any case an initialization
- if (defined($remotetlpdb) && !$remotetlpdb->is_virtual &&
- ($remotetlpdb->root eq $location)) {
- # nothing to be done
- return 1;
- }
-
- # choose a mirror if we are asked.
- if ($location =~ m/^ctan$/i) {
- $location = give_ctan_mirror();
- } elsif ($location =~ m,^$TeXLiveServerURL,) {
- my $mirrorbase = TeXLive::TLUtils::give_ctan_mirror_base();
- $location =~ s,^$TeXLiveServerURL,$mirrorbase,;
- }
-
- my $errormsg;
- ($remotetlpdb, $errormsg) = setup_one_remotetlpdb($location, 'main');
- if (!defined($remotetlpdb)) {
- return(0, $errormsg);
- }
-
- return 1 if ($silent);
-
-
- # this "location-url" line should not be changed since GUI programs
- # depend on it:
- if ($::machinereadable) {
- print "location-url\t$location\n";
- } else {
- my $verstat = "";
- if (!$remotetlpdb->is_verified) {
- $verstat = ": ";
- $verstat .= $VerificationStatusDescription{$remotetlpdb->verification_status};
- }
- info("$prg: package repository $location (" .
- ($remotetlpdb->is_verified ? "" : "not ") . "verified$verstat)\n");
- }
- return 1;
-}
-
-sub setup_one_remotetlpdb {
- my $location = shift;
- my $addarg = shift;
- my $is_main = ((defined($addarg) && ($addarg eq 'main')) ? 1 : 0);
- my $remotetlpdb;
-
- # TODO
- # check if that is already loaded!!!
-
- # choose a mirror if we are asked.
- if ($location =~ m/^ctan$/i) {
- $location = give_ctan_mirror();
- } elsif ($location =~ m,^$TeXLiveServerURL,) {
- my $mirrorbase = TeXLive::TLUtils::give_ctan_mirror_base();
- $location =~ s,^$TeXLiveServerURL,$mirrorbase,;
- }
-
- # if we talk about a net location try to download the hash of the tlpdb
- # - if that is possible, check for the locally saved file and if the hash
- # agrees load the local copy if present instead of the remote one,
- # if the hashes disagree, load the remote tlpdb
- # - if that does not work assume we are offline or target not reachable,
- # so warn the user and use saved, but note that installation will
- # not work
- info("start load $location\n") if ($::machinereadable);
-
- my $local_copy_tlpdb_used = 0;
- if ($location =~ m;^(https?|ftp)://;) {
- # first check that the saved tlpdb is present at all
- my $loc_digest = TeXLive::TLCrypto::tl_short_digest($location);
- my $loc_copy_of_remote_tlpdb =
- ($is_main ?
- "$Master/$InfraLocation/texlive.tlpdb.main.$loc_digest" :
- "$Master/$InfraLocation/texlive.tlpdb.$loc_digest");
- ddebug("loc_digest = $loc_digest\n");
- ddebug("loc_copy = $loc_copy_of_remote_tlpdb\n");
- if (-r $loc_copy_of_remote_tlpdb) {
- ddebug("loc copy found!\n");
- # we found the tlpdb matching the current location
- # check for the remote hash
- my $path = "$location/$InfraLocation/$DatabaseName";
- ddebug("remote path of digest = $path\n");
- my ($verified, $status)
- = TeXLive::TLCrypto::verify_checksum_and_check_return($loc_copy_of_remote_tlpdb, $path,
- $is_main, 1); # the 1 means local copy mode!
- # deal with those cases that need special treatment
- if ($status == $VS_CONNECTION_ERROR) {
- info(<<END_NO_INTERNET);
-Unable to download the checksum of the remote TeX Live database,
-but found a local copy, so using that.
-
-You may want to try specifying an explicit or different CTAN mirror,
-or maybe you need to specify proxy information if you're behind a firewall;
-see the information and examples for the -repository option at
-https://tug.org/texlive/doc/install-tl.html
-(and in the output of install-tl --help).
-
-END_NO_INTERNET
- # above text duplicated in install-tl
- $remotetlpdb = TeXLive::TLPDB->new(root => $location,
- tlpdbfile => $loc_copy_of_remote_tlpdb);
- $local_copy_tlpdb_used = 1;
- } elsif ($status == $VS_VERIFIED || $status == $VS_EXPKEYSIG || $status == $VS_REVKEYSIG) {
- $remotetlpdb = TeXLive::TLPDB->new(root => $location,
- tlpdbfile => $loc_copy_of_remote_tlpdb);
- $local_copy_tlpdb_used = 1;
- # if verification was successful, make sure that is recorded
- $remotetlpdb->verification_status($status);
- $remotetlpdb->is_verified($verified);
- }
- # nothing to do in the else case
- # we tldie already in the verify_checksum_and_check_return
- # for all other cases
- }
- }
- if (!$local_copy_tlpdb_used) {
- $remotetlpdb = TeXLive::TLPDB->new(root => $location, verify => 1);
- if ($is_main && $remotetlpdb) {
- if ($remotetlpdb->verification_status == $VS_UNSIGNED) {
- # we don't allow unsigned main data bases!
- tldie("$prg: main database at $location is not signed\n");
- }
- }
- }
- if (!defined($remotetlpdb)) {
- info("fail load $location\n") if ($::machinereadable);
- return(undef, $loadmediasrcerror . $location);
- }
- if ($opts{"require-verification"} && !$remotetlpdb->is_verified) {
- info("fail load $location\n") if ($::machinereadable);
- tldie("Remote TeX Live database ($location) is not verified, exiting.\n");
- }
-
- # we allow a range of years to be specified by the remote tlpdb
- # for which it might work.
- # the lower limit is TLPDB->config_minrelease
- # the upper limit is TLPDB->config_release
- # if the later is not present only the year in config_release is accepted
- # checks are done on the first 4 digits only
- # Why only the first four places: some optional network distributions
- # might use
- # release/2009-foobar
- # If it should work for 2009 and 2010, please use
- # minrelease/2009-foobar
- # release/2010-foobar
- # One exception: if there *is* an extension like -foobar (-gpg, ..)
- # we allow the local release to be smaller than the max,
- # so that additional repos can do
- # release/3000-foobar
- # and be usable with all future releases, too.
- my $texlive_release = $remotetlpdb->config_release;
- my $texlive_minrelease = $remotetlpdb->config_minrelease;
- my $rroot = $remotetlpdb->root;
- if (!defined($texlive_release)) {
- info("fail load $location\n") if ($::machinereadable);
- return(undef, "The installation repository ($rroot) does not specify a "
- . "release year for which it was prepared, goodbye.");
- }
- # still here, so we have $texlive_release defined
- my $texlive_release_year = $texlive_release;
- $texlive_release_year =~ s/^(....).*$/$1/;
- if ($texlive_release_year !~ m/^[1-9][0-9][0-9][0-9]$/) {
- info("fail load $location\n") if ($::machinereadable);
- return(undef, "The installation repository ($rroot) does not specify a "
- . "valid release year, goodbye: $texlive_release");
- }
- # so $texlive_release_year is numeric, good
- if (defined($texlive_minrelease)) {
- # we specify a range of years!
- my $texlive_minrelease_year = $texlive_minrelease;
- $texlive_minrelease_year =~ s/^(....).*$/$1/;
- if ($texlive_minrelease_year !~ m/^[1-9][0-9][0-9][0-9]$/) {
- info("fail load $location\n") if ($::machinereadable);
- return(undef, "The installation repository ($rroot) does not specify a "
- . "valid minimal release year, goodbye: $texlive_minrelease");
- }
- # ok, all numeric and fine, check for range
- if ($TeXLive::TLConfig::ReleaseYear < $texlive_minrelease_year
- || $TeXLive::TLConfig::ReleaseYear > $texlive_release_year) {
- info("fail load $location\n") if ($::machinereadable);
- return (undef, "The TeX Live versions supported by the repository
-$rroot
- ($texlive_minrelease_year--$texlive_release_year)
-do not include the version of the local installation
- ($TeXLive::TLConfig::ReleaseYear).");
- }
- #
- # if the release of the installed TL is less than the release
- # of the main remote repository, then
- # warn that one needs to call update-tlmgr-latest.sh --update
- # We do this only if there is no extension like 2100-gpg etc
- if ($is_main && $TeXLive::TLConfig::ReleaseYear < $texlive_release_year) {
- if (length($texlive_release) > 4) {
- debug("Accepting a newer release as remote due to presence of release extension!\n");
- } else {
- info("fail load $location\n") if ($::machinereadable);
- return (undef, "Local TeX Live ($TeXLive::TLConfig::ReleaseYear)"
- . " is older than remote repository ($texlive_release_year).\n"
- . "Cross release updates are only supported with\n"
- . " update-tlmgr-latest(.sh/.exe) --update\n"
- . "See https://tug.org/texlive/upgrade.html for details.")
- }
- }
- } else {
- # $texlive_minrelease not defined, so only one year is valid
- if ($texlive_release_year != $TeXLive::TLConfig::ReleaseYear) {
- info("fail load $location\n") if ($::machinereadable);
- return(undef, "The TeX Live versions of the local installation
-and the repository are not compatible:
- local: $TeXLive::TLConfig::ReleaseYear
- repository: $texlive_release_year ($rroot)
-(Perhaps you need to use a different CTAN mirror? Just a guess.)");
- }
- }
-
- # check for being frozen
- if ($remotetlpdb->config_frozen) {
- my $frozen_msg = <<FROZEN;
-TeX Live $TeXLive::TLConfig::ReleaseYear is frozen and will no longer
-be routinely updated. This happens in preparation for a new release.
-
-If you're willing to help with pretesting the new release, and we hope
-you are, (when pretests are available), please read
-https://tug.org/texlive/pretest.html.
-
-Otherwise, just wait, and the new release will be ready in due time.
-FROZEN
- # don't die here, we want to allow updates even if tlnet is frozen!
- tlwarn($frozen_msg);
- }
-
- # save remote database if it is a net location
- # make sure that the writeout of the tlpdb is done in UNIX mode
- # since otherwise the checksum will change.
- if (!$local_copy_tlpdb_used && $location =~ m;^(https?|ftp)://;) {
- my $loc_digest = TeXLive::TLCrypto::tl_short_digest($location);
- my $loc_copy_of_remote_tlpdb =
- ($is_main ?
- "$Master/$InfraLocation/texlive.tlpdb.main.$loc_digest" :
- "$Master/$InfraLocation/texlive.tlpdb.$loc_digest");
- my $tlfh;
- if (!open($tlfh, ">:unix", $loc_copy_of_remote_tlpdb)) {
- # that should be only a debug statement, since a user without
- # write permission might have done a tlmgr search --global or
- # similar
- &debug("Cannot save remote TeX Live database to $loc_copy_of_remote_tlpdb: $!\n");
- } else {
- &debug("writing out tlpdb to $loc_copy_of_remote_tlpdb\n");
- $remotetlpdb->writeout($tlfh);
- close($tlfh);
- # Remove all other copies of main databases in case different mirrors
- # are used $Master/$InfraLocation/texlive.tlpdb.main.$loc_digest
- if ($is_main) {
- for my $fn (<"$Master/$InfraLocation/texlive.tlpdb.main.*">) {
- next if ($fn eq $loc_copy_of_remote_tlpdb);
- unlink($fn);
- }
- }
- }
- }
-
- info("finish load $location\n") if ($::machinereadable);
- return($remotetlpdb);
-}
-
-
-
-# finish handles the -pause option (wait for input from stdin),
-# and then exits unless the global $::gui_mode is set, in which case we
-# merely return.
-#
-sub finish {
- my ($ret) = @_;
-
- if ($ret > 0) {
- print "$prg: exiting unsuccessfully (status $ret).\n";
- }
-
- if ($::gui_mode) {
- return $ret;
- } else {
- exit($ret);
- }
-}
-
-
-# tlmgr config file handling. These config files are located in
-# TEXMFCONFIG/tlmgr/config, thus specific for each user.
-#
-# format:
-# key=value
-#
-sub load_config_file {
- #
- # first set default values
- $config{"gui-expertmode"} = 1;
- $config{"auto-remove"} = 1;
- $config{"persistent-downloads"} = 1;
- $config{"verify-repo"} = "main";
- # do NOT set this here, we distinguish between explicitly set in the
- # config file or implicitly true:
- # $config{"verify-downloads"} = 1;
-
- # loads system config file, this cannot be changes with tlmgr
- chomp (my $TEXMFSYSCONFIG = `kpsewhich -var-value=TEXMFSYSCONFIG`);
- my $fnsys = "$TEXMFSYSCONFIG/tlmgr/config";
- my $tlmgr_sys_config_file = TeXLive::TLConfFile->new($fnsys, "#", "=");
- load_options_from_config($tlmgr_sys_config_file, 'sys')
- if $tlmgr_sys_config_file;
-
- chomp (my $TEXMFCONFIG = `kpsewhich -var-value=TEXMFCONFIG`);
- my $fn = "$TEXMFCONFIG/tlmgr/config";
- $tlmgr_config_file = TeXLive::TLConfFile->new($fn, "#", "=");
- load_options_from_config($tlmgr_config_file) if $tlmgr_config_file;
-
- $config{"verify-repo"}
- = convert_crypto_options($config{"verify-downloads"},
- $config{"require-verification"},
- $config{"verify-repo"});
- delete $config{"require-verification"};
- delete $config{"verify-downloads"};
-
- # TODO TODO
- # rename old crypto options
- #
- # TODO TODO
- # what should we do with this?
- # set $opts{"key"} from $config{"key"} if not passed in on cmd line
- if (!defined($opts{"require-verification"})) {
- $opts{"require-verification"} = $config{"require-verification"};
- }
- if (!defined($opts{"persistent-downloads"})) {
- $opts{"persistent-downloads"} = $config{"persistent-downloads"};
- }
-
- # switched names for this one after initial release.
- if ($tlmgr_config_file->key_present("gui_expertmode")) {
- $tlmgr_config_file->rename_key("gui_expertmode", "gui-expertmode");
- }
-}
-
-sub load_options_from_config {
- my ($tlmgr_config_file, $sysmode) = @_;
- my $fn = $tlmgr_config_file->file;
- for my $key ($tlmgr_config_file->keys) {
- my $val = $tlmgr_config_file->value($key);
- if ($key eq "gui-expertmode") {
- if ($val eq "0") {
- $config{"gui-expertmode"} = 0;
- } elsif ($val eq "1") {
- $config{"gui-expertmode"} = 1;
- } else {
- tlwarn("$prg: $fn: unknown value for gui-expertmode: $val\n");
- }
-
- } elsif ($key eq "persistent-downloads") {
- if (($val eq "0") || ($val eq "1")) {
- $config{'persistent-downloads'} = $val;
- } else {
- tlwarn("$prg: $fn: unknown value for persistent-downloads: $val\n");
- }
-
- } elsif ($key eq "update-exclude") {
- my @exs = split(/,/, $val);
- $config{'update-exclude'} = \@exs;
-
- } elsif ($key eq "gui-lang") {
- $config{'gui-lang'} = $val;
-
- } elsif ($key eq "auto-remove") {
- if ($val eq "0") {
- $config{"auto-remove"} = 0;
- } elsif ($val eq "1") {
- $config{"auto-remove"} = 1;
- } else {
- tlwarn("$prg: $fn: unknown value for auto-remove: $val\n");
- }
-
- } elsif ($key eq "require-verification") {
- if ($val eq "0") {
- $config{"require-verification"} = 0;
- } elsif ($val eq "1") {
- $config{"require-verification"} = 1;
- } else {
- tlwarn("$prg: $fn: unknown value for require-verification: $val\n");
- }
-
- } elsif ($key eq "verify-downloads") {
- if ($val eq "0") {
- $config{"verify-downloads"} = 0;
- } elsif ($val eq "1") {
- $config{"verify-downloads"} = 1;
- } else {
- tlwarn("$prg: $fn: unknown value for verify-downloads: $val\n");
- }
-
- } elsif ($key eq "verify-repo") {
- if ($val =~ m/$allowed_verify_args_regex/) {
- $config{"verify-repo"} = $val;
- } else {
- tlwarn("$prg: $fn: unknown value for verify-repo: $val\n");
- }
-
- } elsif ($key eq "no-checksums") {
- if ($val eq "1") {
- $config{"no-checksums"} = 1;
- } elsif ($val eq "0") {
- $config{"no-checksums"} = 0;
- } else {
- tlwarn("$prg: $fn: unknown value for no-checksums: $val\n");
- }
-
- } elsif ($key eq "tkfontscale") {
- $config{'tkfontscale'} = $val;
-
- } elsif ($sysmode) {
- # keys here are only allowed in sys mode
- if ($key eq "allowed-actions") {
- my @acts = split(/,/, $val);
- $config{'allowed-actions'} = \@acts;
- } else {
- tlwarn("$prg: $fn: unknown tlmgr configuration variable: $key\n");
- }
- } else {
- tlwarn("$prg: $fn: unknown tlmgr configuration variable: $key\n");
- }
- }
-}
-
-sub write_config_file {
- if (!defined($tlmgr_config_file)) {
- chomp (my $TEXMFCONFIG = `kpsewhich -var-value=TEXMFCONFIG`);
- my $dn = "$TEXMFCONFIG/tlmgr";
- my $fn = "$dn/config";
- # create a new one
- $tlmgr_config_file = TeXLive::TLConfFile->new($fn, "#", "=");
- }
- for my $k (keys %config) {
- # it doesn't hurt to save all config settings as we check in TLConfFile
- # if the value has actually changed
- $tlmgr_config_file->value($k, $config{$k});
- }
- # make sure that deleted config entries are carried over
- for my $k ($tlmgr_config_file->keys) {
- if (not(defined($config{$k}))) {
- $tlmgr_config_file->delete_key($k);
- }
- }
- if ($tlmgr_config_file->is_changed) {
- $tlmgr_config_file->save;
- }
-}
-
-sub convert_crypto_options {
- my ($verify_downloads, $require_verification, $verify_repo) = @_;
-
- # leave undefined to deal with case that nothing has been passed in
- my $ret;
-
- # crypto options rewriting
- if ((defined($verify_downloads) || defined($require_verification)) &&
- defined($verify_repo)) {
- # we cannot have all three, warn and bail out
- tldie("$prg: options verify-downloads and require-verification have\n"
- . "$prg: been superseded by verify-repo; please use only the latter!\n");
- }
- # return immediately if verify_repo is already set
- return($verify_repo) if (defined($verify_repo));
-
- if (defined($verify_downloads)) {
- if ($verify_downloads) {
- # explicit --verify-downloads was given
- if ($require_verification) {
- # --require-verification was given
- $ret = "all";
- } else {
- # either nothing passed or --no-require-verification (default)
- # use explicit setting to main
- $ret = "main";
- }
- } else {
- # explicit --no-verify-downloads was given
- if ($require_verification) {
- # --require-verification was given
- tldie("You cannot ask for --no-verify-downloads and"
- . " --require-verification at the same time!\n");
- } else {
- $ret = "none";
- }
- }
- } else {
- # nothing related to verify-download was given, so it is by default
- # set to true
- if ($require_verification) {
- $ret = "all";
- } else {
- # don't set anything, as nothing has been passed in
- }
- }
- return($ret);
-}
-
-# if the packagelog variable is set then write to PACKAGELOG filehandle
-#
-sub logpackage {
- if ($packagelogfile) {
- $packagelogged++;
- my $tim = localtime();
- print PACKAGELOG "[$tim] @_\n";
- }
-}
-sub logcommand {
- if ($commandlogfile) {
- my $tim = localtime();
- print COMMANDLOG "[$tim] @_\n";
- }
-}
-
-
-# resolve relative paths from tlpdb wrt tlroot
-sub norm_tlpdb_path {
- my ($path) = @_;
- return if (!defined($path));
- $path =~ s!\\!/!;
- # just return if absolute path
- return $path if ($path =~ m!^/|:!);
- init_local_db() unless defined($localtlpdb);
- return $localtlpdb->root . "/$path";
-}
-
-# clear the backup dir for $pkg and keep only $autobackup packages
-# mind that with $autobackup == 0 all packages are cleared
-#
-sub clear_old_backups {
- my ($pkg, $backupdir, $autobackup, $dry, $v) = @_;
-
- my $verb = ($v ? 1 : 0);
- my $dryrun = 0;
- $dryrun = 1 if ($dry);
- # keep arbitrary many backups
- return if ($autobackup == -1);
-
- opendir (DIR, $backupdir) || die "opendir($backupdir) failed: $!";
- my @dirents = readdir (DIR);
- closedir (DIR) || warn "closedir($backupdir) failed: $!";
- my @backups;
- for my $dirent (@dirents) {
- next if (-d $dirent);
- next if ($dirent !~ m/^$pkg\.r([0-9]+)\.tar\.$CompressorExtRegexp$/);
- push @backups, [ $1, $dirent ] ;
- }
- my $i = 1;
- for my $e (reverse sort {$a->[0] <=> $b->[0]} @backups) {
- if ($i > $autobackup) {
- # only echo out if explicitly asked for verbose which is done
- # in the backup --clean action
- if ($verb) {
- info("$prg: Removing backup $backupdir/$e->[1]\n");
- } else {
- debug("Removing backup $backupdir/$e->[1]\n");
- }
- unlink("$backupdir/$e->[1]") unless $dryrun;
- }
- $i++;
- }
-}
-
-# check for updates to tlcritical packages
-#
-sub check_for_critical_updates {
- my ($localtlpdb, $mediatlpdb) = @_;
-
- my $criticalupdate = 0;
- my @critical = $localtlpdb->expand_dependencies("-no-collections",
- $localtlpdb, @CriticalPackagesList);
- my @critical_upd;
- for my $pkg (sort @critical) {
- my $tlp = $localtlpdb->get_package($pkg);
- if (!defined($tlp)) {
- # that should not happen, we expanded in the localtlpdb so why
- # should it not be present, any anyway, those are so fundamental
- # so they have to be there
- tlwarn("\n$prg: Fundamental package $pkg not present, uh oh, goodbye");
- die "Should not happen, $pkg not found";
- }
- my $localrev = $tlp->revision;
- my $mtlp = $mediatlpdb->get_package($pkg);
- if (!defined($mtlp)) {
- debug("Very surprising, $pkg is not present in the remote tlpdb.\n");
- next;
- }
- my $remoterev = $mtlp->revision;
- push (@critical_upd, $pkg) if ($remoterev > $localrev);
- }
- return(@critical_upd);
-}
-
-sub critical_updates_warning {
- tlwarn("=" x 79, "\n");
- tlwarn("tlmgr itself needs to be updated.\n");
- tlwarn("Please do this via either\n");
- tlwarn(" tlmgr update --self\n");
- tlwarn("or by getting the latest updater for Unix-ish systems:\n");
- tlwarn(" $TeXLiveURL/update-tlmgr-latest.sh\n");
- tlwarn("and/or Windows systems:\n");
- tlwarn(" $TeXLiveURL/update-tlmgr-latest.exe\n");
- tlwarn("Then continue with other updates as usual.\n");
- tlwarn("=" x 79, "\n");
-}
-
-#
-# our compare function for package sorting, which makes sure that
-# packages with .ARCH names are sorted *before* the main packages
-sub packagecmp {
- my $aa = $a;
- my $bb = $b;
- # remove the part after the . if at all present
- $aa =~ s/\..*$//;
- $bb =~ s/\..*$//;
- if ($aa lt $bb) {
- return -1;
- } elsif ($aa gt $bb) {
- return 1;
- } else {
- # the parts before the . are the same
- # sort the .something *before* the ones without
- if ($a eq $aa && $b eq $bb) {
- return 0;
- } elsif ($a eq $aa) {
- # so $a = foobar
- # and $b = foobar.something
- # this is the special case where we want to invert the order
- return 1;
- } elsif ($b eq $bb) {
- # so $a = foobar.something
- # and $b = foobar
- return -1;
- } else {
- return ($a cmp $b);
- }
- }
-}
-
-sub check_on_writable {
- return 1 if $opts{"usermode"};
- if (!TeXLive::TLUtils::dir_writable("$Master/tlpkg")) {
- tlwarn("You don't have permission to change the installation in any way,\n");
- tlwarn("specifically, the directory $Master/tlpkg/ is not writable.\n");
- tlwarn("Please run this program as administrator, or contact your local admin.\n");
- if ($opts{"dry-run"}) {
- tlwarn("$prg: Continuing due to --dry-run\n");
- return 1;
- } else {
- return 0;
- }
- }
- return 1;
-}
-
-
-1;
-__END__
-
-=head1 NAME
-
-tlmgr - the native TeX Live Manager
-
-=head1 SYNOPSIS
-
-tlmgr [I<option>...] I<action> [I<option>...] [I<operand>...]
-
-=head1 DESCRIPTION
-
-B<tlmgr> manages an existing TeX Live installation, both packages and
-configuration options. For information on initially downloading and
-installing TeX Live, see L<https://tug.org/texlive/acquire.html>.
-
-The most up-to-date version of this documentation (updated nightly from
-the development sources) is available at
-L<https://tug.org/texlive/tlmgr.html>, along with procedures for updating
-C<tlmgr> itself and information about test versions.
-
-TeX Live is organized into a few top-level I<schemes>, each of which is
-specified as a different set of I<collections> and I<packages>, where a
-collection is a set of packages, and a package is what contains actual
-files. Schemes typically contain a mix of collections and packages, but
-each package is included in exactly one collection, no more and no less.
-A TeX Live installation can be customized and managed at any level.
-
-See L<https://tug.org/texlive/doc> for all the TeX Live documentation
-available.
-
-=head1 EXAMPLES
-
-After successfully installing TeX Live, here are a few common operations
-with C<tlmgr>:
-
-=over 4
-
-=item C<tlmgr option repository ctan>
-
-=item C<tlmgr option repository http://mirror.ctan.org/systems/texlive/tlnet>
-
-Tell C<tlmgr> to use a nearby CTAN mirror for future updates; useful if
-you installed TeX Live from the DVD image and want to have continuing
-updates. The two commands are equivalent; C<ctan> is just an alias for
-the given url.
-
-Caveat: C<mirror.ctan.org> resolves to many different hosts, and they
-are not perfectly synchronized; we recommend updating only daily (at
-most), and not more often. You can choose a particular mirror if
-problems; the list of all CTAN mirrors with the status of each is at
-L<https://ctan.org/mirrors/mirmon>.
-
-=item C<tlmgr update --list>
-
-Report what would be updated without actually updating anything.
-
-=item C<tlmgr update --all>
-
-Make your local TeX installation correspond to what is in the package
-repository (typically useful when updating from CTAN).
-
-=item C<tlmgr info> I<what>
-
-Display detailed information about a package I<what>, such as the installation
-status and description, of searches for I<what> in all packages.
-
-=back
-
-For all the capabilities and details of C<tlmgr>, please read the
-following voluminous information.
-
-=head1 OPTIONS
-
-The following options to C<tlmgr> are global options, not specific to
-any action. All options, whether global or action-specific, can be
-given anywhere on the command line, and in any order. The first
-non-option argument will be the main action. In all cases,
-C<-->I<option> and C<->I<option> are equivalent, and an C<=> is optional
-between an option name and its value.
-
-=over 4
-
-=item B<--repository> I<url|path>
-
-Specify the package repository from which packages should be installed
-or updated, either a local directory or network location, as below. This
-overridesthe default package repository found in the installation's TeX
-Live Package Database (a.k.a. the TLPDB, which is given entirely in the
-file C<tlpkg/texlive.tlpdb>).
-
-This C<--repository> option changes the location only for the current
-run; to make a permanent change, use C<option repository> (see the
-L</option> action).
-
-As an example, you can choose a particular CTAN mirror with something
-like this:
-
- -repository http://ctan.example.org/its/ctan/dir/systems/texlive/tlnet
-
-Of course a real hostname and its particular top-level CTAN directory
-have to be specified. The list of CTAN mirrors is available at
-L<https://ctan.org/mirrors/mirmon>.
-
-Here's an example of using a local directory:
-
- -repository /local/TL/repository
-
-For backward compatibility and convenience, C<--location> and C<--repo>
-are accepted as aliases for this option.
-
-Locations can be specified as any of the following:
-
-=over 4
-
-=item C</some/local/dir>
-
-=item C<file:/some/local/dir>
-
-Equivalent ways of specifying a local directory.
-
-=item C<ctan>
-
-=item C<http://mirror.ctan.org/systems/texlive/tlnet>
-
-Pick a CTAN mirror automatically, trying for one that is both nearby and
-up-to-date. The chosen mirror is used for the entire download. The bare
-C<ctan> is merely an alias for the full url. (See L<https://ctan.org> for
-more about CTAN and its mirrors.)
-
-=item C<http://server/path/to/tlnet>
-
-Standard HTTP. If the (default) LWP method is used, persistent
-connections are supported. TL can also use C<curl> or C<wget> to do the
-downloads, or an arbitrary user-specified program, as described in the
-C<tlmgr> documentation
-(L<https://tug.org/texlive/doc/tlmgr.html#ENVIRONMENT-VARIABLES>).
-
-=item C<https://server/path/to/tlnet>
-
-Again, if the (default) LWP method is used, this supports persistent
-connections. Unfortunately, some versions of C<wget> and C<curl> do not
-support https, and even when C<wget> supports https, certificates may be
-rejected even when the certificate is fine, due to a lack of local
-certificate roots. The simplest workaround for this problem is to use
-http or ftp.
-
-=item C<ftp://server/path/to/tlnet>
-
-If the (default) LWP method is used, persistent connections are
-supported.
-
-=item C<user@machine:/path/to/tlnet>
-
-=item C<scp://user@machine/path/to/tlnet>
-
-=item C<ssh://user@machine/path/to/tlnet>
-
-These forms are equivalent; they all use C<scp> to transfer files. Using
-C<ssh-agent> is recommended. (Info:
-L<https://en.wikipedia.org/wiki/OpenSSH>,
-L<https://en.wikipedia.org/wiki/Ssh-agent>.)
-
-=back
-
-If the repository is on the network, trailing C</> characters and/or
-trailing C</tlpkg> and/or C</archive> components are ignored.
-
-=item B<--gui> [I<action>]
-
-Two notable GUI front-ends for C<tlmgr>, C<tlshell> and C<tlcockpit>,
-are started up as separate programs; see their own documentation.
-
-C<tlmgr> itself has a graphical interface as well as the command line
-interface. You can give the option to invoke it, C<--gui>, together with
-an action to be brought directly into the respective screen of the GUI.
-For example, running
-
- tlmgr --gui update
-
-starts you directly at the update screen. If no action is given, the
-GUI will be started at the main screen. See L<GUI FOR TLMGR>.
-
-However, the native GUI requires Perl/TK, which is no longer included in
-TeX Live's Perl distribution for Windows. You may find C<tlshell> or
-C<tlcockpit> easier to work with.
-
-
-=for comment Keep language list in sync with install-tl.
-
-=item B<--gui-lang> I<llcode>
-
-By default, the GUI tries to deduce your language from the environment
-(on Windows via the registry, on Unix via C<LC_MESSAGES>). If that fails
-you can select a different language by giving this option with a
-language code (based on ISO 639-1). Currently supported (but not
-necessarily completely translated) are: S<English (en, default)>,
-S<Czech (cs)>, S<German (de)>, S<French (fr)>, S<Italian (it)>,
-S<Japanese (ja)>, S<Dutch (nl)>, S<Polish (pl)>, S<Brazilian Portuguese
-(pt_BR)>, S<Russian (ru)>, S<Slovak (sk)>, S<Slovenian (sl)>, S<Serbian
-(sr)>, S<Ukrainian (uk)>, S<Vietnamese (vi)>, S<simplified Chinese
-(zh_CN)>, and S<traditional Chinese (zh_TW)>.
-
-tlshell shares its message catalog with tlmgr.
-
-=item B<--command-logfile> I<file>
-
-C<tlmgr> logs the output of all programs invoked (mktexlr, mtxrun, fmtutil,
-updmap) to a separate log file, by default
-C<TEXMFSYSVAR/web2c/tlmgr-commands.log>. This option allows you to specify a
-different file for the log.
-
-=item B<--debug-translation>
-
-In GUI mode, this switch tells C<tlmgr> to report any untranslated (or
-missing) messages to standard error. This can help translators to see
-what remains to be done.
-
-=item B<--machine-readable>
-
-Instead of the normal output intended for human consumption, write (to
-standard output) a fixed format more suitable for machine parsing. See
-the L<MACHINE-READABLE OUTPUT> section below.
-
-=item B<--no-execute-actions>
-
-Suppress the execution of the execute actions as defined in the tlpsrc
-files. Documented only for completeness, as this is only useful in
-debugging.
-
-=item B<--package-logfile> I<file>
-
-C<tlmgr> logs all package actions (install, remove, update, failed
-updates, failed restores) to a separate log file, by default
-C<TEXMFSYSVAR/web2c/tlmgr.log>. This option allows you to specify a
-different file for the log.
-
-=item B<--pause>
-
-This option makes C<tlmgr> wait for user input before exiting. Useful on
-Windows to avoid disappearing command windows.
-
-=item B<--persistent-downloads>
-
-=item B<--no-persistent-downloads>
-
-For network-based installations, this option (on by default) makes
-C<tlmgr> try to set up a persistent connection (using the C<LWP> Perl
-module). The idea is to open and reuse only one connection per session
-between your computer and the server, instead of initiating a new
-download for each package.
-
-If this is not possible, C<tlmgr> will fall back to using C<wget>. To
-disable these persistent connections, use C<--no-persistent-downloads>.
-
-=item B<--pin-file>
-
-Change the pinning file location from C<TEXMFLOCAL/tlpkg/pinning.txt>
-(see L</Pinning> below). Documented only for completeness, as this is
-only useful in debugging.
-
-=item B<--usermode>
-
-Activates user mode for this run of C<tlmgr>; see L<USER MODE> below.
-
-=item B<--usertree> I<dir>
-
-Uses I<dir> for the tree in user mode; see L<USER MODE> below.
-
-=item B<--verify-repo=[none|main|all]>
-
-Defines the level of verification done: If C<none> is specified, no
-verification whatsoever is done. If C<main> is given and a working GnuPG
-(C<gpg>) binary is available, all repositories are checked, but only the
-main repository is required to be signed. If C<all> is given, then all
-repositories need to be signed. See L<CRYPTOGRAPHIC VERIFICATION> below
-for details.
-
-=back
-
-The standard options for TeX Live programs are also accepted:
-C<--help/-h/-?>, C<--version>, C<-q> (no informational messages), C<-v>
-(debugging messages, can be repeated). For the details about these, see
-the C<TeXLive::TLUtils> documentation.
-
-The C<--version> option shows version information about the TeX Live
-release and about the C<tlmgr> script itself. If C<-v> is also given,
-revision number for the loaded TeX Live Perl modules are shown, too.
-
-=head1 ACTIONS
-
-=head2 help
-
-Display this help information and exit (same as C<--help>, and on the
-web at L<https://tug.org/texlive/doc/tlmgr.html>). Sometimes the
-C<perldoc> and/or C<PAGER> programs on the system have problems,
-resulting in control characters being literally output. This can't
-always be detected, but you can set the C<NOPERLDOC> environment
-variable and C<perldoc> will not be used.
-
-=head2 version
-
-Gives version information (same as C<--version>).
-
-If C<-v> has been given the revisions of the used modules are reported, too.
-
-=head2 backup
-
-=over 4
-
-=item B<backup [I<option>...] --all>
-
-=item B<backup [I<option>...] I<pkg>...>
-
-If the C<--clean> option is not specified, this action makes a backup of
-the given packages, or all packages given C<--all>. These backups are
-saved to the value of the C<--backupdir> option, if that is an existing
-and writable directory. If C<--backupdir> is not given, the C<backupdir>
-option setting in the TLPDB is used, if present. If both are missing, no
-backups are made. (The installer sets C<backupdir> to
-C<.../tlpkg/backups>, under the TL root installation directory, so it is
-usually defined; see the L</option> description for more information.)
-
-If the C<--clean> option is specified, backups are pruned (removed)
-instead of saved. The optional integer value I<N> may be specified to
-set the number of backups that will be retained when cleaning. If C<N>
-is not given, the value of the C<autobackup> option is used. If both are
-missing, an error is issued. For more details of backup pruning, see
-the C<option> action.
-
-Options:
-
-=over 4
-
-=item B<--backupdir> I<directory>
-
-Overrides the C<backupdir> option setting in the TLPDB.
-The I<directory> argument is required and must specify an existing,
-writable directory where backups are to be placed.
-
-=item B<--all>
-
-If C<--clean> is not specified, make a backup of all packages in the TeX
-Live installation; this will take quite a lot of space and time. If
-C<--clean> is specified, all packages are pruned.
-
-=item B<--clean>[=I<N>]
-
-Instead of making backups, prune the backup directory of old backups, as
-explained above. The optional integer argument I<N> overrides the
-C<autobackup> option set in the TLPDB. You must use C<--all> or a list
-of packages together with this option, as desired.
-
-=item B<--dry-run>
-
-Nothing is actually backed up or removed; instead, the actions to be
-performed are written to the terminal.
-
-=back
-
-=back
-
-=head2 candidates I<pkg>
-
-Shows the available candidate repositories for package I<pkg>.
-See L<MULTIPLE REPOSITORIES> below.
-
-=head2 check [I<option>...] [depends|executes|files|runfiles|texmfdbs|all]
-
-Execute one (or all) check(s) of the consistency of the installation.
-If no problems are found, there will be no output. (To get a view of
-what is being done, run C<tlmgr -v check>.)
-
-=over 4
-
-=item B<depends>
-
-Lists those packages which occur as dependencies in an installed collection,
-but are themselves not installed, and those packages which are not
-contained in any collection.
-
-If you call C<tlmgr check collections> this test will be carried out
-instead since former versions for C<tlmgr> called it that way.
-
-=item B<executes>
-
-Check that the files referred to by C<execute> directives in the TeX
-Live Database are present.
-
-=item B<files>
-
-Checks that all files listed in the local TLPDB (C<texlive.tlpdb>) are
-actually present, and lists those missing.
-
-=item B<runfiles>
-
-List those filenames that are occurring more than one time in the
-runfiles sections, except for known duplicates.
-
-=item B<texmfdbs>
-
-Checks related to the C<ls-R> files. If you have defined new trees, or
-changed the C<TEXMF> or C<TEXMFDBS> variables, it can't hurt to run
-this. It checks that:
-
-=over 8
-
-=item - all items in C<TEXMFDBS> have the C<!!> prefix.
-
-=item - all items in C<TEXMFBDS> have an C<ls-R> file (if they exist at all).
-
-=item - all items in C<TEXMF> with C<!!> are listed in C<TEXMFDBS>.
-
-=item - all items in C<TEXMF> with an C<ls-R> file are listed in C<TEXMFDBS>.
-
-=back
-
-=back
-
-Options:
-
-=over 4
-
-=item B<--use-svn>
-
-Use the output of C<svn status> instead of listing the files; for
-checking the TL development repository. (This is run nightly.)
-
-=back
-
-=head2 conf
-
-=over 4
-
-=item B<conf [texmf|tlmgr|updmap [--conffile I<file>] [--delete] [I<key> [I<value>]]]>
-
-=item B<conf auxtrees [--conffile I<file>] [show|add|remove] [I<value>]>
-
-With only C<conf>, show general configuration information for TeX Live,
-including active configuration files, path settings, and more. This is
-like running C<texconfig conf>, but works on all supported platforms.
-
-With one of C<conf texmf>, C<conf tlmgr>, or C<conf updmap>, shows all
-key/value pairs (i.e., all settings) as saved in C<ROOT/texmf.cnf>, the
-user-specific C<tlmgr> configuration file (see below), or the first
-found (via C<kpsewhich>) C<updmap.cfg> file, respectively.
-
-If I<key> is given in addition, shows the value of only that I<key> in
-the respective file. If option I<--delete> is also given, the value in
-the given configuration file is entirely removed (not just commented
-out).
-
-If I<value> is given in addition, I<key> is set to I<value> in the
-respective file. I<No error checking is done!>
-
-The C<PATH> value shown by C<conf> is as used by C<tlmgr>. The
-directory in which the C<tlmgr> executable is found is automatically
-prepended to the PATH value inherited from the environment.
-
-Here is a practical example of changing configuration values. If the
-execution of (some or all) system commands via C<\write18> was left
-enabled during installation, you can disable it afterwards:
-
- tlmgr conf texmf shell_escape 0
-
-The subcommand C<auxtrees> allows adding and removing arbitrary
-additional texmf trees, completely under user control. C<auxtrees show>
-shows the list of additional trees, C<auxtrees add> I<tree> adds a tree
-to the list, and C<auxtrees remove> I<tree> removes a tree from the list
-(if present). The trees should not contain an C<ls-R> file (or files
-will not be found if the C<ls-R> becomes stale). This works by
-manipulating the Kpathsea variable C<TEXMFAUXTREES>, in (by default)
-C<ROOT/texmf.cnf>. Example:
-
- tlmgr conf auxtrees add /quick/test/tree
- tlmgr conf auxtrees remove /quick/test/tree
-
-In all cases the configuration file can be explicitly specified via the
-option C<--conffile> I<file>, e.g., if you don't want to change the
-system-wide configuration.
-
-Warning: The general facility for changing configuration values is here,
-but tinkering with settings in this way is strongly discouraged. Again,
-no error checking on either keys or values is done, so any sort of
-breakage is possible.
-
-=back
-
-=head2 dump-tlpdb [I<option>...] [--json]
-
-Dump complete local or remote TLPDB to standard output, as-is. The
-output is analogous to the C<--machine-readable> output; see
-L<MACHINE-READABLE OUTPUT> section.
-
-Options:
-
-=over 4
-
-=item B<--local>
-
-Dump the local TLPDB.
-
-=item B<--remote>
-
-Dump the remote TLPDB.
-
-=item B<--json>
-
-Instead of dumping the actual content, the database is dumped as
-JSON. For the format of JSON output see C<tlpkg/doc/JSON-formats.txt>,
-format definition C<TLPDB>.
-
-=back
-
-Exactly one of C<--local> and C<--remote> must be given.
-
-In either case, the first line of the output specifies the repository
-location, in this format:
-
- "location-url" "\t" location
-
-where C<location-url> is the literal field name, followed by a tab, and
-I<location> is the file or url to the repository.
-
-Line endings may be either LF or CRLF depending on the current platform.
-
-=head2 generate
-
-=over 4
-
-=item B<generate [I<option>...] language>
-
-=item B<generate [I<option>...] language.dat>
-
-=item B<generate [I<option>...] language.def>
-
-=item B<generate [I<option>...] language.dat.lua>
-
-=back
-
-The C<generate> action overwrites any manual changes made in the
-respective files: it recreates them from scratch based on the
-information of the installed packages, plus local adaptions.
-The TeX Live installer and C<tlmgr> routinely call C<generate> for
-all of these files.
-
-For managing your own fonts, please read the C<updmap --help>
-information and/or L<https://tug.org/fonts/fontinstall.html>.
-
-For managing your own formats, please read the C<fmtutil --help>
-information.
-
-In more detail: C<generate> remakes any of the configuration files
-C<language.dat>, C<language.def>, and C<language.dat.lua>
-from the information present in the local TLPDB, plus
-locally-maintained files.
-
-The locally-maintained files are C<language-local.dat>,
-C<language-local.def>, or C<language-local.dat.lua>,
-searched for in C<TEXMFLOCAL> in the respective
-directories. If local additions are present, the final file is made by
-starting with the main file, omitting any entries that the local file
-specifies to be disabled, and finally appending the local file.
-
-(Historical note: The formerly supported C<updmap-local.cfg> and
-C<fmtutil-local.cnf> are no longer read, since C<updmap> and C<fmtutil>
-now reads and supports multiple configuration files. Thus,
-local additions can and should be put into an C<updmap.cfg> of C<fmtutil.cnf>
-file in C<TEXMFLOCAL>. The C<generate updmap> and C<generate fmtutil> actions
-no longer exist.)
-
-Local files specify entries to be disabled with a comment line, namely
-one of these:
-
- %!NAME
- --!NAME
-
-where C<language.dat> and C<language.def> use C<%>,
-and C<language.dat.lua> use C<-->. In all cases, the I<name> is
-the respective format name or hyphenation pattern identifier.
-Examples:
-
- %!german
- --!usenglishmax
-
-(Of course, you're not likely to actually want to disable those
-particular items. They're just examples.)
-
-After such a disabling line, the local file can include another entry
-for the same item, if a different definition is desired. In general,
-except for the special disabling lines, the local files follow the same
-syntax as the master files.
-
-The form C<generate language> recreates all three files C<language.dat>,
-C<language.def>, and C<language.dat.lua>, while the forms with an
-extension recreates only that given language file.
-
-Options:
-
-=over 4
-
-=item B<--dest> I<output_file>
-
-specifies the output file (defaults to the respective location in
-C<TEXMFSYSVAR>). If C<--dest> is given to C<generate language>, it
-serves as a basename onto which C<.dat> will be appended for the name of
-the C<language.dat> output file, C<.def> will be appended to the value
-for the name of the C<language.def> output file, and C<.dat.lua> to the
-name of the C<language.dat.lua> file. (This is just to avoid
-overwriting; if you want a specific name for each output file, we
-recommend invoking C<tlmgr> twice.)
-
-=item B<--localcfg> I<local_conf_file>
-
-specifies the (optional) local additions (defaults to the respective
-location in C<TEXMFLOCAL>).
-
-=item B<--rebuild-sys>
-
-tells C<tlmgr> to run necessary programs after config files have been
-regenerated. These are:
-C<fmtutil-sys --all> after C<generate fmtutil>,
-C<fmtutil-sys --byhyphen .../language.dat> after C<generate language.dat>,
-and
-C<fmtutil-sys --byhyphen .../language.def> after C<generate language.def>.
-
-These subsequent calls cause the newly-generated files to actually take
-effect. This is not done by default since those calls are lengthy
-processes and one might want to made several related changes in
-succession before invoking these programs.
-
-=back
-
-The respective locations are as follows:
-
- tex/generic/config/language.dat (and language-local.dat)
- tex/generic/config/language.def (and language-local.def)
- tex/generic/config/language.dat.lua (and language-local.dat.lua)
-
-=head2 gui
-
-Start the graphical user interface. See B<GUI> below.
-
-=head2 info
-
-=over 4
-
-=item B<info [I<option>...] I<pkg>...>
-
-=item B<info [I<option>...] collections>
-
-=item B<info [I<option>...] schemes>
-
-With no argument, lists all packages available at the package
-repository, prefixing those already installed with C<i>.
-
-With the single word C<collections> or C<schemes> as the argument, lists
-the request type instead of all packages.
-
-With any other arguments, display information about I<pkg>: the name,
-category, short and long description, sizes, installation status, and TeX Live
-revision number. If I<pkg> is not locally installed, searches in the
-remote installation source.
-
-For normal packages (not collections or schemes), the sizes of the four
-groups of files (run/src/doc/bin files) are shown separately. For
-collections, the cumulative size is shown, including all
-directly-dependent packages (but not dependent collections). For
-schemes, the cumulative size is also shown, including all
-directly-dependent collections and packages.
-
-If I<pkg> is not found locally or remotely, the search action is used
-and lists matching packages and files.
-
-It also displays information taken from the TeX Catalogue, namely the
-package version, date, and license. Consider these, especially the
-package version, as approximations only, due to timing skew of the
-updates of the different pieces. By contrast, the C<revision> value
-comes directly from TL and is reliable.
-
-The former actions C<show> and C<list> are merged into this action,
-but are still supported for backward compatibility.
-
-Options:
-
-=over 4
-
-=item B<--list>
-
-If the option C<--list> is given with a package, the list of contained
-files is also shown, including those for platform-specific dependencies.
-When given with schemes and collections, C<--list> outputs their
-dependencies in a similar way.
-
-=item B<--only-installed>
-
-If this option is given, the installation source will not be used; only
-locally installed packages, collections, or schemes are listed.
-
-=item B<--only-remote>
-
-Only list packages from the remote repository. Useful when checking what
-is available in a remote repository using
-C<tlmgr --repo ... --only-remote info>. Note that
-C<--only-installed> and C<--only-remote> cannot both be specified.
-
-=item B<--data C<item1,item2,...>>
-
-If the option C<--data> is given, its argument must be a comma separated
-list of field names from: C<name>, C<category>, C<localrev>,
-C<remoterev>, C<shortdesc>, C<longdesc>, C<installed>, C<size>,
-C<relocatable>, C<depends>, C<cat-version>, C<cat-date>, C<cat-license>,
-plus various C<cat-contact-*> fields (see below).
-
-The C<cat-*> fields all come from the TeX Catalogue
-(L<https://ctan.org/pkg/catalogue>). For each, there are two more
-variants with prefix C<l> and C<r>, e.g., C<lcat-version> and
-C<rcat-version>, which indicate the local and remote information,
-respectively. The variants without C<l> and C<r> show the most current
-one, which is normally the remote value.
-
-The requested packages' information is listed in CSV format, one package
-per line, and the column information is given by the C<itemN>. The
-C<depends> column contains the names of all the dependencies separated
-by C<:> characters.
-
-At this writing, the C<cat-contact-*> fields include: C<home>,
-C<repository>, C<support>, C<bugs>, C<announce>, C<development>. Each
-may be empty or a url value. A brief description is on the CTAN upload
-page for new packages: L<https://ctan.org/upload>.
-
-=item B<--json>
-
-In case C<--json> is specified, the output is a JSON encoded array where
-each array element is the JSON representation of a single C<TLPOBJ> but
-with additional information. For details see
-C<tlpkg/doc/JSON-formats.txt>, format definition: C<TLPOBJINFO>. If both
-C<--json> and C<--data> are given, C<--json> takes precedence.
-
-=back
-
-=back
-
-=head2 init-usertree
-
-Sets up a texmf tree for so-called user mode management, either the
-default user tree (C<TEXMFHOME>), or one specified on the command line
-with C<--usertree>. See L<USER MODE> below.
-
-=head2 install [I<option>...] I<pkg>...
-
-Install each I<pkg> given on the command line, if it is not already
-installed. It does not touch existing packages; see the C<update>
-action for how to get the latest version of a package.
-
-By default this also installs all packages on which the given I<pkg>s are
-dependent. Options:
-
-=over 4
-
-=item B<--dry-run>
-
-Nothing is actually installed; instead, the actions to be performed are
-written to the terminal.
-
-=item B<--file>
-
-Instead of fetching a package from the installation repository, use
-the package files given on the command line. These files must
-be standard TeX Live package files (with contained tlpobj file).
-
-=item B<--force>
-
-If updates to C<tlmgr> itself (or other parts of the basic
-infrastructure) are present, C<tlmgr> will bail out and not perform the
-installation unless this option is given. Not recommended.
-
-=item B<--no-depends>
-
-Do not install dependencies. (By default, installing a package ensures
-that all dependencies of this package are fulfilled.)
-
-=item B<--no-depends-at-all>
-
-Normally, when you install a package which ships binary files the
-respective binary package will also be installed. That is, for a
-package C<foo>, the package C<foo.i386-linux> will also be installed on
-an C<i386-linux> system. This option suppresses this behavior, and also
-implies C<--no-depends>. Don't use it unless you are sure of what you
-are doing.
-
-=item B<--reinstall>
-
-Reinstall a package (including dependencies for collections) even if it
-already seems to be installed (i.e, is present in the TLPDB). This is
-useful to recover from accidental removal of files in the hierarchy.
-
-When re-installing, only dependencies on normal packages are followed
-(i.e., not those of category Scheme or Collection).
-
-=item B<--with-doc>
-
-=item B<--with-src>
-
-While not recommended, the C<install-tl> program provides an option to
-omit installation of all documentation and/or source files. (By
-default, everything is installed.) After such an installation, you may
-find that you want the documentation or source files for a given package
-after all. You can get them by using these options in conjunction with
-C<--reinstall>, as in (using the C<fontspec> package as the example):
-
- tlmgr install --reinstall --with-doc --with-src fontspec
-
-=back
-
-This action does not automatically add new symlinks in system
-directories; you need to run C<tlmgr path add> (L</path>) yourself if
-you are using this feature and want new symlinks added.
-
-=head2 key
-
-=over 4
-
-=item B<key list>
-
-=item B<key add I<file>>
-
-=item B<key remove I<keyid>>
-
-The action C<key> allows listing, adding and removing additional GPG
-keys to the set of trusted keys, that is, those that are used to verify
-the TeX Live databases.
-
-With the C<list> argument, C<key> lists all keys.
-
-The C<add> argument requires another argument, either a filename or
-C<-> for stdin, from which the key is added. The key is added to the
-local keyring C<GNUPGHOME/repository-keys.gpg>, which is normally
-C<tlpkg/gpg/repository-keys.gpg>.
-
-The C<remove> argument requires a key id and removes the requested id
-from the local keyring.
-
-=back
-
-=head2 list
-
-Synonym for L</info>.
-
-=head2 option
-
-=over 4
-
-=item B<option [--json] [show]>
-
-=item B<option [--json] showall|help>
-
-=item B<option I<key> [I<value>]>
-
-=back
-
-The first form, C<show>, shows the global TeX Live settings currently
-saved in the TLPDB with a short description and the C<key> used for
-changing it in parentheses.
-
-The second form, C<showall>, is similar, but also shows options which
-can be defined but are not currently set to any value (C<help> is a
-synonym).
-
-Both C<show...> forms take an option C<--json>, which dumps the option
-information in JSON format. In this case, both forms dump the same
-data. For the format of the JSON output see
-C<tlpkg/doc/JSON-formats.txt>, format definition C<TLOPTION>.
-
-In the third form, with I<key>, if I<value> is not given, the setting
-for I<key> is displayed. If I<value> is present, I<key> is set to
-I<value>.
-
-Possible values for I<key> are (run C<tlmgr option showall> for
-the definitive list):
-
- repository (default package repository),
- formats (generate formats at installation or update time),
- postcode (run postinst code blobs)
- docfiles (install documentation files),
- srcfiles (install source files),
- backupdir (default directory for backups),
- autobackup (number of backups to keep).
- sys_bin (directory to which executables are linked by the path action)
- sys_man (directory to which man pages are linked by the path action)
- sys_info (directory to which Info files are linked by the path action)
- desktop_integration (Windows-only: create Start menu shortcuts)
- fileassocs (Windows-only: change file associations)
- multiuser (Windows-only: install for all users)
-
-One common use of C<option> is to permanently change the installation to
-get further updates from the Internet, after originally installing from
-DVD. To do this, you can run
-
- tlmgr option repository http://mirror.ctan.org/systems/texlive/tlnet
-
-The C<install-tl> documentation has more information about the possible
-values for C<repository>. (For backward compatibility, C<location> can
-be used as a synonym for C<repository>.)
-
-If C<formats> is set (this is the default), then formats are regenerated
-when either the engine or the format files have changed. Disable this
-only when you know how and want to regenerate formats yourself whenever
-needed (which is often, in practice).
-
-The C<postcode> option controls execution of per-package
-postinstallation action code. It is set by default, and again disabling
-is not likely to be of interest except to developers doing debugging.
-
-The C<docfiles> and C<srcfiles> options control the installation of
-their respective file groups (documentation, sources; grouping is
-approximate) per package. By default both are enabled (1). Either or
-both can be disabled (set to 0) if disk space is limited or for minimal
-testing installations, etc. When disabled, the respective files are not
-downloaded at all.
-
-The options C<autobackup> and C<backupdir> determine the defaults for
-the actions C<update>, C<backup> and C<restore>. These three actions
-need a directory in which to read or write the backups. If
-C<--backupdir> is not specified on the command line, the C<backupdir>
-option value is used (if set). The TL installer sets C<backupdir> to
-C<.../tlpkg/backups>, under the TL root installation directory.
-
-The C<autobackup> option (de)activates automatic generation of backups.
-Its value is an integer. If the C<autobackup> value is C<-1>, no
-backups are removed. If C<autobackup> is 0 or more, it specifies the
-number of backups to keep. Thus, backups are disabled if the value is
-0. In the C<--clean> mode of the C<backup> action this option also
-specifies the number to be kept. The default value is 1, so that
-backups are made, but only one backup is kept.
-
-To setup C<autobackup> to C<-1> on the command line, use:
-
- tlmgr option -- autobackup -1
-
-The C<--> avoids having the C<-1> treated as an option. (The C<-->
-stops parsing for options at the point where it appears; this is a
-general feature across most Unix programs.)
-
-The C<sys_bin>, C<sys_man>, and C<sys_info> options are used on Unix
-systems to control the generation of links for executables, Info files
-and man pages. See the C<path> action for details.
-
-The last three options affect behavior on Windows installations. If
-C<desktop_integration> is set, then some packages will install items in
-a sub-folder of the Start menu for C<tlmgr gui>, documentation, etc. If
-C<fileassocs> is set, Windows file associations are made (see also the
-C<postaction> action). Finally, if C<multiuser> is set, then adaptions
-to the registry and the menus are done for all users on the system
-instead of only the current user. All three options are on by default.
-
-=head2 paper
-
-=over 4
-
-=item B<paper [a4|letter]>
-
-=item B<<[xdvi|pdftex|dvips|dvipdfmx|context|psutils] paper [I<papersize>|--list]>>
-
-=item B<paper --json>
-
-=back
-
-With no arguments (C<tlmgr paper>), shows the default paper size setting
-for all known programs.
-
-With one argument (e.g., C<tlmgr paper a4>), sets the default for all
-known programs to that paper size.
-
-With a program given as the first argument and no paper size specified
-(e.g., C<tlmgr dvips paper>), shows the default paper size for that
-program.
-
-With a program given as the first argument and a paper size as the last
-argument (e.g., C<tlmgr dvips paper a4>), set the default for that
-program to that paper size.
-
-With a program given as the first argument and C<--list> given as the
-last argument (e.g., C<tlmgr dvips paper --list>), shows all valid paper
-sizes for that program. The first size shown is the default.
-
-If C<--json> is specified without other options, the paper setup is
-dumped in JSON format. For the format of JSON output see
-C<tlpkg/doc/JSON-formats.txt>, format definition C<TLPAPER>.
-
-Incidentally, this syntax of having a specific program name before the
-C<paper> keyword is unusual. It is inherited from the longstanding
-C<texconfig> script, which supports other configuration settings for
-some programs, notably C<dvips>. C<tlmgr> does not support those extra
-settings.
-
-=head2 path
-
-=over 4
-
-=item B<path [--w32mode=user|admin] add>
-
-=item B<path [--w32mode=user|admin] remove>
-
-On Unix, adds or removes symlinks for executables, man pages, and info
-pages in the system directories specified by the respective options (see
-the L</option> description above). Does not change any initialization
-files, either system or personal. Furthermore, any executables added or
-removed by future updates are not taken care of automatically; this
-command must be rerun as needed.
-
-On Windows, the registry part where the binary directory is added or
-removed is determined in the following way:
-
-If the user has admin rights, and the option C<--w32mode> is not given,
-the setting I<w32_multi_user> determines the location (i.e., if it is
-on then the system path, otherwise the user path is changed).
-
-If the user has admin rights, and the option C<--w32mode> is given, this
-option determines the path to be adjusted.
-
-If the user does not have admin rights, and the option C<--w32mode>
-is not given, and the setting I<w32_multi_user> is off, the user path
-is changed, while if the setting I<w32_multi_user> is on, a warning is
-issued that the caller does not have enough privileges.
-
-If the user does not have admin rights, and the option C<--w32mode>
-is given, it must be C<user> and the user path will be adjusted. If a
-user without admin rights uses the option C<--w32mode admin> a warning
-is issued that the caller does not have enough privileges.
-
-=back
-
-=head2 pinning
-
-The C<pinning> action manages the pinning file, see L</Pinning> below.
-
-=over 4
-
-=item C<pinning show>
-
-Shows the current pinning data.
-
-=item C<pinning add> I<repo> I<pkgglob>...
-
-Pins the packages matching the I<pkgglob>(s) to the repository
-I<repo>.
-
-=item C<pinning remove> I<repo> I<pkgglob>...
-
-Any packages recorded in the pinning file matching the <pkgglob>s for
-the given repository I<repo> are removed.
-
-=item C<pinning remove I<repo> --all>
-
-Remove all pinning data for repository I<repo>.
-
-=back
-
-=head2 platform
-
-=over 4
-
-=item B<platform list|add|remove I<platform>...>
-
-=item B<platform set I<platform>>
-
-=item B<platform set auto>
-
-C<platform list> lists the TeX Live names of all the platforms
-(a.k.a. architectures), (C<i386-linux>, ...) available at the package
-repository.
-
-C<platform add> I<platform>... adds the executables for each given platform
-I<platform> to the installation from the repository.
-
-C<platform remove> I<platform>... removes the executables for each given
-platform I<platform> from the installation, but keeps the currently
-running platform in any case.
-
-C<platform set> I<platform> switches TeX Live to always use the given
-platform instead of auto detection.
-
-C<platform set auto> switches TeX Live to auto detection mode for platform.
-
-Platform detection is needed to select the proper C<xz> and
-C<wget> binaries that are shipped with TeX Live.
-
-C<arch> is a synonym for C<platform>.
-
-Options:
-
-=over 4
-
-=item B<--dry-run>
-
-Nothing is actually installed; instead, the actions to be performed are
-written to the terminal.
-
-=back
-
-=back
-
-=cut
-
-# keep the following on *ONE* line otherwise Losedows perldoc does
-# not show it!!!!
-
-=pod
-
-=head2 postaction
-
-=over 4
-
-=item B<postaction [I<option>...] install [shortcut|fileassoc|script] [I<pkg>...]>
-
-=item B<postaction [I<option>...] remove [shortcut|fileassoc|script] [I<pkg>...]>
-
-Carry out the postaction C<shortcut>, C<fileassoc>, or C<script> given
-as the second required argument in install or remove mode (which is the
-first required argument), for either the packages given on the command
-line, or for all if C<--all> is given.
-
-Options:
-
-=over 4
-
-=item B<--w32mode=[user|admin]>
-
-If the option C<--w32mode> is given the value C<user>, all actions will
-only be carried out in the user-accessible parts of the
-registry/filesystem, while the value C<admin> selects the system-wide
-parts of the registry for the file associations. If you do not have
-enough permissions, using C<--w32mode=admin> will not succeed.
-
-=item B<--fileassocmode=[1|2]>
-
-C<--fileassocmode> specifies the action for file associations. If it is
-set to 1 (the default), only new associations are added; if it is set to
-2, all associations are set to the TeX Live programs. (See also
-C<option fileassocs>.)
-
-=item B<--all>
-
-Carry out the postactions for all packages
-
-=back
-
-=back
-
-=head2 print-platform
-
-Print the TeX Live identifier for the detected platform
-(hardware/operating system) combination to standard output, and exit.
-C<--print-arch> is a synonym.
-
-=head2 print-platform-info
-
-Print the TeX Live platform identifier, TL platform long name, and
-original output from guess.
-
-=head2 remove [I<option>...] I<pkg>...
-
-Remove each I<pkg> specified. Removing a collection removes all package
-dependencies (unless C<--no-depends> is specified), but not any
-collection dependencies of that collection. However, when removing a
-package, dependencies are never removed. Options:
-
-=over 4
-
-=item B<--all>
-
-Uninstalls all of TeX Live, asking for confirmation unless C<--force> is
-also specified.
-
-=item B<--backup>
-
-=item B<--backupdir> I<directory>
-
-These options behave just as with the L<update|/update
-[I<option>...] [I<pkg>...]> action (q.v.), except they apply to making
-backups of packages before they are removed. The default is to make
-such a backup, that is, to save a copy of packages before removal.
-
-The L</restore> action explains how to restore from a backup.
-
-=item B<--no-depends>
-
-Do not remove dependent packages.
-
-=item B<--no-depends-at-all>
-
-See above under L<install|/install [I<option>...] I<pkg>...> (and beware).
-
-=item B<--force>
-
-By default, removal of a package or collection that is a dependency of
-another collection or scheme is not allowed. With this option, the
-package will be removed unconditionally. Use with care.
-
-A package that has been removed using the C<--force> option because it
-is still listed in an installed collection or scheme will not be
-updated, and will be mentioned as C<forcibly removed> in the output of
-C<tlmgr update --list>.
-
-=item B<--dry-run>
-
-Nothing is actually removed; instead, the actions to be performed are
-written to the terminal.
-
-=back
-
-This action does not automatically remove symlinks to executables from
-system directories; you need to run C<tlmgr path remove> (L</path>)
-yourself if you are using this feature and want stale symlinks removed.
-
-=head2 repository
-
-=over 4
-
-=item B<repository list>
-
-=item B<repository list I<path|url|tag>>
-
-=item B<repository add I<path> [I<tag>]>
-
-=item B<repository remove I<path|tag>>
-
-=item B<repository set I<path>[#I<tag>] [I<path>[#I<tag>] ...]>
-
-=item B<repository status>
-
-This action manages the list of repositories. See L<MULTIPLE
-REPOSITORIES> below for detailed explanations.
-
-The first form, C<repository list>, lists all configured repositories
-and the respective tags if set. If a path, url, or tag is given after
-the C<list> keyword, it is interpreted as the source from which to
-initialize a TL database and lists the contained packages. This can also
-be an otherwise-unused repository, either local or remote. If the option
-C<--with-platforms> is specified in addition, for each package the
-available platforms (if any) are also listed.
-
-The form C<repository add> adds a repository (optionally attaching a
-tag) to the list of repositories, while C<repository remove> removes a
-repository, either by full path/url, or by tag.
-
-The form C<repository set> sets the list of available repositories to
-the items given on the command line, overwriting previous settings.
-
-The form C<repository status> reports the verification status of the
-loaded repositories with the format of one repository per line
-with fields separated by a single space:
-
-=over 4
-
-=item The tag (which can be the same as the url);
-
-= the url;
-
-= iff machine-readable output is specified, the verification code (a
-number);
-
-= a textual description of the verification status, as the last field
-extending to the end of line.
-
-=back
-
-That is, in normal (not machine-readable) output, the third field
-(numeric verification status) is not present.
-
-In all cases, one of the repositories must be tagged as C<main>;
-otherwise, all operations will fail!
-
-=back
-
-=head2 restore
-
-=over 4
-
-=item B<restore [I<option>...] I<pkg> [I<rev>]>
-
-=item B<restore [I<option>...] --all>
-
-Restore a package from a previously-made backup.
-
-If C<--all> is given, try to restore the latest revision of all
-package backups found in the backup directory.
-
-Otherwise, if neither I<pkg> nor I<rev> are given, list the available
-backup revisions for all packages. With I<pkg> given but no I<rev>,
-list all available backup revisions of I<pkg>.
-
-When listing available packages, C<tlmgr> shows the revision, and in
-parenthesis the creation time if available (in format yyyy-mm-dd hh:mm).
-
-If (and only if) both I<pkg> and a valid revision number I<rev> are
-specified, try to restore the package from the specified backup.
-
-Options:
-
-=over 4
-
-=item B<--all>
-
-Try to restore the latest revision of all package backups found in the
-backup directory. Additional non-option arguments (like I<pkg>) are not
-allowed.
-
-=item B<--backupdir> I<directory>
-
-Specify the directory where the backups are to be found. If not given it
-will be taken from the configuration setting in the TLPDB.
-
-=item B<--dry-run>
-
-Nothing is actually restored; instead, the actions to be performed are
-written to the terminal.
-
-=item B<--force>
-
-Don't ask questions.
-
-=item B<--json>
-
-When listing backups, the option C<--json> turn on JSON output.
-The format is an array of JSON objects (C<name>, C<rev>, C<date>).
-For details see C<tlpkg/doc/JSON-formats.txt>, format definition: C<TLBACKUPS>.
-If both C<--json> and C<--data> are given, C<--json> takes precedence.
-
-=back
-
-=back
-
-=head2 search
-
-=over 4
-
-=item B<search [I<option>...] I<what>>
-
-=item B<search [I<option>...] --file I<what>>
-
-=item B<search [I<option>...] --all I<what>>
-
-By default, search the names, short descriptions, and long descriptions
-of all locally installed packages for the argument I<what>, interpreted
-as a (Perl) regular expression.
-
-Options:
-
-=over 4
-
-=item B<--file>
-
-List all filenames containing I<what>.
-
-=item B<--all>
-
-Search everything: package names, descriptions and filenames.
-
-=item B<--global>
-
-Search the TeX Live Database of the installation medium, instead of the
-local installation.
-
-=item B<--word>
-
-Restrict the search of package names and descriptions (but not
-filenames) to match only full words. For example, searching for
-C<table> with this option will not output packages containing the word
-C<tables> (unless they also contain the word C<table> on its own).
-
-=back
-
-=back
-
-=head2 shell
-
-Starts an interactive mode, where tlmgr prompts for commands. This can
-be used directly, or for scripting. The first line of output is
-C<protocol> I<n>, where I<n> is an unsigned number identifying the
-protocol version (currently 1).
-
-In general, tlmgr actions that can be given on the command line
-translate to commands in this shell mode. For example, you can say
-C<update --list> to see what would be updated. The TLPDB is loaded the
-first time it is needed (not at the beginning), and used for the rest of
-the session.
-
-Besides these actions, a few commands are specific to shell mode:
-
-=over 4
-
-=item protocol
-
-Print C<protocol I<n>>, the current protocol version.
-
-=item help
-
-Print pointers to this documentation.
-
-=item version
-
-Print tlmgr version information.
-
-=item quit, end, bye, byebye, EOF
-
-Exit.
-
-=item restart
-
-Restart C<tlmgr shell> with the original command line; most useful when
-developing C<tlmgr>.
-
-=item load [local|remote]
-
-Explicitly load the local or remote, respectively, TLPDB.
-
-=item save
-
-Save the local TLPDB, presumably after other operations have changed it.
-
-=item get [I<var>]
-=item set [I<var> [I<val>]]
-
-Get the value of I<var>, or set it to I<val>. Possible I<var> names:
-C<debug-translation>, C<machine-readable>, C<no-execute-actions>,
-C<require-verification>, C<verify-downloads>, C<repository>, and
-C<prompt>. All except C<repository> and C<prompt> are booleans, taking
-values 0 and 1, and behave like the corresponding command line option.
-The C<repository> variable takes a string, and sets the remote
-repository location. The C<prompt> variable takes a string, and sets the
-current default prompt.
-
-If I<var> or then I<val> is not specified, it is prompted for.
-
-=back
-
-=head2 show
-
-Synonym for L</info>.
-
-=head2 uninstall
-
-Synonym for L<remove|/remove [I<option>...] I<pkg>...>.
-
-=head2 update [I<option>...] [I<pkg>...]
-
-Updates the packages given as arguments to the latest version available
-at the installation source. Either C<--all> or at least one I<pkg> name
-must be specified. Options:
-
-=over 4
-
-=item B<--all>
-
-Update all installed packages except for C<tlmgr> itself. If updates to
-C<tlmgr> itself are present, this gives an error, unless also the option
-C<--force> or C<--self> is given. (See below.)
-
-In addition to updating the installed packages, during the update of a
-collection the local installation is (by default) synchronized to the
-status of the collection on the server, for both additions and removals.
-
-This means that if a package has been removed on the server (and thus
-has also been removed from the respective collection), C<tlmgr> will
-remove the package in the local installation. This is called
-``auto-remove'' and is announced as such when using the option
-C<--list>. This auto-removal can be suppressed using the option
-C<--no-auto-remove> (not recommended, see option description).
-
-Analogously, if a package has been added to a collection on the server
-that is also installed locally, it will be added to the local
-installation. This is called ``auto-install'' and is announced as such
-when using the option C<--list>. This auto-installation can be
-suppressed using the option C<--no-auto-install> (also not recommended).
-
-An exception to the collection dependency checks (including the
-auto-installation of packages just mentioned) are those that have been
-``forcibly removed'' by you, that is, you called C<tlmgr remove --force>
-on them. (See the C<remove> action documentation.) To reinstall any
-such forcibly removed packages use C<--reinstall-forcibly-removed>.
-
-To reiterate: automatic removals and additions are entirely determined
-by comparison of collections. Thus, if you manually install an
-individual package C<foo> which is later removed from the server,
-C<tlmgr> will not notice and will not remove it locally. (It has to be
-this way, without major rearchitecture work, because the tlpdb does not
-record the repository from which packages come from.)
-
-If you want to exclude some packages from the current update run (e.g.,
-due to a slow link), see the C<--exclude> option below.
-
-=item B<--self>
-
-Update C<tlmgr> itself (that is, the infrastructure packages) if updates
-to it are present. On Windows this includes updates to the private Perl
-interpreter shipped inside TeX Live.
-
-If this option is given together with either C<--all> or a list of
-packages, then C<tlmgr> will be updated first and, if this update
-succeeds, the new version will be restarted to complete the rest of the
-updates.
-
-In short:
-
- tlmgr update --self # update infrastructure only
- tlmgr update --self --all # update infrastructure and all packages
- tlmgr update --force --all # update all packages but *not* infrastructure
- # ... this last at your own risk, not recommended!
-
-=item B<--dry-run>
-
-Nothing is actually installed; instead, the actions to be performed are
-written to the terminal. This is a more detailed report than C<--list>.
-
-=item B<--list> [I<pkg>]
-
-Concisely list the packages which would be updated, newly installed, or
-removed, without actually changing anything.
-If C<--all> is also given, all available updates are listed.
-If C<--self> is given, but not C<--all>, only updates to the
-critical packages (tlmgr, texlive infrastructure, perl on Windows, etc.)
-are listed.
-If neither C<--all> nor C<--self> is given, and in addition no I<pkg> is
-given, then C<--all> is assumed (thus, C<tlmgr update --list> is the
-same as C<tlmgr update --list --all>).
-If neither C<--all> nor C<--self> is given, but specific package names are
-given, those packages are checked for updates.
-
-=item B<--exclude> I<pkg>
-
-Exclude I<pkg> from the update process. If this option is given more
-than once, its arguments accumulate.
-
-An argument I<pkg> excludes both the package I<pkg> itself and all
-its related platform-specific packages I<pkg.ARCH>. For example,
-
- tlmgr update --all --exclude a2ping
-
-will not update C<a2ping>, C<a2ping.i386-linux>, or
-any other C<a2ping.>I<ARCH> package.
-
-If this option specifies a package that would otherwise be a candidate
-for auto-installation, auto-removal, or reinstallation of a forcibly
-removed package, C<tlmgr> quits with an error message. Excludes are not
-supported in these circumstances.
-
-This option can also be set permanently in the tlmgr config file with
-the key C<update-exclude>.
-
-=item B<--no-auto-remove> [I<pkg>...]
-
-By default, C<tlmgr> tries to remove packages in an existing collection
-which have disappeared on the server, as described above under C<--all>.
-This option prevents such removals, either for all packages (with
-C<--all>), or for just the given I<pkg> names. This can lead to an
-inconsistent TeX installation, since packages are not infrequently
-renamed or replaced by their authors. Therefore this is not recommended.
-
-=item B<--no-auto-install> [I<pkg>...]
-
-Under normal circumstances C<tlmgr> will install packages which are new
-on the server, as described above under C<--all>. This option prevents
-any such automatic installation, either for all packages (with
-C<--all>), or the given I<pkg> names.
-
-Furthermore, after the C<tlmgr> run using this has finished, the
-packages that would have been auto-installed I<will be considered as
-forcibly removed>. So, if C<foobar> is the only new package on the
-server, then
-
- tlmgr update --all --no-auto-install
-
-is equivalent to
-
- tlmgr update --all
- tlmgr remove --force foobar
-
-Again, since packages are sometimes renamed or replaced, using this
-option is not recommended.
-
-=item B<--reinstall-forcibly-removed>
-
-Under normal circumstances C<tlmgr> will not install packages that have
-been forcibly removed by the user; that is, removed with C<remove
---force>, or whose installation was prohibited by C<--no-auto-install>
-during an earlier update.
-
-This option makes C<tlmgr> ignore the forcible removals and re-install
-all such packages. This can be used to completely synchronize an
-installation with the server's idea of what is available:
-
- tlmgr update --reinstall-forcibly-removed --all
-
-=item B<--backup>
-
-=item B<--backupdir> I<directory>
-
-These two options control the creation of backups of packages I<before>
-updating; that is, backing up packages as currently installed. If
-neither option is given, no backup will made. If C<--backupdir> is
-given and specifies a writable directory then a backup will be made in
-that location. If only C<--backup> is given, then a backup will be made
-to the directory previously set via the L</option> action (see
-below). If both are given then a backup will be made to the specified
-I<directory>.
-
-You can also set options via the L</option> action to automatically make
-backups for all packages, and/or keep only a certain number of backups.
-
-C<tlmgr> always makes a temporary backup when updating packages, in case
-of download or other failure during an update. In contrast, the purpose
-of this C<--backup> option is to save a persistent backup in case the
-actual I<content> of the update causes problems, e.g., introduces an TeX
-incompatibility.
-
-The L</restore> action explains how to restore from a backup.
-
-=item B<--no-depends>
-
-If you call for updating a package normally all depending packages
-will also be checked for updates and updated if necessary. This switch
-suppresses this behavior.
-
-=item B<--no-depends-at-all>
-
-See above under L<install|/install [I<option>...] I<pkg>...> (and beware).
-
-=item B<--force>
-
-Force update of normal packages, without updating C<tlmgr> itself
-(unless the C<--self> option is also given). Not recommended.
-
-Also, C<update --list> is still performed regardless of this option.
-
-=back
-
-If the package on the server is older than the package already installed
-(e.g., if the selected mirror is out of date), C<tlmgr> does not
-downgrade. Also, packages for uninstalled platforms are not installed.
-
-C<tlmgr> saves one copy of the main C<texlive.tlpdb> file used for an
-update with a suffix representing the repository url, as in
-C<tlpkg/texlive.tlpdb.main.>I<long-hash-string>. Thus, even when many
-mirrors are used, only one main C<tlpdb> backup is kept. For non-main
-repositories, which do not generally have (m)any mirrors, no pruning of
-backups is done.
-
-This action does not automatically add or remove new symlinks in system
-directories; you need to run C<tlmgr> L</path> yourself if you are using
-this feature and want new symlinks added.
-
-=head1 CONFIGURATION FILE FOR TLMGR
-
-C<tlmgr> reads two configuration files: one is system-wide, in
-C<TEXMFSYSCONFIG/tlmgr/config>, and the other is user-specific, in
-C<TEXMFCONFIG/tlmgr/config>. The user-specific one is the default for
-the C<conf tlmgr> action. (Run C<kpsewhich
--var-value=TEXMFSYSCONFIG> or C<... TEXMFCONFIG ...> to see the actual
-directory names.)
-
-A few defaults corresponding to command-line options can be set in these
-configuration files. In addition, the system-wide file can contain a
-directive to restrict the allowed actions.
-
-In these config files, empty lines and lines starting with # are
-ignored. All other lines must look like:
-
- key = value
-
-where the spaces are optional but the C<=> is required.
-
-The allowed keys are:
-
-=over 4
-
-=item C<auto-remove>, value 0 or 1 (default 1), same as command-line
-option.
-
-=item C<gui-expertmode>, value 0 or 1 (default 1).
-This switches between the full GUI and a simplified GUI with only the
-most common settings.
-
-=item C<gui-lang> I<llcode>, with a language code value as with the
-command-line option.
-
-=item C<no-checksums>, value 0 or 1 (default 0, see below).
-
-=item C<persistent-downloads>, value 0 or 1 (default 1), same as
-command-line option.
-
-=item C<require-verification>, value 0 or 1 (default 0), same as
-command-line option.
-
-=item C<tkfontscale>, value any float.
-Controls the scaling of fonts in the Tk based frontends.
-
-=item C<update-exclude>, value: comma-separated list of packages
-(no space allowed). Same as the command line option C<--exclude>
-for the action C<update>.
-
-=item C<verify-downloads>, value 0 or 1 (default 1), same as
-command-line option.
-
-=back
-
-The system-wide config file can contain one additional key:
-
-=over 4
-
-=item C<allowed-actions> I<action1> [,I<action>,...]
-The value is a comma-separated list of C<tlmgr> actions which are
-allowed to be executed when C<tlmgr> is invoked in system mode (that is,
-without C<--usermode>).
-
-This allows distributors to include the C<tlmgr> in their packaging, but
-allow only a restricted set of actions that do not interfere with their
-distro package manager. For native TeX Live installations, it doesn't
-make sense to set this.
-
-=back
-
-The C<no-checksums> key needs more explanation. By default, package
-checksums computed and stored on the server (in the TLPDB) are compared
-to checksums computed locally after downloading. C<no-checksums>
-disables this process.
-
-The checksum algorithm is SHA-512. Your system must have one of (looked
-for in this order) the Perl C<Digest::SHA> module, the C<openssl>
-program (L<https://openssl.org>), the C<sha512sum> program (from GNU
-Coreutils, L<https://www.gnu.org/software/coreutils>), or finally the
-C<shasum> program (just to support old Macs). If none of these are
-available, a warning is issued and C<tlmgr> proceeds without checking
-checksums. (Incidentally, other SHA implementations, such as the pure
-Perl and pure Lua modules, are much too slow to be usable in our
-context.) C<no-checksums> avoids the warning.
-
-=head1 CRYPTOGRAPHIC VERIFICATION
-
-C<tlmgr> and C<install-tl> perform cryptographic verification if
-possible. If verification is performed and successful, the programs
-report C<(verified)> after loading the TLPDB; otherwise, they report
-C<(not verified)>. But either way, by default the installation and/or
-updates proceed normally.
-
-If a program named C<gpg> is available (that is, found in C<PATH>), by
-default cryptographic signatures will be checked: we require the main
-repository be signed, but not any additional repositories. If C<gpg> is
-not available, by default signatures are not checked and no verification
-is carried out, but C<tlmgr> still proceeds normally.
-
-The behavior of the verification can be controlled by the command line
-and config file option C<verify-repo> which takes one of the following
-values: C<none>, C<main>, or C<all>. With C<none>, no verification
-whatsoever is attempted. With C<main> (the default) verification is
-required only for the main repository, and only if C<gpg> is available;
-though attempted for all, missing signatures of subsidiary repositories
-will not result in an error. Finally, in the case of C<all>, C<gpg>
-must be available and all repositories need to be signed.
-
-In all cases, if a signature is checked and fails to verify, an error
-is raised.
-
-Cryptographic verification requires checksum checking (described just
-above) to succeed, and a working GnuPG (C<gpg>) program (see below for
-search method). Then, unless cryptographic verification has been
-disabled, a signature file (C<texlive.tlpdb.*.asc>) of the checksum file
-is downloaded and the signature verified. The signature is created by
-the TeX Live Distribution GPG key 0x0D5E5D9106BAB6BC, which in turn is
-signed by Karl Berry's key 0x0716748A30D155AD and
-Norbert Preining's key 0x6CACA448860CDC13. All
-of these keys are obtainable from the standard key servers.
-
-Additional trusted keys can be added using the C<key> action.
-
-=head2 Configuration of GnuPG invocation
-
-The executable used for GnuPG is searched as follows: If the environment
-variable C<TL_GNUPG> is set, it is tested and used; otherwise C<gpg> is
-checked; finally C<gpg2> is checked.
-
-Further adaptation of the C<gpg> invocation can be made using the two
-environment variables C<TL_GNUPGHOME>, which is passed to C<gpg> as the
-value for C<--homedir>, and C<TL_GNUPGARGS>, which replaces the default
-options C<--no-secmem-warning --no-permission-warning>.
-
-=head1 USER MODE
-
-C<tlmgr> provides a restricted way, called ``user mode'', to manage
-arbitrary texmf trees in the same way as the main installation. For
-example, this allows people without write permissions on the
-installation location to update/install packages into a tree of their
-own.
-
-C<tlmgr> is switched into user mode with the command line option
-C<--usermode>. It does not switch automatically, nor is there any
-configuration file setting for it. Thus, this option has to be
-explicitly given every time user mode is to be activated.
-
-This mode of C<tlmgr> works on a user tree, by default the value of the
-C<TEXMFHOME> variable. This can be overridden with the command line
-option C<--usertree>. In the following when we speak of the user tree
-we mean either C<TEXMFHOME> or the one given on the command line.
-
-Not all actions are allowed in user mode; C<tlmgr> will warn you and not
-carry out any problematic actions. Currently not supported (and
-probably will never be) is the C<platform> action. The C<gui> action is
-currently not supported, but may be in a future release.
-
-Some C<tlmgr> actions don't need any write permissions and thus work the
-same in user mode and normal mode. Currently these are: C<check>,
-C<help>, C<list>, C<print-platform>, C<print-platform-info>, C<search>,
-C<show>, C<version>.
-
-On the other hand, most of the actions dealing with package management
-do need write permissions, and thus behave differently in user mode, as
-described below: C<install>, C<update>, C<remove>, C<option>, C<paper>,
-C<generate>, C<backup>, C<restore>, C<uninstall>, C<symlinks>.
-
-Before using C<tlmgr> in user mode, you have to set up the user tree
-with the C<init-usertree> action. This creates I<usertree>C</web2c> and
-I<usertree>C</tlpkg/tlpobj>, and a minimal
-I<usertree>C</tlpkg/texlive.tlpdb>. At that point, you can tell
-C<tlmgr> to do the (supported) actions by adding the C<--usermode>
-command line option.
-
-In user mode the file I<usertree>C</tlpkg/texlive.tlpdb> contains only
-the packages that have been installed into the user tree using C<tlmgr>,
-plus additional options from the ``virtual'' package
-C<00texlive.installation> (similar to the main installation's
-C<texlive.tlpdb>).
-
-All actions on packages in user mode can only be carried out on packages
-that are known as C<relocatable>. This excludes all packages containing
-executables and a few other core packages. Of the 2500 or so packages
-currently in TeX Live the vast majority are relocatable and can be
-installed into a user tree.
-
-Description of changes of actions in user mode:
-
-=head2 User mode install
-
-In user mode, the C<install> action checks that the package and all
-dependencies are all either relocated or already installed in the system
-installation. If this is the case, it unpacks all containers to be
-installed into the user tree (to repeat, that's either C<TEXMFHOME> or
-the value of C<--usertree>) and add the respective packages to the user
-tree's C<texlive.tlpdb> (creating it if need be).
-
-Currently installing a collection in user mode installs all dependent
-packages, but in contrast to normal mode, does I<not> install dependent
-collections. For example, in normal mode C<tlmgr install
-collection-context> would install C<collection-basic> and other
-collections, while in user mode, I<only> the packages mentioned in
-C<collection-context> are installed.
-
-If a package shipping map files is installed in user mode, a backup of
-the user's C<updmap.cfg> in C<USERTREE/web2c/> is made, and then this file
-regenerated from the list of installed packages.
-
-=head2 User mode backup, restore, remove, update
-
-In user mode, these actions check that all packages to be acted on are
-installed in the user tree before proceeding; otherwise, they behave
-just as in normal mode.
-
-=head2 User mode generate, option, paper
-
-In user mode, these actions operate only on the user tree's
-configuration files and/or C<texlive.tlpdb>.
-creates configuration files in user tree
-
-=head1 MULTIPLE REPOSITORIES
-
-The main TeX Live repository contains a vast array of packages.
-Nevertheless, additional local repositories can be useful to provide
-locally-installed resources, such as proprietary fonts and house styles.
-Also, alternative package repositories distribute packages that cannot
-or should not be included in TeX Live, for whatever reason.
-
-The simplest and most reliable method is to temporarily set the
-installation source to any repository (with the C<-repository> or
-C<option repository> command line options), and perform your operations.
-
-When you are using multiple repositories over a sustained length of
-time, however, explicitly switching between them becomes inconvenient.
-Thus, it's possible to tell C<tlmgr> about additional repositories you
-want to use. The basic command is C<tlmgr repository add>. The rest of
-this section explains further.
-
-When using multiple repositories, one of them has to be set as the main
-repository, which distributes most of the installed packages. When you
-switch from a single repository installation to a multiple repository
-installation, the previous sole repository will be set as the main
-repository.
-
-By default, even if multiple repositories are configured, packages are
-I<still> I<only> installed from the main repository. Thus, simply
-adding a second repository does not actually enable installation of
-anything from there. You also have to specify which packages should be
-taken from the new repository, by specifying so-called ``pinning''
-rules, described next.
-
-=head2 Pinning
-
-When a package C<foo> is pinned to a repository, a package C<foo> in any
-other repository, even if it has a higher revision number, will not be
-considered an installable candidate.
-
-As mentioned above, by default everything is pinned to the main
-repository. Let's now go through an example of setting up a second
-repository and enabling updates of a package from it.
-
-First, check that we have support for multiple repositories, and have
-only one enabled (as is the case by default):
-
- $ tlmgr repository list
- List of repositories (with tags if set):
- /var/www/norbert/tlnet
-
-Ok. Let's add the C<tlcontrib> repository (this is a real
-repository hosted at L<http://contrib.texlive.info>) with the tag C<tlcontrib>:
-
- $ tlmgr repository add http://contrib.texlive.info/current tlcontrib
-
-Check the repository list again:
-
- $ tlmgr repository list
- List of repositories (with tags if set):
- http://contrib.texlive.info/current (tlcontrib)
- /var/www/norbert/tlnet (main)
-
-Now we specify a pinning entry to get the package C<classico> from
-C<tlcontrib>:
-
- $ tlmgr pinning add tlcontrib classico
-
-Check that we can find C<classico>:
-
- $ tlmgr show classico
- package: classico
- ...
- shortdesc: URW Classico fonts
- ...
-
-- install C<classico>:
-
- $ tlmgr install classico
- tlmgr: package repositories:
- ...
- [1/1, ??:??/??:??] install: classico @tlcontrib [737k]
-
-In the output here you can see that the C<classico> package has been
-installed from the C<tlcontrib> repository (C<@tlcontrib>).
-
-Finally, C<tlmgr pinning> also supports removing certain or all packages
-from a given repository:
-
- $ tlmgr pinning remove tlcontrib classico # remove just classico
- $ tlmgr pinning remove tlcontrib --all # take nothing from tlcontrib
-
-A summary of C<tlmgr pinning> actions is given above.
-
-=head1 GUI FOR TLMGR
-
-The graphical user interface for C<tlmgr> requires Perl/Tk
-L<https://search.cpan.org/search?query=perl%2Ftk>. For Unix-based
-systems Perl/Tk (as well as Perl of course) has to be installed
-outside of TL. L<https://tug.org/texlive/distro.html#perltk> has a
-list of invocations for some distros. For Windows the necessary
-modules are no longer shipped within TeX Live, so you'll have to have an
-external Perl available that includes them.
-
-We are talking here about the GUI built into tlmgr itself, not about the
-other tlmgr GUIs, which are: tlshell (Tcl/Tk-based), tlcockpit
-(Java-based) and, only on Macs, TeX Live Utility. These are invoked as
-separate programs.
-
-The GUI mode of tlmgr is started with the invocation C<tlmgr gui>;
-assuming Tk is loadable, the graphical user interface will be shown.
-The main window contains a menu bar, the main display, and a status
-area where messages normally shown on the console are displayed.
-
-Within the main display there are three main parts: the C<Display
-configuration> area, the list of packages, and the action buttons.
-
-Also, at the top right the currently loaded repository is shown; this
-also acts as a button and when clicked will try to load the default
-repository. To load a different repository, see the C<tlmgr> menu item.
-
-Finally, the status area at the bottom of the window gives additional
-information about what is going on.
-
-=head2 Main display
-
-=head3 Display configuration area
-
-The first part of the main display allows you to specify (filter) which
-packages are shown. By default, all are shown. Changes here are
-reflected right away.
-
-=over 4
-
-=item Status
-
-Select whether to show all packages (the default), only those installed,
-only those I<not> installed, or only those with update available.
-
-=item Category
-
-Select which categories are shown: packages, collections, and/or
-schemes. These are briefly explained in the L</DESCRIPTION> section
-above.
-
-=item Match
-
-Select packages matching for a specific pattern. By default, this
-searches both descriptions and filenames. You can also select a subset
-for searching.
-
-=item Selection
-
-Select packages to those selected, those not selected, or all. Here,
-``selected'' means that the checkbox in the beginning of the line of a
-package is ticked.
-
-=item Display configuration buttons
-
-To the right there are three buttons: select all packages, select none
-(a.k.a. deselect all), and reset all these filters to the defaults,
-i.e., show all available.
-
-=back
-
-=head3 Package list area
-
-The second are of the main display lists all installed packages. If a
-repository is loaded, those that are available but not installed are
-also listed.
-
-Double clicking on a package line pops up an informational window with
-further details: the long description, included files, etc.
-
-Each line of the package list consists of the following items:
-
-=over 4
-
-=item a checkbox
-
-Used to select particular packages; some of the action buttons (see
-below) work only on the selected packages.
-
-=item package name
-
-The name (identifier) of the package as given in the database.
-
-=item local revision (and version)
-
-If the package is installed the TeX Live revision number for the
-installed package will be shown. If there is a catalogue version given
-in the database for this package, it will be shown in parentheses.
-However, the catalogue version, unlike the TL revision, is not
-guaranteed to reflect what is actually installed.
-
-=item remote revision (and version)
-
-If a repository has been loaded the revision of the package in the
-repository (if present) is shown. As with the local column, if a
-catalogue version is provided it will be displayed. And also as with
-the local column, the catalogue version may be stale.
-
-=item short description
-
-The short description of the package.
-
-=back
-
-=head3 Main display action buttons
-
-Below the list of packages are several buttons:
-
-=over 4
-
-=item Update all installed
-
-This calls C<tlmgr update --all>, i.e., tries to update all available
-packages. Below this button is a toggle to allow reinstallation of
-previously removed packages as part of this action.
-
-The other four buttons only work on the selected packages, i.e., those
-where the checkbox at the beginning of the package line is ticked.
-
-=item Update
-
-Update only the selected packages.
-
-=item Install
-
-Install the selected packages; acts like C<tlmgr install>, i.e., also
-installs dependencies. Thus, installing a collection installs all its
-constituent packages.
-
-=item Remove
-
-Removes the selected packages; acts like C<tlmgr remove>, i.e., it will
-also remove dependencies of collections (but not dependencies of normal
-packages).
-
-=item Backup
-
-Makes a backup of the selected packages; acts like C<tlmgr backup>. This
-action needs the option C<backupdir> set (see C<Options -> General>).
-
-=back
-
-=head2 Menu bar
-
-The following entries can be found in the menu bar:
-
-=over 4
-
-=item C<tlmgr> menu
-
-The items here load various repositories: the default as specified in
-the TeX Live database, the default network repository, the repository
-specified on the command line (if any), and an arbitrarily
-manually-entered one. Also has the so-necessary C<quit> operation.
-
-=item C<Options menu>
-
-Provides access to several groups of options: C<Paper> (configuration of
-default paper sizes), C<Platforms> (only on Unix, configuration of the
-supported/installed platforms), C<GUI Language> (select language used in
-the GUI interface), and C<General> (everything else).
-
-Several toggles are also here. The first is C<Expert options>, which is
-set by default. If you turn this off, the next time you start the GUI a
-simplified screen will be shown that display only the most important
-functionality. This setting is saved in the configuration file of
-C<tlmgr>; see L<CONFIGURATION FILE FOR TLMGR> for details.
-
-The other toggles are all off by default: for debugging output, to
-disable the automatic installation of new packages, and to disable the
-automatic removal of packages deleted from the server. Playing with the
-choices of what is or isn't installed may lead to an inconsistent TeX Live
-installation; e.g., when a package is renamed.
-
-=item C<Actions menu>
-
-Provides access to several actions: update the filename database (aka
-C<ls-R>, C<mktexlsr>, C<texhash>), rebuild all formats (C<fmtutil-sys
---all>), update the font map database (C<updmap-sys>), restore from a backup
-of a package, and use of symbolic links in system directories (not on
-Windows).
-
-The final action is to remove the entire TeX Live installation (also not
-on Windows).
-
-=item C<Help menu>
-
-Provides access to the TeX Live manual (also on the web at
-L<https://tug.org/texlive/doc.html>) and the usual ``About'' box.
-
-=back
-
-=head2 GUI options
-
-Some generic Perl/Tk options can be specified with C<tlmgr gui> to
-control the display:
-
-=over 4
-
-=item C<-background> I<color>
-
-Set background color.
-
-=item C<-font "> I<fontname> I<fontsize> C<">
-
-Set font, e.g., C<tlmgr gui -font "helvetica 18">. The argument to
-C<-font> must be quoted, i.e., passed as a single string.
-
-=item C<-foreground> I<color>
-
-Set foreground color.
-
-=item C<-geometry> I<geomspec>
-
-Set the X geometry, e.g., C<tlmgr gui -geometry 1024x512-0+0> creates
-the window of (approximately) the given size in the upper-right corner
-of the display.
-
-=item C<-xrm> I<xresource>
-
-Pass the arbitrary X resource string I<xresource>.
-
-=back
-
-A few other obscure options are recognized but not mentioned here. See
-the Perl/Tk documentation (L<https://search.cpan.org/perldoc?Tk>) for the
-complete list, and any X documentation for general information.
-
-=head1 MACHINE-READABLE OUTPUT
-
-With the C<--machine-readable> option, C<tlmgr> writes to stdout in the
-fixed line-oriented format described here, and the usual informational
-messages for human consumption are written to stderr (normally they are
-written to stdout). The idea is that a program can get all the
-information it needs by reading stdout.
-
-Currently this option only applies to the
-L<update|/update [I<option>...] [I<pkg>...]>,
-L<install|/install [I<option>...] I<pkg>...>, and
-L</option> actions.
-
-=head2 Machine-readable C<update> and C<install> output
-
-The output format is as follows:
-
- fieldname "\t" value
- ...
- "end-of-header"
- pkgname status localrev serverrev size runtime esttot
- ...
- "end-of-updates"
- other output from post actions, not in machine readable form
-
-The header section currently has two fields: C<location-url> (the
-repository source from which updates are being drawn), and
-C<total-bytes> (the total number of bytes to be downloaded).
-
-The I<localrev> and I<serverrev> fields for each package are the
-revision numbers in the local installation and server repository,
-respectively. The I<size> field is the number of bytes to be
-downloaded, i.e., the size of the compressed tar file for a network
-installation, not the unpacked size. The runtime and esttot fields
-are only present for updated and auto-install packages, and contain
-the currently passed time since start of installation/updates
-and the estimated total time.
-
-Line endings may be either LF or CRLF depending on the current platform.
-
-=over 4
-
-=item C<location-url> I<location>
-
-The I<location> may be a url (including C<file:///foo/bar/...>), or a
-directory name (C</foo/bar>). It is the package repository from which
-the new package information was drawn.
-
-=item C<total-bytes> I<count>
-
-The I<count> is simply a decimal number, the sum of the sizes of all the
-packages that need updating or installing (which are listed subsequently).
-
-=back
-
-Then comes a line with only the literal string C<end-of-header>.
-
-Each following line until a line with literal string C<end-of-updates>
-reports on one package. The fields on
-each line are separated by a tab. Here are the fields.
-
-=over 4
-
-=item I<pkgname>
-
-The TeX Live package identifier, with a possible platform suffix for
-executables. For instance, C<pdftex> and C<pdftex.i386-linux> are given
-as two separate packages, one on each line.
-
-=item I<status>
-
-The status of the package update. One character, as follows:
-
-=over 8
-
-=item C<d>
-
-The package was removed on the server.
-
-=item C<f>
-
-The package was removed in the local installation, even though a
-collection depended on it. (E.g., the user ran C<tlmgr remove
---force>.)
-
-=item C<u>
-
-Normal update is needed.
-
-=item C<r>
-
-Reversed non-update: the locally-installed version is newer than the
-version on the server.
-
-=item C<a>
-
-Automatically-determined need for installation, the package is new on
-the server and is (most probably) part of an installed collection.
-
-=item C<i>
-
-Package will be installed and isn't present in the local installation
-(action install).
-
-=item C<I>
-
-Package is already present but will be reinstalled (action install).
-
-=back
-
-=item I<localrev>
-
-The revision number of the installed package, or C<-> if it is not
-present locally.
-
-=item I<serverrev>
-
-The revision number of the package on the server, or C<-> if it is not
-present on the server.
-
-=item I<size>
-
-The size in bytes of the package on the server. The sum of all the
-package sizes is given in the C<total-bytes> header field mentioned above.
-
-=item I<runtime>
-
-The run time since start of installations or updates.
-
-=item I<esttot>
-
-The estimated total time.
-
-=back
-
-=head2 Machine-readable C<option> output
-
-The output format is as follows:
-
- key "\t" value
-
-If a value is not saved in the database the string C<(not set)> is shown.
-
-If you are developing a program that uses this output, and find that
-changes would be helpful, do not hesitate to write the mailing list.
-
-=head1 ENVIRONMENT VARIABLES
-
-C<tlmgr> uses many of the standard TeX environment variables, as
-reported by, e.g., C<tlmgr conf> (L</conf>).
-
-In addition, for ease in scripting and debugging, C<tlmgr> looks for the
-following environment variables. These are not of interest for normal
-user installations.
-
-=over 4
-
-=item C<TEXLIVE_COMPRESSOR>
-
-This variable allows selecting a different compressor program for
-backups and intermediate rollback containers. The order of selection is:
-
-=over 8
-
-=item 1.
-
-If the environment variable C<TEXLIVE_COMPRESSOR> is
-defined, use it; abort if it doesn't work. Possible values:
-C<lz4>, C<gzip>, C<xz>. The necessary options are added internally.
-
-=item 2.
-
-If lz4 is available (either from the system or TL) and working, use that.
-
-=item 3.
-
-If gzip is available (from the system) and working, use that.
-
-=item 4.
-
-If xz is available (either from the system or TL) and working, use that.
-
-=back
-
-lz4 and gzip are faster in creating tlmgr's local backups, hence they
-are preferred. The unconditional use of xz for the tlnet containers is
-unaffected, to minimize download sizes.
-
-=item C<TEXLIVE_DOWNLOADER>
-
-=item C<TL_DOWNLOAD_PROGRAM>
-
-=item C<TL_DOWNLOAD_ARGS>
-
-These options allow selecting different download programs then the ones
-automatically selected by the installer. The order of selection is:
-
-=over 8
-
-=item 1.
-
-If the environment variable C<TEXLIVE_DOWNLOADER> is defined, use it;
-abort if the specified program doesn't work. Possible values: C<lwp>,
-C<curl>, C<wget>. The necessary options are added internally.
-
-=item 2.
-
-If the environment variable C<TL_DOWNLOAD_PROGRAM> is
-defined (can be any value), use it together with
-C<TL_DOWNLOAD_ARGS>; abort if it doesn't work.
-
-=item 3.
-
-If LWP is available and working, use that (by far the most
-efficient method, as it supports persistent downloads).
-
-=item 4.
-
-If curl is available (from the system) and working, use that.
-
-=item 5.
-
-If wget is available (either from the system or TL) and working, use that.
-
-=back
-
-TL provides C<wget> binaries for platforms where necessary, so some
-download method should always be available.
-
-=item C<TEXLIVE_PREFER_OWN>
-
-By default, compression and download programs provided by the system,
-i.e., found along C<PATH> are preferred over those shipped with TeX
-Live.
-
-This can create problems with systems that are too old, and so can be
-overridden by setting the environment variable C<TEXLIVE_PREFER_OWN> to
-1. In this case, executables shipped with TL will be preferred.
-
-Extra compression/download programs not provided by TL, such as gzip,
-lwp, and curl, are still checked for on the system and used if
-available, per the above. C<TEXLIVE_PREFER_OWN> only applies when the
-program being checked for is shipped with TL, namely the lz4 and
-xz compressors and wget downloader.
-
-Exception: on Windows, the C<tar.exe> shipped with TL is always used,
-regardless of any setting.
-
-=back
-
-=head1 AUTHORS AND COPYRIGHT
-
-This script and its documentation were written for the TeX Live
-distribution (L<https://tug.org/texlive>) and both are licensed under the
-GNU General Public License Version 2 or later.
-
-$Id: tlmgr.pl 57772 2021-02-17 19:01:36Z karl $
-=cut
-
-# test HTML version: pod2html --cachedir=/tmp tlmgr.pl >/tmp/tlmgr.html
-
-### Local Variables:
-### perl-indent-level: 2
-### tab-width: 2
-### indent-tabs-mode: nil
-### End:
-# vim:set tabstop=2 expandtab: #
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/updmap-sys.sh b/Build/source/texk/texlive/linked_scripts/texlive/updmap-sys.sh
deleted file mode 100755
index 4bb9a4cd4af..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/updmap-sys.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-# $Id: updmap-sys.sh 36962 2015-04-20 01:48:35Z preining $
-# updmap-sys - arrange for updmap to affect system directories.
-# Maintained in Master/texmf-dist/scripts/texlive/
-# Public domain. Originally written by Thomas Esser.
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-exec updmap --sys ${1+"$@"}
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/updmap-user.sh b/Build/source/texk/texlive/linked_scripts/texlive/updmap-user.sh
deleted file mode 100755
index 14dd4133ad2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/updmap-user.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-# $Id: updmap-user.sh 51911 2019-08-19 20:59:22Z karl $
-# updmap-user - arrange for updmap to affect user directories.
-# Maintained in Master/texmf-dist/scripts/texlive/
-# Public domain. Originally written by Thomas Esser.
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-exec updmap --user ${1+"$@"}
diff --git a/Build/source/texk/texlive/linked_scripts/texlive/updmap.pl b/Build/source/texk/texlive/linked_scripts/texlive/updmap.pl
deleted file mode 100755
index 40dd22ef003..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texlive/updmap.pl
+++ /dev/null
@@ -1,2542 +0,0 @@
-#!/usr/bin/env perl
-# $Id: updmap.pl 51338 2019-06-07 16:36:59Z karl $
-# updmap - maintain map files for outline fonts.
-# (Maintained in TeX Live:Master/texmf-dist/scripts/texlive.)
-#
-# Copyright 2011-2019 Norbert Preining
-# This file is licensed under the GNU General Public License version 2
-# or any later version.
-#
-# History:
-# Original shell script (C) 2002 Thomas Esser
-# first perl variant by Fabrice Popineau
-# later adaptions by Reinhard Kotucha and Karl Berry
-# the original versions were licensed under the following agreement:
-# Anyone may freely use, modify, and/or distribute this file, without
-
-my $svnid = '$Id: updmap.pl 51338 2019-06-07 16:36:59Z karl $';
-
-my $TEXMFROOT;
-BEGIN {
- $^W = 1;
- $TEXMFROOT = `kpsewhich -var-value=TEXMFROOT`;
- if ($?) {
- die "$0: kpsewhich -var-value=TEXMFROOT failed, aborting early.\n";
- }
- chomp($TEXMFROOT);
- unshift(@INC, "$TEXMFROOT/tlpkg");
-}
-
-my $lastchdate = '$Date: 2019-06-07 18:36:59 +0200 (Fri, 07 Jun 2019) $';
-$lastchdate =~ s/^\$Date:\s*//;
-$lastchdate =~ s/ \(.*$//;
-my $svnrev = '$Revision: 51338 $';
-$svnrev =~ s/^\$Revision:\s*//;
-$svnrev =~ s/\s*\$$//;
-my $version = "r$svnrev ($lastchdate)";
-
-use Getopt::Long qw(:config no_autoabbrev ignore_case_always);
-use strict;
-use TeXLive::TLUtils qw(mkdirhier mktexupd win32 basename dirname
- sort_uniq member touch);
-
-(my $prg = basename($0)) =~ s/\.pl$//;
-
-# sudo sometimes does not reset the home dir of root;
-# see more comments at the definition of this function.
-reset_root_home();
-
-chomp(my $TEXMFDIST = `kpsewhich --var-value=TEXMFDIST`);
-chomp(my $TEXMFVAR = `kpsewhich -var-value=TEXMFVAR`);
-chomp(my $TEXMFSYSVAR = `kpsewhich -var-value=TEXMFSYSVAR`);
-chomp(my $TEXMFCONFIG = `kpsewhich -var-value=TEXMFCONFIG`);
-chomp(my $TEXMFSYSCONFIG = `kpsewhich -var-value=TEXMFSYSCONFIG`);
-chomp(my $TEXMFHOME = `kpsewhich -var-value=TEXMFHOME`);
-
-# make sure that on windows *everything* is in lower case for comparison
-if (win32()) {
- $TEXMFDIST = lc($TEXMFDIST);
- $TEXMFVAR = lc($TEXMFVAR);
- $TEXMFSYSVAR = lc($TEXMFSYSVAR);
- $TEXMFCONFIG = lc($TEXMFCONFIG);
- $TEXMFSYSCONFIG = lc($TEXMFSYSCONFIG);
- $TEXMFROOT = lc($TEXMFROOT);
- $TEXMFHOME = lc($TEXMFHOME);
-}
-
-my $texmfconfig = $TEXMFCONFIG;
-my $texmfvar = $TEXMFVAR;
-
-my %opts = ( quiet => 0, nohash => 0, nomkmap => 0 );
-my $alldata;
-my $updLSR;
-
-my @cmdline_options = (
- "sys",
- "user",
- "listfiles",
- "cnffile=s@",
- "copy",
- "disable=s@",
- "dvipdfmoutputdir=s",
- "dvipdfmxoutputdir=s",
- "dvipsoutputdir=s",
- # the following does not work, Getopt::Long looses the first
- # entry in a multi setting, treat it separately in processOptions
- # furthermore, it is not supported by older perls, so do it differently
- #"enable=s{1,2}",
- "edit",
- "force",
- "listavailablemaps",
- "listmaps|l",
- "nohash",
- "nomkmap",
- "dry-run|n",
- "outputdir=s",
- "pdftexoutputdir=s",
- "pxdvioutputdir=s",
- "quiet|silent|q",
- # the following is a correct specification of an option according
- # to the manual, but it does not work!
- # we will treat that option by itself in processOptions
- # furthermore, it is not supported by older perls, so do it differently
- #"setoption=s@{1,2}",
- "showoptions=s@",
- "showoption=s@",
- "syncwithtrees",
- "version",
- "help|h",
- # some debugging invocations
- "_readsave=s",
- "_dump",
- );
-
-my %settings = (
- dvipsPreferOutline => {
- type => "binary",
- default => "true",
- },
- LW35 => {
- type => "string",
- possible => [ qw/URW URWkb ADOBE ADOBEkb/ ],
- default => "URWkb",
- },
- dvipsDownloadBase35 => {
- type => "binary",
- default => "true",
- },
- pdftexDownloadBase14 => {
- type => "binary",
- default => "true",
- },
- dvipdfmDownloadBase14 => {
- type => "binary",
- default => "true",
- },
- pxdviUse => {
- type => "binary",
- default => "false",
- },
- jaEmbed => {
- type => "any",
- default => "noEmbed",
- },
- jaVariant => {
- type => "any",
- default => "",
- },
- scEmbed => {
- type => "any",
- default => "noEmbed",
- },
- tcEmbed => {
- type => "any",
- default => "noEmbed",
- },
- koEmbed => {
- type => "any",
- default => "noEmbed",
- },
-);
-
-&main();
-
-##################################################################
-#
-sub main {
- processOptions();
-
- help() if $opts{'help'};
-
- if ($opts{'version'}) {
- print version();
- exit (0);
- }
-
- ($texmfconfig, $texmfvar) =
- TeXLive::TLUtils::setup_sys_user_mode($prg, \%opts,
- $TEXMFCONFIG, $TEXMFSYSCONFIG, $TEXMFVAR, $TEXMFSYSVAR);
-
- if ($opts{'dvipdfmoutputdir'} && !defined($opts{'dvipdfmxoutputdir'})) {
- $opts{'dvipdfmxoutputdir'} = $opts{'dvipdfmoutputdir'};
- print_warning("Using --dvipdfmoutputdir options for dvipdfmx,"
- . " but please use --dvipdfmxoutputdir\n");
- }
-
- if ($opts{'dvipdfmoutputdir'} && $opts{'dvipdfmxoutputdir'}
- && $opts{'dvipdfmoutputdir'} ne $opts{'dvipdfmxoutputdir'}) {
- print_error("Options for --dvipdfmoutputdir and --dvipdfmxoutputdir"
- . " do not match\n"
- . "Please use only --dvipdfmxoutputdir; exiting.\n");
- exit(1);
- }
-
- if ($opts{'_readsave'}) {
- read_updmap_files($opts{'_readsave'});
- merge_settings_replace_kanji();
- print "READING DONE ============================\n";
- $alldata->{'updmap'}{$opts{'_readsave'}}{'changed'} = 1;
- save_updmap($opts{'_readsave'});
- exit 0;
- }
-
- if ($opts{'showoptions'}) {
- for my $o (@{$opts{'showoptions'}}) {
- if (defined($settings{$o})) {
- if ($settings{$o}{'type'} eq "binary") {
- print "true false\n";
- } elsif ($settings{$o}{'type'} eq "string") {
- print "@{$settings{$o}{'possible'}}\n";
- } elsif ($settings{$o}{'type'} eq "any") {
- print "(any string)\n";
- } else {
- print_warning("strange: unknown type of option $o\nplease report\n");
- }
- } else {
- print_warning("unknown option: $o\n");
- }
- }
- exit 0;
- }
-
- # config file for changes
- my $changes_config_file;
-
- # determine which config files should be used
- # replaces the former "setupCfgFile"
- #
- # we also determine here where changes will be saved to
- if ($opts{'cnffile'}) {
- my @tmp;
- for my $f (@{$opts{'cnffile'}}) {
- if (! -f $f) {
- die "$prg: Config file \"$f\" not found.";
- }
- push @tmp, (win32() ? lc($f) : $f);
- }
- @{$opts{'cnffile'}} = @tmp;
- # in case that config files are given on the command line, the first
- # in the list is the one where changes will be written to.
- ($changes_config_file) = @{$opts{'cnffile'}};
- } else {
- my @all_files = `kpsewhich -all updmap.cfg`;
- chomp(@all_files);
- my @used_files;
- for my $f (@all_files) {
- push @used_files, (win32() ? lc($f) : $f);
- }
- #
- my $TEXMFLOCALVAR;
- my @TEXMFLOCAL;
- if (win32()) {
- chomp($TEXMFLOCALVAR =`kpsewhich --expand-path=\$TEXMFLOCAL`);
- @TEXMFLOCAL = map { lc } split(/;/ , $TEXMFLOCALVAR);
- } else {
- chomp($TEXMFLOCALVAR =`kpsewhich --expand-path='\$TEXMFLOCAL'`);
- @TEXMFLOCAL = split /:/ , $TEXMFLOCALVAR;
- }
- #
- # search for TEXMFLOCAL/web2c/updmap.cfg
- my @tmlused;
- for my $tml (@TEXMFLOCAL) {
- my $TMLabs = Cwd::abs_path($tml);
- next if (!$TMLabs);
- if (-r "$TMLabs/web2c/updmap.cfg") {
- push @tmlused, "$TMLabs/web2c/updmap.cfg";
- }
- #
- # at least check for old updmap-local.cfg and warn!
- if (-r "$TMLabs/web2c/updmap-local.cfg") {
- print_warning("=============================\n");
- print_warning("Old configuration file\n $TMLabs/web2c/updmap-local.cfg\n");
- print_warning("found! This file is *not* evaluated anymore, please move the information\n");
- print_warning("to the file $TMLabs/updmap.cfg!\n");
- print_warning("=============================\n");
- }
- }
- #
- # updmap (user):
- # ==============
- # TEXMFCONFIG $HOME/.texliveYYYY/texmf-config/web2c/updmap.cfg
- # TEXMFVAR $HOME/.texliveYYYY/texmf-var/web2c/updmap.cfg
- # TEXMFHOME $HOME/texmf/web2c/updmap.cfg
- # TEXMFSYSCONFIG $TEXLIVE/YYYY/texmf-config/web2c/updmap.cfg
- # TEXMFSYSVAR $TEXLIVE/YYYY/texmf-var/web2c/updmap.cfg
- # TEXMFLOCAL $TEXLIVE/texmf-local/web2c/updmap.cfg
- # TEXMFDIST $TEXLIVE/YYYY/texmf-dist/web2c/updmap.cfg
- #
- # updmap-sys (root):
- # ==================
- # TEXMFSYSCONFIG $TEXLIVE/YYYY/texmf-config/web2c/updmap.cfg
- # TEXMFSYSVAR $TEXLIVE/YYYY/texmf-var/web2c/updmap.cfg
- # TEXMFLOCAL $TEXLIVE/texmf-local/web2c/updmap.cfg
- # TEXMFDIST $TEXLIVE/YYYY/texmf-dist/web2c/updmap.cfg
- #
- @{$opts{'cnffile'}} = @used_files;
- #
- # Determine the config file that we will use for changes:
- # if the list of used files contains one from either
- # TEXMFHOME or TEXMFCONFIG (which is TEXMFSYSCONFIG in the -sys case)
- # then use the *top* file (which will be one of the two *CONFIG);
- # if neither of those two exists, create a file in TEXMFCONFIG and use it.
- my $use_top = 0;
- for my $f (@used_files) {
- if ($f =~ m!(\Q$TEXMFHOME\E|\Q$texmfconfig\E)/web2c/updmap.cfg!) {
- $use_top = 1;
- last;
- }
- }
- if ($use_top) {
- ($changes_config_file) = @used_files;
- } else {
- # add the empty config file
- my $dn = "$texmfconfig/web2c";
- $changes_config_file = "$dn/updmap.cfg";
- }
- }
- if (!$opts{'quiet'}) {
- print "$prg will read the following updmap.cfg files (in precedence order):\n";
- for my $f (@{$opts{'cnffile'}}) {
- print " $f\n";
- }
- print "$prg may write changes to the following updmap.cfg file:\n";
- print " $changes_config_file\n";
- }
- if ($opts{'listfiles'}) {
- # we listed it above, so be done
- exit 0;
- }
-
- $alldata->{'changes_config'} = $changes_config_file;
-
- read_updmap_files(@{$opts{'cnffile'}});
-
- if ($opts{'_dump'}) {
- merge_settings_replace_kanji();
- read_map_files();
- require Data::Dumper;
- # two times to silence perl warnings!
- $Data::Dumper::Indent = 1;
- $Data::Dumper::Indent = 1;
- print "READING DONE ============================\n";
- print Data::Dumper::Dumper($alldata);
- exit 0;
- }
-
- if ($opts{'showoption'}) {
- merge_settings_replace_kanji();
- for my $o (@{$opts{'showoption'}}) {
- if (defined($settings{$o})) {
- my ($v, $vo) = get_cfg($o);
- $v = "\"$v\"" if ($v =~ m/\s/);
- print "$o=$v ($vo)\n";
- } else {
- print_warning("unknown option: $o\n");
- }
- }
- exit 0;
- }
-
- if ($opts{'listmaps'} || $opts{'listavailablemaps'}) {
- merge_settings_replace_kanji();
- # only check for missing map files
- # (pass in true argument to read_map_files)
- my %missing = map { $_ => 1 } read_map_files(1);
- for my $m (sort keys %{$alldata->{'maps'}}) {
- next if ($missing{$m} && $opts{'listavailablemaps'});
- my $origin = $alldata->{'maps'}{$m}{'origin'};
- my $type = ($origin eq 'builtin' ? 'Map' :
- $alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'});
- my $status = ($origin eq 'builtin' ? 'enabled' :
- $alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'});
- my $avail = ($missing{$m} ? "\t(not available)" : '');
- print "$type\t$m\t$status\t$origin$avail\n";
- #print $alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'}, " $m ",
- #$alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'}, " in $origin\n";
- }
- exit 0;
- }
-
- # we do changes always in the used config file with the highest
- # priority
- my $bakFile = $changes_config_file;
- $bakFile =~ s/\.cfg$/.bak/;
- my $changed = 0;
-
- $updLSR = &mktexupd();
- $updLSR->{mustexist}(0);
-
- if ($opts{'syncwithtrees'}) {
- merge_settings_replace_kanji();
- my @missing = read_map_files();
- if (@missing) {
- print "Missing map files found, disabling\n";
- for my $m (@missing) {
- my $orig = $alldata->{'maps'}{$m}{'origin'};
- print "\t$m (in $orig)\n";
- }
- print "in $changes_config_file\n";
- print "Do you really want to continue (y/N)? ";
- my $answer = <STDIN>;
- $answer = "n" if !defined($answer);
- chomp($answer);
- print "answer =$answer=\n";
- if ($answer ne "y" && $answer ne "Y") {
- print "Please fix manually before running updmap(-sys) again!\n";
- exit 0;
- }
- $changed ||= enable_disable_maps(@missing);
- print "$0 --syncwithtrees finished.\n";
- print "Now you need to run $prg normally to recreate map files.\n"
- }
- exit 0;
- }
-
- my $cmd;
- if ($opts{'edit'}) {
- if ($opts{"dry-run"}) {
- print_error("No, are you joking, you want to edit with --dry-run?\n");
- exit 1;
- }
- # it's not a good idea to edit updmap.cfg manually these days,
- # but for compatibility we'll silently keep the option.
- $cmd = 'edit';
- my $editor = $ENV{'VISUAL'} || $ENV{'EDITOR'};
- $editor ||= (&win32 ? "notepad" : "vi");
- if (-r $changes_config_file) {
- &copyFile($changes_config_file, $bakFile);
- } else {
- touch($bakFile);
- touch($changes_config_file);
- }
- system($editor, $changes_config_file);
- $changed = files_are_different($bakFile, $changes_config_file);
- } elsif ($opts{'setoption'}) {
- $cmd = 'setOption';
- $changed = setOptions (@{$opts{'setoption'}});
- } elsif ($opts{'enable'} || $opts{'disable'}) {
- $cmd = 'enableMap';
- $changed ||= enable_disable_maps(@{$opts{'enable'}}, @{$opts{'disable'}});
- }
-
-
- if ($cmd && !$opts{'force'} && !$changed) {
- print "$changes_config_file unchanged. Map files not recreated.\n"
- if !$opts{'quiet'};
- } else {
- if (!$opts{'nomkmap'}) {
- # before we continue we have to make sure that a newly created config
- # file is acually used. So we have to push the $changes_config_file
- # onto the list of available files. Since it is already properly
- # initialized and the merging is done later, all settings should be
- # honored
- my @aaa = @{$alldata->{'order'}};
- unshift @aaa, $changes_config_file;
- $alldata->{'order'} = [ @aaa ];
- #
- setupOutputDir("dvips");
- setupOutputDir("pdftex");
- setupOutputDir("dvipdfmx");
- # do pxdvi below, in mkmaps.
- merge_settings_replace_kanji();
- my @missing = read_map_files();
- if (@missing) {
- print_error("The following map file(s) couldn't be found:\n");
- for my $m (@missing) {
- my $orig = $alldata->{'maps'}{$m}{'origin'};
- print_error("\t$m (in $orig)\n");
- }
- print_error("Did you run mktexlsr?\n\n" .
- "\tYou can disable non-existent map entries using the option\n".
- "\t --syncwithtrees.\n\n");
- exit 1;
- }
- merge_data();
- # for inspecting the output
- #print STDERR Data::Dumper->Dump([$alldata], [qw(mapdata)]);
- #print Dumper($alldata);
- mkMaps();
- }
- unlink ($bakFile) if (-r $bakFile);
- }
-
- if (!$opts{'nohash'}) {
- print "$prg: Updating ls-R files.\n" if !$opts{'quiet'};
- $updLSR->{exec}() unless $opts{"dry-run"};
- }
-
- return 0;
-}
-
-##################################################################
-#
-sub getFonts {
- my ($first, @rest) = @_;
- my $getall = 0;
- my @maps = ();
- return if !defined($first);
- if ($first eq "-all") {
- $getall = 1;
- @maps = @rest;
- } else {
- @maps = ($first, @rest);
- }
- my @lines = ();
- for my $m (@maps) {
- if (defined($alldata->{'maps'}{$m})) {
- print LOG "\n" . $alldata->{'maps'}{$m}{'fullpath'} . ":\n" unless $opts{'dry-run'};
- push @lines, "% $m";
- for my $k (sort keys %{$alldata->{'maps'}{$m}{'fonts'}}) {
- if ($getall || $alldata->{'fonts'}{$k}{'origin'} eq $m) {
- if (defined($alldata->{'maps'}{$m}{'fonts'}{$k})) {
- push @lines, "$k " . $alldata->{'maps'}{$m}{'fonts'}{$k};
- } else {
- print_warning("undefined fonts for $k in $m ?!?!?\n");
- }
- print LOG "$k\n" unless $opts{'dry-run'};
- }
- }
- }
- }
- chomp @lines;
- return @lines;
-}
-
-###############################################################################
-# writeLines()
-# write the lines in $filename
-#
-sub writeLines {
- my ($fname, @lines) = @_;
- return if $opts{"dry-run"};
- map { ($_ !~ m/\n$/ ? s/$/\n/ : $_ ) } @lines;
- open FILE, ">$fname" or die "$prg: can't write lines to $fname: $!";
- print FILE @lines;
- close FILE;
-}
-
-###############################################################################
-# to_pdftex()
-# if $pdftexStripEnc is set, strip "PS_Encoding_Name ReEncodeFont"
-# from map entries; they are ignored by pdftex. But since the sh
-# incarnation of updmap included them, and we want to minimize
-# differences, this is not done by default.
-#
-sub to_pdftex {
- my $pdftexStripEnc = 0;
- return @_ unless $pdftexStripEnc;
- my @in = @_;
- my @out;
- foreach my $line (@in) {
- if ($line =~ /^(.*\s+)(\S+\s+ReEncodeFont\s)(.*)/) {
- $line = "$1$3";
- $line =~ s/\s+\"\s+\"\s+/ /;
- }
- push @out, $line;
- }
- return @out;
-}
-
-###############################################################################
-# setupSymlinks()
-# set symlink for psfonts.map according to dvipsPreferOutline variable
-#
-sub setupSymlinks {
- my ($dvipsPreferOutline, $dvipsoutputdir, $pdftexDownloadBase14, $pdftexoutputdir) = @_;
- my $src;
- my %link;
- my @link;
-
- if ($dvipsPreferOutline eq "true") {
- $src = "psfonts_t1.map";
- } else {
- $src = "psfonts_pk.map";
- }
- unlink "$dvipsoutputdir/psfonts.map" unless $opts{"dry-run"};
- push @link, &SymlinkOrCopy("$dvipsoutputdir", "$src", "psfonts.map");
-
- if ($pdftexDownloadBase14 eq "true") {
- $src = "pdftex_dl14.map";
- } else {
- $src = "pdftex_ndl14.map";
- }
- unlink "$pdftexoutputdir/pdftex.map" unless $opts{"dry-run"};
- push @link, &SymlinkOrCopy("$pdftexoutputdir", "$src", "pdftex.map");
- %link = @link;
- return \%link;
-}
-
-###############################################################################
-# SymlinkOrCopy(dir, src, dest)
-# create symlinks if possible, otherwise copy files
-#
-sub SymlinkOrCopy {
- my ($dir, $src, $dest) = @_;
- return ($src, $dest) if $opts{"dry-run"};
- if (&win32 || $opts{'copy'}) { # always copy
- &copyFile("$dir/$src", "$dir/$dest");
- } else { # symlink if supported by fs, copy otherwise
- system("cd \"$dir\" && ln -s $src $dest 2>/dev/null || "
- . "cp -p \"$dir/$src\" \"$dir/$dest\"");
- }
- # remember for "Files generated" in &mkMaps.
- return ($dest, $src);
-}
-
-
-###############################################################################
-# transLW35(mode args ...)
-# transform fontname and filenames according to transformation specified
-# by mode. Possible values:
-# URW|URWkb|ADOBE|ADOBEkb
-#
-sub transLW35 {
- my ($mode, @lines) = @_;
-
- my @psADOBE = (
- 's/ URWGothicL-Demi / AvantGarde-Demi /',
- 's/ URWGothicL-DemiObli / AvantGarde-DemiOblique /',
- 's/ URWGothicL-Book / AvantGarde-Book /',
- 's/ URWGothicL-BookObli / AvantGarde-BookOblique /',
- 's/ URWBookmanL-DemiBold / Bookman-Demi /',
- 's/ URWBookmanL-DemiBoldItal / Bookman-DemiItalic /',
- 's/ URWBookmanL-Ligh / Bookman-Light /',
- 's/ URWBookmanL-LighItal / Bookman-LightItalic /',
- 's/ NimbusMonL-Bold / Courier-Bold /',
- 's/ NimbusMonL-BoldObli / Courier-BoldOblique /',
- 's/ NimbusMonL-Regu / Courier /',
- 's/ NimbusMonL-ReguObli / Courier-Oblique /',
- 's/ NimbusSanL-Bold / Helvetica-Bold /',
- 's/ NimbusSanL-BoldCond / Helvetica-Narrow-Bold /',
- 's/ NimbusSanL-BoldItal / Helvetica-BoldOblique /',
- 's/ NimbusSanL-BoldCondItal / Helvetica-Narrow-BoldOblique /',
- 's/ NimbusSanL-Regu / Helvetica /',
- 's/ NimbusSanL-ReguCond / Helvetica-Narrow /',
- 's/ NimbusSanL-ReguItal / Helvetica-Oblique /',
- 's/ NimbusSanL-ReguCondItal / Helvetica-Narrow-Oblique /',
- 's/ CenturySchL-Bold / NewCenturySchlbk-Bold /',
- 's/ CenturySchL-BoldItal / NewCenturySchlbk-BoldItalic /',
- 's/ CenturySchL-Roma / NewCenturySchlbk-Roman /',
- 's/ CenturySchL-Ital / NewCenturySchlbk-Italic /',
- 's/ URWPalladioL-Bold / Palatino-Bold /',
- 's/ URWPalladioL-BoldItal / Palatino-BoldItalic /',
- 's/ URWPalladioL-Roma / Palatino-Roman /',
- 's/ URWPalladioL-Ital / Palatino-Italic /',
- 's/ StandardSymL / Symbol /',
- 's/ NimbusRomNo9L-Medi / Times-Bold /',
- 's/ NimbusRomNo9L-MediItal / Times-BoldItalic /',
- 's/ NimbusRomNo9L-Regu / Times-Roman /',
- 's/ NimbusRomNo9L-ReguItal / Times-Italic /',
- 's/ URWChanceryL-MediItal / ZapfChancery-MediumItalic /',
- 's/ Dingbats / ZapfDingbats /',
- );
-
- my @fileADOBEkb = (
- 's/\buagd8a.pfb\b/pagd8a.pfb/',
- 's/\buagdo8a.pfb\b/pagdo8a.pfb/',
- 's/\buagk8a.pfb\b/pagk8a.pfb/',
- 's/\buagko8a.pfb\b/pagko8a.pfb/',
- 's/\bubkd8a.pfb\b/pbkd8a.pfb/',
- 's/\bubkdi8a.pfb\b/pbkdi8a.pfb/',
- 's/\bubkl8a.pfb\b/pbkl8a.pfb/',
- 's/\bubkli8a.pfb\b/pbkli8a.pfb/',
- 's/\bucrb8a.pfb\b/pcrb8a.pfb/',
- 's/\bucrbo8a.pfb\b/pcrbo8a.pfb/',
- 's/\bucrr8a.pfb\b/pcrr8a.pfb/',
- 's/\bucrro8a.pfb\b/pcrro8a.pfb/',
- 's/\buhvb8a.pfb\b/phvb8a.pfb/',
- 's/\buhvb8ac.pfb\b/phvb8an.pfb/',
- 's/\buhvbo8a.pfb\b/phvbo8a.pfb/',
- 's/\buhvbo8ac.pfb\b/phvbo8an.pfb/',
- 's/\buhvr8a.pfb\b/phvr8a.pfb/',
- 's/\buhvr8ac.pfb\b/phvr8an.pfb/',
- 's/\buhvro8a.pfb\b/phvro8a.pfb/',
- 's/\buhvro8ac.pfb\b/phvro8an.pfb/',
- 's/\buncb8a.pfb\b/pncb8a.pfb/',
- 's/\buncbi8a.pfb\b/pncbi8a.pfb/',
- 's/\buncr8a.pfb\b/pncr8a.pfb/',
- 's/\buncri8a.pfb\b/pncri8a.pfb/',
- 's/\buplb8a.pfb\b/pplb8a.pfb/',
- 's/\buplbi8a.pfb\b/pplbi8a.pfb/',
- 's/\buplr8a.pfb\b/pplr8a.pfb/',
- 's/\buplri8a.pfb\b/pplri8a.pfb/',
- 's/\busyr.pfb\b/psyr.pfb/',
- 's/\butmb8a.pfb\b/ptmb8a.pfb/',
- 's/\butmbi8a.pfb\b/ptmbi8a.pfb/',
- 's/\butmr8a.pfb\b/ptmr8a.pfb/',
- 's/\butmri8a.pfb\b/ptmri8a.pfb/',
- 's/\buzcmi8a.pfb\b/pzcmi8a.pfb/',
- 's/\buzdr.pfb\b/pzdr.pfb/',
- );
-
- my @fileURW = (
- 's/\buagd8a.pfb\b/a010015l.pfb/',
- 's/\buagdo8a.pfb\b/a010035l.pfb/',
- 's/\buagk8a.pfb\b/a010013l.pfb/',
- 's/\buagko8a.pfb\b/a010033l.pfb/',
- 's/\bubkd8a.pfb\b/b018015l.pfb/',
- 's/\bubkdi8a.pfb\b/b018035l.pfb/',
- 's/\bubkl8a.pfb\b/b018012l.pfb/',
- 's/\bubkli8a.pfb\b/b018032l.pfb/',
- 's/\bucrb8a.pfb\b/n022004l.pfb/',
- 's/\bucrbo8a.pfb\b/n022024l.pfb/',
- 's/\bucrr8a.pfb\b/n022003l.pfb/',
- 's/\bucrro8a.pfb\b/n022023l.pfb/',
- 's/\buhvb8a.pfb\b/n019004l.pfb/',
- 's/\buhvb8ac.pfb\b/n019044l.pfb/',
- 's/\buhvbo8a.pfb\b/n019024l.pfb/',
- 's/\buhvbo8ac.pfb\b/n019064l.pfb/',
- 's/\buhvr8a.pfb\b/n019003l.pfb/',
- 's/\buhvr8ac.pfb\b/n019043l.pfb/',
- 's/\buhvro8a.pfb\b/n019023l.pfb/',
- 's/\buhvro8ac.pfb\b/n019063l.pfb/',
- 's/\buncb8a.pfb\b/c059016l.pfb/',
- 's/\buncbi8a.pfb\b/c059036l.pfb/',
- 's/\buncr8a.pfb\b/c059013l.pfb/',
- 's/\buncri8a.pfb\b/c059033l.pfb/',
- 's/\buplb8a.pfb\b/p052004l.pfb/',
- 's/\buplbi8a.pfb\b/p052024l.pfb/',
- 's/\buplr8a.pfb\b/p052003l.pfb/',
- 's/\buplri8a.pfb\b/p052023l.pfb/',
- 's/\busyr.pfb\b/s050000l.pfb/',
- 's/\butmb8a.pfb\b/n021004l.pfb/',
- 's/\butmbi8a.pfb\b/n021024l.pfb/',
- 's/\butmr8a.pfb\b/n021003l.pfb/',
- 's/\butmri8a.pfb\b/n021023l.pfb/',
- 's/\buzcmi8a.pfb\b/z003034l.pfb/',
- 's/\buzdr.pfb\b/d050000l.pfb/',
- );
-
- my @fileADOBE = (
- 's/\buagd8a.pfb\b/agd_____.pfb/',
- 's/\buagdo8a.pfb\b/agdo____.pfb/',
- 's/\buagk8a.pfb\b/agw_____.pfb/',
- 's/\buagko8a.pfb\b/agwo____.pfb/',
- 's/\bubkd8a.pfb\b/bkd_____.pfb/',
- 's/\bubkdi8a.pfb\b/bkdi____.pfb/',
- 's/\bubkl8a.pfb\b/bkl_____.pfb/',
- 's/\bubkli8a.pfb\b/bkli____.pfb/',
- 's/\bucrb8a.pfb\b/cob_____.pfb/',
- 's/\bucrbo8a.pfb\b/cobo____.pfb/',
- 's/\bucrr8a.pfb\b/com_____.pfb/',
- 's/\bucrro8a.pfb\b/coo_____.pfb/',
- 's/\buhvb8a.pfb\b/hvb_____.pfb/',
- 's/\buhvb8ac.pfb\b/hvnb____.pfb/',
- 's/\buhvbo8a.pfb\b/hvbo____.pfb/',
- 's/\buhvbo8ac.pfb\b/hvnbo___.pfb/',
- 's/\buhvr8a.pfb\b/hv______.pfb/',
- 's/\buhvr8ac.pfb\b/hvn_____.pfb/',
- 's/\buhvro8a.pfb\b/hvo_____.pfb/',
- 's/\buhvro8ac.pfb\b/hvno____.pfb/',
- 's/\buncb8a.pfb\b/ncb_____.pfb/',
- 's/\buncbi8a.pfb\b/ncbi____.pfb/',
- 's/\buncr8a.pfb\b/ncr_____.pfb/',
- 's/\buncri8a.pfb\b/nci_____.pfb/',
- 's/\buplb8a.pfb\b/pob_____.pfb/',
- 's/\buplbi8a.pfb\b/pobi____.pfb/',
- 's/\buplr8a.pfb\b/por_____.pfb/',
- 's/\buplri8a.pfb\b/poi_____.pfb/',
- 's/\busyr.pfb\b/sy______.pfb/',
- 's/\butmb8a.pfb\b/tib_____.pfb/',
- 's/\butmbi8a.pfb\b/tibi____.pfb/',
- 's/\butmr8a.pfb\b/tir_____.pfb/',
- 's/\butmri8a.pfb\b/tii_____.pfb/',
- 's/\buzcmi8a.pfb\b/zcmi____.pfb/',
- 's/\buzdr.pfb\b/zd______.pfb/',
- );
-
- if ($mode eq "" || $mode eq "URWkb") {
- # do nothing
- } elsif ($mode eq "URW") {
- for my $r (@fileURW) {
- map { eval($r); } @lines;
- }
- } elsif ($mode eq "ADOBE" || $mode eq "ADOBEkb") {
- for my $r (@psADOBE) {
- map { eval($r); } @lines;
- }
- my @filemode = eval ("\@file" . $mode);
- for my $r (@filemode) {
- map { eval($r); } @lines;
- }
- }
- return @lines;
-}
-
-###############################################################################
-# cidx2dvips()
-# reads from stdin, writes to stdout. It transforms "cid-x"-like syntax into
-# "dvips"-like syntax.
-#
-# Specifying the PS Name:
-# dvips needs the PSname instead of the file name. Thus we allow specifying
-# the PSname in the comment:
-# The PS Name can be specified in the font definition line
-# by including the following sequence somewhere after the
-# other components:
-#
-# %!PS<SPACE-TAB><PSNAME><NON-WORD-CHAR-OR-EOL>
-#
-# where
-# <SPACE-TAB> is either a space or a tab character
-# <PSNAME> is *one* word, defined by \w\w* perl re
-# <NON-WORD-CHAR-OR-EOL> is a non-\w char or the end of line
-#
-# That means we could have
-# ... %here the PS font name: %!PS fontname some other comment
-# ... %!PS fontname %other comments
-# ... %!PS fontname
-#
-# reimplementation of the cryptic code that was there before
-sub cidx2dvips {
- my ($s) = @_;
- my %fname_psname = (
- # Morisawa
- 'A-OTF-FutoGoB101Pr6N-Bold' => 'FutoGoB101Pr6N-Bold',
- 'A-OTF-FutoGoB101Pro-Bold' => 'FutoGoB101Pro-Bold',
- 'A-OTF-FutoMinA101Pr6N-Bold' => 'FutoMinA101Pr6N-Bold',
- 'A-OTF-FutoMinA101Pro-Bold' => 'FutoMinA101Pro-Bold',
- 'A-OTF-GothicBBBPr6N-Medium' => 'GothicBBBPr6N-Medium',
- 'A-OTF-GothicBBBPro-Medium' => 'GothicBBBPro-Medium',
- 'A-OTF-Jun101Pr6N-Light' => 'Jun101Pr6N-Light',
- 'A-OTF-Jun101Pro-Light' => 'Jun101Pro-Light',
- 'A-OTF-MidashiGoPr6N-MB31' => 'MidashiGoPr6N-MB31',
- 'A-OTF-MidashiGoPro-MB31' => 'MidashiGoPro-MB31',
- 'A-OTF-RyuminPr6N-Light' => 'RyuminPr6N-Light',
- 'A-OTF-RyuminPro-Light' => 'RyuminPro-Light',
- # Hiragino font file names and PS names are the same
- #
- # IPA
- 'ipaexg' => 'IPAexGothic',
- 'ipaexm' => 'IPAexMincho',
- 'ipag' => 'IPAGothic',
- 'ipam' => 'IPAMincho',
- #
- # Kozuka font names and PS names are the same
- );
- my @d;
- foreach (@$s) {
- # ship empty lines and comment lines out as is
- if (m/^\s*(%.*)?$/) {
- push(@d, $_);
- next;
- }
- # get rid of new lines for now
- chomp;
- # save the line for warnings
- my $l = $_;
- #
- my $psname;
- my $fbname;
- #
- # special case for pre-defined fallback from unicode encoded font
- if ($_ =~ m/%!DVIPSFB\s\s*([0-9A-Za-z-_!,][0-9A-Za-z-_!,]*)/) {
- $fbname = $1;
- # minimal adjustment
- $fbname =~ s/^!//;
- $fbname =~ s/,Bold//;
- }
- # first check whether a PSname is given
- # the matching on \w* is greedy, so will take all the word chars available
- # that means we do not need to test for end of word
- if ($_ =~ m/%!PS\s\s*([0-9A-Za-z-_][0-9A-Za-z-_]*)/) {
- $psname = $1;
- }
- # remove comments
- s/[^0-9A-Za-z-_]*%.*$//;
- # replace supported ",SOMETHING" constructs
- my $italicmax = 0;
- if (m/,BoldItalic/) {
- $italicmax = .3;
- s/,BoldItalic//;
- }
- s/,Bold//;
- if (m/,Italic/) {
- $italicmax = .3;
- s/,Italic//;
- }
- # replace supported "/AJ16" and co. for ptex-fontmaps CID emulation
- # note that the emulation method in GS is incomplete
- # due to "Reversal CMap method" (cf. "ToUnicode method")
- s!/A[JGCK]1[0-6]!!;
- # break out if unsupported constructs are found: @ / ,
- next if (m![\@/,]!);
- # make everything single spaced
- s/\s\s*/ /g;
- # unicode encoded fonts are not supported
- # but if a fallback font is pre-defined, we can use it
- next if (!defined($fbname) && (m!^[0-9A-Za-z-_][0-9A-Za-z-_]* unicode !));
- # now we have the following format
- # <word> <word> <word> some options like -e or -s
- if ($_ !~ m/([^ ][^ ]*) ([^ ][^ ]*) ([^ ][^ ]*)( (.*))?$/) {
- print_warning("cidx2dvips warning: Cannot translate font line:\n==> $l\n");
- print_warning("Current translation status: ==>$_==\n");
- next;
- }
- my $tfmname = $1;
- my $cid = $2;
- my $fname = $3;
- my $opts = (defined($5) ? " $5" : "");
- # remove extensions from $fname
- $fname =~ s/\.[Oo][Tt][Ff]//;
- $fname =~ s/\.[Tt][Tt][FfCc]//;
- # remove leading ! from $fname
- $fname =~ s/^!//;
- # remove leading :<number>: from $fname
- $fname =~ s/:[0-9]+://;
- # remove leading space from $opt
- $opts =~ s/^\s+//;
- # replace -e and -s in the options
- $opts =~ s/-e ([.0-9-][.0-9-]*)/ "$1 ExtendFont"/;
- if (m/-s ([.0-9-][.0-9-]*)/) {
- if ($italicmax > 0) {
- # we have already a definition of SlantFont via ,Italic or ,BoldItalic
- # warn the user that larger one is kept
- print_warning("cidx2dvips warning: Double slant specified via Italic and -s:\n==> $l\n==> Using only the biggest slant value.\n");
- }
- $italicmax = $1 if ($1 > $italicmax);
- $opts =~ s/-s ([.0-9-][.0-9-]*)//;
- }
- if ($italicmax != 0) {
- $opts .= " \"$italicmax SlantFont\"";
- }
- # print out the result
- if (defined($fbname)) {
- push @d, "$tfmname $fbname\n";
- } else {
- if (defined($psname)) {
- push @d, "$tfmname $psname-$cid$opts\n";
- } else {
- if (defined($fname_psname{$fname})) {
- push @d, "$tfmname $fname_psname{$fname}-$cid$opts\n";
- } else {
- push @d, "$tfmname $fname-$cid$opts\n";
- }
- }
- }
- }
- return @d;
-}
-
-sub cidx2dvips_old {
- my ($s) = @_;
- my @d;
- foreach (@$s) {
- if (m/^%/) {
- push(@d, $_);
- next;
- }
- s/,BoldItalic/ -s .3/;
- s/,Bold//;
- s/,Italic/ -s .3/;
- s/\s\s*/ /g;
- if ($_ =~ /.*[@\:\/,]/) {next;}
- elsif ($_ =~ /^[^ ][^ ]* unicode /) {next;}
- s/^([^ ][^ ]* [^ ][^ ]* [^ ][^ ]*)\.[Oo][Tt][Ff]/$1/;
- s/^([^ ][^ ]* [^ ][^ ]* [^ ][^ ]*)\.[Tt][Tt][FfCc]/$1/;
- s/$/ %/;
- s/^(([^ ]*).*)/$1$2/;
- s/^([^ ][^ ]* ([^ ][^ ]*) !*([^ ][^ ]*).*)/$1 $3-$2/;
- s/^(.* -e ([.0-9-][.0-9-]*).*)/$1 "$2 ExtendFont"/;
- s/^(.* -s ([.0-9-][.0-9-]*).*)/$1 "$2 SlantFont"/;
- s/.*%//;
- push(@d, $_);
- }
- return @d
-}
-
-sub get_cfg {
- my ($v) = @_;
- if (defined($alldata->{'merged'}{'setting'}{$v})) {
- return ( $alldata->{'merged'}{'setting'}{$v}{'val'},
- $alldata->{'merged'}{'setting'}{$v}{'origin'} );
- } else {
- return ($settings{$v}{'default'}, "default");
- }
-}
-
-sub mkMaps {
- my $logfile;
-
- $logfile = "$texmfvar/web2c/updmap.log";
-
- if (! $opts{'dry-run'}) {
- mkdirhier("$texmfvar/web2c");
- open LOG, ">$logfile"
- or die "$prg: Can't open log file \"$logfile\": $!";
- print LOG &version();
- printf LOG "%s\n\n", scalar localtime();
- print LOG "Using the following config files:\n";
- for (@{$opts{'cnffile'}}) {
- print LOG " $_\n";
- }
- }
- sub print_and_log {
- my $str=shift;
- print $str if !$opts{'quiet'};
- print LOG $str unless $opts{'dry-run'};
- }
- sub only_log {
- print LOG shift unless $opts{'dry-run'};
- }
-
- my ($mode, $mode_origin) = get_cfg('LW35');
- my ($dvipsPreferOutline, $dvipsPreferOutline_origin) =
- get_cfg('dvipsPreferOutline');
- my ($dvipsDownloadBase35, $dvipsDownloadBase35_origin) =
- get_cfg('dvipsDownloadBase35');
- my ($pdftexDownloadBase14, $pdftexDownloadBase14_origin) =
- get_cfg('pdftexDownloadBase14');
- my ($pxdviUse, $pxdviUse_origin) = get_cfg('pxdviUse');
- my ($jaEmbed, $jaEmbed_origin) = get_cfg('jaEmbed');
- my ($jaVariant, $jaVariant_origin) = get_cfg('jaVariant');
- my ($scEmbed, $scEmbed_origin) = get_cfg('scEmbed');
- my ($tcEmbed, $tcEmbed_origin) = get_cfg('tcEmbed');
- my ($koEmbed, $koEmbed_origin) = get_cfg('koEmbed');
-
- # keep backward compatibility with old definitions
- # of kanjiEmbed, kanjiVariant
- ($jaEmbed, $jaEmbed_origin) = get_cfg('kanjiEmbed')
- if (!defined($jaEmbed));
- ($jaVariant, $jaVariant_origin) = get_cfg('kanjiVariant')
- if (!defined($jaVariant));
-
-
- # pxdvi is optional, and off by default. Don't create the output
- # directory unless we are going to put something there.
- setupOutputDir("pxdvi") if $pxdviUse eq "true";
-
- print_and_log ("\n$prg is creating new map files"
- . "\nusing the following configuration:"
- . "\n LW35 font names : "
- . "$mode ($mode_origin)"
- . "\n prefer outlines : "
- . "$dvipsPreferOutline ($dvipsPreferOutline_origin)"
- . "\n texhash enabled : "
- . ($opts{'nohash'} ? "false" : "true")
- . "\n download standard fonts (dvips) : "
- . "$dvipsDownloadBase35 ($dvipsDownloadBase35_origin)"
- . "\n download standard fonts (pdftex) : "
- . "$pdftexDownloadBase14 ($pdftexDownloadBase14_origin)"
- . "\n jaEmbed replacement string : "
- . "$jaEmbed ($jaEmbed_origin)"
- . "\n jaVariant replacement string : "
- . ($jaVariant ? $jaVariant : "<empty>") . " ($jaVariant_origin)"
- . "\n scEmbed replacement string : "
- . "$scEmbed ($scEmbed_origin)"
- . "\n tcEmbed replacement string : "
- . "$tcEmbed ($tcEmbed_origin)"
- . "\n koEmbed replacement string : "
- . "$koEmbed ($koEmbed_origin)"
- . "\n create a mapfile for pxdvi : "
- . "$pxdviUse ($pxdviUse_origin)"
- . "\n\n");
-
- print_and_log ("Scanning for LW35 support files");
- my $dvips35 = $alldata->{'maps'}{"dvips35.map"}{'fullpath'};
- my $pdftex35 = $alldata->{'maps'}{"pdftex35.map"}{'fullpath'};
- my $ps2pk35 = $alldata->{'maps'}{"ps2pk35.map"}{'fullpath'};
- my $LW35 = "\n$dvips35\n$pdftex35\n$ps2pk35\n\n";
- only_log ("\n");
- only_log ($LW35);
- print_and_log (" [ 3 files]\n");
- only_log ("\n");
-
- print_and_log ("Scanning for MixedMap entries");
- my @mixedmaps;
- my @notmixedmaps;
- my @kanjimaps;
- for my $m (keys %{$alldata->{'maps'}}) {
- my $origin = $alldata->{'maps'}{$m}{'origin'};
- next if !defined($origin);
- next if ($origin eq 'builtin');
- next if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'} eq "disabled");
- push @mixedmaps, $m
- if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "MixedMap");
- push @notmixedmaps, $m
- if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "Map");
- push @kanjimaps, $m
- if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "KanjiMap");
- }
-
- @mixedmaps = sort @mixedmaps;
- @notmixedmaps = sort @notmixedmaps;
- @kanjimaps = sort @kanjimaps;
- only_log("\n");
- foreach my $m (sort @mixedmaps) {
- if (defined($alldata->{'maps'}{$m}{'fullpath'})) {
- only_log($alldata->{'maps'}{$m}{'fullpath'} . "\n");
- } else {
- only_log("$m (full path not set?)\n");
- }
- }
- only_log("\n");
- print_and_log (sprintf(" [%3d files]\n", scalar @mixedmaps));
- only_log("\n");
-
- print_and_log ("Scanning for KanjiMap entries");
- only_log("\n");
- foreach my $m (@kanjimaps) {
- if (defined($alldata->{'maps'}{$m}{'fullpath'})) {
- only_log($alldata->{'maps'}{$m}{'fullpath'} . "\n");
- } else {
- only_log("$m (full path not set?)\n");
- }
- }
- only_log("\n");
- print_and_log (sprintf(" [%3d files]\n", scalar @kanjimaps));
- only_log("\n");
-
- print_and_log ("Scanning for Map entries");
- only_log("\n");
- foreach my $m (@notmixedmaps) {
- if (defined($alldata->{'maps'}{$m}{'fullpath'})) {
- only_log($alldata->{'maps'}{$m}{'fullpath'} . "\n");
- } else {
- only_log("$m (full path not set?)\n");
- }
- }
- only_log("\n");
- print_and_log (sprintf(" [%3d files]\n\n", scalar @notmixedmaps));
- only_log("\n");
-
- my $first_time_creation_in_usermode = 0;
- # Create psfonts_t1.map, psfonts_pk.map, ps2pk.map and pdftex.map:
- my $dvipsoutputdir = $opts{'dvipsoutputdir'};
- my $pdftexoutputdir = $opts{'pdftexoutputdir'};
- my $dvipdfmxoutputdir = $opts{'dvipdfmxoutputdir'};
- my $pxdvioutputdir = $opts{'pxdvioutputdir'};
- if (!$opts{'dry-run'}) {
- my @managed_files = ("$dvipsoutputdir/download35.map",
- "$dvipsoutputdir/builtin35.map",
- "$dvipsoutputdir/psfonts_t1.map",
- "$dvipsoutputdir/psfonts_pk.map",
- "$pdftexoutputdir/pdftex_dl14.map",
- "$pdftexoutputdir/pdftex_ndl14.map",
- "$dvipdfmxoutputdir/kanjix.map",
- "$dvipsoutputdir/ps2pk.map");
- push @managed_files, "$pxdvioutputdir/xdvi-ptex.map"
- if ($pxdviUse eq "true");
- for my $file (@managed_files) {
- if (!$opts{'sys'} && ! -r $file) {
- $first_time_creation_in_usermode = 1;
- }
- open FILE, ">$file";
- print FILE "% $file:\
-% maintained by updmap[-sys] (multi).\
-% Don't change this file directly. Use updmap[-sys] instead.\
-% See the updmap documentation.\
-% A log of the run that created this file is available here:\
-% $logfile\
-";
- close FILE;
- }
- }
-
- my @kanjimaps_fonts = getFonts(@kanjimaps);
- @kanjimaps_fonts = &normalizeLines(@kanjimaps_fonts);
- my @ps2pk_fonts = getFonts('-all', "ps2pk35.map");
- my @dvips35_fonts = getFonts('-all', "dvips35.map");
- my @pdftex35_fonts = getFonts('-all', "pdftex35.map");
- my @mixedmaps_fonts = getFonts(@mixedmaps);
- my @notmixedmaps_fonts = getFonts(@notmixedmaps);
-
- print "Generating output for dvipdfmx...\n" if !$opts{'quiet'};
- &writeLines(">$dvipdfmxoutputdir/kanjix.map", @kanjimaps_fonts);
-
- if ($pxdviUse eq "true") {
- # we use the very same data as for kanjix.map, but generate
- # a different file, in case a user wants to hand-craft it
- print "Generating output for pxdvi...\n" if !$opts{'quiet'};
- &writeLines(">$pxdvioutputdir/xdvi-ptex.map", @kanjimaps_fonts);
- }
-
-
- print "Generating output for ps2pk...\n" if !$opts{'quiet'};
- my @ps2pk_map;
- push @ps2pk_map, "% ps2pk35.map";
- push @ps2pk_map, transLW35($mode, @ps2pk_fonts);
- push @ps2pk_map, @mixedmaps_fonts;
- push @ps2pk_map, @notmixedmaps_fonts;
- &writeLines(">$dvipsoutputdir/ps2pk.map",
- normalizeLines(@ps2pk_map));
-
- print "Generating output for dvips...\n" if !$opts{'quiet'};
- my @download35_map;
- push @download35_map, "% ps2pk35.map";
- push @download35_map, transLW35($mode, @ps2pk_fonts);
- &writeLines(">$dvipsoutputdir/download35.map",
- normalizeLines(@download35_map));
-
- my @builtin35_map;
- push @builtin35_map, "% dvips35.map";
- push @builtin35_map, transLW35($mode, @dvips35_fonts);
- &writeLines(">$dvipsoutputdir/builtin35.map",
- normalizeLines(@builtin35_map));
-
- my @dftdvips_fonts =
- (($dvipsDownloadBase35 eq "true") ? @ps2pk_fonts : @dvips35_fonts);
-
- my @psfonts_t1_map;
- if ($dvipsDownloadBase35 eq "true") {
- push @psfonts_t1_map, "% ps2pk35.map";
- @dftdvips_fonts = @ps2pk_fonts;
- } else {
- push @psfonts_t1_map, "% dvips35.map";
- @dftdvips_fonts = @dvips35_fonts;
- }
- push @psfonts_t1_map, transLW35($mode, @dftdvips_fonts);
- my @tmpkanji2 = cidx2dvips(\@kanjimaps_fonts);
- push @psfonts_t1_map, @mixedmaps_fonts;
- push @psfonts_t1_map, @notmixedmaps_fonts;
- push @psfonts_t1_map, @tmpkanji2;
- &writeLines(">$dvipsoutputdir/psfonts_t1.map",
- normalizeLines(@psfonts_t1_map));
-
- my @psfonts_pk_map;
- push @psfonts_pk_map, transLW35($mode, @dftdvips_fonts);
- push @psfonts_pk_map, @notmixedmaps_fonts;
- push @psfonts_pk_map, @tmpkanji2;
- &writeLines(">$dvipsoutputdir/psfonts_pk.map",
- normalizeLines(@psfonts_pk_map));
-
- print "Generating output for pdftex...\n" if !$opts{'quiet'};
- # remove PaintType due to Sebastian's request
- my @pdftexmaps_ndl;
- push @pdftexmaps_ndl, "% pdftex35.map";
- push @pdftexmaps_ndl, transLW35($mode, @pdftex35_fonts);
- push @pdftexmaps_ndl, @mixedmaps_fonts;
- push @pdftexmaps_ndl, @notmixedmaps_fonts;
- @pdftexmaps_ndl = grep { $_ !~ m/(^%\|PaintType)/ } @pdftexmaps_ndl;
-
- my @pdftexmaps_dl;
- push @pdftexmaps_dl, "% ps2pk35.map";
- push @pdftexmaps_dl, transLW35($mode, @ps2pk_fonts);
- push @pdftexmaps_dl, @mixedmaps_fonts;
- push @pdftexmaps_dl, @notmixedmaps_fonts;
- @pdftexmaps_dl = grep { $_ !~ m/(^%\|PaintType)/ } @pdftexmaps_dl;
-
- my @pdftex_ndl14_map = @pdftexmaps_ndl;
- @pdftex_ndl14_map = &normalizeLines(@pdftex_ndl14_map);
- @pdftex_ndl14_map = &to_pdftex(@pdftex_ndl14_map);
- &writeLines(">$pdftexoutputdir/pdftex_ndl14.map", @pdftex_ndl14_map);
-
- my @pdftex_dl14_map = @pdftexmaps_dl;
- @pdftex_dl14_map = &normalizeLines(@pdftex_dl14_map);
- @pdftex_dl14_map = &to_pdftex(@pdftex_dl14_map);
- &writeLines(">$pdftexoutputdir/pdftex_dl14.map", @pdftex_dl14_map);
-
- our $link = &setupSymlinks($dvipsPreferOutline, $dvipsoutputdir, $pdftexDownloadBase14, $pdftexoutputdir);
-
- print_and_log ("\nFiles generated:\n");
- sub dir {
- my ($d, $f, $target)=@_;
- our $link;
- if (-e "$d/$f") {
- my @stat=lstat("$d/$f");
- my ($s,$m,$h,$D,$M,$Y)=localtime($stat[9]);
- my $timestamp=sprintf ("%04d-%02d-%02d %02d:%02d:%02d",
- $Y+1900, $M+1, $D, $h, $m, $s);
- my $date=sprintf "%12d %s %s", $stat[7], $timestamp, $f;
- print_and_log ($date);
-
- if (-l "$d/$f") {
- my $lnk=sprintf " -> %s\n", readlink ("$d/$f");
- print_and_log ($lnk);
- } elsif ($f eq $target) {
- if (&files_are_identical("$d/$f", "$d/" . $link->{$target})) {
- print_and_log (" = $link->{$target}\n");
- } else {
- print_and_log (" = ?????\n"); # This shouldn't happen.
- }
- } else {
- print_and_log ("\n");
- }
- } else {
- print_warning("File $d/$f doesn't exist.\n");
- print LOG "Warning: File $d/$f doesn't exist.\n"
- unless $opts{'dry-run'};
- }
- }
-
- sub check_mismatch {
- my ($mm, $d, $f, $prog) = @_;
- chomp (my $kpsefound = `kpsewhich --progname=$prog $f`);
- if (lc("$d/$f") ne lc($kpsefound)) {
- $mm->{$f} = $kpsefound;
- }
- }
-
- my %mismatch;
- my $d;
- $d = "$dvipsoutputdir";
- print_and_log(" $d:\n");
- foreach my $f ('builtin35.map', 'download35.map', 'psfonts_pk.map',
- 'psfonts_t1.map', 'ps2pk.map', 'psfonts.map') {
- dir ($d, $f, 'psfonts.map');
- if (!$opts{'dry-run'}) {
- $updLSR->{add}("$d/$f");
- $updLSR->{exec}();
- $updLSR->{reset}();
- check_mismatch(\%mismatch, $d, $f, "dvips");
- }
- }
- $d = "$pdftexoutputdir";
- print_and_log(" $d:\n");
- foreach my $f ('pdftex_dl14.map', 'pdftex_ndl14.map', 'pdftex.map') {
- dir ($d, $f, 'pdftex.map');
- if (!$opts{'dry-run'}) {
- $updLSR->{add}("$d/$f");
- $updLSR->{exec}();
- $updLSR->{reset}();
- check_mismatch(\%mismatch, $d, $f, "pdftex");
- }
- }
- $d="$dvipdfmxoutputdir";
- print_and_log(" $d:\n");
- foreach my $f ('kanjix.map') {
- dir ($d, $f, '');
- if (!$opts{'dry-run'}) {
- $updLSR->{add}("$d/$f");
- $updLSR->{exec}();
- $updLSR->{reset}();
- check_mismatch(\%mismatch, $d, $f, "dvipdfmx");
- }
- }
- if ($pxdviUse eq "true") {
- $d="$pxdvioutputdir";
- print_and_log(" $d:\n");
- foreach my $f ('xdvi-ptex.map') {
- dir ($d, $f, '');
- $updLSR->{add}("$d/$f") unless $opts{'dry-run'};
- if (!$opts{'dry-run'}) {
- $updLSR->{add}("$d/$f");
- $updLSR->{exec}();
- $updLSR->{reset}();
- check_mismatch(\%mismatch, $d, $f, "xdvi");
- }
- }
- }
-
- # all kind of warning messages
- if ($first_time_creation_in_usermode) {
- print_and_log("
-*************************************************************
-* *
-* WARNING: you are switching to updmap's per-user mappings. *
-* Please read the following explanations. *
-* *
-*************************************************************
-
-You have run updmap-user (as opposed to updmap-sys) for the first time; this
-has created configuration files which are local to your personal account.
-
-Any changes in system map files will *not* be automatically reflected in
-your files; furthermore, running updmap-sys will no longer have any
-effect for you. As a consequence, you have to rerun updmap-user yourself
-after any change in the system directories; for example, if a new font
-package is added.
-
-See http://tug.org/texlive/scripts-sys-user.html for details.
-
-If you want to undo this, remove the files mentioned above.
-
-(Run $prg --help for full documentation of updmap.)
-");
- }
-
- if (keys %mismatch) {
- print_and_log("
-WARNING: $prg has found mismatched files!
-
-The following files have been generated as listed above,
-but will not be found because overriding files exist, listed below.
-");
- #
- if ($prg eq "updmap-sys") {
- print_and_log ("
-Perhaps you have run updmap in the past, but are running updmap-sys
-now. Once you run updmap the first time, you have to keep using it,
-or else remove the personal configuration files it creates (the ones
-listed below).
-");
- }
- #
- for my $f (sort keys %mismatch) {
- print_and_log (" $f: $mismatch{$f}\n");
- }
- #
- print_and_log("(Run $prg --help for full documentation of updmap.)\n");
- }
-
- close LOG unless $opts{'dry-run'};
- print "\nTranscript written on \"$logfile\".\n" if !$opts{'quiet'};
-
-}
-
-
-sub locateMap {
- my $map = shift;
- my $ret = `kpsewhich --format=map $map`;
- chomp($ret);
- return $ret;
-}
-
-sub processOptions {
- # first process the stupid setoption= s@{1,2} which is not accepted
- # furthermore, try to work around missing s{1,2} support in older perls
- my $oldconfig = Getopt::Long::Configure(qw(pass_through));
- our @setoptions;
- our @enable;
- sub read_one_or_two {
- my ($opt, $val) = @_;
- our @setoptions;
- our @enable;
- # check if = occirs in $val, if not, get the next argument
- if ($val =~ m/=/) {
- if ($opt eq "setoption") {
- push @setoptions, $val;
- } else {
- push @enable, $val;
- }
- } else {
- my $vv = shift @ARGV;
- die "Try \"$prg --help\" for more information.\n"
- if !defined($vv);
- if ($opt eq "setoption") {
- push @setoptions, "$val=$vv";
- } else {
- push @enable, "$val=$vv";
- }
- }
- }
- GetOptions("setoption=s@" => \&read_one_or_two,
- "enable=s@" => \&read_one_or_two) or
- die "Try \"$prg --help\" for more information.\n";
-
- @{$opts{'setoption'}} = @setoptions if (@setoptions);
- @{$opts{'enable'}} = @enable if (@enable);
-
- Getopt::Long::Configure($oldconfig);
-
- # now continue with normal option handling
-
- GetOptions(\%opts, @cmdline_options) or
- die "Try \"$prg --help\" for more information.\n";
-}
-
-# determines the output dir for driver from cmd line, or if not given
-# from TEXMFVAR
-sub setupOutputDir {
- my $driver = shift;
- if (!$opts{$driver . "outputdir"}) {
- if ($opts{'outputdir'}) {
- $opts{$driver . "outputdir"} = $opts{'outputdir'};
- } else {
- $opts{$driver . "outputdir"} = "$texmfvar/fonts/map/$driver/updmap";
- }
- }
- my $od = $opts{$driver . "outputdir"};
- if (!$opts{"dry-run"}) {
- &mkdirhier($od);
- if (! -w $od) {
- die "$prg: Directory \"$od\" isn't writable: $!";
- }
- }
- print "$driver output dir: \"$od\"\n" if !$opts{'quiet'};
- return $od;
-}
-
-###############################################################################
-# setOption (@options)
-# parse @options for "key=value" (one element of @options)
-# we can only have "key=value" since that is the way it was prepared
-# in process_options
-# (These were the values provided to --setoption.)
-#
-sub setOptions {
- my (@options) = @_;
- for (my $i = 0; $i < @options; $i++) {
- my $o = $options[$i];
-
- my ($key,$val) = split (/=/, $o, 2);
-
- die "$prg: unexpected empty key or val for options (@options), goodbye.\n"
- if !$key || !defined($val);
-
- &setOption ($key, $val);
- }
- return save_updmap($alldata->{'changes_config'});
-}
-
-sub enable_disable_maps {
- my (@what) = @_;
- my $tc = $alldata->{'changes_config'};
- die "$prg: top config file $tc has not been read."
- if (!defined($alldata->{'updmap'}{$tc}));
-
- for my $w (@what) {
- if ($w =~ m/=/) {
- # this is --enable MapType=MapName
- my ($type, $map) = split ('=', $w);
- # allow for all lowercase map types (map/mixedmap/kanjimap)
- $type =~ s/map$/Map/;
- $type = ucfirst($type);
- # don't allow map names containing /
- die "$prg: map names cannot contain /: $map\n" if ($map =~ m{/});
- enable_map($tc, $type, $map);
- } else {
- # this is --disable MapName
- disable_map($tc, $w);
- }
- }
- return save_updmap($tc);
-}
-
-sub enable_map {
- my ($tc, $type, $map) = @_;
-
- die "$prg: invalid mapType $type" if ($type !~ m/^(Map|MixedMap|KanjiMap)$/);
-
- if (defined($alldata->{'updmap'}{$tc}{'maps'}{$map})) {
- # the map data has already been read in, no special precautions necessary
- if (($alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} eq "enabled") &&
- ($alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} eq $type)) {
- # nothing to do here ... be happy!
- return;
- } else {
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "enabled";
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} = $type;
- $alldata->{'maps'}{$map}{'origin'} = $tc;
- $alldata->{'maps'}{$map}{'status'} = "enabled";
- $alldata->{'updmap'}{$tc}{'changed'} = 1;
- }
- } else {
- # add a new map file!
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} = $type;
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "enabled";
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'line'} = -1;
- $alldata->{'updmap'}{$tc}{'changed'} = 1;
- $alldata->{'maps'}{$map}{'origin'} = $tc;
- $alldata->{'maps'}{$map}{'status'} = "enabled";
- }
-}
-
-sub disable_map {
- my ($tc, $map) = @_;
-
- merge_settings_replace_kanji();
-
- if (defined($alldata->{'updmap'}{$tc}{'maps'}{$map})) {
- # the map data has already been read in, no special precautions necessary
- if ($alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} eq "disabled") {
- # nothing to do here ... be happy!
- } else {
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "disabled";
- $alldata->{'maps'}{$map}{'origin'} = $tc;
- $alldata->{'maps'}{$map}{'status'} = "disabled";
- $alldata->{'updmap'}{$tc}{'changed'} = 1;
- }
- } else {
- # disable a Map type that might be activated in a lower ranked updmap.cfg
- if (!defined($alldata->{'maps'}{$map})) {
- print_warning("map file not present, nothing to disable: $map\n");
- return;
- }
- my $orig = $alldata->{'maps'}{$map}{'origin'};
- # add a new entry to the top level where we disable it
- # copy over the type from the last entry
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} =
- $alldata->{'updmap'}{$orig}{'maps'}{$map}{'type'};
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "disabled";
- $alldata->{'updmap'}{$tc}{'maps'}{$map}{'line'} = -1;
- # rewrite the origin
- $alldata->{'maps'}{$map}{'origin'} = $tc;
- $alldata->{'maps'}{$map}{'status'} = "disabled";
- # go on for writing
- $alldata->{'updmap'}{$tc}{'changed'} = 1;
- }
-}
-
-
-# returns 1 if actually saved due to changes
-sub save_updmap {
- my $fn = shift;
- return if $opts{'dry-run'};
- my %upd = %{$alldata->{'updmap'}{$fn}};
- if ($upd{'changed'}) {
- mkdirhier(dirname($fn));
- open (FN, ">$fn") || die "$prg: can't write to $fn: $!";
- my @lines = @{$upd{'lines'}};
- if (!@lines) {
- print "Creating new config file $fn\n";
- # update lsR database
- $updLSR->{add}($fn);
- $updLSR->{exec}();
- # reset the LSR stuff, otherwise we add files several times
- $updLSR->{reset}();
- }
- # collect the lines with data
- my %line_to_setting;
- my %line_to_map;
- my @add_setting;
- my @add_map;
- if (defined($upd{'setting'})) {
- for my $k (keys %{$upd{'setting'}}) {
- if ($upd{'setting'}{$k}{'line'} == -1) {
- push @add_setting, $k;
- } else {
- $line_to_setting{$upd{'setting'}{$k}{'line'}} = $k;
- }
- }
- }
- if (defined($upd{'maps'})) {
- for my $k (keys %{$upd{'maps'}}) {
- if ($upd{'maps'}{$k}{'line'} == -1) {
- push @add_map, $k;
- } else {
- $line_to_map{$upd{'maps'}{$k}{'line'}} = $k;
- }
- }
- }
- for my $i (0..$#lines) {
- if (defined($line_to_setting{$i})) {
- my $k = $line_to_setting{$i};
- my $v = $upd{'setting'}{$k}{'val'};
- print FN "$k $v\n";
- } elsif (defined($line_to_map{$i})) {
- my $m = $line_to_map{$i};
- my $rm;
- if (defined($upd{'maps'}{$m}{'original'})) {
- # we have the case that @noEmbed@ was replaced by the respective
- # setting. Before writing out we have to replace this back with
- # the original line!A
- $rm = $upd{'maps'}{$m}{'original'};
- } else {
- $rm = $m;
- }
- my $t = $upd{'maps'}{$m}{'type'};
- my $p = ($upd{'maps'}{$m}{'status'} eq "disabled" ? "#! " : "");
- print FN "$p$t $rm\n";
- } else {
- print FN "$lines[$i]\n";
- }
- }
- # add the new settings and maps
- for my $k (@add_setting) {
- my $v = $upd{'setting'}{$k}{'val'};
- print FN "$k $v\n";
- }
- for my $m (@add_map) {
- my $t = $upd{'maps'}{$m}{'type'};
- my $p = ($upd{'maps'}{$m}{'status'} eq "disabled" ? "#! " : "");
- print FN "$p$t $m\n";
- }
- close(FN) || warn("$prg: Cannot close file handle for $fn: $!");
- delete $alldata->{'updmap'}{$fn}{'changed'};
- return 1;
- }
- return 0;
-}
-
-######################
-# check for correct option value
-#
-sub check_option {
- my ($opt, $val) = @_;
- if ((($settings{$opt}{'type'} eq "binary") &&
- $val ne "true" && $val ne "false") ||
- (($settings{$opt}{'type'} eq "string") &&
- !member($val, @{$settings{$opt}{'possible'}}))) {
- return 0;
- }
- return 1;
-}
-
-###############################################################################
-# setOption (conf_file, option, value)
-# sets option to value in the config file (replacing the existing setting
-# or by adding a new line to the config file).
-#
-sub setOption {
- my ($opt, $val) = @_;
-
- # allow backward compatility with old kanjiEmbed and kanjiVariant settings
- if ($opt eq "kanjiEmbed") {
- print_warning("using jaEmbed instead of kanjiEmbed\n");
- $opt = "jaEmbed";
- }
- if ($opt eq "kanjiVariant") {
- print_warning("using jaVariant instead of kanjiVariant\n");
- $opt = "jaVariant";
- }
-
- die "$prg: Unsupported option $opt." if (!defined($settings{$opt}));
- die "$0: Invalid value $val for option $opt."
- if (!check_option($opt, $val));
-
- # silently accept this old option name, just in case.
- return if $opt eq "dvipdfmDownloadBase14";
-
- #print "Setting option $opt to $val...\n" if !$opts{'quiet'};
- my $tc = $alldata->{'changes_config'};
-
- die "$prg: top config file $tc has not been read."
- if (!defined($alldata->{'updmap'}{$tc}));
-
- if (defined($alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'})) {
- # the value is already set, do nothing
- if ($alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} eq $val) {
- return;
- }
- $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} = $val;
- $alldata->{'updmap'}{$tc}{'changed'} = 1;
- } else {
- $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} = $val;
- $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'line'} = -1;
- $alldata->{'updmap'}{$tc}{'changed'} = 1;
- }
-}
-
-
-###############################################################################
-# copyFile()
-# copy file $src to $dst, sets $dst creation and mod time
-#
-sub copyFile {
- my ($src, $dst) = @_;
- my $dir;
- ($dir=$dst)=~s/(.*)\/.*/$1/;
- mkdirhier($dir);
-
- $src eq $dst && return "can't copy $src to itself!\n";
-
- open IN, "<$src" or die "$0: can't open source file $src for copying: $!";
- open OUT, ">$dst";
-
- binmode(IN);
- binmode(OUT);
- print OUT <IN>;
- close(OUT);
- close(IN);
- my @t = stat($src);
- utime($t[8], $t[9], $dst);
-}
-
-###############################################################################
-# files_are_identical(file_A, file_B)
-# compare two files. Same as cmp(1).
-#
-sub files_are_identical {
- my $file_A=shift;
- my $file_B=shift;
- my $retval=0;
-
- open IN, "$file_A";
- my $A=(<IN>);
- close IN;
- open IN, "$file_B";
- my $B=(<IN>);
- close IN;
-
- $retval=1 if ($A eq $B);
- return $retval;
-}
-
-###############################################################################
-# files_are_different(file_A, file_B[, comment_char])
-# compare two equalized files.
-#
-sub files_are_different {
- my $file_A=shift;
- my $file_B=shift;
- my $comment=shift;
- my $retval=0;
-
- my $A=equalize_file("$file_A", $comment);
- my $B=equalize_file("$file_B", $comment);
- $retval=1 unless ($A eq $B);
- return $retval;
-}
-
-###############################################################################
-# equalize_file(filename[, comment_char])
-# read a file and return its processed content as a string.
-# look into the source code for more details.
-#
-sub equalize_file {
- my $file=shift;
- my $comment=shift;
- my @temp;
-
- open IN, "$file";
- my @lines = (<IN>);
- close IN;
- chomp(@lines);
-
- for (@lines) {
- s/\s*${comment}.*// if (defined $comment); # remove comments
- next if /^\s*$/; # remove empty lines
- s/\s+/ /g; # replace multiple whitespace chars by a single one
- push @temp, $_;
- }
- return join('X', sort(@temp));
-}
-
-###############################################################################
-# normalizeLines()
-# not the original function, we want it to keep comments, that are
-# anyway only the file names we are adding!
-# whitespace is exactly one space, no empty lines,
-# no whitespace at end of line, one space before and after "
-#
-sub normalizeLines {
- my @lines = @_;
- my %count = ();
-
- # @lines = grep { $_ !~ m/^[*#;%]/ } @lines;
- map {$_ =~ s/\s+/ /gx } @lines;
- @lines = grep { $_ !~ m/^\s*$/x } @lines;
- map { $_ =~ s/\s$//x ;
- $_ =~ s/\s*\"\s*/ \" /gx;
- $_ =~ s/\" ([^\"]*) \"/\"$1\"/gx;
- } @lines;
-
- # @lines = grep {++$count{$_} < 2 } (sort @lines);
- @lines = grep {++$count{$_} < 2 } (@lines);
-
- return @lines;
-}
-
-
-#################################################################
-#
-# reading updmap-cfg files and the actual map files
-#
-# the following hash saves *all* the information and is passed around
-# we do not fill everything from the very beginning to make sure that
-# we only read what is necessary (speed!)
-#
-# initialized by main
-# $alldata->{'changes_config'} = the config file where changes are saved
-#
-# initialized by read_updmap_files
-# $alldata->{'order'} = [ list of updmap in decreasing priority ]
-# $alldata->{'updmap'}{$full_path_name_of_updmap}{'lines'} = \@lines
-# $alldata->{'updmap'}{$full_path_name_of_updmap}{'setting'}{$key}{'val'} = $val
-# $alldata->{'updmap'}{$full_path_name_of_updmap}{'setting'}{$key}{'line'} = $i
-# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'type'}
-# = 'Map'|'MixedMap'|'KanjiMap'|'disabled'
-# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'status'}
-# = 'enabled'|'disabled'
-# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'line'} = $i
-# $alldata->{'maps'}{$m}{'origin'} = $updmap_path_name
-# $alldata->{'maps'}{$m}{'status'} = enabled | disabled
-#
-# initialized by read_map_files
-# $alldata->{'maps'}{$m}{'fonts'}{$font} = $definition
-# $alldata->{'fonts'}{$f}{'origin'} = $map
-#
-# initialized by merge_data
-# $alldata->{'merged'}{'setting'}{$key}{'val'} = $val
-# $alldata->{'merged'}{'setting'}{$key}{'origin'} = $origin_updmap_cfg
-# $alldata->{'merged'}{'allMaps'}{'fonts'}{$fontdef} = $rest
-# $alldata->{'merged'}{'noMixedMaps'}{'fonts'}{$fontdef} = $rest
-# $alldata->{'merged'}{'KanjiMaps'}{'fonts'}{$fontdef} = $rest
-#
-
-sub read_updmap_files {
- my (@l) = @_;
- for my $l (@l) {
- my $updmap = read_updmap_file($l);
- $alldata->{'updmap'}{$l}{'lines'} = $updmap->{'lines'};
- if (defined($updmap->{'setting'})) {
- for my $k (keys %{$updmap->{'setting'}}) {
- $alldata->{'updmap'}{$l}{'setting'}{$k}{'val'} = $updmap->{'setting'}{$k}{'val'};
- $alldata->{'updmap'}{$l}{'setting'}{$k}{'line'} = $updmap->{'setting'}{$k}{'line'};
- }
- }
- if (defined($updmap->{'maps'})) {
- for my $k (keys %{$updmap->{'maps'}}) {
- $alldata->{'updmap'}{$l}{'maps'}{$k}{'type'} = $updmap->{'maps'}{$k}{'type'};
- $alldata->{'updmap'}{$l}{'maps'}{$k}{'status'} = $updmap->{'maps'}{$k}{'status'};
- $alldata->{'updmap'}{$l}{'maps'}{$k}{'line'} = $updmap->{'maps'}{$k}{'line'};
- }
- }
- }
- # in case the changes_config is a new one read it in and initialize it here
- my $cc = $alldata->{'changes_config'};
- if (! -r $cc) {
- $alldata->{'updmap'}{$cc}{'lines'} = [ ];
- }
- #
- $alldata->{'order'} = \@l;
-}
-
-sub merge_settings_replace_kanji {
- #
- my @l = @{$alldata->{'order'}};
- #
- # for security clean out everything that was there
- %{$alldata->{'merged'}} = ();
- #
- # first read in the settings
- # we read it in *reverse* order and simple fill up the combined data
- # thus if there are multiple definitions/settings, the one coming from
- # the first in the original list will win!
- for my $l (reverse @l) {
- # merge settings
- if (defined($alldata->{'updmap'}{$l}{'setting'})) {
- for my $k (keys %{$alldata->{'updmap'}{$l}{'setting'}}) {
- $alldata->{'merged'}{'setting'}{$k}{'val'} = $alldata->{'updmap'}{$l}{'setting'}{$k}{'val'};
- $alldata->{'merged'}{'setting'}{$k}{'origin'} = $l;
- }
- }
- }
- #
- my ($jaEmbed, $jaEmbed_origin) = get_cfg('jaEmbed');
- my ($jaVariant, $jaVariant_origin) = get_cfg('jaVariant');
- my ($scEmbed, $scEmbed_origin) = get_cfg('scEmbed');
- my ($tcEmbed, $tcEmbed_origin) = get_cfg('tcEmbed');
- my ($koEmbed, $koEmbed_origin) = get_cfg('koEmbed');
-
- # keep backward compatibility with old definitions
- # of kanjiEmbed, kanjiVariant
- ($jaEmbed, $jaEmbed_origin) = get_cfg('kanjiEmbed')
- if (!defined($jaEmbed));
- ($jaVariant, $jaVariant_origin) = get_cfg('kanjiVariant')
- if (!defined($jaVariant));
-
- #
- # go through all map files and check that the text is properly replaced
- # after the replacement check that the generated map file actually
- # exists, we do NOT want to break in this case!
- #
- for my $l (@l) {
- for my $m (keys %{$alldata->{'updmap'}{$l}{'maps'}}) {
- my $newm = $m;
- # do all kinds of substitutions
- $newm =~ s/\@jaEmbed@/$jaEmbed/;
- $newm =~ s/\@jaVariant@/$jaVariant/;
- $newm =~ s/\@scEmbed@/$scEmbed/;
- $newm =~ s/\@tcEmbed@/$tcEmbed/;
- $newm =~ s/\@koEmbed@/$koEmbed/;
- # also do substitutions of old strings in case they are left
- # over somewhere
- $newm =~ s/\@kanjiEmbed@/$jaEmbed/;
- $newm =~ s/\@kanjiVariant@/$jaVariant/;
- if ($newm ne $m) {
- # something was substituted
- if (locateMap($newm)) {
- # now we have to update various linked items
- $alldata->{'updmap'}{$l}{'maps'}{$newm}{'type'} =
- $alldata->{'updmap'}{$l}{'maps'}{$m}{'type'};
- $alldata->{'updmap'}{$l}{'maps'}{$newm}{'status'} =
- $alldata->{'updmap'}{$l}{'maps'}{$m}{'status'};
- $alldata->{'updmap'}{$l}{'maps'}{$newm}{'line'} =
- $alldata->{'updmap'}{$l}{'maps'}{$m}{'line'};
- $alldata->{'updmap'}{$l}{'maps'}{$newm}{'original'} = $m;
- } else {
- print_warning("generated map $newm (from $m) does not exist, not activating it!\n");
- }
- # in any case delete the @kanji...@ entry line, such a map will
- # never exist
- delete $alldata->{'updmap'}{$l}{'maps'}{$m};
- }
- }
- }
- #
- # first round determine which maps should be used and which type, as
- # different updmap.cfg files might specify different types of maps
- # (MixedMap or Map or KanjiMap).
- # Again, we have to do that in reverse order
- for my $l (reverse @l) {
- if (defined($alldata->{'updmap'}{$l}{'maps'})) {
- for my $m (keys %{$alldata->{'updmap'}{$l}{'maps'}}) {
- $alldata->{'maps'}{$m}{'origin'} = $l;
- $alldata->{'maps'}{$m}{'status'} = $alldata->{'updmap'}{$l}{'maps'}{$m}{'status'};
- }
- }
- }
-}
-
-sub read_updmap_file {
- my $fn = shift;
- my %data;
- if (!open(FN,"<$fn")) {
- die ("Cannot read $fn: $!");
- }
- # we count lines from 0 ..!!!!
- my $i = -1;
- my @lines = <FN>;
- chomp(@lines);
- $data{'lines'} = [ @lines ];
- close(FN) || warn("$prg: Cannot close $fn: $!");
- for (@lines) {
- $i++;
- chomp;
- next if /^\s*$/;
- next if /^\s*#$/;
- next if /^\s*#[^!]/;
- next if /^\s*##/;
- next if /^#![^ ]/;
- # allow for commands on the line itself
- s/([^#].*)#.*$/$1/;
- my ($a, $b, @rest) = split ' ';
- # make sure we get empty strings as arguments
- $b = "" if (!defined($b));
- if ($a eq "#!") {
- if ($b eq "Map" || $b eq "MixedMap" || $b eq "KanjiMap") {
- my $c = shift @rest;
- if (!defined($c)) {
- print_warning("apparently not a real disable line, ignored: $_\n");
- } else {
- if (defined($data{'maps'}{$c})) {
- print_warning("double mention of $c in $fn\n");
- }
- $data{'maps'}{$c}{'status'} = 'disabled';
- $data{'maps'}{$c}{'type'} = $b;
- $data{'maps'}{$c}{'line'} = $i;
- }
- }
- next;
- }
- if (@rest) {
- print_warning("line $i in $fn contains a syntax error, more than two words!\n");
- }
- # backward compatibility with kanjiEmbed/kanjiVariant
- $a = ($a eq "kanjiEmbed" ? "jaEmbed" : $a);
- $a = ($a eq "kanjiVariant" ? "jaVariant" : $a);
- if (defined($settings{$a})) {
- if (check_option($a, $b)) {
- $data{'setting'}{$a}{'val'} = $b;
- $data{'setting'}{$a}{'line'} = $i;
- } else {
- print_warning("unknown setting for $a: $b, ignored!\n");
- }
- } elsif ($a eq "Map" || $a eq "MixedMap" || $a eq "KanjiMap") {
- if (defined($data{'maps'}{$b}) && $data{'maps'}{$b}{'type'} ne $a) {
- print_warning("double mention of $b with conflicting types in $fn\n");
- } else {
- $data{'maps'}{$b}{'type'} = $a;
- $data{'maps'}{$b}{'status'} = 'enabled';
- $data{'maps'}{$b}{'line'} = $i;
- }
- } else {
- print_warning("unrecognized line $i in $fn: $_\n");
- }
- }
- return \%data;
-}
-
-sub read_map_files {
- my $quick = shift;
- if (!defined($alldata->{'updmap'})) {
- return;
- }
- my @missing;
- my @l = @{$alldata->{'order'}};
- # first collect all the map files we are interested in
- # and determine whether they exist, and get their full path
- my @maps;
- for my $f (@l) {
- next if !defined($alldata->{'updmap'}{$f}{'maps'});
- for my $m (keys %{$alldata->{'updmap'}{$f}{'maps'}}) {
- # only read a map file if its final status is enabled!
- push @maps, $m if ($alldata->{'maps'}{$m}{'status'} eq 'enabled');
- }
- }
- for my $m (qw/dvips35.map pdftex35.map ps2pk35.map/) {
- push @maps, $m;
- $alldata->{'maps'}{$m}{'status'} = 'enabled';
- $alldata->{'maps'}{$m}{'origin'} = 'builtin';
- }
- @maps = sort_uniq(@maps);
- my @fullpath = `kpsewhich --format=map @maps`;
- chomp @fullpath;
- foreach my $map (@maps) {
- # in case they give an absolute path (not needed/desired, but ...);
- # Windows not supported.
- my $dirsep = ($map =~ m!^/!) ? "" : "/";
- # quotemeta the map string to avoid perl regexp warning, e.g.,
- # if map name contains "\Users", the "\U" should be literal.
- my ($ff) = grep /$dirsep\Q$map\E(\.map)?$/, @fullpath;
- if ($ff) {
- $alldata->{'maps'}{$map}{'fullpath'} = $ff;
- } else {
- # if the map file is not found, then push it onto the list of
- # missing map files, since we know that it is enabled
- push @missing, $map;
- }
- }
- return @missing if $quick;
-
- #
- # read in the three basic fonts definition maps
- for my $m (qw/dvips35.map pdftex35.map ps2pk35.map/) {
- my $ret = read_map_file($alldata->{'maps'}{$m}{'fullpath'});
- my @ff = ();
- for my $font (keys %$ret) {
- $alldata->{'fonts'}{$font}{'origin'} = $m;
- $alldata->{'maps'}{$m}{'fonts'}{$font} = $ret->{$font};
- }
- }
- # we read the updmap in reverse directions, since we
- # replace the origin field of font definition always with the
- # top one
- for my $f (reverse @l) {
- my @maps = keys %{$alldata->{'updmap'}{$f}{'maps'}};
- for my $m (@maps) {
- # we do not read a map file multiple times, if $alldata{'maps'}{$m} is
- # defined we expect that it was read and do skip it
- next if defined($alldata->{'maps'}{$m}{'fonts'});
- # we do not read a map files content if it is disabled
- next if ($alldata->{'maps'}{$m}{'status'} eq 'disabled');
- if (!defined($alldata->{'maps'}{$m}{'fullpath'})) {
- # we have already pushed these map files onto the list of missing
- # map files, so do nothing here
- next;
- }
- my $ret = read_map_file($alldata->{'maps'}{$m}{'fullpath'});
- if (defined($ret)) {
- for my $font (keys %$ret) {
- if (defined($alldata->{'fonts'}{$font})) {
- # we got another definition, warn on that
- # if the origin is not defined by now, the font is defined
- # multiple times in the same map file, otherwise it is
- # defined in another map file already
- if (defined($alldata->{'fonts'}{$font}{'origin'})) {
- my $fontorig = $alldata->{'fonts'}{$font}{'origin'};
- my $maporig;
- if (($fontorig eq "ps2pk35.map") ||
- ($fontorig eq "pdftex35.map") ||
- ($fontorig eq "dvips35.map")) {
- $maporig = "built in map - both used - warning!";
- } else {
- $maporig = "from " . $alldata->{'maps'}{$fontorig}{'origin'};
- }
- print_warning("font $font is defined multiple times:\n");
- print_warning(" $fontorig ($maporig)\n");
- print_warning(" $m (from $f) (used)\n");
- } else {
- print_warning("font $font is multiply defined in $m, using an arbitrary instance!\n");
- }
- }
- $alldata->{'fonts'}{$font}{'origin'} = $m;
- $alldata->{'maps'}{$m}{'fonts'}{$font} = $ret->{$font};
- }
- }
- }
- }
- return (@missing);
-}
-
-sub read_map_file {
- my $fn = shift;
- my @lines;
- if (!open(MF,"<$fn")) {
- warn("$prg: open($fn) failed: $!");
- return;
- }
- @lines = <MF>;
- close(MF);
- chomp(@lines);
- my %data;
- for (@lines) {
- next if /^\s*#/;
- next if /^\s*%/;
- next if /^\s*$/;
- my ($a, $b) = split(' ', $_, 2);
- $data{$a} = $b;
- }
- return \%data;
-}
-
-#
-# merging the various font definitions
-#
-sub merge_data {
- my @l = @{$alldata->{'order'}};
- #
- # now merge the data
- #
- for my $m (keys %{$alldata->{'maps'}}) {
- my $origin = $alldata->{'maps'}{$m}{'origin'};
- next if !defined($origin);
- next if ($origin eq 'builtin');
- next if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'} eq "disabled");
- for my $f (keys %{$alldata->{'maps'}{$m}{'fonts'}}) {
- # use the font definition only for those fonts where the origin matches
- if ($alldata->{'fonts'}{$f}{'origin'} eq $m) {
- $alldata->{'merged'}{'allMaps'}{'fonts'}{$f} =
- $alldata->{'maps'}{$m}{'fonts'}{$f}
- if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} ne "KanjiMap");
- $alldata->{'merged'}{'noMixedMaps'}{'fonts'}{$f} =
- $alldata->{'maps'}{$m}{'fonts'}{$f}
- if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "Map");
- $alldata->{'merged'}{'KanjiMap'}{'fonts'}{$f} =
- $alldata->{'maps'}{$m}{'fonts'}{$f}
- if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "KanjiMap");
- }
- }
- }
-}
-
-
-#
-# $HOME and sudo and updmap-sys horror
-# some instances of sudo do not reset $HOME to the home of root
-# as an effect of "sudo updmap" creates root owned files in the home
-# of a normal user, and "sudo updmap-sys" uses map files and updmap.cfg
-# files from the directory of a normal user, but creating files
-# in TEXMFSYSCONFIG. This is *all* wrong.
-# we check: if we are running as UID 0 (root) on Unix and the
-# ENV{HOME} is NOT the same as the one of root, then give a warning
-# and reset it to the real home dir of root.
-
-sub reset_root_home {
- if (!win32() && ($> == 0)) { # $> is effective uid
- my $envhome = $ENV{'HOME'};
- # if $HOME isn't an existing directory, we don't care.
- if (defined($envhome) && (-d $envhome)) {
- # we want to avoid calling getpwuid as far as possible, so if
- # $envhome is one of some usual values we accept it without worrying.
- if ($envhome =~ m,^(/|/root|/var/root)/*$,) {
- return;
- }
- # $HOME is defined, check what is the home of root in reality
- my (undef,undef,undef,undef,undef,undef,undef,$roothome) = getpwuid(0);
- if (defined($roothome)) {
- if ($envhome ne $roothome) {
- print_warning("resetting \$HOME value (was $envhome) to root's "
- . "actual home ($roothome).\n");
- $ENV{'HOME'} = $roothome;
- } else {
- # envhome and roothome do agree, nothing to do, that is the good case
- }
- } else {
- print_warning("home of root not defined, strange!\n");
- }
- }
- }
-}
-
-sub print_warning {
- print STDERR "$prg [WARNING]: ", @_ if (!$opts{'quiet'})
-}
-sub print_error {
- print STDERR "$prg [ERROR]: ", @_;
-}
-
-
-# help, version.
-
-sub version {
- my $ret = sprintf "%s version %s\n", $prg, $version;
- return $ret;
-}
-
-sub help {
- my $usage = <<"EOF";
-Usage: $prg [-user|-sys] [OPTION] ... [COMMAND]
- or: $prg-user [OPTION] ... [COMMAND]
- or: $prg-sys [OPTION] ... [COMMAND]
-
-Update the default font map files used by pdftex (pdftex.map), dvips
-(psfonts.map), and dvipdfm(x), and optionally pxdvi, as determined by
-all configuration files updmap.cfg (the ones returned by running
-"kpsewhich --all updmap.cfg", but see below).
-
-Among other things, these map files are used to determine which fonts
-should be used as bitmaps and which as outlines, and to determine which
-font files are included, typically subsetted, in the PDF or PostScript output.
-
-updmap-sys (or updmap -sys) is intended to affect the system-wide
-configuration, while updmap-user (or updmap -user) affects personal
-configuration files only, overriding the system files.
-As a consequence, once updmap-user has been run, even a single time,
-running updmap-sys no longer has any effect. (updmap-sys issues a
-warning in this situation.)
-
-See http://tug.org/texlive/scripts-sys-user.html for details.
-
-By default, the TeX filename database (ls-R) is also updated.
-
-The updmap system is regrettably complicated, for both inherent and
-historical reasons. A general overview:
-
-- updmap.cfg files are mainly about listing other files, namely the
- font-specific .maps, in which each line gives information about a
- different TeX (.tfm) font.
-- updmap reads the updmap.cfg files and then concatenates the
- contents of those .map files into the main output files: psfonts.map
- for dvips and pdftex.map for pdftex and dvipdfmx.
-- The updmap.cfg files themselves are created and updated at package
- installation time, by the system installer or the package manager or
- by hand, and not (by default) by updmap.
-
-Good luck.
-
-Options:
- --cnffile FILE read FILE for the updmap configuration
- (can be given multiple times, in which case
- all the files are used)
- --dvipdfmxoutputdir DIR specify output directory (dvipdfm(x) syntax)
- --dvipsoutputdir DIR specify output directory (dvips syntax)
- --pdftexoutputdir DIR specify output directory (pdftex syntax)
- --pxdvioutputdir DIR specify output directory (pxdvi syntax)
- --outputdir DIR specify output directory (for all files)
- --copy cp generic files rather than using symlinks
- --force recreate files even if config hasn't changed
- --nomkmap do not recreate map files
- --nohash do not run texhash
- --sys affect system-wide files (equivalent to updmap-sys)
- --user affect personal files (equivalent to updmap-user)
- -n, --dry-run only show the configuration, no output
- --quiet, --silent reduce verbosity
-
-Commands:
- --help show this message and exit
- --version show version information and exit
- --showoption OPTION show the current setting of OPTION
- --showoptions OPTION show possible settings for OPTION
- --setoption OPTION VALUE set OPTION to value; option names below
- --setoption OPTION=VALUE as above, just different syntax
- --enable MAPTYPE MAPFILE add "MAPTYPE MAPFILE" to updmap.cfg,
- where MAPTYPE is Map, MixedMap, or KanjiMap
- --enable Map=MAPFILE add \"Map MAPFILE\" to updmap.cfg
- --enable MixedMap=MAPFILE add \"MixedMap MAPFILE\" to updmap.cfg
- --enable KanjiMap=MAPFILE add \"KanjiMap MAPFILE\" to updmap.cfg
- --disable MAPFILE disable MAPFILE, of whatever type
- --listmaps list all maps (details below)
- --listavailablemaps list available maps (details below)
- --syncwithtrees disable unavailable map files in updmap.cfg
-
-The main output:
-
- The main output of updmap is the files containing the individual font
- map lines which the drivers (dvips, pdftex, etc.) read to handle fonts.
-
- The map files for dvips (psfonts.map) and pdftex and dvipdfmx
- (pdftex.map) are written to TEXMFVAR/fonts/map/updmap/{dvips,pdftex}/.
-
- In addition, information about Kanji fonts is written to
- TEXMFVAR/fonts/map/updmap/dvipdfmx/kanjix.map, and optionally to
- TEXMFVAR/fonts/map/updmap/pxdvi/xdvi-ptex.map. These are for Kanji
- only and are not like other map files. dvipdfmx reads pdftex.map for
- the map entries for non-Kanji fonts.
-
- If no option is given, so the invocation is just "updmap-user" or
- "updmap-sys", these output files are always recreated.
-
- Otherwise, if an option such as --enable or --disable is given, the
- output files are recreated if the list of enabled map files (from
- updmap.cfg) has changed. The --force option overrides this,
- always recreating the output files.
-
-Explanation of the map types:
-
- The normal type is Map.
-
- The only difference between Map and MixedMap is that MixedMap entries
- are not added to psfonts_pk.map. The purpose is to help users with
- devices that render Type 1 outline fonts worse than mode-tuned Type 1
- bitmap fonts. So, MixedMap is used for fonts that are available as
- both Type 1 and Metafont.
-
- KanjiMap entries are added to psfonts_t1.map and kanjix.map.
-
-Explanation of the OPTION names for --showoptions, --showoption, --setoption:
-
- dvipsPreferOutline true,false (default true)
- Whether dvips uses bitmaps or outlines, when both are available.
- dvipsDownloadBase35 true,false (default true)
- Whether dvips includes the standard 35 PostScript fonts in its output.
- pdftexDownloadBase14 true,false (default true)
- Whether pdftex includes the standard 14 PDF fonts in its output.
- pxdviUse true,false (default false)
- Whether maps for pxdvi (Japanese-patched xdvi) are under updmap's control.
- jaEmbed (any string)
- jaVariant (any string)
- scEmbed (any string)
- tcEmbed (any string)
- koEmbed (any string)
- See below.
- LW35 URWkb,URW,ADOBEkb,ADOBE (default URWkb)
- Adapt the font and file names of the standard 35 PostScript fonts.
-
- URWkb URW fonts with "berry" filenames (e.g. uhvbo8ac.pfb)
- URW URW fonts with "vendor" filenames (e.g. n019064l.pfb)
- ADOBEkb Adobe fonts with "berry" filenames (e.g. phvbo8an.pfb)
- ADOBE Adobe fonts with "vendor" filenames (e.g. hvnbo___.pfb)
-
- These options are only read and acted on by updmap; dvips, pdftex, etc.,
- do not know anything about them. They work by changing the default map
- file which the programs read, so they can be overridden by specifying
- command-line options or configuration files to the programs, as
- explained at the beginning of updmap.cfg.
-
- The options jaEmbed and jaVariant (formerly kanjiEmbed and kanjiVariant)
- specify special replacements in the map lines. If a map contains the
- string \@jaEmbed\@, then this will be replaced by the value of that option;
- similarly for jaVariant. In this way, users of Japanese TeX can select
- different fonts to be included in the final output. The counterpart for
- Simplified Chinese, Traditional Chinese and Korean fonts are
- scEmbed, tcEmbed and koEmbed respectively.
-
-Explanation of trees and files normally used:
-
- If --cnffile is specified on the command line (can be given multiple
- times), its value(s) is(are) used. Otherwise, updmap reads all the
- updmap.cfg files found by running \`kpsewhich -all updmap.cfg',
- in the order returned by kpsewhich (which is the order of trees
- defined in texmf.cnf).
-
- In either case, if multiple updmap.cfg files are found, all the maps
- mentioned in all the updmap.cfg files are merged.
-
- Thus, if updmap.cfg files are present in all trees, and the default
- layout is used as shipped with TeX Live, the following files are
- read, in the given order.
-
- For updmap-sys:
- TEXMFSYSCONFIG \$TEXLIVE/YYYY/texmf-config/web2c/updmap.cfg
- TEXMFSYSVAR \$TEXLIVE/YYYY/texmf-var/web2c/updmap.cfg
- TEXMFLOCAL \$TEXLIVE/texmf-local/web2c/updmap.cfg
- TEXMFDIST \$TEXLIVE/YYYY/texmf-dist/web2c/updmap.cfg
-
- For updmap-user:
- TEXMFCONFIG \$HOME/.texliveYYYY/texmf-config/web2c/updmap.cfg
- TEXMFVAR \$HOME/.texliveYYYY/texmf-var/web2c/updmap.cfg
- TEXMFHOME \$HOME/texmf/web2c/updmap.cfg
- TEXMFSYSCONFIG \$TEXLIVE/YYYY/texmf-config/web2c/updmap.cfg
- TEXMFSYSVAR \$TEXLIVE/YYYY/texmf-var/web2c/updmap.cfg
- TEXMFLOCAL \$TEXLIVE/texmf-local/web2c/updmap.cfg
- TEXMFDIST \$TEXLIVE/YYYY/texmf-dist/web2c/updmap.cfg
-
- (where YYYY is the TeX Live release version).
-
- According to the actions, updmap might write to one of the given files
- or create a new updmap.cfg, described further below.
-
-Where and which updmap.cfg changes are saved:
-
- When no options are given, the updmap.cfg file(s) are only read, not
- written. It's when an option --setoption, --enable or --disable is
- specified that an updmap.cfg needs to be updated. In this case:
-
- 1) If config files are given on the command line, then the first one
- given is used to save any such changes.
-
- 2) If the config files are taken from kpsewhich output, then the
- algorithm is more complex:
-
- 2a) If \$TEXMFCONFIG/web2c/updmap.cfg or \$TEXMFHOME/web2c/updmap.cfg
- appears in the list of used files, then the one listed first by
- kpsewhich --all (equivalently, the one returned by kpsewhich
- updmap.cfg), is used.
-
- 2b) If neither of the above two are present and changes are made, a
- new config file is created in \$TEXMFCONFIG/web2c/updmap.cfg.
-
- In general, the idea is that if the user cannot write to a given
- config file, a higher-level one can be used. That way, the
- distribution's settings can be overridden system-wide using
- TEXMFLOCAL, and system settings can be overridden again in a
- particular user's TEXMFHOME.
-
-Resolving multiple definitions of a font:
-
- If a font is defined in more than one map file, then the definition
- coming from the first-listed updmap.cfg is used. If a font is
- defined multiple times within the same map file, one is chosen
- arbitrarily. In both cases a warning is issued.
-
-Disabling maps:
-
- updmap.cfg files with higher priority (listed earlier) can disable
- maps mentioned in lower priority (listed later) updmap.cfg files by
- writing, e.g.,
- \#! Map mapname.map
- or
- \#! MixedMap mapname.map
- in the higher-priority updmap.cfg file. (The \#! must be at the
- beginning of the line, with at least one space or tab afterward, and
- whitespace between each word on the list.)
-
- As an example, suppose you have a copy of MathTime Pro fonts
- and want to disable the Belleek version of the fonts; that is,
- disable the map belleek.map. You can create the file
- \$TEXMFCONFIG/web2c/updmap.cfg with the content
- #! Map belleek.map
- Map mt-plus.map
- Map mt-yy.map
- and call $prg.
-
-Listing of maps:
-
- The two options --listmaps and --listavailablemaps list all maps
- defined in any of the updmap.cfg files (for --listmaps), and
- only those actually found on the system (for --listavailablemaps).
- The output format is one line per font map, with the following
- fields separated by tabs: map, type (Map, MixedMap, KanjiMap),
- status (enabled, disabled), origin (the updmap.cfg file where
- it is mentioned, or 'builtin' for the three basic maps).
-
- In the case of --listmaps there can be one additional fields
- (again separated by tab) containing '(not available)' for those
- map files that cannot be found.
-
-updmap-user vs. updmap-sys:
-
- When updmap-sys is run, TEXMFSYSCONFIG and TEXMFSYSVAR are used
- instead of TEXMFCONFIG and TEXMFVAR, respectively. This is the
- primary difference between updmap-sys and updmap-user.
-
- Other locations may be used if you give them on the command line, or
- these trees don't exist, or you are not using the original TeX Live.
-
-To see the precise locations of the various files that
-will be read and written, give the -n option (or read the source).
-
-The log file is written to TEXMFVAR/web2c/updmap.log.
-
-For step-by-step instructions on making new fonts known to TeX, read
-http://tug.org/fonts/fontinstall.html. For even more terse
-instructions, read the beginning of the main updmap.cfg file.
-
-Report bugs to: tex-live\@tug.org
-TeX Live home page: <http://tug.org/texlive/>
-EOF
-;
- print &version();
- print $usage;
- exit 0;
-}
-
-### Local Variables:
-### perl-indent-level: 2
-### tab-width: 2
-### indent-tabs-mode: nil
-### End:
-# vim:set tabstop=2 expandtab: #
diff --git a/Build/source/texk/texlive/linked_scripts/texliveonfly/texliveonfly.py b/Build/source/texk/texlive/linked_scripts/texliveonfly/texliveonfly.py
deleted file mode 100755
index fa809ff07a5..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texliveonfly/texliveonfly.py
+++ /dev/null
@@ -1,384 +0,0 @@
-#!/usr/bin/env python
-
-# default options; feel free to change!
-defaultCompiler = "pdflatex"
-defaultArguments = "-synctex=1 -interaction=nonstopmode"
-defaultSpeechSetting = "never"
-
-#
-# texliveonfly.py (formerly lualatexonfly.py) - "Downloading on the fly"
-# (similar to miktex) for texlive.
-#
-# Given a .tex file, runs lualatex (by default) repeatedly, using error messages
-# to install missing packages.
-#
-#
-# Version 1.2 ; October 4, 2011
-#
-# Written on Ubuntu 10.04 with TexLive 2011
-# Python 2.6+ or 3
-# Should work on Linux and OS X
-#
-# Copyright (C) 2011 Saitulaa Naranong
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/copyleft/gpl.html>.
-
-import re, subprocess, os, time, optparse, sys, shlex
-
-scriptName = os.path.basename(__file__) #the name of this script file
-py3 = sys.version_info[0] >= 3
-
-#functions to support python3's usage of bytes in some places where 2 uses strings
-tobytesifpy3 = lambda s = None : s.encode() if py3 and s != None else s
-frombytesifpy3 = lambda b = None : b.decode("UTF-8") if py3 and b != None else b
-
-#version of Popen.communicate that always takes and returns strings
-#regardless of py version
-def communicateStr ( process, s = None ):
- (a,b) = process.communicate( tobytesifpy3(s) )
- return ( frombytesifpy3(a), frombytesifpy3(b) )
-
-subprocess.Popen.communicateStr = communicateStr
-
-#global variables (necessary in py2; for py3 should use nonlocal)
-installation_initialized = False
-installing = False
-
-def generateSudoer(this_terminal_only = False, tempDirectory = os.path.join(os.getenv("HOME"), ".texliveonfly") ):
- lockfilePath = os.path.join(tempDirectory, "newterminal_lock")
- #NOTE: double-escaping \\ is neccessary for a slash to appear in the bash command
- # in particular, double quotations in the command need to be written \\"
- def spawnInNewTerminal(bashCommand):
- #makes sure the temp directory exists
- try:
- os.mkdir(tempDirectory)
- except OSError:
- print("\n" + scriptName + ": Our temp directory " + tempDirectory + " already exists; good.")
-
- #creates lock file
- lockfile = open(lockfilePath, 'w')
- lockfile.write( "Terminal privilege escalator running.")
- lockfile.close()
-
- #adds intro and line to remove lock
- bashCommand = '''echo \\"The graphical privilege escalator failed for some reason; we'll try asking for your administrator password here instead.\\n{0}\\n\\";{1}; rm \\"{2}\\"'''.format("-"*18, bashCommand, lockfilePath)
-
- #runs the bash command in a new terminal
- try:
- subprocess.Popen ( ['x-terminal-emulator', '-e', 'sh -c "{0}"'.format(bashCommand) ] )
- except OSError:
- try:
- subprocess.Popen ( ['xterm', '-e', 'sh -c "{0}"'.format(bashCommand) ] )
- except OSError:
- os.remove(lockfilePath)
- raise
-
- #doesn't let us proceed until the lock file has been removed by the bash command
- while os.path.exists(lockfilePath):
- time.sleep(0.1)
-
- def runSudoCommand(bashCommand):
- if this_terminal_only:
- process = subprocess.Popen( ['sudo'] + shlex.split(bashCommand) )
- process.wait()
- elif os.name == "mac":
- process = subprocess.Popen(['osascript'], stdin=subprocess.PIPE )
- process.communicateStr( '''do shell script "{0}" with administrator privileges'''.format(bashCommand) )
- else:
- #raises OSError if neither exist
- try:
- process = subprocess.Popen( ['gksudo', bashCommand] )
- except OSError:
- process = subprocess.Popen( ['kdesudo', bashCommand] )
-
- process.wait()
-
- # First tries one-liner graphical/terminal sudo, then opens extended command in new terminal
- # raises OSError if both do
- def attemptSudo(oneLiner, newTerminalCommand = ""):
- try:
- runSudoCommand(oneLiner)
- except OSError:
- if this_terminal_only:
- print("The sudo command has failed and we can't launch any more terminals.")
- raise
- else:
- print("Default graphical priviledge escalator has failed for some reason.")
- print("A new terminal will open and you may be prompted for your sudo password.")
- spawnInNewTerminal(newTerminalCommand)
-
- return attemptSudo
-
-#speech_setting = "never" prioritized over all others: "always", "install", "fail"
-def generateSpeakers(speech_setting):
- speech_setting = speech_setting.lower()
- doNothing = lambda x, failure = None : None
-
- #most general inputs, always speaks
- generalSpeaker = lambda expression, failure = False : speakerFunc(expression)
-
- if "never" in speech_setting:
- return (doNothing, doNothing)
-
- try:
- if os.name == "mac":
- speaker = subprocess.Popen(['say'], stdin=subprocess.PIPE )
- else:
- speaker = subprocess.Popen(['espeak'], stdin=subprocess.PIPE )
- except:
- return (doNothing, doNothing)
-
- def speakerFunc(expression):
- if not expression.endswith("\n"):
- expression += "\n"
- try:
- speaker.stdin.write(tobytesifpy3(expression))
- speaker.stdin.flush()
- except: #very tolerant of errors here
- print("An error has occurred when using the speech synthesizer.")
-
- #if this is called, we're definitely installing.
- def installationSpeaker(expression):
- global installing
- installing = True #permanantly sets installing (for the endSpeaker)
- if "install" in speech_setting:
- speakerFunc(expression)
-
- def endSpeaker(expression, failure = False):
- if installing and "install" in speech_setting or failure and "fail" in speech_setting:
- speakerFunc(expression)
-
- if "always" in speech_setting:
- return (generalSpeaker, generalSpeaker)
- else:
- return (installationSpeaker, endSpeaker)
-
-#generates speaker for installing packages and an exit function
-def generateSpeakerFuncs(speech_setting):
- (installspeaker, exitspeaker) = generateSpeakers(speech_setting)
-
- def exiter(code = 0):
- exitspeaker("Compilation{0}successful.".format(", un" if code != 0 else " "), failure = code != 0 )
- sys.exit(code)
-
- return (installspeaker, exiter)
-
-def generateTLMGRFuncs(tlmgr, speaker, sudoFunc):
- #checks that tlmgr is installed, raises OSError otherwise
- #also checks whether we need to escalate permissions, using fake remove command
- process = subprocess.Popen( [ tlmgr, "remove" ], stdin=subprocess.PIPE, stdout = subprocess.PIPE, stderr=subprocess.PIPE )
- (tlmgr_out, tlmgr_err) = process.communicateStr()
-
- #does our default user have update permissions?
- default_permission = "don't have permission" not in tlmgr_err
-
- #always call on first update; updates tlmgr and checks permissions
- def initializeInstallation():
- updateInfo = "Updating tlmgr prior to installing packages\n(this is necessary to avoid complaints from itself)."
- print( scriptName + ": " + updateInfo)
-
- if default_permission:
- process = subprocess.Popen( [tlmgr, "update", "--self" ] )
- process.wait()
- else:
- print( "\n{0}: Default user doesn't have permission to modify the TeX Live distribution; upgrading to superuser for installation mode.\n".format(scriptName) )
- basicCommand = ''''{0}' update --self'''.format(tlmgr)
- sudoFunc( basicCommand, '''echo \\"This is {0}'s 'install packages on the fly' feature.\\n\\n{1}\\n\\" ; sudo {2}'''.format(scriptName, updateInfo, basicCommand ) )
-
- def installPackages(packages):
- if len(packages) == 0:
- return
-
- global installation_initialized
- if not installation_initialized:
- initializeInstallation()
- installation_initialized = True
-
- packagesString = " ".join(packages)
- print("{0}: Attempting to install LaTex package(s): {1}".format( scriptName, packagesString ) )
-
- if default_permission:
- process = subprocess.Popen( [ tlmgr, "install"] + packages , stdin=subprocess.PIPE )
- process.wait()
- else:
- basicCommand = ''''{0}' install {1}'''.format(tlmgr, packagesString)
- bashCommand='''echo \\"This is {0}'s 'install packages on the fly' feature.\\n\\nAttempting to install LaTeX package(s): {1} \\"
-echo \\"(Some of them might not be real.)\\n\\"
-sudo {2}'''.format(scriptName, packagesString, basicCommand)
-
- sudoFunc(basicCommand, bashCommand)
-
- #strictmatch requires an entire /file match in the search results
- def getSearchResults(preamble, term, strictMatch):
- fontOrFile = "font" if "font" in preamble else "file"
- speaker("Searching for missing {0}: {1} ".format(fontOrFile, term))
- print( "{0}: Searching repositories for missing {1} {2}".format(scriptName, fontOrFile, term) )
-
- process = subprocess.Popen([ tlmgr, "search", "--global", "--file", term], stdin=subprocess.PIPE, stdout = subprocess.PIPE, stderr=subprocess.PIPE )
- ( output , stderrdata ) = process.communicateStr()
- outList = output.split("\n")
-
- results = ["latex"] #latex 'result' for removal later
-
- for line in outList:
- line = line.strip()
- if line.startswith(preamble) and (not strictMatch or line.endswith("/" + term)):
- #filters out the package in:
- # texmf-dist/.../package/file
- #and adds it to packages
- results.append(line.split("/")[-2].strip())
- results.append(line.split("/")[-3].strip()) #occasionally the package is one more slash before
-
- results = list(set(results)) #removes duplicates
- results.remove("latex") #removes most common fake result
-
- if len(results) == 0:
- speaker("File not found.")
- print("{0}: No results found for {1}".format( scriptName, term ) )
- else:
- speaker("Installing.")
-
- return results
-
- def searchFilePackage(file):
- return getSearchResults("texmf-dist/", file, True)
-
- def searchFontPackage(font):
- font = re.sub(r"\((.*)\)", "", font) #gets rid of parentheses
- results = getSearchResults("texmf-dist/fonts/", font , False)
-
- #allow for possibility of lowercase
- if len(results) == 0:
- return [] if font.islower() else searchFontPackage(font.lower())
- else:
- return results
-
- def searchAndInstall(searcher, entry):
- installPackages(searcher(entry))
- return entry #returns the entry just installed
-
- return ( lambda entry : searchAndInstall(searchFilePackage, entry), lambda entry : searchAndInstall(searchFontPackage, entry) )
-
-def generateCompiler(compiler, arguments, texDoc, exiter):
- def compileTexDoc():
- try:
- process = subprocess.Popen( [compiler] + shlex.split(arguments) + [texDoc], stdin=sys.stdin, stdout = subprocess.PIPE )
- return readFromProcess(process)
- except OSError:
- print( "{0}: Unable to start {1}; are you sure it is installed?{2}".format(scriptName, compiler,
- " \n\n(Or run " + scriptName + " --help for info on how to choose a different compiler.)" if compiler == defaultCompiler else "" )
- )
- exiter(1)
-
- def readFromProcess(process):
- getProcessLine = lambda : frombytesifpy3(process.stdout.readline())
-
- output = ""
- line = getProcessLine()
- while line != '':
- output += line
- sys.stdout.write(line)
- line = getProcessLine()
-
- returnCode = None
- while returnCode == None:
- returnCode = process.poll()
-
- return (output, returnCode)
-
- return compileTexDoc
-
-### MAIN PROGRAM ###
-
-if __name__ == '__main__':
- # Parse command line
- parser = optparse.OptionParser(
- usage="\n\n\t%prog [options] file.tex\n\nUse option --help for more info.",
- description = 'This program downloads TeX Live packages "on the fly" while compiling .tex documents. ' +
- 'Some of its default options can be directly changed in {0}. For example, the default compiler can be edited on line 4.'.format(scriptName) ,
- version='1.2',
- epilog = 'Copyright (C) 2011 Saitulaa Naranong. This program comes with ABSOLUTELY NO WARRANTY; see the GNU General Public License v3 for more info.' ,
- conflict_handler='resolve'
- )
-
- parser.add_option('-h', '--help', action='help', help='print this help text and exit')
- parser.add_option('-c', '--compiler', dest='compiler', metavar='COMPILER',
- help='your LaTeX compiler; defaults to {0}'.format(defaultCompiler), default=defaultCompiler)
- parser.add_option('-a', '--arguments', dest='arguments', metavar='ARGS',
- help='arguments to pass to compiler; default is: "{0}"'.format(defaultArguments) , default=defaultArguments)
- parser.add_option('--texlive_bin', dest='texlive_bin', metavar='LOCATION',
- help='Custom location for the TeX Live bin folder', default="")
- parser.add_option('--terminal_only', action = "store_true" , dest='terminal_only', default=False,
- help="Forces us to assume we can run only in this terminal. Permission escalators will appear here rather than graphically or in a new terminal.")
- parser.add_option('-s', '--speech_when' , dest='speech_setting', metavar="OPTION", default=defaultSpeechSetting ,
- help='Toggles speech-synthesized notifications (where supported). OPTION can be "always", "never", "installing", "failed", or some combination.')
- parser.add_option('-f', '--fail_silently', action = "store_true" , dest='fail_silently',
- help="If tlmgr cannot be found, compile document anyway.", default=False)
-
- (options, args) = parser.parse_args()
-
- if len(args) == 0:
- parser.error( "{0}: You must specify a .tex file to compile.".format(scriptName) )
-
- texDoc = args[0]
- compiler_path = os.path.join( options.texlive_bin, options.compiler)
-
- (installSpeaker, exitScript) = generateSpeakerFuncs(options.speech_setting)
- compileTex = generateCompiler( compiler_path, options.arguments, texDoc, exitScript)
-
- #initializes tlmgr, responds if the program not found
- try:
- tlmgr_path = os.path.join(options.texlive_bin, "tlmgr")
- (installFile, installFont) = generateTLMGRFuncs(tlmgr_path, installSpeaker, generateSudoer(options.terminal_only))
- except OSError:
- if options.fail_silently:
- (output, returnCode) = compileTex()
- exitScript(returnCode)
- else:
- parser.error( "{0}: It appears {1} is not installed. {2}".format(scriptName, tlmgr_path,
- "Are you sure you have TeX Live 2010 or later?" if tlmgr_path == "tlmgr" else "" ) )
-
- #loop constraints
- done = False
- previousFile = ""
- previousFontFile = ""
- previousFont =""
-
- #keeps running until all missing font/file errors are gone, or the same ones persist in all categories
- while not done:
- (output, returnCode) = compileTex()
-
- #most reliable: searches for missing file
- filesSearch = re.findall(r"! LaTeX Error: File `([^`']*)' not found" , output) + re.findall(r"! I can't find file `([^`']*)'." , output)
- filesSearch = [ name for name in filesSearch if name != texDoc ] #strips our .tex doc from list of files
- #next most reliable: infers filename from font error
- fontsFileSearch = [ name + ".tfm" for name in re.findall(r"! Font \\[^=]*=([^\s]*)\s", output) ]
- #brute force search for font name in files
- fontsSearch = re.findall(r"! Font [^\n]*file\:([^\:\n]*)\:", output) + re.findall(r"! Font \\[^/]*/([^/]*)/", output)
-
- try:
- if len(filesSearch) > 0 and filesSearch[0] != previousFile:
- previousFile = installFile(filesSearch[0] )
- elif len(fontsFileSearch) > 0 and fontsFileSearch[0] != previousFontFile:
- previousFontFile = installFile(fontsFileSearch[0])
- elif len(fontsSearch) > 0 and fontsSearch[0] != previousFont:
- previousFont = installFont(fontsSearch[0])
- else:
- done = True
- except OSError:
- print("\n{0}: Unable to update; all privilege escalation attempts have failed!".format(scriptName) )
- print("We've already compiled the .tex document, so there's nothing else to do.\n Exiting..")
- exitScript(returnCode)
-
- exitScript(returnCode)
diff --git a/Build/source/texk/texlive/linked_scripts/texloganalyser/texloganalyser b/Build/source/texk/texlive/linked_scripts/texloganalyser/texloganalyser
deleted file mode 100755
index 121a9f48907..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texloganalyser/texloganalyser
+++ /dev/null
@@ -1,426 +0,0 @@
-#!/usr/bin/env perl
-# This is texloganalyser, for parsing of TeX logs
-# Copyright (c) 2006-2020 Thomas van Oudenhove
-# All rights reserved
-
-# README - important notice:
-# you should feed the first line with the path of your Perl executable
-# (on *nix systems, the output of 'which perl')
-#
-# (this program works at least with perl 5.8.8)
-# Getopt::Long MUST be installed on your system for this program to work
-
-# License:
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-
-use warnings;
-use strict;
-use Getopt::Long;
-Getopt::Long::Configure ("bundling");
-
-my $version = "0.11";
-my $copyright = "2006-2020";
-my $opt = {
- help => '',
- version => '',
- last => '',
- a => '',
- h => '',
- o => '',
- u => '',
- v => '',
- c => '',
- p => '',
- f => '',
- w => '',
- e => '',
- i => '',
- s => '',
- r => '',
- t => '',
- n => '',
-};
-
-GetOptions(
- 'help' => \$opt->{help},
- 'version' => \$opt->{version},
- 'last' => \$opt->{last},
- 'a' => \$opt->{a},
- 'c' => \$opt->{c},
- 'h' => \$opt->{h},
- 'o' => \$opt->{o},
- 'u' => \$opt->{u},
- 'v' => \$opt->{v},
- 'p' => \$opt->{p},
- 'f' => \$opt->{f},
- 'w' => \$opt->{w},
- 'e' => \$opt->{e},
- 'i' => \$opt->{i},
- 't' => \$opt->{t},
- 's' => \$opt->{s},
- 'r' => \$opt->{r},
- 'n' => \$opt->{n},
-);
-
-my $abstract = {
- warnings => 0,
- badboxes => 0,
-};
-
-my $texlog = $ARGV[-1];
-
-die "Usage: $0 ".options()." <TeX log>\n"
- if (not defined $texlog and
- (not $opt->{help} and not $opt->{version}));
-
-if ($opt->{help}) {
- printhelp();
- exit();
-}
-
-if ($opt->{version}) {
- printversion();
- exit();
-}
-
-analyze();
-
-sub analyze {
- my $line;
- my ($cbox, $chead);
- my $output;
- my $test = 0;
- my $png = 0;
-
- open my $source, "<", $texlog;
- while (defined ($line = <$source>)) {
- undef $output;
- # default: display summary
- summary($line);
- # and page numbers ('n' option)
- my $pn = pagenumber($line);
- print '['.$pn.']' if ($opt->{n} and $pn);
- $png = $pn if $pn;
-
- if ($opt->{e}) {
- if ($line =~ m/Here is how much/) {
- $test = 1;
- $output = "\n";
- }
- $output .= $line if $test;
- }
- # look for boxes warnings
- if ($opt->{c} and $opt->{o} and $opt->{h}) {
- if ($line =~ m/\\hbox/ and $line =~ m/Overfull/) {
- $line =~ m/^Overfull \\hbox \((\d+\.\d+)pt too wide\) .*$/;
- $cbox->{$1} = 'Page '.$png.': '.$line;
- $chead = 'Overfull hboxes classified:';
- }
- } elsif ($opt->{c} and $opt->{u} and $opt->{h}) {
- if ($line =~ m/\\hbox/ and $line =~ m/Underfull/) {
- $line =~ m/^Underfull \\hbox \(badness (\d+)\) .*$/;
- $cbox->{$1} = 'Page '.$png.': '.$line;
- $chead = 'Underfull hboxes classified:';
- }
- } elsif ($opt->{o} and $opt->{h}) {
- $output = $line if ($line =~ m/\\hbox/ and
- $line =~ m/Overfull/);
- } elsif ($opt->{u} and $opt->{h}) {
- $output = $line if ($line =~ m/\\hbox/ and
- $line =~ m/Underfull/);
- } elsif ($opt->{o} and $opt->{v}) {
- $output = $line if ($line =~ m/\\vbox/ and
- $line =~ m/Overfull/);
- } elsif ($opt->{u} and $opt->{v}) {
- $output = $line if ($line =~ m/\\vbox/ and
- $line =~ m/Underfull/);
- } elsif ($opt->{h} and $opt->{v}) {
- $output = $line if ($line =~ m/\\vbox/ or
- $line =~ m/\\hbox/);
- } elsif ($opt->{o} and $opt->{u}) {
- $output = $line if ($line =~ m/Underfull/ or
- $line =~ m/Overfull/);
- } elsif ($opt->{h}) {
- $output = $line if ($line =~ m/\\hbox/);
- } elsif ($opt->{v}) {
- $output = $line if ($line =~ m/\\vbox/);
- } elsif ($opt->{o}) {
- $output = $line if ($line =~ m/Overfull/);
- $abstract->{badboxes} += 1;
- } elsif ($opt->{u}) {
- $output = $line if ($line =~ m/Underfull/);
- $abstract->{badboxes} += 1;
- }
- # look for LaTeX Font Info
- if ($opt->{f}) {
- $output = $line if ($line =~ m/Font Info/);
- }
- # packages infos
- if ($opt->{p}) {
- $output = $line if ($line =~ m/Package/);
- }
- # references warnings
- if ($opt->{r}) {
- $output = $line if ($line =~ m/Reference/ or
- $line =~ m/Label(.*)/ and $1 =~ m/multiply defined/);
- }
- # TeX files used
- if ($opt->{t}) {
- scannedtexfiles($line, "tex");
- }
- # sty and cls files used
- if ($opt->{s}) {
- scannedfiles($line, "sty");
- scannedfiles($line, "cls");
- }
- # images (pdf, ps, jpg, png)
- if ($opt->{i}) {
- foreach my $t ('pdf', 'eps', 'ps', 'png', 'jpg') {
- scannedfiles($line, $t);
- }
- }
- # display all warnings
- if ($opt->{w}) {
- $output = $line if ($line =~ m/Warning/);
- }
- # if 'last' option, let's flush data
- if ($opt->{last} and $line =~ m/^This is .*TeX, Version 3\.14159/) {
- # Flush.
- $output = '';
- $abstract->{warnings} = 0;
- }
-
- print "$output" if defined $output;
- }
- print "\n";
- if ($opt->{c} and $opt->{h} and ($opt->{u} or $opt->{o})) {
- print "$chead\n";
- foreach my $key (sort {$a <=> $b} keys %{$cbox}) {
- print $cbox->{$key};
- }
- print "\n";
- }
- print_abstract();
- close $source;
-}
-
-sub pagenumber {
- my $logline = shift;
- if ($logline =~ m/.*\[([0-9]+)(\]|$)/) {
- return $1;
- }
-}
-
-sub scannedfiles {
- my ($logline, $filetype) = @_;
- if ($logline =~ m/^\((.*\.$filetype)/i) {
- print "(".$1.")";
- }
-}
-
-sub scannedtexfiles {
- my ($logline, $filetype) = @_;
- if ($logline =~ m/\((.*\.$filetype)/i) {
- print "(".$1.")";
- }
-}
-
-sub summary {
- my $line = shift;
- # prints log summary ()
- $abstract->{warnings} += 1 if ($line =~ m/Warning/);
-}
-
-sub options {
- my $stropts = "[";
- my $multopt = '';
- foreach my $k (sort keys %{$opt}) {
- if ($k eq 'version') {
- $stropts .= "--version|";
- } elsif ($k eq 'help') {
- $stropts .= "--help|";
- } else {
- $multopt .= $k;
- }
- }
- $stropts .= '-'.$multopt.']';
- return $stropts;
-}
-
-sub print_abstract {
- print "The log contained ".$abstract->{warnings}." warnings";
- print " and $abstract->{badboxes} bad boxes" if $opt->{a};
- print ".\n";
-}
-
-sub printversion {
- print "This is texloganalyser (Perl script), version $version\n";
- print "\t Copyright $copyright Thomas van Oudenhove\n";
- print "\t License: BSD\n";
-}
-
-sub printhelp {
- printversion();
- print "\nUsage: texloganalyser ".options()." <TeX log>\n";
- print "\t Displays selective infos of LaTeX logs\n";
- print "\nThese flags may be used:\n";
- print "\t a: displays number of warnings about bad boxes\n";
- print "\t c: displays the boxes warning by size (at the end)\n";
- print "\t e: displays the end of the log\n";
- print "\t f: outputs the LaTeX Font Infos\n";
- print "\t h: outputs only warnings about horizontal boxes\n";
- print "\t i: displays 'images' (pdf, [e]ps, png, jpg) used\n";
- print "\t n: displays page numbers\n";
- print "\t o: outputs only warnings about overfull boxes\n";
- print "\t p: outputs the LaTeX Packages infos\n";
- print "\t r: displays warnings about references\n";
- print "\t s: displays .sty and .cls files used\n";
- print "\t t: displays .tex files used\n";
- print "\t u: outputs only warnings about underfull boxes\n";
- print "\t v: outputs only warnings about vertical boxes\n";
- print "\t w: displays all Warnings\n\n";
- print "More documentation is available with `perldoc texloganalyser`.\n";
-}
-
-__END__
-
-
-=pod
-
-=head1 texloganalyser Documentation
-
-=head2 NAME
-
-texloganalyser -- displays selective infos from TeX log files
-
-=head2 SYNOPSIS
-
-texloganalyser [-acefhinoprstuvw] tex_log_file
-
-texloganalyser [--version]
-
-texloganalyser [--help]
-
-=head2 DESCRIPTION
-
-Various options may be used to select which information from the TeX log you want to see/analyze (see next section). The default is to display only warnings number.
-
-=head2 OPTIONS
-
-=over 1
-
-=item B<--version>: displays version information.
-
-=item B<--help>: displays help as a summary of options.
-
-=item B<--last>: the Log file may content several logs; in this case, consider only the last one.
-
-=item B<-a>: counts number of badboxes.
-
-=item B<-c>: classify boxes warnings by size (needs h&o,u or v&o,u) at the end.
-
-=item B<-e>: displays the end of the log, about the TeX's memory.
-
-=item B<-f>: outputs the LaTeX Font Infos warnings and calculations.
-
-=item B<-h>: outputs only warnings about horizontal boxes.
-
-=item B<-i>: displays 'images' (pdf, [e]ps, png, jpg) used.
-
-=item B<-n>: displays page numbers.
-
-=item B<-o>: outputs only warnings about overfull boxes.
-
-=item B<-p>: outputs the LaTeX Packages infos and warnings.
-
-=item B<-r>: displays warnings about references (missing or multiply-defined).
-
-=item B<-s>: displays .sty and .cls files used.
-
-=item B<-t>: displays .tex files used. This option is B<very> useful when you parse logs of master files, to know in which file to look to correct errors/warnings.
-
-=item B<-u>: outputs only warnings about underfull boxes.
-
-=item B<-v>: outputs only warnings about vertical boxes.
-
-=item B<-w>: displays all TeX, LaTeX and font Warnings.
-
-=back
-
-=head2 BUGS
-
-None yet identified. However, the display should be improved...
-
-=head2 HISTORY
-
-This program was first released in 2006. Its purpose was to display selective information of my PhD's TeX log.
-
-Markus Hennig submitted some new options (-a and -n) at the end of 2009.
-
-Akim Demaille submitted a patch for 'last' option, June 2012.
-
-Paulo Ney de Souza had the idea of -c option to better handle hboxes, March 2020.
-
-=head3 Changelog
-
-=over
-
-=item v0.11: bug fix for -c option (regexp was too specific)
-
-=item v0.10: added option -c, to classify boxes warnings by size (Paulo Ney de Souza's idea).
-
-=item v0.9: added option --last, if log file contains several compilations (Akim Demaille's patch).
-
-=item v0.8: added options for page and bad boxes number (Markus Hennig's patch).
-
-=item v0.7: bug patch for .tex files (-t option)
-
-=item v0.6: default displays number of warnings (and page numbers).
-
- added option: references and label warnings
-
-=item v0.5: use of GetOpt::Long and code cleaning
-
- added options: display of files used
- improved documentation
-
-=item v0.4: added features and bugs corrections (options h, v, o and u)
-
-=item v0.3: display of Warnings and last lines of the log
-
-=item v0.2: display of "Font Info" and "Packages" added
-
-=item v0.1: first version, displays only warnings about boxes
-
-=back
-
-=head2 AUTHORS
-
-I<texloganalyser> is a program by Thomas van Oudenhove (L<thomasvo+tex_AT_thomasvo.net>). Feel free to contact him for features requests or bugs.
-
-Markus Hennig submitted a patch, many thanks to him :).
-
-June 2012, Akim Demaille submitted the 'last' option patch, many thanks to him :).
-
-=cut
-
diff --git a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery b/Build/source/texk/texlive/linked_scripts/texosquery/texosquery
deleted file mode 100755
index 2f97a43db65..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar`
-java -jar "$jarpath" "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh b/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh
deleted file mode 100755
index 73edbe03205..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-
-scriptname=`basename "$0" .sh`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-java -jar "$jarpath" "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh b/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh
deleted file mode 100755
index 77411bcf87d..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-
-scriptname=`basename "$0" .sh`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-java -Djava.locale.providers=CLDR,JRE -jar "$jarpath" "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh b/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh
deleted file mode 100755
index 73edbe03205..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-
-scriptname=`basename "$0" .sh`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-java -jar "$jarpath" "$@"
diff --git a/Build/source/texk/texlive/linked_scripts/texplate/texplate.sh b/Build/source/texk/texlive/linked_scripts/texplate/texplate.sh
deleted file mode 100644
index da649780378..00000000000
--- a/Build/source/texk/texlive/linked_scripts/texplate/texplate.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-# Public domain. Originally written by Norbert Preining and Karl Berry, 2018.
-# Note from Paulo: this script provides better Cygwin support than our original
-# approach, so the team decided to use it as a proper wrapper for texplate as well.
-
-scriptname=`basename "$0"`
-jar="$scriptname.jar"
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-exec java -jar "$jarpath" "$@" \ No newline at end of file
diff --git a/Build/source/texk/texlive/linked_scripts/thumbpdf/thumbpdf.pl b/Build/source/texk/texlive/linked_scripts/thumbpdf/thumbpdf.pl
deleted file mode 100755
index a5f0b54eafe..00000000000
--- a/Build/source/texk/texlive/linked_scripts/thumbpdf/thumbpdf.pl
+++ /dev/null
@@ -1,1604 +0,0 @@
-eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
- if 0;
-use strict;
-$^W=1; # turn warning on
-#
-# thumbpdf.pl
-#
-# Copyright (C) 1999-2018 Heiko Oberdiek.
-#
-# This work may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.3
-# of this license or (at your option) any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.3 or later is part of all distributions of LaTeX
-# version 2003/12/01 or later.
-#
-# This work has the LPPL maintenance status "maintained".
-#
-# This Current Maintainer of this work is Heiko Oberdiek.
-#
-# See file "readme.txt" for a list of files that belong to this project.
-#
-# This file "thumbpdf.pl" may be renamed to "thumbpdf"
-# for installation purposes.
-#
-my $file = "thumbpdf.pl";
-my $program = uc($&) if $file =~ /^\w+/;
-my $prj = 'thumbpdf';
-my $version = "3.17";
-my $date = "2018/09/07";
-my $author = "Heiko Oberdiek";
-my $copyright = "Copyright (c) 1999-2018 by $author.";
-#
-# Reqirements: Perl5, Ghostscript
-# History:
-# 1999/02/14 v1.0: First release.
-# 1999/02/23 v1.1:
-# * Looking for the media box to calculate the resolution
-# for Ghostscript
-# * new option --resolution
-# 1999/03/01 v1.2:
-# * optimization: indirect objects for length values removed.
-# * "first line" from epstopdf
-# 1999/03/12 v1.3:
-# * Copyright: LPPL
-# 1999/05/05 v1.4:
-# * Detecting of cygwin32 environment.
-# * Minor corrections of output of error messages.
-# * Sharing RGB objects.
-# 1999/06/13 v1.5:
-# * gs detection extended.
-# 1999/07/27 v1.6
-# 1999/08/08 v1.7:
-# * \immediate before \pdfobj (pdfTeX 0.14a)
-# 1999/09/09 v1.8
-# 1999/09/06 v1.9:
-# * Check for direct /Length values (for jpg images)
-# 2000/01/11 v1.10:
-# * Bug fix: /Length (direct) as last entry.
-# * Direct /Length in RGB objects supported.
-# 2000/01/19 v1.11:
-# * "for (my $j=0;...;...)" replaced by "my $j; for($j=0;...;...)",
-# because there exist perl versions that have problems with.
-# 2000/02/11 v1.12:
-# * Option `clean' added.
-# * The name of thumbnail data file: jobname.tnd,
-# if thumbpdf is called: thumbpdf jobname[.pdf] [options]
-# 2000/02/22 v2.0:
-# * pdfmark support for dvips/ps2pdf route added.
-# * <jobname>.tpt replaces thumbdta.tex (for pdfTeX)
-# <jobname>.tpm (for pdfmark)
-# <jobname>.top replaces thumbopt.tex
-# * Options `useps', `modes' added,
-# `makedef' renamed to `makedata'.
-# 2000/02/28 v2.1:
-# * Environment variable `THUMBPDF' supported.
-# 2000/03/07 v2.2:
-# * Support for Distiller 3 and 4, the streams are uncompressed.
-# * Call of gs is changed in order to show the currently processed
-# page number of the pdf file.
-# * Option --printgscmd creates the command line file `thumbpdf.gs'
-# for the Ghostscript call.
-# 2000/03/22 v2.3:
-# * Bug fix: --useps now works.
-# 2000/04/10 v2.4:
-# * Fix for ActiveState Perl 5.6.0: uc line changed, fork removed.
-# (Thanks to Andreas Buehmann <andreas.buehmann@gmx.de>.)
-# * Version test for thumbpdf.tex added for users that
-# mix versions, sigh.
-# 2000/07/29 v2.5:
-# * `save' trick in call of ghostscript.
-# * Undocumented option --gspages added.
-# 2000/09/27 v2.6
-# 2000/10/27 v2.7:
-# * -dFIXEDMEDIA=0 added in gs call
-# 2001/01/12 v2.8:
-# * Bug fix in dvips mode and active option `level2':
-# pack parameter corrected for little-endian machines.
-# * /Rotate in pdf pages:
-# ghostscript versions around 6.01 have added a hack
-# in /pdfshowpage_setpage, that ignores the /Rotate entry.
-# A patch is added to disable the hack.
-# * Ghostscript uses the MediaBox for calculating the
-# page size. For version 6.50 a patch is added to use
-# the /CropBox instead.
-# 2001/03/29 v2.9:
-# * Option --password added.
-# 2001/04/02 v2.10
-# 2001/04/26 v2.11
-# * Option --antialias added (suggestion of Juergen Bausa).
-# 2002/01/11 v3.0
-# * Syntax of option --antialias changed (see readme.txt).
-# * Support for VTeX's PS mode added.
-# * Greek mode added (see readme.txt).
-# * Signal handlers added for cleanup.
-# 2002/05/26 v3.1
-# * SIG_HUP unkown in Windows.
-# * Bug fix: The signal function for __DIE__ "cleanup" aborts
-# before the error message of "die" is printed.
-# Replaced by "clean" that does not contain "exit 1".
-# * Small bug fix in mode detection and mode "vtex"
-# removed from list. "vtexpdfmark" was detected,
-# "vtex" did not work and perhaps it will be used
-# later for VTeX in PDF mode.
-# 2002/05/26 v3.2
-# * Fix: "MacOS/X: darwin" is now not interpreted as
-# Windows.
-# 2003/03/19 v3.3
-# * Fix for gs 8.00 in mode dvips:
-# THB_DistillerPatch also applied to ghostscript >= 8.00.
-# 2003/06/06 v3.4
-# * Bug fix, two forgotten "pop"s added for Distiller case.
-# 2004/10/24 v3.5
-# * Revert Cygwin detection: is unix (request by Jan Nieuwenhuizen).
-# * LPPL 1.3.
-# 2004/11/19 v3.6
-# * Bug fix for dvips mode and gs < 8.00 (/stackunderflow in pop).
-# 2004/11/19 v3.7:
-# * For easier debugging, the special thumbpdf objects of
-# thumbpdf.pdf are now valid PDF objects (dictionaries).
-# * Remove of extra '\n' before "endstream" that is added
-# by pdfTeX 1.20a.
-# 2005/07/06 v3.8:
-# * Fix because of pdfTeX 1.30.
-# 2007/11/07 v3.9:
-# * Deprecation warning of perl 5.8.8 fixed.
-# 2008/04/16 v3.10
-# 2010/07/07 v3.11
-# * \input is used with file name extension for "thumbpdf.tex".
-# 2011/08/10 v3.13
-# * Use gswin64c in Windows with 64 bits.
-# 2012/04/09 v3.14
-# 2012/04/18 v3.15
-# * Option --version added.
-# 2014/07/15 v3.16
-# * Patch for "thumbpdf.pl" by Norbert Preining because of
-# pdfTeX 1.40.15 (TeX Live 2014).
-# 2018/09/07 v3.17
-# * { } quoted as \{ \} in regex for "new" stricter perl syntax.
-#
-
-### program identification
-my $title = "$program $version, $date - $copyright\n";
-
-### error strings
-my $Error = "!!! Error:"; # error prefix
-
-### string constants for Ghostscript run
-# get Ghostscript command name
-my $GS = "gs";
-$GS = "gs386" if $^O =~ /dos/i;
-$GS = "gsos2" if $^O =~ /os2/i;
-if ($^O =~ /mswin32c/i) {
- # http://perldoc.perl.org/perlport.html#DOS-and-Derivatives
- use Config;
- $GS = "gswin32c";
- $GS = "gswin64c" if $Config{'archname'} =~ /mswin32-x64/i;
-}
-
-# Windows detection (no SIGHUP)
-my $Win = 0;
-$Win = 1 if $^O =~ /mswin32/i;
-
-my $gspages = 1;
-$gspages = 0 if $^O =~ /dos/i;
-
-### variables
-my $jobname = "";
-my $jobfile = "";
-my $pdftexfile = "";
-my $pdfmarkfile = "";
-my $psext = ".ps";
-my $pdfext = ".pdf";
-my $pdftexext = ".tpt";
-my $pdfmarkext = ".tpm";
-my $thumbprefix = "thb";
-my $envvar = "THUMBPDF";
-my $pdffile = "thumbpdf.pdf";
-my $logfile = "thumbpdf.log";
-my $texfile = "thumbpdf.tex";
-my $package = "thumbpdf.sty";
-my $readme = "readme.txt";
-my $gscnffile = "thumbpdf.gs";
-my $gssection = "section I. `Known Problems'";
-my @cleanlist = ();
-my $resolution = 9;
-my $mode_pdftex = 0;
-my $mode_pdfmark = 0;
-my $antialias_default = "4";
-my @arglist = @ARGV;
-my $gskidrunning = 0;
-
-### option variables
-my @bool = ("false", "true");
-$::opt_device = "png16m";
-$::opt_compress = "10";
-$::opt_resolution = "";
-$::opt_modes = "pdftex";
-$::opt_gscmd = "";
-$::opt_level2 = 0;
-$::opt_help = 0;
-$::opt_version = 0;
-$::opt_quiet = 0;
-$::opt_debug = 0;
-$::opt_verbose = 0;
-$::opt_useps = 0;
-$::opt_printgscmd = 0;
-$::opt_gspages = $gspages; # undocumented
-$::opt_makepng = 1;
-$::opt_makepdf = 1;
-$::opt_makedata = 1;
-$::opt_clean = 1;
-$::opt_password = "";
-$::opt_antialias = $antialias_default;
-$::opt_greek = 0;
-
-my $usage = <<"END_OF_USAGE";
-${title}Syntax: \L$program\E [options] <jobname[.pdf|.ps]>
-Function: Support of thumbnails for pdfTeX or dvips/ps2pdf (pdfmark).
- Thumbnails are generated by Ghostscript and the result is
- written to data files for package `$package':
- `<jobname>$pdftexext' (pdfTeX), `<jobname>$pdfmarkext' (pdfmark)
-Options: (defaults:)
- --help print usage
- --version print version number
- --(no)quiet suppress messages ($bool[$::opt_quiet])
- --(no)verbose verbose printing ($bool[$::opt_verbose])
- --(no)debug debug informations ($bool[$::opt_debug])
- --(no)makepng make thumbnails `$thumbprefix*.png' ($bool[$::opt_makepng])
- --(no)makepdf make `$pdffile' with thumbnails as images ($bool[$::opt_makepdf])
- --(no)makedata make data file(s) for package `$package' ($bool[$::opt_makedata])
- --(no)clean clear temp files ($bool[$::opt_clean])
- --(no)useps `makepng' uses `.ps' instead of `.pdf' file ($bool[$::opt_useps])
- --(no)level2 `<jobname>.tpm' with ps level 2 features ($bool[$::opt_level2])
- --(no)greek text in greek style (experimental) ($bool[$::opt_greek])
- --gscmd <name> call of ghostscript ($GS)
- --antialias <num1>[num2] anti-aliasing, 0 = disable, 4 = max ($::opt_antialias)
- --device|png [png]<dev> Ghostscript device for thumbnails,
- dev = mono, gray, 16, 256, 16m ($::opt_device)
- --resolution <res> thumbnail resolution for makepng ($resolution)
- --compress <n> thumbnail compress level, n = 0..10 ($::opt_compress)
- --modes <mode>[,mode] mode=pdftex|pdfmark|dvips|ps2pdf|
- vtexpdfmark|all ($::opt_modes)
- --password <password> for an encrypted pdf file ($::opt_password)
-END_OF_USAGE
-
-### environment variable THUMBPDF
-if ($ENV{$envvar}) {
- unshift(@ARGV, split(/\s+/, $ENV{$envvar}));
-}
-
-### process options
-my @OrgArgv = @ARGV;
-use Getopt::Long;
-GetOptions(
- "help!",
- "version!",
- "quiet!",
- "debug!",
- "verbose!",
- "device|png=s",
- "gscmd=s",
- "level2!",
- "compress=i",
- "resolution=f",
- "modes=s",
- "useps!",
- "printgscmd!",
- "gspages!",
- "makepng!",
- "makepdf!",
- "makedata!",
- "clean!",
- "password=s",
- "antialias=s",
- "greek!"
-) or die $usage;
-!$::opt_help or die $usage;
-if ($::opt_version) {
- print "$prj $date v$version\n";
- exit(0);
-}
-@ARGV < 2 or die "$usage$Error Too many files!\n";
-@ARGV == 1 or die "$usage$Error Missing jobname!\n";
-
-$::opt_device = "png$::opt_device" unless $::opt_device =~ /^png/;
-$::opt_quiet = 0 if $::opt_verbose;
-$::opt_clean = 0 if $::opt_debug or !$::opt_makepdf or !$::opt_makedata;
-
-$::opt_compress = 0 if $::opt_compress < 0;
-$::opt_compress = 10 if $::opt_compress > 10;
-my $J = "^^J";
-$J = "" if $::opt_compress == 10;
-
-$::opt_antialias = $antialias_default if $::opt_antialias eq "";
-$::opt_antialias =~ /^[0124][0124]?$/ or
- die "$usage$Error Wrong value for option --antialias!\n";
-$::opt_antialias .= $::opt_antialias if length($::opt_antialias) < 2;
-my $AntiAliasText = substr($::opt_antialias, 0, 1);
-my $AntiAliasGraphics = substr($::opt_antialias, 1, 1);
-$AntiAliasText = "1" if $AntiAliasText eq "0";
-$AntiAliasGraphics = "1" if $AntiAliasGraphics eq "0";
-
-$GS = $::opt_gscmd if $::opt_gscmd;
-$gspages = $::opt_gspages;
-
-### get modes
-$::opt_modes = "\L$::opt_modes\E";
-$::opt_modes =~ s/dvips/pdfmark/g;
-$::opt_modes =~ s/ps2pdf/pdfmark/g;
-$::opt_modes =~ s/vtexpdfmark/pdfmark/g;
-$::opt_modes =~ s/vtexpdfmark/pdfmark/g;
-if ($::opt_modes =~ /pdftex/)
-{
- $mode_pdftex = 1;
- $::opt_modes =~ s/pdftex//g;
-}
-if ($::opt_modes =~ /pdfmark/)
-{
- $mode_pdfmark = 1;
- $::opt_modes =~ s/pdfmark//g;
-}
-if ($::opt_modes =~ /all/)
-{
- $mode_pdftex = 1;
- $mode_pdfmark = 1;
- $::opt_modes =~ s/all//g;
-}
-$::opt_modes =~ s/\s+//g;
-$::opt_modes =~ s/,+/,/g;
-$::opt_modes =~ s/^,//;
-$::opt_modes =~ s/,$//;
-if ($::opt_modes ne "")
-{
- die "$usage$Error Unknown mode(s): `$::opt_modes'\n";
-}
-if ($::opt_makedata)
-{
- $mode_pdftex or $mode_pdfmark or
- die "$usage$Error Missing mode!\n";
-}
-
-### get jobname
-$jobname = $ARGV[0];
-if ($::opt_useps)
-{
- $jobname =~ s/\.ps$//i;
- $jobname =~ s/\\/\//g;
- $jobfile = $jobname . $psext;
-}
-else
-{
- $jobname =~ s/\.pdf$//i;
- $jobname =~ s/\\/\//g;
- $jobfile = $jobname . $pdfext;
-}
-$pdftexfile = $jobname . $pdftexext;
-$pdfmarkfile = $jobname . $pdfmarkext;
-
-print $title unless $::opt_quiet;
-
-print "* jobname: `$jobname'\n" if $::opt_verbose;
-
-if ($::opt_debug) {
- print <<"END_DEB";
-* OSNAME: $^O
-* PERL_VERSION: $]
-* ARGV: @OrgArgv
-END_DEB
-}
-
-### set signals
-$SIG{__DIE__} = \&clean;
-setsignals(\&cleanup);
-
-my $MaxThumb = 0;
-
-###
-### make thumbnails
-###
-if ($::opt_makepng)
-{
- print "*** make png files / run Ghostscript ***\n"
- unless $::opt_quiet or $::opt_printgscmd;
- if ($::opt_useps)
- {
- print "* ps file: $jobfile\n" if $::opt_verbose;
- }
- else
- {
- print "* pdf file: $jobfile\n" if $::opt_verbose;
- }
- print "* Ghostscript command: `$GS'\n" .
- "* Ghostscript png device: `$::opt_device'\n" if $::opt_verbose;
-
- if ($::opt_resolution)
- {
- $resolution = $::opt_resolution
- }
- else
- {
- # looking for MediaBox
-
- my $max_x = 0;
- my $max_y = 0;
- {
- my $MB = $jobfile;
- open(MB, $MB) or die "$Error Cannot open `$MB'!\n";
- binmode(MB);
- my $xy_patt = '[\-\.\d]';
- while (<MB>)
- {
- if (/\/MediaBox\s*\[\s*($xy_patt+)\s+($xy_patt+)\s+($xy_patt+)\s+($xy_patt+)\s*\]/)
- {
- my $x = $3 - $1;
- my $y = $4 - $2;
- $max_x = $x if $x > $max_x;
- $max_y = $y if $y > $max_y;
- }
- }
- close(MB);
- }
- if ($max_x <= 0 || $max_y <= 0)
- {
- print "!!! Warning: MediaBox not found, " .
- "using default resolution: $resolution DPI\n";
- }
- else
- {
- print "* Max. Size of MediaBox: $max_x x $max_y\n" if $::opt_verbose;
-
- my $rx = 106 * 72 / $max_x;
- my $ry = 106 * 72 / $max_y;
- $resolution = $rx;
- $resolution = $ry if $ry < $rx;
- print "* Resolution: $resolution DPI\n" if $::opt_verbose;
- }
- }
-
-# Ghostscript's pdfshowpage_setpage is patched for solving
-# some problems:
-# * gs6.0* includes a hack that ignores the /Rotate entry
-# in the PDF page, if OutputFile is set.
-# gs6.50 does not need a fix and it is not applied,
-# because pdfshowpage_setpage does not contain /OutputFile.
-# * If /CropBox is set, then it should be used instead
-# of the /MediaBox entry. Because the CropBox area should
-# be part of the MediaBox, the MediaBox is overwritten
-# with the CropBox values for generating the thumbnails.
-# The fixes are only applied for versions >= 6.0, because
-# gs5.50 gets a /PageSize problem with this fix.
-#
- my $SetPageHack = <<'SET_PAGE_HACK';
-currentglobal true setglobal
-false
-/product where {
- pop
- product (Ghostscript) search {
- pop pop pop
- revision 600 ge {
- pop true
- } if
- }{pop} ifelse
-} if
-{ /pdfdict where {
- pop
- pdfdict begin
- /pdfshowpage_setpage
- [ pdfdict /pdfshowpage_setpage get
- { dup type /nametype eq
- { dup /OutputFile eq
- { pop /AntiRotationHack
- }{
- dup /MediaBox eq revision 650 ge and
- { /THB.CropHack {
- 1 index /CropBox pget
- { 2 index exch /MediaBox exch put
- } if
- } def
- /THB.CropHack cvx
- } if
- } ifelse
- } if
- } forall
- ] cvx def
- end
- } if
-} if
-setglobal
-SET_PAGE_HACK
-
- my $Greek = "";
- $Greek = <<'END_GREEK' if $::opt_greek;
-currentglobal true setglobal
-userdict begin
- % * Patch for `show'
- /THB_ORG_show {show} bind def
- /THB_greekstring
- /.charboxpath where
- {
- pop
- {
- currentpoint newpath moveto
- true .charboxpath closepath fill
- } bind def
- }{
- {
- {
- 1 string dup 0 4 -1 roll put
- dup stringwidth pop exch
- true charpath flattenpath pathbbox
- 2 index sub exch 3 index sub exch rectfill
- 0 rmoveto
- } forall
- } bind def
- } ifelse
- /show {
- currentfont /FontType get 1 eq
- {
- dup
- gsave
- % assuming white background
- [ currentrgbcolor ]
- { 1 add 2 div } forall
- setrgbcolor
- THB_greekstring
- grestore
- stringwidth pop 0 rmoveto
- }{
- THB_ORG_show
- } ifelse
- } bind def
-
- % * Patch for the PDF case
- userdict /GS_PDF_ProcSet known
- {
- % GS_PDF_ProcSet is readonly, so it will be copied first
- GS_PDF_ProcSet length 10 add dict dup
- GS_PDF_ProcSet {
- put dup
- } forall
- /GS_PDF_ProcSet exch def
- dup
- begin
- % `setshowstate' contains the use of `show', so it has to
- % be overwritten, because it was defined with `bind'.
- % The definition is taken from `pdf_ops.ps'.
- revision 710 lt
- { % 5.50, 6.51, 7.00, 7.02
-
-/setshowstate
- { WordSpacing 0 eq TextSpacing 0 eq and
- { TextRenderingMode 0 eq
- { { setfillstate show } }
- { { false charpath textrenderingprocs TextRenderingMode get exec } }
- ifelse
- }
- { TextRenderingMode 0 eq
- { WordSpacing 0 eq
- { { setfillstate TextSpacing exch 0 exch ashow } }
- { TextSpacing 0 eq
- { { setfillstate WordSpacing exch 0 exch 32 exch widthshow } }
- { { setfillstate WordSpacing exch TextSpacing exch 0 32 4 2 roll 0 exch awidthshow } }
- ifelse
- }
- ifelse
- }
- { { WordSpacing TextSpacing
- % Implement the combination of t3 and false charpath.
- % Note that we must use cshow for this, because we
- % can't parse multi-byte strings any other way.
- % Stack: string xword xchar
- { pop pop (x) dup 0 3 index put false charpath
- % Stack: xword xchar ccode
- 3 copy 32 eq { add } { exch pop } ifelse 0 rmoveto pop
- }
- 4 -1 roll cshow pop pop
- textrenderingprocs TextRenderingMode get exec
- }
- }
- ifelse
- }
- ifelse /Show gput
- } bdef
-
- }{ % 7.10
-
-/setshowstate
- { WordSpacing 0 eq TextSpacing 0 eq and
- { TextRenderingMode 0 eq
- { { setfillstate show } }
- { { false charpath textrenderingprocs TextRenderingMode get exec } }
- ifelse
- }
- { TextRenderingMode 0 eq
- { WordSpacing 0 eq
- { { setfillstate TextSpacing 0 Vexch 3 -1 roll ashow } }
- { TextSpacing 0 eq
- { { setfillstate WordSpacing 0 Vexch 32 4 -1 roll widthshow } }
- { { setfillstate WordSpacing 0 Vexch 32
- TextSpacing 0 Vexch 6 -1 roll awidthshow } }
- ifelse
- }
- ifelse
- }
- { { WordSpacing TextSpacing
- % Implement the combination of t3 and false charpath.
- % Note that we must use cshow for this, because we
- % can't parse multi-byte strings any other way.
- % Stack: string xword xchar
- { pop pop (x) dup 0 3 index put false charpath
- % Stack: xword xchar ccode
- 3 copy 32 eq { add } { exch pop } ifelse 0 Vexch rmoveto pop
- }
- 4 -1 roll cshow pop pop
- textrenderingprocs TextRenderingMode get exec
- }
- }
- ifelse
- }
- ifelse /Show gput
- } bdef
-
- } ifelse
- end
- readonly pop
- } if
-end
-setglobal
-END_GREEK
-
- my $SetPassword = "";
- $SetPassword = "/PDFPassword($::opt_password)def" if $::opt_password;
-
- my $PSHeader = "save pop $SetPassword $SetPageHack $Greek";
- $PSHeader =~ s/%\s.*\n/ /g;
- $PSHeader =~ s/\s+/ /g;
- $PSHeader =~ s/\s+([\(\/\[\]\{\}])/$1/g;
- $PSHeader =~ s/([\)\[\]\{\}])\s+/$1/g;
- $PSHeader =~ s/\s+$//;
-
- my $AntiAlias = "";
- $AntiAlias = "\n-dTextAlphaBits=$AntiAliasText\n" .
- "-dGraphicsAlphaBits=$AntiAliasGraphics"
- if $::opt_antialias;
-
- my $gs_cmd = <<"GS_CMD_END";
-$GS$AntiAlias
--dNOPAUSE
--dBATCH
--sDEVICE=$::opt_device
--r$resolution
--sOutputFile=$thumbprefix%d.png
--c "$PSHeader"
--f $jobfile
-GS_CMD_END
- # The trick with `save' comes from `ps2pdf':
- # Doing an initial `save' helps keep fonts from being flushed
- # between pages.
-
- if ($::opt_printgscmd)
- {
- open(GSCNF, ">$gscnffile") or die "$Error Cannot open `$gscnffile'!\n";
- $gs_cmd =~ s/^[^\r\n]+[\r\n]+//;
- print GSCNF $gs_cmd;
- close(GSCNF);
- my $options = "@arglist";
- $options =~ s/\s*--?pr[intgscmd]*\s*/ /i;
- $options =~ s/^\s+//;
- $options =~ s/\s+$//;
- print <<"END_PERL" if $::opt_verbose;
-* Perl interpreter: $^X
-* Perl script: $0
-END_PERL
- print <<"END_GS";
-1. Run `Ghostscript' manually:
- ==> $GS \@$gscnffile
-2. Call `thumbpdf' again with the additional option `--nomakepng':
- ==> thumbpdf --nomakepng $options
-END_GS
- exit(0);
- }
-
- chomp($gs_cmd);
- $gs_cmd =~ s/\n/ /mg;
- print "> $gs_cmd\n" if $::opt_verbose;
-
- if ($::opt_debug)
- {
- if ($gspages)
- {
- print "* Ghostscript with page numbers\n";
- }
- else
- {
- print "* Ghostscript without page numbers\n";
- }
- }
-
- setsignals(\&gscleanup);
- my $capture = "";
- if ($gspages)
- {
- my $newline = 0;
- open(KID, "$gs_cmd|") or die "$Error Cannot open Ghostscript ($!)!\n";
- *::GSKID = *KID;
- $gskidrunning = 1;
- my $orgbar = $|;
- $|=1;
- while (<KID>)
- {
- $capture .= $_;
- if ($::opt_verbose)
- {
- print;
- }
- else
- {
- if (!$::opt_quiet)
- {
- print if /^Processing pages/;
- if (/^Page\s+(\d+)/)
- {
- print " " if $newline;
- $newline = 1;
- print "[$1]";
- }
- }
- }
- }
- $gskidrunning =0;
- if (!close(KID))
- {
- if ($!)
- {
- die "$Error Closing Ghostscript ($!)!\n";
- }
- else
- {
- my $exitvalue = $? >> 8;
- die "$Error Closing Ghostscript (exit status: $exitvalue)!\n";
- }
- }
- print "\n" if $newline;
- $| = $orgbar;
- }
- else # without pages
- {
- $capture = `$gs_cmd`;
- if (!defined($capture))
- {
- die "$Error Cannot execute Ghostscript!\n";
- }
- print $capture if $::opt_verbose;
- }
-
- if ($capture =~ /Error:\s*(.*)\n/)
- {
- die <<"END_DIE";
-$Error `$1' (Ghostscript)!
-See `$readme', $gssection, for further information.
-END_DIE
- }
- if ($capture =~ /Unknown device:\s*(.*)\n/)
- {
- die "$Error Unknown device `$1' (Ghostscript)!\n";
- }
- if ($?)
- {
- my $exitvalue = $?;
- if ($exitvalue > 255)
- {
- $exitvalue >>= 8;
- die "$Error Closing Ghostscript (exit status: $exitvalue)!\n";
- }
- die "$Error Closing Ghostscript ($exitvalue)!\n";
- }
- if ($capture =~ /Processing pages \d+ through (\d+)./)
- {
- $MaxThumb = $1;
- }
- print "* max. page: $MaxThumb\n" if $::opt_debug;
- setsignals(\&cleanup);
-}
-
-###
-### make thumbpdf.pdf file
-###
-if ($::opt_makepdf)
-{
- print "*** make `$pdffile' / run pdfTeX ***\n" unless $::opt_quiet;
-
- if ($MaxThumb > 0)
- {
- my $i;
- for ($i=1; $i<=$MaxThumb; $i++)
- {
- push(@cleanlist, "$thumbprefix$i.png");
- }
- }
- else
- {
- # get max thumb number to speed up the pdfTeX run
- $MaxThumb = 0;
- foreach (glob("$thumbprefix*.png"))
- {
- next unless /$thumbprefix(\d+).png/;
- $MaxThumb = $1 if $1 > $MaxThumb;
- push(@cleanlist, $_);
- }
- }
-
- push(@cleanlist, $logfile);
- push(@cleanlist, $pdffile);
-
- my $compress = $::opt_compress;
- $compress = 9 if $::opt_compress == 10;
- my $cmd = "pdftex \"" .
- "\\nonstopmode" .
- "\\pdfcompresslevel$compress" .
- "\\def\\thumbjob{$jobname}" .
- "\\def\\thumbmax{$MaxThumb}" .
- "\\input $texfile" .
- "\"";
- print "> $cmd\n" if $::opt_verbose;
- my @capture = `$cmd`;
- if (!@capture)
- {
- die "$Error Cannot execute pdfTeX!\n";
- }
- if ($::opt_verbose)
- {
- print @capture;
- }
- else
- {
- foreach (@capture)
- {
- print if /^!\s/;
- }
- }
- if ($?)
- {
- my $exitvalue = $?;
- if ($exitvalue > 255)
- {
- $exitvalue >>= 8;
- die "$Error Closing pdfTeX (exit status: $exitvalue)!\n";
- }
- die "$Error Closing pdfTeX ($exitvalue)!\n";
- }
- # test version
- my $versionfound = 0;
- foreach (@capture)
- {
- if (/File:.*thumbpdf.*(\d\d\d\d\/\d\d\/\d\d)\s+v(\d+\.\d+)/)
- {
- $versionfound = 1;
- if ($1 ne $date or $2 ne $version) {
- print <<"END_WARN";
-!!! Warning: Version of `thumbpdf.tex' does not match with perl script!
- Current `thumbpdf.tex': $1 v$2
- Please install version: $date v$version
-END_WARN
- }
- }
- }
- print "!!! Warning: Version of `thumbpdf.tex' not found!\n"
- if !$versionfound;
-
- $_ = pop(@cleanlist);
-}
-
-###
-### parse thumbpdf.pdf
-###
-
-if ($::opt_makedata)
-{
- push(@cleanlist, $pdffile);
-
- print "*** parse `$pdffile' ***\n" unless $::opt_quiet;
-
-### reading file and parse obj structure
-
- my @objno = (); # obj number
- my @objdict = (); # boolean, object is dict
- my @objtext = (); # text of object
- my @objstream = (); # stream of object if any
- my $maxobj = 0;
-
- my @getobjindex = (); # $getobj[obj number] ==> index for $obj...[index]
-
- # open file
- my $PDF = $pdffile;
- open(PDF, $PDF) or die "$Error Cannot open `$PDF'!\n";
- binmode(PDF);
- my $lineno = 0;
-
- # read header
- $_ = <PDF>; $lineno++;
- $_ or die "$Error Cannot read header of `$PDF' or file is empty!\n";
- /^%PDF/ or die "$Error No PDF specification found!\n";
- print "* pdf header: $_" if ($::opt_debug);
-
- # read body objects
- my $count = 0;
- while (<PDF>)
- {
- $lineno++;
-
- # continue, if comment line (2nd line of PDF output by pdfTeX 1.30)
- next if /^%/;
-
- # stop at xref
- last if /^xref$/;
-
- # scan first obj line
- /^(\d+)\s+0\s+obj\s*(<<)?$/ or
- die "$Error `obj' expected on line $lineno!\n";
- $objno[$count] = $1;
- $getobjindex[$1] = $count;
- $objdict[$count] = ($2); # boolean (if $2 exists)
- if (!$objdict[$count]) {
- # check for << on thext line, new PDF-X/2014
- $_ = <PDF>;
- if (/^<<$/) {
- $objdict[$count] = 1;
- $lineno++;
- $_ = <PDF>;
- $lineno++;
- }
- }
- my $stream = 0;
- print "* obj $objno[$count]" .
- (($objdict[$count]) ? " (dict)" : "") .
- "\n" if $::opt_debug;
-
- # get obj
- $objtext[$count] = "";
- while ($_)
- {
- if ($objdict[$count])
- {
- if (/^>>/)
- {
- last if /^>>\s+endobj$/; # obj without stream
-
- $_ = <PDF>; $lineno++;
- last if /^endobj$/; # obj without stream, new PDF-X/2014
-
- # get stream
- /^stream$/ or die "$Error `stream' expected on line $lineno!\n";
-
- print "* stream\n" if $::opt_debug;
- $objstream[$count] = "";
- while (<PDF>)
- {
- $lineno++;
-
- if (/(.*)endstream$/)
- {
- $objstream[$count] .= $1;
- last;
- }
- $objstream[$count] .= $_;
- }
-
- $_ = <PDF>; $lineno++;
- /^endobj$/ or die "$Error `endobj' expected on line $lineno!\n";
- last;
- }
- }
- else # no dict
- {
- last if /^endobj$/;
- }
- $objtext[$count] .= $_;
-
- $_ = <PDF>;
- $lineno++;
- }
- $count++;
- }
- close(PDF);
- $maxobj = $count;
- print "* $maxobj objects found.\n" if $::opt_debug;
-
-### get thumbnail page numbers
- my @thumbpageno = ();
- my $found = 0;
- foreach (@objtext)
- {
- if (/^<<\/ListThumbs\s+(.+)>>$/)
- {
- $_ = $1;
- chomp;
- @thumbpageno = split / /; # split(/ /, $_);
- print "* ListThumbs: @thumbpageno\n" if $::opt_debug;
- $found = 1;
- last;
- }
- }
- $found or die "$Error `/ListThumbs' not found!\n";
- {
- my $j;
- for ($j=0; $j<@thumbpageno; $j++)
- {
- $thumbpageno[$j] = $1 if $thumbpageno[$j] =~ /^{(.+)}$/;
- }
- }
-
-### identify thumb objects
-
- my @thumbobj = (); # index for @obj... with image stream
- my @thumblength = (); # stream length values
- my @thumbrgbobj = (); # index for @obj... with rgb stream
- my @thumbrgblength = (); # rgb stream length values
- my $maxthumb = 0;
-
- $count = 0;
- my $i;
- for ($i=0; $i<$maxobj; $i++)
- {
- if ($objtext[$i] =~
- /^\/Type\s+\/XObject\n\/Subtype\s+\/Image\n/m)
- {
- $thumbobj[$count] = $i;
- $_ = $';
- $objtext[$i] = $_;
-
- # check width and height
- /\/Width\s+(\d+)\n\/Height\s+(\d+)/m or
- die "$Error width/height of thumbnail not found!\n";
- print "* Size: $1x$2\n" if $::opt_debug;
- print "==> Width ($1) " .
- "of thumbnail `$thumbpageno[$count]' " .
- "is larger than recommended (106).\n"
- if $1 > 106;
- print "==> Height ($2) " .
- "of thumbnail `$thumbpageno[$count]' " .
- "is larger than recommended (106).\n"
- if $2 > 106;
-
- # get stream length
- if (/\/Length\s+(\d+)\s+([\/\>]|$)/m)
- {
- $thumblength[$count] = $1;
- print "* Length (direct): $1\n" if $::opt_debug;
- # remove whitespace after length obj
- $objtext[$i] =~ s/(\/Length\s+\d+)\s+\n/$1\n/;
- }
- else # looking for indirect reference
- {
- /\/Length\s+(\d+)\s+0\s+R/m or
- die "$Error `/Length' entry not found!\n";
- # save obj text for later correction
- my $objpre = $`;
- my $objpost = $';
- # look for length obj
- $getobjindex[$1] or die "$Error Length obj not found!\n";
- $objtext[$getobjindex[$1]] =~ /^(\d+)$/m or
- die "$Error length value not found!\n";
- $thumblength[$count] = $1;
- print "* Length (indirect): $1\n" if $::opt_debug;
- # insert obj length directly:
- $objtext[$i] = $objpre . "/Length $1" . $objpost;
- }
-
- # remove \n from end of stream
- if ($thumblength[$count] < length($objstream[$i])) {
- chop($objstream[$i]);
- }
-
- # check /Indexed /DeviceRGB
- if ($objtext[$i] =~
- /\/ColorSpace\s+\[\/Indexed\s+\/DeviceRGB\s+(\d+)\s+(\d+)\s+0\s+R\]/m)
- {
- # correct thumb object text
- $objtext[$i] =
- "$`/ColorSpace [/Indexed /DeviceRGB $1 \\the\\pdflastobj\\ 0 R]$'";
- # get RGB obj number
- $getobjindex[$2] or die "$Error RGB object not found!\n";
- $_ = $getobjindex[$2];
- $thumbrgbobj[$count] = $_;
- # get stream length
- if ($objtext[$_] =~ /\/Length\s+(\d+)\s+([\/\>]|$)/m)
- {
- $thumbrgblength[$count] = $1;
- print "* RGB length (direct): $1\n" if $::opt_debug;
- $objtext[$_] =~ s/(\/Length\s+\d+)\s+\n/$1\n/;
- }
- else # looking for indirect reference
- {
- $objtext[$_] =~ /\/Length\s+(\d+)\s+0\s+R/m or
- die "$Error Length entry of rgb object not found\n";
- # save obj text for later correction
- my $objrgbpre = $`;
- my $objrgbpost = $';
- # get rgb stream length
- $getobjindex[$1] or die "$Error RGB length object not found!\n";
- $objtext[$getobjindex[$1]] =~ /^(\d+)$/m or
- die "$Error length value not found!\n";
- $thumbrgblength[$count] = $1;
- print "* RGB length (indirect): $1\n" if $::opt_debug;
- # insert RGB object length directly:
- $objtext[$_] = $objrgbpre . "/Length $1" . $objrgbpost;
- }
- }
-
- $count++;
- }
- }
- $maxthumb = $count;
-
- if ($maxthumb != @thumbpageno)
- {
- my $pagecount = @thumbpageno;
- die "$Error $maxthumb thumbnails found, but there should be $pagecount!\n";
- }
- print "* $maxthumb thumbnails found.\n" if $::opt_verbose;
-
-
-###
-### write data files
-###
-
- my $timestamp;
- {
- my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
- $mon++;
- $year += 1900;
- $timestamp = sprintf("%04d/%02d/%02d %02d:%02d:%02d",
- $year, $mon, $mday, $hour, $min, $sec);
- }
- if ($mode_pdftex)
- {
- print "*** write `$pdftexfile' (pdfTeX thumbnail data) ***\n"
- unless $::opt_quiet;
- my $DTA_PT = $pdftexfile;
- open(DTA_PT, ">$DTA_PT") or die "$Error Cannot open `$DTA_PT'!\n";
- binmode(DTA_PT);
- print DTA_PT <<"END_DTA";
-% File: $DTA_PT
-% Producer: $program $version
-% Mode: pdftex
-% Date: $timestamp
-END_DTA
- }
- my $maxpagethumb;
- my $dictbegin;
- if ($mode_pdfmark)
- {
- print "*** write `$pdfmarkfile' (pdfmark thumbnail data) ***\n"
- unless $::opt_quiet;
- my $DTA_PM = $pdfmarkfile;
- open(DTA_PM, ">$DTA_PM") or die "$Error Cannot open `$DTA_PM'!\n";
- binmode(DTA_PM);
-
- # write tex part
- print DTA_PM <<"END_DTA";
-% \\iffalse
-% File: $DTA_PM
-% Producer: $program $version
-% Mode: pdfmark
-% Date: $timestamp
-% \\fi
-END_DTA
-
- # looking for max. number of regular thumbnails
- $maxpagethumb = $maxthumb;
- for ($i=0; $i<$maxobj; $i++)
- {
- if ($objtext[$i] =~ /<<\/MaxThumbNumber\s+(\d+)>>/)
- {
- $maxpagethumb = $1;
- last;
- }
- }
-
- # write TeX part
- for ($i=$maxpagethumb; $i<$maxthumb; $i++)
- {
- print DTA_PM "% \\DefThisThumb{$thumbpageno[$i]}\n";
- }
-
- # write PostScript header
- my $dictstart = <<'END_DICT';
- 4 dict begin
- /enddict {
- counttomark 2 idiv dup dict begin {def} repeat pop
- currentdict end
- } bind def
-END_DICT
- chomp($dictstart);
- $dictbegin = "[";
- my $dictend = "enddict";
- my $filter = "";
- my $read = "readhexstring";
- if ($::opt_level2)
- {
- $dictstart = " 3 dict begin";
- $dictbegin = "<<";
- $dictend = ">>";
- $filter = " /ASCII85Decode filter";
- $read = "readstring";
- }
-
- print DTA_PM <<"END_DTA";
-% \\endinput
-% TeX part ends here
-
-% PostScript definitions
-END_DTA
-
- my $PS_Header = <<"END_HEAD";
-%
-% Default definition of pdfmark
-/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
-%
-% Check the version of Ghostscript. If it is below 6.0,
-% the commands, that produce the thumbnails, are defined
-% to be dummies.
-%
-true
-/product where {
- pop
- product (Ghostscript) search {
- pop pop pop
- revision 600 lt {
- (!!! Warning (thumbpdf): Ghostscript 6.0 required for thumbnails!\\n)
- print pop false
- } if
- }{pop} ifelse
-} if
-{
-% Syntax: <thumb object> thisTHB -
-% thisTHB is used globally, so it is defined in the current
-% dictionary (perhaps userdict should explicitly be set).
- /thisTHB {[ exch /Thumb exch /PAGE pdfmark} bind def
-$dictstart
-% Syntax: <page object> <thumb object> pagethumb -
- /pagethumb {
- [ 3 1 roll $dictbegin exch /Thumb exch $dictend /PUT pdfmark
- } bind def
-% Syntax: <thumb object> <stream length>
-% <mark> <key value pairs> streamobj -
-%
-% Distiller ignores the compression of previously compressed
-% streams and uses its own settings. Therefore for Distiller
-% the streams are uncompressed.
-% Now ghostscript versions greater than 8 behave in the same way
-% as Distiller. Therefore detection for this versions is added.
-% The detection and patch for distiller require features of level 2
-% and the filter /FlateDecode (level 3), that is used by pdfTeX's
-% compression.
- /THB_DistillerPatch false def
- /languagelevel where {
- pop
- languagelevel 2 ge {
- product (Distiller) search {pop pop pop true}{pop false} ifelse
- product (Ghostscript) search {
- pop pop pop
- revision 800 ge
- }{pop false} ifelse
- or
- {
- (FlateDecode) {
- pop
-% Syntax: <dict> THB_DistillerPatch <dict> false
-% <dict> THB_DistillerPatch <dict> <filter>
- /THB_DistillerPatch {
- dup /Filter known {
- dup dup /Filter get exch /Filter undef
- }{false} ifelse
- } bind def
- } (FlateDecode) /Filter resourceforall
- } if
- } if
- } if
- /streamobj {
- $dictend exch
-% Stack: <thumb> <dict> <length>
- 3 -1 roll dup
-% Stack: <dict> <length> <thumb> <thumb>
- [ /_objdef 3 -1 roll /type /stream /OBJ pdfmark
-% Stack: <dict> <length> <thumb>
- dup dup 5 -1 roll
-% Stack: <length> <thumb> <thumb> <thumb> <dict>
- THB_DistillerPatch
-% Stack: <length> <thumb> <thumb> <thumb> <dict> <filter/false>
- [ 4 -2 roll /PUT pdfmark
-% Stack: <length> <thumb> <thumb> <filter/false>
- [ 3 1 roll currentfile${filter}
-% Stack: <length> <thumb> [ <thumb> <filter/false> <file>
- 6 -1 roll string $read pop
-% Stack: <thumb> [ <thumb> <filter/false> <string>
- exch dup type /booleantype ne {true} if {filter} if
-% Stack: <thumb> [ <thumb> <file>
- /PUT pdfmark
-% Stack: <thumb>
- [ exch /CLOSE pdfmark
- } bind def
-}{
-% Syntax: <thumb object> thisTHB -
- /thisTHB {pop} bind def
- 2 dict begin
-% Syntax: <page object> <thumb object> pagethumb -
- /pagethumb {pop pop} bind def
-% Syntax: <thumb object> <stream length>
-% <mark> <key value pairs> streamobj -
- /streamobj {
- cleartomark exch pop
- string currentfile${filter}
- exch $read pop pop
- } bind def
-} ifelse
-END_HEAD
- $PS_Header =~ s/%[^\r\n]*[\r\n]+//gm;
- print DTA_PM $PS_Header;
- print DTA_PM <<"END_DTA";
-
-% adding thumbnails to pages
-END_DTA
-
- for ($i=0; $i<$maxpagethumb; $i++)
- {
- print DTA_PM <<"END_DTA";
-{Page$thumbpageno[$i]} {THB$thumbpageno[$i]} pagethumb
-END_DTA
- }
- print DTA_PM "\n% thumbnail data\n";
- }
-
- for ($i=0; $i<$maxthumb; $i++)
- {
- # rgb object
- if ($thumbrgbobj[$i])
- {
- # find the same rgb object
- my $j;
- for ($j=0; $j<$i; $j++)
- {
- next unless $thumbrgbobj[$j];
- next unless $objtext[$thumbrgbobj[$j]] eq
- $objtext[$thumbrgbobj[$i]];
- next unless $objstream[$thumbrgbobj[$j]] eq
- $objstream[$thumbrgbobj[$i]];
- last;
- }
- if ($j==$i) # not found
- {
- if ($mode_pdftex)
- {
- {
- my $rgbstream = pdftexstream($objstream[$thumbrgbobj[$i]]);
- my $dict = $objtext[$thumbrgbobj[$i]];
- if ($::opt_compress == 10)
- {
- chomp($dict);
- $dict =~ s/\n([^\/])/^^J\n$1/mg;
- $dict =~ s/[ ]+\//\//mg;
- }
- else
- {
- $dict =~ s/\n/^^J\n/mg;
- }
- print DTA_PT <<"END_DTA";
-\\immediate\\pdfobj{<<$J
-$dict>>$J
-stream^^J
-$rgbstream
-endstream}
-\\DefRGB{$i}
-END_DTA
- }
- }
- if ($mode_pdfmark)
- {
- {
- my $rgbstream = pdfmarkstream($objstream[$thumbrgbobj[$i]]);
- my $rgblength = $thumbrgblength[$i];
- my $dict = $objtext[$thumbrgbobj[$i]];
- $dict =~ s/\/Length\s+\d+\s*//;
- $dict =~ s/^\s+//;
- $dict =~ s/\s+$//;
- print DTA_PM <<"END_DTA";
-{RGB_$i} $rgblength $dictbegin
-$dict
-streamobj
-$rgbstream
-END_DTA
- }
- }
- }
- else # $j with same rgb obj
- {
- $objtext[$thumbobj[$i]] =~
- s/\\the\\pdflastobj/\\UseRGB{$j}/;
- print "* Reuses RGB object $j for $i\n" if $::opt_debug;
- }
- }
-
- # thumb object
- if ($mode_pdftex)
- {
- {
- my $dict = $objtext[$thumbobj[$i]];
- if ($::opt_compress == 10)
- {
- chomp($dict);
- $dict =~ s/\n([^\/])/^^J\n$1/mg;
- $dict =~ s/[ ]+\//\//mg;
- $dict =~ s/[ ]+\[/\[/mg;
- }
- else
- {
- $dict =~ s/\n/^^J\n/mg;
- }
- my $stream = pdftexstream($objstream[$thumbobj[$i]]);
- print DTA_PT <<"END_DTA";
-\\immediate\\pdfobj{<<$J
-$dict>>$J
-stream^^J
-$stream
-endstream}
-\\DefThumb{$thumbpageno[$i]}
-END_DTA
- }
- }
- if ($mode_pdfmark)
- {
- {
- my $stream = pdfmarkstream($objstream[$thumbobj[$i]]);
- my $length = $thumblength[$i];
- my $dict = $objtext[$thumbobj[$i]];
- $dict =~ s/\\the\\pdflastobj\\\s*\d+\s*R/{RGB_$i}/;
- $dict =~ s/\\UseRGB\{(\d+)\}\\\s*\d+\s*R/{RGB_$1}/;
- $dict =~ s/\/Length\s+\d+\s*//;
- $dict =~ s/^\s+//;
- $dict =~ s/\s+$//;
- my $thismarker = "";
- $thismarker = "_", if $i >= $maxpagethumb;
- print DTA_PM <<"END_DTA";
-{THB$thismarker$thumbpageno[$i]} $length $dictbegin
-$dict
-streamobj
-$stream
-END_DTA
- }
- }
- }
-
- if ($mode_pdftex)
- {
- print DTA_PT "\\endinput\n";
- close(DTA_PT);
- }
- if ($mode_pdfmark)
- {
- print DTA_PM <<"END_DTA";
-end
-% end of thumbnail data file
-END_DTA
- close(DTA_PM);
- }
-}
-
-sub pdftexstream
-{
- my $str = "";
- my $mod = 0;
- foreach (split(//, $_[0]))
- {
- my $num = ord($_);
- if ($num == 13) { $str .= '\\/'; }
- elsif ($num < 32) { $str .= '^^' . chr($num + 64); }
- elsif ($num == 32) { $str .= '\\~'; } # space
- elsif ($num == 37) { $str .= '\\%'; } # percent
- elsif ($num == 92) { $str .= '\\\\'; } # backslash
- elsif ($num == 94) { $str .= '\\+'; } # caret
- elsif ($num == 123) { $str .= '\\{'; } # curly brace left
- elsif ($num == 125) { $str .= '\\}'; } # curly brace right
- else { $str .= $_; }
- $mod++;
- if ($mod == 26)
- {
- $mod = 0;
- $str .= "\n";
- }
- }
- chomp $str;
- return $str;
-}
-
-sub pdfmarkstream
-{
- my $str;
- if ($::opt_level2)
- {
- my $s = $_[0];
- my $len = length($s);
- $str = "";
- my $i;
- for ($i=0; $i<$len-4; $i+=4)
- {
- $_ = ASCII85Encode(substr($s, $i, 4));
- s/!!!!!/z/;
- $str .= $_;
- }
- my $r = $len % 4;
- if ($r)
- {
- $_ = substr($s, $i, $r) . "\000\000\000";
- $_ = ASCII85Encode(substr($_, 0, 4));
- $str .= substr($_, 0, $r+1);
- }
- $str =~ s/(.{60})/$1\n/g;
- chomp($str);
- $str .= "~>";
- }
- else
- {
- $str = uc(unpack('H*', $_[0]));
- $str =~ s/(.{60})/$1\n/g;
- chomp($str);
- }
- return $str;
-}
-
-sub ASCII85Encode
-{
- my $val = unpack("N", $_[0]);
- my @c;
- $c[4] = $val % 85 + 33;
- $val = int($val/85);
- $c[3] = $val % 85 + 33;
- $val = int($val/85);
- $c[2] = $val % 85 + 33;
- $val = int($val/85);
- $c[1] = $val % 85 + 33;
- $c[0] = int($val/85) + 33;
- return pack("C*", @c);
-}
-
-sub setsignals {
- my $func = $_[0];
- $SIG{'HUP'} = $func unless $Win;
- $SIG{'INT'} = $func;
- $SIG{'QUIT'} = $func;
- $SIG{'TERM'} = $func;
-}
-
-sub clean {
- if ($::opt_clean) {
- print "*** clear temp files ***\n" unless $::opt_quiet;
- foreach (@cleanlist) {
- unlink;
- }
- }
-}
-
-sub cleanup {
- print "\n" unless $::opt_quiet;
- clean();
- exit 1;
-}
-
-sub gscleanup {
- print "\n" unless $::opt_quiet;
- clean();
- close(::GSKID) if $gskidrunning;
- foreach (glob("$thumbprefix*.png")) {
- unlink;
- }
- exit 1;
-}
-
-clean();
-
-print "*** ready. ***\n" unless $::opt_quiet;
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/tikztosvg/tikztosvg b/Build/source/texk/texlive/linked_scripts/tikztosvg/tikztosvg
deleted file mode 100755
index 664aea37020..00000000000
--- a/Build/source/texk/texlive/linked_scripts/tikztosvg/tikztosvg
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/bin/sh
-
-puts()
-{
- printf "\033[1m\033[38;5;%sm[%s]\033[m %s\n" "$3" "$1" "$2"
-}
-
-error()
-{
- puts "ERROR" "$1" "9"
-
- if [ -n "$2" ]
- then
- exit "$2"
- else
- exit 1
- fi
-}
-
-message()
-{
- puts "TIKZTOSVG" "$1" "2"
-}
-
-showHelp()
-{
- man tikztosvg
- exit 0
-}
-
-showVersion()
-{
- echo 0.1.2
- exit 0
-}
-
-if ! [ -x "$(command -v xelatex)" ]
-then
- error "xelatex could not be found"
-fi
-
-if ! [ -x "$(command -v pdf2svg)" ]
-then
- error "pdf2svg could not be found"
-fi
-
-# Parsing the arguments
-PACKAGES=""
-while [ $# -gt 1 ]
-do
- case "$1" in
- -h|--help)
- showHelp
- ;;
- -v|--version)
- showVersion
- ;;
- -p|--package)
- case "$2" in
- "")
- error "Unnexpected EOF"
- ;;
- # Check if the name of the package is valid
- *" "*)
- error "Invalid package name. LaTeX package names cannot contain scapes!"
- ;;
- *)
- PACKAGES="$PACKAGES $2"
- shift
- shift
- esac
- ;;
- -o|--output)
- if [ -n "$OUTPUT" ]
- then
- error "The output path was specified multiple times"
- elif [ -z "$2" ]
- then
- error "Unexpected EOF"
- else
- OUTPUT="$2"
- shift
- shift
- fi
- ;;
- -q|--quit)
- QUIET=1
- shift
- ;;
- *)
- error "Unexpected token: \"$1\""
- ;;
- esac
-done
-
-case "$1" in
- -h|--help)
- showHelp
- ;;
- -v|--version)
- showVersion
- ;;
- "")
- error "No input path provided"
- ;;
- "-")
- INPUT=/dev/stdin
- ;;
- *)
- INPUT="$1"
- ;;
-esac
-
-case "$OUTPUT" in
- # Set the output to stdout
- -)
- QUIET=1
- OUTPUT=/dev/stdout
- ;;
-
- # If no output path is provided, use the basename of the input
- "")
- if [ -x "$(command -v dirname)" ]
- then
- OUTPUT="$(dirname "$INPUT")/$(basename "$INPUT" | cut -d "." -f1).svg"
- fi
- ;;
-
- # If the output path is provided, but it resolves to directory, output a
- # a file with the same basename as the input in the target directory
- */)
- OUTPUT="$OUTPUT$(basename "$INPUT" | cut -d "." -f1).svg"
- ;;
-esac
-
-TEMP_DIR="$(mktemp -d)"
-TEX_FILE="$TEMP_DIR/tmp.tex"
-
-# Generate the LaTeX document
-printf "\documentclass[crop,tikz,multi=false]{standalone}\n" > "$TEX_FILE"
-
-for PACKAGE in $PACKAGES
-do
- printf "\usepackage{%s}\n" "$PACKAGE" >> "$TEX_FILE"
-done
-
-printf "\\\begin{document} \huge\n" >> "$TEX_FILE"
-cat "$INPUT" >> "$TEX_FILE"
-
-if [ $? -ne 0 ]
-then
- rm "$TEMP_DIR" -r
- error "File not found: $INPUT"
-fi
-
-printf "\\\end{document}\n" >> "$TEX_FILE"
-
-if [ -z "$QUIET" ]
-then
- message "Rendering the LaTeX document. . ."
- xelatex -halt-on-error -output-directory="$TEMP_DIR" "$TEX_FILE"
-else
- xelatex -halt-on-error -output-directory="$TEMP_DIR" "$TEX_FILE" 1> /dev/null 2>&1
-fi
-
-S=$?
-if [ $S -ne 0 ]
-then
- rm "$TEMP_DIR" -r
- if [ -z "$QUIET" ]
- then
- error "xelatex exited with code $S" $S
- else
- exit $S
- fi
-fi
-
-if [ -z "$QUIET" ]
-then
- message "Converting the output to SVG. . ."
-fi
-
-pdf2svg "$TEMP_DIR/tmp.pdf" "$OUTPUT" 1
-
-S=$?
-if [ $S -ne 0 ]
-then
- rm "$TEMP_DIR" -r
- if [ -z "$QUIET" ]
- then
- error "pdf2svg exited with code $S" $S
- else
- exit $S
- fi
-fi
-
-if [ -z "$QUIET" ]
-then
- message "Done!"
-fi
-
-rm "$TEMP_DIR" -rf
-
diff --git a/Build/source/texk/texlive/linked_scripts/tlcockpit/tlcockpit.sh b/Build/source/texk/texlive/linked_scripts/tlcockpit/tlcockpit.sh
deleted file mode 100755
index 11da62a683b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/tlcockpit/tlcockpit.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-# Public domain. Originally written by Norbert Preining and Karl Berry, 2018-2020.
-
-scriptname=`basename "$0"`
-javaVersion=$(java -version 2>&1 | head -1)
-case "$javaVersion" in
- *"1.8"*) jar="$scriptname-jdk8".jar ;;
- *) jar="$scriptname.jar" ;;
-esac
-jarpath=`kpsewhich --progname="$scriptname" --format=texmfscripts "$jar"`
-
-kernel=`uname -s 2>/dev/null`
-if echo "$kernel" | grep CYGWIN >/dev/null; then
- CYGWIN_ROOT=`cygpath -w /`
- export CYGWIN_ROOT
- jarpath=`cygpath -w "$jarpath"`
-fi
-
-exec java -jar "$jarpath" "$@"
-
diff --git a/Build/source/texk/texlive/linked_scripts/tlshell/tlshell.tcl b/Build/source/texk/texlive/linked_scripts/tlshell/tlshell.tcl
deleted file mode 100755
index 1afe782355b..00000000000
--- a/Build/source/texk/texlive/linked_scripts/tlshell/tlshell.tcl
+++ /dev/null
@@ -1,2761 +0,0 @@
-#!/usr/bin/env wish
-
-# Copyright 2017-2020 Siep Kroonenberg
-
-# This file is licensed under the GNU General Public License version 2
-# or any later version.
-
-package require Tk
-
-# security: disable send
-catch {rename send {}}
-
-# unix: make sure TL comes first on process searchpath
-# on windows, a wrapper takes care of this.
-if {$::tcl_platform(platform) ne "windows"} {
- set texbin [file dirname [file normalize [info script]]]
- # prepend texbin to PATH, unless it is already the _first_
- # path component
- set dirs [split $::env(PATH) ":"]
- if {[lindex $dirs 0] ne $texbin} {
- set ::env(PATH) "${texbin}:$::env(PATH)"
- }
- unset texbin
- unset dirs
-}
-
-set ::instroot [exec kpsewhich -var-value=TEXMFROOT]
-
-# try to read a configuration variable (gui-lang, tkfontscale)
-# from tlmgr config ($TEXMF[SYS]CONFIG/tlmgr/config
-# failure results in an empty string.
-# this proc will be invoked by tltcl if tlshell is the invoker of tltcl
-proc get_config_var {k} {
- set v ""
- set r [join [list {^\s*} $k {\s*=\s*(\S.*)$}] ""]
- foreach tmf {"TEXMFCONFIG" "TEXMFSYSCONFIG"} {
- if [catch {exec kpsewhich -var-value $tmf} d] {
- break; # apparently there is not yet a TL installation
- }
-
- if [catch {open [file join $d "tlmgr" "config"] r} fid] continue
- while 1 {
- if [chan eof $fid] {
- break
- }
- if [catch {chan gets $fid} l] break
- # we can assume that $k contains no special characters
- if [regexp $r $l m v] {
- set v [regsub {\s*$} $v ""]
- break
- } else {
- # regexp will have unset v
- set v ""
- }
- }
- chan close $fid
- if {$v ne ""} break
- }
- return $v
-}
-
-proc save_config_var {k v} {
- if [catch {exec kpsewhich -var-value "TEXMFCONFIG"} d] {return 0}
- set d [file join $d "tlmgr"]
- if [catch {file mkdir $d}] {return 0} ; # mkdir on existing dir is ok
- set fn [file join $d "config"]
- set oldlines [list]
- set r [join [list {^\s*} $k {\s*=\s*(\S.*)$}] ""]
- # read current config file
- if [file exists $fn] {
- if [catch {open $fn r} fid] {return 0}
- set cnt 0
- while 1 {
- if [catch {chan gets $fid} l] break
- if [chan eof $fid] break
- incr cnt
- if {! [regexp $r $l]} {
- lappend oldlines $l
- }
- if {$cnt>40} break
- }
- catch {chan close $fid}
- }
- lappend oldlines "$k = $v"
- if [catch {open $fn w} fid] {return 0}
- foreach l $oldlines {
- if [catch {puts $fid $l}] {
- catch {chan close $fid}
- return 0
- }
- }
- catch {chan close $fid}
- return 1
-}
-
-# tltcl: declarations and utilities shared with install-tl-gui.tcl
-# tltcl likes to know who was the invoker
-set ::invoker [file tail [info script]]
-if [string match -nocase ".tcl" [string range $::invoker end-3 end]] {
- set ::invoker [string range $::invoker 0 end-4]
-}
-source [file join $::instroot "tlpkg" "tltcl" "tltcl.tcl"]
-
-# now is a good time to ask tlmgr for the _TL_ name of our platform
-set ::our_platform [exec -ignorestderr tlmgr print-platform]
-
-# searchpath and locale:
-# windows: tlshell runs via a wrapper which adjusts the searchpath
-# for the current process.
-# others: tlshell.tcl should be run via a symlink in a directory
-# which also contains (a symlink to) kpsewhich.
-# This directory will be prepended to the searchpath.
-# kpsewhich should disentangle symlinks.
-
-# dis/enable the restore dialog
-set do_restore 0
-
-# tlcontrib
-set tlcontrib "http://contrib.texlive.info/current"
-
-# dis/enable debug output (only for private development purposes)
-set ddebug 0
-
-##### general housekeeping ############################################
-
-# menus: disable tearoff feature
-option add *Menu.tearOff 0
-
-proc search_nocase {needle haystack} {
- if {$needle eq ""} {return -1}
- if {$haystack eq ""} {return -1}
- return [string first [string tolower $needle] [string tolower $haystack]]
-}
-
-# the stderr and stdout of tlmgr are each read into lists of strings
-set err_log {}
-set out_log {}
-
-#### debug output, ATM only for private development purposes ####
-
-if $ddebug {set dbg_log {}}
-
-proc do_debug {s} {
- if $::ddebug {
- if {$::tcl_platform(platform) ne "windows"} {puts stderr $s}
- # On windows, stderr output goes nowhere.
- # Therefore also debug output for the log dialog.
- lappend ::dbg_log $s
- file mkdir ${::instroot}/temp
- set dbg [open "${::instroot}/temp/mydbglog" a]
- puts $dbg "TCL: $s"
- chan close $dbg
- # Track debug output in the log dialog if it is running:
- if [winfo exists .tllg.dbg.tx] {
- .tllg.dbg.tx configure -state normal
- .tllg.dbg.tx insert end "$s\n"
- if {$::tcl_platform(os) ne "Darwin"} {
- .tllg.dbg.tx configure -state disabled
- }
- }
- }
-} ; # do_debug
-
-### temporary files and directories #########################
-
-proc maketemp {ext} {
- set fname ""
- foreach i {0 1 2 3 4 5 6 7 8 9} { ; # ten tries
- set fname [file join $::tempsub "[expr {int(10000.0*rand())}]$ext"]
- if {[file exist $fname]} {set fname ""; continue}
- # create empty file. although we just want a name,
- # we must make sure that it can be created.
- set fid [open $fname w]
- chan close $fid
- if {! [file exists $fname]} {error "Cannot create temporary file"}
- if {$::tcl_platform(platform) eq "unix"} {
- file attributes $fname -permissions 0600
- }
- break
- }
- if {$fname eq ""} {error "Cannot create temporary file"}
- return $fname
-} ; # maketemp
-
-set tempsub "" ; # subdir for temp files, set during initialization
-
-### GUI utilities #####################################################
-
-# mouse clicks: deal with MacOS platform differences
-if {[tk windowingsystem] eq "aqua"} {
- event add <<RightClick>> <ButtonRelease-2> <Control-ButtonRelease-1>
-} else {
- event add <<RightClick>> <ButtonRelease-3>
-}
-
-## default_bg color, only used for menus under ::plain_unix
-if [catch {ttk::style lookup TFrame -background} ::default_bg] {
- set ::default_bg white
-}
-
-# NOTE
-# text widgets aren't ttk widgets:
-# state disabled => configure -state disabled
-# state !disabled => configure -state normal
-
-# dialog with textbox
-proc long_message {str type {p "."}} {
- # alternate messagebox implemented as custom dialog
- # not all message types are supported
- if {$type ne "ok" && $type ne "okcancel" && $type ne "yesnocancel"} {
- err_exit "Unsupported type $type for long_message"
- }
- create_dlg .tlmg $p
- wm title .tlmg ""
-
- # wallpaper frame; see populate_main
- pack [ttk::frame .tlmg.bg] -fill both -expand 1
-
- # buttons
- pack [ttk::frame .tlmg.bts] -in .tlmg.bg -side bottom -fill x
- if {$type eq "ok" || $type eq "okcancel"} {
- ttk::button .tlmg.ok -text [__ "Ok"] -command "end_dlg \"ok\" .tlmg"
- ppack .tlmg.ok -in .tlmg.bts -side right
- }
- if {$type eq "yesnocancel"} {
- ttk::button .tlmg.yes -text [__ "Yes"] -command "end_dlg \"yes\" .tlmg"
- ppack .tlmg.yes -in .tlmg.bts -side right
- ttk::button .tlmg.no -text [__ "No"] -command "end_dlg \"no\" .tlmg"
- ppack .tlmg.no -in .tlmg.bts -side right
- }
- if {$type eq "yesnocancel" || $type eq "okcancel"} {
- ttk::button .tlmg.cancel -text [__ "Cancel"] -command \
- "end_dlg \"cancel\" .tlmg"
- ppack .tlmg.cancel -in .tlmg.bts -side right
- }
- if [winfo exists .tlmg.cancel] {
- bind .tlmg <Escape> {.tlmg.cancel invoke}
- wm protocol .tlmg WM_DELETE_WINDOW {cancel_or_destroy .tlmg.cancel .tlmg}
- } elseif {$type eq "ok"} {
- bind .tlmg <Escape> {.tlmg.ok invoke}
- wm protocol .tlmg WM_DELETE_WINDOW {cancel_or_destroy .tlmg.ok .tlmg}
- }
-
- ppack [ttk::frame .tlmg.tx] -in .tlmg.bg -side top -fill both -expand 1
- pack [ttk::scrollbar .tlmg.tx.scroll -command ".tlmg.tx.txt yview"] \
- -side right -fill y
- ppack [text .tlmg.tx.txt -height 20 -width 60 -bd 2 -relief groove \
- -wrap word -yscrollcommand ".tlmg.tx.scroll set"] -expand 1 -fill both
-
- .tlmg.tx.txt insert end $str
- .tlmg.tx.txt configure -state disabled
-
- # default resizable
- place_dlg .tlmg $p
- tkwait window .tlmg
- return $::dialog_ans
-} ; # long_message
-
-proc any_message {str type {p "."}} {
- if {[string length $str] < 400} {
- if {$type ne "ok"} {
- return [tk_messageBox -message $str -type $type -parent $p \
- -icon question]
- } else {
- return [tk_messageBox -message $str -type $type -parent $p]
- }
- } else {
- # just hope that tcl will do the right thing with multibyte characters
- if {[string length $str] > 500000} {
- set str [string range $str 0 500000]
- append str "\n....."
- }
- return [long_message $str $type $p]
- }
-} ; # any_message
-
-##### tl global data ##################################################
-
-set ::last_cmd ""
-
-set ::progname [info script]
-regexp {^.*[\\/]([^\\/\.]*)(?:\....)?$} $progname dummy ::progname
-set ::procid [pid]
-
-# package repositories
-array unset ::repos
-
-# mirrors: dict of dicts of lists of urls per country per continent
-# moved to tltcl.tcl
-#set ::mirrors [dict create]
-
-# dict of (local and global) package dicts
-set ::pkgs [dict create]
-
-# platforms
-set ::platforms [dict create]
-
-set ::have_remote 0 ; # remote packages info not yet loaded
-set ::need_update_tlmgr 0
-set ::n_updates 0
-set ::tlshell_updatable 0
-
-## package data to be displayed ##
-
-# sorted display data for packages; package data stored as lists
-set ::filtered [dict create]
-
-# selecting packages for display: status and detail
-set ::stat_opt "inst"
-set ::dtl_opt "all"
-# searching packages for display; also search short descriptions?
-set ::search_desc 0
-
-### enabling and disabling user interaction based on global data
-
-proc selective_dis_enable {} {
- # disable actions which make no sense at the time
-
- # buttons in the middle section
- set pkg_buttons [list .mrk_inst .mrk_upd .mrk_rem .upd_tlmgr .upd_all]
- foreach b [list .mrk_inst .mrk_upd .mrk_rem .upd_tlmgr .upd_all] {
- $b state !disabled
- }
- if $::do_restore {.mrk_rest state !disabled}
-
- if {!$::have_remote} {
- foreach b [list .mrk_inst .mrk_upd .upd_tlmgr .upd_all] {
- $b state disabled
- }
- } elseif {!$::n_updates} {
- foreach b [list .mrk_upd .upd_tlmgr .upd_all] {
- $b state disabled
- }
- } elseif $::need_update_tlmgr {
- foreach b [list .mrk_inst .mrk_upd] {
- $b state disabled
- }
- if {$::tcl_platform(platform) eq "windows"} {
- .upd_all state disabled
- }
- } elseif {!$::need_update_tlmgr} {
- .upd_tlmgr state disabled
- }
-
- # platforms menu item
- if {$::tcl_platform(platform) ne "windows"} {
- if {!$::have_remote || $::need_update_tlmgr} {
- .mn.opt entryconfigure $::inx_platforms -state disabled
- } else {
- .mn.opt entryconfigure $::inx_platforms -state normal
- }
- }
-}; # selective_dis_enable
-
-proc total_dis_enable {y_n} {
- # to be invoked when tlmgr becomes busy or idle, i.e.
- # if it starts with a tlmgr command through run_cmds
- # or read_line notices the command(s) ha(s|ve) ended.
- # This proc should cover all active interface elements of the main window.
- # But if actions are initiated via a dialog, the main window can instead
- # be deactivated by a grab and focus on the dialog.
-
- if {!$y_n} { ; # disable
- set ::busy [__ "Running"]
- . configure -menu .mn_empty
- foreach c [winfo children .] {
- if {$c ne ".showlogs" && [winfo class $c] in $::active_cls} {
- # this should cover all relevant widgets in the main window
- $c state disabled
- }
- }
- } else { ; # enable
- . configure -menu .mn
- foreach c [winfo children .] {
- if {[winfo class $c] in $::active_cls} {
- $c state !disabled
- }
- }
- set ::busy [__ "Idle"]
- selective_dis_enable
- }
-} ; # total_dis_enable
-
-##### handling tlmgr via pipe and stderr tempfile #####################
-
-set ::prmpt "tlmgr>"
-set ::busy [__ "Running"]
-
-# copy logs to log window yes/no
-set ::show_output 0
-
-# about [chan] gets:
-# if a second parameter, in this case l, is supplied
-# then this variable receives the result, with EOL stripped,
-# and the return value is the string length, possibly 0
-# EOF is indicated by a return value of -1.
-
-proc read_err_tempfile {} {
- if [info exists ::err] {
- set len 0
- while 1 {
- set len [chan gets $::err l]
- if {$len >= 0} {
- lappend ::err_log $l
- } else {
- break
- }
- }
- }
-} ; # read_err_tempfile
-
-proc err_exit {{m ""}} {
- do_debug "error exit"
- read_err_tempfile
- if {$m ne ""} {
- set ::err_log [linsert $::err_log 0 $m]
- }
- any_message [join $::err_log "\n"] "ok"
- exit
-} ; # err_exit
-
-# Capture stdout of tlmgr into a pipe $::tlshl,
-# stderr into a temp file file $::err_file which is set at initialization.
-
-proc start_tlmgr {{args ""}} {
- # Start the TeX Live Manager shell interface.
- # Below, vwait ::done_waiting forces tlshell
- # to process initial tlmgr output before continuing.
- unset -nocomplain ::done_waiting
- do_debug "opening tlmgr"
- # -gui -. -gui-lang
- for {set i 0} {$i < [llength $args]} {incr i} {
- if {[lindex $args $i] eq "-lang"} {
- set args [lreplace $args $i $i "-gui-lang"]
- }
- }
- set cmd [list "|tlmgr" {*}$args "--machine-readable" "shell" 2>>$::err_file]
- if [catch {open $cmd w+} ::tlshl] {
- tk_messageBox -message [get_stacktrace]
- exit
- }
- set ::perlpid [pid $::tlshl]
- do_debug "done opening tlmgr"
- set ::err [open $::err_file r]
- chan configure $::tlshl -buffering line -blocking 0
- chan event $::tlshl readable read_line
- vwait ::done_waiting
-} ; # start_tlmgr
-
-proc close_tlmgr {} {
- run_cmd_waiting "quit"
-}
-
-# read a line of tlmgr output
-proc read_line {} {
- # a caller of run_cmd needs to explicitly invoke 'vwait ::done_waiting'
- # if it wants to wait for the command to finish
- set l "" ; # will contain the line to be read
- if {([catch {chan gets $::tlshl l} len] || [chan eof $::tlshl])} {
- # copy as much of stderr as possible to ::err_log
- catch {read_err_tempfile ; chan close $::err}
- if [chan eof $::tlshl] {
- catch {chan close $::tlshl}
- unset -nocomplain ::tlshl
- unset -nocomplain ::err
- set ::perlpid 0
- set ::done_waiting 1
- } else {
- #do_debug "read_line: failing to read "
- puts stderr "Read failure; tlmgr command was $::last_cmd"
- # note. the normal way to terminate is terminating the GUI shell.
- # This closes stdin of tlmgr shell.
- err_exit
- }
- } elseif {$len >= 0} {
- # do_debug "read: $l"
- if $::ddebug {puts $::flid $l}
- if {[string first $::prmpt $l] == 0} {
- # prompt line: we are done with the current command
- total_dis_enable 1 ; # this may have to be redone later
- # catch up with stderr
- read_err_tempfile
- if $::show_output {
- do_debug "prompt found, $l"
- log_widget_finish
- }
- # for vwait:
- set ::done_waiting 1
- set ::show_output 0
- } else {
- # regular output
- lappend ::out_log $l
- if $::show_output {
- log_widget_add $l
- }
- }
- }
-} ; # read_line
-
-# copy error strings to error page in logs dialog .tllg and send it to top.
-# This by itself does not map the logs dialog .tllg
-
-proc show_err_log {} {
- #do_debug "show_err_log"
- .tllg.err.tx configure -state normal
- .tllg.err.tx delete 1.0 end
- if {[llength $::err_log] > 0} {
- foreach l $::err_log {.tllg.err.tx insert end "$l\n"}
- .tllg.err.tx yview moveto 1
- .tllg.logs select .tllg.err
- }
- if {$::tcl_platform(os) ne "Darwin"} {
- # os x: text widget disabled => no selection possible
- .tllg.err.tx configure -state disabled
- }
-} ; # show_err_log
-
-proc log_widget_init {} {
- show_logs ; # create the logs dialog
- set ::busy [__ "Running"]
- .tllg.close state disabled
-}
-
-proc log_widget_add l {
- .tllg.log.tx configure -state normal
- .tllg.log.tx insert end "$l\n"
- if {$::tcl_platform(os) ne "Darwin"} {
- .tllg.log.tx configure -state disabled
- }
-}
-
-proc log_widget_finish {} {
- .tllg.log.tx yview moveto 1
- .tllg.logs select .tllg.log
- # error log on top if it contains anything
- show_err_log
- if {$::tcl_platform(os) ne "Darwin"} {
- .tllg.log.tx configure -state disabled
- }
- set ::busy [__ "Idle"]
- .tllg.close state !disabled
- bind .tllg <Escape> {.tllg.close invoke}
-}
-
-##### running tlmgr commands #####
-
-# run a list of commands
-proc run_cmds {cmds {show 0}} {
- set ::show_output $show
- do_debug "run_cmds \"$cmds\""
- if $::ddebug {puts $::flid "\n$cmds"}
- set ::out_log {}
- set ::err_log {}
- if $show {
- show_logs
- .tllg.status configure -text [__ "Running"]
- .tllg.close state disabled
- }
- set l [llength $cmds]
- for {set i 0} {$i<$l} {incr i} {
- if {! [info exists ::tlshl]} {
- err_exit "Back end gone. Last command: \n $::last_cmd"
- }
- set cmd [lindex $cmds $i]
- set ::last_cmd $cmd
- unset -nocomplain ::done_waiting
- # disable widgets for each new command,
- # since read_line will re-enable them
- # when a particular command is finished
- total_dis_enable 0
- chan puts $::tlshl $cmd
- chan flush $::tlshl
- if {$i < [expr {$l-1}]} {vwait ::done_waiting}
- }
-} ; # run_cmds
-
-# run a single command
-proc run_cmd {cmd {show 0}} {
- run_cmds [list $cmd] $show
-} ; # run_cmd
-
-proc run_cmd_waiting {cmd} {
- run_cmd $cmd 0
- vwait ::done_waiting
-} ; # run_cmd_waiting
-
-##### Handling package info #####
-
-# what invokes what?
-# The main 'globals' are (excepting dicts and arrays):
-
-# ::have_remote is initialized to false. It is set to true by
-# get_packages_info_remote, and remains true except temporarily at
-# a change of repository.
-
-# The other globals ones are ::n_updates, ::need_update_tlmgr and
-# ::tlshell_updatable. These are initially set to 0 and re-calculated
-# by update_globals.
-
-# update_globals is invoked by get_packages_info_remote and
-# update_local_revnumbers. It enables and disables buttons as appropriate.
-
-# displayed global status info is updated by update_globals.
-# update button/menu states are set at initialization and updated
-# by update_globals, both via the selective_dis_enable proc
-
-# The repositories play a small part in this front end. Tlmgr mostly works
-# with a virtual repository, which is the combined set of repositories,
-# with pinning applied if there is more than one repository.
-# But get_packages_info_remote must invoke
-# show_repos to display updated verification info.
-# show_repos is also invoked by initialize.
-
-# get_packages_info_local is invoked only once, at initialization. After
-# installations and removals, the collected information is updated by
-# update_local_revnumbers.
-# Both procs also invoke get_platforms
-
-# get_packages_info_remote should be invoked before collect_filtered if
-# ::have_remote is false. Afterwards, ::have_remote will be true.
-# There will be no need to invoke get_packages_info_remote again except
-# at a change of repository by repos_commit.
-# get_packages_info_remote invokes update_globals, show_repos
-# and get_platforms.
-
-# update_local_revnumbers will be invoked after any updates. It also
-# invokes update_globals.
-
-# collect_filtered does not only filter, but also organize the
-# information to be displayed. It invokes display_packages_info.
-# It is invoked at initialization, when filtering options change and
-# at the end of install-, remove- and update procs.
-
-# display_packages_info is mostly invoked by collect_filtered, but
-# also when the search term or the search option changes.
-
-proc is_updatable {nm} {
- set pk [dict get $::pkgs $nm]
- set lr [dict get $pk localrev]
- set rr [dict get $pk remoterev]
- return [expr {$lr > 0 && $rr > 0 && $rr > $lr}]
-}
-
-proc display_updated_globals {} {
- if {$::have_remote && $::need_update_tlmgr} {
- .topfll.luptodate configure -text [__ "Needs updating"]
- } elseif $::have_remote {
- .topfll.luptodate configure -text [__ "Up to date"]
- } else {
- .topfll.luptodate configure -text [__ "Unknown"]
- }
- # ... and status of update buttons
- selective_dis_enable
-}
-
-proc update_globals {} {
- if {! $::have_remote} return
- set ::n_updates 0
- foreach nm [dict keys $::pkgs] {
- if [is_updatable $nm] {incr ::n_updates}
- }
- set ::need_update_tlmgr [is_updatable texlive.infra]
- set ::tlshell_updatable [is_updatable tlshell]
-
- # also update displayed status info
- display_updated_globals
-}
-
-# The package display treeview widget in the main window has columns
-# for both local and remote revision numbers.
-# It gets its data from $::filtered rather than directly from $::pkgs.
-# ::pkgs should already be up to date.
-
-# I added a field 'marked' to ::pkgs. It is displayed in the first treeview
-# column. This looks better than the treeview tag facilities.
-# In ::pkgs, 'marked' is represented as a boolean.
-# In ::filtered and .pkglist they are represented as unicode symbols.
-
-# display packages obeying both filter and search string.
-# even on a relatively slow system, regenerating .pkglist from ::filtered
-# at every keystroke is acceptably responsive.
-# with future more advanced search options, this scheme may not suffice.
-
-proc display_packages_info {} {
- # do_debug [get_stacktrace]
- set curr [.pkfilter.search_e get]
- .pkglist delete [.pkglist children {}]
- dict for {nm pk} $::filtered {
- set do_show 0
- if {$curr eq ""} {
- # empty search string
- set do_show 1
- } elseif {[search_nocase $curr $nm] >= 0} {
- set do_show 1
- } elseif {$::search_desc && \
- [search_nocase $curr [dict get $::pkgs $nm shortdesc]] >= 0} {
- set do_show 1
- }
- if $do_show {
- .pkglist insert {} end -id $nm -values $pk
- }
- }
-} ; # display_packages_info
-
-proc for_other_platform {nm} {
- set r [string last "." $nm]
- if {$r < 0} {
- return 0
- } else {
- set n [string range $nm 0 [expr {$r-1}]]
- set p [string range $nm [expr {$r+1}] end]
- # p a platform identifier of an installed platform?
- if [dict exists $::platforms $p] {
- return [expr {! [dict get $::platforms $p "cur"]}]
- } else {
- return 0
- }
- }
-}
-
-# (re)create ::filtered dictionary; disregard search string in selection
-# The value associated with each key/package is a list, not another dict.
-proc collect_filtered {} {
- do_debug \
- "collect_filtered for $::stat_opt and $::dtl_opt"
- if {$::stat_opt ne "inst" && ! $::have_remote} {
- # have_remote should have been ensured when changing stat_opt from inst
- err_exit "collect_filtered should not have been invoked at this time"
- }
- foreach nm [dict keys $::filtered] {
- dict unset ::filtered $nm
- }
- foreach nm [lsort [dict keys $::pkgs]] {
- # do not list packages for platforms which are not installed
- if [for_other_platform $nm] continue
- set pk [dict get $::pkgs $nm]
- set do_show 1
- set mrk [mark_sym [dict get $pk marked]]
- set lr [dict get $pk localrev]
- set rr [dict get $pk remoterev]
- set ct [dict get $pk category]
- if {$::stat_opt eq "inst" && $lr == 0} {
- set do_show 0
- } elseif {$::stat_opt eq "notins" && $lr > 0} {
- set do_show 0
- } elseif {$::stat_opt eq "upd" && ($lr == 0 || $rr == 0 || $rr <= $lr)} {
- set do_show 0
- }
- if {! $do_show} continue
- if {$::dtl_opt eq "schm" && $ct ne "Scheme"} {
- set do_show 0
- } elseif {$::dtl_opt eq "coll" && \
- $ct ne "Scheme" && $ct ne "Collection"} {
- set do_show 0
- }
- if {! $do_show} continue
-
- # collect data to be displayed for $nm
- dict lappend ::filtered $nm $mrk
- dict lappend ::filtered $nm $nm
- set v [dict get $pk localrev]
- set lv [dict get $pk lcatv]
- if {$v eq "0" || $v == 0} {
- set v "" ; # can this happen?
- } elseif {$lv != 0 && $lv ne ""} {
- set v "$v ($lv)"
- }
- dict lappend ::filtered $nm $v
- set v [dict get $pk remoterev]
- set rv [dict get $pk rcatv]
- if {$v eq "0" || $v == 0} {
- set v ""
- } elseif {$rv != 0 && $rv ne ""} {
- set v "$v ($rv)"
- }
- dict lappend ::filtered $nm $v
- dict lappend ::filtered $nm [dict get $pk shortdesc]
- }
-} ; # collect_filtered
-
-proc collect_and_display_filtered {} {
- collect_filtered
- display_packages_info
-}
-
-proc get_platforms {} {
- # guarantee fresh start
- foreach k $::platforms {dict unset ::platforms $k}
- set ::platforms [dict create]
- # find binary packages for pdftex; 'platform list' not available on windows
- foreach k [dict keys $::pkgs {pdftex.*}] {
- # {pdftex.*} is a glob pattern, not a regexp: '.' is a literal
- set plname [string range $k 7 end]
- if {[dict get $::pkgs $k localrev] > 0} {
- dict set ::platforms $plname "cur" 1
- #dict set ::platforms $plname "fut" 1
- } else {
- dict set ::platforms $plname "cur" 0
- #dict set ::platforms $plname "fut" 0
- }
- }
-}
-
-# get fresh package list. invoked at program start
-# some local packages may not be available online.
-# to test, create local dual-platform installation from dvd, try to update
-# from more recent linux-only installation
-
-proc get_packages_info_local {} {
- # start from scratch; see also update_local_revnumbers
- foreach nm [dict keys $::pkgs] {
- dict unset ::pkgs $nm
- }
- set ::have_remote 0
- set ::need_update_tlmgr 0
- set ::updatable 0
- set ::tlshell_updatable 0
-
- run_cmd_waiting \
- "info --only-installed --data name,localrev,cat-version,category,shortdesc"
- set re {^([^,]+),([0-9]+),([^,]*),([^,]*),(.*)$}
- foreach l $::out_log {
- if [regexp $re $l m nm lrev lcatv catg pdescr] {
- # double-quotes in short description: remove outer, unescape inner
- if {[string index $pdescr 0] eq "\""} {
- set pdescr [string range $pdescr 1 end-1]
- }
- set pdescr [string map {\\\" \"} $pdescr]
- dict set ::pkgs $nm \
- [list "marked" 0 "localrev" $lrev "lcatv" $lcatv "remoterev" 0 \
- "rcatv" 0 "category" $catg shortdesc $pdescr]
- }
- }
- get_platforms
-} ; # get_packages_info_local
-
-proc abort_load {} {
- # try to close back end forcibly
- catch {chan close $::tlshl}
- if {$::tcl_platform(platform) eq "windows"} {
- catch {exec -ignorestderr taskkill /pid $::perlpid /t /f}
- } else {
- catch {exec -ignorestderr kill -9 $::perlpid}
- # should also be ok for darwin
- }
- # start new tlshell process
- exec $::progname &
-
- # end current tlshell process nicely
- exit
- # kill current tlshell process forcibly if necessary
- if {$::tcl_platform(platform) eq "windows"} {
- catch {exec -ignorestderr taskkill /pid [pid] /t /f}
- } else {
- catch {exec -ignorestderr kill -9 [pid]}
- }
-} ; # abort load
-
-# toplevel with abort button in case loading of a repository takes too long.
-# it can be closed when loading finishes
-proc splash_loading {} {
-
- create_dlg .loading .
-
- wm title .loading [__ "Loading"]
-
- # wallpaper
- pack [ttk::frame .loading.bg -padding 3pt] -fill both -expand 1
-
- set lbl [__ \
- "If loading takes too long, press Abort and choose another repository."]
- append lbl "\n([__ "Options"] \/ [__ "Repositories"] ...)"
- ppack [ttk::label .loading.l0 -text $lbl \
- -wraplength [expr {60*$::cw}] -justify left] \
- -in .loading.bg -anchor w
-
- pack [ttk::frame .loading.tfr] -in .loading.bg -expand 1 -fill x
- pack [ttk::scrollbar .loading.scroll -command ".loading.tx yview"] \
- -in .loading.tfr -side right -fill y
- ppack [text .loading.tx -height 5 -wrap word \
- -yscrollcommand ".loading.scroll set"] \
- -in .loading.tfr -expand 1 -fill both
- pack [ttk::frame .loading.buttons] -in .loading.bg -expand 1 -fill x
- ttk::button .loading.close -text [__ "Close"] -command {end_dlg "" .loading}
- ppack .loading.close -in .loading.buttons -side right
- .loading.close configure -state disabled
- ttk::button .loading.abo -text [__ "Abort"] -command abort_load
- ppack .loading.abo -in .loading.buttons -side right
- wm protocol .loading {cancel_or_destroy .loading.abo .loading}
- wm resizable .loading 0 0
- place_dlg .loading .
-} ; # splash_loading
-
-
-proc track_err {} {
- set inx0 [llength $::err_log]
- read_err_tempfile
- .loading.tx configure -state normal
- for {set i $inx0} {$i < [llength $::err_log]} {incr i} {
- .loading.tx insert end "[lindex $::err_log $i]\n"
- }
- .loading.tx configure -state disabled
- update idletasks
- if {![info exists ::loaded]} {
- after 500 track_err
- } else {
- .loading.close state !disabled
- .loading.abo state disabled
- .loading.tx configure -state normal
- .loading.tx insert end [__ "Done loading"]
- .loading.tx configure -state disabled
- }
-}
-
-# remote: preserve information on installed packages
-proc get_packages_info_remote {} {
- # remove non-local database entries
- foreach k [dict keys $::pkgs] {
- if {! [dict get $::pkgs $k localrev]} {
- dict unset ::pkgs $k
- }
- }
- set ::need_update_tlmgr 0
- set ::updatable 0
- set ::tlshell_updatable 0
-
- splash_loading
-
- unset -nocomplain ::loaded
- track_err
- set catv "rcat-version"
- if {[dict get $::pkgs texlive.infra localrev] < 56458} { set catv "cat-version" }
- if [catch {run_cmd \
- "info --data name,remoterev,$catv,category,shortdesc"}] {
- do_debug [get_stacktrace]
- tk_messageBox -message [__ "A configured repository is unavailable."]
- return 0
- }
- vwait ::done_waiting
- set ::loaded 1
- set re {^([^,]+),([0-9]+),([^,]*),([^,]*),(.*)$}
- foreach l $::out_log {
- if [regexp $re $l m nm rrev rcatv catg pdescr] {
- # double-quotes in short description: remove outer, unescape inner
- if {[string index $pdescr 0] eq "\""} {
- set pdescr [string range $pdescr 1 end-1]
- }
- set pdescr [string map {\\\" \"} $pdescr]
- if [catch {dict get $::pkgs $nm} pk] {
- # package entry does not yet exist, create it
- dict set ::pkgs $nm [list "marked" 0 "localrev" 0 "lcatv" 0]
- }
- dict set ::pkgs $nm "remoterev" $rrev
- dict set ::pkgs $nm "rcatv" $rcatv
- dict set ::pkgs $nm "category" $catg
- dict set ::pkgs $nm "shortdesc" $pdescr
- }
- }
- get_platforms ; # derive from $::pkgs
-
- set ::have_remote 1
- update_globals
- show_repos
- return 1
-} ; # get_packages_info_remote
-
-## update ::pkgs after installing packages without going online again.
-proc update_local_revnumbers {} {
- do_debug "update_local_revnumbers"
- run_cmd_waiting "info --only-installed --data name,localrev,lcat-version"
- set re {^([^,]+),([0-9]+),(.*)$}
- dict for {pk pk_dict} $::pkgs {
- do_debug "zeroing local data for $pk"
- dict set pk_dict "localrev" 0
- dict set pk_dict "lcatv" 0
- dict set ::pkgs $pk $pk_dict
- }
- foreach l $::out_log {
- if [regexp $re $l m pk lr lv] {
- set pk_dict [dict get $::pkgs $pk]
- dict set pk_dict "localrev" $lr
- dict set pk_dict "lcatv" $lv
- dict set pk_dict "rcatv" $lv
- dict set ::pkgs $pk $pk_dict
- }
- }
- get_platforms
- update_globals
-} ; # update_local_revnumbers
-
-##### Logs notebook ##############################
-
-# if invoked via run_cmds, it tracks progress of (a) tlmgr command(s).
-# run_cmds will temporarily disable the close button
-# and set .tllg.status to busy via total_dis_enable 0.
-# otherwise, it shows the output of the last completed (list of) command(s).
-
-# Note that run_cmds clears ::out_log and ::err_log, but not ::dbg_log.
-
-proc show_logs {} {
- create_dlg .tllg .
- wm title .tllg Logs
-
- # wallpaper
- pack [ttk::frame .tllg.bg] -fill both -expand 1
-
- # close button and busy label
- pack [ttk::frame .tllg.bottom] -in .tllg.bg -side bottom -fill x
- ttk::button .tllg.close -text [__ "Close"] -command {end_dlg 0 .tllg}
- ppack .tllg.close -in .tllg.bottom -side right -anchor e
- ppack [ttk::label .tllg.status -textvariable ::busy -anchor w] \
- -in .tllg.bottom -side left
- bind .tllg <Escape> {.tllg.close invoke}
- wm protocol .tllg WM_DELETE_WINDOW \
- {cancel_or_destroy .tllg.close .tllg}
-
- # notebook pages and scrollbars
- ttk::frame .tllg.log
- pack [ttk::scrollbar .tllg.log.scroll -command ".tllg.log.tx yview"] \
- -side right -fill y
- ppack [text .tllg.log.tx -height 10 -wrap word \
- -yscrollcommand ".tllg.log.scroll set"] \
- -expand 1 -fill both
- .tllg.log.tx configure -state normal
- foreach l $::out_log {
- .tllg.log.tx insert end "$l\n"
- }
- if {$::tcl_platform(os) ne "Darwin"} {.tllg.log.tx configure -state disabled}
- .tllg.log.tx yview moveto 1
-
- ttk::frame .tllg.err
- pack [ttk::scrollbar .tllg.err.scroll -command ".tllg.err.tx yview"] \
- -side right -fill y
- ppack [text .tllg.err.tx -height 10 -wrap word \
- -yscrollcommand ".tllg.err.scroll set"] \
- -expand 1 -fill both
- .tllg.err.tx configure -state normal
- foreach l $::err_log {
- .tllg.err.tx configure -state normal
- .tllg.err.tx insert end "$l\n"
- }
- if {$::tcl_platform(os) ne "Darwin"} {.tllg.err.tx configure -state disabled}
- .tllg.err.tx yview moveto 1
-
- if $::ddebug {
- ttk::frame .tllg.dbg
- pack [ttk::scrollbar .tllg.dbg.scroll -command ".tllg.dbg.tx yview"] \
- -side right -fill y
- ppack [text .tllg.dbg.tx -height 10 -bd 2 -relief groove -wrap word \
- -yscrollcommand ".tllg.dbg.scroll set"] \
- -expand 1 -fill both
- .tllg.dbg.tx configure -state normal
- foreach l $::dbg_log {
- .tllg.dbg.tx insert end "$l\n"
- }
- if {$::tcl_platform(os) ne "Darwin"} {
- .tllg.dbg.tx configure -state disabled
- }
- .tllg.dbg.tx yview moveto 1
- }
-
- # collect pages in notebook widget
- pack [ttk::notebook .tllg.logs] -in .tllg.bg -side top -fill both -expand 1
- .tllg.logs add .tllg.log -text [__ "Output"]
- .tllg.logs add .tllg.err -text [__ "Other"]
- if $::ddebug {
- .tllg.logs add .tllg.dbg -text "Debug"
- raise .tllg.dbg .tllg.logs
- }
- raise .tllg.err .tllg.logs
- raise .tllg.log .tllg.logs
-
- # default resizable
- place_dlg .tllg .
-} ; # show_logs
-
-##### repositories ###############################################
-
-### mirrors
-#mangle_name {n} {} ; moved to tltcl.tcl
-#proc read_mirrors {} {} ; moved to tltcl.tcl
-
-proc pick_local_repo {} {
- set nw_repo [.tlr.cur cget -text]
- if {! [file isdirectory $nw_repo]} {
- set nw_repo $::env(HOME) ; # HOME also o.k. for windows
- }
- while 1 {
- set nw_repo [browse4dir $nw_repo .tlr]
- if {$nw_repo ne "" && ! [possible_repository $nw_repo]} {
- tk_messageBox -message [__ "%s not a repository" $nw_repo] -parent .tlr
- continue
- } else {
- .tlr.save state !disabled
- break
- }
- }
- if {$nw_repo ne ""} {
- .tlr.new delete 0 end
- .tlr.new insert end $nw_repo
- }
-} ; # pick_local_repo
-
-proc get_repos_from_tlmgr {} {
- array unset ::repos
- run_cmd_waiting "option repository"
- set rps ""
- foreach l $::out_log {
- if [regexp {repository\t(.*)$} $l dum rps] break
- }
- if {$rps ne ""} {
- set reps [split $rps " "]
- set nr [llength $reps]
- foreach rp $reps {
- # decode spaces and %
- set rp [string map {"%20" " "} $rp]
- set rp [string map {"%25" "%"} $rp]
- if {! [regexp {^(.+)#(.+)$} $rp dum r t]} {
- # no tag; use repository as its own tag
- set r $rp
- set t $rp
- }
- if {$nr == 1} {
- set t "main"
- }
- set ::repos($t) $r
- }
- if {"main" ni [array names ::repos]} {
- array unset ::repos
- }
- }
-}; # get_repos_from_tlmgr
-
-proc set_repos_in_tlmgr {} {
- # tlmgr has no command to replace a single repository;
- # we need to compose a string for opt_location ourselves from $::repos.
- # a single repository should not get a tag.
- # apparently, we can safely ignore bogus pinning data.
- set nr [array size ::repos]
- set opt_repos ""
- set rp ""
- foreach nm [array names ::repos] {
- if {$nr==1} {
- if {$nm ne "main"} {
- err_exit "Internal error"
- } else {
- # pinning command only supported for multiple repositories
- set rp $::repos(main)
- }
- } else {
- if {$nm eq $::repos($nm)} {
- set rp $nm
- } else {
- set rp $::repos($nm)
- append rp "#$nm"
- }
- }
- # encode % and spaces
- set rp [string map {"%" "%25"} $rp]
- set rp [string map {" " "%20"} $rp]
- append opt_repos " $rp"
- }
- run_cmd_waiting "repository set [string range $opt_repos 1 end]"
-}; # set_repos_in_tlmgr
-
-proc show_repos {} {
- # this proc lists the configured repository/ies
- # in the upper left portion of the main window.
- # it makes one call to the back end, but no need to go online.
- set w .toprepo
- foreach ch [winfo children $w] {destroy $ch}
- set nms [array names ::repos]
- set c [llength $nms]
- grid [ttk::frame $w.repoheadframe] \
- -row 0 -column 0 -columnspan 3 -sticky w
- pack [ttk::label $w.head -font hfont] \
- -in $w.repoheadframe -side left
- pack [ttk::label $w.load -text ""] \
- -in $w.repoheadframe -side left -anchor sw
- if {$c <= 0} {
- $w.head configure -text [__ "No repositories"]
- return
- } elseif {$c == 1} {
- $w.head configure -text [__ "Repository"]
- } else {
- $w.head configure -text [__ "Multiple repositories"]
- }
- if {! $::have_remote} {
- $w.load configure -text " ([__ "Not loaded"])"
- }
- set repodict [dict create]
- if $::have_remote {
- run_cmd_waiting "repository status"
- set re {^(\S+) (\S+)/tlpkg/texlive.tlpdb (-?\d+) (.*)$}
- foreach l $::out_log {
- if [regexp $re $l dum nm rp n d] {
- # dummy tag repository verification_code description
- # restore spaces and percent characters in nm and rp
- set nm [string map {"%20" " "} $nm]
- set nm [string map {"%25" "%"} $nm]
- set rp [string map {"%20" " "} $rp]
- set rp [string map {"%25" "%"} $rp]
- dict set repodict $nm "url" $rp
- dict set repodict $nm "vericode" $n
- dict set repodict $nm "veridescr" $d
- }
- }
- }
- set rw 0
- foreach nm [array names ::repos] {
- incr rw
- pgrid [ttk::label $w.u$nm -text $::repos($nm) -justify left] \
- -sticky nw -row $rw -column 0
- if {$::repos($nm) eq $::any_mirror && $::have_remote} {
- set s $::repos($nm)
- append s "\n[__ "Actual repository"]:\n"
- append s [dict get $repodict $nm "url"]
- $w.u$nm configure -text $s
- }
- if {[array size ::repos] > 1 && $nm ne $::repos($nm)} {
- pgrid [ttk::label $w.n$nm -text "($nm)"] \
- -sticky nw -row $rw -column 1
- }
- if $::have_remote {
- pgrid [ttk::label $w.v$nm -text \
- "verification: [dict get $repodict $nm "veridescr"]"] \
- -sticky nw -row $rw -column 2
- }
- }
-} ; # show_repos
-
-proc repos_commit {} {
- set changes 0
- # set repositories then add pinning if appropriate
- set new_repo [forward_slashify [.tlr.new get]]
- if {! [regexp {^\s*$} $new_repo]} {
- # repository entry widget non-empty: use it
- if {$::repos(main) ne $new_repo} {
- set ::repos(main) $new_repo
- set changes 1
- }
- }
- set had_contrib 0
- if $::toggle_contrib {
- set changes 1
- foreach nm [array names ::repos] {
- if {$::repos($nm) eq $::tlcontrib} {
- set had_contrib 1
- run_cmds [list "pinning remove $nm --all" \
- "pinning remove $::repos($nm) --all"] 0
- vwait ::done_waiting
- array unset ::repos $nm
- }
- }
- if {! $had_contrib} {
- set ::repos(tlcontrib) $::tlcontrib
- }
- }
- if $changes {
- set_repos_in_tlmgr
- close_tlmgr
- start_tlmgr
- if {$::toggle_contrib && ! $had_contrib} {
- run_cmd_waiting "pinning add tlcontrib \"*\""
- }
- }
-} ; # repos_commit
-
-proc dis_enable_reposave {} {
- if [possible_repository [.tlr.new get]] {
- .tlr.save state !disabled
- } else {
- .tlr.save state disabled
- }
-}
-
-proc save_load_repo {} {
- repos_commit
- end_dlg "" .tlr
- # reload remote package information
- set ::have_remote 0
- get_packages_info_remote
- collect_and_display_filtered
-}
-
-proc select_mir {m} {
- .tlr.new delete 0 end; .tlr.new insert end $m
- .tlr.save state !disabled
-}
-
-# main repository dialog
-proc repository_dialog {} {
-
- # dialog with
- # - popup menu of mirrors (parse tlpkg/installer/ctan-mirrors.pl)
- # - text entry box
- # - directory browser button
- # - ok and cancel buttons
-
- create_dlg .tlr .
- wm title .tlr [__ "Main Repository"]
-
- # wallpaper frame; see populate_main
- pack [ttk::frame .tlr.bg] -expand 1 -fill x
-
- pack [ttk::frame .tlr.info] -in .tlr.bg -expand 1 -fill x
- grid columnconfigure .tlr.info 1 -weight 1
- set row -1
-
- # current repository
- incr row
- pgrid [ttk::label .tlr.lcur -text [__ "Current:"]] \
- -in .tlr.info -row $row -column 0 -sticky w
- pgrid [ttk::label .tlr.cur -text $::repos(main)] \
- -in .tlr.info -row 0 -column 1 -sticky w
- # proposed new repository
- incr row
- pgrid [ttk::label .tlr.lnew -text [__ "New"]] \
- -in .tlr.info -row $row -column 0 -sticky w
- pgrid [ttk::entry .tlr.new] \
- -in .tlr.info -row $row -column 1 -columnspan 2 -sticky ew
- .tlr.new insert 0 $::repos(main)
- bind .tlr.new <KeyRelease> dis_enable_reposave
-
- ### three ways to specify a repository ###
- pack [ttk::frame .tlr.mirbuttons] -in .tlr.bg -fill x
- # 1. default remote repository
- ttk::button .tlr.ctan -text [__ "Any CTAN mirror"] -command {
- .tlr.new delete 0 end
- .tlr.new insert end $::any_mirror
- .tlr.save state !disabled
- }
- ppack .tlr.ctan -in .tlr.mirbuttons -side left -fill x
- # 2. specific repository: create a cascading dropdown menu of mirrors
- mirror_menu .tlr.mir select_mir
- ppack .tlr.mir -in .tlr.mirbuttons -side left -fill x
- # 3. local repository
- ttk::button .tlr.browse -text [__ "Local directory..."] -command {
- .tlr.new delete 0 end; .tlr.new insert end [pick_local_repo]}
- ppack .tlr.browse -in .tlr.mirbuttons -side left -fill x
-
- ### add/remove tlcontrib ###
- ttk::label .tlr.contribt -text [__ "tlcontrib additional repository"] \
- -font bfont
- pack .tlr.contribt -in .tlr.bg -anchor w -padx 3pt -pady [list 10pt 3pt]
- pack [ttk::label .tlr.contribl] -in .tlr.bg -anchor w -padx 3pt -pady 3pt
- ttk::checkbutton .tlr.contribb -variable ::toggle_contrib
- pack .tlr.contribb -in .tlr.bg -anchor w -padx 3pt -pady [list 3pt 10pt]
- set ::toggle_contrib 0
- set has_contrib 0
- foreach nm [array names ::repos] {
- if {$::repos($nm) eq $::tlcontrib} {
- set has_contrib 1
- set contrib_tag $nm
- break
- }
- }
- if $has_contrib {
- .tlr.contribl configure -text [__ "tlcontrib repository is included"]
- .tlr.contribb configure -text [__ "Remove tlcontrib repository"]
- } else {
- .tlr.contribl configure -text [__ "tlcontrib repository is not included"]
- .tlr.contribb configure -text [__ "Add tlcontrib repository"]
- }
-
- # two ways to close the dialog
- pack [ttk::frame .tlr.closebuttons] -pady [list 10pt 0pt] -in .tlr.bg -fill x
- ttk::button .tlr.save -text [__ "Save and Load"] -command save_load_repo
- ppack .tlr.save -in .tlr.closebuttons -side right
- dis_enable_reposave
- ttk::button .tlr.cancel -text [__ "Cancel"] -command {end_dlg "" .tlr}
- ppack .tlr.cancel -in .tlr.closebuttons -side right
- bind .tlr <Escape> {.tlr.cancel invoke}
-
- wm protocol .tlr WM_DELETE_WINDOW \
- {cancel_or_destroy .tlr.cancel .tlr}
- wm resizable .tlr 1 0
- place_dlg .tlr .
-} ; # repository_dialog
-
-### platforms
-
-# ::platforms is a dictionary of dictionaries.
-# each element dictionary has keys cur and fut indicating
-# current and future status (i.e. being installed),
-# with values 0 meaning 'not installed' and 1 meaning 'installed'.
-# elsewhere, we shall only be interested in cur.
-# within the treeview list, we shall use the usual unicode mark symbols.
-
-# for windows, there is no platforms menu entry,
-# and the platforms dialog returns immediately, i.e. is a no-op.
-
-proc toggle_pl_marked {pl cl} {
- # toggle_pl_marked is triggered by a mouse click only in column #1.
- # 'fut'[ure] should get updated in ::platforms _and_ in .tlpl.pl.
-
- if {$cl ne "#1"} return
- if {$pl eq $::our_platform} {
- tk_messageBox -message \
- [__ "Cannot remove own platform %s" $::our_platform] -parent .tlpl
- return
- }
- set m1 [expr {[dict get $::platforms $pl "fut"] ? 0 : 1}]
- dict set ::platforms $pl "fut" $m1
- set m0 [dict get $::platforms $pl "cur"]
- if {$m1 eq $m0} {
- .tlpl.pl tag remove "changed" $pl
- } else {
- .tlpl.pl tag add "changed" $pl
- }
- .tlpl.pl set $pl "stat" [mark_sym $m1]
- # any changes to apply?
- .tlpl.do state disabled
- dict for {pname pdict} $::platforms {
- if {[dict get $pdict "fut"] ne [dict get $pdict "cur"]} {
- .tlpl.do state !disabled
- break
- }
- }
-} ; # toggle_pl_marked
-
-proc platforms_commit {} {
- set pl_add {}
- set pl_remove {}
- dict for {pname pdict} $::platforms {
- if {[dict get $pdict "cur"] ne [dict get $pdict "fut"]} {
- if {[dict get $pdict "fut"]} {
- lappend pl_add $pname
- } else {
- lappend pl_remove $pname
- }
- }
- }
- if {[llength $pl_add] == 0 && [llength $pl_remove] == 0} return
- set cmds {}
- if {[llength $pl_add] > 0} {
- set cmd "platform add "
- append cmd [join $pl_add " "]
- lappend cmds $cmd
- }
- if {[llength $pl_remove] > 0} {
- set cmd "platform remove "
- append cmd [join $pl_remove " "]
- lappend cmds $cmd
- }
- run_cmds $cmds 1
- vwait ::done_waiting
- update_local_revnumbers
- collect_and_display_filtered
-
-} ; # platforms_commit
-
-# the platforms dialog
-proc platforms_select {} {
- if {$::tcl_platform(platform) eq "windows"} return
-
- create_dlg .tlpl
- wm title .tlpl [__ "Platforms"]
- if $::plain_unix {wm attributes .tlpl -type dialog}
-
- # wallpaper frame
- pack [ttk::frame .tlpl.bg] -expand 1 -fill both
-
- # buttons
- pack [ttk::frame .tlpl.but] -in .tlpl.bg -side bottom -fill x
- ttk::button .tlpl.do -text [__ "Apply and close"] -command {
- disable_dlg .tlpl
- platforms_commit
- end_dlg "" .tlpl
- }
- ttk::button .tlpl.dont -text [__ "Close"] -command \
- {end_dlg "" .tlpl}
- ppack .tlpl.do -in .tlpl.but -side right
- ppack .tlpl.dont -in .tlpl.but -side left
- bind .tlpl <Escape> {.tlpl.dont invoke}
-
- pack [ttk::label .tlpl.bold -text [__ "Changed entries are bold"] \
- -font bfont] -in .tlpl.bg -side bottom
-
- # platforms treeview; do we need a scrollbar?
-
- pack [ttk::frame .tlpl.fpl] -in .tlpl.bg -fill both -expand 1
- ttk::treeview .tlpl.pl -columns {stat plat} -show headings \
- -height [dict size $::platforms] -yscrollcommand {.tlpl.plsb set}
- ppack .tlpl.pl -in .tlpl.fpl -side left -fill both -expand 1
- ttk::scrollbar .tlpl.plsb -orient vertical \
- -command {.tlpl.pl yview}
- ppack .tlpl.plsb -in .tlpl.fpl -side right -fill y -expand 1
- .tlpl.pl column stat -width [expr {$::cw * 3}]
- .tlpl.pl heading plat -text [__ "platform"] -anchor w
- .tlpl.pl column plat -width [expr {$::cw * 20}]
-
- # tag for indicating changed entries
- .tlpl.pl tag configure "changed" -font bfont
-
- dict for {pname pdict} $::platforms {
- dict set ::platforms $pname "fut" [dict get $pdict "cur"]
- }
- foreach pname [lsort [dict keys $::platforms]] {
- .tlpl.pl insert {} end -id $pname -values \
- [list [mark_sym [dict get $::platforms $pname "cur"]] $pname]
- }
-
- bind .tlpl.pl <space> {toggle_pl_marked [.tlpl.pl focus] "#1"}
- bind .tlpl.pl <Return> {toggle_pl_marked [.tlpl.pl focus] "#1"}
- # only toggle when column is #1
- bind .tlpl.pl <ButtonRelease-1> \
- {toggle_pl_marked \
- [.tlpl.pl identify item %x %y] \
- [.tlpl.pl identify column %x %y]}
-
- # enable commit button only if changes are requested
- .tlpl.do state disabled
- wm resizable .tlpl 0 1
- place_dlg .tlpl .
-} ; # platforms_select
-
-### paper sizes
-
-# for the simple options:
-proc set_all_papers {p} {
- run_cmd "paper paper $p" 1
-}
-
-# the next few procs are for the advanced paper selection dialog
-
-proc paper_diff {} {
- # check for different values and update widgets accordingly
- set n [lindex [array names ::papers] 0]
- set p $::papers($n)
- set ::allpapers $p
- set ::paperchanges 0
- .tlpap.do state disabled
- foreach nm [array names ::papers] {
- .tlpap.radios.$nm configure -font TkDefaultFont
- if {$::papers($nm) ne $p} {set ::allpapers ""}
- if {$::papers($nm) ne $::prevpapers($nm)} {
- .tlpap.radios.$nm configure -font bfont
- set ::paperchanges 1
- .tlpap.do state !disabled
- }
- }
-}
-
-proc allpapers_adv {} {
- # ::allpapers has already been set
- set ::paperchanges 0
- .tlpap.do state disabled
- foreach nm [array names ::papers] {
- set ::papers($nm) $::allpapers
- }
- paper_diff
-}
-
-proc commit_papers {} {
- foreach nm [array names ::papers] {
- if {$::papers($nm) ne $::prevpapers($nm)} {
- set cmd "paper $nm paper $::papers($nm)"
- if [catch {run_cmd_waiting $cmd} res] {
- puts "failed paper setting: $res"
- }
- }
- }
- # clean up no longer needed globals
- foreach nm [array names ::papers] {unset -nocomplain ::papers($nm)}
- foreach nm [array names ::prevpapers] {unset -nocomplain ::prevpapers($nm)}
- unset -nocomplain ::allpapers
- unset -nocomplain ::paperchanges
-}
-
-proc papersize_advanced {} {
- # dialog for settings papersize for:
- # all | pdftex | dvipdfmx | context | dvips | psutils | xdvi
- # on windows, xdvi is omitted
- # we also insert a non-existent engine to test handling of missing entries
- # we could have handled papers somewhat like the platforms dialog,
- # but radio buttons seem more natural,
- # and there are not enough items to worry about scrollability.
- # we create a grid with the radio buttons and a column 'changed'.
-
- set ::papers(dummy) "" ; # dummy: see comment above
- foreach nm {"pdftex" "dvipdfmx" "context" "dvips" "psutils" "xdvi"} {
- set ::papers($nm) ""
- }
- if {$::tcl_platform(platform) eq "windows"} {
- unset -nocomplain ::papers(xdvi)
- }
- foreach nm [array names ::papers] {
- if {[catch {run_cmd_waiting "paper $nm paper"} ::papers($nm)] ||
- ([llength $::err_log]<1)} {
- unset -nocomplain ::papers($nm)
- } else {
- set l [lindex $::err_log 0]
- set r [string last "): " $l]
- if {$r<0} {
- unset -nocomplain ::papers($nm)
- continue
- } else {
- set r [expr {$r+3}]
- set ::papers($nm) [string tolower [string range $l $r end]]
- }
- if {$::papers($nm) ne "a4" && $::papers($nm) ne "letter"} {
- set $::papers($nm) ""
- }
- }
- }
- set nms [array names ::papers] ; # invalid names have now been weeded out
- if {[llength $nms] < 1} {
- tk_messageBox -title [__ "Error"] -message [__ "No papersizes available"]
- # we did not yet start building the dialog, so we can just:
- return
- }
- set nm0 [lindex $nms 0]
- set ::allpapers $::papers($nm0)
- foreach nm $nms {
- set ::prevpapers($nm) $::papers($nm)
- if {$::papers($nm) ne $::allpapers} {set ::allpapers ""}
- }
- set ::paperchanges 0
-
- # build gui
- create_dlg .tlpap
- wm title .tlpap [__ "Paper sizes"]
- if $::plain_unix {wm attributes .tlpap -type dialog}
-
- # wallpaper frame
- pack [ttk::frame .tlpap.bg] -expand 1 -fill both
-
- # grid with radio buttons
- pack [ttk::frame .tlpap.radios] -in .tlpap.bg
-
- foreach {p c} {"a4" 1 "letter" 2} {
- pgrid [ttk::label .tlpap.radios.head$p -text $p -font bfont] \
- -row 0 -column $c
- }
- grid [ttk::separator .tlpap.radios.sep0 -orient horizontal] \
- -row 1 -column 0 -columnspan 3 -sticky ew
- pgrid [ttk::label .tlpap.radios.lall -text [__ "All"]] \
- -row 2 -column 0 -sticky e
- foreach {p c} {"a4" 1 "letter" 2} {
- pgrid [ttk::radiobutton .tlpap.radios.${p}all -value $p \
- -variable ::allpapers -command allpapers_adv] -row 2 -column $c
- }
- grid [ttk::separator .tlpap.radios.sep1 -orient horizontal] \
- -row 3 -column 0 -columnspan 3 -sticky ew
- set rw 3
- foreach nm $nms {
- incr rw
- pgrid [ttk::label .tlpap.radios.$nm -text $nm] \
- -row $rw -column 0 -sticky e
- foreach {p c} {"a4" 1 "letter" 2} {
- pgrid [ttk::radiobutton .tlpap.radios.$p$nm -value $p \
- -variable ::papers($nm) -command paper_diff] -row $rw -column $c
- }
- }
- incr rw
- grid [ttk::separator .tlpap.radios.sep2 -orient horizontal] \
- -row $rw -column 0 -columnspan 3 -sticky ew
-
- # buttons
- pack [ttk::frame .tlpap.but] -in .tlpap.bg -side bottom -fill x
- ttk::button .tlpap.do -text [__ "Apply and close"] -command {
- disable_dlg .tlpap
- commit_papers
- end_dlg "" .tlpap
- }
- ttk::button .tlpap.dont -text [__ "Close"] -command \
- {end_dlg "" .tlpap}
- ppack .tlpap.do -in .tlpap.but -side right
- ppack .tlpap.dont -in .tlpap.but -side right
- .tlpap.do state disabled
- bind .tlpap <Escape> {.tlpap.dont invoke}
-
- pack [ttk::label .tlpap.bold -text [__ "Changed entries are bold"] \
- -font bfont] -in .tlpap.bg -side bottom
-
- wm resizable .tlpap 0 0
- place_dlg .tlpap .
-}
-
-##### restore from backup #####
-
-# This is currently rather dangerous.
-# ::do_restore is set to 0 or 1 near the top of this source.
-# This code, currently disbled, has not been tested in a while.
-
-if $::do_restore {
-# dictionary of backups, with mapping to list of available revisions
-set bks {}
-
-proc enable_restore {y_n} {
- set st [expr {$y_n ? !disabled : disabled}]
- .tlbk.bklist state $st
- .tlbk.all state $st
- .tlbk.done state $st
-} ; # enable_restore
-
-proc finish_restore {} {
- vwait ::done_waiting
- # now log_widget_finish should have run and re-enabled its close button.
- # We won't wait for the log dialog to close, but we will
- # update the packages display in the main window.
- update_local_revnumbers
- collect_and_display_filtered
-} ; # finish_restore
-
-proc restore_all {} {
- run_cmd "restore --force --all" 1
- finish_restore
-} ; # restore_all
-
-proc restore_this {} {
- set id [.tlbk.bklist focus]
- if {$id eq {}} return
- set r [.tlbk.bklist set $id rev]
- if {$r eq {}} return
- set p [.tlbk.bklist set $id pkg]
- if {$p eq {}} {
- set id [.tlbk.bklist parent $id]
- if {$id ne {}} {set p [.tlbk.bklist set $id pkg]}
- }
- if {$p eq {}} return
- set ans [tk_messageBox -message [__ "Restore %s to revision %s?" $p $r] \
- -type okcancel -parent .tlbk]
- if {$ans ne {ok}} return
- run_cmd "restore --force $p $r" 1
- finish_restore
-} ; # restore_this
-
-proc bklist_callback_click {x y} {
- set cl [.tlbk.bklist identify column $x $y]
- if {$cl eq "#0"} return
- set id [.tlbk.bklist identify item $x $y]
- .tlbk.bklist focus $id
- restore_this
-} ; # bklist_callback_click
-
-proc restore_backups_dialog {} {
- run_cmd_waiting "option autobackup"
- set re {autobackup\t(.*)$}
- set abk 0
- foreach l $::out_log {
- if [regexp $re $l m abk] break
- }
- if {$abk == 0} {
- tk_messageBox -message [__ "No backups configured"]
- return
- }
- run_cmd_waiting "option backupdir"
- set re {backupdir\t(.*)$}
- set bdir ""
- foreach l $::out_log {
- if [regexp $re $l m bdir] break
- }
- if {$bdir eq ""} {
- tk_messageBox -message [__ "No backup directory defined"]
- return
- }
- set bdir [file join [exec kpsewhich -var-value SELFAUTOPARENT] $bdir]
- if {! [file isdirectory $bdir]} {
- tk_messageBox -message [__ "Backup directory %s does not exist" $bdir]
- return
- }
- set pwd0 [pwd]
- cd $bdir
- set backups [lsort [glob -nocomplain *.tar.xz]]
- if {[llength $backups] == 0} {
- tk_messageBox -message [__ "No backups found in $bdir"]
- return
- }
- # dictionary of backups; package => list of available revisions
- set ::bks [dict create]
- set re {^(.*)\.r(\d+)\.tar\.xz$}
- foreach b $backups {
- if [regexp $re $b m pk r] {
- if {$pk in [dict keys $::bks]} {
- dict lappend ::bks $pk $r
- } else {
- dict set ::bks $pk [list $r]
- }
- }
- }
- if {[llength [dict keys $::bks]] == 0} {
- tk_messageBox -message [__ "No packages in backup directory %s" $bdir]
- return
- }
- # invert sort order of revisions for each package
- foreach pk [dict keys $::bks] {
- dict set ::bks $pk [lsort -decreasing [dict get $::bks $pk]]
- }
- toplevel .tlbk -class Dialog
- wm withdraw .tlbk
- wm transient .tlbk .
- wm title .tlbk [__ "Restore from backup"]
- if $::plain_unix {wm attributes .tlbk -type dialog}
-
- # wallpaper frame; see populate_main
- pack [ttk::frame .tlbk.bg] -expand 1 -fill x
-
- # the displayed list of backed-up packages
- pack [ttk::frame .tlbk.fbk] -in .tlbk.bg -side top
- # package names not in #0, because we want to trigger actions
- # without automatically opening a parent.
- pack [ttk::treeview .tlbk.bklist -columns {"pkg" "rev"} \
- -show {tree headings} -height 8 -selectmode browse \
- -yscrollcommand {.tlbk.bkvsb set}] -in .tlbk.fbk -side left
- pack [ttk::scrollbar .tlbk.bkvsb -orient vertical -command \
- {.tlbk.bklist yview}] -in .tlbk.fbk -side right -fill y
-
- .tlbk.bklist heading "pkg" -text [__ "Package"] -anchor w
- .tlbk.bklist heading "rev" -text [__ "Revision"] -anchor w
-
- .tlbk.bklist column "#0" -width [expr {$::cw * 2}]
- .tlbk.bklist column "pkg" -width [expr {$::cw * 25}]
- .tlbk.bklist column "rev" -width [expr {$::cw * 12}]
-
- # fill .tlbk.bklist. Use the last available revision.
- # Remember that $::bks is sorted and revisions inversely sorted
- # id must be unique in the entire list: rev does not qualify
- # must as well use $id for package items too
- set id 0
- dict for {pk rlist} $::bks {
- # package
- .tlbk.bklist insert {} end -id [incr id] \
- -values [list $pk [lindex $rlist 0]] -open 0
- set l [llength $rlist]
- # additional revisions
- if {$l > 1} {
- set idparent $id
- for {set i 1} {$i<$l} {incr i} {
- .tlbk.bklist insert $idparent end -id [incr id] \
- -values [list "" [lindex $rlist $i]]
- }
- }
- }
-
- # since we can only restore one non-last revision at a time, it is better
- # to only show one non-last revision at a time too.
- bind .tlbk.bklist <<TreeviewOpen>> {
- foreach p [.tlbk.bklist children {}] {
- if {$p ne [.tlbk.bklist focus]} {
- .tlbk.bklist item $p -open 0
- }
- }
- }
- # restoring a single package
- bind .tlbk.bklist <<RightClick>> {bklist_callback_click %x %y}
- bind .tlbk.bklist <space> restore_this
-
- # frame with buttons
- pack [ttk::frame .tlbk.fbut] -in .tlbk.bg -side bottom -fill x
- ppack [ttk::button .tlbk.all -text [__ "Restore all"] -command restore_all] \
- -in .tlbk.fbut -side right
- ppack [ttk::button .tlbk.done -text [__ "Close"] -command {
- end_dlg "" .tlbk}] -in .tlbk.fbut -side right
-
- place_dlg .tlbk .
- wm resizable .tlbk 0 0
- tkwait .tlbk
-} ; # restore_backups_dialog
-
-} ; # if $::do_restore
-
-##### Main window and supporting procs and callbacks ##################
-
-##### package-related #####
-
-### updating
-
-proc update_tlmgr_w32 {} {
- close_tlmgr
- # don't try pipes or capturing, because of
- # tlmgr's acrobatics with nested command prompts
- wm iconify .
- exec -ignorestderr cmd /k "start cmd /k tlmgr update --self"
- exec $::progname &
- destroy .
-}
-
-proc update_tlmgr {} {
- if {! $::need_update_tlmgr} {
- tk_messageBox -message [__ "Nothing to do!"]
- return
- }
- if {$::tcl_platform(platform) eq "windows"} {
- update_tlmgr_w32
- return
- }
- run_cmd "update --self" 1
- vwait ::done_waiting
- # tlmgr restarts itself automatically
- update_local_revnumbers
- .topfr.linfra configure -text \
- "tlmgr: r[dict get $::pkgs texlive.infra localrev]"
- collect_and_display_filtered
-} ; # update_tlmgr
-
-proc update_all {} {
- set updated_tlmgr 0
- if $::need_update_tlmgr {
- if {$::tcl_platform(platform) eq "windows"} {
- return ; # just to be sure; 'update all' button should be disabled
- }
- run_cmd "update --self" 1
- vwait ::done_waiting
- # tlmgr restarts itself automatically
- update_local_revnumbers
- set updated_tlmgr 1
- }
- # tlmgr restarts itself automatically
- # tk_messageBox -message [__ "Update self first!"]
- # return
- if {! $::n_updates && !$updated_tlmgr} {
- tk_messageBox -message [__ "Nothing to do!"]
- return
- } elseif $::n_updates {
- run_cmd "update --all" 1
- vwait ::done_waiting
- update_local_revnumbers
- }
- collect_and_display_filtered
-} ; # update_all
-
-### doing something with some packages
-
-proc pkglist_from_option {opt {pk ""}} {
- if {$opt eq "marked"} {
- set pks {}
- dict for {p props} $::pkgs {
- if [dict get $props "marked"] {lappend pks $p}
- }
- } elseif {$opt eq "focus"} {
- set p [.pkglist focus]
- if {$p ne {}} {lappend pks $p}
- } elseif {$opt eq "name"} {
- lappend pks $pk
- }
- return $pks
-} ; # pkglist_from_option
-
-proc install_pkgs {sel_opt {pk ""}} {
- set pks [pkglist_from_option $sel_opt $pk]
- # check whether packages are installed
- set pre_installed {}
- set todo {}
- foreach p $pks {
- if {[dict get $::pkgs $p localrev] > 0} {
- lappend pre_installed $p
- } else {
- lappend todo $p
- }
- }
- if {[llength $todo] == 0} {
- tk_messageBox -message [__ "Nothing to do!"] -type ok -icon info
- return
- }
- run_cmd_waiting "install --dry-run $todo"
- # check whether dependencies are going to be installed
- set r {^(\S+)\s+i\s}
- set deps {}
- foreach l $::out_log {
- if {[regexp $r $l d p] && $p ni $pks} {
- lappend deps $p
- }
- }
- if {[llength $deps] > 0} {
- set ans \
- [any_message \
- [__ "Also installing dependencies\n\n%s" $deps] \
- "okcancel"]
- if {$ans eq "cancel"} return
- }
- run_cmd "install $todo" 1
- vwait ::done_waiting
- if {[llength $pre_installed] > 0} {
- lappend ::err_log [__ "Already installed: %s" $pre_installed]
- show_err_log
- }
- update_local_revnumbers
- if {$sel_opt eq "marked"} unmark_all
- collect_and_display_filtered
-} ; # install_pkgs
-
-proc update_pkgs {sel_opt {pk ""}} {
- set pks [pkglist_from_option $sel_opt $pk]
- # check whether packages are installed
- set not_inst {}
- set uptodate {}
- set todo {}
- foreach p $pks {
- set lv [dict get $::pkgs $p localrev]
- if {[dict get $::pkgs $p localrev] == 0} {
- lappend not_inst $p
- } else {
- set rv [dict get $::pkgs $p remoterev]
- if {$lv >= $rv} {
- lappend uptodate $p
- } else {
- lappend todo $p
- }
- }
- }
- if {[llength $todo] == 0} {
- tk_messageBox -message [__ "Nothing to do!"] -type ok -icon info
- return
- }
- run_cmd_waiting "update --dry-run $todo"
- # check whether dependencies are going to be updated
- set r {^(\S+)\s+u\s}
- set deps {}
- foreach l $::out_log {
- if {[regexp $r $l d p] && $p ni $pks} {
- lappend deps $p
- }
- }
- if {[llength $deps] > 0} {
- set ans [any_message [__ "Also updating dependencies\n\n%s?" $deps] \
- "yesnocancel"]
- switch $ans {
- "cancel" return
- "yes" {run_cmd "update $todo" 1}
- "no" {
- set deps {}
- run_cmd_waiting "update --dry-run --no-depends $todo"
- foreach l $::out_log {
- if {[regexp $r $l u p] && $p ni $pks} {
- lappend deps $p
- }
- }
- if {[llength $deps] > 0} {
- set ans [any_message \
- [__ "Updating some dependencies %s anyway. Continue?" $deps] \
- "okcancel"]
- if {$ans eq "cancel"} return
- }
- run_cmd "update --no-depends $todo" 1
- }
- }
- } else {
- run_cmd "update $todo" 1
- }
- vwait ::done_waiting
- if {[llength $not_inst] > 0} {
- lappend ::err_log [__ "Skipped because not installed: %s" $not_inst]
- }
- if {[llength $uptodate] > 0} {
- lappend ::err_log [__ "Skipped because already up to date: %s" $uptodate]
- }
- if {[llength $not_inst] > 0 || [llength $uptodate] > 0} {
- show_err_log
- }
- update_local_revnumbers
- if {$sel_opt eq "marked"} unmark_all
- collect_and_display_filtered
-} ; # update_pkgs
-
-proc remove_pkgs {sel_opt {pk ""}} {
- set pks [pkglist_from_option $sel_opt $pk]
- # check whether packages are installed
- set not_inst {}
- set todo {}
- foreach p $pks {
- if {[dict get $::pkgs $p localrev] > 0} {
- lappend todo $p
- } else {
- lappend not_inst $p
- }
- }
- run_cmd_waiting "remove --dry-run $todo"
- # check whether dependencies are going to be removed
- set r {^(\S+)\s+d\s}
- set deps {}
- foreach l $::out_log {
- if {[regexp $r $l d p] && $p ni $pks} {
- lappend deps $p
- }
- }
- if {[llength $todo] == 0} {
- tk_messageBox -message [__ "Nothing to do!"] -type ok -icon info
- return
- }
- if {[llength $deps] > 0} {
- set ans [any_message [__ "Also remove dependencies\n\n%s?" $deps] \
- "yesnocancel"]
- switch $ans {
- "cancel" return
- "yes" {run_cmd "remove $todo" 1}
- "no" {
- set deps {}
- run_cmd_waiting "remove --dry-run --no-depends $todo"
- foreach l $::out_log {
- if {[regexp $r $l d p] && $p ni $pks} {
- lappend deps $p
- }
- }
- if {[llength $deps] > 0} {
- set ans [any_message \
- [__ "Removing some dependencies %s anyway. Continue?" $deps] \
- "okcancel"]
- if {$ans eq "cancel"} return
- }
- run_cmd "remove --no-depends $todo" 1
- }
- }
- } else {
- run_cmd "remove $todo" 1
- }
- vwait ::done_waiting
- if {[llength $not_inst] > 0} {
- lappend ::err_log "Skipped because not installed: $not_inst"
- show_err_log
- }
- update_local_revnumbers
- if {$sel_opt eq "marked"} unmark_all
- collect_and_display_filtered
-} ; # remove_pkgs
-
-# restoring packages is a rather different story, controlled by the
-# contents of the backup directory. see further up.
-
-##### varous callbacks #####
-
-proc restart_self {} {
- do_debug "trying to restart"
- if {$::progname eq ""} {
- tk_messageBox -message "progname not found; not restarting"
- return
- }
- close_tlmgr
- exec $::progname &
- # on windows, it may take several seconds before
- # the old tlshell disappears.
- # oh well, windows is still windows....
- destroy .
-} ; # restart_self
-
-proc toggle_marked_pkg {itm cl} {
- # toggle_marked_pkg is triggered by a mouse click only in column #1.
- # 'marked' should get updated in ::pkgs, ::filtered and in .pkglist.
-
- if {$cl ne "#1"} return
- # clicking in the header:
- if {$itm eq ""} return
- # $mrk: negation of current value of marked for $itm
- set mrk [expr {[dict get $::pkgs $itm "marked"] ? 0 : 1}]
- dict set ::pkgs $itm "marked" $mrk
- set m [mark_sym $mrk]
- dict set ::filtered $itm [lreplace [dict get $::filtered $itm] 0 0 $m]
- .pkglist set $itm mk $m
-} ; # toggle_marked_pkg
-
-proc unmark_all {} {
- foreach nm [dict keys $::pkgs] {
- dict set ::pkgs $nm "marked" 0
- }
- set m [mark_sym 0]
- foreach nm [dict keys $::filtered] {
- dict set ::filtered $nm [lreplace [dict get $::filtered $nm] 0 0 $m]
- }
- foreach nm [.pkglist children {}] {
- .pkglist set $nm mk $m
- }
-} ; # unmark_all
-
-proc mark_displayed {} {
- set m [mark_sym 1]
- foreach nm [.pkglist children {}] {
- dict set ::pkgs $nm "marked" 1
- dict set ::filtered $nm [lreplace [dict get $::filtered $nm] 0 0 $m]
- .pkglist set $nm mk $m
- }
-} ; # mark_displayed
-
-##### package popup #####
-
-proc do_package_popup_menu {x y X Y} {
- # as focused item, the identity of the clicked item will be
- # globally available:
- .pkglist focus [.pkglist identify item $x $y]
- # recreate menu with only applicable items
- set lr [dict get $::pkgs [.pkglist focus] "localrev"]
- set rr [dict get $::pkgs [.pkglist focus] "remoterev"]
- .pkg_popup delete 0 end
-
- .pkg_popup add command -label [__ "Info"] -command {
- run_cmd "info [.pkglist focus]" 1; vwait ::done_waiting
- }
- if {$::have_remote && ! $::need_update_tlmgr && $rr > 0 && $lr == 0} {
- .pkg_popup add command -label [__ "Install"] -command {
- install_pkgs "focus"
- }
- }
- if {$::have_remote && ! $::need_update_tlmgr && $lr > 0 && $rr > $lr} {
- .pkg_popup add command -label [__ "Update"] -command {
- update_pkgs "focus"
- }
- }
- if {$lr > 0} {
- .pkg_popup add command -label [__ "Remove"] -command {
- remove_pkgs "focus"
- }
- }
- .pkg_popup post [expr {$X - 2}] [expr {$Y - 2}]
- focus .pkg_popup
-} ; # do_package_popup_menu
-
-#### gui options ####
-
-proc set_language {l} {
- set ::lang $l
- load_translations
- rebuild_interface
- if {! [save_config_var "gui-lang" $::lang]} {
- tk_messageBox -message [__"Cannot save language setting"]
- }
-}
-
-proc set_fontscale {s} {
- set ::tkfontscale $s
- redo_fonts
- rebuild_interface
- if {[dict get $::pkgs texlive.infra localrev] >= 54766} {
- if {! [save_config_var "tkfontscale" $::tkfontscale]} {
- tk_messageBox -message [__"Cannot save font scale setting"]
- }
- }
-}
-
-proc zoom {n} {
- if {$n <= 0} {set n 1}
- set_fontscale [expr {$n*$::tkfontscale}]
-}
-
-##### running external commands #####
-
-# For capturing an external command, we need a separate output channel,
-# but we reuse ::out_log.
-# stderr is bundled with stdout so ::err_log should stay empty.
-proc read_capture {} {
- set l "" ; # will contain the line to be read
- if {([catch {chan gets $::capt l} len] || [chan eof $::capt])} {
- catch {chan close $::capt}
- log_widget_finish
- set ::done_waiting 1
- } elseif {$len >= 0} {
- lappend ::out_log $l
- log_widget_add $l
- }
-}; # read_capture
-
-proc run_external {cmd mess} {
- set ::out_log {}
- set ::err_log {}
- lappend ::out_log $mess
- unset -nocomplain ::done_waiting
- # treat cmd as a list, possibly of one element
- # using a list enables a direct invocation, bypassing a shell
- set cmd0 [lindex $cmd 0]
- set cmd [lreplace $cmd 0 0 "|$cmd0"]
- set cmd [list {*}$cmd 2>@1]
- if [catch {open $cmd r} ::capt] {
- tk_messageBox -message "Failure to launch $cmd"
- }
- chan configure $::capt -buffering line -blocking 0
- chan event $::capt readable read_capture
- log_widget_init
-}
-
-proc about_cmd {} {
- set msg "\u00a9 2017-2020 Siep Kroonenberg\n\n"
- append msg [__ "GUI interface for TeX Live Manager\nImplemented in Tcl/Tk"]
- tk_messageBox -message $msg
-}
-
-proc show_help {} {
- set ::env(NOPERLDOC) 1
- long_message [exec tlmgr --help] ok
-}
-
-## arbitrary commands: no way to know what data have to be updated
-#proc custom_command {} {
-# create_dlg .tlcust .
-# wm title .tlcust [__ "Custom command"]
-# pack [ttk::frame .tlcust.bg] -expand 1 -fill x
-#
-# ppack [ttk::entry .tlcust.e] \
-# -in .tlcust.bg -side left -fill x -expand 1
-# ppack [ttk::button .tlcust.b -text [__ "Go"] -command run_entry] \
-# -in .tlcust.bg -side left
-# bind .tlcust.e <Return> run_entry
-# bind .tlcust <Escape> {end_dlg "" .tlcust}
-# wm .tlcust resizable 1 0
-# place_dlg .tlcust .
-#}
-
-##### main window #####
-
-proc try_loading_remote {} {
- if {[possible_repository $::repos(main)]} {
- get_packages_info_remote
- collect_and_display_filtered
- } else {
- set mes [__ "%s is not a local or remote repository.
-Please configure a valid repository" $::repos(main)]
- append mes "\n([__ "Options"] \/ [__ "Repositories"] ...)"
- tk_messageBox -message $mes -title [__ "Error"] -type ok -icon error
- }
-}
-
-proc populate_main {} {
-
- wm withdraw .
-
- wm title . "TeX Live Shell"
-
- ## menu ##
-
- # dummy empty menu to replace the real menu .mn in disabled states.
- # the "File" cascade should ensure that the dummy menu
- # occupies the same vertical space as the real menu.
- menu .mn_empty
- .mn_empty add cascade -label [__ "File"] -menu .mn_empty.file -underline 0
- if $::plain_unix {
- .mn_empty configure -borderwidth 0
- .mn_empty configure -background $::default_bg
- menu .mn_empty.file
- }
- # real menu
- menu .mn
- . configure -menu .mn
- if $::plain_unix {
- .mn configure -borderwidth 0
- .mn configure -background $::default_bg
-
- # plain_unix: avoid a possible RenderBadPicture error on quitting
- # when there is a menu.
- # 'send' bypasses the bug by changing the shutdown sequence.
- # 'tk appname <something>' restores 'send'.
- bind . <Destroy> {
- catch {tk appname appname}
- }
- }
-
- # inx: keeping count to record submenu indices where needed,
- # i.e. when an entry needs to be referenced.
- # not all submenus need this.
-
- .mn add cascade -label [__ "File"] -menu .mn.file -underline 0
- menu .mn.file
- .mn.file add command -label [__ "Load repository"] \
- -command try_loading_remote
- .mn.file add command -command {destroy .} -label [__ "Exit"] -underline 1
-
- .mn add cascade -label [__ "Actions"] -menu .mn.act -underline 0
- menu .mn.act
- set inx -1
- incr inx
- .mn.act add command -label [__ "Regenerate filename database"] -command \
- {run_external "mktexlsr" [__ "Regenerating filename database..."]}
- .mn.act add command -label [__ "Regenerate formats"] -command \
- {run_external "fmtutil-sys --all" [__ "Rebuilding formats..."]}
- .mn.act add command -label [__ "Regenerate fontmaps"] -command \
- {run_external "updmap-sys" [__ "Rebuilding fontmap files..."]}
- #.mn.act add command -label [__ "Custom command"] -command custom_command
-
- .mn add cascade -label [__ "Options"] -menu .mn.opt -underline 0
-
- menu .mn.opt
- set inx -1
- incr inx
- .mn.opt add command -label "[__ "Repositories"] ..." \
- -command repository_dialog
-
- incr inx
- .mn.opt add cascade -label [__ "Paper ..."] -menu .mn.opt.paper
- incr inx
- menu .mn.opt.paper
- foreach p {a4 letter} {
- .mn.opt.paper add command -label $p -command \
- "set_all_papers [string tolower $p]"
- }
- .mn.opt.paper add command -label "[__ "Advanced"] ..." \
- -command papersize_advanced
-
-
- if {$::tcl_platform(platform) ne "windows"} {
- incr inx
- set ::inx_platforms $inx
- .mn.opt add command -label "[__ "Platforms"] ..." -command platforms_select
- }
-
- if {[llength $::langs] > 1} {
- .mn add cascade -label [__ "GUI language"] \
- -menu .mn.lang
- menu .mn.lang
- foreach l [lsort $::langs] {
- if {$l eq $::lang} {
- set mlabel "$l *"
- } else {
- set mlabel $l
- }
- .mn.lang add command -label $mlabel \
- -command "set_language $l"
- }
- }
-
- .mn add cascade -label [__ "GUI font scaling"] \
- -menu .mn.fscale
- menu .mn.fscale
- .mn.fscale add command -label \
- "[__ "Current:"] [format {%.2f} $::tkfontscale]"
- foreach s {0.6 0.8 1 1.2 1.6 2 2.5 3 3.8 5 6 7.5 9} {
- .mn.fscale add command -label $s -command "set_fontscale $s"
- }
-
- # browser-style keyboard shortcuts for scaling
- bind . <Control-KeyRelease-minus> {zoom 0.8}
- bind . <Control-KeyRelease-equal> {zoom 1.25}
- bind . <Control-Shift-KeyRelease-equal> {zoom 1.25}
- bind . <Control-KeyRelease-plus> {zoom 1.25}
- bind . <Control-KeyRelease-0> {set_fontscale 1}
- if {$::tcl_platform(os) eq "Darwin"} {
- bind . <Command-KeyRelease-minus> {zoom 0.8}
- bind . <Command-KeyRelease-equal> {zoom 1.25}
- bind . <Command-Shift-KeyRelease-equal> {zoom 1.25}
- bind . <Command-KeyRelease-plus> {zoom 1.25}
- bind . <Command-KeyRelease-0> {set_fontscale 1}
- }
-
- .mn add cascade -label [__ "Help"] -menu .mn.help -underline 0
- menu .mn.help
- .mn.help add command -label [__ "About"] -command about_cmd
- .mn.help add command -label [__ "tlmgr help"] -command show_help
-
- ## menu end
-
- # wallpaper frame
- # it is possible to set a background color for a toplevel, but on
- # MacOS I did not find a way to determine the right $::default_bg
- # color. Instead, all toplevels are given a wallpaper ttk::frame
- # with the default ttk::frame color, which seems to work
- # everywhere.
- pack [ttk::frame .bg] -expand 1 -fill both
- .bg configure -padding 5pt
-
- # bottom of main window
- pack [ttk::frame .endbuttons] -in .bg -side bottom -fill x
- ttk::label .busy -textvariable ::busy -font hfont -anchor w
- ppack .busy -in .endbuttons -side left
- ppack [ttk::button .q -text [__ Quit] -command {destroy .}] \
- -in .endbuttons -side right
- ppack [ttk::button .r -text [__ "Restart self"] -command restart_self] \
- -in .endbuttons -side right
- ppack [ttk::button .t -text [__ "Restart tlmgr"] \
- -command {close_tlmgr; start_tlmgr}] \
- -in .endbuttons -side right
- ttk::button .showlogs -text [__ "Show logs"] -command show_logs
- ppack .showlogs -in .endbuttons -side right
-
- # top of main window
- ppack [ttk::frame .topf] -in .bg -side top -anchor w -fill x
-
- if $::ddebug {
- ppack [ttk::label .topf.test -text [info nameofexecutable]]
- ppack [ttk::label .topf.test2 -text $::progname]
- ppack [ttk::label .topf.test3 -text \
- [string range $::env(PATH) 0 59]]
- }
-
- # left info frame
- pack [ttk::frame .topfl] -in .topf -side left -anchor nw
-
- # subframe for repositories, to be filled by show_repos
- pack [ttk::frame .toprepo] -in .topfl -side top -anchor w
-
- # various info (left frame)
- pack [ttk::frame .topfll] -in .topfl -side top -anchor nw -pady {6pt 0pt}
- ttk::label .topfll.lluptodate -text [__ "TL Manager up to date?"] -anchor w
- pgrid .topfll.lluptodate -row 2 -column 0 -sticky w
- ttk::label .topfll.luptodate -text [__ "Unknown"] -anchor w
- pgrid .topfll.luptodate -row 2 -column 1 -sticky w
-
- ttk::label .topfll.llcmd -text [__ "Last tlmgr command:"] -anchor w
-
- pgrid .topfll.llcmd -row 3 -column 0 -sticky w
- ttk::label .topfll.lcmd -textvariable ::last_cmd \
- -wraplength [expr {60*$::cw}] -justify left -anchor w
- pgrid .topfll.lcmd -row 3 -column 1 -sticky w
-
- # right info frame
- ppack [ttk::frame .topfr] -in .topf -side right -anchor ne
- if {$::tcl_platform(platform) eq "windows"} {
- pack [ttk::label .topfr.ladmin] -side top -anchor e
- }
- pack [ttk::label .topfr.lroot] -side top -anchor e
- .topfr.lroot configure -text [__ "Root at %s" $::instroot]
- pack [ttk::label .topfr.linfra] -side top -anchor e
- pack [ttk::label .topfr.lshell] -side top -anchor e
-
- pack [ttk::separator .sp -orient horizontal] \
- -in .bg -side top -fill x -pady 3pt
-
- # controls frame, between info frame and package list
- pack [ttk::frame .middle] -in .bg -side top -fill x
- pack [ttk::frame .pkcontrol] \
- -in .middle -side left -anchor nw -fill x
-
- # package list display options
- ttk::label .lpack -text [string toupper [__ "Package list"]] \
- -font hfont
- pack .lpack -in .pkcontrol -side top -padx 3pt -pady {6pt 6pt} -anchor w
-
- pack [ttk::frame .pkfilter -relief groove -borderwidth 2 -padding 3pt] \
- -in .pkcontrol -side top -anchor nw
- # on my current linux, groove works only with a dimensionless borderwidth
-
- # separator columns
- grid columnconfigure .pkfilter 1 -minsize 20pt
- grid [ttk::separator .pkfilter.sep1 -orient vertical] \
- -column 1 -row 0 -rowspan 5 -sticky ns
- grid columnconfigure .pkfilter 3 -minsize 20pt
- grid [ttk::separator .pkfilter.sep3 -orient vertical] \
- -column 3 -row 0 -rowspan 5 -sticky ns
-
- # filter on status: inst, all, upd
- ttk::label .pkfilter.lstat -font bfont -text [__ "Status"]
- ttk::radiobutton .pkfilter.inst -text [__ "Installed"] -value inst \
- -variable ::stat_opt -command collect_and_display_filtered
- ttk::radiobutton .pkfilter.notins -text [__ "Not installed"] -value notins \
- -variable ::stat_opt -command {
- if {! $::have_remote} get_packages_info_remote
- collect_and_display_filtered
- }
- ttk::radiobutton .pkfilter.alls -text [__ "All"] -value all \
- -variable ::stat_opt -command {
- if {! $::have_remote} get_packages_info_remote
- collect_and_display_filtered
- }
- ttk::radiobutton .pkfilter.upd -text [__ "Updatable"] -value upd \
- -variable ::stat_opt -command {
- if {! $::have_remote} get_packages_info_remote
- collect_and_display_filtered
- }
- grid .pkfilter.lstat -column 0 -row 0 -sticky w -padx {3pt 50pt}
- pgrid .pkfilter.inst -column 0 -row 1 -sticky w
- pgrid .pkfilter.notins -column 0 -row 2 -sticky w
- pgrid .pkfilter.alls -column 0 -row 3 -sticky w
- pgrid .pkfilter.upd -column 0 -row 4 -sticky w
-
- # filter on detail level: all, coll, schm
- ttk::label .pkfilter.ldtl -font bfont -text [__ "Detail >> Global"]
- ttk::radiobutton .pkfilter.alld -text [__ All] -value all \
- -variable ::dtl_opt -command collect_and_display_filtered
- ttk::radiobutton .pkfilter.coll -text [__ "Collections and schemes"] \
- -value coll -variable ::dtl_opt -command collect_and_display_filtered
- ttk::radiobutton .pkfilter.schm -text [__ "Only schemes"] -value schm \
- -variable ::dtl_opt -command collect_and_display_filtered
- pgrid .pkfilter.ldtl -column 2 -row 0 -sticky w
- pgrid .pkfilter.alld -column 2 -row 1 -sticky w
- pgrid .pkfilter.coll -column 2 -row 2 -sticky w
- pgrid .pkfilter.schm -column 2 -row 3 -sticky w
-
- # search interface
- ttk::label .pkfilter.search_l -font bfont -text [__ "Search"]
- ttk::entry .pkfilter.search_e -width 30
- ttk::radiobutton .pkfilter.search_n -variable ::search_desc \
- -value 0 -text [__ "By name"]
- ttk::radiobutton .pkfilter.search_d -variable ::search_desc \
- -value 1 -text [__ "By name and description"]
- pgrid .pkfilter.search_l -column 4 -row 0 -sticky w
- pgrid .pkfilter.search_e -column 4 -row 1 -sticky w
- pgrid .pkfilter.search_n -column 4 -row 2 -sticky w
- pgrid .pkfilter.search_d -column 4 -row 3 -sticky w
-
- bind .pkfilter.search_e <KeyRelease> display_packages_info
- bind .pkfilter.search_n <ButtonRelease> \
- {set ::search_desc 0; display_packages_info}
- bind .pkfilter.search_d <ButtonRelease> \
- {set ::search_desc 1; display_packages_info}
-
- # actions
- pack [ttk::frame .pkact] -in .middle -side right -anchor ne
- ttk::button .mrk_inst -text [__ "Install marked"] -command {
- install_pkgs "marked"}
- ppack .mrk_inst -in .pkact -side top -fill x
- ttk::button .mrk_upd -text [__ "Update marked"] -command {
- update_pkgs "marked"}
- ppack .mrk_upd -in .pkact -side top -fill x
- ttk::button .mrk_rem -text [__ "Remove marked"] -command {
- remove_pkgs "marked"}
- ppack .mrk_rem -in .pkact -side top -fill x
- if $::do_restore {
- ttk::button .mrk_rest -text "[__ "Restore from backup"] ..." -command \
- restore_backups_dialog
- ppack .mrk_rest -in .pkact -side top -fill x
- }
- ttk::button .upd_tlmgr -text [__ "Update tlmgr"] -command update_tlmgr
- ppack .upd_tlmgr -in .pkact -side top -fill x
- ttk::button .upd_all -text [__ "Update all"] -command update_all
- ppack .upd_all -in .pkact -side top -fill x
-
- # marking all/none
- pack [ttk::frame .pksel] \
- -in .bg -pady 6pt -side top -fill x
- pack [ttk::button .mrk_all -text [__ "Mark all displayed"] \
- -command mark_displayed] -in .pksel -side left
- pack [ttk::button .mrk_none -text [__ "Mark none"] -command unmark_all] \
- -in .pksel -padx 6pt -side left
- ttk::label .binwarn \
- -text [__ "Only packages for installed platforms are displayed"]
- pack .binwarn -in .pksel -padx 3pt -side right -anchor s
-
- # packages list itself
- pack [ttk::frame .fpkg] -in .bg -side top -fill both -expand 1
- ttk::treeview .pkglist -columns \
- {mk name localrev remoterev shortdesc} \
- -show headings -height 8 -selectmode extended \
- -yscrollcommand {.pkvsb set}
- .pkglist heading mk -text "" -anchor w
- .pkglist heading name -text [__ "Name"] -anchor w
- .pkglist heading localrev -text [__ "Local rev. (ver.)"] -anchor w
- .pkglist heading remoterev -text [__ "Remote rev. (ver.)"] -anchor w
- .pkglist heading shortdesc -text [__ "Description"] -anchor w
- .pkglist column mk -width [expr {$::cw * 3}] -stretch 0
- .pkglist column name -width [expr {$::cw * 25}] -stretch 1
- .pkglist column localrev -width [expr {$::cw * 18}] -stretch 0
- .pkglist column remoterev -width [expr {$::cw * 18}] -stretch 0
- .pkglist column shortdesc -width [expr {$::cw * 50}] -stretch 1
-
- ttk::scrollbar .pkvsb -orient vertical -command {.pkglist yview}
- ppack .pkglist -in .fpkg -side left -expand 1 -fill both
- ppack .pkvsb -in .fpkg -side left -fill y
-
- # "#1" refers to the first column (with mark symbols)
- bind .pkglist <space> {toggle_marked_pkg [.pkglist focus] "#1"}
- bind .pkglist <Return> {toggle_marked_pkg [.pkglist focus] "#1"}
- # only toggle when column is "mk" i.e. #1
- bind .pkglist <ButtonRelease-1> {toggle_marked_pkg [
- .pkglist identify item %x %y] [.pkglist identify column %x %y]}
-
- menu .pkg_popup ; # entries added on-the-fly
- bind .pkglist <<RightClick>> {do_package_popup_menu %x %y %X %Y}
- if $::plain_unix {
- bind .pkg_popup <Leave> {.pkg_popup unpost}
- }
-
- wm protocol . WM_DELETE_WINDOW {cancel_or_destroy .q .}
- wm resizable . 1 1
- wm state . normal
- raise .
-}
-
-proc display_all_data {} {
- # (re)display all data
- if {$::tcl_platform(platform) eq "windows"} {
- .topfr.ladmin configure -text \
- [expr {$::multiuser ? [__ "Multi-user"] : [__ "Single-user"]}]
- }
- # revision numbers for tlmgr and tlshell
- .topfr.linfra configure -text \
- "tlmgr: r[dict get $::pkgs texlive.infra localrev]"
- .topfr.lshell configure -text \
- "tlshell: r[dict get $::pkgs tlshell localrev]"
- show_repos
- display_packages_info
- display_updated_globals
-}
-
-# to be invoked at initialization and after a font scaling- or language change
-proc rebuild_interface {} {
- foreach c [winfo children .] {catch {destroy $c}}
-
- # for busy/idle indicators
- set ::busy [__ "Idle"]
- populate_main
- display_all_data
- if {$::tcl_platform(platform) eq "windows"} {wm deiconify .}
-}
-
-##### initialize ######################################################
-
-proc initialize {} {
- # seed random numbers
- expr {srand([clock seconds])}
-
- # directory for temp files
- set attemptdirs {}
- foreach tmp {TMPDIR TEMP TMP} {
- if {$tmp in [array names ::env]} {
- lappend attemptdirs $::env($tmp)
- }
- }
- if {$::tcl_platform(platform) eq "unix"} {
- lappend attemptdirs "/tmp"
- }
- lappend attemptdirs [pwd]
- set ::tempsub ""
- foreach tmp $attemptdirs {
- if {$::tcl_platform(platform) eq "windows"} {
- regsub -all {\\} $tmp {/} tmp
- }
- if {[file isdirectory $tmp]} {
- # no real point in randomizing directory name itself
- if {$::tcl_platform(platform) eq "unix"} {
- set ::tempsub [file join $tmp $::env(USER)]
- } else {
- set ::tempsub [file join $tmp $::env(USERNAME)]
- }
- append ::tempsub "-tlshell"
- if {! [catch {file mkdir $::tempsub}]} {break} ;# success
- }
- }
-
- if {$::tempsub eq "" || [file isdirectory $::tempsub] == 0} {
- error "Cannot create directory for temporary files"
- }
- # temp file for stderr
- set ::err_file [maketemp ".err_tlshl"]
-
- # logfile
- if $::ddebug {
- set fname [file join $::tempsub \
- [clock format [clock seconds] -format {%H:%M}]]
- set ::flid [open $fname w]
- }
-
- # store language in tlmgr configuration
- save_config_var "gui-lang" $::lang
-
- # in case we are going to do something with json:
- # add json subdirectory to auto_path, but at low priority
- # since the tcl/tk installation may already have a better implementation.
- # Trust kpsewhich to find out own directory and bypass symlinks.
- #set tlsdir [file dirname [exec kpsewhich -format texmfscripts tlshell.tcl]]
- #lappend ::auto_path [file join $tlsdir "json"]
-
- populate_main
-
- # testing writablilty earlier led to sizing problems
- if {! [dir_writable $::instroot]} {
- set ans [tk_messageBox -type yesno -icon warning -message \
- [__ "%s is not writable. You can probably not do much.
- Are you sure you want to continue?" $::instroot]]
- if {$ans ne "yes"} {exit}
- }
-
- start_tlmgr {*}$::argv
- if {$::tcl_platform(platform) eq "windows"} {
- run_cmd_waiting "option multiuser"
- set ::multiuser 0
- foreach l $::out_log {
- if [regexp {^\s*multiuser\s+([01])\s*$} $l d ::multiuser] break
- }
- }
- get_packages_info_local
- collect_filtered
- get_repos_from_tlmgr
- display_all_data
-}; # initialize
-
-initialize
diff --git a/Build/source/texk/texlive/linked_scripts/typeoutfileinfo/typeoutfileinfo.sh b/Build/source/texk/texlive/linked_scripts/typeoutfileinfo/typeoutfileinfo.sh
deleted file mode 100755
index 2780883e82f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/typeoutfileinfo/typeoutfileinfo.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/sh
-##
-## This is `typeoutfileinfo.sh', a minimalist shell script for Unices.
-##
-## ./typeoutfileinfo.sh [FILENAME].[EXT]
-##
-## runs latex with the readprov package:
-##
-## http://ctan.org/pkg/readprov
-##
-## in order to display [FILENAME].[TXT]'s FILE INFO (\listfile entry)
-## using \typeout. This requires that [FILENAME].[EXT] contains a
-## \ProvidesFile, \ProvidesPackage, or \ProvidesClass command.
-latex \\RequirePackage{readprov}\\ReadFileInfos{$1}\
-\\typeout{^^J^^J + $1 info: + \\csname ver@$1\\endcsname^^J}\
-\\batchmode\\stop
-##
-## Copyright (C) 2012 Uwe Lueck, http://contact-ednotes.sty.de.vu/
-##
-## This program may be distributed and/or modified under the
-## conditions of the LaTeX Project Public License, either version 1.3c
-## of this license or (at your option) any later version.
-## The latest version of this license is in
-## http://www.latex-project.org/lppl.txt
-## and version 1.3c or later is part of all distributions of LaTeX
-## version 1999/12/01 or later.
-##
-## There is NO WARRANTY.
-##
-## This is package version v0.31 as of 2012-09-28.
-##
-## CREDITS: This work derived from Harald Harders' `latexfileversion'
-## as a simplification using my `readprov'. Reinhard Kotucha
-## improved the code, see HISTORY.
-##
-## PURPOSE/BACKGROUND: A package like this, `latexfileversion' or
-## `ltxfileinfo' when you wonder which version of a source file
-## (package, document component) is available in some directory --
-## I typically test package changes by symbolic links in single
-## project directories before installing them globally, and then
-## sometimes don't remember ... when I get an "undefined" error,
-## I wonder whether I have installed the symbolic link or whether
-## I just forgot to define this, or whether I lost the most recent
-## version ...
-##
-## HISTORY:
-## v0.1a 2012/03/16
-## v0.2 2012/09/16 adds \batchmode thanks to Heiko Oberdiek on texhax
-## v0.21 2012/09/19 shebang line corrected/improved by Reinhard Kotucha
-## v0.3 2012/09/27 long line instead of here document,
-## different spacing, * -> + (misinterpreded)
-## v0.31 2012/09/28 code line broken by `\', thanks to Reinhard Kotucha
diff --git a/Build/source/texk/texlive/linked_scripts/ulqda/ulqda.pl b/Build/source/texk/texlive/linked_scripts/ulqda/ulqda.pl
deleted file mode 100755
index 036c1f2a7dd..00000000000
--- a/Build/source/texk/texlive/linked_scripts/ulqda/ulqda.pl
+++ /dev/null
@@ -1,295 +0,0 @@
-#!/usr/bin/perl
-#
-# Helper Perl script for ulqda
-# A LaTeX package supporting Qualitative Data Analysis
-#
-# Copyright (C) 2009 by Ivan Griffin
-#
-# This file may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either
-# version 1.2 of this license or (at your option) any later
-# version. The latest version of this license is in:
-#
-# http://www.latex-project.org/lppl.txt
-#
-# and version 1.2 or later is part of all distributions of
-# LaTeX version 1999/12/01 or later.
-#
-
-use Getopt::Long;
-use Digest::SHA1 qw(sha1 sha1_hex sha1_base64);
-
-sub Display_Version()
-{
- print "Version: ulqda.pl [2009/06/11 v1.1 Qualitative Data Analysis package]\n\n";
- exit;
-}
-
-sub Display_Usage()
-{
- print<<"EOF";
-Usage: $0 \\
- <--list>|<--graphflat>|<--graphnet>|<--cloud>|<--help>|<--version> \\
- [<--filter section>] [<--number-->] infile.csv outfile
-
---filter: filter based on document section label
---graphflat: Generate GraphViz .dot output of codes (unconnected)
---graphnet: Generate GraphViz .dot output of codes (connected)
---cloud: Generate Cloud output of codes
---help: Print this help and exit
---list: Generate LaTeX table of codes (labelled as table:qda_codes)
---number: Output quantity details
---version: Dispaly version information
-EOF
- exit;
-}
-
-sub sort_codes_hashvalue_descending {
- $codes{$b} <=> $codes{$a};
-}
-
-sub sort_codes_alphabetic {
- $a cmp $b;
-}
-
-@colors = ("#d40000", "#e35a24", "#f67c00", "#faa800", "#ffc000", "#ffde00", "#aae900", "#62dc68", "#bbcced", "#a3bbe0", "#8aaad4", "#7299c7", "#5676b5", "#4554a3", "#2e3191", "#000472");
-
-$result = GetOptions("number" => \$options{'n'},
- "list" => \$options{'l'},
- "cloud" => \$options{'c'},
- "graphflat" => \$options{'g'},
- "filter=s" => \$options{'f'},
- "graphnet" => \$options{'G'},
- "version" => \$options{'v'},
- "help" => \$options{'h'});
-
-&Display_Usage() if !$result;
-&Display_Usage() if $options{'h'};
-
-&Display_Version() if $options{'v'};
-
-if (!($options{'c'} || $options{'l'} || $options{'g'} || $options{'G'}))
-{
- print "Requires one of --cloud, --list, --graphflat, --graphnet, --version or --help\n\n";
- &Display_Usage()
-}
-
-if (($ARGV[0]) && ($ARGV[1]))
-{
- open(FILEIN, "<$ARGV[0]") or die "Could not open input file $ARGV[0]\n";
- open(FILEOUT, ">$ARGV[1]") or die "Could not open output file $ARGV[1]\n";
-}
-else
-{
- &Display_Usage();
-}
-
-if ($options{'l'})
-{
- print FILEOUT << "EOF";
-{
-\\vspace{0.1in}
-\\hrule
-
-\\begin{multicols}{3}
-\\label{table:qda_codes}
-EOF
-}
-elsif ($options{'c'})
-{
- #
- print FILEOUT << "EOF";
-{
-\\begin{center}
-\\noindent%
-EOF
-}
-elsif ($options{'g'} || $options{'G'})
-{
- print FILEOUT << "EOF";
-digraph codes {
-overlap=scale
-ratio=compress
-smoothType=spring
-repulsiveforce=1.2
-splines=true
-
-#
-# Nodes
-#
-EOF
-}
-
-<FILEIN>; # gobble first line (it is just header)
-
-# now, for each line, parse into comma separated values
-# codes are further split based on the '!' separator character
-# e.g. risk!business becomes two codes, risk and business, with a
-# connection between risk->business
-GOBBLE_LOOP: while (<FILEIN>)
-{
- chomp;
- ($page, $section, $code_list, $text) = split(/\,/, $_, 4);
-#print"DEBUG: >>$code_list<< $_ \n";
-
- if (($options{'f'}) && ($options{'f'} != $section))
- {
- # filtering selected so if no match, then skip
- next GOBBLE_LOOP;
- }
-
- foreach $code ( split(/\!/, $code_list) )
- {
- $code =~ s/^ //g;
- $codes{$code} += 1;
- }
-
- @connections = (@connections, $code_list);
-}
-close(FILEIN);
-
-#
-# Find the maximum number of connections and the minimum number of connections
-# This will be used for scaling subsequently
-#
-$iterationCount = 0; $nodeCount = 0;
-$maxConnections = 0; $minConnections=65535;
-
-if ($options{'c'})
-{
- @key_list = (sort sort_codes_alphabetic keys %codes);
-}
-else
-{
- @key_list = (sort sort_codes_hashvalue_descending keys %codes);
-}
-
-LOOP: foreach $i (sort sort_codes_hashvalue_descending keys %codes)
-{
- if ($codes{$i} > $maxConnections) { $maxConnections = $codes{$i} }
- if ($codes{$i} < $minConnections) { $minConnections = $codes{$i} }
-}
-
-#
-# For each code, output it as requested
-#
-foreach $i (@key_list)
-{
- $digest = sha1_hex($i);
-
- if ($options{'l'} && ($iterationCount))
- {
- print FILEOUT "\\\\\n";
- }
- elsif ($options{'c'})
- {
- my $base = int(7 + ($codes{$i}/3));
- my $lead = $base + 3;
- my $raisept = int(($base - 7)/4);
-
- if ($raisept) { print FILEOUT "\\raisebox{-${raisept}pt}";}
- print FILEOUT "{\\fontsize{$base}{$lead}\\selectfont ";
- }
- elsif ($options{'g'} || $options{'G'})
- {
- $nodeCount++;
- print FILEOUT "Node$digest [label=\"";
- }
-
- $i =~ s/!/:/g;
- print FILEOUT "$i";
-
- if ($options{'c'})
- {
- print FILEOUT "}\n";
- }
- elsif ($options{'n'})
- {
- print FILEOUT "{\\textcolor{red}{" if ($options{'l'});
- print FILEOUT "($codes{$i})";
- print FILEOUT "}}" if ($options{'l'});
- }
-
- if ($options{'g'} || $options{'G'})
- {
- $fontSize = 15 + ((60 * $codes{$i})/$maxConnections);
- print FILEOUT "\", fontsize=$fontSize";
- #if ($iterationCount <= 5)
- {
- # heatmap based colors
- # $colorIndex = 6 - int((6*($codes{$i} - $minConnections))/($maxConnections - $minConnections));
- # index based colors
- $colorIndex = int(($iterationCount*16)/(keys %codes));
- print FILEOUT ",color=\"$colors[$colorIndex]\",style=filled";
- }
- print FILEOUT "]\n";
- }
- elsif (! ($options{'l'} || $options{'c'}) )
- {
- print FILEOUT "\n";
- }
- $iterationCount++;
-}
-
-#
-# For connection graphs, process each connection between points
-#
-if ($options{'G'})
-{
- print FILEOUT <<"EOF";
-
-#
-# Connections
-#
-EOF
-
- for $code_list (@connections)
- {
- print FILEOUT "// $code_list\n";
- @code_list_array = split(/\!/, $code_list);
- $previous_code = shift(@code_list_array);
- $previous_code =~ s/^ //g;
-
- if (defined($previous_code))
- {
- foreach $code ( @code_list_array )
- {
- $code =~ s/^ //g;
- $previous_digest = sha1_hex($previous_code);
- $digest = sha1_hex($code);
-
- # ensure only 1 connection between points
- if (!defined($connection{"$previous_digest-$digest"}))
- {
- $connection{"$previous_digest-$digest"} = 1;
- $len=0.25+(0.75*$codes{$previous_code}/$maxConnections);
- $w=0.25+(0.75*$codes{$previous_code}/$maxConnections);
- print FILEOUT "Node$previous_digest->Node$digest [label=\"\", w=$w, len=$len]\n";
- }
-
- $previous_code = $code;
- }
- }
- }
-}
-
-#
-# Tidy up
-#
-if ($options{'l'})
-{
- print FILEOUT << "EOF";
-\\end{multicols}
-\\hrule
-EOF
-}
-elsif ($options{'c'})
-{
- print FILEOUT << "EOF";
-\\end{center}
-EOF
-}
-
-print FILEOUT "\n}\n";
-
-close(FILEOUT);
diff --git a/Build/source/texk/texlive/linked_scripts/urlbst/urlbst b/Build/source/texk/texlive/linked_scripts/urlbst/urlbst
deleted file mode 100755
index c917d02f1d2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/urlbst/urlbst
+++ /dev/null
@@ -1,889 +0,0 @@
-#! /usr/bin/perl -w
-#
-# Usage: ./urlbst.pl [--eprint] [--doi] [--pubmed]
-# [--nohyperlinks] [--inlinelinks] [--hypertex] [--hyperref]
-# [input-file [output-file]]
-# If either input-file or output-file is omitted, they are replaced by
-# stdin or stdout respectively.
-#
-# See http://purl.org/nxg/dist/urlbst for documentation
-#
-# Copyright 2002-03, 2005-12, 2014, 2019, Norman Gray <http://nxg.me.uk>
-#
-# This program is distributed under the terms of the
-# GNU General Public Licence, v2.0.
-# The modifications to the input .bst files are asserted as Copyright 2002-03, 2005-12, 2014, 2019, Norman Gray,
-# and distributed under the terms of the LaTeX Project Public Licence.
-# See the package README for further dicussion of licences.
-
-$version = '0.8';
-($progname = $0) =~ s/.*\///;
-$mymarker = "% $progname";
-$mymarkerend = "% ...$progname to here";
-$myurl = 'http://purl.org/nxg/dist/urlbst';
-
-
-$infile = '-';
-$outfile = '-';
-
-$addeprints = 1; # if true (nonzero) we add support for eprints
-$literals{eprintprefix} = 'arXiv:'; # make these settable with --eprint? syntax?
-$eprinturl = 'http://arxiv.org/abs/';
-
-$adddoiresolver = 1;
-$literals{doiprefix} = 'doi:';
-$doiurl = 'https://doi.org/';
-
-$addpubmedresolver = 1;
-$literals{pubmedprefix} = 'PMID:';
-$pubmedurl = 'http://www.ncbi.nlm.nih.gov/pubmed/';
-
-$makehref = 0;
-$literals{urlintro} = "URL: ";
-$inlinelinks = 0;
-
-$literals{online} = "online";
-$literals{cited} = "cited ";
-$literals{linktext} = "[link]";
-
-$automatic_output_filename = 0;
-
-$Usage = "$progname [--eprint] [--doi] [--pubmed]\n [--nohyperlinks] [--[no]inlinelinks] [--hypertex] [--hyperref]\n [--literal key=value]\n [--help] [input-file [output-file]]";
-
-# Magic environment variable: if this is set, then we're being called from a Platypus wrapper
-# See http://www.sveinbjorn.org/platypus
-if ($ENV{"CALLED_FROM_PLATYPUS"}) {
- $automatic_output_filename = 1;
-}
-
-while ($#ARGV >= 0) {
- if ($ARGV[0] eq '--eprint') {
- $addeprints = 1;
- } elsif ($ARGV[0] eq '--noeprint') {
- $addeprints = 0;
- } elsif ($ARGV[0] eq '--doi') {
- $adddoiresolver = 1;
- } elsif ($ARGV[0] eq '--nodoi') {
- $adddoiresolver = 0;
- } elsif ($ARGV[0] eq '--pubmed') {
- $addpubmedresolver = 1;
- } elsif ($ARGV[0] eq '--nopubmed') {
- $addpubmedresolver = 0;
- } elsif ($ARGV[0] eq '--nohyperlinks') {
- $makehref = 0;
- } elsif ($ARGV[0] eq '--hypertex') {
- $makehref = 1;
- } elsif ($ARGV[0] eq '--hyperref') {
- $makehref = 2;
- } elsif ($ARGV[0] eq '--inlinelinks') {
- $inlinelinks = 1;
- } elsif ($ARGV[0] eq '--noinlinelinks') {
- $inlinelinks = 0;
- } elsif ($ARGV[0] eq '--automatic-output') {
- $automatic_output_filename = 1;
- } elsif ($ARGV[0] eq '--literal') {
- shift;
- my $showstrings = 0;
- if ((($k, $v) = ($ARGV[0] =~ /^(\w+)=(.*)/)) && exists $literals{$k}) {
- $literals{$k} = $v;
- } elsif ($ARGV[0] eq 'help') {
- $showstrings = 1;
- } else {
- print "No literal found in $ARGV[0]; ignoring that\n";
- $showstrings = 1;
- }
- if ($showstrings) {
- print " Possible literal strings (and defaults) are...\n";
- while (($k, $v) = each (%literals)) {
- print " $k ($v)\n";
- }
- exit(0);
- }
- } elsif ($ARGV[0] eq '--help') {
- print <<EOD;
-urlbst version $version
- Usage: $Usage
- --[no]eprint include support for `eprint' fields
- --[no]doi include support for `doi' field
- --[no]pubmed include support for `pubmed' field
- --nohyperlinks do not include active links anywhere
- --[no]inlinelinks add hyperlinks to entry titles
- --hypertex include HyperTeX-style hyperlink support
- --hyperref include {hyperref}-style hyperlink support
- (generally better)
- --literal key=value set one of the literal strings
- (see `--literal help' for possibilities)
- --help print this help
- Input and output files may be given as `-' (default) to indicate stdin/out.
-
-EOD
- printf(" Defaults:\n");
- printf(" eprint refs %s\n", ($addeprints ? "included" : "not included"));
- printf(" DOIs %s\n", ($adddoiresolver ? "included" : "not included"));
- printf(" PUBMED refs %s\n", ($addpubmedresolver ? "included" : "not included"));
- printf(" hyperlinks %s\n", ($makehref==0 ? "none" : $makehref==1 ? "hypertex" : "hyperref"));
- printf(" inline links %s\n", ($inlinelinks ? "included" : "not included"));
- exit(0);
- } elsif ($ARGV[0] =~ /^-/) {
- die "Unrecognised option $ARGV[0]: Usage: $Usage\n";
- } elsif ($infile eq '-') {
- $infile = $ARGV[0];
- } elsif ($outfile eq '-') {
- $outfile = $ARGV[0];
- } else {
- die "Usage: $Usage\n";
- }
- shift(@ARGV);
-}
-
-if ($inlinelinks && $makehref == 0) {
- print <<'EOD';
-Warning: --inlinelinks and --nohyperlinks were both specified (possibly
- implicitly). That combination makes no sense, so I'll ignore
- --nohyperlinks and use --hyperref instead
-EOD
- $makehref = 2;
-}
-
-if ($automatic_output_filename) {
- if ($infile eq '-') {
- print "ERROR: No input filename given with --automatic-output\n";
- }
- $outfile = $infile;
- @outparts = split /\./, $outfile;
- $ext = pop(@outparts);
- $outfile=join('.', @outparts);
- if ($outfile eq '') {
- $outfile = $ext . '-url';
- } else {
- $outfile = $outfile . '-url.' . $ext;
- }
-}
-
-$exitstatus = 0; # success status
-
-open (IN, "<$infile") || die "Can't open $infile to read";
-open (OUT, ">$outfile") || die "Can't open $outfile to write";
-
-# We have to make certain assumptions about the source files, in order
-# to patch them at the correct places. Specifically, we assume that
-#
-# - there's a function init.state.consts
-#
-# - ...and an output.nonnull which does the actual outputting, which
-# has the `usual' interface.
-#
-# - we can replace
-# fin.entry
-# by
-# new.block
-# output.url % the function which formats and displays any URL
-# fin.entry
-#
-# - there is a function which handles the `article' entry type (this
-# will always be true)
-#
-# - there is a function output.bibitem which is called at the
-# beginning of each entry type
-# - ...and one called fin.entry which is called at the end
-#
-# If the functions format.date, format.title or new.block are not defined (the
-# former is not in apalike, for example, and the last is not in the
-# AMS styles), then replacements are included in the output.
-#
-# All these assumptions are true of the standard files and, since most
-# style files derive from them more or less directly, are true of most (?)
-# other style files, too.
-#
-# There's some rather ugly Perl down here. The parsing for
-# brace-matching could probably do with being rewritten in places, to
-# make it less ugly, and more robust.
-
-print OUT "%%% Modification of BibTeX style file ", ($infile eq '-' ? '<stdin>' : $infile), "\n";
-print OUT "%%% ... by $progname, version $version (marked with \"$mymarker\")\n%%% See <$myurl>\n";
-print OUT "%%% Modifications Copyright 2002-03, 2005-12, 2014, 2019, Norman Gray,\n";
-print OUT "%%% and distributed under the terms of the LPPL; see README for discussion.\n";
-print OUT "%%%\n";
-print OUT "%%% Added webpage entry type, and url and lastchecked fields.\n";
-print OUT "%%% Added eprint support.\n" if ($addeprints);
-print OUT "%%% Added DOI support.\n" if ($adddoiresolver);
-print OUT "%%% Added PUBMED support.\n" if ($addpubmedresolver);
-print OUT "%%% Added HyperTeX support.\n" if ($makehref == 1);
-print OUT "%%% Added hyperref support.\n" if ($makehref == 2);
-print OUT "%%% Original headers follow...\n\n";
-
-$found{initconsts} = 0;
-$found{outputnonnull} = 0;
-$found{article} = 0;
-$found{outputbibitem} = 0;
-$found{finentry} = 0;
-$found{formatdate} = 0;
-$found{formattitle} = 0;
-$found{newblock} = 0;
-# The following are initialised negative, which Perl treats as true,
-# so the simple test 'if ($found{formateprint}) ...' will be true.
-$found{formateprint} = -1;
-$found{formatdoi} = -1;
-$found{formatpubmed} = -1;
-
-while (<IN>) {
- /^ *%/ && do {
- # Pass commented lines unchanged
- print OUT;
- next;
- };
-
- /^ *ENTRY/ && do {
- # Work through the list of entry types, finding what ones are there.
- # If we find a URL entry there already, object, since these edits
- # will mess things up.
- $line = $_;
- until ($line =~ /\{\s*(\w*)/) {
- $line .= <IN>;
- }
- $bracematchtotal = 0; # reset
- bracematcher($line);
- $line =~ /\{\s*(\w*)/;
- $found{'entry'.$1} = 1;
- print OUT $line;
- $line = <IN>;
- until (bracematcher($line) == 0) {
- # XXX deal with multiple entries on one line
- ($line =~ /^\s*(\w*)/) && ($found{'entry'.$1} = 1);
- print OUT $line;
- $line = <IN>;
- }
- if (defined($found{entryurl})) {
- print STDERR "$progname: style file $infile already has URL entry!\n";
- # print out the rest of the file, and give up
- print OUT $line;
- while (<IN>) {
- print OUT;
- }
- $exitstatus = 1;
- last;
- } else {
- print OUT " eprint $mymarker\n doi $mymarker\n pubmed $mymarker\n url $mymarker\n lastchecked $mymarker\n";
- }
- print OUT $line;
- next;
- };
-
- /^ *FUNCTION *\{init\.state\.consts\}/ && do {
- # In the init.state.consts function, add an extra set of
- # constants at the beginning. Also use this as the marker for
- # the place to add the init strings function.
- print OUT <<EOD;
-$mymarker...
-% urlbst constants and state variables
-STRINGS { urlintro
- eprinturl eprintprefix doiprefix doiurl pubmedprefix pubmedurl
- citedstring onlinestring linktextstring
- openinlinelink closeinlinelink }
-INTEGERS { hrefform inlinelinks makeinlinelink
- addeprints adddoiresolver addpubmedresolver }
-FUNCTION {init.urlbst.variables}
-{
- % The following constants may be adjusted by hand, if desired
-
- % The first set allow you to enable or disable certain functionality.
- #$addeprints 'addeprints := % 0=no eprints; 1=include eprints
- #$adddoiresolver 'adddoiresolver := % 0=no DOI resolver; 1=include it
- #$addpubmedresolver 'addpubmedresolver := % 0=no PUBMED resolver; 1=include it
- #$makehref 'hrefform := % 0=no crossrefs; 1=hypertex xrefs; 2=hyperref refs
- #$inlinelinks 'inlinelinks := % 0=URLs explicit; 1=URLs attached to titles
-
- % String constants, which you _might_ want to tweak.
- "$literals{urlintro}" 'urlintro := % prefix before URL; typically "Available from:" or "URL":
- "$literals{online}" 'onlinestring := % indication that resource is online; typically "online"
- "$literals{cited}" 'citedstring := % indicator of citation date; typically "cited "
- "$literals{linktext}" 'linktextstring := % dummy link text; typically "[link]"
- "$eprinturl" 'eprinturl := % prefix to make URL from eprint ref
- "$literals{eprintprefix}" 'eprintprefix := % text prefix printed before eprint ref; typically "arXiv:"
- "$doiurl" 'doiurl := % prefix to make URL from DOI
- "$literals{doiprefix}" 'doiprefix := % text prefix printed before DOI ref; typically "doi:"
- "$pubmedurl" 'pubmedurl := % prefix to make URL from PUBMED
- "$literals{pubmedprefix}" 'pubmedprefix := % text prefix printed before PUBMED ref; typically "PMID:"
-
- % The following are internal state variables, not configuration constants,
- % so they shouldn't be fiddled with.
- #0 'makeinlinelink := % state variable managed by possibly.setup.inlinelink
- "" 'openinlinelink := % ditto
- "" 'closeinlinelink := % ditto
-}
-INTEGERS {
- bracket.state
- outside.brackets
- open.brackets
- within.brackets
- close.brackets
-}
-$mymarkerend
-EOD
- $line = $_;
- until ($line =~ /\{.*\}.*\{/s) {
- $line .= <IN>;
- }
- $line =~ s/(\{.*?\}.*?\{)/$1 #0 'outside.brackets := $mymarker...
- #1 'open.brackets :=
- #2 'within.brackets :=
- #3 'close.brackets := $mymarkerend
-
- /s;
- print OUT $line;
- $found{initconsts} = 1;
- next;
- };
-
- /^ *EXECUTE *\{init\.state\.consts\}/ && do {
- print OUT "EXECUTE {init.urlbst.variables} $mymarker\n";
- print OUT;
- next;
- };
-
- /^ *FUNCTION *\{new.block\}/ && do {
- $found{newblock} = 1;
- };
-
- /^ *FUNCTION *\{format.doi\}/ && do {
- #print STDERR "$progname: style file $infile already supports DOIs; urlbst format.doi disabled\n(see generated .bst style: you may need to make edits near \$adddoiresolver)\n";
- $found{formatdoi} = 1;
- $adddoiresolver = 0;
- };
-
- /^ *FUNCTION *\{format.eprint\}/ && do {
- #print STDERR "$progname: style file $infile already supports eprints; urlbst format.eprint disabled\n(see generated .bst style: you may need to make edits near \$addeprints)\n";
- $found{formateprint} = 1;
- $addeprints = 0;
- };
-
- /^ *FUNCTION *\{format.pubmed\}/ && do {
- #print STDERR "$progname: style file $infile already supports Pubmed; urlbst format.pubmed disabled\n(see generated .bst style: you may need to make edits near \$addpubmedresolver)\n";
- $found{formatpubmed} = 1;
- $addpubmedresolver = 0;
- };
-
- /^ *FUNCTION *{output\.nonnull}/ && do {
- print OUT "$mymarker\n";
- print OUT "FUNCTION {output.nonnull.original}\n";
- copy_block();
- print_output_functions();
- $found{outputnonnull} = 1;
- next;
- };
-
- /FUNCTION *\{fin.entry\}/ && do {
- # Rename fin.entry to fin.entry.original (wrapped below)
- s/fin.entry/fin.entry.original/;
- s/$/ $mymarker (renamed from fin.entry, so it can be wrapped below)/;
- $found{finentry} = 1;
- print OUT;
- next;
- };
-
- /^ *FUNCTION *{format\.date}/ && do {
- $found{formatdate} = 1;
- print OUT;
- next;
- };
-
- /^ *FUNCTION *{format\.title}/ && do {
- # record that we found this
- $found{formattitle} = 1;
- print OUT;
- next;
- };
-
- /^ *format\.b?title/ && do {
- # interpolate a call to possibly.setup.inlinelink
- print OUT " title empty\$ 'skip\$ 'possibly.setup\.inlinelink if\$ $mymarker\n";
- print OUT;
- next;
- };
-
- /^ *format\.vol\.num\.pages/ && do {
- # interpolate a call to possibly.setup.inlinelink
- s/^( *)/$1possibly.setup.inlinelink /;
- s/$/$mymarker/;
- print OUT;
- next;
- };
-
- /^ *FUNCTION *\{article\}/ && do {
-
- print_missing_functions();
- print_webpage_def();
-
- print OUT;
- $found{article} = 1;
- next;
- };
-
- /FUNCTION *\{output.bibitem\}/ && do {
- # Rename output.bibitem to output.bibitem.original (wrapped below)
- s/{output.bibitem\}/\{output.bibitem.original\}/;
- s/$/ $mymarker (renamed from output.bibitem, so it can be wrapped below)/;
- $found{outputbibitem} = 1;
- print OUT;
- next;
- };
-
- print OUT;
-};
-
-if ($exitstatus == 0) {
- # Skip this if we've already reported an error -- it'll only be confusing
- foreach $k (keys %found) {
- if ($found{$k} == 0) {
- print STDERR "$progname: $infile: failed to find feature $k\n";
- }
- }
-}
-
-close (IN);
-close (OUT);
-
-exit $exitstatus;;
-
-
-
-
-
-
-sub print_output_functions {
- print OUT "$mymarker...\n";
-
- print OUT <<'EOD';
-% The following three functions are for handling inlinelink. They wrap
-% a block of text which is potentially output with write$ by multiple
-% other functions, so we don't know the content a priori.
-% They communicate between each other using the variables makeinlinelink
-% (which is true if a link should be made), and closeinlinelink (which holds
-% the string which should close any current link. They can be called
-% at any time, but start.inlinelink will be a no-op unless something has
-% previously set makeinlinelink true, and the two ...end.inlinelink functions
-% will only do their stuff if start.inlinelink has previously set
-% closeinlinelink to be non-empty.
-% (thanks to 'ijvm' for suggested code here)
-FUNCTION {uand}
-{ 'skip$ { pop$ #0 } if$ } % 'and' (which isn't defined at this point in the file)
-FUNCTION {possibly.setup.inlinelink}
-{ makeinlinelink hrefform #0 > uand
- { doi empty$ adddoiresolver uand
- { pubmed empty$ addpubmedresolver uand
- { eprint empty$ addeprints uand
- { url empty$
- { "" }
- { url }
- if$ }
- { eprinturl eprint * }
- if$ }
- { pubmedurl pubmed * }
- if$ }
- { doiurl doi * }
- if$
- % an appropriately-formatted URL is now on the stack
- hrefform #1 = % hypertex
- { "\special {html:<a href=" quote$ * swap$ * quote$ * "> }{" * 'openinlinelink :=
- "\special {html:</a>}" 'closeinlinelink := }
- { "\href {" swap$ * "} {" * 'openinlinelink := % hrefform=#2 -- hyperref
- % the space between "} {" matters: a URL of just the right length can cause "\% newline em"
- "}" 'closeinlinelink := }
- if$
- #0 'makeinlinelink :=
- }
- 'skip$
- if$ % makeinlinelink
-}
-FUNCTION {add.inlinelink}
-{ openinlinelink empty$
- 'skip$
- { openinlinelink swap$ * closeinlinelink *
- "" 'openinlinelink :=
- }
- if$
-}
-EOD
-
- # new.block is defined elsewhere
-
- print OUT <<'EOD';
-FUNCTION {output.nonnull}
-{ % Save the thing we've been asked to output
- 's :=
- % If the bracket-state is close.brackets, then add a close-bracket to
- % what is currently at the top of the stack, and set bracket.state
- % to outside.brackets
- bracket.state close.brackets =
- { "]" *
- outside.brackets 'bracket.state :=
- }
- 'skip$
- if$
- bracket.state outside.brackets =
- { % We're outside all brackets -- this is the normal situation.
- % Write out what's currently at the top of the stack, using the
- % original output.nonnull function.
- s
- add.inlinelink
- output.nonnull.original % invoke the original output.nonnull
- }
- { % Still in brackets. Add open-bracket or (continuation) comma, add the
- % new text (in s) to the top of the stack, and move to the close-brackets
- % state, ready for next time (unless inbrackets resets it). If we come
- % into this branch, then output.state is carefully undisturbed.
- bracket.state open.brackets =
- { " [" * }
- { ", " * } % bracket.state will be within.brackets
- if$
- s *
- close.brackets 'bracket.state :=
- }
- if$
-}
-
-% Call this function just before adding something which should be presented in
-% brackets. bracket.state is handled specially within output.nonnull.
-FUNCTION {inbrackets}
-{ bracket.state close.brackets =
- { within.brackets 'bracket.state := } % reset the state: not open nor closed
- { open.brackets 'bracket.state := }
- if$
-}
-
-FUNCTION {format.lastchecked}
-{ lastchecked empty$
- { "" }
- { inbrackets citedstring lastchecked * }
- if$
-}
-EOD
- print OUT "$mymarkerend\n";
-}
-
-sub print_webpage_def {
- print OUT "$mymarker...\n";
-
- # Some of the functions below call new.block, so we need a dummy
- # version, in the case where the style being edited doesn't supply
- # that function.
- if (! $found{newblock}) {
- print OUT "FUNCTION {new.block} % dummy new.block function\n{\n % empty\n}\n\n";
- $found{newblock} = 1;
- }
-
- print OUT <<'EOD';
-% Functions for making hypertext links.
-% In all cases, the stack has (link-text href-url)
-%
-% make 'null' specials
-FUNCTION {make.href.null}
-{
- pop$
-}
-% make hypertex specials
-FUNCTION {make.href.hypertex}
-{
- "\special {html:<a href=" quote$ *
- swap$ * quote$ * "> }" * swap$ *
- "\special {html:</a>}" *
-}
-% make hyperref specials
-FUNCTION {make.href.hyperref}
-{
- "\href {" swap$ * "} {\path{" * swap$ * "}}" *
-}
-FUNCTION {make.href}
-{ hrefform #2 =
- 'make.href.hyperref % hrefform = 2
- { hrefform #1 =
- 'make.href.hypertex % hrefform = 1
- 'make.href.null % hrefform = 0 (or anything else)
- if$
- }
- if$
-}
-
-% If inlinelinks is true, then format.url should be a no-op, since it's
-% (a) redundant, and (b) could end up as a link-within-a-link.
-FUNCTION {format.url}
-{ inlinelinks #1 = url empty$ or
- { "" }
- { hrefform #1 =
- { % special case -- add HyperTeX specials
- urlintro "\url{" url * "}" * url make.href.hypertex * }
- { urlintro "\url{" * url * "}" * }
- if$
- }
- if$
-}
-EOD
-
- $formateprintfunction = <<'EOD';
-FUNCTION {format.eprint}
-{ eprint empty$
- { "" }
- { eprintprefix eprint * eprinturl eprint * make.href }
- if$
-}
-EOD
- output_replacement_function($found{formateprint},
- 'format.eprint',
- 'addeprints',
- $formateprintfunction);
-
- $formatdoifunction = <<'EOD';
-FUNCTION {format.doi}
-{ doi empty$
- { "" }
- { doiprefix doi * doiurl doi * make.href }
- if$
-}
-EOD
- output_replacement_function($found{formatdoi},
- 'format.doi',
- 'adddoiresolver',
- $formatdoifunction);
-
- $formatpubmedfunction = <<'EOD';
-FUNCTION {format.pubmed}
-{ pubmed empty$
- { "" }
- { pubmedprefix pubmed * pubmedurl pubmed * make.href }
- if$
-}
-EOD
- output_replacement_function($found{formatpubmed},
- 'format.pubmed',
- 'addpubmedresolver',
- $formatpubmedfunction);
-
- print OUT <<'EOD';
-% Output a URL. We can't use the more normal idiom (something like
-% `format.url output'), because the `inbrackets' within
-% format.lastchecked applies to everything between calls to `output',
-% so that `format.url format.lastchecked * output' ends up with both
-% the URL and the lastchecked in brackets.
-FUNCTION {output.url}
-{ url empty$
- 'skip$
- { new.block
- format.url output
- format.lastchecked output
- }
- if$
-}
-
-FUNCTION {output.web.refs}
-{
- new.block
- inlinelinks
- 'skip$ % links were inline -- don't repeat them
- { % If the generated DOI will be the same as the URL,
- % then don't print the URL (thanks to Joseph Wright for this code,
- % at http://tex.stackexchange.com/questions/5660)
- adddoiresolver
- doiurl doi empty$ { "X" } { doi } if$ * % DOI URL to be generated
- url empty$ { "Y" } { url } if$ % the URL, or "Y" if empty
- = % are the strings equal?
- and
- 'skip$
- { output.url }
- if$
- addeprints eprint empty$ not and
- { format.eprint output.nonnull }
- 'skip$
- if$
- adddoiresolver doi empty$ not and
- { format.doi output.nonnull }
- 'skip$
- if$
- addpubmedresolver pubmed empty$ not and
- { format.pubmed output.nonnull }
- 'skip$
- if$
- }
- if$
-}
-
-% Wrapper for output.bibitem.original.
-% If the URL field is not empty, set makeinlinelink to be true,
-% so that an inline link will be started at the next opportunity
-FUNCTION {output.bibitem}
-{ outside.brackets 'bracket.state :=
- output.bibitem.original
- inlinelinks url empty$ not doi empty$ not or pubmed empty$ not or eprint empty$ not or and
- { #1 'makeinlinelink := }
- { #0 'makeinlinelink := }
- if$
-}
-
-% Wrapper for fin.entry.original
-FUNCTION {fin.entry}
-{ output.web.refs % urlbst
- makeinlinelink % ooops, it appears we didn't have a title for inlinelink
- { possibly.setup.inlinelink % add some artificial link text here, as a fallback
- linktextstring output.nonnull }
- 'skip$
- if$
- bracket.state close.brackets = % urlbst
- { "]" * }
- 'skip$
- if$
- fin.entry.original
-}
-
-% Webpage entry type.
-% Title and url fields required;
-% author, note, year, month, and lastchecked fields optional
-% See references
-% ISO 690-2 http://www.nlc-bnc.ca/iso/tc46sc9/standard/690-2e.htm
-% http://www.classroom.net/classroom/CitingNetResources.html
-% http://neal.ctstateu.edu/history/cite.html
-% http://www.cas.usf.edu/english/walker/mla.html
-% for citation formats for web pages.
-FUNCTION {webpage}
-{ output.bibitem
- author empty$
- { editor empty$
- 'skip$ % author and editor both optional
- { format.editors output.nonnull }
- if$
- }
- { editor empty$
- { format.authors output.nonnull }
- { "can't use both author and editor fields in " cite$ * warning$ }
- if$
- }
- if$
- new.block
- title empty$ 'skip$ 'possibly.setup.inlinelink if$
- format.title "title" output.check
- inbrackets onlinestring output
- new.block
- year empty$
- 'skip$
- { format.date "year" output.check }
- if$
- % We don't need to output the URL details ('lastchecked' and 'url'),
- % because fin.entry does that for us, using output.web.refs. The only
- % reason we would want to put them here is if we were to decide that
- % they should go in front of the rather miscellaneous information in 'note'.
- new.block
- note output
- fin.entry
-}
-EOD
-
- print OUT "$mymarkerend\n\n\n";
-}
-
-
-sub output_replacement_function {
- my $emit_function = $_[0];
- my $function_name = $_[1];
- my $disabling_variable = $_[2];
- my $function_definition_string = $_[3];
-
- if ($emit_function > 0) {
- print OUT <<"EOD";
-%%% The style file $infile already supports $function_name,
-%%% but it might not do so in the same way as urlbst expects.
-%%% I've therefore left $infile 's function unchanged,
-%%% and disabled urlbst's version; proceed with some caution.
-EOD
-
- print STDERR "$progname: WARNING: style file $infile already includes a $function_name function;\nyou may need to disable the urlbst version by setting \$$disabling_variable to zero.\nYou might want to edit the output file (search for $function_name).\n";
-
- ($t = $function_definition_string) =~ s/\n/\n%%% /g;
- print OUT "%%% " . $t . "$mymarker\n";
- } else {
- print OUT $function_definition_string;
- }
- print OUT "\n";
-}
-
-sub print_missing_functions {
- # We've got to the bit of the file which handles the entry
- # types, so write out the webpage entry handler. This uses
- # the format.date function, which which many but not all
- # bst files have (for example, apalike doesn't). So
- # check that we either have found this function already, or
- # add it.
- if (! $found{formatdate}) {
- if ($found{entrymonth}) {
- print OUT <<'EOD';
-FUNCTION {format.date}
-{ year empty$
- { month empty$
- { "" }
- { "there's a month but no year in " cite$ * warning$
- month
- }
- if$
- }
- { month empty$
- 'year
- { month " " * year * }
- if$
- }
- if$
-}
-EOD
- } else {
- print OUT <<'EOD';
-FUNCTION {format.date}
-{ year empty$
- 'skip$
- { %write$
- "(" year * ")" *
- }
- if$
-}
-EOD
- }
- $found{formatdate} = 1;
- }
-
- # If the style file didn't supply a format.title function, then supply
- # one here (the {webpage} function requires it).
- if (! $found{formattitle}) {
- print OUT <<'EOD';
-FUNCTION {format.title}
-{ title empty$
- { "" }
- { title "t" change.case$ }
- if$
-}
-EOD
- $found{formattitle} = 1;
- }
-}
-
-# Utility function: Keep track of open and close braces in the string argument.
-# Keep state in $bracematchtotal, return the current value.
-sub bracematcher {
- my $s = shift;
- $s =~ s/[^\{\}]//g;
- #print "s=$s\n";
- foreach my $c (split (//, $s)) {
- $bracematchtotal += ($c eq '{' ? 1 : -1);
- }
- return $bracematchtotal;
-}
-
-# Utility function: use bracematcher to copy the complete block which starts
-# on or after the current line.
-sub copy_block {
- $bracematchtotal = 0;
- # copy any leading lines which don't have braces (presumably comments)
- while (defined ($line = <IN>) && ($line !~ /{/)) {
- print OUT $line;
- }
- while (defined ($line) && bracematcher($line) > 0) {
- print OUT $line;
- $line = <IN>;
- }
- print OUT "$line\n"; # print out terminating \} (assumed
- # alone on the line)
-}
diff --git a/Build/source/texk/texlive/linked_scripts/vpe/vpe.pl b/Build/source/texk/texlive/linked_scripts/vpe/vpe.pl
deleted file mode 100755
index ba93d8c4d75..00000000000
--- a/Build/source/texk/texlive/linked_scripts/vpe/vpe.pl
+++ /dev/null
@@ -1,430 +0,0 @@
-eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
- if 0;
-use strict;
-#
-# vpe.pl
-#
-# Copyright (C) 2000, 2012 Heiko Oberdiek.
-#
-# This program may be distributed and/or modified under the
-# conditions of the LaTeX Project Public License, either version 1.2
-# of this license or (at your option) any later version.
-# The latest version of this license is in
-# http://www.latex-project.org/lppl.txt
-# and version 1.2 or later is part of all distributions of LaTeX
-# version 1999/12/01 or later.
-#
-# See file "vpe.txt" for a list of files that belong to this project.
-#
-# This file "vpe.pl" may be renamed to "vpe"
-# for installation purposes.
-#
-my $prj = 'vpe';
-my $file = "$prj.pl";
-my $program = uc($&) if $file =~ /^\w+/;
-my $version = "0.2";
-my $date = "2012/04/18";
-my $author = "Heiko Oberdiek";
-my $copyright = "Copyright (c) 2000, 2012 by $author.";
-#
-# History:
-# 2000/09/15 v0.1: First release.
-# 2012/04/18 v0.2: Option --version added.
-#
-
-### program identification
-my $title = "$program $version, $date - $copyright\n";
-
-### editor call
-# %F: file name
-# %L: line number
-my $EditorCall = "xterm -e joe +%d %s";
-$EditorCall = $ENV{TEXEDIT} if $ENV{TEXEDIT};
-$EditorCall = $ENV{VPE} if $ENV{VPE};
-
-### error strings
-my $Error = "!!! Error:"; # error prefix
-
-my $usage = <<"END_OF_USAGE";
-${title}
-Depending on the name of the script `vpe' works in four modes:
-
-* [vpe] Syntax: vpe <pdf file>[.pdf]
- The pdf file is scanned for actions created by VTeX,
- that start an editor with the source file at the
- specified line under Windows.
- A symbol link is made from the source file name
- extended by the extension `.vpe' to this script.
- The line number is encoded in the path and the
- action is changed to start this script.
-
-* [sty] Internal for vpe.sty:
- Syntax: vpe --sty [--progname=...] <latex file> <vpe file>
-
-* [system] Internal for vpe.sty:
- Syntax: vpe --system <vpe file>
-
-* [launch] Syntax: <source file name>.vpe
- The script decodes the line number in the path of
- the source file name and starts an editor with
- this file at that line number.
-
-Options:
- --help: print usage
- --version print version number
- --verbose: print additional informations during running
- --force: force symbol links
- --delete: delete symbol links
- --sty: internal for `vpe.sty' (get absolute file name and lines)
- --system: internal for `vpe.sty' (get system info linux or win)
- --progname: latex, pdflatex, elatex, pdfelatex
-END_OF_USAGE
-
-### options
-$::opt_verbose = 0;
-$::opt_help = 0;
-$::opt_version = 0;
-$::opt_force = 0;
-$::opt_delete = 0;
-$::opt_sty = 0;
-$::opt_system = 0;
-$::opt_progname = "latex";
-use Getopt::Long;
-GetOptions(
- "help!",
- "version!",
- "verbose!",
- "force!",
- "delete!",
- "sty!",
- "system!",
- "progname=s",
-) or die $usage;
-if ($::opt_help) {
- die $usage;
-}
-if ($::opt_version) {
- print "$prj $date v$version\n";
- exit(0);
-}
-
-if ($::opt_sty and $::opt_system) {
- die "$usage" .
- "$Error Options --sty and --system cannot used together!\n";
-}
-
-###################
-### launch mode ###
-###################
-if ($0 =~ /\.vpe/) {
-
- @ARGV == 0 or
- die "$usage$Error Too many arguments [launch mode]!\n";
-
- my $file = "";
- $0 =~ m|(^[\./]+\./)(.+)\.vpe$| or
- die "$Error Cannot extract line number ($0)!\n";
- my $str = $1;
- $file = "/$2";
-
- my $line = "";
- while ($str ne "") {
- $str =~ m|^(/*)(\.?)\./(.*)$| or
- die "$Error Parse error!\n";
- $line .= length($1) + (($2 eq ".") ? 5 : 0);
- $str = $3;
- }
-
- my $callstr = $EditorCall;
- $EditorCall =~ s/%s/$file/;
- $EditorCall =~ s/%d/$line/;
- print "File: $file, line: $line\n" if $::opt_verbose;
- exec($EditorCall);
- exit 1;
-}
-
-###
-### used by both sty and system mode:
-###
-my $system = "linux";
-$system = "" if $^O =~ /os2/i;
-$system = "" if $^O =~ /mac/i;
-$system = "win" if $^O =~ /dos/i;
-$system = "win" if $^O =~ /win/i;
-
-################
-### sty mode ###
-################
-if ($::opt_sty) {
-
- @ARGV == 2 or
- die "$usage$Error Wrong arguments [sty mode]!\n";
-
- my $vpefile = $ARGV[1];
- print "VPE file: $vpefile\n" if $::opt_verbose;
-
- my $file = `kpsewhich -progname=$::opt_progname $ARGV[0]`;
- chomp $file;
- if (!($file =~ m|^/| or $file =~ m|^\w:|)) {
- use Cwd;
- $file = cwd() . "/" . $file;
- $file =~ s|/[^/]+/\.\./|/|g;
- $file =~ s|/\./|/|g;
- }
- -f $file or
- die "$Error Cannot find file `$file' [sty mode]!\n";
- print "File: $file\n" if $::opt_verbose;
-
- my $last = 0;
- if (open(IN, $file)) {
- while (<IN>) {
- $last++;
- }
- }
- if ($last == 0) {
- $last = 10000;
- }
- print "Last line: $last\n" if $::opt_verbose;
-
- open(OUT, ">>$vpefile") or
- die "$Error Cannot open file `$vpefile`!\n";
- print OUT "\\vpeentry{$file}{$last}\n";
-
- exit 1;
-}
-
-###################
-### system mode ###
-###################
-if ($::opt_system) {
-
- @ARGV == 1 or
- die "$usage$Error Wrong arguments [system mode]!\n";
-
- my $vpefile = $ARGV[0];
- print "VPE file: $vpefile\n" if $::opt_verbose;
-
- open(OUT, ">>$vpefile") or
- die "$Error Cannot open file `$vpefile`!\n";
- print OUT "\\vpesystem{$system}\n";
-
- exit 1;
-}
-
-################
-### vpe mode ###
-################
-if (@ARGV < 1) {
- die "$usage$Error Missing pdf file [vpe mode]!\n";
-}
-if (@ARGV > 2) {
- die "$usage$Error Too many arguments [vpe mode]!\n";
-}
-
-my $pdffile = $ARGV[0];
-if (!-f $pdffile) {
- my $name = $pdffile;
- $pdffile .= ".pdf";
- -f $pdffile or
- die "$Error File `$name' not found [vpe mode]!\n";
-}
-
-open(IN, "+<$pdffile") or
- die "$Error Cannot open `$pdffile' [vpe mode]!\n";
-binmode(IN);
-my %symlinks = ();
-while (<IN>) {
-
- if (m|/F\([\./]*(/.*)\.vpe\)|) {
- $symlinks{$1} = 1;
- next;
- }
-
- my $do = 0;
- my ($action, $file, $line, $type);
- # my $color; # only for debugging
-
- if (m|^
- /A \s* << \s*
- /Type \s* /Action \s*
- /S \s* /Launch \s*
- /Win \s* << \s*
- /F \s* \(aftcomp.exe\) \s*
- /P \s* \("(.*)\" \s+ \d+\-(\d+)\) \s*
- >> \s*
- >> \s*
- $
- |x
- ) {
- $action = $_;
- $file = $1;
- $line = $2;
- # $color = "/C[0 0 1]"; # only for debugging
- $type = "aftcomp";
- $do = 1;
- }
-
- if (m|^
- /A \s* << \s*
- /Type \s* /Action \s*
- /S \s* /Launch \s*
- /Win \s* << \s*
- /F \s* \(repos.exe\) \s*
- /P \s* \(
- "(.*)" \s*
- "(\d+)" \s*
- "(.*)" \s*
- "(\d+)"
- \) \s*
- >> \s*
- >> \s*
- $
- |x
- ) {
- $action = $_;
- if ($3 eq "") {
- $file = $1;
- $line = $2;
- }
- else {
- # ???
- $file = $1;
- $line = $2;
- }
- # $color = "/C[1 0 0]"; # only for debugging
- $type = "repos";
- $do = 1;
- }
-
- if ($do) {
- my $length = length($action);
- print "* File: $file, line: $line, type: $type\n" if $::opt_verbose;
-
- if (!($file =~ m|^/|)) {
- print STDERR "$Error File `$file' lacks of absolute path!\n";
- next;
- }
-
- if (!$::opt_delete) {
- if ($line <= 0) {
- $line = 1;
- }
-
- my $newaction = "";
- {
- my $digit = substr($line, 0, 1);
- if ($digit <= 5) {
- $newaction .= "/" x $digit;
- }
- else {
- $newaction .= "/" x ($digit - 5) . ".";
- }
- $newaction .= "./";
- my $rest = $line;
- while (($rest = substr($rest, 1)) ne "") {
- $digit = substr($rest, 0, 1);
- if ($digit < 5) {
- $newaction .= "/" x $digit;
- }
- else {
- $newaction .= "/" x ($digit - 5) . ".";
- }
- $newaction .= "./";
- }
- }
- $newaction .= substr($file, 1) . ".vpe";
- $newaction = # $color . # only for debugging
- "/A<</Type/Action/S/Launch/F($newaction)>>";
- $newaction .= " " x ($length - length($newaction) - 1);
- if (length($newaction) > $length) {
- print STDERR "$Error Action too long!\n";
- next;
- }
-
- seek(IN, -length($action), 1);
- print IN $newaction;
- }
-
- $symlinks{$file} = 1;
- }
-}
-
-if (keys(%symlinks)) {
-
- my $this = $0;
- if (!$::opt_delete) {
- if (!-f $0 or !-x $0) {
- $this = `which $0`;
- ($this ne "") or die "$Error Cannot find this script!\n";
- }
- if (!($this =~ m|^/|)) {
- use Cwd;
- $this = cwd() . "/" . $this;
- }
- $this =~ s|/[^/]+/\.\./|/|g;
- $this =~ s|/\./|/|g;
- }
-
- if ($::opt_delete) {
- print "Delete symlinks:\n";
- }
- else {
- if ($::opt_force) {
- print "Forced symlinks to $this:\n";
- }
- else {
- print "Symlinks to $this:\n";
- }
- }
-
- foreach (keys(%symlinks)) {
- my $sym = $_ . ".vpe";
- print " $sym [";
-
- if ($::opt_delete) {
- if (!-l $sym) {
- print "ok, not existing]\n";
- next;
- }
- unlink($sym);
- if (!-l $sym) {
- print "ok, deleted]\n";
- next;
- }
- print "failed]\n";
- next;
- }
- if ($::opt_force) {
- if (-l $sym) {
- unlink($sym);
- if (-l $sym) {
- print "deletion failed]\n";
- next;
- }
- if (symlink($this, $sym)) {
- print "ok, deleted and created]\n";
- next;
- }
- print "deleted, creation failed]\n";
- next;
- }
- if (symlink($this, $sym)) {
- print "ok, created]\n";
- next;
- }
- print "creation failed]\n";
- next;
- }
- if (-f $sym) {
- print "exists]\n";
- next;
- }
- if (symlink($this, $sym)) {
- print "ok, created]\n";
- next;
- }
- print "failed]\n";
- next;
- }
-}
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/webquiz/webquiz.py b/Build/source/texk/texlive/linked_scripts/webquiz/webquiz.py
deleted file mode 100755
index de1e052fb7c..00000000000
--- a/Build/source/texk/texlive/linked_scripts/webquiz/webquiz.py
+++ /dev/null
@@ -1,1124 +0,0 @@
-#!/usr/bin/env python3
-r'''
-------------------------------------------------------------------------------
- webquiz | Online quizzes generated from LaTeX using python and TeX4ht
- | This module mainly deals with command-line options and
- | settings and then calls MakeWebQuiz to build the quiz
-------------------------------------------------------------------------------
- Copyright (C) Andrew Mathas and Donald Taylor, University of Sydney
-
- Distributed under the terms of the GNU General Public License (GPL)
- http://www.gnu.org/licenses/
-
- This file is part of the WebQuiz system.
-
- <Andrew.Mathas@sydney.edu.au>
-------------------------------------------------------------------------------
-'''
-
-import argparse
-import codecs
-import errno
-import glob
-import os
-import re
-import shutil
-import signal
-import subprocess
-import sys
-
-# imports of webquiz code
-import webquiz_makequiz
-import webquiz_templates
-import webquiz_util
-
-#################################################################################
-# read in basic meta data such as author, version, ... and set debugging=False
-try:
- metadata = webquiz_util.MetaData(webquiz_util.kpsewhich('webquiz.ini'), debugging=False)
-except subprocess.CalledProcessError:
- # check to see if we are running from the zip file
- ini_file = os.path.join(webquiz_util.webquiz_file(''), '..', 'latex', 'webquiz.ini')
- try:
- metadata = webquiz_util.MetaData(ini_file, debugging=False)
- except (FileNotFoundError, subprocess.CalledProcessError):
- print(webquiz_templates.missing_webquiz_ini.format(ini_file))
- sys.exit(1)
-
-# ---------------------------------------------------------------------------------------
-def graceful_exit(sig, frame):
- ''' exit gracefully on SIGINT and SIGTERM'''
- if metadata:
- webquiz_util.webquiz_error(False, 'program terminated (signal {}\n {})'.format(sig, frame))
- else:
- webquiz_util.webquiz_error(False, 'program terminated (signal {})'.format(sig))
-
-signal.signal(signal.SIGINT, graceful_exit)
-signal.signal(signal.SIGTERM, graceful_exit)
-
-
-#################################################################################
-def preprocess_with_pst2pdf(options, quiz_file):
- r'''
- Preprocess the latex file using pst2pdf. As we are preprocessing the file it
- is not enough to have latex pass us a flag that tells us to use pst2pdf.
- Instead, we have to extract the class file option from the tex file
-
- INPUT: quiz_file should be the name of the quiz file, WITHOUT the .tex extension
- '''
- options.talk('Preprocessing {} with pst2pdsf'.format(quiz_file))
- try:
- # pst2pdf converts pspicture environments to svg images and makes a
- # new latex file quiz_file+'-pdf' that includes these
- cmd = 'pst2pdf --svg --imgdir={q_file} {q_file}.tex'.format(q_file=quiz_file)
- # pst2pdf is missing a #!-header so we need shell=True
- options.run(cmd, shell=True)
- except OSError as err:
- if err.errno == errno.ENOENT:
- webquiz_util.webquiz_error(options.debugging, 'pst2pdf not found. You need to install pst2pdf to use the pst2pdf option', err)
- else:
- webquiz_util.webquiz_error(options.debugging, 'error running pst2pdf on {}'.format(quiz_file), err)
-
- # match \includegraphics commands
- fix_svg = re.compile(r'(\\includegraphics\[scale=1\])\{('+quiz_file+r'-fig-[0-9]*)\}')
- # the svg images are in the quiz_file subdirectory but latex can't
- # find them so we update the tex file to look in the right place
- try:
- with codecs.open(quiz_file + '-pdf.tex', 'r', encoding='utf8') as pst_file:
- with codecs.open(quiz_file + '-pdf-fixed.tex', 'w', encoding='utf8') as pst_fixed:
- for line in pst_file:
- pst_fixed.write(fix_svg.sub(r'\1{%s/\2.svg}' % quiz_file, line))
- except OSError as err:
- webquiz_util.webquiz_error(options.debugging,
- 'there was an problem running pst2pdf for {}'.format(quiz_file),
- err
- )
-
-class WebQuizSettings:
- r'''
- Class for initialising webquiz. This covers both reading and writing the
- webquizrc file and copying files into the web directories during
- initialisation. The settings themselves are stored in the attribute
- settings, which is a dictionary. The class reads and writes the settings to
- the webquizrc file and the values of the settings are available as items:
- >>> wq = WebQuizSettings()
- >>> wq['webquiz_url']
- ... /WebQuiz
- >>> wq['webquiz_url'] = '/new_url'
- '''
-
- # default of settings for the webquizrc file - a dictionary of dictionaries
- # the 'help' field is for printing descriptions of the settings to help the
- # user - they are also printed in the webquizrc file
- settings = dict(
- webquiz_url={
- 'default': '',
- 'advanced': False,
- 'help': 'Relative URL for the webquiz web directory',
- },
- webquiz_www={
- 'default': '',
- 'advanced': False,
- 'help': 'Full path to WebQuiz web directory',
- },
- language={
- 'default': 'english',
- 'advanced': False,
- 'help': 'Default language used on web pages'
- },
- engine = {
- 'default': 'latex',
- 'advanced': False,
- 'help': 'Default TeX engine used to compile web pages',
- 'values': dict(latex='', lua='--lua', xelatex='--xetex')
- },
- theme={
- 'default': 'default',
- 'advanced': False,
- 'help': 'Default colour theme used on web pages'
- },
- breadcrumbs={
- 'default': '',
- 'advanced': False,
- 'help': 'Breadcrumbs at the top of quiz page',
- },
- department={
- 'default': '',
- 'advanced': False,
- 'help': 'Name of department',
- },
- department_url={
- 'default': '/',
- 'advanced': False,
- 'help': 'URL for department',
- },
- institution={
- 'default': '',
- 'advanced': False,
- 'help': 'Institution or university',
- },
- institution_url={
- 'default': '/',
- 'advanced': False,
- 'help': 'URL for institution or university',
- },
- hide_side_menu={
- 'default': 'false',
- 'advanced': False,
- 'help': 'Do not display the side menu at start of quiz',
- },
- one_page={
- 'default': 'false',
- 'advanced': False,
- 'help': 'Display questions on one page',
- },
- random_order={
- 'default': 'false',
- 'advanced': False,
- 'help': 'Randomly order the quiz questions',
- },
- webquiz_layout={
- 'default': 'webquiz_layout',
- 'advanced': True,
- 'help': 'Name of python module that formats the quizzes',
- },
- make4ht={
- 'default': '',
- 'advanced': True,
- 'help': 'Build file for make4ht',
- },
- mathjax={
- 'default':
- 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js',
- 'advanced':
- True,
- 'help':
- 'URL for mathjax',
- },
- version={
- 'advanced': False,
- 'help': 'WebQuiz version number for webquizrc settings',
- })
-
- # by default we assume we don't need to print a initialisation warning
- initialise_warning = ''
-
- # turn debugging on by default because any error message that we hit before
- # we process the command line options really should not happen
- debugging = True
-
- # keep track of whether we have initialised
- have_initialised = False
-
- def __init__(self):
- '''
- First read the system webquizrc file and then read the
- to use some system settings and to override others.
-
- By default, there is no webquiz initialisation file. We first
- look for webquizrc in the webquiz source directory and then
- for .webquizrc file in the users home directory.
- '''
- self.settings['version']['default'] = metadata.version
- for key in self.settings:
- self.settings[key]['value'] = self.settings[key]['default']
- if not 'editable' in self.settings[key]:
- self.settings[key]['editable'] = False
-
- # define user and system rc file and load the ones that exist
-
- TEXMFLOCAL=''
- try:
- TEXMFLOCAL = webquiz_util.kpsewhich('-var-value TEXMFLOCAL')
- except subprocess.CalledProcessError:
- pass
-
- if TEXMFLOCAL == '':
- TEXMFLOCAL = webquiz_util.kpsewhich('-var-value TEXMFMAIN')
-
- self.system_rcfile = os.path.join(TEXMFLOCAL, 'tex', 'latex', 'webquiz', 'webquizrc')
- self.read_webquizrc(self.system_rcfile)
-
- # the user rc file defaults to:
- # ~/.dotfiles/config/webquizrc if .dotfiles/config exists
- # ~/.config/webquizrc if .config exists
- # and otherwise to ~/.webquizrc
- if os.path.isdir(os.path.join(os.path.expanduser('~'), '.dotfiles', 'config')):
- self.user_rcfile = os.path.join(os.path.expanduser('~'), '.dotfiles', 'config', 'webquizrc')
- elif os.path.isdir(os.path.join(os.path.expanduser('~'), '.config')):
- self.user_rcfile = os.path.join(os.path.expanduser('~'), '.config', 'webquizrc')
- else:
- self.user_rcfile = os.path.join(os.path.expanduser('~'), '.webquizrc')
-
- self.read_webquizrc(self.user_rcfile)
-
- def webquiz_debug(self, msg):
- r'''
- Customised debugging message for the MakeSettings module
- '''
- webquiz_util.webquiz_debug(self.debugging, 'main: '+msg)
-
- def webquiz_error(self, msg, err=None):
- r'''
- Customised error messages for the Module
- '''
- webquiz_util.webquiz_error(self.debugging, 'settings: '+msg, err)
-
- def __getitem__(self, key):
- r'''
- Return the value of the corresponding setting. That is, it returns
- self.settings[key]['value']
- and an error if the key is unknown.
- '''
- if key in self.settings:
- return self.settings[key]['value']
-
- self.webquiz_error('getitem: unknown setting "{}" in webquizrc.'.format(key))
-
- def __setitem__(self, key, value):
- r'''
- Set the value of the corresponding setting. This is the equivalent of
- self.settings[key]['value'] = value
- and an error if the key is unknown.
- '''
- if key in self.settings:
- self.settings[key]['value'] = value
- else:
- self.webquiz_error('setitem: unknown setting "{}" in webquizrc'.format(key))
-
- def read_webquizrc(self, rcfile, must_exist=False):
- r'''
- Read the settings from the specified webquizrc file - if it exists, in
- which case set self.rcfile equal to this directory. If the file does
- not exist then return without changing the current settings.
- '''
- if os.path.isfile(rcfile):
- try:
- with codecs.open(rcfile, 'r', encoding='utf8') as webquizrc:
- for line in webquizrc:
- if '#' in line: # remove comments
- line = line[:line.index('#')]
- if '=' in line:
- key, value = line.split('=')
- key = key.strip().lower().replace('-','_')
- value = value.strip()
- if key in self.settings:
- if value != self[key]:
- self[key] = value
- elif key != '':
- self.webquiz_error('unknown setting "{}" in {}'.format(key, rcfile))
-
- # record the rcfile for later use
- self.rcfile = rcfile
-
- except OSError as err:
- self.webquiz_error('there was a problem reading the rc-file {}'.format(rcfile), err)
-
- except Exception as err:
- self.webquiz_error('there was an error reading the webquizrc file,', err)
-
- elif must_exist:
- # this is only an error if we have been asked to read this file
- self.webquiz_error('the rc-file "{}" does not exist'.format(rcfile))
-
- def keys(self):
- r'''
- Return a list of keys for all settings, ordered alphabetically with the
- advanced options last/
- '''
- return sorted(self.settings.keys(), key=lambda k: '{}{}'.format(self.settings[k]['advanced'], k))
-
- def write_webquizrc(self):
- r'''
- Write the settings to the webquizrc file, defaulting to the user
- rcfile if unable to write to the system rcfile
- '''
- if not hasattr(self, 'rcfile'):
- # when initialising an rcfile will not exist yet
- self.rcfile = self.system_rcfile
-
- file_not_written = True
- while file_not_written:
- try:
- dire = os.path.dirname(self.rcfile)
- if dire != '' and not os.path.isdir(dire):
- os.makedirs(dire, exist_ok=True)
- with codecs.open(self.rcfile, 'w', encoding='utf8') as rcfile:
- for key in self.keys():
- # Only save settings in the rcfile if they have changed
- # Note that changed means changed from the last read
- # rcfile rather than from the default (of course, the
- # defaults serve as the "initial rcfile")
- if key == 'version' or self.settings[key]['default']!=self[key]:
- rcfile.write('# {}\n{:<17} = {}\n'.format(
- self.settings[key]['help'],
- key.replace('_','-'),
- self[key])
- )
-
- print('\nWebQuiz settings saved in {}\n'.format( self.rcfile))
- input('Press RETURN to continue... ')
- file_not_written = False
-
- except (OSError, PermissionError) as err:
- # if writing to the system_rcfile then try to write to user_rcfile
- alt_rcfile = self.user_rcfile if self.rcfile != self.user_rcfile else self.system_rcfile
- response = input(
- webquiz_templates.rc_permission_error.format(
- error=err,
- rcfile=self.rcfile,
- alt_rcfile=alt_rcfile))
- if response.startswith('2'):
- self.rcfile = alt_rcfile
- elif response.startswith('3'):
- rcfile = input('WebQuiz rc-file: ')
- print('\nTo access this rc-file you will need to use: webquiz --rcfile {} ...'.format(rcfile))
- self.rcfile = os.path.expanduser(rcfile)
- elif not response.startswith('1'):
- print('exiting...')
- sys.exit(1)
-
- def list_settings(self, setting='all'):
- r'''
- Print the non-default settings for webquiz from the webquizrc
- '''
- if not hasattr(self, 'rcfile'):
- print(webquiz_templates.initialise_settings)
- sys.exit(1)
-
- if setting not in ['all', 'verbose', 'help']:
- setting = setting.replace('-', '_')
- if setting in self.settings:
- print(self.settings[setting]['value'])
- else:
- self.webquiz_error('{} is an invalid setting'.format(setting))
-
- elif setting=='all':
- dash = '-'*len('WebQuiz rc-file: {}'.format(self.rcfile))
- print('{dash}\nWebQuiz rc-file: {rcfile}\n{dash}'.format(rcfile=self.rcfile, dash=dash))
- for key in self.keys():
- print('{:<17} = {}'.format(key.replace('_', '-'), self[key]))
- print('{dash}'.format(dash=dash))
-
- elif setting=='help':
- for key in self.keys():
- print('{:<17} {}'.format(key.replace('_', '-'), self.settings[key]['help'].lower()))
-
- else:
- print('WebQuiz settings from {}'.format(self.rcfile))
- for key in self.keys():
- print('# {}{}\n{:<17} = {:<17} {}'.format(
- self.settings[key]['help'],
- ' (advanced)' if self.settings[key]['advanced'] else '',
- key.replace('_', '-'),
- self[key],
- '(default)' if self[key]==self.settings[key]['default'] else ''
- )
- )
-
- def initialise_webquiz(self, need_to_initialise=False, developer=False):
- r'''
- Set the root for the WebQuiz web directory and copy the www files into
- this directory. Once this is done save the settings to webquizrc.
- This method should only be used when WebQuiz is being set up.
-
- If `need_to_initialise` is `True` then this is a forced initialisation.
- '''
-
- # keep track of whether we have initialised
- self.have_initialised = True
-
- if need_to_initialise:
- self.initialise_warning = webquiz_templates.web_initialise_warning
- initialise = input(webquiz_templates.initialise_invite)
- if initialise!='' and initialise.strip().lower()[0]!='y':
- self['webquiz_url'] = 'http://www.maths.usyd.edu.au/u/mathas/WebQuiz'
- return
-
- if self['webquiz_url']=='':
- self['webquiz_url'] = '/WebQuiz'
-
- # prompt for directory and copy files - are these reasonable defaults
- # for each OS?
- if sys.platform == 'darwin':
- default_root = '/Library/WebServer/Documents/WebQuiz'
- platform = 'Mac OSX'
- elif sys.platform.startswith('win'):
- default_root = 'c:\inetpub\wwwroot\WebQuiz'
- platform = 'Windows'
- else:
- default_root = '/var/www/html/WebQuiz'
- platform = sys.platform.capitalize()
-
- if self['webquiz_www'] != '':
- webquiz_root = self['webquiz_www']
- else:
- webquiz_root = default_root
-
- print(webquiz_templates.initialise_introduction)
- input('Press RETURN to continue... ')
-
- print(webquiz_templates.webroot_request.format(
- platform=platform,
- webquiz_dir = webquiz_root)
- )
- input('Press RETURN to continue... ')
-
- files_copied = False
- while not files_copied:
- web_dir = input('\nWebQuiz web directory:\n[{}] '.format(webquiz_root))
- if web_dir == '':
- web_dir = webquiz_root
- else:
- web_dir = os.path.expanduser(web_dir)
-
- print('Web directory set to {}'.format(web_dir))
- if web_dir=='SMS':
- # undocumented: allow links to SMS web pages
- self['webquiz_www'] = 'SMS'
- self['webquiz_url'] = 'http://www.maths.usyd.edu.au/u/mathas/WebQuiz'
-
- else:
- try:
- # ...remove the doc directory
- web_doc = os.path.join(web_dir, 'doc')
- if os.path.isfile(web_doc) or os.path.islink(web_doc):
- os.remove(web_doc)
- elif os.path.isdir(web_doc):
- shutil.rmtree(web_doc)
-
- # Need to locate the www directory, which should be a subdirectory
- # of the webquiz doc directory. First try using texdoc
- webquiz_doc = ''
- try:
- webquiz_pdf = webquiz_util.shell_command('texdoc --list --machine webquiz.pdf').split()[-1]
- if webquiz_pdf.endswith('webquiz.pdf'):
- webquiz_doc = os.path.dirname(webquiz_pdf)
- except subprocess.CalledProcessError:
- pass
-
- # if texdoc failed then try using TEXMFMAIN
- if webquiz_doc=='':
- try:
- webquiz_doc = os.path.join(webquiz_util.kpsewhich('-var-value TEXMFMAIN'), 'doc','latex', 'webquiz')
- except subprocess.CalledProcessError:
- pass
-
- # if we still don't have webquiz_doc then try working backwards from webquiz.cls
- # unlikely to work if TEXMFMAIN doesn't
- if not os.path.isdir(webquiz_doc):
- parent = os.path.dirname
- try:
- texdist_dir = parent(parent(parent(parent(parent(webquiz_util.kpsewhich('webquiz.cls'))))))
- except subprocess.CalledProcessError:
- print(webquiz_templates.not_installed.format(metadata.repository))
- sys.exit(1)
-
- webquiz_doc = os.path.join(texdist_dir, 'doc', 'latex', 'webquiz')
-
- # get the root directory of the source code for developer
- # mode and just in case webquiz_www still does not exist
- webquiz_src = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-
- webquiz_www = os.path.join(webquiz_doc, 'www')
- if not os.path.isdir(webquiz_www):
- webquiz_www = os.path.join(webquiz_src, 'doc', 'www')
-
- if developer and os.path.isdir(os.path.join(webquiz_src, 'doc')):
- # this is a development version so add links from the
- # web directory to the css,doc and js directories
- print('\nInstalling files for development version')
- print('Linking web files {} -> {} ...\n'.format(web_dir, webquiz_src))
- if not os.path.exists(web_dir):
- os.makedirs(web_dir)
-
- for (src, target) in [('javascript', 'js'), ('css', 'css'), ('doc', 'doc')]:
- newlink = os.path.join(web_dir, target)
- try:
- os.remove(newlink)
- except FileNotFoundError:
- pass
- try:
- os.symlink(os.path.join(webquiz_src,src), newlink)
- except OSError as err:
- print('There was a problem linking {}: {}'.format(newlink, err))
-
- else:
- # loop until we find some files to install or exit
- while not os.path.isdir(webquiz_www) or webquiz_www=='':
- print('\nUnable to find the WebQuiz web files')
- webquiz_www = input('Please enter the location of the WebQuiz www directory\nor press RETURN to exit: ')
- webquiz_www = os.path.expanduser(webquiz_www)
- if webquiz_www=='':
- sys.exit()
- if not (webquiz_www.endswith('www/') or webquiz_www.endswith('www')):
- print('\nThe webquiz web directory is called www, so\n {}\ncannot be the right directory.'.format(
- webquiz_www)
- )
- webquiz_www = False
-
-
- # the www directory exists so we copy it to web_dir
- print('\nCopying web files to {} ...'.format(web_dir))
- webquiz_util.copytree(webquiz_www, web_dir)
-
- self['webquiz_www'] = web_dir
- files_copied = True
-
- except PermissionError:
- print(webquiz_templates.permission_error.format(web_dir))
-
- except OSError as err:
- print(webquiz_templates.oserror_copying.format(web_dir=web_dir, err=err))
-
- if self['webquiz_www']!='SMS':
- # now prompt for the relative url
- webquiz_url = input(webquiz_templates.webquiz_url_message.format(self['webquiz_url']))
- if webquiz_url != '':
- # removing trailing slashes from webquiz_url
- while webquiz_url[-1] == '/':
- webquiz_url = webquiz_url[:len(webquiz_url) - 1]
-
- if webquiz_url[0] != '/': # force URL to start with /
- webquiz_url = '/' + webquiz_url
-
- if not web_dir.endswith(webquiz_url):
- print(webquiz_templates.webquiz_url_warning)
- input('Press RETURN to continue... ')
-
- self['webquiz_url'] = webquiz_url
-
- # save the settings and exit
- self.write_webquizrc()
- print(webquiz_templates.initialise_ending.format(web_dir=self['webquiz_www']))
-
- def edit_settings(self):
- r'''
- Change current default values for the WebQuiz settings
- '''
- advanced_not_started = True
- for key in self.keys():
- if key not in ['webquiz_www', 'version']:
- if advanced_not_started and self.settings[key]['advanced']:
- print(webquiz_templates.advanced_settings)
- advanced_not_started = False
-
- skey = '{}'.format(self[key])
- setting = input('{}{}[{}]: '.format(
- self.settings[key]['help'],
- ' ' if len(skey)<40 else '\n',
- skey
- )
- ).strip()
- if setting != '':
- if key == 'webquiz_url' and setting[0] != '/':
- print(" ** prepending '/' to webquiz_url **")
- setting = '/' + setting
-
- elif key == 'webquiz_layout':
- setting = os.path.expanduser(setting)
- if setting.endswith('.py'):
- print(" ** removing .py extension from webquiz_layout **")
- setting = setting[:-3]
-
- elif key == 'engine' and setting not in self.settings['engine'].values:
- print('setting not changed: {} is not a valid TeX engine'.format(setting))
- setting = self['engine']
-
- elif key in ['hide_side_menu', 'random_order']:
- setting = setting.lower()
- if setting not in ['true', 'false']:
- print('setting not changed: {} must be True or False'.format(key))
- setting = self[key]
-
- elif setting=='NONE':
- setting = ''
-
- self[key] = setting
-
- # save the settings, print them and exit
- self.write_webquizrc()
- self.list_settings()
-
- def tex_install(self):
- r'''
- Install the tex files into the standard locations in TEXMFMAIN:
- scripts -> TEXMFMAIN/scripts/webquiz
- doc -> TEXMFMAIN/doc/latex/webquiz
- latex -> TEXMFMAIN/tex/latex/webquiz
- It is assumed that this is run from the zipfile installation. There
- is little in the way of error checking or debugging.
-
- Undocumented feature - useful for debugging initialisation routine
- '''
- webquiz_top = os.path.abspath(webquiz_util.webquiz_file('..'))
- texmf = webquiz_util.kpsewhich('-var-value TEXMFMAIN')
- for (src, target) in [('scripts', 'scripts'),
- ('latex', 'tex/latex'),
- ('doc', 'doc/latex')]:
- try:
- webquiz_util.copytree(os.path.join(webquiz_top,src), os.path.join(texmf, target, 'webquiz'))
-
- except (FileExistsError,FileNotFoundError):
- continue
-
- except PermissionError as err:
- print(webquiz_templates.insufficient_permissions.format(err))
- sys.exit(1)
-
- try:
-
- # add a link to webquiz.py
- texbin = os.path.dirname(shutil.which('pdflatex'))
- if sys.platform.startswith('win'):
- shutil.copyfile(
- os.path.join(texmf,'scripts','webquiz','webquiz.bat'),
- os.path.join(texbin, 'webquiz.bat')
- )
- else:
- os.symlink(
- os.path.join(texmf,'scripts','webquiz','webquiz.py'),
- os.path.join(texbin, 'webquiz')
- )
- subprocess.call('mktexlsr', shell=True)
-
- except (FileExistsError,FileNotFoundError):
- pass
-
- except PermissionError as err:
- print(webquiz_templates.insufficient_permissions.format(err))
- sys.exit(1)
-
- except subprocess.CalledProcessError as err:
- self.webquiz_error('There was a problem running mktexlsr', err)
-
- def tex_uninstall(self):
- r'''
- UnInstall the tex files into TEXMFMAIN. It is assumed that the files
- are installed in the natural locations in the TEXMFMAIN tree, namely:
- scripts -> TEXMFMAIN/scripts/webquiz
- doc -> TEXMFMAIN/doc/latex/webquiz
- latex -> TEXMFMAIN/tex/latex/webquiz
- There is little in the way of error checking or debugging.
-
- Undocumented feature - useful for debugging initialisation routine
- '''
- webquiz_top = os.path.abspath(webquiz_util.webquiz_file('..'))
- texmf = webquiz_util.kpsewhich('-var-value TEXMFMAIN')
- for target in ['scripts', 'tex/latex', 'doc/latex']:
- try:
- shutil.rmtree(os.path.join(texmf, target, 'webquiz'))
-
- except (FileExistsError,FileNotFoundError):
- pass
-
- except PermissionError as err:
- print(webquiz_templates.insufficient_permissions.format(err))
- sys.exit(1)
-
- try:
- # remove link from texbin to webquiz.py
- texbin = os.path.dirname(shutil.which('pdflatex'))
- if sys.platform.startswith('win'):
- os.remove(os.path.join(texbin, 'webquiz.bat'))
- else:
- os.remove(os.path.join(texbin, 'webquiz'))
-
- except (FileExistsError,FileNotFoundError):
- pass
-
- except PermissionError as err:
- print(webquiz_templates.insufficient_permissions.format(err))
- sys.exit(1)
-
- # remove any rcfiles that exist in obvious places
- try:
- if os.path.isfile(self.system_rcfile):
- os.remove(self.system_rcfile)
- if os.path.isfile(self.user_rcfile):
- os.remove(self.user_rcfile)
- if os.path.isfile(self.rcfile):
- os.remove(self.rcfile)
- except PermissionError:
- print(webquiz_templates.insufficient_permissions.format(err))
- sys.exit(1)
-
- # remove link to webquiz.py
- texbin = os.path.dirname(shutil.which('pdflatex'))
- try:
- if sys.platform.startswith('win'):
- webquiz = os.path.join(texbin, 'webquiz.bat')
- os.remove(webquiz)
- else:
- webquiz = os.path.join(texbin,'webquiz')
- target = os.readlink(webquiz)
- if target==os.path.join(texmf,'scripts','webquiz','webquiz.py'):
- os.remove(webquiz)
-
- except (FileExistsError,FileNotFoundError):
- pass
-
- except OSError as err:
- print('There was a problem removing the link to webquiz: {}'.format(err))
-
- def uninstall_webquiz(self):
- r'''
- Remove all of the webquiz files from the webserver
- '''
-
- if os.path.isdir(self['webquiz_www']):
- remove = input('Do you really want to remove the WebQuiz from your web server [N/yes]? ')
- if remove != 'yes':
- print('WebQuiz unistall aborted!')
- return
-
- try:
- shutil.rmtree(self['webquiz_www'])
- print('WebQuiz files successfully removed from {}'.format(self['webquiz_www']))
-
- except PermissionError as err:
- print(webquiz_templates.insufficient_permissions.format(err))
- sys.exit(1)
-
- except OSError as err:
- self.webquiz_error('There was a problem removing webquiz files from {}'.format(self['webquiz_www']), err)
-
- # now reset and save the locations of the webquiz files and URL
- self['webquiz_url'] = ''
- self['webquiz_www'] = ''
- self.write_webquizrc()
-
- else:
- self.webquiz_error('uninstall: no webwquiz files are installed on your web server??')
-
- for rfile in ['system', 'user']:
- rcfile = getattr(self, rfile+'_rcfile')
- if os.path.isfile(rcfile):
- rm = input('Remove {} rcfile {}\n[Y/no] '.format(rfile, rcfile))
- if rm != 'no':
- try:
- os.remove(rcfile)
- except (OSError, PermissionError) as err:
- self.webquiz_error('There was a problem deleting {}'.format(rcfile), err)
-
-
-# =====================================================
-if __name__ == '__main__':
- try:
- settings = WebQuizSettings()
-
- # parse the command line options
- parser = argparse.ArgumentParser(description=metadata.description)
-
- parser.add_argument(
- 'quiz_file',
- nargs='*',
- type=str,
- default=None,
- help='latex quiz files')
-
- parser.add_argument(
- '-q',
- '--quiet',
- action='count',
- default=0,
- help='Suppress tex4ht messages (also -qq etc)')
-
- parser.add_argument(
- '-d', '--draft',
- action='store_true',
- default=False,
- help='Use make4ht draft mode')
-
- parser.add_argument(
- '-s',
- '--shell-escape',
- action='store_true',
- default=False,
- help='Shell escape for tex4ht/make4ht')
-
- engine = parser.add_mutually_exclusive_group()
- engine.add_argument(
- '--latex',
- action='store_const',
- const='latex',
- default=settings['engine'],
- dest='engine',
- help='Use latex to compile document with make4ht (default)')
- engine.add_argument(
- '-l',
- '--lua',
- action='store_const',
- const='lua',
- dest='engine',
- help='Use lualatex to compile the quiz')
- engine.add_argument(
- '-x',
- '--xelatex',
- action='store_const',
- const='xelatex',
- dest='engine',
- help='Use xelatex to compile the quiz')
-
- parser.add_argument(
- '-r',
- '--rcfile',
- action='store',
- default=None,
- help='Specify location of the webquiz rc-file ')
-
- settings_parser = parser.add_mutually_exclusive_group()
- settings_parser.add_argument(
- '-i',
- '--initialise',
- '--initialize',
- action='store_true',
- default=False,
- help='Install web components of webquiz')
- settings_parser.add_argument(
- '-e', '--edit-settings',
- action='store_true',
- default=False,
- help='Edit default settings for webquiz')
- settings_parser.add_argument(
- '--settings',
- action='store',
- const='all',
- default='',
- nargs='?',
- type=str,
- help='List default settings for webquiz'
- )
- settings_parser.add_argument(
- '--developer',
- action='store_true',
- default=False,
- help=argparse.SUPPRESS
- )
-
- # options suppressed from the help message
- parser.add_argument(
- '-m',
- '--make4ht',
- action='store',
- type=str,
- dest='make4ht_options',
- default=settings['make4ht'],
- help=argparse.SUPPRESS
- )
-
- parser.add_argument(
- '--webquiz_layout',
- action='store',
- type=str,
- dest='webquiz_layout',
- default=settings['webquiz_layout'],
- help=argparse.SUPPRESS
- )
-
- install_parser = parser.add_mutually_exclusive_group()
- install_parser.add_argument(
- '--tex-install',
- action='store_true',
- default=False,
- help=argparse.SUPPRESS
- )
- install_parser.add_argument(
- '--tex-uninstall',
- action='store_true',
- default=False,
- help=argparse.SUPPRESS
- )
- install_parser.add_argument(
- '--uninstall',
- action='store_true',
- default=False,
- help=argparse.SUPPRESS
- )
-
- parser.add_argument(
- '--version',
- action='version',
- version='%(prog)s version {}'.format(metadata.version),
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--debugging',
- action='store_true',
- default=False,
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--shorthelp',
- action='store_true',
- default=False,
- help=argparse.SUPPRESS
- )
-
- # parse the options
- options = parser.parse_args()
- options.prog = parser.prog
-
- # set debugging mode from options
- settings.debugging = options.debugging
-
- # read the rcfile and throw an error if we are not adjusting the settings
- if options.rcfile is not None:
- rcfile = os.path.expanduser(options.rcfile)
- settings.read_webquizrc(rcfile)
-
- if options.uninstall:
- # uninstall web files and exit
- settings.uninstall_webquiz()
- sys.exit()
- elif options.tex_install:
- # install files from zip file into tex distribution and then exit
- settings.tex_install()
- sys.exit()
- elif options.tex_uninstall:
- # install files from zip file into tex distribution and then exit
- settings.tex_uninstall()
- sys.exit()
-
- # initialise and exit
- if options.initialise or options.developer:
- settings.initialise_webquiz(developer=options.developer)
-
- # force initialisation if the url is not set
- elif settings['webquiz_url'] == '':
- settings.initialise_webquiz(need_to_initialise=True)
-
- # list settings and exit
- if options.settings != '':
- settings.list_settings(options.settings)
- sys.exit()
-
- # edit settings and exit
- if options.edit_settings:
- settings.edit_settings()
- sys.exit()
-
- # print short help and exit
- if options.shorthelp:
- parser.print_usage()
- sys.exit()
-
- # if no filename then exit
- if options.quiz_file==[]:
- if settings.have_initialised:
- sys.exit()
- else:
- parser.print_help()
- sys.exit(1)
-
- # import the local page formatter
- mod_dir, mod_layout = os.path.split(options.webquiz_layout)
- if mod_dir != '':
- sys.path.insert(0, mod_dir)
- options.write_web_page = __import__(mod_layout).write_web_page
-
- # run() is a shorthand for executing system commands depending on the quietness
- # - we need to use shell=True because otherwise pst2pdf gives an error
- # options.talk() is a shorthand for letting the user know what is happening
- if options.quiet == 0:
- options.run = webquiz_util.run
- options.talk = lambda msg: print(msg)
- elif options.quiet == 1:
- options.run = webquiz_util.quiet_run
- options.talk = lambda msg: print(msg)
- else:
- options.run = webquiz_util.silent_run
- options.talk = lambda msg: None
-
- # run through the list of quizzes and make them
- for quiz_file in options.quiz_file:
- if len(options.quiz_file) > 1 and options.quiet < 3:
- print('Making web page for {}'.format(quiz_file))
-
- quiz_name, ext = os.path.splitext(quiz_file) # extract filename and extension
- # quiz_file is assumed to be a tex file if no extension is given
- if ext=='':
- ext = '.tex'
- quiz_file += ext
-
- # windows likes adding a prefix of '.\\'to filename and this causes havoc with latex
- if os.path.dirname(quiz_file)=='.':
- quiz_file = os.path.basename(quiz_file)
-
- if ext not in ['.tex', '.xml']:
- webquiz_util.webquiz_error(True, 'unrecognised file extension {}'.format(ext))
-
- if not os.path.isfile(quiz_file):
- webquiz_util.webquiz+error(True, 'WebQuiz error: cannot read file {}'.format(quiz_file))
-
- # the quiz name and the quiz_file will be different if pst2pdf is used
- quiz_name = quiz_file
- if options.quiet < 2:
- print('WebQuiz generating web page for {}'.format(quiz_file))
-
- options.pst2pdf = False
- if ext==".tex":
- # If the pst2pdf option is used then we need to preprocess
- # the latex file BEFORE passing it to MakeWebQuiz. Set
- # options.pst2pdf = True if pst2pdf is given as an option to
- # the webquiz documentclass
- with codecs.open(quiz_file, 'r', encoding='utf8') as q_file:
- doc = q_file.read()
-
- try:
- brac = doc.index(r'\documentclass[') + 15 # start of class options
- if 'pst2pdf' in [
- opt.strip()
- for opt in doc[brac:brac+doc[brac:].index(']')].split(',')
- ]:
- preprocess_with_pst2pdf(options, quiz_file[:-4])
- options.pst2pdf = True
- # now run webquiz on the modified tex file
- quiz_file = quiz_file[:-4] + '-pdf-fixed.tex'
- except ValueError:
- pass
-
- # the file exists and is readable so make the quiz
- webquiz_makequiz.MakeWebQuiz(quiz_name, quiz_file, options, settings, metadata)
-
- quiz_name, ext = os.path.splitext(quiz_name) # extract filename and extension
-
- # move the css file into the directory for the quiz
- css_file = os.path.join(quiz_name, quiz_name + '.css')
- if os.path.isfile(quiz_name + '.css'):
- if os.path.isfile(css_file):
- os.remove(css_file)
- shutil.move(quiz_name + '.css', css_file)
-
- # now clean up unless debugging
- if not options.debugging:
- for ext in ['4ct', '4tc', 'dvi', 'idv', 'lg', 'log',
- 'ps', 'pdf', 'tmp', 'xml', 'xref'
- ]:
- if os.path.isfile(quiz_name + '.' + ext):
- os.remove(quiz_name + '.' + ext)
-
- # files created when using pst2pdf
- if options.pst2pdf:
- for file in glob.glob(quiz_name + '-pdf.*'):
- os.remove(file)
- for file in glob.glob(quiz_name + '-pdf-fixed.*'):
- os.remove(file)
- for extention in ['.preamble', '.plog', '-tmp.tex',
- '-pst.tex', '-fig.tex'
- ]:
- if os.path.isfile(quiz_name + extention):
- os.remove(quiz_name + extention)
- if os.path.isdir(os.path.join(quiz_name, quiz_name)):
- shutil.rmtree(os.path.join(quiz_name, quiz_name))
-
- if settings.initialise_warning != '' and not settings.have_initialised:
- print(webquiz_templates.text_initialise_warning)
-
- except Exception as err:
-
- # there is a small chance that there is an error before the
- # settings.debugging flag has been set
- webquiz_util.webquiz_error(settings.debugging if 'settings' in globals() else True,
- 'unknown problem.\n\nIf you think this is a bug please report it by creating an issue at\n {}\n'
- .format(metadata.repository), err)
diff --git a/Build/source/texk/texlive/linked_scripts/wordcount/wordcount.sh b/Build/source/texk/texlive/linked_scripts/wordcount/wordcount.sh
deleted file mode 100755
index 8e1c80473e2..00000000000
--- a/Build/source/texk/texlive/linked_scripts/wordcount/wordcount.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/sh
-# wordcount.sh 1.7 Copyright 2016/06/03 Michael John Downes
-
-# Following Michael's death, his family have requested that his TeX
-# related files are made publicly available under the LPPL license.
-#
-# This file is available under the LaTeX Project Public License version 1
-# or (at your option) any later version.
-# https://latex-project.org/lppl/
-# (LPPL maintenance status: unmaintained)
-#
-# This is a Unix Bourne shell script that counts the characters and
-# spaces in a LaTeX document by running it through LaTeX using
-# wordcount.tex, and then counting the lines in the resulting
-# wordcount.log file that match a special pattern. It assumes that you
-# have a program "grep" with a -c option meaning "Report the number of
-# matching lines". To use perl or some other tool instead of grep,
-# redefine $COUNT in some suitable way, below.
-#
-# The characters that are counted with this method are actual font
-# characters in the page body (excluding running heads): in math, each
-# subscript and superscript character is counted separately, even when
-# they appear one over the other; and so are the separate combining
-# pieces used to make large delimiters. Interword spaces are counted as
-# separate characters, and so are the spaces around mathrel symbols in
-# math formulas (equal signs and the like)---but not the spaces around
-# mathbin symbols (plus, minus, and the like).
-#
-# You can count words by dividing the character count by 5 (or
-# whatever), or by counting the occurrences of interword spaces. The
-# latter method (illustrated here) is highly accurate at counting the
-# actual number of words---until tables or math formulas enter the
-# picture. In the case of tables, the number of words will tend to be
-# overestimated because tabskip glue, counted as an interword space,
-# appears on both sides of each table cell. (Not counting the tabskip
-# glue at all would result in an underestimate, and the underestimate
-# would tend to be slightly less accurate than the overestimate that we
-# have chosen to do.)
-#
-# And of course, in the case of math formulas, how do you define what is
-# a "word"?
-
-SCRIPT=`basename $0`
-LOGFILE=wordcount.log
-COUNT="grep -c"
-LATEX=latex
-
-die () {
- echo "$@ was apparently unsuccessful."
- exit 1
-}
-
-no_files_msg () {
- echo "$SCRIPT: At least one file name must be supplied" \
- "on the command line."
- exit 1
-}
-
-case X$1 in
- X) no_files_msg ;;
- *) : ;;
-esac
-
-for f in "$@"
-do
- # Since \? is not defined by LaTeX itself, this use via \csname causes
- # it to be defined as \relax, and it then serves as a filename
- # terminator. And within wordcount.tex if \? is found to be no longer
- # undefined, certain messages are suppressed.
- echo "$f" | $LATEX 'wordcount.tex\csname ?\endcsname' || die "LaTeX run"
- # Count interword spaces and end-of-paragraph spaces
- words=`$COUNT '3[.]0863[35]' $LOGFILE` || die "Log search"
- # Count nonspace characters and interword spaces
- chars=`$COUNT '3[.]0863[23]' $LOGFILE` || die "Log search"
- # If you want to see what the log file looks like, comment out the
- # following line:
- rm $LOGFILE
- echo "$f contains $chars characters and $words words."
-done
diff --git a/Build/source/texk/texlive/linked_scripts/xindex/xindex.lua b/Build/source/texk/texlive/linked_scripts/xindex/xindex.lua
deleted file mode 100755
index a29fdb0d65a..00000000000
--- a/Build/source/texk/texlive/linked_scripts/xindex/xindex.lua
+++ /dev/null
@@ -1,252 +0,0 @@
-#!/usr/bin/env texlua
------------------------------------------------------------------------
--- FILE: xindex.lua
--- DESCRIPTION: create an index
--- REQUIREMENTS:
--- AUTHOR: Herbert VoĂź
--- LICENSE: LPPL 1.3
------------------------------------------------------------------------
-
- xindex = xindex or { }
- local version = 0.28
-xindex.version = version
---xindex.self = "xindex"
-
---[[doc--
-
-xindex(1)
-
-This file is provided under the terms of the LPPL v1.3 or
-later as printed in full text in the manual (xindex.pdf).
-
-\url{https://ctan.org/license/lppl1.3}.
-
-Report bugs to
-
- \url{https://gitlab.com/hvoss49/xindex/issues}.
-
---doc]]--
-
-kpse.set_program_name("luatex")
-
-local f = kpse.find_file("lualibs.lua")
-print ("filename "..f)
-require("lualibs") -- all part of LuaTeX
-require('unicode')
-require('string')
-require("lpeg")
-
-
-local args = require ('xindex-lapp') [[
- parameter handling
- -q,--quiet
- -h,--help
- -v... Verbosity level; can be -v, -vv, -vvv
- -c,--config (default cfg)
- -e,--escapechar (default ")
- -n,--noheadings
- -a,--no_casesensitive
- -o,--output (default "")
- -l,--language (default en)
- -p,--prefix (default L)
- -u,--use_UCA
- <input> (string)
-]]
-
-
---[[
- No -v flag, v is just { false }. not args.v[1] is true, so vlevel becomes 0.
- One -v flags, v is { true }
- Two -v flags, v is { true, true }
- Three -v flags, v is { true, true, true }
-]]
-
-vlevel = not args.v[1] and 0 or #args.v
-not_quiet = not args["quiet"]
-
-local luaVersion = _VERSION
-if (luaVersion < "Lua 5.3") then
- print("=========================================")
- print("Sorry. but we need at least LuaTeX 1.09")
- print("Leaving program xindex")
- print("=========================================")
- os.exit()
-end
-
---local inspect = require 'inspect'
---print(inspect(args))
-
---[[
-if args.h then
-print(
-Syntax: xinput [options] <file>
-By default the Lua program "xindex" creates a so-called
-.ind file, which has the same main filename as the input file
-unless you are using the option "-o <output file>" There will
-be no log file created.
-)
-end
-]]
-
-
---[[
-if not args["input"] then
- io.write ("Filename: ")
- inFile = io.read()
-else
- inFile = args["input"]
-end
-]]
-
-require('xindex-lib')
-
-inFile = args["input"]
-if not file_exists(inFile) then
- if file_exists(inFile..".idx") then
- inFile = inFile..".idx"
- else
- writeLog(2,"Inputfile "..inFile.." or "..inFile..".idx not found!\n",0)
- os.exit()
- end
-end
-
-local filename
-local logfilename
-if args["output"] == '""' then
- if inFile:sub(inFile:len()-3,inFile:len()) == ".idx" then
- filename = inFile:sub(1,inFile:len()-3).."ind"
- logfilename = inFile:sub(1,inFile:len()-3).."ilg"
- else
- filename = inFile..".ind"
- logfilename = inFile..".ilg"
- end
-else
- filename = args.output
- logfilename = filename:gsub('%p...','')..".ilg"
-end
-
-logFile = io.open(logfilename,"w+")
-writeLog(2,"xindex v."..version.." (c) Herbert VoĂź\n",-1)
-writeLog(1,"Verbose level = "..vlevel.."\n",1)
-
-writeLog(2,"Open outputfile "..filename,0)
-outFile = io.open(filename,"w+")
-writeLog(2," ... done\n",0)
-
-if vlevel > 0 then
- writeLog(1,"---------- parameter ----------\n",1)
- for k,v in pairs(args) do
- writeLog(1,tostring(k)..", "..tostring(v).."\n",1)
- end
- for k=1,#args.v do
- writeLog(1,"v["..k.."]= "..tostring(args.v[k]).."\n",1)
- end
- writeLog(1,"---------- parameter ----------\n",1)
-end
-
-writeLog(2,"Using input file: "..inFile.."\n",0)
-
-labelPrefix = args.prefix
-writeLog(2,"Label prefix: "..labelPrefix.."\n",-1)
-
-writeLog(2,"Loading common config file ".."xindex-cfg-common\n",1)
-Config_File_Common = kpse.find_file("xindex-cfg-common.lua")
-cfg_common = require(Config_File_Common)
-
-local config_file = "xindex-"..args.config..".lua"
-writeLog(2,"Loading local config file "..config_file,0)
-Config_File = kpse.find_file(config_file)
-cfg = require(Config_File)
-writeLog(2," ... done\n",0)
-
--- Create the character list maps for faster sorting
-
-alphabet_lower_map = CreateCharListMap(alphabet_lower)
-alphabet_upper_map = CreateCharListMap(alphabet_upper)
-
-local esc_char = args.escapechar
-writeLog(2,"Escapechar = "..esc_char.."\n",1)
-escape_chars = { -- by default " is the escape char
- {esc_char..'"', '//escapedquote//', '"' },
- {esc_char..'@', '//escapedat//', '@' },
- {esc_char..'|', '//escapedvert//', '|' },
- {esc_char..'!', '//scapedexcl//', '!' },
- {esc_char..'(', '//escapedparenleft//', '(' },
- {esc_char..')', '//escapedparenright//',')' }
-}
-
-language = "en" -- default language
-
-language = string.lower(args["language"]):sub(1, 2)
-writeLog(2,"Language = "..language.."\n",1)
-if (indexheader[language] == nil) then
- writeLog(2,'Corrected the unknown language "'..language..'" to "en"'.."\n",0)
- language = "en"
-end
-index_header = indexheader[language]
-if vlevel > 0 then for i=1,#index_header do writeLog(2,index_header[i].."\n",1) end end
-if (folium[language] == nil) then
- writeLog(2,'Corrected the unknown language "'..language..'" for page folium to "en"'.."\n",0)
- page_folium = folium["en"]
-else
- page_folium = folium[language]
-end
-
-use_UCA = args["use_UCA"]
-if use_UCA then
- writeLog(1,"Will use LUA-UCA\n",1)
- ducet = require "lua-uca.lua-uca-ducet"
- collator = require "lua-uca.lua-uca-collator"
- languages = require "lua-uca.lua-uca-languages"
- collator_obj = collator.new(ducet)
-
- local uca_config_file = "xindex-cfg-uca.lua"
- writeLog(2,"Loading local UCA config file "..uca_config_file,0)
- UCA_Config_File = kpse.find_file(uca_config_file)
- uca_cfg = require(UCA_Config_File)
- writeLog(2," ... done\n",0)
-
--- language name specified on the command line doesn't seem to be available
--- in the config file, so we just try to find it ourselves
- for i, a in ipairs(arg) do
- if a == "-l" or a=="--language" then
- language = arg[i+1]
- break
- end
- end
-
- if languages[language] then
- print("[Lua-UCA] Loading language: " .. language)
- collator_obj = languages[language](collator_obj)
- end
-else
- writeLog(1,"Will _not_ use LUA-UCA\n",1)
-end
-
-upper = unicode.utf8.upper
-
-no_caseSensitive = args["no_casesensitive"]
-if no_caseSensitive then
- writeLog(1,"Sorting will be no case sensitive\n",1)
-else
- writeLog(1,"Sorting will be case sensitive\n",1)
-end
-
-no_headings = args["noheadings"]
-if no_headings then
- writeLog(1,"Output with NO headings between different first letter\n",1)
-else
- writeLog(1,"Output with headings between different first letter\n",1)
-end
-
-writeLog(2,"Open outputfile "..filename,0)
-outFile = io.open(filename,"w+")
-writeLog(2,"... done\n",0)
-
-
-writeLog(1,"Starting base file ... \n",2)
-BaseRunFile = kpse.find_file("xindex-base.lua")
-dofile(BaseRunFile)
-
-logFile:close()
-
diff --git a/Build/source/texk/texlive/linked_scripts/yplan/yplan b/Build/source/texk/texlive/linked_scripts/yplan/yplan
deleted file mode 100755
index 1bd69f867da..00000000000
--- a/Build/source/texk/texlive/linked_scripts/yplan/yplan
+++ /dev/null
@@ -1,326 +0,0 @@
-#!/usr/bin/perl
-# ===========
-# Filename : yplan[.pl]
-# Revision : 0.3, 2000-03-14
-# Purpose : Writes LaTeX2e code for an A4 year-planner,
-# : in the style designed by Dick Nickalls
-# Author : John Palmer,
-# : using matter from Dick Nickalls and Harald Harders
-# ===========
-# Revision History
-# 0.3, 2000-03-14 avoids long lines in the program where possible
-# 0.2, 2000-03-08 YEAR arg mandatory; PAGE arg added;
-# error-messages changed
-# 0.1, 2000-02-18 alternative languages added (after Harald Harders)
-# 2000-02-11 adding the bulk of the boilerplate
-# (copied from Dick Nickalls)
-# 1999-08-28 dividing into two pages and adding more TeX boilerplate
-# 1999-08-18 program begun: first attempt to align days of week
-# ===========
-# Usage: yplan LANGUAGE LETTERCASE PAGE YEAR >FILE.tex
-# where:
-# LANGUAGE is one of: english, german, french, italian, spanish,
-# portuguese, swedish, latin; if omitted, english is assumed;
-# LETTERCASE is one of: uppercase, lowercase; controls the setting
-# of month-names; if omitted, uppercase is assumed;
-# PAGE is one of: p1, p2; selects the first or second six months
-# of the chosen YEAR; if omitted, both pages are printed;
-# YEAR must be written with four digits;
-# FILE.tex is where to put the generated LaTeX code.
-# Acceptable variants:
-# Arguments wholly or partly in uppercase are translated to
-# lowercase.
-# Arguments are recognised even if given in the wrong order.
-# You may write any argument with - or / at the start, and, in
-# general, obvious extra characters at start and end of arguments
-# are ignored.
-# Fatal errors:
-# The program will stop with an error-message in these cases:
-# if YEAR missing; if YEAR <1999; if LANGUAGE not in the set above.
-# Location: in CTAN at macros/latex/contrib/other/yplan/yplan.pl
-#============
-# Things to do:
-#============
-sub Leapyear
-{
- my $year = shift; # one argument
- if (($year%4) != 0) {return 0}
- elsif (($year%400) == 0) {return 1}
- elsif (($year%100) == 0) {return 0}
- else {return 1};
-}
-#============
-# Multilingual facilities Copyright 1999 Harald Harders
-# <harald.harders@dlr.de>
-# Adapted to Perl, with Swedish, Latin extensions,
-# by John Palmer, 2000
-
-@{$MonthsOfYear{english}} =
-('','January','February','March','April','May','June',
-'July','August','September','October','November','December');
-@{$DaysOfWeek{english}} = ('Su','Mo','Tu','We','Th','Fr','Sa');
-$LY{english} = 'leap year';
-
-@{$MonthsOfYear{german}} =
-( '','Januar','Februar','M\"arz','April','Mai','Juni',
-'Juli','August','September','Oktober','November','Dezember');
-@{$DaysOfWeek{german}} = ('So','Mo','Di','Mi','Do','Fr','Sa','So');
-$LY{german}= 'Schaltjahr';
-
-@{$MonthsOfYear{french}} =
-('','Janvier',"F\\'evrier",'Mars','Avril','Mai','Juin',
-'Juillet','Ao\^ut','Septembre','Octobre','Novembre',"D\\'ecembre");
-@{$DaysOfWeek{french}} = ('Di','Lu','Ma','Me','Je','Ve','Sa');
-$LY{french}= "ann\\'ee bissextile";
-
-@{$MonthsOfYear{italian}} =
-('','Gennaio','Febbraio','Marzo','Avrile','Maggio','Giugno',
-'Luglio','Agosto','Septembre','Ottobre','Novembre','Dicembre');
-@{$DaysOfWeek{italian}} = ('Do','Lu','Ma','Me','Gi','Ve','Sa');
-$LY{italian}= 'anno di salto';
-
-@{$MonthsOfYear{spanish}} =
-('','Enero','Febrero','Marcha','Abril','Mayo','Junio',
-'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre');
-@{$DaysOfWeek{spanish}} = ('Do','Lu','Ma','Mi','Ju','Vi',"S\\'a");
-$LY{spanish}= 'A\~no bisiesto';
-
-@{$MonthsOfYear{portuguese}} =
-('','Janeiro','Fevereiro','Mar\c{c}o','Abril','Maio','Junho',
-'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro');
-# \c needs special treatment when converting to uppercase
-@{$DaysOfWeek{portuguese}} =
-('Dom','Seg','Ter','Qua','Qui','Sex',"S\\'ab");
-$LY{portuguese}= 'Ano de pulo';
-
-@{$MonthsOfYear{swedish}} =
-('','Januari','Februari','Mars','April','Mai','Juni',
-'Juli','Augusti','September','October','November','December');
-@{$DaysOfWeek{swedish}} =
-('S\"o','M\aa{}','Ti','On','To','Fr','L\"o');
-$LY{swedish} = 'skott\aa{}r';
-
-@{$MonthsOfYear{latin}} =
-('','Ianuarius','Februarius','Martius','Aprilis','Maius','Iunius',
-'Iulius','Augustus','Septembris','Octobris','Nouembris','Decembris');
-@{$DaysOfWeek{latin}} = ('So','Lu','Ma','Me','Io','Ve','Sa');
-$LY{latin} = 'annvs bissextilis';
-# use v not u as it will be set as \textsc
-# Antiquarian note:
-# There is evidence for a seven-day cycle in Latin-speaking
-# communities in the 1st cent. AD. The days are: (dies) Solis,
-# Lunae, Martis, Mercurii, Iouis, Veneris, Saturni. Iulius, Augustus
-# were originally Quintilis, Sextilis but were renamed after two
-# personages of the 1st cent. BC. In Latin of this period there is
-# no distinction between I and J (I used for both) or between
-# U and V (lowercase u, uppercase V). ---JP
-#============
-# Set default values for the arguments:
-$Year = '';
-$Language = 'english';
-$Monthcase = 'uppercase';
-$Page = '';
-
-# Override them by actual arguments:
-foreach (@ARGV)
-{
- if ($_ =~ m/(p1|p2)/i) { $Page = lc $1 }
- elsif ($_ =~ m/([0-9]+)/) { $Year = $1 }
- elsif ($_ =~ m/(uppercase|lowercase)/i) { $Monthcase = lc $1 }
- elsif ($_ =~ m/([a-z]+)/i) { $Language = lc $1 };
-};
-if ($Year !~ /^\d+$/)
-{ die "Usage: yplan [language] [lowercase] [page] year >file.tex\n" };
-if ($Year < 1999)
-{ die "Years < 1999 not available\n" };
-if (! exists $MonthsOfYear{$Language})
-{ die "Language $Language not available\n" };
-if ($Monthcase =~ m/uppercase/)
-{ foreach (@{$MonthsOfYear{$Language}})
- { $_ = uc $_; $_ =~ s/\\C/\\c/g;
- if ($Language eq 'latin') {$_ =~ s/U/V/g}
- }
-};
-$shortYear = $Year ; $shortYear =~ s/..(..)/$1/ ;
-#============
-# count days from 1999 January 1 to $Year January 1:
-$thisYear = 1999 ;
-$startDayofWeek[1] = 5 ;
-# 1999 January 1 is a Friday. 0=Sunday,1=Monday,etc.
-# count days from 1999 January 1 to $Year January 1:
-while ($thisYear < $Year)
-{
- $daysinYear = Leapyear($thisYear) ? 366 : 365 ;
- $startDayofWeek[1] = $startDayofWeek[1] + $daysinYear ;
- $thisYear++;
-};
-$startDayofWeek[1] = $startDayofWeek[1] % 7 ;
-#============
-# make a list of the lengths of months:
-@monthLengths =
-( 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ) ;
-$Ly = '';
-if (Leapyear($thisYear))
-{ $monthLengths[2] = 29 ; $Ly = $LY{$Language} };
-#============
-# for each month, determine the day of week of day 1 of the month
-for ($i=1; $i<12; $i++)
-{
- $startDayofWeek[1+$i] =
- ( $startDayofWeek[$i] + $monthLengths[$i] ) % 7;
-};
-#============
-# for each month, write an appropriately shifted array of daysofMonth;
-# meantime determine the greatest index (plus one) to any such array:
-$stopRow = 0;
-for ($i=1; $i<=12; $i++)
-{
- $monthVec[$i] = (); # create the array
- $j = $startDayofWeek[$i];
- $k = 1;
- while ($k <= @monthLengths[$i])
- {
- ${$monthVec[$i]}[$j] = $k;
- $k++; $j++;
- };
- if ($stopRow < $j) { $stopRow = $j };
-};
-#============
-# fill in $monthVec[0] with the days of week:
-$j = 0;
-for ($i=0; $i<$stopRow; $i++)
-{
- ${$monthVec[0]}[$i] = $j; $j++; $j %= 7;
-};
-#============
-# determine the least of @startDayofWeek:
-$topDayofWeek = 6;
-for ($i=1; $i<=12; $i++)
-{
- if ($startDayofWeek[$i]<$topDayofWeek)
- {$topDayofWeek=$startDayofWeek[$i]}
-};
-#============
-# emit the opening boilerplate:
-print <<ENDFRONT;
-%% Yplan
-%% Vertical year-planner calendar
-%%
-%% ---------------------------
-%% Copyright 1999 RWD Nickalls, 2000 John Palmer
-%% Multlingual support based on yplan.sty,
-%% copyright 1999 Harald Harders
-%% This program Yplan[.pl] can be redistributed and/or modified
-%% under the terms of the LaTeX Project Public License distributed
-%% from CTAN archives in directory macros/latex/base/lppl.txt;
-%% either version 1 of the License, or any later version.
-%% --------------------------
-%% Author of the original LaTeX source:
-%% Dr RWD Nickalls,
-%% Department of Anaesthesia,
-%% City Hospital,
-%% Nottingham, UK.
-%%
-%% dicknickalls\@compuserve.com
-%% TEL: +44-(0)-115-9691169 Ext:45637
-%% FAX: +44-(0)-115-9627713
-%%
-%% Author of the original multilingual package:
-%% Harald Harders,
-%% harald.harders\@dlr.de
-%%
-%% Author of the Perl program:
-%% John W Palmer,
-%% johnp\@bcs.org.uk
-%%
-%% Designed for LaTeX 2e, although it can be easily adapted for
-%% use with LaTeX 2.09, since it is only a big table.
-%%
-%% I designed this year planner as one year my
-%% A4 diary had no good year planner at the end
-%% The vertical size can be adjusted by changing \datestrut.
-%% ---enjoy! RWDN
-%%
-%%------------------------------------
-\\documentclass[a4paper]{article}
-%%------------------------------------
-\\setlength{\\topmargin}{-1cm}
-\\setlength{\\oddsidemargin}{-13.5mm}
-\\setlength{\\textwidth}{18.5cm}
-%%
-\\newcommand{\\monthstrut}{\\rule{0pt}{12pt}}
-%% \\monthstrut controls the white space above the month.
-%%
-\\newcommand{\\datestrut}{\\rule{0pt}{12pt}}
-%% \\datestrut controls the white space above the date.
-%%
-\\newcommand{\\bs}{\$\\backslash\$}
-%% Used in the footnotes.
-%%--------------------------------------
-\\begin{document}
-%---------------
-%% no pagenumbering
-\\pagestyle{empty}
-%--------------------
-ENDFRONT
-#============
-# start emitting rows. In each row, col 0 is a dayofWeek,
-# the remainder are daysofMonth for different months.
-
-$ema=6; $emb=12;
-if ($Page eq 'p1') { $emb = 6 } elsif ($Page eq 'p2') { $ema = 12 };
-for($endmonth=$ema; $endmonth<=$emb; $endmonth+=6)
-{
-print <<ENDHEAD;
-\\begin{table}
-\\hspace{1cm} {\\LARGE $Year}\\qquad\\textsc{$Ly}\\\\
-{\\ } \\\\
-\\begin{tabular}{|c||p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|}
-ENDHEAD
- print '%%',"\n";
- print '\hline',"\n";
- print ' \multicolumn{1}{|c||}{\monthstrut\ }',"\n" ;
- for ($j=$endmonth-5; $j<=$endmonth; $j++)
- {
- print ' & \multicolumn{1}{|c|}{',
- ${$MonthsOfYear{$Language}}[$j],'}',"\n";
- };
- print "\\\\\n\\hline\n\\hline\n";
- for ($i=$topDayofWeek; $i<$stopRow; $i++)
- {
- print '\datestrut ',
- ${$DaysOfWeek{$Language}}[${$monthVec[0]}[$i]];
- for ($j=$endmonth-5; $j<=$endmonth; $j++)
- {
- if ($j>0) { print ' & ' };
- print ${$monthVec[$j]}[$i];
- };
- print " \\\\\n"; # that's space, two backslashes and a newline
- if (${$monthVec[0]}[$i]==0) # Sunday
- { print '\hline\hline',"\n" } # full double rule at `end' of week
- else
- { print '\cline{1-1}'; # always put rule in day-of-week column
- for ($j=$endmonth-5; $j<=$endmonth; $j++)
- { if (${$monthVec[$j]}[$i] || ${$monthVec[$j]}[$i+1])
- { print '\cline{',($j-$endmonth+7),'-',($j-$endmonth+7),'}' }
- # in month columns put rule only above or below a day-number
- };
- print "\n";
- if ($i==$stopRow-1) { print '\hline',"\n" };
- # end of tabular matter
- };
- };
-print <<ENDFOOT;
-\\end{tabular}
-{\\ } \\\\
-%%\\newcommand{\\bs}{\$\\backslash\$}
-\\textsc{ctan}/macros/latex/contrib/other/yplan/yplan.pl%
-\\hfill\\hbox{\\copyright{} 1999 RWD Nickalls, H Harders, 2000 J Palmer}
-\\end{table}
-%-----------------
-ENDFOOT
-};
-print '\end{document}',"\n";
-#============
-# End of program
-#============
diff --git a/Build/source/texk/texlive/tests/updmap-cmdline-test.pl b/Build/source/texk/texlive/tests/updmap-cmdline-test.pl
deleted file mode 100755
index 955796f06cc..00000000000
--- a/Build/source/texk/texlive/tests/updmap-cmdline-test.pl
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env perl
-# $Id$
-# Public domain. Originally written 2011, Karl Berry.
-# Check that updmap can parse various cmdline invocations.
-
-# srcdir = texlive (in the source tree)
-BEGIN { chomp ($srcdir = $ENV{"srcdir"} || `cd \`dirname $0\`/.. && pwd`); }
-require "$srcdir/../tests/common-test.pl";
-
-exit (&main ());
-
-sub main {
- my $ret = &test_run ("$srcdir/linked_scripts/texlive/updmap.pl","--version");
-
- # erroneous invocations we should check for and/or handle better:
- # updmap foo
- # updmap --enable Map
-
- my $bad = $ret != 0;
- return $bad;
-}
diff --git a/Build/source/texk/texlive/tl_support/ChangeLog b/Build/source/texk/texlive/tl_support/ChangeLog
deleted file mode 100644
index 2db19b13364..00000000000
--- a/Build/source/texk/texlive/tl_support/ChangeLog
+++ /dev/null
@@ -1,906 +0,0 @@
-2020-05-28 Karl Berry <karl@freefriends.org>
-
- * Makefile.am (run-texlinks): do nothing if the texlinks script
- or the needed fmtutil.cnf do not exist or are empty files. This
- can happen with, e.g., --disable-texlive.
- (texlinks_fmtutil): new variable for fmtutil.cnf location.
- ($(DESTDIR)$(bindir)/texlinks,
- $(DESTDIR)$(web2cdir)/fmtutil.cnf): remove targets, since we check
- explicitly for the files now. make install must be run first.
- Report from Andreas Scherer,
- https://tug.org/pipermail/tlbuild/2020q1/004614.html.
-
-2020-01-31 Karl Berry <karl@freefriends.org>
-
- * mktexlsr.1,
- * mktexmf.1,
- * mktexpk.1: replace @KPATHSEA_VERSION@ with current info,
- since these are no longer substituted.
-
-2020-01-30 Karl Berry <karl@tug.org>
-
- * mktextfm.1: mention new MF_MODE_EXTRA_INFO feature.
-
-2019-12-29 Karl Berry <karl@tug.org>
-
- * mktexlsr.1,
- * mktexmf.1,
- * mktexpk.1,
- * mktextfm.1: add here, moved from
- Build/source/texk/kpathsea/man. Not yet sure of the best way
- to handle the man pages for Master-maintained scripts, but this will
- suffice for now.
- * Makefile.am (dist_man_MANS): add mktex{lsr,mf,pk,tfm}.man.
- (man1_links): add mktexlsr:texhash.
-
-2017-12-18 Karl Berry <karl@tug.org>
-
- * texconfig.sh: more updates from Norbert to use tlmgr (from 45882).
-
-2017-04-24 Paul Vojta <vojta@math.berkeley.edu>
-
- * texconfig.sh: xdvi paper size updates (also in TLPaper.pm).
- Also, no more dvipdfm "config" file.
-
-2017-04-16 Karl Berry <karl@tug.org>
-
- * texconfig.sh: remove references to dvipdfm, since it is no
- longer separate from dvipdfmx.
- * tcfmgr.map (config): likewise.
- (pdftexconfig.tex): now in tex/generic/tex-ini-files.
- From Paul Vojta.
-
-2017-03-28 Karl Berry <karl@tug.org>
-
- * Makefile.am (xupdmap.1,xfmtutil.1): also make /tmp/*.html.
-
-2016-03-18 Karl Berry <karl@tug.org>
-
- * texconfig-dialog.sh (cleanup): termCtl ctl rather than reset,
- to avoid altering user's terminal settings.
- http://tug.org/pipermail/tex-live/2016-March/037852.html
-
-2015-04-27 Karl Berry <karl@tug.org>
-
- * Makefile.am (xmans): new phony target.
-
-2015-04-20 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Remove fmtutil-sys.sh and updmap-sys.sh, they are
- maintained under Master and now handled via linked_scripts.
-
-2015-04-19 Karl Berry <karl@tug.org>
-
- * texlinks.sh (install_link): use $exeext for pdfcsplain too,
- for Cygwin. From Ken Brown.
-
-2015-04-12 Norbert Preining <norbert@preining.info>
-
- * Makefile.am: remove fmtutil.sh, it is now handled via
- linked_scripts and fmtutil.pl
-
-2014-11-20 Karl Berry <karl@tug.org>
-
- * fmtutil.sh: (init_log_warnings, log_warning): remove.
- (main): change log_warning calls to log_failure.
- (flush_msg_buffers, byebye): no warnings any more.
-
- * fmtutil-sys.sh: doc fixes.
-
- * updmap-sys.sh: prepend directory of executable to $PATH.
-
-2014-11-17 Karl Berry <karl@tug.org>
-
- * fmtutil.sh: install (modified) patch from Zephyrus C,
- 29 May 2014 00:15:15,
- http://tug.org/pipermail/tex-live/2014-May/035443.html.
- (setupTmpDir): call byebye instead of cleanup, to display msgs.
- (byebye): exit 1 if warnings, not just errors.
- (verbose): do not assume && ... || precedence.
- (main): set setupTmpDir (and trap in general) earlier.
- (run_initex): check for mv and cp failure, e.g., full file system.
-
-2014-07-28 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (run-texlinks): Install the required files.
-
-2014-07-27 Karl Berry <karl@tug.org>
-
- * Makefile.am (texlinks_prog): separate out from $(run_texlinks).
-
-2014-07-17 Karl Berry <karl@tug.org>
-
- * tcfmgr,
- * fmtutil.sh,
- * fmtutil-sys.sh:
- * texconfig.1: prepend directory of executable to $PATH.
-
-2014-07-13 Karl Berry <karl@tug.org>
-
- * texconfig.sh,
- * texconfig-sys.sh,
- * texconfig-dialog.sh,
- * texconfig.1: prepend directory of executable to $PATH.
- (Testing with texconfig before propagating to updmap and fmtutil.)
-
-2014-05-09 Karl Berry <karl@tug.org>
-
- * texlinks.sh (install_link): force destination for
- pdfcsplain to be pdftex.
-
-2014-04-21 Norbert Preining <preining@logic.at>
-
- * fmtutil.sh: new option --no-error-if-no-engine,
- for the sake of luajittex, not available on all platforms.
-
-2013-07-31 Norbert Preining <preining@logic.at>
-
- * updmap-sys.sh: call updmap --sys instead of epanding vars
-
-2013-04-28 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Simplify '$(srcdir)/..'=> '$(top_srcdir)'.
-
-2013-04-14 Karl Berry <karl@tug.org>
-
- * updmap.pl: wording, sync from Master.
-
-2013-02-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am ({texconfig,web2c}dir): Change texmf => texmf-dist.
-
-2013-01-26 Karl Berry <karl@tug.org>
-
- * Makefile.am (echo-shell-scripts): new target, for
- check-wrapper-consistency.
-
-2013-01-15 Karl Berry <karl@tug.org>
-
- * fmtutil.sh (run_initex): save log file first,
- even if the .fmt isn't built. Tweak message wordings.
- Report from tljack, 12 Jan 2013 14:35:16.
-
-2012-08-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * fmtutil*, tcfmgr*, texconfig*, texlinks* (removed):
- Moved from here to ../texlive/tetex/.
- * Makefile.am: Adapted; run-texlinks rule
-
-2012-08-07 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tests/, all*, dvi2fax*, dvired*, fontinst*, kpsetool*,
- kpsewhere*, ps2frag*, pslatex*, rubibtex*, rumakeindex*,
- updmap* (removed): Moved from here to ../texlive/tetex/.
- * Makefile.am: Adapted.
-
-2012-08-06 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * e2pall.man, texdoctk.man, texdoctk.man (removed): Moved from
- here to ../texlive/tetex/.
- * Makefile.am: Adapted.
-
-2012-08-04 Karl Berry <karl@tug.org>
-
- * tl-sys-wrapper: not needed. The Windows wrapper, runscript.tlu,
- already handles -sys, as does the Windows fmtutil.c.
- * Makefile.am (EXTRA_DIST): remove it again.
-
-2012-08-03 Karl Berry <karl@tug.org>
-
- * tl-sys-wrapper.pl: initial attempt.
-
-2012-07-31 Norbert Preining <preining@logic.at>
-
- * updmap.pl (main): fix quoting and var expansion on Windows.
- * updmap.pl (main): and another fix, this time for PATH separator
-
-2012-07-30 Norbert Preining <preining@logic.at>
-
- * updmap.pl (main): support for multiple entry TEXMFLOCAL.
- Tell the user which config files is used for writing.
-
-2012-07-23 Karl Berry <karl@tug.org>
-
- * updmap.pl (help): we have both --showoption and --showoptions.
- Ugh. Found by Bruno Voisin, 11 Jun 2012 21:34:44.
-
-2012-06-10 Norbert Preining <preining@logic.at>
-
- * updmap.pl: fix ordering of how updmap.cfg files are read
- and add documentation.
-
-2012-06-04 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (EXTRA_DIST): Add the new file updmap.help2man.
-
-2012-06-01 Karl Berry <karl@tug.org>
-
- * Makefile.am (xupdmap.man): new (phony) target to run help2man.
- * updmap.help2man: new file.
-
- * updmap.pl: consistently use $prg, and remove .pl suffix.
-
-2012-05-31 Karl Berry <karl@tug.org>
-
- * updmap.pl (reset_root_home): accept /var/root.
-
-2012-05-31 Norbert Preining <preining@logic.at>
-
- * updmap.pl: reset root $HOME if it is not the real one, since
- sudo does not reset it
-
-2012-05-21 Norbert Preining <preining@logic.at>
-
- * updmap.pl
- . on win32, ensure file names are in lower case
- . add --dvipdfmxoutputdir, make --dvipdfmoutputdir synonym
- (more or less)
- . make sure that the file name database is properly updated
- when creating a new config file
- . remove --old-mode cmd line option
-
-2012-05-15 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * updmap.pl: Moved from ../texlive/linked_scripts/texlive/
- back to here.
- * tests/ (new): Moved from ../texlive/ to here and adapted.
- * Makefile.am: Adapted.
-
-2012-05-14 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * tests/ (removed): Moved from here to ../texlive/.
- * Makefile.am: Adapted.
-
- * fmtutil.cnf: Updated from Master.
-
-2012-05-14 Norbert Preining <preining@logic.at>
-
- * updmap.pl: rename to updmap-single.pl, we ship updmap.pl now
- via ../texlive/linked_scripts/texlive/updmap.pl
-
-2012-04-10 Karl Berry <karl@tug.org>
-
- * fmtutil (main): eradicate double slashes in tmpdir.
- tex-k mail from Alexey Vikhlinin, 8 Apr 2012 17:32:02.
-
-2012-03-12 Karl Berry <karl@tug.org>
-
- * updmap.cfg.5: avoid ... at beginning of line.
- Replace Debian-specific text.
-
-2012-02-21 Karl Berry <karl@tug.org>
-
- * updmap.pl (help): updates for kanji.
-
-2012-02-10 Norbert Preining <preining@logic.at>
-
- * updmap.pl: fix breakage of updmap if a generated file does
- not exist (wrong double substitution of @kanji*@ strings)
-
-2012-02-01 Norbert Preining <preining@logic.at>
-
- * updmap.pl:
- . support -showoption key that shows the current setting
- . fix not-acceptance of empty values in key/val -setoption
-
-2012-01-19 Norbert Preining <preining@logic.at>
-
- * updmap.pl:
- . allow --enable Map foo.map again
- . support kanjiVariant options and replacement
-
-2011-12-12 Karl Berry <karl@tug.org>
-
- * updmap.pl: untabify, formatting.
-
-2011-12-06 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Replace ${prefix}/texmf => $(datarootdir)/texmf.
-
-2011-11-16 Norbert Preining <preining@logic.at>
-
- * updmap.pl: make sure that kanjiEmbed is set to a default value
- if not found in the config file.
-
-2011-11-09 Norbert Preining <preining@logic.at>
-
- * updmap.pl: add support for pxdviUse config option in updmap,
- and generate xdvi-ptex.map if it is set in a similar way as kanjix.map,
- patch based on work of Hironori Kitagawa
-
-2011-11-04 Norbert Preining <preining@logic.at>
-
- * updmap.pl: small fixes to documentation of updmap.pl, and fixes
- to --syncwithtrees and --listavail, patch from Hironori Kitagawa
-
-2011-11-02 Norbert Preining <preining@logic.at>
-
- * updmap.pl: apply patch from Hironori Kitagawa that fixes
- a --syncwithtrees problem in searching for map names.
-
-2011-10-26 Norbert Preining <preining@logic.at>
-
- * updmap.pl: apply patch from ptexlive Tsuchimura to support
- kanjiEmbed setting, and generate kanjix.map.
-
-2011-09-09 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Adapt to script_links.am using relpath.
- (run-texlinks): Declare as .PHONY; skip texlinks for WIN32.
-
-2011-09-09 Karl Berry <karl@tug.org>
-
- * tests: new subdir, with first updmap test, that doesn't really
- work yet but passes anyway.
- * Makefile.am (TESTS): add tests/updmap-cmdline-test.pl.
- * updmap.pl (read_option_vals): don't call getopt twice (from Norbert).
- Don't complain about non-option args, that is how --enable/--disable
- are currently (mis)handled.
- (writeLines, copyFile, setupOutputDir, SetupCfgFile): do nothing
- if $dry_run.
-
-2011-09-05 Karl Berry <karl@tug.org>
-
- * texconfig-dialog (runDialog): only clear screen if we actually
- run the dialog program.
- (findDialog): do not bother setting DIALOG_TERM and
- DIALOG_TERMINFO if we don't find a system dialog program,
- since we're just going to abort anyway.
- * texmf: remove subdir with terminfo definitions.
- * Makefile.am (texconfdir, nobase_dist_texconf_DATA): likewise rm.
-
-2011-09-04 Norbert Preining <preining@logic.at>
-
- * updmap.pl (BEGIN): older versions are supported again.
- (read_for_set_options): new fn.
- (processOptions): call it, so we call getopt twice,
- so we can avoid using the =s{1,2} specifier (for --setoption)
- which needs perl 5.8.8.
- Also, complain about non-option arguments.
- http://tug.org/pipermail/tex-live/2011-July/029764.html
- http://tug.org/pipermail/tex-k/2011-September/002329.html
-
-2011-08-26 Karl Berry <karl@tug.org>
-
- * texconfig-dialog: do not invoke tcdialog as fallback,
- give up instead. We don't want to install our own (tc)dialog any
- more, induces curses dependencies. More importantly, texconfig,
- and especially this interactive configuration, has not been the
- way we have been moving (or testing) for years now. If there is
- anyone left who wants to do it, they can install their own dialog
- (or whiptail) program.
-
-2011-06-27 Karl Berry <karl@tug.org>
-
- * fmtutil (version): rename to versionfunc, or Solaris sh dies
- with "bad substitution".
- Report from Nelson, 23 Jun 2011 09:42:09.
-
-2011-06-18 Karl Berry <karl@tug.org>
-
- * updmap.pl (locateMap): allow "Map foo" (without the ".map"),
- as the sh updmap map. (The actual file still being foo.map.)
- Report from Peter Dyballa, 15 Jun 2011 10:04:36.
-
-2011-06-16 Karl Berry <karl@tug.org>
-
- * updmap.pl (help): add more info and modify to work with help2man.
- * updmap.man: generate with help2man.
-
- * updmap.pl (progname): eliminate fn in favor of $0
- or hardwired "updmap" as appropriate.
-
- * old-updmap: rename from updmap, to make it clearer this
- (sh version) is not used any more.
- * old-fontinst.bat: rename from fontinst.bat.
-
- * updmap.pl ($pdftexStripEnc): set to zero.
- (to_pdftex): return the input, not empty.
- (ProcessOptions): accept and ignore dvipdfmoutputdir.
-
- * updmap.pl (@psADOBE): use the same list as from sh updmap,
- including the spaces, to be sure we are getting the same behavior.
-
- Related:
- * Master/texmf/fonts/map/dvips/tetex/pdftex35.map,
- * Master/texmf/fonts/map/dvips/tetex/ps2pk35.map (phvbo8rn,phvbo8yn):
- ever since at least TL 7, these have had
- spurious "-Narrow-BoldOblique" suffixes on the correct
- NimbusSanL-BoldCondItal, left over from the Adobe
- Helvetica-Narrow-BoldOblique.
- (Yet the fonts could still be used.)
- * Master/texmf/fonts/map/{dvips,pdftex}/updmap: regenerate.
-
- * updmap.pl: support --setoption foo bar as well as foo=bar,
- for compatibility.
- (setOptions): new fn.
- (ProcessOptions): use "setoption=s{1,2}" => \@setoptions
- instead of "setoption=s" => \%setOption, since we have to parse
- the values manually.
- (Getopt::Long::Configure): removing bundling, disallows the
- =s{1,2} Getopt directive we specify for parsing.
- Original report from Herbert Schulz,
- mactex mail 13 Jun 2011 07:56:50.
-
- Unrelated, sorry:
- Add $0 to die commands.
- (setOption): silently accept dvipdfmDownloadBase14.
- ($verbose): remove unused variable.
-
-2011-06-15 Karl Berry <karl@tug.org>
-
- * updmap.pl: reformat long lists, reduce ####, other formatting.
- (processOptions): do not mkdirhier the output directories
- if it is a dry run.
-
- * updmap.pl (@psADOBE): do BoldItalic (etc.) before Bold (etc.),
- other generated pdftex.map has bogus names with spaces.
- Original report from Herbert Schulz,
- mactex mail 13 Jun 2011 08:27:46.
-
- Unrelated, sorry:
- (Getopt::Long::Configure): set ignore_case_always.
- (Case-insensitive option matching is the default?!)
- (--force, $opt_force): new option.
- (processOptions): sort and indent option list consistently.
-
-2011-05-31 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Use ../am/bin_links.am for $(bindir) links.
-
-2011-05-12 Karl Berry <karl@tug.org>
-
- * updmap.pl (pdftexNoEnc): rename to pdftexStripEnc.
- (to_pdftex): change uses.
- (Reinhard K made an equivalent change.)
-
-2011-04-04 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- Rename updmap-sys => updmap-sys.sh.
- * Makefile.am: Install updmap and updmap-sys as linked scripts
- and use the ../am/script_links.am fragment.
-
-2011-02-08 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am: Use ../am/man1_links.am for manpage links.
-
-2011-01-07 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am, configure.ac [WIN32]: Install wrapper binary for
- fontinst (handled as alias by runscript.tlu).
-
- * texconfig, texconfig-sys: Drop texconfig_sys shell variable;
- now done via TEXMFVAR and TEXMFCONFIG in the environment.
-
-2011-01-04 Karl Berry <karl@tug.org>
-
- * updmap: add many more verbose messages, to help understand what
- files are being created from what sources.
-
-2010-12-27 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (install-exec-hook, install-data-hook): Check
- symlink creation.
-
-2010-12-25 Karl Berry <karl@tug.org>
-
- * doc,
- * pdfetex-pl.pool,
- * README.a2ping: remove these seemingly not useful files.
- * Makefile.am: update accordingly.
-
-2010-12-22 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * configure.ac: Added KPSE_CHECK_WIN32.
- * context/ (removed): Files moved to ../texlive/context/.
- * Makefile.am: Adapted.
-
-2010-12-19 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * ps4pdf: Removed, replaced by newer version under ../texlive/.
- * Makefile.am: Adapted.
-
-2010-12-18 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * context/texmfstart.man: Fix typo.
-
-2010-07-05 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * fmtutil.man: Adapt to fmtutil.
-
-2010-07-04 Norbert Preining <preining@logic.at>
-
- * fmtutil: add --no-error-if-no-format, don't abort in some cases of
- missing formats
-
-2010-06-12 Karl Berry <karl@tug.org>
-
- * fmtutil (--edit): disable.
- (help): document this, other tweaks.
-
-2010-05-31 Manuel P\'egouri\'e-Gonnard <mpg@elzevir.fr>
-
- * fmtutil: allow more than one language file per format.
-
-2010-05-20 Karl Berry <karl@tug.org>
-
- * doc/TETEXDOC.dvi,
- * doc/TETEXDOC.ps: rm files.
- * doc/Makefile: do not bother remaking .dvi + .ps.
- * Makefile.am (dist_tetexdoc_DATA): rm.
-
-2010-04-29 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (run_texlinks, run_texlinks): Respect DESTDIR.
-
-2010-04-28 Manuel P\'egouri\'e-Gonnard <mpg@elzevir.fr>
-
- * texlinks: Append exeext to engine names.
- * Makefile.am (run_texlinks): Invoke texlinks with explicit dir.
-
-2010-03-12 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * texlinks (version): Add missing quote in svn id.
-
-2010-03-11 Karl Berry <karl@tug.org>
-
- * updmap,
- * texlinks,
- * texconfig (version): use svn id.
- (help): regularize info at end of msg.
-
- * fmtutil (help): describe mktexfmt operation.
- (main): give more error message in mktexfmt mode.
- Report from Ludovic Courtes, 08 Mar 2010 21:55:53.
-
-2010-01-17 Karl Berry <karl@tug.org>
-
- * updmap,
- * fmtutil: tweak help messages.
-
- * tcfmgr (setupMap),
- * fmtutil (main),
- * updmap (setupCfgFile): maybe ls-R missing when basic config
- files not found.
-
-2009-12-23 Norbert Preining <preining@logic.at>
-
- * fmtutil: check for infinite loop only in mktexfmt mode so that
- multiple defined format/engine combinations are accepted.
-
-2009-10-24 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- * Makefile.am (bin_links, man1_links):
- New lists of symlinks within bindir and man1dir.
- Moved handling of texhash symlinks to ../kpathsea/man/.
- Moved handling of lambda, ctangle, cweave, odvicopy, odvitype,
- mf-nowin, and pdflatex symlinks to ../web2c/man/.
- (install-data-hook, install-exec-hook, uninstall-hook):
- Use `bin_links' and `man1_links'.
-
- * mkocp.man, mkofm.man, otp2ocp.man, outocp.man: Moved from
- here to ../web2c/otps/.
- * ofm2opl.man, opl2ofm.man, ovf2ovp.man, ovp2ovf.man,
- ttf2afm.man: Moved from here to ../web2c/man/.
- * Makefile.am (dist_man1_MANS): Adjusted.
-
-2009-10-09 Karl Berry <karl@tug.org>
-
- * fmtutil (run_initex): if it doesn't already exist, create
- mplib-luatex.mem when we create mpost.mem.
-
-2009-08-24 Reinhard Kotucha <reinhard.kotucha@web.de>
-
- * updmap.pl (mkMaps): replace dir/ls shell commands by Perl code.
-
-2009-08-22 Tomek Trzeciak <t.m.trzeciak@gmail.com>
-
- * updmap.pl (mkmaps): remove unneeded COMSPEC from backticks
-
-2009-08-19 Karl Berry <karl@tug.org>
-
- * updmap.pl (mkmaps): quote invocation of COMSPEC.
- From Dan Luecking, 19 Aug 2009 15:13:31.
-
-2009-08-15 Karl Berry <karl@tug.org>
-
- * fmtutil (--byengine): new option, from Norbert.
- (help): mention it; other tweaks.
- * fmtutil.man: also update.
-
-2009-07-23 Karl Berry <karl@tug.org>
-
- * updmap (help): mention tug.org/fonts/fontinstall.html.
-
-2009-06-23 Karl Berry <karl@tug.org>
-
- * Makefile.am (run_texlinks): add -e "$(EXEEXT)".
- * texlinks: new option -e to specify executable extension (for
- cygwin).
-
-2009-06-11 Norbert Preining <preining@logic.at>
-
- * fmtutil (log_warning): new fn, related code, so that
- LaTeX's five-year-old warning does not trigger failure.
- Debian bug #531595.
-
-2009-05-28 Karl Berry <karl@tug.org>
-
- * texconfig.man: update from Frank K, 27 May 2009 23:17:49.
-
-2009-05-07 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- Adapt to TL2009 build system.
-
-2009-04-03 Karl Berry <karl@tug.org>
-
- * Makefile.am (EXTRA_DIST): remove texdoc.man from list.
- * texdoc.man: remove file; maintained separately now
- (http://tug.org/texdoc)
-
-2009-03-17 Karl Berry <karl@tug.org>
-
- * updmap (main, cleanup): cd back to the original pwd instead of /,
- to work around
- rm: cannot get current directory: Permission denied
- error in (at least) coreutils 5.2.1 in some ill-defined circumstance.
- Report from Lars Madsen.
-
-2008-10-27 Karl Berry <karl@tug.org>
-
- * updmap.pl: also adjust printed output.
- From Aaron Chen, 25 Oct 2008 16:40:59.
-
-2008-10-24 Karl Berry <karl@tug.org>
-
- * Makefile.in (run-texlinks): quote the PATH
- argument in case there are spaces lurking.
- Report from Angelo Graziosi, 23 Oct 2008 16:08:59.
-
-2008-10-22 Karl Berry <karl@tug.org>
-
- * updmap.pl (cfgval): only consider falsish strings to be 0, else
- leave the value as-is, for the sake of LW35, which does not take a
- boolean. Report and patch from Aaron Chen, 17 Oct 2008 01:22:24.
-
-2008-09-22 Karl Berry <karl@tug.org>
-
- * fmtutil (parse_line): pass --format=mp to kpsewhich when
- engine=mpost, instead of --format=mpost.
-
-2008-07-08 Karl Berry <karl@tug.org>
-
- * texconfig (hyphen, formats): disable these functions,
- fmtutil.cnf and language.dat/def must not be manually edited,
- since they are now automatically regenerated, as tlmgr regenerates.
-
-2008-07-05 Karl Berry <karl@tug.org>
-
- * Makefile.in (run_texlinks): use -f $(web2cdir)/fmtutil.cnf.
- (run_mktexlsr): no longer needed.
- From Francois Charette, tldistro 04 Jul 2008 09:22:42.
-
-2008-06-18 Karl Berry <karl@tug.org>
-
- * texlinks: metafun is not created specially by ConTeXt, so we'll
- create it here.
-
-2008-06-17 Norbert Preining <preining@logic.at>
-
- * fmtutil: add the engine setting to the infinite-loop-detection
- variable.
-
-2008-06-15 Karl Berry <karl@tug.org>
-
- * Makefile.in (run_mktexlsr): no need to set TEXMFDBS, cmdline
- dir is respected again.
- (CONTEXTSCRIPTS): remove texexec, the version here was old.
-
-2008-05-28 Karl Berry <karl@tug.org>
-
- * fmtutil.cnf: new file, a slave of Master/texmf/web2c/fmtutil.cnf,
- which we keep in sync via TL infrastructure scripts.
- * Makefile.in (install-data): install fmtutil.cnf.
- (run-texlinks): new target, invoked by top-level make.
- * texlinks: doc fixes.
-
-2008-05-19 Karl Berry <karl@tug.org>
-
- * texdoc: remove, master is now the lua version in texmf/scripts.
-
-2008-05-11 Norbert Preining <preining@logic.at>
-
- * Makefile.in: do not install texdoc(.man) since we will use the
- texlua version from Frank (to be found in ../texlive)
-
-2008-05-08 Norbert Preining <preining@logic.at>
-
- * updmap, tcfmgr: quote various calls containing env variables
- taken from texmf.cnf which could contain spaces
-
-2008-05-05 Karl Berry <karl@tug.org>
-
- * texconfig (generate): remove this, now done in tlmgr.
-
-2008-05-04 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): add ps4pdf.
-
-2008-04-25 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): now tlmgr.tlu.
-
-2008-04-16 Norbert Preining <preining@logic.at>
-
- * fmtutil: fix creation of dirs with spaces
-
-2008-04-14 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): no more *xindy, the xindy Makefile
- itself takes care of those.
-
-2008-04-12 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKED_SCRIPTS): pdfcrop now in texmf-dist.
- Add xindy.pl, texindy.pl.
-
-2008-03-18 Karl Berry <karl@tug.org>
-
- * Makefile.in (install-linked-scripts): use $(LINKSUFFIX).
- (LINKSUFFIX): new variable, for passing -sys.
- (install-linked-sys-scripts): make install-linked-scripts
- instead of repeating code.
-
-2008-03-15 Reinhard Kotucha <reinhard.kotucha@web.de>
-
- * Makefile.in (LINKEDSCRIPTS): add pdfthumb.
-
-2008-03-14 Reinhard Kotucha <reinhard.kotucha@web.de>
-
- * Makefile.in (LINKED_SYS_SCRIPTS): new list for -sys progs.
- Add getnonfreefonts.pl.
-
-2008-03-14 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKEDSCRIPTS): add ppower4, no longer in tetex.
-
- * fmtutil: check for infinite loops.
- From Stepan Kasal, http://bugzilla.redhat.com/show_bug.cgi?id=437008.
-
-2008-03-07 Karl Berry <karl@tug.org>
-
- * Makefile.in (LINKEDPLSCRIPTS): rename from LINKEDPERLSCRIPTS.
- (LINKEDNOEXTSCRIPTS): new variable for makeglossaries.
- (install-linkedscripts): install them.
-
-2008-03-03 Karl Berry <karl@tug.org>
-
- * latex.info, latex2e.texi: remove; this will become a separate
- package.
- * Makefile.in: remove info-related stuff.
- (LINKEDPERLSCRIPTS): add e2pall, pkfix, ps2eps.
-
-2008-03-02 Karl Berry <karl@tug.org>
-
- * Makefile.in: more doc
-
-2008-02-16 Karl Berry <karl@tug.org>
-
- * texconfig (doGenerate): new fn to call generate-* scripts.
- (help): document it.
-
-2008-01-30 Peter Breitenlohner <peb@mppmu.mpg.de>
-
- Convert from autoconf-2.13 to autoconf-2.59+:
- * Makefile.in: Add @configure_input@ line.
- * aclocal.m4 (new): Generated (aclocal -I ../m4).
- * configure: Regenerated (autoconf).
-
-2008-01-14 Karl Berry <karl@tug.org>
-
- * pdfcrop: update to 1.8 from CTAN.
-
-2007-11-03 Karl Berry <karl@tug.org>
-
- * texlinks.man: --unlink, sort. From Edd.
-
-2007-10-25 Karl Berry <karl@tug.org>
-
- * updmap: make last bit of log nicer, since we may have copies
- instead of symlinks now.
-
-2007-10-24 Karl Berry <karl@tug.org>
-
- * texconfig: update and augment help message;
- accept version and --version;
- show TeX Live version info from release-texlive.txt.
-
-2007-10-19 Karl Berry <karl@tug.org>
-
- * updmap (processOptions): add --copy and -n options.
- (setupSymlinks): with --copy, cp instead of ln -s.
- We want this for TL.
- (mkMaps): with -n, exit before actually doing anything.
- (setupLog): with -n, do not log.
- (help): update and augment.
-
-2007-10-12 Karl Berry <karl@tug.org>
-
- * texlinks: new option -u[nlink] for uninstall.
- From Edd Barrett, 10 Oct 2007 11:05:55.
-
-2007-09-30 Karl Berry <karl@tug.org>
-
- * texconfig-sys: export texconfig_sys.
- * texconfig <init>: use it to figure out which fmtutil/updmap.
- Report from Frank K, 11 Jun 2007 17:05:43.
-
-2007-09-10 Karl Berry <karl@tug.org>
-
- * updmap.pl: TEXMFVAR rather than VARTEXMF.
-
-2007-09-04 Karl Berry <karl@tug.org>
-
- * updmap.pl: ! to clearly check against both empty string and
- undef, rather than eq undef (Jjgod 3 Sep 2007 16:16:50).
-
-2007-07-16 Karl Berry <karl@tug.org>
-
- * texconfig (findDialogProg, runDialog): these fns not used here,
- remove.
- (findprog): new mode of operation, like which(1).
- * texconfig-dialog (findDialog): check for whiptail/dialog on any
- system, not just FreeBSD, Linux, cygwin.
-
-2007-05-31 Karl Berry <karl@tug.org>
-
- * fmtutil (run_initex): do not remove the log file.
-
-2007-01-16 Karl Berry <karl@tug.org>
-
- * texconfig (init): only run texlinks and updmap if fmtutil succeeds.
-
-2007-01-14 Karl Berry <karl@tug.org>
-
- * texconfig: check for pdftex rather than pdfetex.
- Reported by Artemio, 13 Jan 2007 14:54:40.
-
-2006-12-29 Karl Berry <karl@tug.org>
-
- * texconfig: replace sort +1 with sort -k 2. I hate POSIX.
- Reported by gnwiii, 28 Dec 2006 14:53:54.
-
-2006-12-27 Karl Berry <karl@tug.org>
-
- * Makefile.in (install-exec): now the binary is named pdftex again.
-
-2006-12-25 Karl Berry <karl@tug.org>
-
- * updmap: update version.
-
-2006-12-13 Karl Berry <karl@tug.org>
-
- * latex2e.texi: FSF never held copyright (checked with authors).
- Starting latexrefman project at gna.org, with hopes.
-
-2006-11-20 Karl Berry <karl@tug.org>
-
- * Makefile.in (CONTEXTSCRIPTS): new variable.
- (context): new subdir of stubs, updated from Hans' releases.
-
-2006-11-14 Karl Berry <karl@tug.org>
-
- * updmap (normalizeLines): remove CR characters (for skaknew), so
- that the generted map files have consistent line endings for svn.
-
-2006-07-13 Karl Berry <karl@tug.org>
-
- * ps4pdf (tmpdir): don't lose check for TMPDIR and TEMP which te
- had.
-
-Sat Dec 18 14:19:43 CET 1999 te
-
- * added manpages for epstopdf and dvi2fax (contributed by "James
- R. Van Zandt" <jrv@vanzandt.mv.com>)
-
-(This file public domain.)
diff --git a/Build/source/texk/texlive/tl_support/Makefile.am b/Build/source/texk/texlive/tl_support/Makefile.am
deleted file mode 100644
index 06593ac5e8d..00000000000
--- a/Build/source/texk/texlive/tl_support/Makefile.am
+++ /dev/null
@@ -1,101 +0,0 @@
-## $Id$
-## Makefile.am for the TeX Live subdirectory texk/texlive/tl_support/
-##
-## Copyright 2013-2020 Karl Berry <tex-live@tug.org>
-## You may freely use, modify and/or distribute this file.
-
-install-data-hook: install-man1-links
-uninstall-hook: uninstall-man1-links
-
-dist_man_MANS = \
- allcm.1 \
- allec.1 \
- allneeded.1 \
- dvi2fax.1 \
- dvired.1 \
- e2pall.1 \
- fmtutil.1 \
- fmtutil.cnf.5 \
- fontinst.1 \
- kpsetool.1 \
- kpsewhere.1 \
- mktexlsr.1 \
- mktexmf.1 \
- mktexpk.1 \
- mktextfm.1 \
- ps2frag.1 \
- pslatex.1 \
- rubibtex.1 \
- rumakeindex.1 \
- texconfig.1 \
- texlinks.1 \
- updmap.1 \
- updmap.cfg.5
-
-man1_links = \
- fmtutil:fmtutil-sys \
- kpsetool:kpsexpand \
- kpsetool:kpsepath \
- fmtutil:mktexfmt \
- mktexlsr:texhash \
- texconfig:texconfig-sys \
- updmap:updmap-sys
-
-include $(top_srcdir)/../../am/man1_links.am
-
-## Support files
-texconfigdir = $(datarootdir)/texmf-dist/texconfig
-dist_texconfig_SCRIPTS = tcfmgr
-dist_texconfig_DATA = tcfmgr.map
-
-web2cdir = $(datarootdir)/texmf-dist/web2c
-dist_web2c_DATA = fmtutil.cnf
-
-## Generate the updmap/fmtutil man page using help2man plus a bit of
-## handwritten material. But don't actually update updmap/fmtutil.1,
-## since we don't want to require help2man for an install. Leave that
-## to be done by hand (see tlpkg/doc/releng.txt).
-EXTRA_DIST = updmap.help2man fmtutil.help2man
-.PHONY: xmans xupdmap.1 xfmtutil.1
-xmans: xupdmap.1 xfmtutil.1
-Master_dir = $(top_srcdir)/../../../../Master
-tl_scripts_dir = $(Master_dir)/texmf-dist/scripts/texlive
-#
-xupdmap.1: updmap.help2man $(tl_scripts_dir)/updmap.pl
- help2man --include=$< --source="TeX Live" --no-info \
- $(tl_scripts_dir)/updmap.pl >/tmp/$@
- groff -mandoc -Thtml /tmp/$@ >/tmp/$@.html
-#
-xfmtutil.1: fmtutil.help2man $(tl_scripts_dir)/fmtutil.pl
- help2man --include=$< --source="TeX Live" --no-info \
- $(tl_scripts_dir)/fmtutil.pl >/tmp/$@
- groff -mandoc -Thtml /tmp/$@ >/tmp/$@.html
-
-##
-## This target is invoked by the top-level make,
-.PHONY: run-texlinks
-## to create the per-format engine symlinks in $(bindir),
-## after everything else is installed. We explicitly specify the
-## fmtutil.cnf file to use for the sake of distro builds.
-## We pass along the executable extension for the sake of cygwin, so we
-## don't create dangling symlinks there (even though they work).
-##
-## The texlinks script is installed by ../linked_scripts/Makefile[.am].
-## If it doesn't exist, e.g., if --disable-texlive was given, do nothing here.
-## So we do not specify make-level dependencies, but instead check if
-## the texlinks file (normally a symlink) and fmtutil.cnf exist.
-##
-texlinks_prog = $(DESTDIR)$(bindir)/texlinks
-texlinks_fmtutil = $(DESTDIR)$(web2cdir)/fmtutil.cnf
-#
-run_texlinks = $(texlinks_prog) -v \
- -f $(texlinks_fmtutil) \
- -e "$(EXEEXT)" $(DESTDIR)$(bindir)
-#
-run-texlinks:
-if !WIN32
- if test -s $(texlinks_prog) && test -s $(texlinks_fmtutil); then \
- echo "running texlinks in `pwd` via: $(run_texlinks)"; \
- PATH="$(DESTDIR)$(bindir):$(PATH)"; export PATH; $(run_texlinks); \
- else :; fi
-endif !WIN32
diff --git a/Build/source/texk/texlive/tl_support/Makefile.in b/Build/source/texk/texlive/tl_support/Makefile.in
deleted file mode 100644
index e6af0c8a8d4..00000000000
--- a/Build/source/texk/texlive/tl_support/Makefile.in
+++ /dev/null
@@ -1,707 +0,0 @@
-# Makefile.in generated by automake 1.16.3 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-subdir = tl_support
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../../m4/kpse-win32.m4 \
- $(top_srcdir)/../../version.ac $(top_srcdir)/ac/texlive.ac \
- $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(dist_texconfig_SCRIPTS) \
- $(dist_texconfig_DATA) $(dist_web2c_DATA) $(am__DIST_COMMON)
-mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
- test -z "$$files" \
- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
- $(am__cd) "$$dir" && rm -f $$files; }; \
- }
-am__installdirs = "$(DESTDIR)$(texconfigdir)" "$(DESTDIR)$(man1dir)" \
- "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(texconfigdir)" \
- "$(DESTDIR)$(web2cdir)"
-SCRIPTS = $(dist_texconfig_SCRIPTS)
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 =
-SOURCES =
-DIST_SOURCES =
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-man1dir = $(mandir)/man1
-man5dir = $(mandir)/man5
-NROFF = nroff
-MANS = $(dist_man_MANS)
-DATA = $(dist_texconfig_DATA) $(dist_web2c_DATA)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
- $(top_srcdir)/../../am/man1_links.am ChangeLog README
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EXEEXT = @EXEEXT@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-WIN_WRAPPER = @WIN_WRAPPER@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-dist_man_MANS = \
- allcm.1 \
- allec.1 \
- allneeded.1 \
- dvi2fax.1 \
- dvired.1 \
- e2pall.1 \
- fmtutil.1 \
- fmtutil.cnf.5 \
- fontinst.1 \
- kpsetool.1 \
- kpsewhere.1 \
- mktexlsr.1 \
- mktexmf.1 \
- mktexpk.1 \
- mktextfm.1 \
- ps2frag.1 \
- pslatex.1 \
- rubibtex.1 \
- rumakeindex.1 \
- texconfig.1 \
- texlinks.1 \
- updmap.1 \
- updmap.cfg.5
-
-man1_links = \
- fmtutil:fmtutil-sys \
- kpsetool:kpsexpand \
- kpsetool:kpsepath \
- fmtutil:mktexfmt \
- mktexlsr:texhash \
- texconfig:texconfig-sys \
- updmap:updmap-sys
-
-texconfigdir = $(datarootdir)/texmf-dist/texconfig
-dist_texconfig_SCRIPTS = tcfmgr
-dist_texconfig_DATA = tcfmgr.map
-web2cdir = $(datarootdir)/texmf-dist/web2c
-dist_web2c_DATA = fmtutil.cnf
-EXTRA_DIST = updmap.help2man fmtutil.help2man
-Master_dir = $(top_srcdir)/../../../../Master
-tl_scripts_dir = $(Master_dir)/texmf-dist/scripts/texlive
-texlinks_prog = $(DESTDIR)$(bindir)/texlinks
-texlinks_fmtutil = $(DESTDIR)$(web2cdir)/fmtutil.cnf
-#
-run_texlinks = $(texlinks_prog) -v \
- -f $(texlinks_fmtutil) \
- -e "$(EXEEXT)" $(DESTDIR)$(bindir)
-
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/../../am/man1_links.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tl_support/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign tl_support/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
- esac;
-$(top_srcdir)/../../am/man1_links.am $(am__empty):
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-dist_texconfigSCRIPTS: $(dist_texconfig_SCRIPTS)
- @$(NORMAL_INSTALL)
- @list='$(dist_texconfig_SCRIPTS)'; test -n "$(texconfigdir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(texconfigdir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(texconfigdir)" || exit 1; \
- fi; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n' \
- -e 'h;s|.*|.|' \
- -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) { files[d] = files[d] " " $$1; \
- if (++n[d] == $(am__install_max)) { \
- print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
- else { print "f", d "/" $$4, $$1 } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(texconfigdir)$$dir'"; \
- $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(texconfigdir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-dist_texconfigSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_texconfig_SCRIPTS)'; test -n "$(texconfigdir)" || exit 0; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 's,.*/,,;$(transform)'`; \
- dir='$(DESTDIR)$(texconfigdir)'; $(am__uninstall_files_from_dir)
-install-man1: $(dist_man_MANS)
- @$(NORMAL_INSTALL)
- @list1=''; \
- list2='$(dist_man_MANS)'; \
- test -n "$(man1dir)" \
- && test -n "`echo $$list1$$list2`" \
- || exit 0; \
- echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
- { for i in $$list1; do echo "$$i"; done; \
- if test -n "$$list2"; then \
- for i in $$list2; do echo "$$i"; done \
- | sed -n '/\.1[a-z]*$$/p'; \
- fi; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
- done; }
-
-uninstall-man1:
- @$(NORMAL_UNINSTALL)
- @list=''; test -n "$(man1dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.1[a-z]*$$/p'; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
-install-man5: $(dist_man_MANS)
- @$(NORMAL_INSTALL)
- @list1=''; \
- list2='$(dist_man_MANS)'; \
- test -n "$(man5dir)" \
- && test -n "`echo $$list1$$list2`" \
- || exit 0; \
- echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
- { for i in $$list1; do echo "$$i"; done; \
- if test -n "$$list2"; then \
- for i in $$list2; do echo "$$i"; done \
- | sed -n '/\.5[a-z]*$$/p'; \
- fi; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
- done; }
-
-uninstall-man5:
- @$(NORMAL_UNINSTALL)
- @list=''; test -n "$(man5dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.5[a-z]*$$/p'; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
-install-dist_texconfigDATA: $(dist_texconfig_DATA)
- @$(NORMAL_INSTALL)
- @list='$(dist_texconfig_DATA)'; test -n "$(texconfigdir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(texconfigdir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(texconfigdir)" || exit 1; \
- fi; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; \
- done | $(am__base_list) | \
- while read files; do \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(texconfigdir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(texconfigdir)" || exit $$?; \
- done
-
-uninstall-dist_texconfigDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_texconfig_DATA)'; test -n "$(texconfigdir)" || list=; \
- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- dir='$(DESTDIR)$(texconfigdir)'; $(am__uninstall_files_from_dir)
-install-dist_web2cDATA: $(dist_web2c_DATA)
- @$(NORMAL_INSTALL)
- @list='$(dist_web2c_DATA)'; test -n "$(web2cdir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(web2cdir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(web2cdir)" || exit 1; \
- fi; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; \
- done | $(am__base_list) | \
- while read files; do \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(web2cdir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(web2cdir)" || exit $$?; \
- done
-
-uninstall-dist_web2cDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_web2c_DATA)'; test -n "$(web2cdir)" || list=; \
- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- dir='$(DESTDIR)$(web2cdir)'; $(am__uninstall_files_from_dir)
-tags TAGS:
-
-ctags CTAGS:
-
-cscope cscopelist:
-
-
-distdir: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) distdir-am
-
-distdir-am: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(SCRIPTS) $(MANS) $(DATA)
-installdirs:
- for dir in "$(DESTDIR)$(texconfigdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(texconfigdir)" "$(DESTDIR)$(web2cdir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-dist_texconfigDATA \
- install-dist_texconfigSCRIPTS install-dist_web2cDATA \
- install-man
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-data-hook
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man: install-man1 install-man5
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-dist_texconfigDATA \
- uninstall-dist_texconfigSCRIPTS uninstall-dist_web2cDATA \
- uninstall-man
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
-uninstall-man: uninstall-man1 uninstall-man5
-
-.MAKE: install-am install-data-am install-strip uninstall-am
-
-.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
- ctags-am distclean distclean-generic distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-data-hook install-dist_texconfigDATA \
- install-dist_texconfigSCRIPTS install-dist_web2cDATA \
- install-dvi install-dvi-am install-exec install-exec-am \
- install-html install-html-am install-info install-info-am \
- install-man install-man1 install-man5 install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
- pdf-am ps ps-am tags-am uninstall uninstall-am \
- uninstall-dist_texconfigDATA uninstall-dist_texconfigSCRIPTS \
- uninstall-dist_web2cDATA uninstall-hook uninstall-man \
- uninstall-man1 uninstall-man5
-
-.PRECIOUS: Makefile
-
-
-install-data-hook: install-man1-links
-uninstall-hook: uninstall-man1-links
-.PHONY: install-man1-links uninstall-man1-links
-
-install-man1-links:
- @cd $(DESTDIR)$(man1dir) && \
- for s in $(man1_links); do \
- link=`echo $$s | sed 's,.*:,,'`; \
- file=`echo $$s | sed 's,:.*,,'`; \
- rm -f $$link.1; \
- echo "creating link '$$link.1' -> '$$file.1'"; \
- echo ".so man1/$$file.1" >$$link.1; \
- done
-
-uninstall-man1-links:
- @for s in $(man1_links); do \
- link=`echo $$s | sed 's,.*:,,'`; \
- rm -f $(DESTDIR)$(man1dir)/$$link.1; \
- done
-.PHONY: xmans xupdmap.1 xfmtutil.1
-xmans: xupdmap.1 xfmtutil.1
-#
-xupdmap.1: updmap.help2man $(tl_scripts_dir)/updmap.pl
- help2man --include=$< --source="TeX Live" --no-info \
- $(tl_scripts_dir)/updmap.pl >/tmp/$@
- groff -mandoc -Thtml /tmp/$@ >/tmp/$@.html
-#
-xfmtutil.1: fmtutil.help2man $(tl_scripts_dir)/fmtutil.pl
- help2man --include=$< --source="TeX Live" --no-info \
- $(tl_scripts_dir)/fmtutil.pl >/tmp/$@
- groff -mandoc -Thtml /tmp/$@ >/tmp/$@.html
-
-.PHONY: run-texlinks
-#
-run-texlinks:
-@WIN32_FALSE@ if test -s $(texlinks_prog) && test -s $(texlinks_fmtutil); then \
-@WIN32_FALSE@ echo "running texlinks in `pwd` via: $(run_texlinks)"; \
-@WIN32_FALSE@ PATH="$(DESTDIR)$(bindir):$(PATH)"; export PATH; $(run_texlinks); \
-@WIN32_FALSE@ else :; fi
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Build/source/texk/texlive/tl_support/README b/Build/source/texk/texlive/tl_support/README
deleted file mode 100644
index fe28ce08623..00000000000
--- a/Build/source/texk/texlive/tl_support/README
+++ /dev/null
@@ -1,13 +0,0 @@
-$Id$
-Public domain.
-
-This directory mostly contains documentation for scripts which are maintained
-as part of TeX Live. The scripts themselves are maintained under Master:
-Master/texmf-dist/scripts/texlive/
-Master/texmf-dist/scripts/texlive-extra
-
-In addition, the tcfmgr script and tcfmgr.map file, which are installed
-under texmf-dist/texconfig and only used by texconfig, are here.
-
-And there is a copy of fmtutil.cnf, for the sake of the run-texlinks target.
-(It is kept in sync manually, via Master/tlpkg/dev/srclist.txt.)
diff --git a/Build/source/texk/texlive/tl_support/allcm.1 b/Build/source/texk/texlive/tl_support/allcm.1
deleted file mode 100644
index fe75f4ef6d3..00000000000
--- a/Build/source/texk/texlive/tl_support/allcm.1
+++ /dev/null
@@ -1,28 +0,0 @@
-.TH allcm 1 "11/94" "teTeX" "teTeX"
-.SH NAME
-allcm \- force the most important Computer\-Modern\-fonts to be calculated
-.SH SYNOPSIS
-.B allcm [-r]
-.SH DESCRIPTION
-.I allcm
-forces a large number of Computer Modern Fonts to be calculated as pixel files.
-This is done through running
-.IR dvips (1)
-over a certain test-file. Therefore, the fonts are created in the resolution
-needed by dvips.
-
-If the \-r flag is specified, the command
-.IR dvired (1)
-will be used instead of dvips.
-
-.I allcm
-does not recalculate existing fonts (as long as the Metafont mode does not change).
-
-.SH "SEE ALSO"
-allec(1),
-allneeded(1),
-dvips(1),
-dvired(1).
-
-.SH AUTHOR
-Thomas Esser <te@dbs.uni-hannover.de>
diff --git a/Build/source/texk/texlive/tl_support/allec.1 b/Build/source/texk/texlive/tl_support/allec.1
deleted file mode 100644
index 56bf87a60c5..00000000000
--- a/Build/source/texk/texlive/tl_support/allec.1
+++ /dev/null
@@ -1,28 +0,0 @@
-.TH alldc 1 "11/94" "teTeX" "teTeX"
-.SH NAME
-allec \- force the most important ec\-fonts to be calculated
-.SH SYNOPSIS
-.B allec [\-r]
-.SH DESCRIPTION
-.I allec
-forces a large number of ec-style Fonts to be calculated as pixel files.
-This is done through running
-.IR dvips (1)
-over a certain test-file. Therefore, the fonts are created in the resolution
-needed by dvips.
-
-If the \-r flag is specified, the command
-.IR dvired (1)
-will be used instead of dvips.
-
-.I alldc
-does not recalculate existing fonts (as long as the Metafont mode does not change).
-
-.SH "SEE ALSO"
-allcm(1),
-allneeded(1),
-dvips(1),
-dvired(1).
-
-.SH AUTHOR
-Thomas Esser <te@dbs.uni-hannover.de>
diff --git a/Build/source/texk/texlive/tl_support/allneeded.1 b/Build/source/texk/texlive/tl_support/allneeded.1
deleted file mode 100644
index 7d9a67548b7..00000000000
--- a/Build/source/texk/texlive/tl_support/allneeded.1
+++ /dev/null
@@ -1,30 +0,0 @@
-.TH allneeded 1 "11/94" "teTeX" "teTeX"
-.SH NAME
-allneeded \- force the calculation of all fonts now needed
-.SH SYNOPSIS
-.B allneeded [\-r] files ...
-.SH DESCRIPTION
-.I allneeded
-forces the calculation of all fonts that are needed to preview a set of
-dvi files. Just specify where the program should search for files on the
-commandline.
-The fonts generation is triggered by running
-.IR dvips (1)
-over all accessible dvi\-files. Therefore, the fonts are created in the resolution
-needed by dvips.
-
-If the \-r flag is specified, the command
-.IR dvired (1)
-will be used instead of dvips.
-
-.I allneeded
-does not recalculate existing fonts (as long as the Metafont mode does not change).
-
-.SH "SEE ALSO"
-allec(1),
-allcm(1),
-dvips(1),
-dvired(1).
-
-.SH AUTHOR
-Thomas Esser <te@dbs.uni-hannover.de>
diff --git a/Build/source/texk/texlive/tl_support/dvi2fax.1 b/Build/source/texk/texlive/tl_support/dvi2fax.1
deleted file mode 100644
index f7c436d6e33..00000000000
--- a/Build/source/texk/texlive/tl_support/dvi2fax.1
+++ /dev/null
@@ -1,22 +0,0 @@
-.TH DVI2FAX 1 "October 30, 1999"
-.\" man page by Jim Van Zandt <jrv@vanzandt.mv.com> -*- nroff -*-
-.SH NAME
-dvi2fax \- convert a TeX DVI file to G3 fax format
-.SH SYNOPSIS
-\fBdvi2fax\fP [\fB-hi\fP|\fB-lo\fP] \fIfile\fP[.dvi] [\fIoptions for dvips\fP]
-.SH DESCRIPTION
-\fBdvi2fax\fP uses \fBdvips\fP(1) to convert a TeX DVI file to PostScript,
-then \fBgs\fP(1) to convert the PostScript to G3 fax file format.
-.SH OPTIONS
-.LP
-.B -hi
-use high fax resolution (204x196 dpi) (default).
-.LP
-.B -lo
-use low fax resolution (204x98).
-.PP
-\fBdvips\fP options can follow the file name.
-.SH EXAMPLE
-Example: dvi2fax foo -l 2
-.SH SEE ALSO
-\fBdvips\fP(1), \fBgs\fP(1).
diff --git a/Build/source/texk/texlive/tl_support/dvired.1 b/Build/source/texk/texlive/tl_support/dvired.1
deleted file mode 100644
index f76e58087a3..00000000000
--- a/Build/source/texk/texlive/tl_support/dvired.1
+++ /dev/null
@@ -1,63 +0,0 @@
-.TH dvired 1 "09/94" "teTeX" "teTeX"
-.SH NAME
-dvired \- print dvi-files
-.SH SYNOPSIS
-.B dvired
-[
-.B options
-]
-.B file
-.SH DESCRIPTION
-.I dvired
-behaves like
-.IR dvips ,
-except for the fact that two logical pages are put onto each physical
-sheet of paper.
-
-For
-.IR options ,
-see
-.IR dvips (1).
-This program only interprets the following options:
-
-.I \-o file
-\- redirect output into
-.I file.
-
-.I \-P printer
-\- direct output to
-.I printer.
-
-.I \-f
-\- direct output to stdout.
-
-Any other option is passed directly to
-.IR dvips .
-
-.SH EXAMPLES
-It is assumed that the PRINTER-variable is set.
-
-.B dvired \-Plw foo
-\- send output to printer
-.IR lw .
-.br
-.B dvired \-o foo.ps foo
-\- send output to file
-.IR foo.ps .
-.br
-.B dvired \-pp4-7 foo
-\- send 4 pages (reduced onto 2 sheets) of
-.I foo
-to the printer.
-.br
-.B dvired foo \-f | ghostview \-
-\- preview output with ghostview.
-
-.SH "SEE ALSO"
-.IR dvips (1)
-.SH BUGS
-.I dvired
-is fixed on A4 paper size. If you want to use it with other paper, you have
-to change the settings within the source.
-.SH AUTHOR
-Thomas Esser <te@dbs.uni-hannover.de>
diff --git a/Build/source/texk/texlive/tl_support/e2pall.1 b/Build/source/texk/texlive/tl_support/e2pall.1
deleted file mode 100644
index b102568b53a..00000000000
--- a/Build/source/texk/texlive/tl_support/e2pall.1
+++ /dev/null
@@ -1,55 +0,0 @@
-.TH "e2pall" "1" "August 2000" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-e2pall \- convert all EPS files in a LaTeX document to PDF
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBe2pall\fP \fITEXFILE\fP
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBe2pall\fP searches through \fITEXFILE\fP for \eincludegraphics
-commands to find the base names of image files\&. When it finds one,
-\fBe2pall\fP runs \fBepstopdf\fP(1) to create a PDF file from the EPS
-file\&.
-.PP
-\fBe2pall\fP will check to be sure that an existing PDF file is
-up-to-date with the EPS file, and will not run \fBepstopdf\fP(1) if
-the PDF file is newer than the EPS file\&.
-.PP
-.SH "BUGS"
-.PP
-.IP ""
-Seems to be broken
-.IP ""
-Cannot handle \einput{\fIfilename\fP} or
-\eincludegraphics{\fIfilename\fP} split over more than one
-line
-.IP ""
-Must be run from same directory as the LaTeX file
-.IP ""
-Does not look down $TEXINPUTS
-.IP ""
-Cannot handle documents that use \einclude commands
-.IP ""
-Assumes \fIall\fP files included with \eincludegraphics are EPS
-files
-.IP
-.PP
-.SH "SEE ALSO"
-.PP
-\fBepstopdf\fP(1)
-.PP
-.SH "AUTHOR"
-.PP
-\fBe2pall\fP was written by Jody Klymak <jklymak@apl\&.washington\&.edu> and published in a posting to
-the <pdftex@tug\&.org> (mailing list)\&.
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
-.PP
diff --git a/Build/source/texk/texlive/tl_support/fmtutil.1 b/Build/source/texk/texlive/tl_support/fmtutil.1
deleted file mode 100644
index 1b4357cdfa9..00000000000
--- a/Build/source/texk/texlive/tl_support/fmtutil.1
+++ /dev/null
@@ -1,196 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5.
-.TH FMTUTIL "1" "April 2015" "TeX Live" "User Commands"
-.SH NAME
-fmtutil \- manage TeX formats, Metafont bases and Metapost mems, per-user
-.br
-fmtutil-sys \- manage TeX formats, Metafont bases and Metapost mems, system-wide
-.br
-mktexfmt \- create a TeX format, Metafont base, or Metapost mem
-.SH SYNOPSIS
-.B fmtutil
-[\fI\,OPTION\/\fR] ... [\fI\,COMMAND\/\fR]
-.br
-.B fmtutil-sys
-[\fI\,OPTION\/\fR] ... [\fI\,COMMAND\/\fR]
-.br
-.B mktexfmt
-\fI\,FORMAT.fmt|BASE.base|MEM.mem|FMTNAME.EXT\/\fR
-.SH DESCRIPTION
-fmtutil version svn36788 (2015\-04\-13 00:53:26 +0900)
-.PP
-Rebuild and manage TeX formats, Metafont bases and MetaPost mems.
-.PP
-If the command name ends in mktexfmt, only one format can be created.
-The only options supported are \fB\-\-help\fR and \fB\-\-version\fR, and the command
-line must consist of either a format name, with its extension, or a
-plain name that is passed as the argument to \fB\-\-byfmt\fR (see below). The
-full name of the generated file (if any) is written to stdout, and
-nothing else.
-.PP
-If not operating in mktexfmt mode, the command line can be more general,
-and multiple formats can be generated, as follows.
-.SH OPTIONS
-.TP
-\fB\-\-cnffile\fR FILE
-read FILE instead of fmtutil.cnf
-(can be given multiple times, in which case
-all the files are used)
-.HP
-\fB\-\-fmtdir\fR DIRECTORY
-.TP
-\fB\-\-no\-engine\-subdir\fR
-don't use engine\-specific subdir of the fmtdir
-.TP
-\fB\-\-no\-error\-if\-no\-format\fR
-exit successfully if no format is selected
-.TP
-\fB\-\-no\-error\-if\-no\-engine\fR=\fI\,ENGINE1\/\fR,ENGINE2,...
-exit successfully even if the required engine
-.IP
-is missing, if it is included in the list.
-.TP
-\fB\-\-quiet\fR
-be silent
-.TP
-\fB\-\-test\fR
-(not implemented, just for compatibility)
-.TP
-\fB\-\-dolinks\fR
-(not implemented, just for compatibility)
-.TP
-\fB\-\-force\fR
-(not implemented, just for compatibility)
-.SS "Commands:"
-.TP
-\fB\-\-all\fR
-recreate all format files
-.TP
-\fB\-\-missing\fR
-create all missing format files
-.TP
-\fB\-\-refresh\fR
-recreate only existing format files
-.TP
-\fB\-\-byengine\fR ENGINENAME
-(re)create formats using ENGINENAME
-.TP
-\fB\-\-byfmt\fR FORMATNAME
-(re)create format for FORMATNAME
-.TP
-\fB\-\-byhyphen\fR HYPHENFILE
-(re)create formats that depend on HYPHENFILE
-.TP
-\fB\-\-enablefmt\fR FORMATNAME
-enable formatname in config file
-.TP
-\fB\-\-disablefmt\fR FORMATNAME
-disable formatname in config file
-.TP
-\fB\-\-listcfg\fR
-list (enabled and disabled) configurations,
-filtered to available formats
-.TP
-\fB\-\-catcfg\fR
-output the content of the config file
-.TP
-\fB\-\-showhyphen\fR FORMATNAME
-print name of hyphenfile for format FORMATNAME
-.TP
-\fB\-\-version\fR
-show version information and exit
-.TP
-\fB\-\-help\fR
-show this message and exit
-.SH ENVIRONMENT
-.PP
-Explanation of trees and files normally used:
-.IP
-If \fB\-\-cnffile\fR is specified on the command line (possibly multiple
-times), its value(s) are used. Otherwise, fmtutil reads all the
-fmtutil.cnf files found by running `kpsewhich \fB\-all\fR fmtutil.cnf', in the
-order returned by kpsewhich.
-.IP
-In any case, if multiple fmtutil.cnf files are found, all the format
-definitions found in all the fmtutil.cnf files are merged.
-.IP
-Thus, if fmtutil.cnf files are present in all trees, and the default
-layout is used as shipped with TeX Live, the following files are
-read, in the given order.
-.nf
-.IP
-For fmtutil\-sys:
-TEXMFSYSCONFIG \fI\,$TEXLIVE/YYYY/texmf\-config/web2c/fmtutil.cnf\/\fP
-TEXMFSYSVAR \fI\,$TEXLIVE/YYYY/texmf\-var/web2c/fmtutil.cnf\/\fP
-TEXMFLOCAL \fI\,$TEXLIVE/texmf\-local/web2c/fmtutil.cnf\/\fP
-TEXMFDIST \fI\,$TEXLIVE/YYYY/texmf\-dist/web2c/fmtutil.cnf\/\fP
-.IP
-For fmtutil:
-TEXMFCONFIG $HOME/.texliveYYYY/texmf\-config/web2c/fmtutil.cnf
-TEXMFVAR $HOME/.texliveYYYY/texmf\-var/web2c/fmtutil.cnf
-TEXMFHOME \fI\,$HOME/texmf/web2c/fmtutil.cnf\/\fP
-TEXMFSYSCONFIG \fI\,$TEXLIVE/YYYY/texmf\-config/web2c/fmtutil.cnf\/\fP
-TEXMFSYSVAR \fI\,$TEXLIVE/YYYY/texmf\-var/web2c/fmtutil.cnf\/\fP
-TEXMFLOCAL \fI\,$TEXLIVE/texmf\-local/web2c/fmtutil.cnf\/\fP
-TEXMFDIST \fI\,$TEXLIVE/YYYY/texmf\-dist/web2c/fmtutil.cnf\/\fP
-.IP
-(where YYYY is the TeX Live release version).
-.fi
-.IP
-According to the actions, fmtutil might write to one of the given files
-or create a new fmtutil.cnf, described further below.
-.PP
-Where changes are saved:
-.IP
-If config files are given on the command line, then the first one
-given will be used to save any changes from \fB\-\-enable\fR or \fB\-\-disable\fR.
-If the config files are taken from kpsewhich output, then the
-algorithm is more complex:
-.IP
-1) If \fI\,$TEXMFCONFIG/web2c/fmtutil.cnf\/\fP or \fI\,$TEXMFHOME/web2c/fmtutil.cnf\/\fP
-appears in the list of used files, then the one listed first by
-kpsewhich \fB\-\-all\fR (equivalently, the one returned by kpsewhich
-fmtutil.cnf), is used.
-.IP
-2) If neither of the above two are present and changes are made, a
-new config file is created in \fI\,$TEXMFCONFIG/web2c/fmtutil.cnf\/\fP.
-.IP
-In general, the idea is that if a given config file is not writable, a
-higher\-level one can be used. That way, the distribution's settings
-can be overridden for system\-wide using TEXMFLOCAL, and then system
-settings can be overridden again for a particular using using TEXMFHOME.
-.PP
-Resolving multiple definitions of a format:
-.IP
-If a format is defined in more than one config file, then the definition
-coming from the first\-listed fmtutil.cnf is used.
-.PP
-Disabling formats:
-.IP
-fmtutil.cnf files with higher priority (listed earlier) can disable
-formats mentioned in lower priority (listed later) fmtutil.cnf files by
-writing, e.g.,
-.IP
-#! <fmtname> <enginename> <hyphen> <args>
-.IP
-in the higher\-priority fmtutil.cnf file.
-.IP
-As an example, suppose you have want to disable the luajitlatex format.
-You can create the file \fI\,$TEXMFCONFIG/web2c/fmtutil.cnf\/\fP with the content
-.IP
-#! luajitlatex luajittex language.dat,language.dat.lua lualatex.ini
-.IP
-and call fmtutil.
-.PP
-fmtutil vs. fmtutil\-sys (fmtutil \fB\-\-sys\fR):
-.IP
-When fmtutil\-sys is run or the command line option \fB\-\-sys\fR is used,
-TEXMFSYSCONFIG and TEXMFSYSVAR are used instead of TEXMFCONFIG and
-TEXMFVAR, respectively. This is the primary difference between
-fmtutil\-sys and fmtutil.
-.IP
-Other locations may be used if you give them on the command line, or
-these trees don't exist, or you are not using the original TeX Live.
-.SH "REPORTING BUGS"
-Report bugs to: tex\-k@tug.org
-.br
-TeX Live home page: <http://tug.org/texlive/>
diff --git a/Build/source/texk/texlive/tl_support/fmtutil.cnf b/Build/source/texk/texlive/tl_support/fmtutil.cnf
deleted file mode 100644
index 14083c60197..00000000000
--- a/Build/source/texk/texlive/tl_support/fmtutil.cnf
+++ /dev/null
@@ -1,158 +0,0 @@
-# Generated by /home/texlive/karl/Master/bin/x86_64-linux/tlmgr on Sat Oct 3 02:49:47 2020
-# Originally written by Thomas Esser, 1998. Public domain.
-#
-# For guidance on how to support local formats, see the man
-# page of fmtutil, or the output of fmtutil --help.
-#
-# any manual edits of this file (fmtutil.cnf in the TEXMFDIST tree) will
-# be lost on update. So don't do that.
-#
-# The format of the table is:
-#
-# format engine pattern-file arguments
-# Either spaces or tabs can be used as separators.
-#
-# The last "argument" must be the name of the file on which to run the
-# engine (e.g., initex). If the ini-engine is e-TeX (or compatible), and
-# the e-TeX extensions need to be enabled explicitly, the filename must
-# be prefixed with a * character; this is essentially equivalent to the
-# -etex option. (So don't use it if the engine doesn't support -etex.)
-#
-# The purpose of the pattern-file is to support fmtutil's --byhyphen
-# option. It is not included in the command line to rebuild the format.
-# If no pattern-file is desired, use -.
-# fmtutil always passes the -ini option to the engine.
-#
-# Other notes:
-# 1) tex and amstex just load hyphen.tex. No customization.
-# You can have your own customized (via babel's hyphen.cfg)
-# formats on top of plain by using "bplain.tex" instead of
-# plain.tex (e.g., bplain.ini file for bplain format).
-#
-# 2) etex-based formats load language.def, not language.dat.
-#
-# 3) The symbolic link to the right engines (e.g. bplain -> tex)
-# is generated by the "texlinks" script.
-#
-# 4) usual comments start with "# ", whereas disabled configurations
-# start with "#! " in this file.
-#
-# 5) The entries in the main TeX Live fmtutil.cnf are created from the
-# AddFormat directives in (ultimately) the *.tlpsrc files. Don't edit here.
-#
-# from aleph:
-aleph aleph - *aleph.ini
-#
-# from amstex:
-amstex pdftex - -translate-file=cp227.tcx *amstex.ini
-#
-# from context:
-cont-en pdftex cont-usr.tex -8bit *cont-en.mkii
-cont-en xetex cont-usr.tex -8bit *cont-en.mkii
-#! cont-fr pdftex cont-usr.tex -8bit *cont-fr.mkii
-#! cont-it pdftex cont-usr.tex -8bit *cont-it.mkii
-#! cont-nl pdftex cont-usr.tex -8bit *cont-nl.mkii
-#! cont-ro pdftex cont-usr.tex -8bit *cont-ro.mkii
-#
-# from cslatex:
-cslatex pdftex - -etex cslatex.ini
-pdfcslatex pdftex - -etex cslatex.ini
-#
-# from csplain:
-csplain pdftex - -etex -enc csplain-utf8.ini
-luacsplain luatex - -etex csplain.ini
-pdfcsplain luatex - -etex csplain.ini
-pdfcsplain pdftex - -etex -enc csplain-utf8.ini
-pdfcsplain xetex - -etex csplain.ini
-#
-# from eplain:
-eplain pdftex language.dat -translate-file=cp227.tcx *eplain.ini
-#
-# from jadetex:
-jadetex pdftex language.dat *jadetex.ini
-pdfjadetex pdftex language.dat *pdfjadetex.ini
-#
-# from latex-bin:
-dvilualatex luatex language.dat,language.dat.lua dvilualatex.ini
-latex pdftex language.dat -translate-file=cp227.tcx *latex.ini
-lualatex luahbtex language.dat,language.dat.lua lualatex.ini
-pdflatex pdftex language.dat -translate-file=cp227.tcx *pdflatex.ini
-#
-# from latex-bin-dev:
-dvilualatex-dev luatex language.dat,language.dat.lua dvilualatex.ini
-latex-dev pdftex language.dat -translate-file=cp227.tcx *latex.ini
-lualatex-dev luahbtex language.dat,language.dat.lua lualatex.ini
-pdflatex-dev pdftex language.dat -translate-file=cp227.tcx *pdflatex.ini
-#
-# from lollipop:
-lollipop tex - lollipop.ini
-#
-# from luahbtex:
-luahbtex luahbtex language.def,language.dat.lua luatex.ini
-#
-# from luajittex:
-luajithbtex luajithbtex language.def,language.dat.lua luatex.ini
-luajittex luajittex language.def,language.dat.lua luatex.ini
-#
-# from luatex:
-dviluatex luatex language.def,language.dat.lua dviluatex.ini
-luatex luatex language.def,language.dat.lua luatex.ini
-#
-# from metafont:
-mf mf-nowin - -translate-file=cp227.tcx mf.ini
-#
-# from mex:
-mex pdftex mexconf.tex -translate-file=cp227.tcx *mex.ini
-pdfmex pdftex mexconf.tex -translate-file=cp227.tcx *pdfmex.ini
-utf8mex pdftex mexconf.tex -enc *utf8mex.ini
-#
-# from mflua:
-#! mflua mflua-nowin - mf.ini
-#
-# from mltex:
-mllatex pdftex language.dat -translate-file=cp227.tcx -mltex *mllatex.ini
-mltex pdftex - -translate-file=cp227.tcx -mltex mltex.ini
-#
-# from mptopdf:
-mptopdf pdftex - -translate-file=cp227.tcx mptopdf.tex
-#
-# from optex:
-optex luatex hyphen-lan.opm optex.ini
-#
-# from pdftex:
-etex pdftex language.def -translate-file=cp227.tcx *etex.ini
-pdfetex pdftex language.def -translate-file=cp227.tcx *pdfetex.ini
-pdftex pdftex language.def -translate-file=cp227.tcx *pdfetex.ini
-#
-# from platex:
-platex eptex language.dat *platex.ini
-platex-dev eptex language.dat *platex.ini
-#
-# from ptex:
-eptex eptex language.def *eptex.ini
-ptex ptex - ptex.ini
-#
-# from tex:
-tex tex - tex.ini
-#
-# from texsis:
-texsis pdftex - -translate-file=cp227.tcx texsis.ini
-#
-# from uplatex:
-uplatex euptex language.dat *uplatex.ini
-uplatex-dev euptex language.dat *uplatex.ini
-#
-# from uptex:
-euptex euptex language.def *euptex.ini
-uptex uptex - uptex.ini
-#
-# from xelatex-dev:
-xelatex-dev xetex language.dat -etex xelatex.ini
-#
-# from xetex:
-xelatex xetex language.dat -etex xelatex.ini
-xetex xetex language.def -etex xetex.ini
-#
-# from xmltex:
-pdfxmltex pdftex language.dat *pdfxmltex.ini
-xmltex pdftex language.dat *xmltex.ini
diff --git a/Build/source/texk/texlive/tl_support/fmtutil.cnf.5 b/Build/source/texk/texlive/tl_support/fmtutil.cnf.5
deleted file mode 100644
index 4efedcf590c..00000000000
--- a/Build/source/texk/texlive/tl_support/fmtutil.cnf.5
+++ /dev/null
@@ -1,77 +0,0 @@
-.TH "fmtutil\&.cnf" "5" "October 2000" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-fmtutil\&.cnf \- configuration file for fmtutil
-.PP
-.SH "DESCRIPTION"
-.PP
-The \fIfmtutil\&.cnf\fP file contains the configuration information
-for \fBfmtutil\fP(8)\&. Each line contains the name of the format
-(e\&.g\&., ``tex\'\', ``latex\'\', ``omega\'\'), the name of the engine that
-is used by that format (e\&.g\&., ``tex\'\', ``etex\'\', ``omega\'\'), the pattern
-file (e\&.g\&., \fIlanguage\&.dat\fP, \fIlanguage\&.def\fP), and any
-arguments (name of an \fI\&.ini\fP file)\&.
-.PP
-Fields are separated by whitespace\& and complete lines can be commented
-out with ``#\'\'\&. The ``pattern file\'\' field cannot be used to
-define a file that is used while building the format\&.
-It tells \fBfmtutil\fP which files (separated by commas) the
-format creation procedure reads\& and it has an effect to the options
-\fI--showhyphen\fP and \fI--byhyphen\fP\&.
-If the format has no way to
-customize hyphenation, a ``-\'\' can be used to indicate this\&.
-.PP
-.SH "NOTES"
-.PP
-The \fBtex\fP(1) and \fBamstex\fP(1) formats always load
-\fIhyphen\&.tex\fP\&. No customization by a pattern file is available
-for these formats\&. Therefore, the pattern-file field for the
-\fBtex\fP and \fBamstex\fP is usually indicated to be empty (``-\'\')\&.
-.PP
-You can, however, build customized formats on top of plain
-\fBtex\fP(1) or \fBamstex\fP(1) by using \fIbplain\&.tex\fP instead of
-\fIplain\&.tex\fP (b for the \fIBabel\fP system). See, for example,
-the \fIbplain\&.ini\fP file for the bplain format)\&.
-.PP
-\fBetex\fP(1) loads \fIlanguage\&.def\fP, not
-\fIlanguage\&.dat\fP\&.
-.PP
-Symbolic links to the correct engines (e\&.g\&., bplain -> tex)
-are generated by the \fBtexlinks\fP(8) script\&. Remember to run
-\fBtexlinks\fP(8) if you run \fBfmtutil\fP(8) yourself, rather
-than using the FORMATS option in \fBtexconfig\fP(8)\&.
-.PP
-.SH "FILES"
-.PP
-.IP "\fIfmtutil\&.cnf\fP"
-default configuration file
-.IP "\fIlanguage\&.dat\fP"
-hyphenation pattern file
-.IP "\fIlanguage\&.def\fP"
-hyphenation pattern file
-.IP "\fIlanguage\&.dat.lua\fP"
-hyphenation pattern file
-.PP
-.SH "SEE ALSO"
-.PP
-\fBamstex\fP(1), \fBetex\fP(1), \fBfmtutil\fP(8),
-\fBtex\fP(1), \fBtexconfig\fP(8), \fBtexlinks\fP(8)\&.
-.PP
-Web page: <http://tug\&.org/teTeX/>
-.PP
-.SH "BUGS"
-.PP
-None known, but report any bugs found to <tetex@dbs\&.uni-hannover\&.de> (mailing list)\&.
-.PP
-.SH "AUTHOR"
-.PP
-\fIfmtutil\&.cnf\fP was written by Thomas Esser
-<te@dbs\&.uni-hannover\&.de>, and is Copyright 1998,
-1999 but released into the public domain\&.
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
diff --git a/Build/source/texk/texlive/tl_support/fmtutil.help2man b/Build/source/texk/texlive/tl_support/fmtutil.help2man
deleted file mode 100644
index 413acd868bd..00000000000
--- a/Build/source/texk/texlive/tl_support/fmtutil.help2man
+++ /dev/null
@@ -1,22 +0,0 @@
-# $Id$
-# This help2man auxiliary file is in the public domain.
-# Originally created by Karl Berry.
-# See the Makefile for the help2man invocation.
-# do not fill the long TEXMF* tables.
-
-[NAME]
-fmtutil \- manage TeX formats and Metafont bases, per-user
-.br
-fmtutil-sys \- manage TeX formats and Metafont bases, system-wide
-.br
-mktexfmt \- create a TeX format or Metafont base
-
-/show this message and exit/
-.SH ENVIRONMENT
-
-/in the given order/
-.nf
-
-/where YYYY is/
-.fi
-
diff --git a/Build/source/texk/texlive/tl_support/fontinst.1 b/Build/source/texk/texlive/tl_support/fontinst.1
deleted file mode 100644
index b907280d90d..00000000000
--- a/Build/source/texk/texlive/tl_support/fontinst.1
+++ /dev/null
@@ -1,45 +0,0 @@
-.TH "fontinst" "1" "May 2000" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-fontinst \- utility to run TeX as fontinst
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBfontinst\fP \fIpackage\fP
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBfontinst\fP runs \fBtex\fP(1) with the \fB--progname\fP flag set to
-pretend to be the program fontinst (affecting Karl Berry paths)\&.
-.PP
-Typing
-.PP
-\f(CWfontinst fontinst\&.sty\fP
-.PP
-will start \fBtex\fP(1) and give the user an interactive prompt
-(\f(CW*\fP) where fontinst commands can be typed (such as
-\f(CW\elatinfamily{ptm}{}\ebye\fP)\&.
-.PP
-.SH "SEE ALSO"
-.PP
-\fBtex\fP(1)
-.PP
-The fontinst manual, \fIfontinst\&.tex\fP\&.
-.PP
-Web page: <http://tug\&.org/applications/fontinst/>
-.PP
-.SH "BUGS"
-.PP
-None known, but report any bugs found to tex-fonts@tug\&.org (mailing list)\&.
-.PP
-.SH "AUTHOR"
-.PP
-Thomas Esser
-<te@dbs\&.uni-hannover\&.de>
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
diff --git a/Build/source/texk/texlive/tl_support/kpsetool.1 b/Build/source/texk/texlive/tl_support/kpsetool.1
deleted file mode 100644
index addd9b08344..00000000000
--- a/Build/source/texk/texlive/tl_support/kpsetool.1
+++ /dev/null
@@ -1,106 +0,0 @@
-.TH "kpsetool" "1" "September 2000" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-kpsetool \- script to make teTeX-style \fBkpsetool\fP,
-\fBkpsexpand\fP, and \fBkpsepath\fP available
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBkpsetool \fP [ \fIOPTIONS\fP\&.\&.\&. ] \fICOMMAND\fP
-.PP
-\fBkpsexpand\fP [ \fIOPTIONS\fP\&.\&.\&. ] \fISTRING\fP
-.PP
-\fBkpsepath\fP [ \fIOPTIONS\fP\&.\&.\&. ] \fIPATHTYPE\fP
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBkpsetool\fP is a Bourne shell script that makes a teTeX-style
-\fBkpsetool\fP, \fBkpsexpand\fP, and \fBkpsepath\fP available\&.
-\fBkpsetool\fP uses \fBweb2c\fP\'s (new) \fBkpsexpand\fP binary, so the
-syntax for \fBkpsexpand\fP is incompatible with teTeX\'s as of version
-0\&.4\&.
-.PP
-.SH "OPTIONS"
-.PP
-.IP "\fB-m\fP \fImode\fP"
-set Metafont mode
-.IP "\fB-n\fP \fIprogname\fP"
-pretend to be \fIprogname\fP to kpathsea
-.IP "\fB-p\fP"
-act like \fBkpsepath\fP(1)
-.IP "\fB-v\fP"
-act like \fBkpsexpand\fP(1)
-.IP "\fB-w\fP"
-act like \fBkpsewhich\fP(1)
-.PP
-.SH "USAGE"
-.PP
-\fIPATHTYPE\fP can be
-.PP
-.IP "\fBbase\fP"
-Metafont memory dump
-.IP "\fBbib\fP"
-BibTeX bibliography source
-.IP "\fBbst\fP"
-BibTeX style files
-.IP "\fBcnf\fP"
-Kpathsea runtime configuration files
-.IP "\fBdvips_config\fP"
-dvips config files
-.IP "\fBdvips_header\fP"
-dvips header files
-.IP "\fBfmt\fP"
-TeX memory dump
-.IP "\fBgf\fP"
-generic font bitmap
-.IP "\fBmem\fP"
-MetaPost memory dump
-.IP "\fBmf\fP"
-Metafont source
-.IP "\fBmfpool\fP"
-Metafont program strings
-.IP "\fBmp\fP"
-MetaPost source
-.IP "\fBmppool\fP"
-MetaPost program strings
-.IP "\fBmpsupport\fP"
-MetaPost support files
-.IP "\fBpict\fP"
-Other kinds of figures
-.IP "\fBpk\fP"
-packed bitmap font
-.IP "\fBtex\fP"
-TeX source
-.IP "\fBtexpool\fP"
-TeX program strings
-.IP "\fBtfm\fP"
-TeX font metrics
-.IP "\fBtroff_font\fP"
-troff fonts
-.IP "\fBvf\fP"
-virtual font
-.PP
-.SH "SEE ALSO"
-.PP
-\fBkpsewhich\fP(1)
-.PP
-\fIKpathsea: A library for path searching\fP (info or DVI file)
-.PP
-Web page: <http://tug\&.org/teTeX/>
-.PP
-.SH "BUGS"
-.PP
-None known, but report any bugs found to <tetex@dbs\&.uni-hannover\&.de> (mailing list)\&.
-.PP
-.SH "AUTHOR"
-.PP
-\fBkpsetool\fP was written by Thomas Esser
-<te@dbs\&.uni-hannover\&.de> in March, 1997\&. \fBkpsetool\fP
-is in the public domain\&.
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
diff --git a/Build/source/texk/texlive/tl_support/kpsewhere.1 b/Build/source/texk/texlive/tl_support/kpsewhere.1
deleted file mode 100644
index 76700ed33fe..00000000000
--- a/Build/source/texk/texlive/tl_support/kpsewhere.1
+++ /dev/null
@@ -1,50 +0,0 @@
-.TH "kpsewhere" "1" "March 2004" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-kpsewhere \- Expanding \fBkpsewhich\fP to separately iterate over each
-texmf tree listed in $TEXMF.
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBkpsewhere \fP [ \fIkpsewhich-OPTIONS\fP\&.\&.\&. ] \fICOMMAND\fP
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBkpsewhere\fP is an extension to \fBkpsewhich\fP (as \fBwhere\fP is
-for \fBwhich\fP in tcsh). The intention is to provide a way to check
-for conflicts/shadowed files. It will, however, only find \fBone\fP
-file per TEXMF tree.
-.PP
-.SH "OPTIONS"
-.PP
-.IP "\fB-h|--help\fP"
-show a short help message
-.IP "\fB\&*\fP"
-all other options are directly handed to kpsewhich
-.PP
-.SH "SEE ALSO"
-.PP
-\fBkpsewhich\fP(1)
-.PP
-\fIKpathsea: A library for path searching\fP (info or DVI file)
-.PP
-Web page: <http://tug\&.org/teTeX/>
-.PP
-.SH "BUGS"
-.PP
-None known, but report any bugs found to <tetex@dbs\&.uni-hannover\&.de> (mailing list)\&.
-.PP
-.SH "AUTHOR"
-.PP
-\fBkpsewhere\fP was written by Hans Fredrik Nordhaug
-<hans\&.fredrik@nordhaug\&.no>, additions by
-Thomas Esser
-<te@dbs\&.uni-hannover\&.de>, in 2003 and 2004\&. \fBkpsewhere\fP
-is in the public domain\&.
-.PP
-This manual page was written by Frank Küster <frank@kuesterei\&.ch>,
-for the Debian GNU/Linux system\&. It is also in the public domain
-and may be used and changed by others without contacting the author\&.
-Any mistakes or omissions in the manual page are my fault; inquiries
-about or corrections to this manual page should be directed to me (and
-not to the primary author)\&.
diff --git a/Build/source/texk/texlive/tl_support/mktexlsr.1 b/Build/source/texk/texlive/tl_support/mktexlsr.1
deleted file mode 100644
index 5036e381bff..00000000000
--- a/Build/source/texk/texlive/tl_support/mktexlsr.1
+++ /dev/null
@@ -1,49 +0,0 @@
-.TH MKTEXLSR 1 "31 January 2020" "TeX Live" "User Commands"
-.\"=====================================================================
-.if n .ds MP MetaPost
-.if t .ds MP MetaPost
-.if n .ds MF Metafont
-.if t .ds MF M\s-2ETAFONT\s0
-.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP
-.if n .ds TX TeX
-.ie t .ds OX \fIT\v'+0.25m'E\v'-0.25m'X\fP for troff
-.el .ds OX TeX for nroff
-.\" the same but obliqued
-.\" BX definition must follow TX so BX can use TX
-.if t .ds BX \fRB\s-2IB\s0\fP\*(TX
-.if n .ds BX BibTeX
-.\" LX definition must follow TX so LX can use TX
-.if t .ds LX \fRL\\h'-0.36m'\\v'-0.15v'\s-2A\s0\\h'-0.15m'\\v'0.15v'\fP\*(TX
-.if n .ds LX LaTeX
-.\"=====================================================================
-.SH NAME
-mktexlsr \- create ls-R databases
-.SH SYNOPSIS
-.B mktexlsr
-.RI [ directories ]
-.\"=====================================================================
-.SH DESCRIPTION
-This manual page is not meant to be exhaustive. The complete
-documentation for this version of \*(TX can be found in the info file
-or manual
-.IR "Kpathsea: A library for path searching" .
-.PP
-.B mktexlsr
-is used to generate the ls-R databases used by the kpathsea library.
-It will create them for the specified directories, or for a default
-list if no directories are specified.
-.\"=====================================================================
-.SH OPTIONS
-.B mktexlsr
-accepts the following options:
-.TP
-.B --help
-Print help message and exit.
-.TP
-.B --version
-Print version information and exit.
-.\"=====================================================================
-.SH "REPORTING BUGS"
-Report bugs to: tex-k@tug.org (https://lists.tug.org/tex-k)
-.br
-\*(TX Live home page: https://tug.org/texlive/
diff --git a/Build/source/texk/texlive/tl_support/mktexmf.1 b/Build/source/texk/texlive/tl_support/mktexmf.1
deleted file mode 100644
index e6de4aa31c0..00000000000
--- a/Build/source/texk/texlive/tl_support/mktexmf.1
+++ /dev/null
@@ -1,62 +0,0 @@
-.TH MKTEXMF 1 "30 January 2020" "TeX Live" "User Commands"
-.\"=====================================================================
-.if n .ds MP MetaPost
-.if t .ds MP MetaPost
-.if n .ds MF Metafont
-.if t .ds MF M\s-2ETAFONT\s0
-.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP
-.if n .ds TX TeX
-.ie t .ds OX \fIT\v'+0.25m'E\v'-0.25m'X\fP for troff
-.el .ds OX TeX for nroff
-.\" the same but obliqued
-.\" BX definition must follow TX so BX can use TX
-.if t .ds BX \fRB\s-2IB\s0\fP\*(TX
-.if n .ds BX BibTeX
-.\" LX definition must follow TX so LX can use TX
-.if t .ds LX \fRL\\h'-0.36m'\\v'-0.15v'\s-2A\s0\\h'-0.15m'\\v'0.15v'\fP\*(TX
-.if n .ds LX LaTeX
-.\"=====================================================================
-.SH NAME
-mktexmf \- create a Metafont source file
-.SH SYNOPSIS
-.B mktexmf
-.I font
-.\"=====================================================================
-.SH DESCRIPTION
-This manual page is not meant to be exhaustive. The complete
-documentation for this version of \*(TX can be found in the info file
-or manual
-.IR "Kpathsea: A library for path searching" .
-.PP
-.B mktexmf
-is used to generate the \*(MF source file for
-.IR font ,
-if possible. For example,
-.I ecrm1200
-or
-.IR cmr11 .
-.PP
-The name of the generated file is printed on standard output.
-.PP
-.B mktexmf
-is typically called by other programs, rather than from the command
-line.
-.\"=====================================================================
-.SH OPTIONS
-.B mktexmf
-accepts the following options:
-.TP
-.B --help
-Print help message and exit.
-.TP
-.B --version
-Print version information and exit.
-.\"=====================================================================
-.SH "SEE ALSO"
-.BR mktexpk (1),
-.BR mktextfm (1).
-.\"=====================================================================
-.SH "REPORTING BUGS"
-Report bugs to: tex-k@tug.org (https://lists.tug.org/tex-k)
-.br
-\*(TX Live home page: https://tug.org/texlive/
diff --git a/Build/source/texk/texlive/tl_support/mktexpk.1 b/Build/source/texk/texlive/tl_support/mktexpk.1
deleted file mode 100644
index 5bd8d920b7d..00000000000
--- a/Build/source/texk/texlive/tl_support/mktexpk.1
+++ /dev/null
@@ -1,120 +0,0 @@
-.TH MKTEXPK 1 "30 January 2020" "TeX Live" "User Commands"
-.\"=====================================================================
-.if n .ds MP MetaPost
-.if t .ds MP MetaPost
-.if n .ds MF Metafont
-.if t .ds MF M\s-2ETAFONT\s0
-.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP
-.if n .ds TX TeX
-.ie t .ds OX \fIT\v'+0.25m'E\v'-0.25m'X\fP for troff
-.el .ds OX TeX for nroff
-.\" the same but obliqued
-.\" BX definition must follow TX so BX can use TX
-.if t .ds BX \fRB\s-2IB\s0\fP\*(TX
-.if n .ds BX BibTeX
-.\" LX definition must follow TX so LX can use TX
-.if t .ds LX \fRL\\h'-0.36m'\\v'-0.15v'\s-2A\s0\\h'-0.15m'\\v'0.15v'\fP\*(TX
-.if n .ds LX LaTeX
-.\"=====================================================================
-.SH NAME
-mktexpk \- create a PK file for a font
-.SH SYNOPSIS
-.B mktexpk
-.RI [ options ]
-.I font
-.RI [ redirect ]
-.\"=====================================================================
-.SH DESCRIPTION
-This manual page is not meant to be exhaustive. The complete
-documentation for this version of \*(TX can be found in the info file
-or manual
-.IR "Kpathsea: A library for path searching" .
-.PP
-.B mktexpk
-is used to generate a
-.I pk
-file from the \*(MF source files or type1 sources for
-.IR font ,
-if possible.
-.PP
-If
-.I redirect
-is given, it must be string of the form
-.BI >& n
-where
-.I n
-is the number of the file descriptor which is to receive, instead of
-standard output, the name of the generated file.
-.PP
-.B mktexpk
-is typically called by other programs, rather than from the command
-line.
-.\"=====================================================================
-.SH OPTIONS
-.B mktexpk
-accepts the following options:
-.TP
-.BI --bdpi \ num
-Set the base device resolution.
-.TP
-.BI --dpi \ num
-Generate the font at resolution
-.IR num .
-.TP
-.B --help
-Print help message and exit.
-.TP
-.BI --mag \ mag
-The \*(MF magnification that corresponds to the combination of
-.I bdpi
-and
-.I dpi
-that has been specified.
-.TP
-.BI --mfmode \ mode
-The \*(MF mode to use.
-.TP
-.BI --destdir \ dir
-A directory name. If the directory is absolute, it is used as-is.
-Otherwise, it is appended to the root destination directory set in the
-script.
-.TP
-.B --version
-Print version information and exit.
-.\"=====================================================================
-.SH BUGS
-If the
-.I mode
-is not specified,
-.B mktexpk
-tries to determine it from
-.IR bdpi .
-The manner in which this is done is primitive. Since
-.I bpdi
-doesn't provide sufficient information to uniquely determine a
-.I mode
-it is strongly recommended that it be specified explicitly.
-.PP
-If the
-.I mode
-and
-.I bpdi
-don't match, the
-.I mode
-is discarded.
-.PP
-The
-.I dpi
-parameter is redundant, but is not checked for consistency. Worse,
-the program will fail if the wrong
-.I dpi
-is specified.
-.\"=====================================================================
-.SH "SEE ALSO"
-.BR mktexmf (1),
-.BR mktextfm (1).
-.\"=====================================================================
-.SH "REPORTING BUGS"
-Report bugs to: tex-k@tug.org (https://lists.tug.org/tex-k)
-.br
-\*(TX Live home page: https://tug.org/texlive/
diff --git a/Build/source/texk/texlive/tl_support/mktextfm.1 b/Build/source/texk/texlive/tl_support/mktextfm.1
deleted file mode 100644
index 4e269d34086..00000000000
--- a/Build/source/texk/texlive/tl_support/mktextfm.1
+++ /dev/null
@@ -1,92 +0,0 @@
-.TH MKTEXTFM 1 "30 January 2020" "TeX Live" "User Commands"
-.\"=====================================================================
-.if t .ds MF Metafont
-.if n .ds MF Metafont
-.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP
-.if n .ds TX TeX
-.\"=====================================================================
-.SH NAME
-mktextfm \- create a TFM file for a font
-.SH SYNOPSIS
-.B mktextfm
-.RI [ options ]
-.I font
-.\"=====================================================================
-.SH DESCRIPTION
-.B mktextfm
-is used to generate a tfm file from the \*(MF source files for
-.IR font ,
-or
-.BR hbf2gf (1),
-if possible. If
-.I destdir
-is given, the generated file will be installed there, otherwise a
-(rather complicated) heuristic is used. If the tfm file already exists
-in the destination location, this is reported and nothing is done.
-.PP
-If a GF (Generic Font) bitmap file is also generated, as is typical with
-\(*MF, it is converted to PK (Packed Font) and installed similarly.
-.PP
-The full pathname of the generated file is printed on standard output.
-.PP
-If available, the
-.BR mf-nowin (1)
-variant of \*(MF is used to generate fonts to avoid the possibility of
-online display.
-.PP
-.B mktextfm
-is typically called by other programs, via Kpathsea, rather than from
-the command line.
-.\"=====================================================================
-.SH OPTIONS
-.B mktextfm
-accepts the following options:
-.TP
-.BI --destdir \ dir
-A directory name. If the directory is absolute, it is used as-is.
-Otherwise, it is appended to the root destination directory set in the
-script.
-.TP
-.B --help
-Print help message and exit successfully.
-.TP
-.B --version
-Print version information and exit successfully.
-.\"=====================================================================
-.SH ENVIRONMENT
-One environment variable is specific to
-.BR mktextfm :
-.BR MF_MODE_EXTRA_INFO .
-If this is set to a non-empty value, a \*(MF macro
-.B mode_include_extra_info
-will be invoked when the font is made. The standard
-.B modes.mf
-file defines this, as of modes.mf version 4.0, released in 2020.
-This causes the so-called Xerox-world information, notably including the
-.B CODINGSCHEME
-for the font, to be included in the tfm file. (This is not done by
-default since it is too intrusive to redefine the necessary primitives,
-per Don Knuth.) The
-.BR mftrace (1)
-program, for example, can use this to get a clue about the font
-encoding, although the information is not always perfectly definitive or
-unambiguous.
-.PP
-For more about the encodings of \*(MF fonts, see the section ``Bitmap
-font encodings'' in the Dvips manual (e.g.,
-https://tug.org/texinfohtml/dvips.html).
-.PP
-The many other environment variables and various configuration files
-that control a \*(TX system also affect the behavior of
-.BR mktextfm ,
-as usual.
-.\"=====================================================================
-.SH "SEE ALSO"
-.BR mf (1),
-.BR mktexmf (1),
-.BR mktexpk (1).
-.\"=====================================================================
-.SH "REPORTING BUGS"
-Report bugs to: tex-k@tug.org (https://lists.tug.org/tex-k)
-.br
-\*(TX Live home page: https://tug.org/texlive/
diff --git a/Build/source/texk/texlive/tl_support/ps2frag.1 b/Build/source/texk/texlive/tl_support/ps2frag.1
deleted file mode 100644
index b572c5733c1..00000000000
--- a/Build/source/texk/texlive/tl_support/ps2frag.1
+++ /dev/null
@@ -1,41 +0,0 @@
-.TH ps2frag 1 "Feb 95" TeXware
-.SH NAME
-ps2frag - obsolete shell script for the PSfrag system.
-.SH IMPORTANT NOTICE
-The new PSfrag system no longer requires the ps2frag script; instead, it
-handles the processing entirely within TeX/LaTeX and DVIPS. I'm sure you
-will agree that never needing to run ps2frag again is a nice convenience!
-.P
-However, there are two significant differences in the way this new version
-of PSfrag works. Please make yourself aware of them:
-.P
-1) XDvi is no longer able to determine where your PSfrag replacements
-should
-go, so instead it lines them up in a vertical list to the left of the
-figure. This allows you to confirm that they have been typeset properly, at
-least. However, to confirm that PSfrag
-.B positions
-your replacements properly, you will have to view the PostScript
-version of your file with a viewer like GhostView, or print it out.
-This seems to be the
-only disadvantage to the elimination of the pre-processing step.
-.P
-2) If you embed '\\tex' commands inside your figures, you now need to
-explicitly _tell_ PSfrag to process these commands. To do so, use
-\\usepackage[scanall]{psfrag}
-instead of
-\\usepackage{psfrag}
-at the beginning of your LaTeX file.
-.P
-If you only use '\\tex' commands in a small number of figures, then a
-more efficient might be to turn on '\\tex'-scanning only for those
-figures. To do that, add the command '\\psfragscanon' immediately before
-each relevant \\includegraphics or \\epsfbox command.
-.P
-.SH NOTES
-See the PSfrag documentation for further information.
-.SH "SEE ALSO"
-dvips(1), gs(1), ghostview(1), latex(1)
-.SH AUTHORS
-.IP psfrag@rascals.stanford.edu
-The PSfrag maintainer's mailing list.
diff --git a/Build/source/texk/texlive/tl_support/pslatex.1 b/Build/source/texk/texlive/tl_support/pslatex.1
deleted file mode 100644
index c206596a6a0..00000000000
--- a/Build/source/texk/texlive/tl_support/pslatex.1
+++ /dev/null
@@ -1,44 +0,0 @@
-.TH "pslatex" "1" "September 2000" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-pslatex \- utility to typeset LaTeX files using PostScript fonts
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBpslatex\fP [\fILATEXARGS\fP] \fILATEXFILE\fP[\&.tex]
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBpslatex\fP allows you to typeset a LaTeX source file using basic
-Adobe Type 1 PostScript fonts (Times, Helvetica, and Courier)
-\fIwithout\fP editing the file to load the necessary packages\&.
-.PP
-It takes any arguments that \fBlatex\fP(1) can take\&.
-.PP
-.SH "OPTIONS"
-.PP
-None\&.
-.PP
-.SH "FILES"
-.PP
-Many\&. See the readme file for \fIpslatex\&.sty\fP\&.
-.PP
-.SH "SEE ALSO"
-.PP
-\fBlatex\fP(1), \fI\fITEXMF\fP/latex/pslatex/00readme\&.txt\fP
-.PP
-.SH "BUGS"
-.PP
-None known\&. Report any found to the author\&.
-.PP
-.SH "AUTHOR"
-.PP
-\fBpslatex\fP was written by David Carlisle
-<david@dcarlisle\&.demon\&.co\&.uk>\&.
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
diff --git a/Build/source/texk/texlive/tl_support/rubibtex.1 b/Build/source/texk/texlive/tl_support/rubibtex.1
deleted file mode 100644
index 0142072a769..00000000000
--- a/Build/source/texk/texlive/tl_support/rubibtex.1
+++ /dev/null
@@ -1,63 +0,0 @@
-.TH "rubibtex" "1" "October 2000" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-rubibtex \- make a bibliography for (La)TeX using Russian
-letters as item names
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBrubibtex\fP \fIBASENAME\fP
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBrubibtex\fP is used to run \fBbibtex\fP(1) on auxiliary files with
-Russian characters in item names (citation keys)\&. It is part of the
-T2 package\&.
-.PP
-\fBrubibtex\fP copies the auxiliary file to \fI/tmp\fP, uses
-\fBsed\fP(1) to convert Cyrillic character commands to their 8-bit
-ASCII equivalents; runs \fBbibtex\fP(1) on the modified file; and
-finally moves the original auxiliary file back (overwriting the
-modified file)\&.
-.PP
-\fBrubibtex\fP assumes that the \fBbibtex\fP(1) database (\f(CWbib\fP)
-files are encoded with the KOI8-R encoding\&.
-.PP
-.SH "FILES"
-.PP
-.IP
-.IP "\fIbasename\&.aux\fP"
-LaTeX auxiliary file
-.IP
-.PP
-.SH "BUGS"
-.PP
-None known, but report any bugs found to the authors\&.
-.PP
-.SH "COPYRIGHT"
-.PP
-The T2 package is Copyright 1997-1999 Werner Lemberg, Vladimir
-Volovich and any individual authors listed elsewhere in package files\&.
-.PP
-It may be distributed under the conditions of the LaTeX Project Public
-License, either version 1\&.1 of this license or (at your option) any
-later version\&.
-.PP
-.SH "SEE ALSO"
-.PP
-\fBbibtex\fP(1), \fBsed\fP(1),
-<ftp://ftp\&.vsu\&.ru/pub/tex/T2/README>\&.
-.PP
-.SH "AUTHOR"
-.PP
-Werner Lemberg
-<wl@gnu\&.org>, Vladimir Volovich
-<TeX@vvv\&.vsu\&.ru>\&.
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
-.PP
diff --git a/Build/source/texk/texlive/tl_support/rumakeindex.1 b/Build/source/texk/texlive/tl_support/rumakeindex.1
deleted file mode 100644
index 0fb271841d0..00000000000
--- a/Build/source/texk/texlive/tl_support/rumakeindex.1
+++ /dev/null
@@ -1,63 +0,0 @@
-.TH "rumakeindex" "1" "September 2000" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-rumakeindex \- process a LaTeX index using Russian Cyrillic
-characters
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBrumakeindex\fP \fIbasename\fP
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBrumakeindex\fP is used to run \fBmakeindex\fP(1) on \f(CWidx\fP files
-that use Russian characters\&. It is part of the T2 package\&.
-.PP
-\fBrumakeindex\fP runs \fBsed\fP(1) on the \f(CWidx\fP file to convert
-Cyrillic character commands to 8-bit ASCII characters; pipes the
-results through \fBmakeindex\fP(1); and then through \fBtr\fP(1)
-to do some final conversions\&. The results are placed in a KOI8-R
-encoded \f(CWind\fP file\&.
-.PP
-.SH "FILES"
-.PP
-.IP
-.IP "\fIbasename\&.idx\fP"
-LaTeX index entry file
-.IP "\fIbasename\&.ilg\fP"
-LaTeX index log file
-.IP "\fIbasename\&.ind\fP"
-LaTeX processed index file
-.IP
-.PP
-.SH "BUGS"
-.PP
-None known, but report any bugs found to the authors\&.
-.PP
-.SH "COPYRIGHT"
-.PP
-The T2 package is Copyright 1997-1999 Werner Lemberg, Vladimir
-Volovich and any individual authors listed elsewhere in package files\&.
-.PP
-It may be distributed under the conditions of the LaTeX Project Public
-License, either version 1\&.1 of this license or (at your option) any
-later version\&.
-.PP
-.SH "SEE ALSO"
-.PP
-\fBmakeindex\fP(1), \fBsed\fP(1), \fBtr\fP(1),
-<ftp://ftp\&.vsu\&.ru/pub/tex/T2/README>\&.
-.PP
-.SH "AUTHOR"
-.PP
-Werner Lemberg
-<wl@gnu\&.org>, Vladimir Volovich
-<TeX@vvv\&.vsu\&.ru>\&.
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
-.PP
diff --git a/Build/source/texk/texlive/tl_support/tcfmgr b/Build/source/texk/texlive/tl_support/tcfmgr
deleted file mode 100755
index e40ed352371..00000000000
--- a/Build/source/texk/texlive/tl_support/tcfmgr
+++ /dev/null
@@ -1,391 +0,0 @@
-#!/bin/sh
-# $Id$
-# tcfmgr - TeX configuration file manager (sort of).
-# Public domain. Originally written by Thomas Esser.
-
-# invoke the right shell:
-
-test -f /bin/ksh && test -z "$RUNNING_KSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
- && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
-unset RUNNING_KSH
-
-test -f /bin/bsh && test -z "$RUNNING_BSH" \
- && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
- && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
-unset RUNNING_BSH
-
-# preferentially use subprograms from our own directory.
-mydir=`echo "$0" | sed 's,/[^/]*$,,'`
-mydir=`cd "$mydir" && pwd`
-PATH="$mydir:$PATH"; export PATH
-
-# hack around a bug in zsh:
-test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
-
-progname=tcfmgr
-
-abort()
-{
- echo "$progname: $@." >&2
- (exit 1); exit 1
-}
-
-mktexupd()
-{
- setupMktexupd
- "$TFC_MKTEXUPD" "$@" >&2
-}
-
-# call mktexdir script, disable all features (to prevent sticky directories)
-mktexdir()
-{
- setupMktexDir
- MT_FEATURES=none "$TFC_MKTEXDIR" "$@" >&2
-}
-
-setupMap()
-{
- case $setupMapOK in
- "") : ;;
- *) (exit 0); return 0;;
- esac
-
- case $TFC_MAP in
- "") TFC_MAP=`(kpsewhich -progname=texconfig -format='other text files' tcfmgr.map) 2>/dev/null`;;
- esac
-
- case $TFC_MAP in
- "") abort "config file \`tcfmgr.map' (usually in \$TEXMFMAIN/texconfig) not found (ls-R missing?)";;
- esac
-
- if test ! -f "$TFC_MAP"; then
- abort "config file \`TFC_MAP' does not exist"
- fi
- setupMapOK=true
-}
-
-setupTemp()
-{
- case $setupTempOK in
- "") : ;;
- *) (exit 0); return 0;;
- esac
-
- case $TFC_TEMP in
- "") TFC_TEMP=${TEMPDIR-/tmp};;
- esac
-
- if test ! -d "$TFC_TEMP"; then
- abort "temp directory \`$TFC_TEMP' does not exist"
- fi
-
- if test ! -w "$TFC_TEMP"; then
- abort "temp directory \`$TFC_TEMP' is not writable"
- fi
- setupTempOK=true
-}
-
-setupTexmfConfig()
-{
- case $TFC_TEXMFCONFIG in
- "") TFC_TEXMFCONFIG=`(kpsewhich -var-value=TEXMFCONFIG) 2>/dev/null`;;
- *) (exit 0); return 0;;
- esac
- case $TFC_TEXMFCONFIG in
- "") abort "variable \$TEXMFCONFIG is not defined in texmf.cnf";;
- esac
-}
-
-setupMktexDir()
-{
- case $TFC_MKTEXDIR in
- "") TFC_MKTEXDIR=`(kpsewhich --format='web2c files' mktexdir) 2>/dev/null`;;
- esac
-
- case $TFC_MKTEXDIR in
- "") abort "program mktexdir (usually in \$TEXMFMAIN/web2c) not found";;
- esac
-}
-
-setupMktexupd()
-{
- case $TFC_MKTEXUPD in
- "") TFC_MKTEXUPD=`(kpsewhich --format='web2c files' mktexupd) 2>/dev/null`;;
- esac
-
- case $TFC_MKTEXUPD in
- "") abort "program mktexupd (usually in \$TEXMFMAIN/web2c) not found";;
- esac
-}
-
-writableCheck()
-{
- setupTexmfConfig
- if test ! -d "$TFC_TEXMFCONFIG"; then
- mktexdir "$TFC_TEXMFCONFIG" >/dev/null 2>&1
- if test ! -d "$TFC_TEXMFCONFIG"; then
- msg="Directory TEXMFCONFIG=\`$TFC_TEXMFCONFIG' does not exist"
- (exit 1); return 1
- fi
- fi
-
- case "$relDir" in
- "") get_info;;
- esac
- if test -f "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE" \
- && test -w "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE"
- then
- (exit 0); return 0
- fi
-
- if test -d "$TFC_TEXMFCONFIG/$relDir"; then
- if test -w "$TFC_TEXMFCONFIG/$relDir"; then
- (exit 0); return 0
- else
- msg="Directory \`$TFC_TEXMFCONFIG/$relDir' is not writable"
- (exit 1); return 1
- fi
- else
- # we assume that a "mkdir -p" would work if the top-level
- # $TFC_TEXMFCONFIG is writable
- if test -w "$TFC_TEXMFCONFIG"; then
- (exit 0); return 0
- else
- msg="Directory \`$TFC_TEXMFCONFIG' is not writable"
- (exit 1); return 1
- fi
- fi
-}
-
-get_info()
-{
- case "$TFC_FILE" in
- "") abort "missing --file option or empty argument";;
- esac
- setupMap
- # prepare + get info
- IFS=$TAB
- # set -- x `(awk '$1 == file' file=$TFC_FILE <$TFC_MAP) 2>/dev/null`; shift
- set -- x `(grep "^$TFC_FILE[ ]" $TFC_MAP) 2>/dev/null`; shift
- IFS=$STD_IFS
-
- # assign results
- file="$1"
- relDir="$2"
- kpseFormat="$3"
- kpseProgArg="$4"
-
- # sanity checks
- case $file in
- "") abort "no info for file \`$TFC_FILE' in map \`$TFC_MAP'";;
- esac
-
- case $relDir in
- -) abort "no known standard location for file \`$TFC_FILE' in map \`$TFC_MAP'";;
- esac
-
- case $kpseProgArg in
- -) kpseProgArg=kpsewhich;;
- esac
-}
-
-check_out()
-{
- if $createEmptyFile; then
- :
- else
- case "$orig" in
- "")
- get_info
- orig=`(kpsewhich -format="$kpseFormat" -progname="$kpseProgArg" "$TFC_FILE") 2>/dev/null`
- ;;
- *)
- test -f "$orig" || orig=
- esac
-
- case $orig in
- "") abort "file \`$TFC_FILE' not found";;
- esac
- fi
-
- # writableCheck needs to get a valid relDir, so it calls get_info if necessary
- if writableCheck; then
- : ok
- else
- cat >&2 <<eof
-
-There was a problem finding a proper place to store configuration data.
-The message was:
- $msg
-
-To overcome such problems, set up the environment variable TEXMFCONFIG to
-point to a directory tree that is writable to you, e.g.
- TEXMFCONFIG=\$HOME/texmf; export TEXMFCONFIG
-or
- setenv TEXMFCONFIG \$HOME/texmf
-eof
- (exit 1); exit 1
- fi
-
- setupTemp
- : ${TFC_ID=tfc$$}
- for d in "$TFC_TEMP/$TFC_ID" "$TFC_TEMP/$TFC_ID/in" "$TFC_TEMP/$TFC_ID/out"; do
- (umask 077; mkdir "$d") || abort "could not create directory \`$d'"
- done
-
- if $createEmptyFile; then
- (umask 022
- > "$TFC_TEMP/$TFC_ID/in/$TFC_FILE"
- > "$TFC_TEMP/$TFC_ID/out/$TFC_FILE")
- else
- cp "$orig" "$TFC_TEMP/$TFC_ID/in/$TFC_FILE" \
- || abort "copy \`$orig' -> \`$TFC_TEMP/$TFC_ID/in/$TFC_FILE' failed"
-
- cp "$orig" "$TFC_TEMP/$TFC_ID/out/$TFC_FILE" \
- || abort "copy \`$orig' -> \`$TFC_TEMP/$TFC_ID/out/$TFC_FILE' failed"
-
- chmod u+w "$TFC_TEMP/$TFC_ID/out/$TFC_FILE"
- fi
-
- cat >"$TFC_TEMP/$TFC_ID/relDir" <<eof
-$relDir
-eof
-
- cat > "$TFC_TEMP/$TFC_ID/file" <<eof
-$TFC_FILE
-eof
-
- echo "$TFC_ID $TFC_TEMP/$TFC_ID/in/$TFC_FILE $TFC_TEMP/$TFC_ID/out/$TFC_FILE $orig"
-}
-
-check_in()
-{
- setupTemp
-
- if test ! -d "$TFC_TEMP/$TFC_ID"; then
- abort "directory \`$TFC_TEMP/$TFC_ID' does not exist. Perhaps missing arg --id"
- fi
-
- case "$TFC_FILE" in
- "") TFC_FILE=`(cat "$TFC_TEMP/$TFC_ID/file") 2>/dev/null`;;
- esac
-
- for f in "$TFC_TEMP/$TFC_ID/relDir" "$TFC_TEMP/$TFC_ID/file" "$TFC_TEMP/$TFC_ID/in/$TFC_FILE" "$TFC_TEMP/$TFC_ID/out/$TFC_FILE"; do
- if test ! -f "$f"; then
- abort "Oops! file \`$f' does not exist"
- fi
- done
-
- if (cmp "$TFC_TEMP/$TFC_ID/in/$TFC_FILE" "$TFC_TEMP/$TFC_ID/out/$TFC_FILE") >/dev/null 2>&1; then
- (exit 0); return 0
- fi
-
- setupTexmfConfig
- relDir=`cat "$TFC_TEMP/$TFC_ID/relDir"`
- if test ! -d "$TFC_TEXMFCONFIG/$relDir"; then
- setupMktexDir
- mktexdir "$TFC_TEXMFCONFIG/$relDir" || abort "could not create directory \`$TFC_TEXMFCONFIG/$relDir'"
- fi
-
- if test -f "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE"; then
- needsLSRUpdate=false
- test -w "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE" || rm -f "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE"
- else
- needsLSRUpdate=true
- fi
-
- if test -f "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE"; then
- cat <"$TFC_TEMP/$TFC_ID/out/$TFC_FILE" >"$TFC_TEXMFCONFIG/$relDir/$TFC_FILE" ||
- abort "failed to write new file \`$TFC_TEXMFCONFIG/$relDir/$TFC_FILE'"
- else
- cp "$TFC_TEMP/$TFC_ID/out/$TFC_FILE" "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE" ||
- abort "failed to copy \`$TFC_TEMP/$TFC_ID/out/$TFC_FILE' to \`$TFC_TEXMFCONFIG/$relDir/$TFC_FILE'"
- chmod 644 "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE" 2>/dev/null
- fi
- if $needsLSRUpdate; then
- mktexupd "$TFC_TEXMFCONFIG/$relDir" "$TFC_FILE"
- fi
- echo "$TFC_TEXMFCONFIG/$relDir/$TFC_FILE"
- (exit 0); return 0
-}
-
-find_file()
-{
- get_info
- kpsewhich -format="$kpseFormat" -progname="$kpseProgArg" "$TFC_FILE"
-}
-
-help()
-{
- cat <<eof
-Usage: $progname [option] ...
-
-Valid options:
- --reldir specify directory relative to texmf root
- --infile specify input file
- --emptyinfile create an empty input file
- --map specify map file
- --texmfconfig texmf tree for config files
- --mktexdir full path of mktexdir
- --mktexupd full path of mktexupd
- --tmp temp directory
- --id identity string (generated when running command co)
- --file specify configuration entry from map file
- --cmd command to execute
- --help display this help
-
-Valid commands (--cmd) are:
- co check out
- ci check in
- find look up source for file
- mapfile display path name of map file
-eof
-}
-
-show_map()
-{
- setupMap
- echo "$TFC_MAP"
-}
-
-TAB=' '
-SPACE=' '
-NL='
-'
-createEmptyFile=false
-
-STD_IFS="$TAB$SPACE$NL"
-while
- case $1 in
- --reldir) relDir=$2; shift;;
- --infile) orig=$2; shift;;
- --emptyinfile) createEmptyFile=true;;
- --map) TFC_MAP=$2; shift;;
- --texmfconfig)
- TFC_TEXMFCONFIG=$2; shift;;
- --mktexdir)
- TFC_MKTEXDIR=$2;;
- --mktexupd)
- TFC_MKTEXUPD=$2;;
- --tmp) TFC_TEMP=$2; shift;;
- --id) TFC_ID=$2; shift;;
- --file)TFC_FILE=$2; shift;;
- --cmd) TFC_CMD=$2; shift;;
- --help) TFC_CMD=help;;
- "") break;;
- *) abort "unknown option \`$1'; try $progname --help"; (exit 1); exit 1;;
- esac
-do test $# -gt 0 && shift; done
-
-case $TFC_CMD in
- ci) check_in;;
- co) check_out;;
- find) find_file;;
- mapfile) show_map;;
- help) help;;
- "")
- abort "no command; try $progname --help"; (exit 1); exit 1;;
- *)
- abort "unknown command \`$TFC_CMD'; try $progname --help"; (exit 1); exit 1;;
-esac
diff --git a/Build/source/texk/texlive/tl_support/tcfmgr.map b/Build/source/texk/texlive/tl_support/tcfmgr.map
deleted file mode 100644
index 9fc9d4cee16..00000000000
--- a/Build/source/texk/texlive/tl_support/tcfmgr.map
+++ /dev/null
@@ -1,9 +0,0 @@
-# file rel dir search path progname
-dvipdfmx.cfg dvipdfmx other text files dvipdfmx
-config.ps dvips/config dvips config -
-modes.mf metafont/misc .mf -
-pdftexconfig.tex tex/generic/tex-ini-files .tex -
-fmtutil.cnf web2c web2c files -
-mktex.cnf web2c web2c files -
-updmap.cfg web2c web2c files -
-XDvi xdvi other text files xdvi
diff --git a/Build/source/texk/texlive/tl_support/texconfig.1 b/Build/source/texk/texlive/tl_support/texconfig.1
deleted file mode 100644
index 0963b2257a9..00000000000
--- a/Build/source/texk/texlive/tl_support/texconfig.1
+++ /dev/null
@@ -1,216 +0,0 @@
-.TH texconfig 1 "July 2014" "TeX Live" "TeX Live"
-.SH NAME
-texconfig \- configures teTeX or TeX Live
-.LP
-texconfig-sys \- configures teTeX or TeX Live system\-wide
-.SH SYNOPSIS
-.B texconfig
-.LP
-.B texconfig
-[\fB commands\fR ...]
-.LP
-.B texconfig-sys
-.SH DESCRIPTION
-.I texconfig
-allows one to configure and maintain TeX in an easy and convenient
-manner, offering a series of dialog boxes to the user. The directory in
-which \fItexconfig\fP is found is also preferentially used to find
-subprograms.
-.PP
-The
-.I tlmgr
-program has subsumed this function for TeX Live. This program
-is still supported, but the tlmgr interface is much more actively
-developed and tested.
-.PP
-After choosing settings or options, the appropriate files
-are changed automatically and the new settings are applied for the
-user. If needed, copies of files in
-.I TEXMFDIST
-or
-.I TEXMFMAIN
-will be made in the user's
-.I TEXMFCONFIG
-tree.
-.PP
-.I texconfig
-uses either the
-.IR whiptail (1)
-or
-.IR dialog (1)
-program to communicate with the user, so must be run in a terminal.
-.PP
-For making system-wide changes, which will apply to all users of TeX
-(for example, default paper size and so on), run
-.I texconfig-sys
-instead. Changed or generated files will be placed in
-.IR TEXMFSYSCONFIG .
-(You may need to be root to do this.)
-.PP
-.I texconfig
-also offers a non-interactive batch mode which can be accessed with
-the following commands
-.SH COMMANDS
-Commands that accept further options usually display available options
-if called without them. For example,
-.B texconfig dvipdfm paper
-will inform about valid paper settings.
-.PP
-.B
-.IP conf
-Display the system configuration.
-.PP
-.TP
-.B dvipdfm paper [letter|legal|ledger|tabloid|a4|a3]
-Set up dvipdfm to use papersize PAPER by default.
-.TP
-.B dvips add PRINTERNAME
-Create a new (empty) configuration file
-.I TEXMFCONFIG/dvips/config/config.PRINTERNAME.
-This file can later be filled with the
-.B mode, offset
-or
-.B printcmd
-options
-.TP
-.B dvips del PRINTERNAME
-Remove
-.I config.PRINTERNAME
-.TP
-.B dvips mode
-List available Metafont modes.
-.TP
-.B dvips [-P PRINTER] mode MODE
-Change the Metafont mode to
-.I MODE
-for
-.I PRINTER
-or for all output files
-.I (config.ps),
-if no
-.B -P
-option is given.
-.TP
-.B dvips [-P PRINTER] offset x-OFFSET,y-OFFSET
-Set printer offset for
-.I PRINTER
-or for all output files
-.I (config.ps),
-if no
-.B -P
-option is given. Offsets must be given with units, e.g.
-.I 0pt,10pt
-You can use testpage.tex from the LaTeX distribution to find these
-numbers.
-.TP
-.B dvips [-P PRINTER] printcmd CMD
-Set the printing command for
-.I PRINTER
-or for all output files
-.I (config.ps),
-if no
-.B -P
-option is given. Commands might be
-.B lp
-or
-.B lpr.
-See the description of the
-.I o
-option in
-.B info dvips
-or the
-.I -O
-option in
-.B dvips(1).
-.TP
-.B faq
-Display the list of Frequently Asked Questions about
-.B teTeX
-(and their answers).
-.TP
-.B font vardir DIR, font ro, font rw
-.TP
-.B formats
-This command allows to edit
-.B fmtutil.cnf(5)
-and (re)creates any new or changed formats afterwards.
-.TP
-.B hyphen FORMAT
-This command allows to edit the hyphenation configuration file for
-formats that support this, and recreates the formats afterwards to
-enable the new languages. Available formats are shown when no
-.I FORMAT
-is given.
-.IP
-Note that for formats that use LaTeX's
-.I language.dat,
- e.g.
-.I (pdf)jadetex
-and
-.I latex
-itself, this change is not persistent, since this file is a generated
-file. You should not use this command in these cases, read
-.B update-language(1)
-for alternatives.
-.TP
-.B init [format]
-Recreate
-.I format
-or all formats if none is given, and the font information. This is
-the same as calling
-.B fmtutil --byfmt format
-or
-.B fmtutil --all,
-respectively, followed by
-.B updmap.
-.TP
-.B mode-list
-List available printer modes, together with the printers they were
-developed for, and their DPI resolution
-.TP
-.B mode MODE
-Set the default printer mode in
-.I /etc/texmf/web2c/mktex.cnf
-or the respective user file in
-.I $TEXMFCONFIG/web2c
-to
-.B MODE.
-.TP
-.B paper [a4|letter]
-Set the default papersize for
-.B dvips, dvipdfm, pdftex
-and
-.B xdvi.
-The set is restricted because not all programs understand all sizes.
-.TP
-.B pdftex paper [a4|letter]
-Set the default paper size for
-.B pdftex.
-.TP
-.B rehash
-Call
-.B mktexlsr.
-.TP
-.B xdvi paper PAPER
-Set the default paper size for
-.B xdvi.
-The (long) list is available with
-.B texconfig xdvi paper.
-
-.SH ENVIRONMENT
-To let you change files,
-.B texconfig
-will open the editor specified in the VISUAL or EDITOR variables, or
-.B sensible-editor
-if both are unset.
-.SH "SEE ALSO"
-.IR whiptail (1),
-.IR dialog (1),
-.IR tlmgr (1),
-.IR tex (1),
-.IR mf (1),
-.IR vi (1),
-.IR EDITOR
-environment variable.
-.SH AUTHOR
-Thomas Esser
diff --git a/Build/source/texk/texlive/tl_support/texlinks.1 b/Build/source/texk/texlive/tl_support/texlinks.1
deleted file mode 100644
index 75e7effcb15..00000000000
--- a/Build/source/texk/texlive/tl_support/texlinks.1
+++ /dev/null
@@ -1,66 +0,0 @@
-.TH "texlinks" "8" "November 2007" "teTeX" "teTeX"
-.PP
-.SH "NAME"
-texlinks \- maintain symbolic links from format to engine
-.PP
-.SH "SYNOPSIS"
-.PP
-\fBtexlinks\fP [ \fIOPTIONS\fP\&.\&.\&. ] \fIDIRECTORIES\fP\&.\&.\&.
-.PP
-.SH "DESCRIPTION"
-.PP
-\fBtexlinks\fP is used to create or recreate symbolic links from
-formats to engines according to the information in
-\fIfmtutil\&.cnf\fP or a file specified with \fB--cnffile\fP\&.
-.PP
-\fIDIRECTORIES\fP is an optional list of directories in which to
-operate\&. If no directories are specified the list of directories
-depends on the \fB--multiplatform\fP option\&.
-.PP
-.SH "OPTIONS"
-.PP
-.IP "\fB--cnffile\fP \fIFILE\fP or \fB-f\fP \fIFILE\fP"
-use file as configuration file (default:
-\fIfmtutil\&.cnf\fP)
-.IP "\fB--help\fP or \fB-h\fP"
-show some help text
-.IP "\fB--multiplatform\fP or \fB-m\fP"
-operate in all
-platform-specific directories (default:
-operate only in the directory for this
-platform)
-.IP "\fB--silent\fP or \fB-s\fP"
-silently skip over existing
-scripts/binaries instead of printing a warning
-.IP "\fB--unlink\fP or \fB-u\fP"
-Unlink previously created symlinks
-.IP "\fB--verbose\fP or \fB-v\fP"
-+set verbose mode on (default: off)
-.PP
-.SH "FILES"
-.PP
-.IP "\fIfmtutil\&.cnf\fP"
-default configuration file
-.PP
-.SH "SEE ALSO"
-.PP
-\fBfmtutil\fP(1), \fBfmtutil\&.cnf\fP(5)
-.PP
-Web page: <http://tug\&.org/teTeX/>
-.PP
-.SH "BUGS"
-.PP
-None known, but report any bugs found to <tex-k@tug\&.org> (mailing list)\&.
-.PP
-.SH "AUTHOR"
-.PP
-\fBtexlinks\fP was written by Thomas Esser
-<te@dbs\&.uni-hannover\&.de> in 1999\&.
-\fBtexlinks\fP has been released into the public domain\&.
-.PP
-This manual page was written by C\&.M\&. Connelly
-<c@eskimo\&.com>, for
-the Debian GNU/Linux system\&. It may be used by other distributions
-without contacting the author\&. Any mistakes or omissions in the
-manual page are my fault; inquiries about or corrections to this
-manual page should be directed to me (and not to the primary author)\&.
diff --git a/Build/source/texk/texlive/tl_support/updmap.1 b/Build/source/texk/texlive/tl_support/updmap.1
deleted file mode 100644
index c72ae139fec..00000000000
--- a/Build/source/texk/texlive/tl_support/updmap.1
+++ /dev/null
@@ -1,374 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.45.1.
-.TH UPDMAP "1" "May 2014" "TeX Live" "User Commands"
-.SH NAME
-updmap \- manage TeX font maps, per-user
-.br
-updmap-sys \- manage TeX font maps, system-wide
-.SH SYNOPSIS
-.B updmap
-[\fI\,OPTION\/\fR] ... [\fI\,COMMAND\/\fR]
-.br
-.B updmap-sys
-[\fI\,OPTION\/\fR] ... [\fI\,COMMAND\/\fR]
-.SH DESCRIPTION
-updmap version svn33988 (2014\-05\-12 15:39:32 +0900)
-.PP
-Update the default font map files used by pdftex, dvips, and dvipdfm(x),
-and optionally pxdvi, as determined by all configuration files updmap.cfg
-(the ones returned by running "kpsewhich \fB\-\-all\fR updmap.cfg", but see below).
-.PP
-Among other things, these map files are used to determine which fonts
-should be used as bitmaps and which as outlines, and to determine which
-font files are included in the PDF or PostScript output.
-.PP
-updmap\-sys is intended to affect the system\-wide configuration, while
-updmap affects personal configuration files only, overriding the system
-files. As a consequence, once updmap has been run, even a single time,
-running updmap\-sys no longer has any effect. (updmap\-sys issues a
-warning in this situation.)
-.PP
-By default, the TeX filename database (ls\-R) is also updated.
-.SH OPTIONS
-.TP
-\fB\-\-cnffile\fR FILE
-read FILE for the updmap configuration
-(can be given multiple times, in which case
-all the files are used)
-.TP
-\fB\-\-dvipdfmxoutputdir\fR DIR
-specify output directory (dvipdfm(x) syntax)
-.TP
-\fB\-\-dvipsoutputdir\fR DIR
-specify output directory (dvips syntax)
-.TP
-\fB\-\-pdftexoutputdir\fR DIR
-specify output directory (pdftex syntax)
-.TP
-\fB\-\-pxdvioutputdir\fR DIR
-specify output directory (pxdvi syntax)
-.TP
-\fB\-\-outputdir\fR DIR
-specify output directory (for all files)
-.TP
-\fB\-\-copy\fR
-cp generic files rather than using symlinks
-.TP
-\fB\-\-force\fR
-recreate files even if config hasn't changed
-.TP
-\fB\-\-nomkmap\fR
-do not recreate map files
-.TP
-\fB\-\-nohash\fR
-do not run texhash
-.TP
-\fB\-\-sys\fR
-affect system\-wide files (equivalent to updmap\-sys)
-.TP
-\fB\-n\fR, \fB\-\-dry\-run\fR
-only show the configuration, no output
-.TP
-\fB\-\-quiet\fR, \fB\-\-silent\fR
-reduce verbosity
-.SS "Commands:"
-.TP
-\fB\-\-help\fR
-show this message and exit
-.TP
-\fB\-\-version\fR
-show version information and exit
-.TP
-\fB\-\-showoption\fR OPTION
-show the current setting of OPTION
-.TP
-\fB\-\-showoptions\fR OPTION
-show possible settings for OPTION
-.TP
-\fB\-\-setoption\fR OPTION VALUE
-set OPTION to value; option names below
-.TP
-\fB\-\-setoption\fR OPTION=VALUE
-as above, just different syntax
-.TP
-\fB\-\-enable\fR MAPTYPE MAPFILE
-add "MAPTYPE MAPFILE" to updmap.cfg,
-where MAPTYPE is Map, MixedMap, or KanjiMap
-.TP
-\fB\-\-enable\fR Map=MAPFILE
-add "Map MAPFILE" to updmap.cfg
-.HP
-\fB\-\-enable\fR MixedMap=MAPFILE add "MixedMap MAPFILE" to updmap.cfg
-.HP
-\fB\-\-enable\fR KanjiMap=MAPFILE add "KanjiMap MAPFILE" to updmap.cfg
-.TP
-\fB\-\-disable\fR MAPFILE
-disable MAPFILE, of whatever type
-.TP
-\fB\-\-listmaps\fR
-list all active and inactive maps
-.TP
-\fB\-\-listavailablemaps\fR
-same as \fB\-\-listmaps\fR, but without
-unavailable map files
-.TP
-\fB\-\-syncwithtrees\fR
-disable unavailable map files in updmap.cfg
-.PP
-Explanation of the map types: the (only) difference between Map and
-MixedMap is that MixedMap entries are not added to psfonts_pk.map.
-The purpose is to help users with devices that render Type 1 outline
-fonts worse than mode\-tuned Type 1 bitmap fonts. So, MixedMap is used
-for fonts that are available as both Type 1 and Metafont.
-KanjiMap entries are added to psfonts_t1.map and kanjix.map.
-.PP
-Explanation of the OPTION names for \fB\-\-showoptions\fR, \fB\-\-showoption\fR, \fB\-\-setoption\fR:
-.TP
-dvipsPreferOutline
-true,false (default true)
-.IP
-Whether dvips uses bitmaps or outlines, when both are available.
-.TP
-dvipsDownloadBase35
-true,false (default true)
-.IP
-Whether dvips includes the standard 35 PostScript fonts in its output.
-.TP
-pdftexDownloadBase14
-true,false (default true)
-.IP
-Whether pdftex includes the standard 14 PDF fonts in its output.
-.TP
-pxdviUse
-true,false (default false)
-.IP
-Whether maps for pxdvi (Japanese\-patched xdvi) are under updmap's control.
-.TP
-kanjiEmbed
-(any string)
-.TP
-kanjiVariant
-(any string)
-.IP
-See below.
-.TP
-LW35
-URWkb,URW,ADOBEkb,ADOBE (default URWkb)
-.IP
-Adapt the font and file names of the standard 35 PostScript fonts.
-.nf
-.TP
-URWkb
-URW fonts with "berry" filenames (e.g. uhvbo8ac.pfb)
-.TP
-URW
-URW fonts with "vendor" filenames (e.g. n019064l.pfb)
-.fi
-.TP
-ADOBEkb
-Adobe fonts with "berry" filenames (e.g. phvbo8an.pfb)
-.TP
-ADOBE
-Adobe fonts with "vendor" filenames (e.g. hvnbo___.pfb)
-.fi
-.IP
-These options are only read and acted on by updmap; dvips, pdftex, etc.,
-do not know anything about them. They work by changing the default map
-file which the programs read, so they can be overridden by specifying
-command\-line options or configuration files to the programs, as
-explained at the beginning of updmap.cfg.
-.IP
-The options kanjiEmbed and kanjiVariant specify special replacements
-in the map lines. If a map contains the string @kanjiEmbed@, then
-this will be replaced by the value of that option; similarly for
-kanjiVariant. In this way, users of Japanese TeX can select different
-fonts to be included in the final output.
-.SH ENVIRONMENT
-.PP
-Explanation of trees and files normally used:
-.IP
-If \fB\-\-cnffile\fR is specified on the command line (possibly multiple
-times), its value(s) are used. Otherwise, updmap reads all the
-updmap.cfg files found by running `kpsewhich \fB\-all\fR updmap.cfg', in the
-order returned by kpsewhich.
-.IP
-In any case, if multiple updmap.cfg files are found, all the maps
-mentioned in all the updmap.cfg files are merged.
-.IP
-Thus, if updmap.cfg files are present in all trees, and the default
-layout is used as shipped with TeX Live, the following files are
-read, in the given order.
-.nf
-.IP
-For updmap\-sys:
-TEXMFSYSCONFIG \fI\,$TEXLIVE/YYYY/texmf\-config/web2c/updmap.cfg\/\fP
-TEXMFSYSVAR \fI\,$TEXLIVE/YYYY/texmf\-var/web2c/updmap.cfg\/\fP
-TEXMFLOCAL \fI\,$TEXLIVE/texmf\-local/web2c/updmap.cfg\/\fP
-TEXMFDIST \fI\,$TEXLIVE/YYYY/texmf\-dist/web2c/updmap.cfg\/\fP
-.IP
-For updmap:
-TEXMFCONFIG $HOME/.texliveYYYY/texmf\-config/web2c/updmap.cfg
-TEXMFVAR $HOME/.texliveYYYY/texmf\-var/web2c/updmap.cfg
-TEXMFHOME \fI\,$HOME/texmf/web2c/updmap.cfg\/\fP
-TEXMFSYSCONFIG \fI\,$TEXLIVE/YYYY/texmf\-config/web2c/updmap.cfg\/\fP
-TEXMFSYSVAR \fI\,$TEXLIVE/YYYY/texmf\-var/web2c/updmap.cfg\/\fP
-TEXMFLOCAL \fI\,$TEXLIVE/texmf\-local/web2c/updmap.cfg\/\fP
-TEXMFDIST \fI\,$TEXLIVE/YYYY/texmf\-dist/web2c/updmap.cfg\/\fP
-.IP
-(where YYYY is the TeX Live release version).
-.fi
-.IP
-According to the actions, updmap might write to one of the given files
-or create a new updmap.cfg, described further below.
-.PP
-Where changes are saved:
-.IP
-If config files are given on the command line, then the first one
-given will be used to save any changes from \fB\-\-setoption\fR, \fB\-\-enable\fR
-or \fB\-\-disable\fR. If the config files are taken from kpsewhich output,
-then the algorithm is more complex:
-.IP
-1) If \fI\,$TEXMFCONFIG/web2c/updmap.cfg\/\fP or \fI\,$TEXMFHOME/web2c/updmap.cfg\/\fP
-appears in the list of used files, then the one listed first by
-kpsewhich \fB\-\-all\fR (equivalently, the one returned by kpsewhich
-updmap.cfg), is used.
-.IP
-2) If neither of the above two are present and changes are made, a
-new config file is created in \fI\,$TEXMFCONFIG/web2c/updmap.cfg\/\fP.
-.IP
-In general, the idea is that if a given config file is not writable, a
-higher\-level one can be used. That way, the distribution's settings
-can be overridden for system\-wide using TEXMFLOCAL, and then system
-settings can be overridden again for a particular using using TEXMFHOME.
-.PP
-Resolving multiple definitions of a font:
-.IP
-If a font is defined in more than one map file, then the definition
-coming from the first\-listed updmap.cfg is used. If a font is
-defined multiple times within the same map file, one is chosen
-arbitrarily. In both cases a warning is issued.
-.PP
-Disabling maps:
-.IP
-updmap.cfg files with higher priority (listed earlier) can disable
-maps mentioned in lower priority (listed later) updmap.cfg files by
-writing, e.g.,
-.IP
-#! Map mapname.map
-.IP
-or
-.IP
-#! MixedMap mapname.map
-.IP
-in the higher\-priority updmap.cfg file.
-.IP
-As an example, suppose you have a copy of MathTime Pro fonts
-and want to disable the Belleek version of the fonts; that is,
-disable the map belleek.map. You can create the file
-\fI\,$TEXMFCONFIG/web2c/updmap.cfg\/\fP with the content
-.IP
-#! Map belleek.map
-Map mt\-plus.map
-Map mt\-yy.map
-.IP
-and call updmap.
-.PP
-updmap writes the map files for dvips (psfonts.map) and pdftex
-(pdftex.map) to the TEXMFVAR/fonts/map/updmap/{dvips,pdftex}/
-directories.
-.PP
-The log file is written to TEXMFVAR/web2c/updmap.log.
-.PP
-When updmap\-sys is run, TEXMFSYSCONFIG and TEXMFSYSVAR are used
-instead of TEXMFCONFIG and TEXMFVAR, respectively. This is the only
-difference between updmap\-sys and updmap.
-.PP
-Other locations may be used if you give them on the command line, or
-these trees don't exist, or you are not using the original TeX Live.
-.PP
-To see the precise locations of the various files that
-will be read and written, give the \fB\-n\fR option (or read the source).
-.SH EXAMPLES
-.PP
-For step\-by\-step instructions on making new fonts known to TeX, read
-http://tug.org/fonts/fontinstall.html. For even more terse
-instructions, read the beginning of the main updmap.cfg.
-.SH FILES
-Configuration and input files:
-.IP "\fIupdmap\&.cfg\fP"
-Main configuration file\&. In
-\fItexmf-dist/web2c\fP by default, but may be located elsewhere
-depending on your distribution\&. Each texmf tree read should have its
-own \fIupdmap.cfg\fP.
-.IP "\fIdvips35\&.map\fP"
-Map file for standard 35 PostScript fonts for
-use with \fBdvips\fP(1)\&.
-.IP "\fIpdftex35\&.map\fP"
-Map file for standard 35 PostScript fonts for
-use with \fBpdftex\fP(1)\&.
-.IP "\fIps2pk35\&.map\fP"
-Map file for standard 35 PostScript fonts for
-use with \fBps2pk\fP(1)\&.
-.PP
-Output files:
-.IP "\fIpsfonts\&.map\fP"
-For \fBdvips\fP(1)\&.
-Same as \fIpsfonts_t1\&.map\fP if option \fBdvipsPreferOutline\fP active,
-else as \fIpsfonts_pk\&.map\fP.
-.IP "\fIpsfonts_pk\&.map\fP"
-For \fBdvips\fP(1)\&.
-Without information from MixedMap files\&.
-(Setting of \fBdvipsPreferOutline\fP ignored\&.)
-.IP "\fIpsfonts_t1\&.map\fP"
-For \fBdvips\fP(1)\&.
-With information from MixedMap files\&.
-(Setting of \fBdvipsPreferOutline\fP ignored\&.)
-.IP "\fIdownload35\&.map\fP"
-For \fBdvips\fP(1)\&.
-Always downloads the standard 35 fonts\&.
-(Setting of \fBdvipsDownloadBase35\fP ignored\&.)
-.IP "\fIbuiltin35\&.map\fP"
-For \fBdvips\fP(1)\&.
-Never downloads the standard 35 fonts\&.
-(Setting of \fBdvipsDownloadBase35\fP ignored\&.)
-.IP "\fIpdftex\&.map\fP"
-For \fBpdftex\fP(1)\&.
-Same as \fIpdftex_dl14\&.map\fP if option \fBpdftexDownloadBase14\fP active,
-else as \fIpdftex_ndl14\&.map\fP.
-.IP "\fIpdftex_dl14\&.map\fP"
-For \fBpdftex\fP(1)\&.
-Always downloads the standard 14 fonts\&.
-.IP "\fIpdftex_ndl14\&.map\fP"
-For \fBpdftex\fP(1)\&.
-Never downloads the standard 14 fonts\&.
-.IP "\fIps2pk\&.map\fP"
-Similar to \fIpsfonts.map\fP file, but
-forces all fonts to be downloaded, so this map file can be used with
-\fBxdvi\fP(1) and \fBps2pk\fP(1)\&.
-.PP
-Configuration files for \fBdvips\fP(1):
-.IP "\fIconfig\&.builtin35\fP"
-Loads \fIbuiltin35\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.download35\fP"
-Loads \fIdownload35\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.outline\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.pdf\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP and has additional optimizations for PDF generation\&.
-.IP "\fIconfig\&.pk\fP"
-Loads \fIpsfonts_pk\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.www\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-(For compatibility with old versions\&.)
-.IP "\fIconfig\&.gstopk\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.SH "REPORTING BUGS"
-Report bugs to: tex\-k@tug.org
-.br
-TeX Live home page: <http://tug.org/texlive/>
diff --git a/Build/source/texk/texlive/tl_support/updmap.cfg.5 b/Build/source/texk/texlive/tl_support/updmap.cfg.5
deleted file mode 100644
index 43a7cc2d23f..00000000000
--- a/Build/source/texk/texlive/tl_support/updmap.cfg.5
+++ /dev/null
@@ -1,155 +0,0 @@
-.\" Hey, Emacs! This is an -*- nroff -*- source file.
-.\"
-.\" Copyright (C) 2004, 2012 Hilmar Preusse <hille42@web.de>
-.\" Copyright (C) 2012 Norbert Preining <preining@logic.at>
-.\"
-.\" This is free software; you can redistribute it and/or modify it under
-.\" the terms of the GNU General Public License as published by the Free
-.\" Software Foundation; either version 2, or (at your option) any later
-.\" version.
-.\"
-.\" This is distributed in the hope that it will be useful, but WITHOUT
-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-.\" for more details.
-.\"
-.\" You should have received a copy of the GNU General Public License
-.\" along with this program. if not, see <http://www.gnu.org/licenses/>.
-.\"
-.TH "UPDMAP.CFG" "20" "November 2012" "TeX Live" "TeX Live"
-.SH "NAME"
-\fBupdmap.cfg\fR \- configuration of font mapping/inclusion for dvips and
-friends.
-.SH "DESCRIPTION"
-The file \fBupdmap.cfg\fR is the central font configuration file of a
-teTeX system and is read by \fBupdmap\fP(1). It describes if and how
-fonts should be included (or not included) into PS-/PDF-files. This
-works for Outline (Postscript Type1) and Bitmap Fonts (Postscript
-Type3) mostly coming from MetaFont.
-.PP
-\fBupdmap\fP is a utility that creates font configuration files for
-\fBdvips\fP(1), \fBpdftex\fP(1), \fBxdvi\fP(1), \fBps2pk\fP(1),
-\fBgsftopk\fP(1), and \fBdvipdfmx\fP(1)\&. In
-an ideal world, updmap would be unnecessary -- each of these programs
-would read the same configuration file to learn what fonts are
-available and how they should be treated\&. As things stand, however,
-each of these tools has subtly different requirements and thereby
-needs its own font configuration file\&. \fBupdmap\fP creates font
-configuration files for all of these programs from several sources,
-namely all \fBupdmap.cfg\fR, allowing you to easily keep all the different
-configuration files in sync\&.
-.P
-Running "updmap --help" will output the main documentation for using
-\fBupdmap\fR.
-.P
-\fBdvipsPreferOutline\fR
-.br
-Configures if \fBdvips\fR (by default) should prefer bitmap fonts or outline fonts
-if both are available? Independent of this setting, outlines can be forced
-by putting "p psfonts_t1.map" into a config file that dvips reads. Bitmaps
-can be forced by putting "p psfonts_pk.map" into a config file. We provide
-such config files which can be enabled via
-\fBdvips\fR \fI-Poutline\fR (resp. \fBdvips\fR \fI-Ppk\fR).
-.br
-Valid settings for dvipsPreferOutline are \fItrue\fR / \fIfalse\fR.
-.P
-\fBLW35\fR
-.br
-Which fonts of the "Basic 35 Laserwriter Fonts" do you want to use and
-how are the filenames chosen? Valid settings:
-.br
-URW: URW fonts with "vendor" filenames (e.g. n019064l.pfb)
-.br
-URWkb: URW fonts with "berry" filenames (e.g. uhvbo8ac.pfb)
-.br
-ADOBE: Adobe fonts with "vendor" filenames (e.g. hvnbo___.pfb)
-.br
-ADOBEkb: Adobe fonts with "berry" filenames (e.g. phvbo8an.pfb)
-.P
-\fBdvipsDownloadBase35\fR
-.br
-Configures if \fBdvips\fR (by default) should download the 35 base
-PostScript fonts into the document (set \fItrue\fR) or should these
-fonts be used from the ps interpreter / printer (set \fIfalse\fR).
-.br
-The user can override the default by specifying \fBdvips\fR \fI-Pdownload35\fR
-(resp. \fBdvips\fR \fI-Pbuiltin35\fR) to download the LW35 fonts
-(resp. use the built-in fonts).
-.br
-Valid settings are \fItrue\fR / \fIfalse\fR.
-.P
-\fBpdftexDownloadBase14\fR
-.br
-Should \fBpdftex\fR download the 14 base PDF fonts? Since some configurations
-(ps / pdf tools / printers) use bad default fonts, it is safer to download
-the fonts. The pdf files get bigger, but that is the cost.
-.br
-Valid settings are \fItrue\fR (download the fonts) or \fIfalse\fR (don't
-download the fonts). Adobe recommends embedding all fonts.
-.P
-\fBpxdviUse\fR
-.br
-Should special map files for pxdvi be created? pxdvi is an adaption of xdvi
-with support for reading and displaying files generated by the ptex family
-of engines.
-.br
-Valid settings are \fItrue\fR (generate configuration) or \fIfalse\fR. See
-http://www.tug.org/texlive/updmap-kanji.html for detailed discussion.
-.P
-\fBkanjiEmbed\fR
-.br
-\fBkanjiVariant\fR
-.br
-The options \fBkanjiEmbed\fR and \fBkanjiVariant\fR specify special
-replacements in the map lines. In a map, the string "@kanjiEmbed@"
-will be replaced by the value of that option; similarly for
-\fBkanjiVariant\fR. In this way, users of Japanese TeX can select
-different fonts to be included in the final output.
-.P
-\fBMap\fR
-.br
-Points to a map file, which describes a mapping from a font (called in the TeX
-document) to the pfb file containing the Postscript code.
-.br
-Usage: \fBMap\fR filename.map
-.P
-The syntax of map files is the same as \fBdvips\fP(1) uses, see the
-section "psfonts.map" in the manual of \fBdvips\fP(1).
-.P
-\fBMixedMap\fR
-.br
-Similar to \fBMap\fR. It should be used when there is Type1 and a bitmap
-implementation of the font (the latter mostly coming from MetaFont). These
-entries will not be used in the default map of \fBdvips\fR if
-\fBdvipsPreferOutline\fR is set to \fIfalse\fR.
-.br
-Usage: \fBMixedMap\fR filename.map
-.P
-\fBKanjiMap\fR
-.br
-Similar to \fBMap\fR. This should be used for kanji fonts.
-.br
-Usage: \fBKanjiMap\fR filename.map
-.P
-The sign \fB#\fR precedes a comment.
-.P
-Map files not to be used should be commented out using the string
-\fB#!\fR at the beginning of the line. Such entries can be
-(de-)activated using \fBupdmap\fR with the options \fI--enable\fR and
-\fI--disable\fR, respectively.
-
-.SH "AUTHOR"
-This manual page was written by Hilmar Preusse <hille42@web.de> and
-extended by Norbert Preining <preining@logic.at>, for
-the Debian GNU/Linux system by simply copying the comments from
-\fBupdmap.cfg\fR and rewriting some of them. It may be used by other
-distributions without contacting the author. Any mistakes or omissions in
-the manual page are our fault; inquiries about or corrections to this manual
-page should be directed to tex-live@tug.org.
-
-.SH "SEE ALSO"
-updmap(1), dvips(1)
-
-.SH "THANKS TO"
-Frank Kuester,
-Thomas Esser.
diff --git a/Build/source/texk/texlive/tl_support/updmap.help2man b/Build/source/texk/texlive/tl_support/updmap.help2man
deleted file mode 100644
index 30e82b8cf9f..00000000000
--- a/Build/source/texk/texlive/tl_support/updmap.help2man
+++ /dev/null
@@ -1,106 +0,0 @@
-# $Id$
-# This help2man auxiliary file is in the public domain.
-# Originally created by Karl Berry.
-# The FILES text from Claire Connelly.
-# See the Makefile for the help2man invocation.
-# do not fill the long TEXMF* tables.
-
-[NAME]
-updmap \- manage TeX font maps, per-user
-.br
-updmap-sys \- manage TeX font maps, system-wide
-
-/Adapt the font and file/
-.nf
-
-/"vendor" filenames/
-.fi
-
-/in the final output/
-.SH ENVIRONMENT
-
-/in the given order/
-.nf
-
-/where YYYY is/
-.fi
-
-/give the -n option/
-.SH EXAMPLES
-
-[FILES]
-Configuration and input files:
-.IP "\fIupdmap\&.cfg\fP"
-Main configuration file\&. In
-\fItexmf-dist/web2c\fP by default, but may be located elsewhere
-depending on your distribution\&. Each texmf tree read should have its
-own \fIupdmap.cfg\fP.
-.IP "\fIdvips35\&.map\fP"
-Map file for standard 35 PostScript fonts for
-use with \fBdvips\fP(1)\&.
-.IP "\fIpdftex35\&.map\fP"
-Map file for standard 35 PostScript fonts for
-use with \fBpdftex\fP(1)\&.
-.IP "\fIps2pk35\&.map\fP"
-Map file for standard 35 PostScript fonts for
-use with \fBps2pk\fP(1)\&.
-.PP
-Output files:
-.IP "\fIpsfonts\&.map\fP"
-For \fBdvips\fP(1)\&.
-Same as \fIpsfonts_t1\&.map\fP if option \fBdvipsPreferOutline\fP active,
-else as \fIpsfonts_pk\&.map\fP.
-.IP "\fIpsfonts_pk\&.map\fP"
-For \fBdvips\fP(1)\&.
-Without information from MixedMap files\&.
-(Setting of \fBdvipsPreferOutline\fP ignored\&.)
-.IP "\fIpsfonts_t1\&.map\fP"
-For \fBdvips\fP(1)\&.
-With information from MixedMap files\&.
-(Setting of \fBdvipsPreferOutline\fP ignored\&.)
-.IP "\fIdownload35\&.map\fP"
-For \fBdvips\fP(1)\&.
-Always downloads the standard 35 fonts\&.
-(Setting of \fBdvipsDownloadBase35\fP ignored\&.)
-.IP "\fIbuiltin35\&.map\fP"
-For \fBdvips\fP(1)\&.
-Never downloads the standard 35 fonts\&.
-(Setting of \fBdvipsDownloadBase35\fP ignored\&.)
-.IP "\fIpdftex\&.map\fP"
-For \fBpdftex\fP(1)\&.
-Same as \fIpdftex_dl14\&.map\fP if option \fBpdftexDownloadBase14\fP active,
-else as \fIpdftex_ndl14\&.map\fP.
-.IP "\fIpdftex_dl14\&.map\fP"
-For \fBpdftex\fP(1)\&.
-Always downloads the standard 14 fonts\&.
-.IP "\fIpdftex_ndl14\&.map\fP"
-For \fBpdftex\fP(1)\&.
-Never downloads the standard 14 fonts\&.
-.IP "\fIps2pk\&.map\fP"
-Similar to \fIpsfonts.map\fP file, but
-forces all fonts to be downloaded, so this map file can be used with
-\fBxdvi\fP(1) and \fBps2pk\fP(1)\&.
-.PP
-Configuration files for \fBdvips\fP(1):
-.IP "\fIconfig\&.builtin35\fP"
-Loads \fIbuiltin35\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.download35\fP"
-Loads \fIdownload35\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.outline\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.pdf\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP and has additional optimizations for PDF generation\&.
-.IP "\fIconfig\&.pk\fP"
-Loads \fIpsfonts_pk\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-.IP "\fIconfig\&.www\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
-(For compatibility with old versions\&.)
-.IP "\fIconfig\&.gstopk\fP"
-Loads \fIpsfonts_t1\&.map\fP instead
-of \fIpsfonts\&.map\fP\&.
diff --git a/Build/source/texk/texlive/w32_wrapper/README b/Build/source/texk/texlive/w32_wrapper/README
deleted file mode 100644
index 33eb4ae5181..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/README
+++ /dev/null
@@ -1,8 +0,0 @@
-This file and the graphics are public domain.
-
-This directory is for the generic TeX Live wrapper on Windows that is
-used for most scripts. The main file is runscript.tlu.
-
-*.svg are the sources for *.ico,
-and the *.ico are used in wrappers.
-Hence their locaton here.
diff --git a/Build/source/texk/texlive/w32_wrapper/bitmap2eps.ico b/Build/source/texk/texlive/w32_wrapper/bitmap2eps.ico
deleted file mode 100644
index be4be44b3d1..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/bitmap2eps.ico
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w32_wrapper/bitmap2eps.svg b/Build/source/texk/texlive/w32_wrapper/bitmap2eps.svg
deleted file mode 100644
index aac123a3914..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/bitmap2eps.svg
+++ /dev/null
@@ -1,525 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- id="svg3004"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- width="320"
- height="320"
- xml:space="preserve"
- sodipodi:docname="grid_square.svg"><metadata
- id="metadata3010"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
- id="defs3008" /><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1254"
- inkscape:window-height="954"
- id="namedview3006"
- showgrid="false"
- inkscape:zoom="2.334375"
- inkscape:cx="165.30692"
- inkscape:cy="160"
- inkscape:window-x="266"
- inkscape:window-y="30"
- inkscape:window-maximized="0"
- inkscape:current-layer="g3012" /><g
- id="g3012"
- inkscape:groupmode="layer"
- inkscape:label="ink_ext_XXXXXX"
- transform="matrix(1.25,0,0,-1.25,0,320)"><path
- inkscape:connector-curvature="0"
- id="path3016"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0,0 16,0 16,16 0,16 0,0 z" /><path
- style="fill:#100000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 300 L 20 320 L 40 320 L 60 320 L 60 300 L 40 300 L 20 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3018" /><path
- style="fill:#300000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 300 L 60 320 L 80 320 L 100 320 L 100 300 L 80 300 L 60 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3022" /><path
- style="fill:#500000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 300 L 100 320 L 120 320 L 140 320 L 140 300 L 120 300 L 100 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3026" /><path
- style="fill:#700000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 300 L 140 320 L 160 320 L 180 320 L 180 300 L 160 300 L 140 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3030" /><path
- style="fill:#8f0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 300 L 180 320 L 200 320 L 220 320 L 220 300 L 200 300 L 180 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3034" /><path
- style="fill:#536c5d;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 300 L 220 320 L 240 320 L 260 320 L 260 300 L 240 300 L 220 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3038" /><path
- style="fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 300 L 260 320 L 280 320 L 300 320 L 300 300 L 280 300 L 260 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3042" /><path
- inkscape:connector-curvature="0"
- id="path3046"
- style="fill:#1c2224;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 240,0 16,0 0,16 -16,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3048"
- style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,0 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#001000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 260 L 0 280 L 0 300 L 20 300 L 20 280 L 20 260 L 0 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3050" /><path
- style="fill:#101000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 260 L 20 280 L 20 300 L 40 300 L 60 300 L 60 280 L 60 260 L 40 260 L 20 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3052" /><path
- style="fill:#782121;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 260 L 60 280 L 60 300 L 80 300 L 100 300 L 100 280 L 100 260 L 80 260 L 60 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3056" /><path
- style="fill:#501000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 260 L 100 280 L 100 300 L 120 300 L 140 300 L 140 280 L 140 260 L 120 260 L 100 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3060" /><path
- style="fill:#701000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 260 L 140 280 L 140 300 L 160 300 L 180 300 L 180 280 L 180 260 L 160 260 L 140 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3064" /><path
- style="fill:#16502d;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 260 L 180 280 L 180 300 L 200 300 L 220 300 L 220 280 L 220 260 L 200 260 L 180 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3068" /><path
- style="fill:#782121;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 260 L 220 280 L 220 300 L 240 300 L 260 300 L 260 280 L 260 260 L 240 260 L 220 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3072" /><path
- style="fill:#004455;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 260 L 260 280 L 260 300 L 280 300 L 300 300 L 300 280 L 300 260 L 280 260 L 260 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3076" /><path
- style="fill:#782121;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 260 L 300 280 L 300 300 L 320 300 L 320 280 L 320 260 L 300 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3080" /><path
- inkscape:connector-curvature="0"
- id="path3082"
- style="fill:#ff1000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,16 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3116"
- style="fill:#ff2000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,32 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#003000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 220 L 0 240 L 0 260 L 20 260 L 20 240 L 20 220 L 0 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3118" /><path
- style="fill:#164450;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 220 L 20 240 L 20 260 L 40 260 L 60 260 L 60 240 L 60 220 L 40 220 L 20 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3120" /><path
- style="fill:#303000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 220 L 60 240 L 60 260 L 80 260 L 100 260 L 100 240 L 100 220 L 80 220 L 60 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3124" /><path
- style="fill:#503000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 220 L 100 240 L 100 260 L 120 260 L 140 260 L 140 240 L 140 220 L 120 220 L 100 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3128" /><path
- style="fill:#703000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 220 L 140 240 L 140 260 L 160 260 L 180 260 L 180 240 L 180 220 L 160 220 L 140 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3132" /><path
- style="fill:#8f3000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 220 L 180 240 L 180 260 L 200 260 L 220 260 L 220 240 L 220 220 L 200 220 L 180 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3136" /><path
- style="fill:#af3000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 220 L 220 240 L 220 260 L 240 260 L 260 260 L 260 240 L 260 220 L 240 220 L 220 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3140" /><path
- style="fill:#803300;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 220 L 260 240 L 260 260 L 280 260 L 300 260 L 300 240 L 300 220 L 280 220 L 260 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3144" /><path
- style="fill:#808000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 220 L 300 240 L 300 260 L 320 260 L 320 240 L 320 220 L 300 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3148" /><path
- inkscape:connector-curvature="0"
- id="path3150"
- style="fill:#ff3000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,48 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3184"
- style="fill:#ff4000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,64 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#005000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 180 L 0 200 L 0 220 L 20 220 L 20 200 L 20 180 L 0 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3186" /><path
- style="fill:#105000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 180 L 20 200 L 20 220 L 40 220 L 60 220 L 60 200 L 60 180 L 40 180 L 20 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3188" /><path
- style="fill:#305000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 180 L 60 200 L 60 220 L 80 220 L 100 220 L 100 200 L 100 180 L 80 180 L 60 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3192" /><path
- style="fill:#505000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 180 L 100 200 L 100 220 L 120 220 L 140 220 L 140 200 L 140 180 L 120 180 L 100 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3196" /><path
- style="fill:#803300;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 180 L 140 200 L 140 220 L 160 220 L 180 220 L 180 200 L 180 180 L 160 180 L 140 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3200" /><path
- style="fill:#8f5000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 180 L 180 200 L 180 220 L 200 220 L 220 220 L 220 200 L 220 180 L 200 180 L 180 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3204" /><path
- style="fill:#af5000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 180 L 220 200 L 220 220 L 240 220 L 260 220 L 260 200 L 260 180 L 240 180 L 220 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3208" /><path
- style="fill:#536c67;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 180 L 260 200 L 260 220 L 280 220 L 300 220 L 300 200 L 300 180 L 280 180 L 260 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3212" /><path
- style="fill:#784421;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 180 L 300 200 L 300 220 L 320 220 L 320 200 L 320 180 L 300 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3216" /><path
- inkscape:connector-curvature="0"
- id="path3218"
- style="fill:#ff5000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,80 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3252"
- style="fill:#ff6000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,96 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#007000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 140 L 0 160 L 0 180 L 20 180 L 20 160 L 20 140 L 0 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3254" /><path
- style="fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 140 L 20 160 L 20 180 L 40 180 L 60 180 L 60 160 L 60 140 L 40 140 L 20 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3256" /><path
- style="fill:#307000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 140 L 60 160 L 60 180 L 80 180 L 100 180 L 100 160 L 100 140 L 80 140 L 60 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3260" /><path
- style="fill:#507000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 140 L 100 160 L 100 180 L 120 180 L 140 180 L 140 160 L 140 140 L 120 140 L 100 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3264" /><path
- style="fill:#707000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 140 L 140 160 L 140 180 L 160 180 L 180 180 L 180 160 L 180 140 L 160 140 L 140 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3268" /><path
- style="fill:#8f7000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 140 L 180 160 L 180 180 L 200 180 L 220 180 L 220 160 L 220 140 L 200 140 L 180 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3272" /><path
- style="fill:#af7000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 140 L 220 160 L 220 180 L 240 180 L 260 180 L 260 160 L 260 140 L 240 140 L 220 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3276" /><path
- style="fill:#502d16;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 140 L 260 160 L 260 180 L 280 180 L 300 180 L 300 160 L 300 140 L 280 140 L 260 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3280" /><path
- style="fill:#225500;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 140 L 300 160 L 300 180 L 320 180 L 320 160 L 320 140 L 300 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3284" /><path
- inkscape:connector-curvature="0"
- id="path3286"
- style="fill:#ff7000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,112 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3320"
- style="fill:#ff8000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,128 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#782144;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 100 L 0 120 L 0 140 L 20 140 L 20 120 L 20 100 L 0 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3322" /><path
- style="fill:#004455;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 100 L 20 120 L 20 140 L 40 140 L 60 140 L 60 120 L 60 100 L 40 100 L 20 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3324" /><path
- style="fill:#308f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 100 L 60 120 L 60 140 L 80 140 L 100 140 L 100 120 L 100 100 L 80 100 L 60 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3328" /><path
- style="fill:#803300;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 100 L 100 120 L 100 140 L 120 140 L 140 140 L 140 120 L 140 100 L 120 100 L 100 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3332" /><path
- style="fill:#708f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 100 L 140 120 L 140 140 L 160 140 L 180 140 L 180 120 L 180 100 L 160 100 L 140 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3336" /><path
- style="fill:#8f8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 100 L 180 120 L 180 140 L 200 140 L 220 140 L 220 120 L 220 100 L 200 100 L 180 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3340" /><path
- style="fill:#af8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 100 L 220 120 L 220 140 L 240 140 L 260 140 L 260 120 L 260 100 L 240 100 L 220 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3344" /><path
- style="fill:#cf8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 100 L 260 120 L 260 140 L 280 140 L 300 140 L 300 120 L 300 100 L 280 100 L 260 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3348" /><path
- style="fill:#782167;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 100 L 300 120 L 300 140 L 320 140 L 320 120 L 320 100 L 300 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3352" /><path
- inkscape:connector-curvature="0"
- id="path3354"
- style="fill:#ff8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,144 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3388"
- style="fill:#ff9f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,160 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#504416;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 60 L 0 80 L 0 100 L 20 100 L 20 80 L 20 60 L 0 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3390" /><path
- style="fill:#165016;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 60 L 20 80 L 20 100 L 40 100 L 60 100 L 60 80 L 60 60 L 40 60 L 20 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3392" /><path
- style="fill:#502d16;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 60 L 60 80 L 60 100 L 80 100 L 100 100 L 100 80 L 100 60 L 80 60 L 60 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3396" /><path
- style="fill:#668000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 60 L 100 80 L 100 100 L 120 100 L 140 100 L 140 80 L 140 60 L 120 60 L 100 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3400" /><path
- style="fill:#806600;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 60 L 140 80 L 140 100 L 160 100 L 180 100 L 180 80 L 180 60 L 160 60 L 140 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3404" /><path
- style="fill:#008033;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 60 L 180 80 L 180 100 L 200 100 L 220 100 L 220 80 L 220 60 L 200 60 L 180 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3408" /><path
- style="fill:#784421;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 60 L 220 80 L 220 100 L 240 100 L 260 100 L 260 80 L 260 60 L 240 60 L 220 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3412" /><path
- style="fill:#a0892c;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 60 L 260 80 L 260 100 L 280 100 L 300 100 L 300 80 L 300 60 L 280 60 L 260 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3416" /><path
- style="fill:#806600;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 60 L 300 80 L 300 100 L 320 100 L 320 80 L 320 60 L 300 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3420" /><path
- inkscape:connector-curvature="0"
- id="path3422"
- style="fill:#ffaf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,176 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3456"
- style="fill:#ffbf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,192 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#484537;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 20 L 0 40 L 0 60 L 20 60 L 20 40 L 20 20 L 0 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3458" /><path
- style="fill:#338000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 20 L 20 40 L 20 60 L 40 60 L 60 60 L 60 40 L 60 20 L 40 20 L 20 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3460" /><path
- style="fill:#668000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 20 L 60 40 L 60 60 L 80 60 L 100 60 L 100 40 L 100 20 L 80 20 L 60 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3464" /><path
- style="fill:#aa4400;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 20 L 100 40 L 100 60 L 120 60 L 140 60 L 140 40 L 140 20 L 120 20 L 100 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3468" /><path
- style="fill:#008033;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 20 L 140 40 L 140 60 L 160 60 L 180 60 L 180 40 L 180 20 L 160 20 L 140 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3472" /><path
- style="fill:#6f7c91;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 20 L 180 40 L 180 60 L 200 60 L 220 60 L 220 40 L 220 20 L 200 20 L 180 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3476" /><path
- style="fill:#aa4400;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 20 L 220 40 L 220 60 L 240 60 L 260 60 L 260 40 L 260 20 L 240 20 L 220 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3480" /><path
- style="fill:#786721;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 20 L 260 40 L 260 60 L 280 60 L 300 60 L 300 40 L 300 20 L 280 20 L 260 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3484" /><path
- style="fill:#a02c2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 20 L 300 40 L 300 60 L 320 60 L 320 40 L 320 20 L 300 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3488" /><path
- inkscape:connector-curvature="0"
- id="path3490"
- style="fill:#ffcf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,208 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3524"
- style="fill:#ffdf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,224 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3526"
- style="fill:#550000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,240 16,0 0,16 -16,0 0,-16 z" /><path
- style="fill:#483737;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 0 L 20 20 L 40 20 L 60 20 L 60 0 L 40 0 L 20 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3528" /><path
- style="fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 0 L 60 20 L 80 20 L 100 20 L 100 0 L 80 0 L 60 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3532" /><path
- style="fill:#161650;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 0 L 100 20 L 120 20 L 140 20 L 140 0 L 120 0 L 100 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3536" /><path
- style="fill:#445500;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 0 L 140 20 L 160 20 L 180 20 L 180 0 L 160 0 L 140 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3540" /><path
- style="fill:#445016;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 0 L 180 20 L 200 20 L 220 20 L 220 0 L 200 0 L 180 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3544" /><path
- style="fill:#806600;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 0 L 220 20 L 240 20 L 260 20 L 260 0 L 240 0 L 220 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3548" /><path
- style="fill:#89a02c;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 0 L 260 20 L 280 20 L 300 20 L 300 0 L 280 0 L 260 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3552" /><path
- inkscape:connector-curvature="0"
- id="path3556"
- style="fill:#280b0b;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 240,240 16,0 0,16 -16,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3558"
- style="fill:#ffef00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,240 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3560"
- style="fill:#00ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3562"
- style="fill:#10ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 16,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3564"
- style="fill:#20ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 32,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3566"
- style="fill:#30ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 48,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3568"
- style="fill:#40ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 64,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3570"
- style="fill:#50ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 80,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3572"
- style="fill:#60ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 96,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3574"
- style="fill:#70ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 112,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3576"
- style="fill:#80ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 128,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3578"
- style="fill:#8fff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 144,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3580"
- style="fill:#9fff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 160,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3582"
- style="fill:#afff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 176,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3584"
- style="fill:#bfff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 192,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3586"
- style="fill:#cfff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 208,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3588"
- style="fill:#dfff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 224,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3590"
- style="fill:#efff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 240,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3592"
- style="fill:#ffff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,256 0,0 0,0 0,0 z" /><g
- transform="scale(0.90694018,-1.1026086)"
- style="font-size:113.55400085px;font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Frutiger;-inkscape-font-specification:Frutiger Heavy"
- id="text3979"><path
- d="m 18.037517,-135.17236 33.384876,0 c 14.194236,0 30.886688,-3.97441 30.886688,-22.93791 0,-9.65208 -5.450603,-15.32979 -16.011114,-17.48732 l 0,-0.22711 c 8.857203,-2.9524 13.967142,-8.51656 13.967142,-18.5093 0,-13.62646 -11.014753,-20.09906 -25.776758,-20.09906 l -36.450834,0 0,79.2607 m 21.121044,-33.61199 6.472578,0 c 7.267449,0 15.556898,0.79489 15.556898,9.42498 0,8.06233 -8.062342,9.19788 -15.784006,9.19788 l -6.24547,0 0,-18.62286 m 0,-30.65958 6.131916,0 c 7.040341,0 13.853588,0.68133 13.853588,7.94878 0,6.69968 -7.153909,8.403 -14.080696,8.403 l -5.904808,0 0,-16.35178"
- style=""
- id="path3988" /><path
- d="m 93.888041,-135.17236 20.666829,0 -0.45422,-60.86495 0.22711,0 19.30418,60.86495 19.41774,0 20.21261,-60.86495 0.22711,0 -0.34067,60.86495 20.66683,0 0,-79.2607 -32.02223,0 -17.60087,52.68906 -0.2271,0 -16.806,-52.68906 -33.271319,0 0,79.2607"
- style=""
- id="path3990" /><path
- d="m 205.39807,-135.17236 57.34477,0 0,-14.98913 -31.3409,0 5.6777,-4.88282 c 7.49455,-6.47258 24.187,-22.0295 24.187,-37.47282 0,-15.78399 -12.71807,-23.27857 -30.43247,-23.27857 -4.65571,0 -12.15029,0.56777 -23.50568,4.65571 l 0.79488,16.46533 c 4.88281,-2.83885 13.96715,-5.45059 20.78038,-5.45059 6.35902,0 11.24184,2.95241 11.24184,9.99275 0,10.67407 -18.62287,25.89033 -34.74752,39.85745 l 0,15.10269"
- style=""
- id="path3992" /></g><g
- transform="scale(0.90694016,-1.1026086)"
- style="font-size:144.79751587px;font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Frutiger;-inkscape-font-specification:Frutiger Heavy"
- id="text3983"><path
- d="m 17.609618,-14.892303 72.833151,0 0,-19.113273 -45.900813,0 0,-22.878007 41.846482,0 0,-19.113272 -41.846482,0 0,-20.850842 44.30804,0 0,-19.113273 -71.240378,0 0,101.068667"
- style=""
- id="path3995" /><path
- d="m 105.40442,-14.892303 26.93234,0 0,-35.330594 10.42542,0 c 25.19474,0 40.10891,-12.163012 40.10891,-32.579441 0,-22.733192 -14.47978,-33.158632 -45.32162,-33.158632 l -32.14505,0 0,101.068667 m 26.93234,-81.955394 6.95028,0 c 9.26703,0 16.65171,3.330353 16.65171,13.610966 0,10.570208 -7.38468,13.900562 -16.65171,13.900562 l -6.95028,0 0,-27.511528"
- style=""
- id="path3997" /><path
- d="m 193.34402,-17.498659 c 8.97744,2.895948 20.70606,4.343926 30.11789,4.343926 22.44359,0 44.45283,-7.095105 44.45283,-33.303429 0,-36.488937 -47.78318,-25.484379 -47.78318,-41.846482 0,-8.83264 11.29422,-9.411839 18.09969,-9.411839 7.67426,0 15.49334,1.447979 22.44362,4.633521 l 1.73757,-20.850838 c -6.80548,-2.31676 -16.36213,-3.76474 -26.06355,-3.76474 -20.27164,0 -44.01845,6.66071 -44.01845,30.986669 0,36.778532 47.78318,24.905191 47.78318,43.728849 0,8.108653 -8.10867,9.846232 -16.65171,9.846232 -11.1494,0 -20.85085,-2.895955 -27.80113,-6.660686 l -2.31676,22.298817"
- style=""
- id="path3999" /></g></g></svg> \ No newline at end of file
diff --git a/Build/source/texk/texlive/w32_wrapper/calldll.c b/Build/source/texk/texlive/w32_wrapper/calldll.c
deleted file mode 100644
index ddb17f31055..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/calldll.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Public domain.
- * Originally written by Akira Kakuto <kakuto@fuk.kindai.ac.jp>
- *
- * DLL calling main program for TeX & Co
- * DLLPROC must be defined in the Makefile as,
- * e.g., -DDLLPROC=dlltexmain.
- */
-
-__declspec(dllimport) DLLPROC(int ac, char **av);
-int main(int ac, char **av)
-{
- return (DLLPROC(ac, av));
-}
diff --git a/Build/source/texk/texlive/w32_wrapper/callexe.c b/Build/source/texk/texlive/w32_wrapper/callexe.c
deleted file mode 100644
index 2aa041ea0da..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/callexe.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Public domain.
- * Originally written by Akira Kakuto <kakuto@fuk.kindai.ac.jp>
- *
- * WIN32 wrapper program replacing Unix symlinks such as,
- * e.g., ofm2opl -> omfonts.
- *
- * EXEPROG must be defined in the Makefile as,
- * e.g., -DEXEPROG=\"omfonts.exe\".
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <process.h>
-#include <string.h>
-#include <malloc.h>
-
-static int is_include_space(char *s)
-{
- char *p;
- p = strchr(s, ' ');
- if(p) return 1;
- p = strchr(s, '\t');
- if(p) return 1;
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int i;
- char *p;
-
- for(i = 0; i < argc; i++) {
- if(is_include_space(argv[i])) {
- p = (char *)malloc(strlen(argv[i])+3);
- strcpy(p, "\"");
- strcat(p, argv[i]);
- strcat(p, "\"");
- free(argv[i]);
- argv[i] = p;
- }
- }
- argv[argc] = NULL;
- return _spawnvp(_P_WAIT, EXEPROG, (const char * const *)argv);
-}
diff --git a/Build/source/texk/texlive/w32_wrapper/context/mtxrun.dll b/Build/source/texk/texlive/w32_wrapper/context/mtxrun.dll
deleted file mode 100755
index 3c4481c319d..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/context/mtxrun.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w32_wrapper/context/mtxrun.exe b/Build/source/texk/texlive/w32_wrapper/context/mtxrun.exe
deleted file mode 100755
index 0e7882cf926..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/context/mtxrun.exe
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w32_wrapper/context/mtxrun_dll.c b/Build/source/texk/texlive/w32_wrapper/context/mtxrun_dll.c
deleted file mode 100644
index fc2e260f5a2..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/context/mtxrun_dll.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/************************************************************************
-
- Copyright:
-
- Public Domain
- Originally written in 2010 by Tomasz M. Trzeciak and Hans Hagen
-
- This program is derived from the 'runscript' program originally
- written in 2009 by T.M. Trzeciak. It has been adapted for use in
- ConTeXt MkIV.
-
- Comment:
-
- In ConTeXt MkIV we have two core scripts: luatools.lua and
- mtxrun.lua where the second one is used to launch other scripts.
- Normally a user will use a call like:
-
- mtxrun --script font --reload
-
- Here mtxrun is a lua script. In order to avoid the usage of a cmd
- file on windows this runner will start texlua directly. If the
- shared library luatex.dll is available, texlua will be started in
- the same process avoiding thus any additional overhead. Otherwise
- it will be spawned in a new proces.
-
- We also don't want to use other runners, like those that use kpse
- to locate the script as this is exactly what mtxrun itself is doing
- already. Therefore the runscript program is adapted to a more direct
- approach suitable for mtxrun.
-
- Compilation:
-
- with gcc (size optimized):
-
- gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
- gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun
-
- with tcc (extra small size):
-
- tcc -shared -o mtxrun.dll mtxrun_dll.c
- tcc -o mtxrun.exe mtxrun_exe.c mtxrun.def
-
-************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-
-//#define STATIC
-#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t'))
-#define MAX_CMD 32768
-#define DIE(...) { \
- fprintf( stderr, "mtxrun: " ); \
- fprintf( stderr, __VA_ARGS__ ); \
- return 1; \
-}
-
-static char cmdline[MAX_CMD];
-static char dirpath[MAX_PATH];
-static char progname[MAX_PATH];
-static char scriptpath[MAX_PATH];
-static char luatexpath[MAX_PATH];
-HMODULE dllluatex = NULL;
-typedef int ( *mainlikeproc )( int, char ** );
-
-#ifdef STATIC
-int main( int argc, char *argv[] )
-#else
-__declspec(dllexport) int dllrunscript( int argc, char *argv[] )
-#endif
-{
- char *binary, *s, *luatexfname, *argstr, **lua_argv;
- int k, quoted, lua_argc;
- int passprogname = 0;
- unsigned char is_jit=0;
-
- // directory of this module/executable
- HMODULE module_handle = GetModuleHandle( "mtxrun.dll" );
- // if ( module_handle == NULL ) exe path will be used, which is OK too
- k = (int) GetModuleFileName( module_handle, dirpath, MAX_PATH );
- if ( !k || ( k == MAX_PATH ) )
- DIE( "unable to determine a valid module name\n" );
- s = strrchr(dirpath, '\\');
- if ( s == NULL ) DIE( "no directory part in module path: %s\n", dirpath );
- *(++s) = '\0'; //remove file name, leave trailing backslash
-
- // program name
- k = strlen(argv[0]);
- while ( k && (argv[0][k-1] != '/') && (argv[0][k-1] != '\\') ) k--;
- strcpy(progname, &argv[0][k]);
- s = progname;
- if ( s = strrchr(s, '.') ) *s = '\0'; // remove file extension part
-
- /* check "jit" : strlen("jit") = 3 */
- if (strncmp(progname + strlen(progname) - 3, "jit", 3) == 0) {
- is_jit = 1;
- progname[strlen(progname) - 3]='\0';
- }
- else
- is_jit = 0;
-
- // script path
-
- strcpy( scriptpath, dirpath );
- k = strlen(progname);
- if ( k < 6 ) k = 6; // in case the program name is shorter than "mtxrun"
- if ( strlen(dirpath) + k + 4 >= MAX_PATH )
- DIE( "path too long: %s%s\n", dirpath, progname );
-
- if ( strcmpi(progname,"mtxrun") == 0 ) {
- strcat( scriptpath, progname );
- strcat( scriptpath, ".lua" );
- } else if ( strcmpi(progname,"luatools") == 0 ) {
- strcat( scriptpath, "mtxrun.lua" );
- strcpy( progname, "base" );
- passprogname = 1;
- } else if ( strcmpi(progname,"texmfstart") == 0 ) {
- strcat( scriptpath, "mtxrun.lua" );
- } else {
- strcat( scriptpath, "mtxrun.lua" );
- passprogname = 1;
- }
- if ( GetFileAttributes(scriptpath) == INVALID_FILE_ATTRIBUTES )
- DIE( "file not found: %s\n", scriptpath );
-
- // find luatex.exe /luajittex.exe
- if ( SearchPath(
- dirpath, // was getenv( "PATH" ), // path to search (optional)
- (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "luajittex.exe":"luatex.exe");
- } else if ( SearchPath(
- dirpath, // was getenv( "PATH" ), // path to search (optional)
- (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "texluajit.exe":"texlua.exe");
- } else if ( SearchPath(
- getenv("PATH"), // was dirpath, // path to search (optional)
- (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "luajittex.exe":"luatex.exe");
- } else if ( SearchPath(
- getenv("PATH") , // was dirpath, // path to search (optional)
- (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "texluajit.exe":"texlua.exe");
- }else {
- DIE( "unable to locate texlua.exe on the search path" );
- }
-
- /* if ( SearchPath( */
- /* dirpath, // was getenv( "PATH" ), // path to search (optional) */
- /* (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "luajittex.exe":"luatex.exe"); */
- /* }else if ( SearchPath( */
- /* getenv("PATH"), // was dirpath, // path to search (optional) */
- /* (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "luajittex.exe":"luatex.exe"); */
- /* }else if ( SearchPath( */
- /* dirpath, // was getenv( "PATH" ), // path to search (optional) */
- /* (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "texluajit.exe":"texlua.exe"); */
- /* }else if ( SearchPath( */
- /* getenv("PATH") , // was dirpath, // path to search (optional) */
- /* (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "texluajit.exe":"texlua.exe"); */
- /* }else { */
- /* DIE( "unable to locate texlua.exe on the search path" ); */
- /* } */
-
-
-
-
- // link directly with luatex.dll if available in texlua's dir
- strcpy( luatexfname, (is_jit ? "luajittex.dll":"luatex.dll") );
- if ( dllluatex = LoadLibrary(luatexpath) )
- {
- mainlikeproc dllluatexmain = (mainlikeproc) GetProcAddress( dllluatex, (is_jit ? "dllluajittexmain": "dllluatexmain" ));
- if ( dllluatexmain == NULL )
- if (is_jit)
- DIE( "unable to locate dllluatexmain procedure in luajittex.dll" )
- else
- DIE( "unable to locate dllluatexmain procedure in luatex.dll" );
-
- // set up argument list for texlua script
-
- lua_argv = (char **)malloc( (argc + 5) * sizeof(char *) );
- if ( lua_argv == NULL ) DIE( "out of memory\n" );
- lua_argv[lua_argc=0] = luatexfname;
- lua_argv[++lua_argc] = "--luaonly";
- lua_argv[++lua_argc] = scriptpath; // script to execute
- if (passprogname) {
- lua_argv[++lua_argc] = "--script";
- lua_argv[++lua_argc] = progname;
- }
- for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k];
- lua_argv[++lua_argc] = NULL;
-
- // call texlua interpreter
- // dllluatexmain never returns, but we pretend that it does
-
- k = dllluatexmain( lua_argc, lua_argv );
- if (lua_argv) free( lua_argv );
- return k;
- }
- // we are still here, so no luatex.dll; spawn texlua.exe instead
-
- strcpy( luatexfname,binary);
- strcpy( cmdline, " --luaonly " );
- strcpy( cmdline, "\"" );
- strcat( cmdline, luatexpath );
- strcat( cmdline, "\" \"" );
- strcat( cmdline, scriptpath );
- strcat( cmdline, "\"" );
- if (passprogname) {
- strcat( cmdline, " --script " );
- strcat( cmdline, progname );
- }
- argstr = GetCommandLine(); // get the command line of this process
- if ( argstr == NULL ) DIE( "unable to retrieve the command line string\n" );
-
- // skip over argv[0] in the argument string
- // (it can contain embedded double quotes if launched from cmd.exe!)
-
- for ( quoted = 0; (*argstr) && ( !IS_WHITESPACE(*argstr) || quoted ); argstr++ )
- if (*argstr == '"') quoted = !quoted;
-
- // pass through all the arguments
-
- if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD )
- DIE( "command line string too long:\n%s%s\n", cmdline, argstr );
- strcat( cmdline, argstr );
-
- // create child process
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESTDHANDLES;// | STARTF_USESHOWWINDOW;
- //si.dwFlags = STARTF_USESHOWWINDOW;
- //si.wShowWindow = SW_HIDE ; // can be used to hide console window (requires STARTF_USESHOWWINDOW flag)
- si.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
- si.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE );
- si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
- ZeroMemory( &pi, sizeof(pi) );
- if( !CreateProcess(
- NULL, // module name (uses command line if NULL)
- cmdline, // command line
- NULL, // process security atrributes
- NULL, // thread security atrributes
- TRUE, // handle inheritance
- 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS
- NULL, // pointer to environment block (uses parent if NULL)
- NULL, // starting directory (uses parent if NULL)
- &si, // STARTUPINFO structure
- &pi ) // PROCESS_INFORMATION structure
- ) DIE( "command execution failed: %s\n", cmdline );
- DWORD ret = 0;
- CloseHandle( pi.hThread ); // thread handle is not needed
- if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) {
- if ( !GetExitCodeProcess( pi.hProcess, &ret) )
- DIE( "unable to retrieve process exit code: %s\n", cmdline );
- } else DIE( "failed to wait for process termination: %s\n", cmdline );
- CloseHandle( pi.hProcess );
-
- // propagate exit code from the child process
- return ret;
-
-}
diff --git a/Build/source/texk/texlive/w32_wrapper/context/mtxrun_exe.c b/Build/source/texk/texlive/w32_wrapper/context/mtxrun_exe.c
deleted file mode 100644
index 0c27c272e37..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/context/mtxrun_exe.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// This is the .exe part of the mtxrun program, see mtxrun_dll.c
-// for more details.
-
-#include <windows.h>
-
-__declspec(dllimport) int dllrunscript( int argc, char *argv[] );
-
-int main( int argc, char *argv[] ) { return dllrunscript( argc, argv ); }
diff --git a/Build/source/texk/texlive/w32_wrapper/context/readme.txt b/Build/source/texk/texlive/w32_wrapper/context/readme.txt
deleted file mode 100644
index 72892ee2f11..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/context/readme.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Copyright:
-
-The originally 'runscript' program was written by in 2009 by T.M.Trzeciak and is
-public domain. This derived mtxrun program is an adapted version by Hans Hagen and
-Luigi Scarso.
-
-Comment:
-
-In ConTeXt MkIV we have two core scripts: luatools.lua and mtxrun.lua where the
-second one is used to launch other scripts. The mtxrun.exe program calls luatex.exe.
-
-Normally a user will use a call like:
-
- mtxrun --script font --reload
-
-Here mtxrun is a lua script. In order to avoid the usage of a cmd file on windows this
-runner will start texlua directly. In TeXlive a runner is added for each cmd file but
-we don't want that overhead (and extra files). By using an exe we can call these
-scripts in batch files without the need for using call.
-
-The mtxrun.exe file can be copied to a mtxrunjit.exe file in which case luajittex.exe
-is called.
-
- mtxrunjit --script font --reload
-
-We also don't want to use other runners, like those that use kpse to locate the script
-as this is exactly what mtxrun itself is doing already. Therefore the runscript program
-is adapted to a more direct approach suitable for mtxrun.
-
-Compilation:
-
-with gcc (size optimized):
-
- gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
- gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun
-
-with tcc (ver. 0.9.24), extra small size
-
- tcc -shared -o runscript.dll runscript_dll.c
- tcc -o runscript.exe runscript_exe.c runscript.def
diff --git a/Build/source/texk/texlive/w32_wrapper/readme.txt b/Build/source/texk/texlive/w32_wrapper/readme.txt
deleted file mode 100644
index 7914b67aa7a..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/readme.txt
+++ /dev/null
@@ -1,225 +0,0 @@
-
- Script wrappers in TeX Live on Windows
-
- Rationale
-
- Wrappers enable use of scripts on Windows as regular programs.
- They are also required for some binary programs to set up the
- right environment for them.
-
- Batch scripts can be used for wrapping but they are not as universal
- as binaries (there are some odd cases where they don't work) and
- it is hard to make them robust and secure. Compiled binary wrappers
- don't suffer from these problems but they are harder to write, debug
- and maintain in comparison to scripts. For these reasons a hybrid
- approach is taken that combines a binary stub with a launcher script.
-
- Adding wrappers for user scripts
-
- The script wrapping machinery is not limited to scripts shipped with
- TeX Live. You can also use it for script programs from manually
- installed packages. This should minimize problems when using them
- with TeX Live.
-
- First, make sure that there is an interpreter program available on
- your system for the script you want to use. Interpreters for Perl
- and Lua are bundled with TeX Live, all others have to be installed
- independently. Lua scripts are the most efficient to run, so if you
- consider writing a new script, that would be the recommended choice.
-
- The following script types and their file extensions are currently
- supported and searched in that order:
-
- Lua (.tlu;.texlua;.lua) -- included
- Perl (.pl) -- included
- Ruby (.rb) -- requires installation
- Python (.py) -- requires installation
- Tcl (.tcl) -- requires installation
- Java (.jar) -- requires installation
- VBScript (.vbs) -- part of Windows
- JScript (.js) -- part of Windows
- Batch (.bat;.cmd) -- part of Windows
-
- Finally, Unix-style extensionless scripts are searched as last and
- the interpreter program is established based on the she-bang (#!)
- specification on the very first line of the script. This can be
- an arbitrary program but it must be present on the search path.
-
- Next, the script program needs to be installed somewhere below the
- 'scripts' directory under one of the TEXMF trees (consult the
- documentation or texmf/web2c/texmf.cnf file for a list). You may
- need to update the file search database afterwards with:
-
- mktexlsr [TEXMFDIR]
-
- It is also possible to use scripts that are outside of TEXMF hierarchy
- by adjusting TEXMFSCRIPTS environment or kpathsea variable, see
- kpathsea documentation for more information on setting its variables.
-
- Test if the script can be located with:
-
- kpsewhich --format=texmfscripts <script-name>.<ext>
-
- This should output the full path to the script if everything is
- properly installed and configured. If this test is successful,
- the script can be run immediately with:
-
- runscript <script-name> [script arguments]
-
- If you prefer to call the script program simply by its name, copy
- and rename bin/win32/runscript.exe to <script-name>.exe and put it
- somewhere on the search path.
-
- Wrapper structure
-
- Wrappers consist of small binary stubs and a common texlua script.
- The binary stubs are all the same, just different names (but CLI
- and GUI stubs differ, see below, and GUI stubs are actually all
- different due to different embedded icons).
-
- The job of the binary stub is twofold: (a) call the texlua launcher
- script 'runscript.tlu' from the same directory (or more precisely
- from the directory containing 'runscript.dll') and (b) pass to it
- argv[0] and the unparsed argument string as the last two arguments
- (after adding a sentinel argument, which ends with a new line
- character). Arbitrary C strings can be passed, because the script
- is executed by linking with luatex.dll and calling the lua
- interpreter internally rather than by spawning a new process.
-
- There are two flavours of the binary stub: one for CLI programs
- and another one for GUI programs. The GUI variant does not open
- a console window nor does it block the command prompt if started
- from there. It also uses a dialog box to display an error message
- in addition to outputting to stderr.
-
- The stubs are further split into a common DLL and EXE proxies
- to it. This is for maintenance reasons - updates can be done by
- replacement of a single DLL rather than all binary stubs.
-
- The launcher script knows, which variant has been used to invoke it
- based on the sentinel argument. The lack of this argument means
- that it was invoked in a standard way, i.e., through texlua.exe.
-
- All the hard work of locating a script/program to execute happens
- in the launcher script. The located script/program is always
- executed directly by spawning its interpreter (or binary) in a new
- process. The system shell (cmd.exe) is never called (except for
- batch scripts, of course). If the located script happens to be
- a (tex)lua script, it is loaded and called internally from within
- this script, i.e. no new process is spawned. Execution is done
- using a protected call, so any compile or runtime errors are catched.
-
- Source files
-
- runscript.tlu launcher script for locating and dispatching
- target scripts/programs
- runscript_dll.c common DLL part of the binary stubs; locates and
- calls the launcher script
- runscript_exe.c EXE proxy to the common DLL for CLI mode stubs
- wrunscript_exe.c EXE proxy to the common DLL for GUI mode stubs
-
- Compilation of binaries (requires luatex.dll in the same directory)
-
- with gcc (size optimized):
-
- gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -lluatex
- gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript
- gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript
-
- with tcc (extra small size):
-
- tiny_impdef luatex.dll
- tcc -shared -o runscript.dll runscript_dll.c luatex.def
- tcc -o runscript.exe runscript_exe.c runscript.def
- tcc -o wrunscript.exe wrunscript_exe.c runscript.def
-
- License
-
- Originally written in 2009 by Tomasz M. Trzeciak, Public Domain.
-
- Prior work:
- 'tl-w32-wrapper.texlua' by Reinhard Kotucha and Norbert Preining.
- 'tl-w32-wrapper.cmd' by Tomasz M. Trzeciak.
-
- Changelog
-
- 2009/12/04
- - initial version
- 2009/12/15
- - minor fixes for path & extension list parsing
- 2010/01/09
- - added support for GUI mode stubs
- 2010/02/28
- - enable GUI mode stubs for dviout, psv and texworks;
- - added generic handling of sys programs
- - added restricted repstopdf to alias_table
- 2010/03/13
- - added 'readme.txt' and changelog
- - added support and docs for calling user added scripts;
- (use path of 'runscript.dll' instead of .exe stub to
- locate 'runscript.tlu' script)
- - limit search for shell_escape_commands to system trees
- - added function for creating directory hierarchy
- - fixed directory creation for dviout & texworks aliases
- - fixed arg[0] of repstopdf & rpdfcrop
- 2010/03/28
- - restructured docs, added --help and --version options
- (available only when invoked under 'runscript' name)
- - use TEXMF_RESTRICTED_SCRIPTS kpse var for searching
- shell_escape_commands
- - changed command validation to handle a list of commands
- - prepend GUI mode command(s) to the command list
- - added support for .tcl scripts
- 2010/03/31
- - fixed fatal bug in extention_map definition for GUI mode
- 2010/04/15
- - encapsulated main chunk in a function to execute with
- pcall for more robustness and better error catching
- - added texdoctk to scripts4tlperl table
- - added tlgs and tlperl to alias_table; callable as e.g.:
- runscript tlperl ...
- - doc tweaks
- 2010/04/22
- - ensure only backslash is used in USERPROFILE variable
- (Adobe Reader crash case)
- - fixed argument processing for direct execution under texlua
- - more doc tweaks
- 2010/05/30
- - Windows XP or newer required to run TeXworks
- 2010/06/04
- - added support for Perl scripts starting with eval-exec-perl
- construct in place of she-bang (#!)
- 2010/06/25
- - run internal tlperl only with our Perl
- - added fontinst to alias_table
- - added support for all tex4ht commands from mk4ht.pl
- - removed some unsued aliases
- - some code refactoring and cleanup
- 2010/12/28
- - use of external Perl now requires kpathsea variable
- TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL to be explicitly set to 1
- - alias_table replaced with if-elseif-end tests to streamline
- special cases and to avoid hardcoding of texmf* file paths
- - added a2ping to special cases (requires -x switch to Perl)
- - set ASYMPTOTE_GS (for asy) to full path to tlgs
- 2011/01/09
- - removed tex4ht commands starting with ht from mk4ht aliases;
- they have their own scripts and mk4ht calls them internally,
- so aliasing results in an infinite recursion
- - removed alias for fontinst (no fontinst.exe any more)
- - fixed GUI-mode interpreter for Ruby
- 2011/09/10
- - added -dDisableFAPI=true to psview argument list. Needed by
- gs-9.xx
- 2012/03/12
- - added '-i', '.' to psview argument list (author's request)
- - added environment clean up from Perl specific variables
- (when not using external Perl)
- 2012/08/05
- - added alias for fmtutil
- 2013/05/09
- - added alias mkluatexfontdb -> luaotfload-tool
- 2013/07/03
- - fix for psview and UNC paths in unix-style
- - remove not needed is_abs_path function
-
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript.dll b/Build/source/texk/texlive/w32_wrapper/runscript.dll
deleted file mode 100755
index f0d60d00177..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/runscript.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript.exe b/Build/source/texk/texlive/w32_wrapper/runscript.exe
deleted file mode 100755
index 5777d90a17a..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/runscript.exe
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript.tlu b/Build/source/texk/texlive/w32_wrapper/runscript.tlu
deleted file mode 100755
index 90a8659fac1..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/runscript.tlu
+++ /dev/null
@@ -1,941 +0,0 @@
-
-
-local svnrevision = string.match("$Revision: 54353 $", "%d+") or "0"
-local svndate = string.match("$Date: 2020-03-16 21:32:20 +0100 (Mon, 16 Mar 2020) $", "[-%d]+") or "2009-12-04"
-local bannerstr = "runscript wrapper utility (rev. " ..
- svnrevision .. ", " .. svndate .. ")\n" ..
- "usage: runscript script-name [arguments]\n" ..
- "try -help [-v] for more information"
-
-local helpstr = [[
-
- Script wrappers in TeX Live on Windows
-
- Rationale
-
- Wrappers enable use of scripts on Windows as regular programs.
- They are also required for some binary programs to set up the
- right environment for them.
-
- Batch scripts can be used for wrapping but they are not as universal
- as binaries (there are some odd cases where they don't work) and
- it is hard to make them robust and secure. Compiled binary wrappers
- don't suffer from these problems but they are harder to write, debug
- and maintain in comparison to scripts. For these reasons a hybrid
- approach is taken that combines a binary stub with a launcher script.
-
- Adding wrappers for user scripts
-
- The script wrapping machinery is not limited to scripts shipped with
- TeX Live. You can also use it for script programs from manually
- installed packages. This should minimize problems when using them
- with TeX Live.
-
- First, make sure that there is an interpreter program available
- on your system for the script you want to use. Interpreters for
- Perl, Lua and Tcl/Tk (GUI scripts only) are bundled with TeX
- Live, all others have to be installed independently. Lua
- scripts are the most efficient to run, so if you consider
- writing a new script, that would be the recommended choice.
-
- The following script types and their file extensions are currently
- supported and searched in that order:
-
- Lua (.tlu;.texlua;.lua) -- included
- Perl (.pl) -- included
- Ruby (.rb) -- requires installation
- Python (.py) -- requires installation
- Tcl (.tcl) -- included (GUI scripts only)
- Java (.jar) -- requires installation
- VBScript (.vbs) -- part of Windows
- JScript (.js) -- part of Windows
- Batch (.bat;.cmd) -- part of Windows
-
- Finally, Unix-style extensionless scripts are searched as last and
- the interpreter program is established based on the she-bang (#!)
- specification on the very first line of the script. This can be
- an arbitrary program but it must be present on the search path.
-
- Next, the script program needs to be installed somewhere below the
- 'scripts' directory under one of the TEXMF trees (consult the
- documentation or texmf/web2c/texmf.cnf file for a list). You may
- need to update the file search database afterwards with:
-
- mktexlsr [TEXMFDIR]
-
- It is also possible to use scripts that are outside of TEXMF hierarchy
- by adjusting TEXMFSCRIPTS environment or kpathsea variable, see
- kpathsea documentation for more information on setting its variables.
-
- Test if the script can be located with:
-
- kpsewhich --format=texmfscripts <script-name>.<ext>
-
- This should output the full path to the script if everything is
- properly installed and configured. If this test is successful,
- the script can be run immediately with:
-
- runscript <script-name> [script arguments]
-
- If you prefer to call the script program simply by its name, copy
- and rename bin/win32/runscript.exe (or bin/win64/runscript.exe for
- 64-bit Windows) to <script-name>.exe and put it somewhere on the
- search path.]]
-
-local docstr = [[
-
- Wrapper structure
-
- Wrappers consist of small binary stubs and a common texlua script.
- The binary stubs are all the same, just different names (but CLI
- and GUI stubs differ, see below, and GUI stubs are actually all
- different due to different embedded icons).
-
- The job of the binary stub is twofold: (a) call the texlua launcher
- script 'runscript.tlu' from the same directory (or more precisely
- from the directory containing 'runscript.dll') and (b) pass to it
- argv[0] and the unparsed argument string as the last two arguments
- (after adding a sentinel argument, which ends with a new line
- character). Arbitrary C strings can be passed, because the script
- is executed by linking with luatex.dll and calling the lua
- interpreter internally rather than by spawning a new process.
-
- There are two flavours of the binary stub: one for CLI programs
- and another one for GUI programs. The GUI variant does not open
- a console window nor does it block the command prompt if started
- from there. It also uses a dialog box to display an error message
- in addition to outputting to stderr.
-
- The stubs are further split into a common DLL and EXE proxies
- to it. This is for maintenance reasons - updates can be done by
- replacement of a single DLL rather than all binary stubs.
-
- The launcher script knows, which variant has been used to invoke it
- based on the sentinel argument. The lack of this argument means
- that it was invoked in a standard way, i.e., through texlua.exe.
-
- All the hard work of locating a script/program to execute happens
- in the launcher script. The located script/program is always
- executed directly by spawning its interpreter (or binary) in a new
- process. The system shell (cmd.exe) is never called (except for
- batch scripts, of course). If the located script happens to be
- a (tex)lua script, it is loaded and called internally from within
- this script, i.e. no new process is spawned. Execution is done
- using a protected call, so any compile or runtime errors are caught.
-
- Source files
-
- runscript.tlu launcher script for locating and dispatching
- target scripts/programs
- runscript_dll.c common DLL part of the binary stubs; locates and
- calls the launcher script
- runscript_exe.c EXE proxy to the common DLL for CLI mode stubs
- wrunscript_exe.c EXE proxy to the common DLL for GUI mode stubs
-
- Compilation of binaries (requires luatex.dll in the same directory)
-
- with gcc (size optimized):
-
- gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -lluatex
- gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript
- gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript
-
- with tcc (extra small size):
-
- tiny_impdef luatex.dll
- tcc -shared -o runscript.dll runscript_dll.c luatex.def
- tcc -o runscript.exe runscript_exe.c runscript.def
- tcc -o wrunscript.exe wrunscript_exe.c runscript.def
-
- License
-
- Originally written in 2009 by Tomasz M. Trzeciak, Public Domain.
-
- Prior work:
- 'tl-w32-wrapper.texlua' by Reinhard Kotucha and Norbert Preining.
- 'tl-w32-wrapper.cmd' by Tomasz M. Trzeciak.
-
- Changelog
-
- 2009/12/04
- - initial version
- 2009/12/15
- - minor fixes for path & extension list parsing
- 2010/01/09
- - added support for GUI mode stubs
- 2010/02/28
- - enable GUI mode stubs for dviout, psv and texworks;
- - added generic handling of sys programs
- - added restricted repstopdf to alias_table
- 2010/03/13
- - added 'readme.txt' and changelog
- - added support and docs for calling user added scripts;
- (use path of 'runscript.dll' instead of .exe stub to
- locate 'runscript.tlu' script)
- - limit search for shell_escape_commands to system trees
- - added function for creating directory hierarchy
- - fixed directory creation for dviout & texworks aliases
- - fixed arg[0] of repstopdf & rpdfcrop
- 2010/03/28
- - restructured docs, added --help and --version options
- (available only when invoked under 'runscript' name)
- - use TEXMF_RESTRICTED_SCRIPTS kpse var for searching
- shell_escape_commands
- - changed command validation to handle a list of commands
- - prepend GUI mode command(s) to the command list
- - added support for .tcl scripts
- 2010/03/31
- - fixed fatal bug in extention_map definition for GUI mode
- 2010/04/15
- - encapsulated main chunk in a function to execute with
- pcall for more robustness and better error catching
- - added texdoctk to scripts4tlperl table
- - added tlgs and tlperl to alias_table; callable as e.g.:
- runscript tlperl ...
- - doc tweaks
- 2010/04/22
- - ensure only backslash is used in USERPROFILE variable
- (Adobe Reader crash case)
- - fixed argument processing for direct execution under texlua
- - more doc tweaks
- 2010/05/30
- - Windows XP or newer required to run TeXworks
- 2010/06/04
- - added support for Perl scripts starting with eval-exec-perl
- construct in place of she-bang (#!)
- 2010/06/25
- - run internal tlperl only with our Perl
- - added fontinst to alias_table
- - added support for all tex4ht commands from mk4ht.pl
- - removed some unsued aliases
- - some code refactoring and cleanup
- 2010/12/28
- - use of external Perl now requires kpathsea variable
- TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL to be explicitly set to 1
- - alias_table replaced with if-elseif-end tests to streamline
- special cases and to avoid hardcoding of texmf* file paths
- - added a2ping to special cases (requires -x switch to Perl)
- - set ASYMPTOTE_GS (for asy) to full path to tlgs
- 2011/01/09
- - removed tex4ht commands starting with ht from mk4ht aliases;
- they have their own scripts and mk4ht calls them internally,
- so aliasing results in an infinite recursion
- - removed alias for fontinst (no fontinst.exe any more)
- - fixed GUI-mode interpreter for Ruby
- 2011/09/10
- - added -dDisableFAPI=true to psview argument list. Needed by
- gs-9.xx
- 2012/03/12
- - added '-i', '.' to psview argument list (author's request)
- - added environment clean up from Perl specific variables
- (when not using external Perl)
- 2012/08/05
- - added alias for fmtutil
- 2013/05/09
- - added alias mkluatexfontdb -> luaotfload-tool
- 2013/07/03
- - fix for psview and UNC paths in unix-style
- - remove not needed is_abs_path function
- 2013/08/07
- - handle updmap-sys via updmap --sys
- 2013/08/08
- - allow overriding gs/gs_dll/gs_lib with kpse variables
- TEXLIVE_WINDOWS_EXTERNAL_GS, ..._GS_LIB, ..._GS_DLL
- 2013/08/30
- - do not pass -NULL to dviout, to allow users changing and
- saving settings. Patch by Yusuke KUROKI
- 2013/09/22
- - add TEXMFDIST/fonts to the GS_LIB path. Patch by Yusuke KUROKI
- 2014/04/30
- - fix for argument duplication in fmtutil
- 2015/04/12
- - handle fmtutil-sys via fmtutil --sys
- 2015/09/10
- - more slash flipping for the sake of vbscript and unc paths
- 2015/12/11
- - fix spurious arguments for updmap and fmtutil
- 2016/04/22
- - Warning if external perl is requested but missing
- 2017/04/22 (exactly one year later ;-)
- - Cater for fmtutil-user and updmap-user => -user arg
- 2017/04/24
- - GS_LIB setting for tlgs.
- 2017/05/06
- - introduce sys_user_progs, make checks for updmap/fmtutil
- use sys_user_progs instead, add kanji-config-updmap
- 2018/03/12
- - introduce a new function gettexmfdist() for security.
- 2018/04/06
- - introduce a new function is_64bit_windows_os() to
- check Windows OS.
- 2018/06/20
- - support also scripts in trees other than TEXMFDIST:
- https://tug.org/pipermail/tex-live/2018-June/041922.html
- 2018/10/10
- - support cluttex scripts
- 2018/11/08
- - use included tcltk interpreter
-
-]]
-
--- HELPER SUBROUTINES --
-
-local TEXDIR
-local guimode
-
-local function show_error(msg)
- if guimode then
- local err_cmd
- os.setenv('RUNSCRIPT_ERROR_MESSAGE', msg)
- local errmess_path = TEXDIR .. '/texmf-dist/scripts/texlive/tl-errmess.vbs'
- local err_cmd = {"wscript", errmess_path:gsub('/','\\')}
- if lfs.isfile(errmess_path) then
- os.spawn(err_cmd)
- elseif lfs.isfile(TEXDIR..'/tlpkg/tltcl/tclkit.exe') and
- lfs.isfile(TEXDIR..'/tlpkg/tltcl/gui_err.tcl') then
- os.spawn{TEXDIR..'/tlpkg/tltcl/tclkit.exe',
- TEXDIR..'/tlpkg/tltcl/gui_err.tcl'}
- end
- else
- io.stderr:write(msg, '\n')
- end
-end
-
--- quotes string with spaces
-local function _q(str)
- str = string.gsub(str, '"', '') -- disallow embedded double quotes
- return string.find(str, "%s") and '"'..str..'"' or str
-end
-
--- prepends directories to path if they are not already there
-local function prepend_path(path, ...)
- local pathcmp = string.lower(string.gsub(path, '/', '\\'))..';'
- for k = 1, select('#', ...) do
- local dir = string.lower(string.gsub(select(k, ...), '/', '\\'))..';'
- if not string.find(pathcmp, dir, 1, true) then path = dir..path end
- end
- return path
-end
-
--- searches the PATH for a file
-local function search_path(fname, PATH, PATHEXT)
- if string.find(fname, '[/\\]') then
- return nil, "directory part not allowed for PATH search: "..fname
- end
- PATH = PATH or os.getenv('PATH')
- PATHEXT = PATHEXT or '\0' -- '\0' for no extension
- for dir in string.gmatch(PATH, '[^;]+') do
- local dirsep = (string.find(dir, '\\') and '\\' or '/')
- for ext in string.gmatch(PATHEXT, '[^;]+') do
- local f = dir..dirsep..fname..ext
- if lfs.isfile(f) then return f, ext end
- end
- end
- return nil, "file or program not on PATH: "..fname
-end
-
--- tests for tex4ht command (as given in mk4ht.pl)
--- except for commands starting with 'ht' (they have their own scripts)
-local function is_tex4ht_command(progname)
- local prefixes = 'xh uxh xhm mz oo es js jm tei teim db dbm w jh jh1'
- local formats = 'context latex tex texi xelatex xetex'
- for p in string.gmatch(prefixes, '%S+') do
- for q in string.gmatch(formats, '%S+') do
- if (progname == p..q) then
- -- we have a hit, but not all combinations are valid
- return (p ~= 'teim' and p ~= 'dbm') or (q ~= 'xelatex' and q~= 'xetex')
- end
- end
- end
- return false
-end
-
--- checks whether an item is in an array
-local function contains (tab, val)
- for index, value in ipairs(tab) do
- if value == val then
- return true
- end
- end
- return false
-end
-
--- locates texmfscript to execute
-local function find_texmfscript(progname, ext_list)
- ext_list = ext_list or '\0'
- for ext in string.gmatch(ext_list, '[^;]+') do
- local progfullname = kpse.find_file(progname..ext, 'texmfscripts')
- if progfullname then return progfullname, ext end
- end
- return nil, "no appropriate script or program found: "..progname
-end
-
--- converts the #! line to arg table
--- used for scripts w/o extension
--- only the two most common cases are considered:
--- #! /path/to/command [options]
--- #! /usr/bin/env command [options]
--- ([options] after the command are retained as well)
-local function shebang_to_argv(progfullname)
- local fid, errmsg = io.open(progfullname, 'r')
- if not fid then return nil, errmsg end
- local fstln = fid:read('*line')
- fid:close()
- if string.find(fstln, "eval.*exit.*exec.*perl") then
- -- special case of Perl's time-honoured "totally devious construct":
- -- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
- return {"perl"}
- elseif (string.sub(fstln, 1, 2) ~= '#!') then
- return nil, "don't know how to execute script: "..progfullname
- end
- local argv = string.explode( string.sub(fstln, 3) ) -- split on spaces
- argv[1] = string.match(argv[1], '[^/]+$')
- if (argv[1] == 'env') then table.remove(argv, 1) end
- return argv
-end
-
--- checks if command exists on the path and returns its full path
-local function check_command(cmdlist, PATH)
- for cmd in string.gmatch(cmdlist, '%S+') do
- local cmdext = cmd..(string.find(cmd, '%.[^\\/.]*$') and '' or '.exe')
- local fullcmd = search_path(cmdext, PATH)
- if fullcmd then
- return fullcmd, cmd
- end
- end
- return nil, 'program not found (not part of TeX Live): '..cmdlist
-end
-
--- creates directory or directory hierarchy
-local function mkdir_plus(dir)
- if lfs.mkdir(dir) then
- return true
- end
- -- try with system's mkdir in case we need to create intermediate dirs too
- local ret = os.spawn({[0]=search_path("cmd.exe"),
- string.format('cmd.exe /x /c mkdir "%s"', dir)})
- if ret == 0 then
- return true
- else
- return nil, string.format("cannot create directory (error code %d): %s", ret, dir)
- end
-end
-
---
--- return the TEXMFDIST directory in TeX Live
---
-local function gettexmfdist()
- local ffi = require("ffi")
- ffi.cdef[[
- typedef void* HANDLE;
- typedef char* LPCSTR;
- int GetModuleFileNameA(HANDLE h, LPCSTR l, int i);
- HANDLE GetModuleHandleA(const char *a);
- ]]
- local buffer = ffi.new("char[?]", 512)
- local runscripthandle = ffi.C.GetModuleHandleA("runscript.dll")
- if runscripthandle == nil then
- return nil
- end
- local err = ffi.C.GetModuleFileNameA(runscripthandle, buffer, 256)
- if err == 0 then
- return nil
- end
- local str = ffi.string(buffer)
- str = string.gsub(str, "\\","/")
- str = string.reverse(str)
- local a, b
--- remove '/runscript.dll'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
--- remove '/win32'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
--- remove '/bin'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
- str = string.reverse(str)
- str = str .. '/texmf-dist'
- return str
-end
-
---
--- Is the Windows OS 64bit?
---
-local function is_64bit_windows_os()
- local return_val = false
- -- 32 bit binaries always work, thus the default is false
- local architecture = os.getenv('PROCESSOR_ARCHITECTURE')
- if architecture ~= nil then
- if architecture == 'x86' then
- local is_wow64 = os.getenv('PROCESSOR_ARCHITEW6432')
- if is_wow64 == nil then
- return_val = false
- else
- return_val = true
- end
- else
- return_val = true
- end
- end
- return return_val
-end
-
--- MAIN_CHUNK -- encapsulated in a function for more robust execution with pcall
-
-local function MAIN_CHUNK()
-
---[[
-
-OVERVIEW OF MAIN_CHUNK
-
-We start out with a lot of housekeeping, especially with respect to
-perl and ghostscript: if we are going to use the built-in versions,
-then the search path and other environment variables must be set or
-unset to make these findable and working right.
-
-Next we compose an ARGV table for os.spawn, unless the script turns
-out to be a [tex]lua script; see further down this comment block.
-
-The parameter table ARGV can have the following elements (see the
-luatex manual on os.exec and os.spawn):
-
-- ARGV[0]: the full path to the interpreter
-- ARGV[1]: the filename part of the interpreter. The interpreter choice
- depends on the detected script extension and also on gui mode.
-- ARGV[2]: progfulname, the full path to the script
-- ARGV[3]: argline, i.e. the unparsed arguments for the script.
- This is normally the last argument passed to runscript.tlu.
- See the actual code for when this is not the case.
-
-ARGV[0] gets priority over ARGV[1] if it is present.
-
-After everything has been set up, a call os.spawn(ARGV) runs the
-right program with the right arguments.
-
-But in case the script to be run is a texlua script, we run the script
-in the current texlua process using the dofile function. The original arg
-argument table may have been modified before then.
-
-Some variables:
-
-- ARGV, see above
-- arg, the texlua argument table of runscript.tlu
-- progname, the name under which [w]runscript.exe was called
-- progfullname, the full path of the script to be run. This variable
- is introduced only after some special cases have been dealt with.
-- argline, unparsed arguments to the script; may get modified
-
---]]
-
--- set the system-default value for LC_CTYPE
--- http://tug.org/pipermail/tex-live/2018-May/041628.html
-os.setlocale("", "ctype")
-
--- preprocess arguments: arg[-1] => texlua.exe, arg[0] => scriptname
-
--- guimode already declared local
-guimode = false
-local argline = ''
--- check for the sentinel argment coming from the .exe stub
-if arg[#arg-2] and ( string.sub(arg[#arg-2], -1) == '\n' ) then
- -- argv[0] and unparsed argument line are passed
- -- from the .exe stub as the two last arguments
- -- pop them up from the arg table
- argline = table.remove(arg) -- pop unparsed arguments
- arg[0] = table.remove(arg) -- pop C stub's argv[0]
- guimode = (table.remove(arg) == 'GUI_MODE\n') -- pop sentinel argument
-else
- -- we must be called as: texlua runscript.tlu progname ...
- -- this is treated the same as: runscript[.exe] progname ...
- -- we don't have the unparsed arument line in this case, so construct one
- for k = #arg, 1, -1 do argline = _q(arg[k]) .. ' ' .. argline end
-end
-
--- program name
-
--- lower arg[0] : get file name part : remove extension
-local progname, substcount = string.lower(arg[0]):gsub('^.*[\\/]', ''):gsub('%.[^.]*$', '')
--- special behaviour when called under 'runscript' name
-if (progname == 'runscript') then
- -- we are called as: runscript progname ...
- -- or as: runscript --help|-h|--version ...
- -- handle options first (only --help and --version)
- local opt, param = {}, nil
- while true do
- -- remove the first argument from the arg table and from the argline string
- -- (this argument should have no embedded spaces!)
- param = table.remove(arg, 1)
- if not param then break end
- argline = string.gsub(argline, '^%S+%s*', '')
- local optname = string.lower(param):match('^%-%-?(.*)$')
- if not optname then
- break
- elseif (optname == 'h') or (optname == 'help') then
- opt.help = true
- elseif (optname == 'v') then
- opt.v = true
- elseif (optname == 'version') then
- opt.version = true
- else
- error("unknown option: "..param.."\n"..bannerstr)
- end
- end
- if opt.help then
- print(helpstr)
- if opt.v then print(docstr) end
- os.exit(0)
- elseif opt.version or opt.v then
- print(bannerstr)
- os.exit(0)
- end
- -- make sure progname is valid
- arg[0] = assert(param, "not enough arguments!\n"..bannerstr)
- progname = string.lower(arg[0]):gsub('^.*[\\/]', ''):gsub('%.[^.]*$', '')
- assert(progname == string.lower(arg[0]), "bad command name: " .. arg[0])
-end
--- special case of sys programs
-progname, substcount = string.gsub(progname, '%-sys$', '')
-local sysprog = (substcount > 0) -- true if there was a -sys suffix removed
--- special case of user programs
--- we do not guard against programs foobar-user-sys ... we don't ship them
-progname, substcount = string.gsub(progname, '%-user$', '')
-local userprog = (substcount > 0) -- true if there was a -user suffix removed
--- prevent recursive calls to this script
-assert(progname ~= 'runscript', "oops! wrapping the wrapper?")
-
-
--- kpse and environment set-up
-
--- init kpathsea
-local k = -1
-while arg[k-1] do k = k - 1 end -- in case of a call: luatex --luaonly ...
-local lua_binary = arg[k]
-kpse.set_program_name(lua_binary, progname)
-
--- various dir-vars
--- TEXDIR already declared local
-TEXDIR = kpse.var_value('SELFAUTOPARENT')
--- local TEXMFDIST = kpse.var_value('TEXMFDIST')
--- use a new function to obtain TEXMFDIST
-local TEXMFDIST = gettexmfdist()
-if TEXMFDIST == nil then
- TEXMFDIST = kpse.var_value('TEXMFDIST')
-end
-local BINDIR = kpse.var_value('SELFAUTOLOC')
-local PATH = os.getenv('PATH') or ''
-
--- list of programs that have -sys and -user variants
-local sys_user_progs = { 'updmap', 'fmtutil', 'kanji-config-updmap' }
-
--- restricted programs
-local shell_escape_commands = string.lower(kpse.var_value('shell_escape_commands') or '')
-local is_restricted_progname = string.find( ','..shell_escape_commands..',',
- ','..progname..',', 1, true)
-if is_restricted_progname then
- -- limit search path to the restricted (system) trees
- -- (not really necessary for entries in the alias_table,
- -- because they are not searched for with kpathsea)
- os.setenv('TEXMFSCRIPTS', kpse.var_value('TEXMF_RESTRICTED_SCRIPTS'))
-end
--- perl stuff
-local scripts4tlperl = {
- tlperl = true,
- updmap = true,
- fmtutil = true,
- ['updmap-sys'] = true,
- ['fmtutil-sys'] = true,
-}
-local try_extern_perl = (kpse.var_value('TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL') == '1') and
- not (is_restricted_progname or scripts4tlperl[progname])
-local PERLEXE = try_extern_perl and search_path('perl.exe', PATH)
-local extperl_warn
-if not PERLEXE then
- if try_extern_perl then extperl_warn = [[
-External Perl missing or outdated. Please install a recent Perl, or configure
-TeX Live to always use the builtin Perl:
- tlmgr conf texmf TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL 0
-Meanwhile, continuing with built-in Perl...
-]]
- end -- if try_extern_perl
- PERLEXE = TEXDIR..'/tlpkg/tlperl/bin/perl.exe'
- os.setenv('PERL5LIB', TEXDIR..'/tlpkg/tlperl/lib')
- PATH = prepend_path(PATH, TEXDIR..'/tlpkg/tlperl/bin')
- local PERLENV = 'PERL5OPT;PERLIO;PERLIO_DEBUG;PERLLIB;PERL5DB;PERL5DB_THREADED;' ..
- 'PERL5SHELL;PERL_ALLOW_NON_IFS_LSP;PERL_DEBUG_MSTATS;' ..
- 'PERL_DESTRUCT_LEVEL;PERL_DL_NONLAZY;PERL_ENCODING;PERL_HASH_SEED;' ..
- 'PERL_HASH_SEED_DEBUG;PERL_ROOT;PERL_SIGNALS;PERL_UNICODE'
- for var in string.gmatch(PERLENV, '[^;]+') do os.setenv(var, nil) end
-end
--- gs stuff
-local override_gs
-if not is_restricted_progname then
- override_gs = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS')
-end
--- the full path to the executable
-local GSEXE
--- the directory where the gs executable resides
-local GSDIR
--- the name of the gs executable
-local GSNAME
-if override_gs then
- -- first check whether we got an absolute path or only executable name
- if string.find(override_gs, '[/\\]') then
- GSEXE = override_gs
- else
- -- search in the path
- GSEXE = search_path(override_gs, PATH)
- end
-end
-if GSEXE then
- -- split the dir and progname part so that we can set the path
- -- work on a string with all forward slashes
- local foo = string.lower(string.gsub(GSEXE, '\\', '/'))
- GSNAME = string.gsub(foo, '^.*[\\/]', '')
- GSDIR = string.gsub(foo, '^(.*)[\\/].*$', '%1')
- -- search also for a GS_DLL setting
- -- we do not need to check for is_restricted_progname, since
- -- GSEXE is only defined when it is not set
- local GSDLL = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS_DLL')
- if GSDLL then
- os.setenv('GS_DLL', GSDLL)
- end
- local GSLIB = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS_LIB')
- if GSLIB then
- os.setenv('GS_LIB', GSLIB)
- end
-else
- -- use built in gs
- os.setenv('GS_LIB', TEXDIR..'/tlpkg/tlgs/lib;'
- ..TEXDIR..'/tlpkg/tlgs/fonts;'
- ..TEXDIR..'/tlpkg/tlgs/Resource/Init;'
- ..TEXDIR..'/tlpkg/tlgs/Resource;'
- ..TEXDIR..'/tlpkg/tlgs/kanji;'
- ..os.getenv('WINDIR')..'/Fonts;'..TEXMFDIST..'/fonts')
- os.setenv('GS_DLL', TEXDIR..'/tlpkg/tlgs/bin/gsdll32.dll')
- GSEXE = TEXDIR..'/tlpkg/tlgs/bin/gswin32c.exe'
- GSNAME = 'gswin32c.exe'
- GSDIR = TEXDIR..'/tlpkg/tlgs/bin'
-end
--- now setup the path so that the gs program will be found
-PATH = prepend_path(PATH, GSDIR, BINDIR)
-os.setenv('PATH', PATH);
-
--- sys stuff
-if (sysprog and not contains(sys_user_progs, progname)) then
- os.setenv('TEXMFVAR', kpse.var_value('TEXMFSYSVAR'))
- os.setenv('TEXMFCONFIG', kpse.var_value('TEXMFSYSCONFIG'))
-end
--- Adobe Reader crash case: make sure USERPROFILE is not "slashed"
-os.setenv("USERPROFILE", os.getenv("USERPROFILE"):gsub('/', '\\'))
-
--- extension to interpreter mapping
-
--- the extension is mapped to an argument table.
--- the command to execute is given as the first element of the table,
--- which can be a whitespace separated list of names to try.
-local extension_map = {
- ['.bat'] = {'cmd', '/c', 'call'},
- ['.jar'] = {'java.exe', '-jar'},
- ['.pl' ] = {'perl.exe'},
- ['.py' ] = {'python.exe'},
- ['.rb' ] = {'ruby.exe'},
- ['.tcl'] = {'tclsh.exe tclsh86.exe tclsh85.exe tclkitsh.exe'},
- ['.vbs'] = {'cscript.exe', '-nologo'},
-}
-if guimode then
- -- for GUI mode wrappers we try GUI mode interpeters where possible
- extension_map['.jar'][1] = 'javaw.exe ' .. extension_map['.jar'][1]
- extension_map['.pl' ][1] = 'wperl.exe ' .. extension_map['.pl' ][1]
- extension_map['.py' ][1] = 'pythonw.exe ' .. extension_map['.py' ][1]
- extension_map['.rb' ][1] = 'rubyw.exe ' .. extension_map['.rb' ][1]
- -- gui tcl shares no interpreters with non-gui tcl
- extension_map['.tcl'] = {'wish.exe wish86.exe wish85.exe tclkit.exe'}
- extension_map['.vbs'][1] = 'wscript.exe ' .. extension_map['.vbs'][1]
-end
-extension_map['.cmd'] = extension_map['.bat']
-extension_map['.js'] = extension_map['.vbs']
-
--- set up ARGV table
-
-local ARGV = nil
-
--- special cases (aliases)
-
-if is_tex4ht_command(progname) then
- argline = progname .. ' ' .. argline
- progname = 'mk4ht'
-elseif progname == 'a2ping' then
- table.insert(extension_map['.pl'], '-x')
-elseif contains(sys_user_progs, progname) then
- if sysprog then
- argline = ' --sys ' .. argline
- elseif userprog then
- argline = ' --user ' .. argline
- end
- -- do not guess input encoding in format creation for ptex
- -- and friends since guessing is not complete
- os.setenv('GUESS_INPUT_KANJI_ENCODING', '0')
-elseif progname == 'asy' then
- os.setenv('ASYMPTOTE_GS', GSEXE)
- os.setenv('CYGWIN', 'nodosfilewarning')
- if is_64bit_windows_os() then
- ARGV = {[0]=TEXDIR..'/tlpkg/asymptote64/asy.exe', 'asy'}
- else
- ARGV = {[0]=TEXDIR..'/tlpkg/asymptote/asy.exe', 'asy'}
- end
-elseif progname == 'dviout' then
- local fontsdir = kpse.var_value('TEXMFVAR') .. '/fonts'
- if (lfs.attributes(fontsdir, 'mode') ~= 'directory') then
- assert(mkdir_plus(fontsdir))
- end
- local tfmpath = kpse.show_path('tfm')
- tfmpath = string.gsub(tfmpath, '!!', '')
- tfmpath = string.gsub(tfmpath, '/', '\\')
- local texrt = {}
- for d in string.gmatch(tfmpath, '([^;]+\\fonts)\\tfm[^;]*') do
- if (lfs.attributes(d, 'mode') == 'directory') then
- table.insert(texrt, d)
- end
- end
- local par = [["-gen=']] .. string.gsub(TEXDIR, '/', '\\') ..
- [[\tlpkg\dviout\gen_pk'" "-TEXROOT=']] ..
- table.concat(texrt, ';') .. [['" "-gsx=']] .. GSEXE .. ' -dDELAYSAFER' .. [['"]];
- ARGV = {[0]=TEXDIR..'/tlpkg/dviout/dviout.exe', 'dviout', par}
-elseif progname == 'mkluatexfontdb' then
- progname = 'luaotfload-tool'
- table.insert(arg, '--alias=mkluatexfontdb')
-elseif progname == 'psv' then
- argline = '-sINPUT='..argline
- ARGV = {[0]=TEXDIR..'/tlpkg/tlpsv/gswxlua.exe', 'gswxlua',
- '-dDisableFAPI=true',
- '-l', (_q(TEXDIR..'/tlpkg/tlpsv/psv.wx.lua'):gsub('/','\\')),
- '-p', (_q(TEXDIR..'/tlpkg/tlpsv/psv_view.ps'):gsub('/','\\')),
- '-i', '.'}
-elseif progname == 'repstopdf' or progname == 'rpdfcrop' then
- argline = '--restricted ' .. argline
- progname = string.sub(progname, 2, -1)
-elseif progname == 'texworks' then
- local winver = tonumber(string.match(os.uname().version, '%D*(%d+%.?%d*)'))
- assert(winver >= 5.01, "Windows XP or newer required to run TeXworks")
- local TW_LIBPATH = kpse.var_value('TW_LIBPATH') or
- kpse.var_value('TEXMFCONFIG')..'/texworks'
- local TW_INIPATH = kpse.var_value('TW_INIPATH') or TW_LIBPATH
- os.setenv('TW_LIBPATH', TW_LIBPATH)
- os.setenv('TW_INIPATH', TW_INIPATH)
- if (TW_INIPATH and lfs.attributes(TW_INIPATH, 'mode') ~= 'directory') then
- -- TeXworks needs directory holding its configuration to exist
- assert(mkdir_plus(TW_INIPATH))
- end
- ARGV = {[0]=TEXDIR..'/tlpkg/texworks/texworks.exe', 'texworks'}
-elseif progname == 'tlgs' then
- ARGV = {[0]=GSEXE, GSNAME}
-elseif progname == 'tlperl' then
- ARGV = {[0]=PERLEXE, 'perl'}
-elseif progname == 'latexdef' then
- progname = 'texdef'
- argline = ' --tex latex ' .. argline
-elseif progname == 'cllualatex' then
- progname = 'cluttex'
- argline = ' --engine=lualatex ' .. argline
-elseif progname == 'clxelatex' then
- progname = 'cluttex'
- argline = ' --engine=xelatex ' .. argline
-end
-
--- general case
-
-if not ARGV then
- os.setenv('TEXMF', TEXMFDIST)
- local extlist = '.tlu;.texlua;.pl;.lua;.rb;.py;.tcl;.jar;.vbs;.js;.bat;.cmd;\0'
- local progfullname = search_path(progname, BINDIR, '.tlu;.bat;.cmd') or
- find_texmfscript(progname, extlist)
- os.setenv('TEXMF', nil)
- if progfullname == nil then
- -- scripts in $TEXMFLOCAL etc. can't be found without the following
- -- line !!
- kpse.set_program_name('runscript')
- progfullname = assert(find_texmfscript(progname, extlist))
- end
- local ext = string.match(string.lower(progfullname), '%.[^\\/.]*$') or ''
- if (ext == '.lua') or (ext == '.tlu') or (ext == '.texlua') then -- lua script
- arg[0] = progfullname
- elseif (ext == '.tcl' and guimode) then -- tcl script; use built-in tcl/tk?
- local try_extern_tcl =
- (kpse.var_value('TEXLIVE_WINDOWS_TRY_EXTERNAL_TCL') == '1') and
- not is_restricted_progname
- local TCLEXENAME, TCLEXE
- if try_extern_tcl then
- TCLEXE, TCLEXENAME = check_command(extension_map['.tcl'][1], PATH)
- end
- if try_extern_tcl and not TCLEXE then
- local exttcl_warn = [[
-External Tcl missing or outdated. Please install a recent Tcl, or configure
-TeX Live to always use the builtin Tcl for gui scripts:
- tlmgr conf texmf TEXLIVE_WINDOWS_TRY_EXTERNAL_TCL 0
-Meanwhile, continuing with built-in Tcl...
-]]
- show_error(exttcl_warn)
- else -- did find something
- ARGV = {[0]=TCLEXE, TCLEXENAME}
- end
- if not TCLEXE then
- -- kit: tlpkg/tltcl/tclkit.exe
- -- regular wish: tlpkg/tltcl/bin/wish.exe
- -- we ignore the fact that a non-kit tcl/tk provides wish AND tclsh
- if lfs.isfile(TEXDIR..'/tlpkg/tltcl/tclkit.exe') then
- ARGV = {[0]=TEXDIR..'/tlpkg/tltcl/tclkit.exe', 'tclkit.exe'}
- PATH = prepend_path(PATH, TEXDIR:gsub('/','\\')..'\\tlpkg\\tltcl')
- elseif lfs.isfile(TEXDIR..'/tlpkg/tltcl/bin/wish.exe') then
- ARGV = {[0]=TEXDIR..'/tlpkg/tltcl/bin/wish.exe', 'wish.exe'}
- PATH = prepend_path(PATH, TEXDIR:gsub('/','\\')..'\\tlpkg\\tltcl\\bin')
- end
- end
- table.insert(ARGV, _q(progfullname:gsub('/','\\')))
- if (argline and argline ~= '') then argline = '-- '..argline end
- else -- not gui tcl or not tcl at all
- ARGV = extension_map[ext] or assert(shebang_to_argv(progfullname))
- -- [w|c]script, for one, mistakes a forward-slashed UNC script path
- -- for an option even when quoted
- table.insert(ARGV, _q(progfullname:gsub('/','\\')))
- if not ARGV[0] then
- ARGV[0], ARGV[1] = assert(check_command(ARGV[1], PATH))
- end
- end
-end
-
--- run the program/script
-
-if ARGV then
- table.insert(ARGV, argline) -- pass through original arguments
- if string.find (table.concat(ARGV, ' '), 'perl.exe') and extperl_warn then
-
- show_error(extperl_warn)
- end
- local ret = assert(os.spawn(ARGV))
- if ret ~= 0 then
- local dbginfo = debug.getinfo(1)
- local errormsg = string.format("%s:%d: command failed with exit code %d:\n%s",
- dbginfo.short_src, dbginfo.currentline - 2,
- ret, table.concat(ARGV, ' ') )
- show_error(errormsg)
- end
- os.exit(ret)
-else -- must be a lua script
- dofile(arg[0])
-end
-
-end -- MAIN_CHUNK
-
--- execute MAIN_CHUNK with pcall to catch any runtime errors
-
-local success, errormsg = pcall(MAIN_CHUNK)
-if not success then
- os.setenv('RUNSCRIPT_ERROR_MESSAGE', errormsg)
- error(errormsg)
-end
-
--- about RUNSCRIPT_ERROR_MESSAGE environment variable:
--- it stores an error message that is caught and displayed
--- in a message box on the C side at process exit
--- (currently used only by gui mode stubs)
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript_dll.c b/Build/source/texk/texlive/w32_wrapper/runscript_dll.c
deleted file mode 100644
index 617a00f7319..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/runscript_dll.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/************************************************************************
-
- This file is a part of the wrapper program for launching scripts
- and programs in TeX Live on Windows. See readme.txt for more details.
-
- This file was originally written in 2009 by Tomasz M. Trzeciak and
- was placed in the Public Domain.
-
-************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t'))
-#define MAX_MSG 2*MAX_PATH
-#define DIE(...) { _snprintf( msg_buf, MAX_MSG - 1, __VA_ARGS__ ); goto DIE; }
-
-char module_name[] = "runscript.dll";
-char script_name[] = "runscript.tlu";
-char texlua_name[] = "texlua"; // just a bare name, luatex strips the rest anyway
-char subsys_mode[] = "CUI_MODE\n";
-char err_env_var[] = "RUNSCRIPT_ERROR_MESSAGE";
-char msg_buf[MAX_MSG];
-
-__declspec(dllimport) int dllluatexmain( int argc, char *argv[] );
-
-__declspec(dllexport) int dllrunscript( int argc, char *argv[] )
-{
- static char own_path[MAX_PATH];
- static char fpath[MAX_PATH];
- char *fname, *argline, **lua_argv;
- int k, quoted, lua_argc;
- HMODULE module_handle = NULL;
-
- // file path of the executable
- k = (int) GetModuleFileName(NULL, own_path, MAX_PATH);
- if ( !k || (k == MAX_PATH) )
- DIE("cannot get own path (may be too long): %s\n", own_path);
-
- // script path (the dir of this library)
- module_handle = GetModuleHandle(module_name);
- // if ( module_handle == NULL ) exe path will be used, which is OK too
- k = (int) GetModuleFileName(module_handle, fpath, MAX_PATH);
- if ( !k || (k == MAX_PATH) )
- DIE("cannot get module path (may be too long): %s\n", fpath);
- fname = strrchr(fpath, '\\');
- if ( fname == NULL ) DIE("no directory part in module path: %s\n", fpath);
- fname++;
- if ( fname + strlen(script_name) >= fpath + MAX_PATH - 1 )
- DIE("path too long: %s\n", fpath);
- strcpy(fname, script_name);
- if ( GetFileAttributes(fpath) == INVALID_FILE_ATTRIBUTES )
- DIE("main lua script not found: %s\n", fpath);
-
- // get command line of this process
- argline = GetCommandLine();
- if ( argline == NULL ) DIE("failed to retrieve command line string\n");
- // skip over argv[0] (it can contain embedded double quotes if launched from cmd.exe!)
- for ( quoted = 0; (*argline) && ( !IS_WHITESPACE(*argline) || quoted ); argline++ )
- if ( *argline == '"' ) quoted = !quoted;
- while ( IS_WHITESPACE(*argline) ) argline++; // remove leading whitespace if any
-
- // set up argument list for texlua script
- lua_argv = (char **)malloc( (argc + 6) * sizeof(char *) );
- lua_argv[lua_argc=0] = texlua_name;
- lua_argv[++lua_argc] = fpath; // script to execute
- for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k]; // copy argument list
- lua_argv[++lua_argc] = subsys_mode; // sentinel argument
- lua_argv[++lua_argc] = argc ? argv[0] : own_path; // original argv[0]
- lua_argv[++lua_argc] = argline; // unparsed arguments
- lua_argv[++lua_argc] = NULL;
-
- // call texlua interpreter
- // dllluatexmain never returns, but we pretend that it does
- k = dllluatexmain( lua_argc, lua_argv );
- if (lua_argv) free(lua_argv);
- return k;
-
-DIE:
- fprintf(stderr, "%s: ", module_name);
- fprintf(stderr, msg_buf);
- if (*subsys_mode == 'G')
- MessageBox( NULL, msg_buf, module_name, MB_ICONERROR | MB_SETFOREGROUND );
- return 1;
-}
-
-void finalize( void )
-{
- // check for and display error message if any
- char *err_msg;
- if ( err_msg = (char *) getenv(err_env_var) )
- MessageBox( NULL, err_msg, script_name, MB_ICONERROR | MB_SETFOREGROUND );
-}
-
-__declspec(dllexport) int dllwrunscript(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- char *argline,
- int winshow
-) {
- // set sentinel argument (G for GUI_MODE)
- *subsys_mode = 'G';
- // clear error var in case it exists already
- SetEnvironmentVariable(err_env_var, NULL);
- // register atexit handler to recover control before terminating
- atexit( finalize );
- // call the console entry point routine
-#ifdef __MSVCRT__
- // WinMain doesn't provide argc & argv, call MSVCRT proc to get them
- int argc = 0;
- char **argv, **env;
- int expand_wildcards = 0;
- int new_mode;
- __getmainargs(&argc, &argv, &env, expand_wildcards, &new_mode);
- return dllrunscript( argc, argv );
-#else
- return dllrunscript( 0, NULL );
-#endif
-}
-
-
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript_exe.c b/Build/source/texk/texlive/w32_wrapper/runscript_exe.c
deleted file mode 100644
index 29d04a93a43..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/runscript_exe.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/************************************************************************
-
- This file is a part of the wrapper program for launching scripts
- and programs in TeX Live on Windows. See readme.txt for more details.
-
- This file was originally written in 2009 by Tomasz M. Trzeciak and
- was placed in the Public Domain.
-
-************************************************************************/
-
-#include <windows.h>
-
-__declspec(dllimport) int dllrunscript( int argc, char *argv[] );
-
-int main( int argc, char *argv[] ) { return dllrunscript( argc, argv ); }
diff --git a/Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c b/Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c
deleted file mode 100644
index e223d39bbf3..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
-
-Simple tray menu
-
-Originally written in 2011 by Tomasz M. Trzeciak, Public Domain
-
-2019 updates, by Siep Kroonenberg:
-- added option to open data files with default application
-- updated menu content
-
-compiling with gcc (size optimized):
-echo 1 ICON "tl-tray-menu.ico">tl-tray-menu.rc
-windres tl-tray-menu.rc tl-tray-menu-rc.o
-gcc -Os -s -mwindows -o tl-tray-menu.exe tl-tray-menu-rc.o tl-tray-menu.c
-
-*/
-
-#define _WIN32_IE 0X0500 // minimum support for tray baloon (IE5)
-
-#include <windows.h>
-#include <shellapi.h>
-#include <process.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define MAX_STR 32768
-
-static char strBuf[MAX_STR];
-
-#define DIE(...) { \
- _snprintf( strBuf, 4*MAX_PATH, __VA_ARGS__ ); \
- MessageBox( NULL, strBuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\
- return 1; \
-}
-
-#define IDI_ICON 1 // resource number of icon
-#define IDI_TRAY 100
-#define WM_TRAYMSG 101
-
-#define MAX_MENU_ENTRIES 31
-#define MENU_CONFIG ( MAX_MENU_ENTRIES + 1 )
-#define MENU_EXIT ( MAX_MENU_ENTRIES + 2 )
-
-// buffer holding menu labels and commands
-// (used only with config file)
-static char menuStrings[MAX_STR];
-
-// default menu labels
-char *menuLabels[MAX_MENU_ENTRIES] = {
-"&Package Manager",
-"&Documentation",
-"&Editor",
-"&Command Prompt",
-NULL };
-
-// default menu commands
-char *menuCommands[MAX_MENU_ENTRIES] = {
-"bin\\win32\\tlshell.exe",
-"doc.html",
-"bin\\win32\\texworks.exe",
-"tlpkg\\installer\\tl-cmd.bat",
-NULL };
-
-char configInfo[4*MAX_PATH] = "\
-The menu can be customized with a configuration file.\n\
-For an example and instructions see:\n";
-
-HMENU hPopMenu;
-NOTIFYICONDATA nid;
-
-// has s executable extension according to PATHEXT?
-int is_exe ( char * s ) {
- int i, j, extl;
- char * pathext, * ext, * t, * t1;
- if ( !s || !(*s)) DIE( "is_exe invoked with NULL or empty string" );
- pathext = getenv( "PATHEXT" );
- if (!pathext) return 1;
- ext = strrchr( s, '.' );
- if (!ext) return 1;
- extl = strlen( ext );
- t = s;
- while ( 1 ) {
- t1 = strchr( t, ';' );
- if ( !t1 ) t1 = s + strlen( s );
- if ( t1 - t == extl && !_strnicmp( ext, t, extl )) {
- return 1;
- } else if ( *t1 ) {
- t = ++t1;
- } else {
- return 0;
- }
- }
- return 0;
-}
-
-LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
-{
- switch ( msg )
- {
- case WM_CREATE:
- {
- hPopMenu = CreatePopupMenu();
- int i;
- for ( i = 0; menuLabels[i]; i++ )
- {
- if ( menuCommands[i] )
- AppendMenu( hPopMenu, MF_STRING, i, menuLabels[i] );
- }
- AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
- AppendMenu( hPopMenu, MF_STRING, MENU_CONFIG, "More..." );
- AppendMenu( hPopMenu, MF_STRING, MENU_EXIT, "E&xit" );
- }
- break;
-
- case WM_TRAYMSG:
- {
- switch ( lParam )
- {
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- {
- POINT pnt;
- GetCursorPos( &pnt );
- SetForegroundWindow( hWnd ); // needed to get keyboard focus
- TrackPopupMenu( hPopMenu, TPM_LEFTALIGN, pnt.x, pnt.y, 0, hWnd, NULL );
- }
- break;
- }
- }
- break;
-
- case WM_COMMAND:
- {
- switch ( LOWORD( wParam ) )
- {
- case MENU_CONFIG:
- MessageBox( NULL, configInfo, nid.szTip, MB_SETFOREGROUND );
- break;
-
- case MENU_EXIT:
- Shell_NotifyIcon( NIM_DELETE, &nid );
- ExitProcess(0);
- break;
-
- default:
- {
- if (is_exe( menuCommands[LOWORD(wParam )])) {
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- //si.dwFlags = STARTF_USESHOWWINDOW;
- //si.wShowWindow = SW_HIDE ;
- ZeroMemory( &pi, sizeof(pi) );
- if( !CreateProcess(
- NULL, // module name (uses command line if NULL)
- menuCommands[LOWORD(wParam)], // command line
- NULL, // process security atrributes
- NULL, // thread security atrributes
- TRUE, // handle inheritance
- 0, // creation flags, e.g. CREATE_NO_WINDOW,
- // DETACHED_PROCESS
- NULL, // pointer to environment block (uses parent if NULL)
- NULL, // starting directory (uses parent if NULL)
- &si, // STARTUPINFO structure
- &pi ) // PROCESS_INFORMATION structure
- ) DIE( "Failed to spawn command (error code %d):\n%s",
- GetLastError(), menuCommands[LOWORD(wParam)] );
- } else {
- // data file; try to open with default application
- ShellExecute( NULL, NULL, menuCommands[LOWORD(wParam)],
- NULL, NULL, SW_SHOWNORMAL );
- }
- }
- }
- }
- break;
-
- default:
- return DefWindowProc( hWnd, msg, wParam, lParam );
-
- }
-
- return 0;
-}
-
-int APIENTRY WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow )
-{
-
- // scratch variables
-
- char *s;
-
- // get file name of this executable
-
- static char dirSelf[MAX_PATH];
- DWORD nchars = GetModuleFileName(NULL, dirSelf, MAX_PATH);
- if ( !nchars || ( nchars == MAX_PATH ) ) DIE( "Cannot get own path." );
- if ( s = strrchr( dirSelf, '\\' ) ) *s = '\0'; // remove file name part
-
- // set current directory
-
- if ( !SetCurrentDirectory( dirSelf ) )
- DIE( "Failed to change current directory to:\n%s", dirSelf );
-
- // prepend bin/win32 to PATH
-
- strcpy( strBuf, dirSelf );
- if ( strlen( dirSelf ) + strlen( "\\bin\\win32;" )
- + strlen( getenv( "PATH" )) >= MAX_STR )
- DIE( "Path getting too long" );
- strcat( strBuf, "\\bin\\win32;" );
- strcat( strBuf, getenv( "PATH" ) );
- SetEnvironmentVariable( "PATH", strBuf );
-
- // configuration
-
- static char fileConfig[MAX_PATH];
- s = dirSelf + strlen(dirSelf) + 1;
- strcpy( fileConfig, s );
- if ( s = strrchr( fileConfig, '.' ) ) *s = '\0'; // remove file extension part
- strcat( fileConfig, ".ini" );
-
- strcat( configInfo, dirSelf );
- strcat( configInfo, "\\tlpkg\\installer\\" );
- strcat( configInfo, fileConfig );
-
- if ( GetFileAttributes( fileConfig ) == INVALID_FILE_ATTRIBUTES ) {
-
- // validate default configuration (menuCommands should be existing files)
-
- int i;
- for ( i = 0; menuLabels[i]; i++ )
- if ( GetFileAttributes( menuCommands[i] ) == INVALID_FILE_ATTRIBUTES )
- menuCommands[i] = NULL;
-
- } else {
-
- // read menu configuration from ini file
-
- FILE *CONFIG = fopen( fileConfig, "rt" );
- if ( CONFIG == NULL )
- DIE( "Failed to open configuration file:\n%s\\%s", dirSelf, fileConfig );
-
- char strSect[] = "[menu]";
- int menuItem = -1;
- int i = 0;
- int lineNo;
- for ( lineNo = 1 ; fgets( strBuf, MAX_STR, CONFIG )
- && menuItem < MAX_MENU_ENTRIES ; lineNo++ )
- {
- if ( menuItem < 0 )
- {
- if ( *strBuf == '[' &&
- strncmp( strBuf, strSect, strlen( strSect ) ) == 0 ) menuItem++;
- continue;
- }
- if ( *strBuf == ';' ) continue; // skip comments
- if ( *strBuf == '[' ) break; // next section
- s = &menuStrings[i];
- i += ExpandEnvironmentStrings( strBuf, s, MAX_STR - i );
- if ( i >= MAX_STR )
- DIE( "Exceeded 32KB limit for configuration." );
- if ( i-2 && menuStrings[i-2] == '\n' ) { menuStrings[i-2] = '\0'; i--; }
- menuLabels[menuItem] = s;
- while ( *s && *s != '=' ) s++;
- if ( *s == '\0' )
- DIE( "Missing '=' on line %d in configuration file:\n%s\\%s",
- lineNo, dirSelf, fileConfig );
- *s++ = '\0'; // assign first, then increment
- menuCommands[menuItem] = s;
- menuItem++;
- }
- if ( menuItem < 0 )
- DIE( "Missing [menu] section in configuration file:\n%s\\%s",
- dirSelf, fileConfig );
- menuLabels[menuItem] = NULL;
- menuCommands[menuItem] = NULL;
-
- fclose( CONFIG );
-
- }
-
- // create a hidden window for messaging
-
- MSG msg;
- WNDCLASS wc;
- HWND hWnd;
- char szAppName[] = "TrayMenu";
-
- ZeroMemory( &wc, sizeof wc );
- wc.hInstance = hInstance;
- wc.lpszClassName = szAppName;
- wc.lpfnWndProc = (WNDPROC)WndProc;
- wc.style = 0;
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
-
- if ( FALSE == RegisterClass( &wc ) ) DIE( "Failed to register window class" );
-
- hWnd = CreateWindow(
- szAppName,
- "",
- 0,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- 0,
- 0,
- hInstance,
- 0);
-
- if ( hWnd == NULL ) DIE( "Failed to create window" );
-
- // tray icon stuff
-
- nid.cbSize = sizeof nid;
- nid.hWnd = hWnd;
- nid.uID = IDI_TRAY;
- nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
- nid.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON ) );
- nid.uCallbackMessage = WM_TRAYMSG;
- strcpy( nid.szTip, "TeX Live Menu" );
-#if (_WIN32_IE >= 0X0500)
- nid.uFlags |= NIF_INFO;
- nid.dwInfoFlags = NIIF_INFO;
- strcpy( nid.szInfo, "Click on the tray icon\nto activate the menu." );
- strcpy( nid.szInfoTitle, nid.szTip );
-#endif
- Shell_NotifyIcon( NIM_ADD, &nid );
-
- // main message loop:
-
- while ( GetMessage( &msg, NULL, 0, 0 ) > 0 )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
-
- return msg.wParam;
-}
-
diff --git a/Build/source/texk/texlive/w32_wrapper/tlmgr-gui.txt b/Build/source/texk/texlive/w32_wrapper/tlmgr-gui.txt
deleted file mode 100644
index 559d97ed3f2..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/tlmgr-gui.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-
-Launcher stub for tlmgr gui (with hidden console window)
-
-//////////////////////////////////////////////////
-
-This version has been replaced with a version which triggers a UAC
-prompt when appropriate. See Master/source/tlmgr-gui_UAC.zip.
-
-//////////////////////////////////////////////////
-
-Originally written in 2011 by Tomasz M. Trzeciak, Public Domain
-
-compiling with gcc (size optimized):
-echo 1 ICON "tlmgr-gui.ico">tlmgr-gui.rc
-windres tlmgr-gui.rc tlmgr-gui-rc.o
-gcc -Os -s -mwindows -o tlmgr-gui.exe tlmgr-gui-rc.o tlmgr-gui.c
-
-compiling with tcc (ver. 0.9.25), extra small size
-windres tlmgr-gui.rc tlmgr-gui-rc.o
-tcc -o tlmgr-gui.exe tlmgr-gui-rc.o tlmgr-gui.c
-
-*/
-
-#include <windows.h>
-
-static char msgbuf[4*MAX_PATH];
-#define DIE(...) { \
- _snprintf( msgbuf, 4*MAX_PATH, __VA_ARGS__ ); \
- MessageBox( NULL, msgbuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\
- return 1; \
-}
-
-static char cmdln[2*MAX_PATH];
-
-int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShowint ) {
-
- // get file name of this executable
-
- static char selfdir[MAX_PATH];
- char *name, *ext, *s;
- DWORD nchars = GetModuleFileName(NULL, selfdir, MAX_PATH);
- if ( !nchars || (nchars == MAX_PATH) ) DIE( "cannot get own path" );
-
- // make command to execute
-
- if ( s = strrchr(selfdir, '\\') ) *s = '\0'; // remove file name part
- strcat( cmdln, "\"" );
- strcat( cmdln, selfdir );
- strcat( cmdln, "\\tlmgr.bat\" -gui" );
-
- // create child process
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE ;
- ZeroMemory( &pi, sizeof(pi) );
-
- if( !CreateProcess(
- NULL, // module name (uses command line if NULL)
- cmdln, // command line
- NULL, // process security atrributes
- NULL, // thread security atrributes
- TRUE, // handle inheritance
- 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS
- NULL, // pointer to environment block (uses parent if NULL)
- NULL, // starting directory (uses parent if NULL)
- &si, // STARTUPINFO structure
- &pi ) // PROCESS_INFORMATION structure
- ) DIE( "command execution failed: %s", cmdln );
-
- return 0;
-
-}
diff --git a/Build/source/texk/texlive/w32_wrapper/tlmgr.ico b/Build/source/texk/texlive/w32_wrapper/tlmgr.ico
deleted file mode 100644
index 6f0c37f54e0..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/tlmgr.ico
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w32_wrapper/tlmgr.svg b/Build/source/texk/texlive/w32_wrapper/tlmgr.svg
deleted file mode 100644
index 6e60a8f273c..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/tlmgr.svg
+++ /dev/null
@@ -1,245 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 10.0.3, SVG Export Plug-In . SVG Version: 3.0.0 Build 77) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="270"
- height="270"
- viewBox="0 0 270.00001 270"
- style="display:inline;overflow:visible"
- xml:space="preserve"
- id="svg2816"
- version="1.1"
- inkscape:version="0.48.1 r9760"
- sodipodi:docname="tlmgr.svg"><metadata
- id="metadata2851"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
- id="defs2849"><linearGradient
- id="linearGradient5749"><stop
- id="stop5751"
- offset="0"
- style="stop-color:#c8bb2c;stop-opacity:1" /><stop
- id="stop5753"
- offset="0.42938474"
- style="stop-color:#c8ab37;stop-opacity:1" /><stop
- id="stop5755"
- offset="1"
- style="stop-color:#786721;stop-opacity:1" /></linearGradient><linearGradient
- id="linearGradient5739"><stop
- style="stop-color:#33b850;stop-opacity:1;"
- offset="0"
- id="stop5741" /><stop
- id="stop5747"
- offset="0.5"
- style="stop-color:#c8ab37;stop-opacity:0.49803922;" /><stop
- style="stop-color:#c8ab37;stop-opacity:0"
- offset="1"
- id="stop5743" /></linearGradient><linearGradient
- id="linearGradient4223"><stop
- id="stop3656"
- offset="0"
- style="stop-color:#6a5c22;stop-opacity:1;" /><stop
- id="stop3654"
- offset="0.70769727"
- style="stop-color:#c8ab37;stop-opacity:1" /><stop
- style="stop-color:#dac15a;stop-opacity:1;"
- offset="1"
- id="stop4227" /></linearGradient><linearGradient
- inkscape:collect="always"
- id="linearGradient4215"><stop
- style="stop-color:#786721;stop-opacity:1;"
- offset="0"
- id="stop4217" /><stop
- style="stop-color:#786721;stop-opacity:0;"
- offset="1"
- id="stop4219" /></linearGradient><linearGradient
- id="linearGradient3682"><stop
- style="stop-color:#f1e671;stop-opacity:1;"
- offset="0"
- id="stop4231" /><stop
- style="stop-color:#c8ab37;stop-opacity:1"
- offset="0.66298664"
- id="stop4213" /><stop
- style="stop-color:#786721;stop-opacity:1"
- offset="1"
- id="stop3686" /></linearGradient><inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 114.031 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="248.47099 : 114.031 : 1"
- inkscape:persp3d-origin="124.2355 : 76.020665 : 1"
- id="perspective2853" /><inkscape:perspective
- id="perspective2856"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" /><inkscape:perspective
- id="perspective2997"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" /><radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3682"
- id="radialGradient3688"
- cx="59.357792"
- cy="136.64711"
- fx="59.357792"
- fy="136.64711"
- r="113.49914"
- gradientTransform="matrix(1.3152342,0.04522208,-0.04703422,1.3679372,-5.8498181,-59.579928)"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4215"
- id="linearGradient4221"
- x1="180.77203"
- y1="71.763046"
- x2="199.85242"
- y2="97.362198"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0809402,0,0,1.0204074,-3.223564,-12.087424)" /><radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4223"
- id="radialGradient3652"
- cx="44.960342"
- cy="223.34352"
- fx="44.960342"
- fy="223.34352"
- r="55.639721"
- gradientTransform="matrix(1.4022312,0.35120986,-0.153588,0.61321069,30.002569,-17.284415)"
- gradientUnits="userSpaceOnUse" /><inkscape:perspective
- id="perspective3667"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" /><linearGradient
- id="linearGradient3682-0"><stop
- style="stop-color:#f1e671;stop-opacity:1;"
- offset="0"
- id="stop4231-6" /><stop
- style="stop-color:#c8ab37;stop-opacity:1"
- offset="0.66298664"
- id="stop4213-1" /><stop
- style="stop-color:#786721;stop-opacity:1"
- offset="1"
- id="stop3686-5" /></linearGradient><linearGradient
- id="linearGradient4223-6"><stop
- id="stop3656-9"
- offset="0"
- style="stop-color:#6a5c22;stop-opacity:1;" /><stop
- id="stop3654-3"
- offset="0.70769727"
- style="stop-color:#c8ab37;stop-opacity:1" /><stop
- style="stop-color:#dac15a;stop-opacity:1;"
- offset="1"
- id="stop4227-7" /></linearGradient><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5749"
- id="linearGradient5745"
- x1="106.28487"
- y1="31.718859"
- x2="125.58268"
- y2="20.102272"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.98036388,-0.19719702,0.19719702,0.98036388,-4.0195208,24.162963)" /></defs><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1096"
- inkscape:window-height="908"
- id="namedview2847"
- showgrid="false"
- inkscape:zoom="2.6219511"
- inkscape:cx="133.1416"
- inkscape:cy="126.24304"
- inkscape:window-x="474"
- inkscape:window-y="50"
- inkscape:window-maximized="0"
- inkscape:current-layer="g2910"
- inkscape:object-nodes="true"
- inkscape:snap-global="false" />
-
-<g
- inkscape:groupmode="layer"
- id="layer1"
- inkscape:label="red"
- transform="translate(0,41.938005)"><path
- sodipodi:type="arc"
- style="fill:#b3faec;fill-opacity:1;stroke:none"
- id="path3763"
- sodipodi:cx="137.88635"
- sodipodi:cy="123.53212"
- sodipodi:rx="101.42695"
- sodipodi:ry="101.42695"
- d="m 239.3133,123.53212 c 0,56.01656 -45.41039,101.42695 -101.42695,101.42695 -56.016554,0 -101.426946,-45.41039 -101.426946,-101.42695 0,-56.016557 45.410392,-101.426949 101.426946,-101.426949 56.01656,0 101.42695,45.410392 101.42695,101.426949 z"
- transform="matrix(0.99808795,0,0,0.99808795,18.430079,-34.438385)" /></g><g
- style="display:inline"
- inkscape:label="New"
- id="g2910"
- inkscape:groupmode="layer"
- transform="translate(0,41.938005)"><path
- id="path2952"
- style="fill:#00612b;fill-opacity:1"
- d="m 200.81661,54.986631 c -3.64879,2.893622 -10.27939,-2.561778 -14.8154,-12.182166 -4.53602,-9.620387 -5.25062,-19.762511 -1.60288,-22.654025 3.64936,-2.890703 10.2794,2.561778 14.81703,12.182977 4.53497,9.622496 5.24956,19.764615 1.60125,22.653214 z"
- inkscape:connector-curvature="0" /><path
- id="path2950"
- style="fill:#00612b;fill-opacity:1"
- d="m 153.95812,24.495879 c -1.18398,8.821918 -6.30211,15.415312 -11.43224,14.7268 -5.1285,-0.688295 -8.32837,-8.400188 -7.14467,-17.219999 1.1837,-8.81981 6.30346,-15.412986 11.43196,-14.724692 5.13012,0.688514 8.32865,8.398081 7.14495,17.217891 z"
- inkscape:connector-curvature="0" /><path
- id="path2920"
- style="fill:url(#linearGradient5745);fill-opacity:1"
- d="m 113.89971,44.482838 c -9.42833,-5.583098 -10.97803,-16.545947 -8.95458,-25.701693 10.78651,-1.879166 15.62267,0.417141 22.40109,4.811931 4.62503,5.334319 8.89665,21.164927 8.89665,21.164927 0,0 -12.91818,5.304769 -22.34316,-0.275165 z"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" /><g
- id="g2914"
- transform="translate(9.9926697,-9.9615949)" /><path
- id="path2932"
- style="fill:#ffffff;fill-opacity:1"
- d="m 129.71368,59.616405 c 0,11.815 -9.941,21.394 -22.20501,21.394 -12.265,0 -22.206,-9.578 -22.206,-21.394 0,-11.816 9.941,-21.393 22.206,-21.393 12.26301,10e-4 22.20501,9.578 22.20501,21.393 z" /><path
- id="path2936"
- d="m 119.60176,60.722511 c 0,6.584565 -5.33607,11.922075 -11.92207,11.922075 -6.58457,0 -11.920639,-5.33751 -11.920639,-11.922075 0,-6.583123 5.336069,-11.919189 11.920639,-11.919189 6.586,0 11.92207,5.336066 11.92207,11.919189 z" /><path
- id="path2938"
- style="fill:url(#radialGradient3688);fill-opacity:1"
- d="m 20.248693,126.38723 c -4.875,13.539 16.851977,38.11817 32.067977,43.40217 -1.406,13.13 18.633,35.877 28.653,41.022 0.271,-6.771 1.083,-12.186 4.062,-16.519 21.935,15.436 36.82901,17.061 53.66101,21.721 -10.862,-3.007 -10.008,-16.379 -15.479,-23.616 23.614,0.197 35.204,12.728 69.596,14.623 l -12.998,-17.331 c 14.352,3.521 34.933,2.708 43.057,4.874 -4.333,-13.811 -3.521,-41.433 -6.77,-55.784 l 18.414,3.52 c -9.749,-17.602 1.103,-75.441995 -43.87,-95.591995 -2.883,-2.148 -12.252,-5.109 -23.536,-6.479 1.331,-3.271 5.393,-2.458 7.289,-5.707 -22.206,-13.54 -53.6787,5.024694 -62.67916,27.983771 C 90.500287,59.627637 62.753824,68.608484 49.688055,76.479943 24.650591,75.107481 -8.7789229,95.442386 20.248693,126.38723 z"
- sodipodi:nodetypes="ccccscccccccccccc" /><path
- id="path2942"
- style="fill:#c8ab37"
- d="m 209.64295,79.922477 c -10.45927,8.654008 -27.04449,11.508862 -32.31327,5.958928 -5.729,-7.866 -0.576,-22.424 12.321,-31.361 11.012,-7.632 23.739,-8.173 33.089,-2.856 0,0 -0.56773,18.814072 -13.09673,28.258072 z"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" /><path
- id="path2944"
- style="fill:#ffffff;fill-opacity:1"
- d="m 161.14537,72.186106 c 0,14.031212 -12.05212,25.405391 -26.91875,25.405391 -14.86662,0 -26.91764,-11.374179 -26.91764,-25.405391 0,-14.030094 12.05102,-25.405393 26.91764,-25.405393 14.86663,0 26.91875,11.374182 26.91875,25.405393 z"
- inkscape:connector-curvature="0" /><path
- id="path2948"
- d="m 152.13337,81.364785 c 0,7.213238 -5.84788,13.062625 -13.06111,13.062625 -7.21172,0 -13.0596,-5.849387 -13.0596,-13.062625 0,-7.210206 5.84788,-13.061111 13.0596,-13.061111 7.21172,0 13.06111,5.847874 13.06111,13.061111 z"
- inkscape:connector-curvature="0" /><path
- style="fill:url(#linearGradient4221);fill-opacity:1;stroke:none"
- d="m 176.24831,85.215715 c 3.96315,-12.290584 9.03724,-17.823025 17.89563,-24.272687 8.8584,-6.449663 21.66306,-9.307376 28.22124,-9.202043 0.9601,6.584307 -4.34708,25.269778 -16.81208,31.477156 -12.465,6.207378 -22.71034,7.847933 -29.30479,1.997574 z"
- id="path2905"
- sodipodi:nodetypes="csczc"
- inkscape:connector-curvature="0" /><path
- style="fill:#786721;fill-opacity:1;stroke:none"
- d="m 48.005001,111.71852 c -2.949904,3.53909 -16.95113,7.33888 -20.126512,4.65943 -2.992792,-2.5254 -7.802482,-14.27033 -5.418417,-18.576378 2.384068,-4.30606 10.357411,-5.39957 17.411449,-1.5565 7.054037,3.843048 11.083384,11.934348 8.13348,15.473448 z"
- id="path2907"
- sodipodi:nodetypes="czzsz" /><path
- style="fill:url(#radialGradient3652);fill-opacity:1;stroke:none;display:inline;overflow:visible"
- d="m 120.72419,134.27017 c 4.7296,4.0489 -17.95314,35.05629 -26.638897,26.20018 -22.634334,14.42744 -49.517528,17.54845 -70.511913,-17.46598 -3.196841,-2.19714 -2.880626,-8.47284 -6.330991,-11.78012 -4.712545,-5.28371 -5.115009,-9.41834 -5.948895,-17.41712 3.637076,7.79459 9.056496,10.69899 14.761583,14.12161 31.651372,43.90812 56.905665,23.7243 64.676686,20.10385 16.608687,12.57492 27.313777,-16.37878 29.992427,-13.76242 z"
- id="path2986"
- sodipodi:nodetypes="cccccccc" /></g></svg> \ No newline at end of file
diff --git a/Build/source/texk/texlive/w32_wrapper/wrunscript_exe.c b/Build/source/texk/texlive/w32_wrapper/wrunscript_exe.c
deleted file mode 100644
index 573501ae757..00000000000
--- a/Build/source/texk/texlive/w32_wrapper/wrunscript_exe.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/************************************************************************
-
- This file is a part of the wrapper program for launching scripts
- and programs in TeX Live on Windows. See readme.txt for more details.
-
- This file was originally written in 2009 by Tomasz M. Trzeciak and
- was placed in the Public Domain.
-
-************************************************************************/
-
-#include <windows.h>
-
-__declspec(dllimport) int dllwrunscript(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- char *argline,
- int winshow
- );
-
-int APIENTRY WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- char *argline,
- int winshow
-){
- return dllwrunscript( hInstance, hPrevInstance, argline, winshow );
-}
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/README b/Build/source/texk/texlive/w64_mingw_wrapper/README
deleted file mode 100644
index 33eb4ae5181..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/README
+++ /dev/null
@@ -1,8 +0,0 @@
-This file and the graphics are public domain.
-
-This directory is for the generic TeX Live wrapper on Windows that is
-used for most scripts. The main file is runscript.tlu.
-
-*.svg are the sources for *.ico,
-and the *.ico are used in wrappers.
-Hence their locaton here.
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.ico b/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.ico
deleted file mode 100644
index be4be44b3d1..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.ico
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg b/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg
deleted file mode 100644
index aac123a3914..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg
+++ /dev/null
@@ -1,525 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- id="svg3004"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- width="320"
- height="320"
- xml:space="preserve"
- sodipodi:docname="grid_square.svg"><metadata
- id="metadata3010"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
- id="defs3008" /><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1254"
- inkscape:window-height="954"
- id="namedview3006"
- showgrid="false"
- inkscape:zoom="2.334375"
- inkscape:cx="165.30692"
- inkscape:cy="160"
- inkscape:window-x="266"
- inkscape:window-y="30"
- inkscape:window-maximized="0"
- inkscape:current-layer="g3012" /><g
- id="g3012"
- inkscape:groupmode="layer"
- inkscape:label="ink_ext_XXXXXX"
- transform="matrix(1.25,0,0,-1.25,0,320)"><path
- inkscape:connector-curvature="0"
- id="path3016"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0,0 16,0 16,16 0,16 0,0 z" /><path
- style="fill:#100000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 300 L 20 320 L 40 320 L 60 320 L 60 300 L 40 300 L 20 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3018" /><path
- style="fill:#300000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 300 L 60 320 L 80 320 L 100 320 L 100 300 L 80 300 L 60 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3022" /><path
- style="fill:#500000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 300 L 100 320 L 120 320 L 140 320 L 140 300 L 120 300 L 100 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3026" /><path
- style="fill:#700000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 300 L 140 320 L 160 320 L 180 320 L 180 300 L 160 300 L 140 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3030" /><path
- style="fill:#8f0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 300 L 180 320 L 200 320 L 220 320 L 220 300 L 200 300 L 180 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3034" /><path
- style="fill:#536c5d;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 300 L 220 320 L 240 320 L 260 320 L 260 300 L 240 300 L 220 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3038" /><path
- style="fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 300 L 260 320 L 280 320 L 300 320 L 300 300 L 280 300 L 260 300 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3042" /><path
- inkscape:connector-curvature="0"
- id="path3046"
- style="fill:#1c2224;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 240,0 16,0 0,16 -16,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3048"
- style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,0 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#001000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 260 L 0 280 L 0 300 L 20 300 L 20 280 L 20 260 L 0 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3050" /><path
- style="fill:#101000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 260 L 20 280 L 20 300 L 40 300 L 60 300 L 60 280 L 60 260 L 40 260 L 20 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3052" /><path
- style="fill:#782121;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 260 L 60 280 L 60 300 L 80 300 L 100 300 L 100 280 L 100 260 L 80 260 L 60 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3056" /><path
- style="fill:#501000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 260 L 100 280 L 100 300 L 120 300 L 140 300 L 140 280 L 140 260 L 120 260 L 100 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3060" /><path
- style="fill:#701000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 260 L 140 280 L 140 300 L 160 300 L 180 300 L 180 280 L 180 260 L 160 260 L 140 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3064" /><path
- style="fill:#16502d;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 260 L 180 280 L 180 300 L 200 300 L 220 300 L 220 280 L 220 260 L 200 260 L 180 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3068" /><path
- style="fill:#782121;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 260 L 220 280 L 220 300 L 240 300 L 260 300 L 260 280 L 260 260 L 240 260 L 220 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3072" /><path
- style="fill:#004455;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 260 L 260 280 L 260 300 L 280 300 L 300 300 L 300 280 L 300 260 L 280 260 L 260 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3076" /><path
- style="fill:#782121;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 260 L 300 280 L 300 300 L 320 300 L 320 280 L 320 260 L 300 260 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3080" /><path
- inkscape:connector-curvature="0"
- id="path3082"
- style="fill:#ff1000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,16 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3116"
- style="fill:#ff2000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,32 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#003000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 220 L 0 240 L 0 260 L 20 260 L 20 240 L 20 220 L 0 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3118" /><path
- style="fill:#164450;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 220 L 20 240 L 20 260 L 40 260 L 60 260 L 60 240 L 60 220 L 40 220 L 20 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3120" /><path
- style="fill:#303000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 220 L 60 240 L 60 260 L 80 260 L 100 260 L 100 240 L 100 220 L 80 220 L 60 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3124" /><path
- style="fill:#503000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 220 L 100 240 L 100 260 L 120 260 L 140 260 L 140 240 L 140 220 L 120 220 L 100 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3128" /><path
- style="fill:#703000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 220 L 140 240 L 140 260 L 160 260 L 180 260 L 180 240 L 180 220 L 160 220 L 140 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3132" /><path
- style="fill:#8f3000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 220 L 180 240 L 180 260 L 200 260 L 220 260 L 220 240 L 220 220 L 200 220 L 180 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3136" /><path
- style="fill:#af3000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 220 L 220 240 L 220 260 L 240 260 L 260 260 L 260 240 L 260 220 L 240 220 L 220 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3140" /><path
- style="fill:#803300;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 220 L 260 240 L 260 260 L 280 260 L 300 260 L 300 240 L 300 220 L 280 220 L 260 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3144" /><path
- style="fill:#808000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 220 L 300 240 L 300 260 L 320 260 L 320 240 L 320 220 L 300 220 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3148" /><path
- inkscape:connector-curvature="0"
- id="path3150"
- style="fill:#ff3000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,48 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3184"
- style="fill:#ff4000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,64 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#005000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 180 L 0 200 L 0 220 L 20 220 L 20 200 L 20 180 L 0 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3186" /><path
- style="fill:#105000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 180 L 20 200 L 20 220 L 40 220 L 60 220 L 60 200 L 60 180 L 40 180 L 20 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3188" /><path
- style="fill:#305000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 180 L 60 200 L 60 220 L 80 220 L 100 220 L 100 200 L 100 180 L 80 180 L 60 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3192" /><path
- style="fill:#505000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 180 L 100 200 L 100 220 L 120 220 L 140 220 L 140 200 L 140 180 L 120 180 L 100 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3196" /><path
- style="fill:#803300;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 180 L 140 200 L 140 220 L 160 220 L 180 220 L 180 200 L 180 180 L 160 180 L 140 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3200" /><path
- style="fill:#8f5000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 180 L 180 200 L 180 220 L 200 220 L 220 220 L 220 200 L 220 180 L 200 180 L 180 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3204" /><path
- style="fill:#af5000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 180 L 220 200 L 220 220 L 240 220 L 260 220 L 260 200 L 260 180 L 240 180 L 220 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3208" /><path
- style="fill:#536c67;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 180 L 260 200 L 260 220 L 280 220 L 300 220 L 300 200 L 300 180 L 280 180 L 260 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3212" /><path
- style="fill:#784421;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 180 L 300 200 L 300 220 L 320 220 L 320 200 L 320 180 L 300 180 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3216" /><path
- inkscape:connector-curvature="0"
- id="path3218"
- style="fill:#ff5000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,80 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3252"
- style="fill:#ff6000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,96 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#007000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 140 L 0 160 L 0 180 L 20 180 L 20 160 L 20 140 L 0 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3254" /><path
- style="fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 140 L 20 160 L 20 180 L 40 180 L 60 180 L 60 160 L 60 140 L 40 140 L 20 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3256" /><path
- style="fill:#307000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 140 L 60 160 L 60 180 L 80 180 L 100 180 L 100 160 L 100 140 L 80 140 L 60 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3260" /><path
- style="fill:#507000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 140 L 100 160 L 100 180 L 120 180 L 140 180 L 140 160 L 140 140 L 120 140 L 100 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3264" /><path
- style="fill:#707000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 140 L 140 160 L 140 180 L 160 180 L 180 180 L 180 160 L 180 140 L 160 140 L 140 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3268" /><path
- style="fill:#8f7000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 140 L 180 160 L 180 180 L 200 180 L 220 180 L 220 160 L 220 140 L 200 140 L 180 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3272" /><path
- style="fill:#af7000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 140 L 220 160 L 220 180 L 240 180 L 260 180 L 260 160 L 260 140 L 240 140 L 220 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3276" /><path
- style="fill:#502d16;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 140 L 260 160 L 260 180 L 280 180 L 300 180 L 300 160 L 300 140 L 280 140 L 260 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3280" /><path
- style="fill:#225500;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 140 L 300 160 L 300 180 L 320 180 L 320 160 L 320 140 L 300 140 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3284" /><path
- inkscape:connector-curvature="0"
- id="path3286"
- style="fill:#ff7000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,112 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3320"
- style="fill:#ff8000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,128 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#782144;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 100 L 0 120 L 0 140 L 20 140 L 20 120 L 20 100 L 0 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3322" /><path
- style="fill:#004455;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 100 L 20 120 L 20 140 L 40 140 L 60 140 L 60 120 L 60 100 L 40 100 L 20 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3324" /><path
- style="fill:#308f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 100 L 60 120 L 60 140 L 80 140 L 100 140 L 100 120 L 100 100 L 80 100 L 60 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3328" /><path
- style="fill:#803300;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 100 L 100 120 L 100 140 L 120 140 L 140 140 L 140 120 L 140 100 L 120 100 L 100 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3332" /><path
- style="fill:#708f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 100 L 140 120 L 140 140 L 160 140 L 180 140 L 180 120 L 180 100 L 160 100 L 140 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3336" /><path
- style="fill:#8f8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 100 L 180 120 L 180 140 L 200 140 L 220 140 L 220 120 L 220 100 L 200 100 L 180 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3340" /><path
- style="fill:#af8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 100 L 220 120 L 220 140 L 240 140 L 260 140 L 260 120 L 260 100 L 240 100 L 220 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3344" /><path
- style="fill:#cf8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 100 L 260 120 L 260 140 L 280 140 L 300 140 L 300 120 L 300 100 L 280 100 L 260 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3348" /><path
- style="fill:#782167;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 100 L 300 120 L 300 140 L 320 140 L 320 120 L 320 100 L 300 100 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3352" /><path
- inkscape:connector-curvature="0"
- id="path3354"
- style="fill:#ff8f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,144 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3388"
- style="fill:#ff9f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,160 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#504416;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 60 L 0 80 L 0 100 L 20 100 L 20 80 L 20 60 L 0 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3390" /><path
- style="fill:#165016;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 60 L 20 80 L 20 100 L 40 100 L 60 100 L 60 80 L 60 60 L 40 60 L 20 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3392" /><path
- style="fill:#502d16;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 60 L 60 80 L 60 100 L 80 100 L 100 100 L 100 80 L 100 60 L 80 60 L 60 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3396" /><path
- style="fill:#668000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 60 L 100 80 L 100 100 L 120 100 L 140 100 L 140 80 L 140 60 L 120 60 L 100 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3400" /><path
- style="fill:#806600;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 60 L 140 80 L 140 100 L 160 100 L 180 100 L 180 80 L 180 60 L 160 60 L 140 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3404" /><path
- style="fill:#008033;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 60 L 180 80 L 180 100 L 200 100 L 220 100 L 220 80 L 220 60 L 200 60 L 180 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3408" /><path
- style="fill:#784421;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 60 L 220 80 L 220 100 L 240 100 L 260 100 L 260 80 L 260 60 L 240 60 L 220 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3412" /><path
- style="fill:#a0892c;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 60 L 260 80 L 260 100 L 280 100 L 300 100 L 300 80 L 300 60 L 280 60 L 260 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3416" /><path
- style="fill:#806600;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 60 L 300 80 L 300 100 L 320 100 L 320 80 L 320 60 L 300 60 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3420" /><path
- inkscape:connector-curvature="0"
- id="path3422"
- style="fill:#ffaf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,176 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3456"
- style="fill:#ffbf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,192 0,0 0,16 0,0 0,-16 z" /><path
- style="fill:#484537;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 0 20 L 0 40 L 0 60 L 20 60 L 20 40 L 20 20 L 0 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3458" /><path
- style="fill:#338000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 20 L 20 40 L 20 60 L 40 60 L 60 60 L 60 40 L 60 20 L 40 20 L 20 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3460" /><path
- style="fill:#668000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 20 L 60 40 L 60 60 L 80 60 L 100 60 L 100 40 L 100 20 L 80 20 L 60 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3464" /><path
- style="fill:#aa4400;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 20 L 100 40 L 100 60 L 120 60 L 140 60 L 140 40 L 140 20 L 120 20 L 100 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3468" /><path
- style="fill:#008033;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 20 L 140 40 L 140 60 L 160 60 L 180 60 L 180 40 L 180 20 L 160 20 L 140 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3472" /><path
- style="fill:#6f7c91;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 20 L 180 40 L 180 60 L 200 60 L 220 60 L 220 40 L 220 20 L 200 20 L 180 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3476" /><path
- style="fill:#aa4400;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 20 L 220 40 L 220 60 L 240 60 L 260 60 L 260 40 L 260 20 L 240 20 L 220 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3480" /><path
- style="fill:#786721;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 20 L 260 40 L 260 60 L 280 60 L 300 60 L 300 40 L 300 20 L 280 20 L 260 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3484" /><path
- style="fill:#a02c2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 300 20 L 300 40 L 300 60 L 320 60 L 320 40 L 320 20 L 300 20 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3488" /><path
- inkscape:connector-curvature="0"
- id="path3490"
- style="fill:#ffcf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,208 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3524"
- style="fill:#ffdf00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,224 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3526"
- style="fill:#550000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,240 16,0 0,16 -16,0 0,-16 z" /><path
- style="fill:#483737;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 20 0 L 20 20 L 40 20 L 60 20 L 60 0 L 40 0 L 20 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3528" /><path
- style="fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 60 0 L 60 20 L 80 20 L 100 20 L 100 0 L 80 0 L 60 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3532" /><path
- style="fill:#161650;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 100 0 L 100 20 L 120 20 L 140 20 L 140 0 L 120 0 L 100 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3536" /><path
- style="fill:#445500;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 140 0 L 140 20 L 160 20 L 180 20 L 180 0 L 160 0 L 140 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3540" /><path
- style="fill:#445016;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 180 0 L 180 20 L 200 20 L 220 20 L 220 0 L 200 0 L 180 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3544" /><path
- style="fill:#806600;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 220 0 L 220 20 L 240 20 L 260 20 L 260 0 L 240 0 L 220 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3548" /><path
- style="fill:#89a02c;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="M 260 0 L 260 20 L 280 20 L 300 20 L 300 0 L 280 0 L 260 0 z "
- transform="matrix(0.8,0,0,-0.8,0,256)"
- id="path3552" /><path
- inkscape:connector-curvature="0"
- id="path3556"
- style="fill:#280b0b;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 240,240 16,0 0,16 -16,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3558"
- style="fill:#ffef00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,240 0,0 0,16 0,0 0,-16 z" /><path
- inkscape:connector-curvature="0"
- id="path3560"
- style="fill:#00ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3562"
- style="fill:#10ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 16,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3564"
- style="fill:#20ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 32,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3566"
- style="fill:#30ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 48,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3568"
- style="fill:#40ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 64,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3570"
- style="fill:#50ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 80,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3572"
- style="fill:#60ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 96,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3574"
- style="fill:#70ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 112,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3576"
- style="fill:#80ff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 128,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3578"
- style="fill:#8fff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 144,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3580"
- style="fill:#9fff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 160,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3582"
- style="fill:#afff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 176,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3584"
- style="fill:#bfff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 192,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3586"
- style="fill:#cfff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 208,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3588"
- style="fill:#dfff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 224,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3590"
- style="fill:#efff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 240,256 16,0 0,0 -16,0 z" /><path
- inkscape:connector-curvature="0"
- id="path3592"
- style="fill:#ffff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 256,256 0,0 0,0 0,0 z" /><g
- transform="scale(0.90694018,-1.1026086)"
- style="font-size:113.55400085px;font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Frutiger;-inkscape-font-specification:Frutiger Heavy"
- id="text3979"><path
- d="m 18.037517,-135.17236 33.384876,0 c 14.194236,0 30.886688,-3.97441 30.886688,-22.93791 0,-9.65208 -5.450603,-15.32979 -16.011114,-17.48732 l 0,-0.22711 c 8.857203,-2.9524 13.967142,-8.51656 13.967142,-18.5093 0,-13.62646 -11.014753,-20.09906 -25.776758,-20.09906 l -36.450834,0 0,79.2607 m 21.121044,-33.61199 6.472578,0 c 7.267449,0 15.556898,0.79489 15.556898,9.42498 0,8.06233 -8.062342,9.19788 -15.784006,9.19788 l -6.24547,0 0,-18.62286 m 0,-30.65958 6.131916,0 c 7.040341,0 13.853588,0.68133 13.853588,7.94878 0,6.69968 -7.153909,8.403 -14.080696,8.403 l -5.904808,0 0,-16.35178"
- style=""
- id="path3988" /><path
- d="m 93.888041,-135.17236 20.666829,0 -0.45422,-60.86495 0.22711,0 19.30418,60.86495 19.41774,0 20.21261,-60.86495 0.22711,0 -0.34067,60.86495 20.66683,0 0,-79.2607 -32.02223,0 -17.60087,52.68906 -0.2271,0 -16.806,-52.68906 -33.271319,0 0,79.2607"
- style=""
- id="path3990" /><path
- d="m 205.39807,-135.17236 57.34477,0 0,-14.98913 -31.3409,0 5.6777,-4.88282 c 7.49455,-6.47258 24.187,-22.0295 24.187,-37.47282 0,-15.78399 -12.71807,-23.27857 -30.43247,-23.27857 -4.65571,0 -12.15029,0.56777 -23.50568,4.65571 l 0.79488,16.46533 c 4.88281,-2.83885 13.96715,-5.45059 20.78038,-5.45059 6.35902,0 11.24184,2.95241 11.24184,9.99275 0,10.67407 -18.62287,25.89033 -34.74752,39.85745 l 0,15.10269"
- style=""
- id="path3992" /></g><g
- transform="scale(0.90694016,-1.1026086)"
- style="font-size:144.79751587px;font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Frutiger;-inkscape-font-specification:Frutiger Heavy"
- id="text3983"><path
- d="m 17.609618,-14.892303 72.833151,0 0,-19.113273 -45.900813,0 0,-22.878007 41.846482,0 0,-19.113272 -41.846482,0 0,-20.850842 44.30804,0 0,-19.113273 -71.240378,0 0,101.068667"
- style=""
- id="path3995" /><path
- d="m 105.40442,-14.892303 26.93234,0 0,-35.330594 10.42542,0 c 25.19474,0 40.10891,-12.163012 40.10891,-32.579441 0,-22.733192 -14.47978,-33.158632 -45.32162,-33.158632 l -32.14505,0 0,101.068667 m 26.93234,-81.955394 6.95028,0 c 9.26703,0 16.65171,3.330353 16.65171,13.610966 0,10.570208 -7.38468,13.900562 -16.65171,13.900562 l -6.95028,0 0,-27.511528"
- style=""
- id="path3997" /><path
- d="m 193.34402,-17.498659 c 8.97744,2.895948 20.70606,4.343926 30.11789,4.343926 22.44359,0 44.45283,-7.095105 44.45283,-33.303429 0,-36.488937 -47.78318,-25.484379 -47.78318,-41.846482 0,-8.83264 11.29422,-9.411839 18.09969,-9.411839 7.67426,0 15.49334,1.447979 22.44362,4.633521 l 1.73757,-20.850838 c -6.80548,-2.31676 -16.36213,-3.76474 -26.06355,-3.76474 -20.27164,0 -44.01845,6.66071 -44.01845,30.986669 0,36.778532 47.78318,24.905191 47.78318,43.728849 0,8.108653 -8.10867,9.846232 -16.65171,9.846232 -11.1494,0 -20.85085,-2.895955 -27.80113,-6.660686 l -2.31676,22.298817"
- style=""
- id="path3999" /></g></g></svg> \ No newline at end of file
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/calldll.c b/Build/source/texk/texlive/w64_mingw_wrapper/calldll.c
deleted file mode 100644
index ddb17f31055..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/calldll.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Public domain.
- * Originally written by Akira Kakuto <kakuto@fuk.kindai.ac.jp>
- *
- * DLL calling main program for TeX & Co
- * DLLPROC must be defined in the Makefile as,
- * e.g., -DDLLPROC=dlltexmain.
- */
-
-__declspec(dllimport) DLLPROC(int ac, char **av);
-int main(int ac, char **av)
-{
- return (DLLPROC(ac, av));
-}
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/callexe.c b/Build/source/texk/texlive/w64_mingw_wrapper/callexe.c
deleted file mode 100644
index 2aa041ea0da..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/callexe.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Public domain.
- * Originally written by Akira Kakuto <kakuto@fuk.kindai.ac.jp>
- *
- * WIN32 wrapper program replacing Unix symlinks such as,
- * e.g., ofm2opl -> omfonts.
- *
- * EXEPROG must be defined in the Makefile as,
- * e.g., -DEXEPROG=\"omfonts.exe\".
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <process.h>
-#include <string.h>
-#include <malloc.h>
-
-static int is_include_space(char *s)
-{
- char *p;
- p = strchr(s, ' ');
- if(p) return 1;
- p = strchr(s, '\t');
- if(p) return 1;
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int i;
- char *p;
-
- for(i = 0; i < argc; i++) {
- if(is_include_space(argv[i])) {
- p = (char *)malloc(strlen(argv[i])+3);
- strcpy(p, "\"");
- strcat(p, argv[i]);
- strcat(p, "\"");
- free(argv[i]);
- argv[i] = p;
- }
- }
- argv[argc] = NULL;
- return _spawnvp(_P_WAIT, EXEPROG, (const char * const *)argv);
-}
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dll b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dll
deleted file mode 100755
index 3c4481c319d..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exe b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exe
deleted file mode 100755
index 0e7882cf926..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exe
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c
deleted file mode 100644
index fc2e260f5a2..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/************************************************************************
-
- Copyright:
-
- Public Domain
- Originally written in 2010 by Tomasz M. Trzeciak and Hans Hagen
-
- This program is derived from the 'runscript' program originally
- written in 2009 by T.M. Trzeciak. It has been adapted for use in
- ConTeXt MkIV.
-
- Comment:
-
- In ConTeXt MkIV we have two core scripts: luatools.lua and
- mtxrun.lua where the second one is used to launch other scripts.
- Normally a user will use a call like:
-
- mtxrun --script font --reload
-
- Here mtxrun is a lua script. In order to avoid the usage of a cmd
- file on windows this runner will start texlua directly. If the
- shared library luatex.dll is available, texlua will be started in
- the same process avoiding thus any additional overhead. Otherwise
- it will be spawned in a new proces.
-
- We also don't want to use other runners, like those that use kpse
- to locate the script as this is exactly what mtxrun itself is doing
- already. Therefore the runscript program is adapted to a more direct
- approach suitable for mtxrun.
-
- Compilation:
-
- with gcc (size optimized):
-
- gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
- gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun
-
- with tcc (extra small size):
-
- tcc -shared -o mtxrun.dll mtxrun_dll.c
- tcc -o mtxrun.exe mtxrun_exe.c mtxrun.def
-
-************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-
-//#define STATIC
-#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t'))
-#define MAX_CMD 32768
-#define DIE(...) { \
- fprintf( stderr, "mtxrun: " ); \
- fprintf( stderr, __VA_ARGS__ ); \
- return 1; \
-}
-
-static char cmdline[MAX_CMD];
-static char dirpath[MAX_PATH];
-static char progname[MAX_PATH];
-static char scriptpath[MAX_PATH];
-static char luatexpath[MAX_PATH];
-HMODULE dllluatex = NULL;
-typedef int ( *mainlikeproc )( int, char ** );
-
-#ifdef STATIC
-int main( int argc, char *argv[] )
-#else
-__declspec(dllexport) int dllrunscript( int argc, char *argv[] )
-#endif
-{
- char *binary, *s, *luatexfname, *argstr, **lua_argv;
- int k, quoted, lua_argc;
- int passprogname = 0;
- unsigned char is_jit=0;
-
- // directory of this module/executable
- HMODULE module_handle = GetModuleHandle( "mtxrun.dll" );
- // if ( module_handle == NULL ) exe path will be used, which is OK too
- k = (int) GetModuleFileName( module_handle, dirpath, MAX_PATH );
- if ( !k || ( k == MAX_PATH ) )
- DIE( "unable to determine a valid module name\n" );
- s = strrchr(dirpath, '\\');
- if ( s == NULL ) DIE( "no directory part in module path: %s\n", dirpath );
- *(++s) = '\0'; //remove file name, leave trailing backslash
-
- // program name
- k = strlen(argv[0]);
- while ( k && (argv[0][k-1] != '/') && (argv[0][k-1] != '\\') ) k--;
- strcpy(progname, &argv[0][k]);
- s = progname;
- if ( s = strrchr(s, '.') ) *s = '\0'; // remove file extension part
-
- /* check "jit" : strlen("jit") = 3 */
- if (strncmp(progname + strlen(progname) - 3, "jit", 3) == 0) {
- is_jit = 1;
- progname[strlen(progname) - 3]='\0';
- }
- else
- is_jit = 0;
-
- // script path
-
- strcpy( scriptpath, dirpath );
- k = strlen(progname);
- if ( k < 6 ) k = 6; // in case the program name is shorter than "mtxrun"
- if ( strlen(dirpath) + k + 4 >= MAX_PATH )
- DIE( "path too long: %s%s\n", dirpath, progname );
-
- if ( strcmpi(progname,"mtxrun") == 0 ) {
- strcat( scriptpath, progname );
- strcat( scriptpath, ".lua" );
- } else if ( strcmpi(progname,"luatools") == 0 ) {
- strcat( scriptpath, "mtxrun.lua" );
- strcpy( progname, "base" );
- passprogname = 1;
- } else if ( strcmpi(progname,"texmfstart") == 0 ) {
- strcat( scriptpath, "mtxrun.lua" );
- } else {
- strcat( scriptpath, "mtxrun.lua" );
- passprogname = 1;
- }
- if ( GetFileAttributes(scriptpath) == INVALID_FILE_ATTRIBUTES )
- DIE( "file not found: %s\n", scriptpath );
-
- // find luatex.exe /luajittex.exe
- if ( SearchPath(
- dirpath, // was getenv( "PATH" ), // path to search (optional)
- (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "luajittex.exe":"luatex.exe");
- } else if ( SearchPath(
- dirpath, // was getenv( "PATH" ), // path to search (optional)
- (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "texluajit.exe":"texlua.exe");
- } else if ( SearchPath(
- getenv("PATH"), // was dirpath, // path to search (optional)
- (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "luajittex.exe":"luatex.exe");
- } else if ( SearchPath(
- getenv("PATH") , // was dirpath, // path to search (optional)
- (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search
- NULL, // file extension to add (optional)
- MAX_PATH, // output buffer size
- luatexpath, // output buffer pointer
- &luatexfname ) // pointer to a file part in the output buffer (optional)
- ) {
- binary = (is_jit ? "texluajit.exe":"texlua.exe");
- }else {
- DIE( "unable to locate texlua.exe on the search path" );
- }
-
- /* if ( SearchPath( */
- /* dirpath, // was getenv( "PATH" ), // path to search (optional) */
- /* (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "luajittex.exe":"luatex.exe"); */
- /* }else if ( SearchPath( */
- /* getenv("PATH"), // was dirpath, // path to search (optional) */
- /* (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "luajittex.exe":"luatex.exe"); */
- /* }else if ( SearchPath( */
- /* dirpath, // was getenv( "PATH" ), // path to search (optional) */
- /* (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "texluajit.exe":"texlua.exe"); */
- /* }else if ( SearchPath( */
- /* getenv("PATH") , // was dirpath, // path to search (optional) */
- /* (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search */
- /* NULL, // file extension to add (optional) */
- /* MAX_PATH, // output buffer size */
- /* luatexpath, // output buffer pointer */
- /* &luatexfname ) // pointer to a file part in the output buffer (optional) */
- /* ) { */
- /* binary = (is_jit ? "texluajit.exe":"texlua.exe"); */
- /* }else { */
- /* DIE( "unable to locate texlua.exe on the search path" ); */
- /* } */
-
-
-
-
- // link directly with luatex.dll if available in texlua's dir
- strcpy( luatexfname, (is_jit ? "luajittex.dll":"luatex.dll") );
- if ( dllluatex = LoadLibrary(luatexpath) )
- {
- mainlikeproc dllluatexmain = (mainlikeproc) GetProcAddress( dllluatex, (is_jit ? "dllluajittexmain": "dllluatexmain" ));
- if ( dllluatexmain == NULL )
- if (is_jit)
- DIE( "unable to locate dllluatexmain procedure in luajittex.dll" )
- else
- DIE( "unable to locate dllluatexmain procedure in luatex.dll" );
-
- // set up argument list for texlua script
-
- lua_argv = (char **)malloc( (argc + 5) * sizeof(char *) );
- if ( lua_argv == NULL ) DIE( "out of memory\n" );
- lua_argv[lua_argc=0] = luatexfname;
- lua_argv[++lua_argc] = "--luaonly";
- lua_argv[++lua_argc] = scriptpath; // script to execute
- if (passprogname) {
- lua_argv[++lua_argc] = "--script";
- lua_argv[++lua_argc] = progname;
- }
- for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k];
- lua_argv[++lua_argc] = NULL;
-
- // call texlua interpreter
- // dllluatexmain never returns, but we pretend that it does
-
- k = dllluatexmain( lua_argc, lua_argv );
- if (lua_argv) free( lua_argv );
- return k;
- }
- // we are still here, so no luatex.dll; spawn texlua.exe instead
-
- strcpy( luatexfname,binary);
- strcpy( cmdline, " --luaonly " );
- strcpy( cmdline, "\"" );
- strcat( cmdline, luatexpath );
- strcat( cmdline, "\" \"" );
- strcat( cmdline, scriptpath );
- strcat( cmdline, "\"" );
- if (passprogname) {
- strcat( cmdline, " --script " );
- strcat( cmdline, progname );
- }
- argstr = GetCommandLine(); // get the command line of this process
- if ( argstr == NULL ) DIE( "unable to retrieve the command line string\n" );
-
- // skip over argv[0] in the argument string
- // (it can contain embedded double quotes if launched from cmd.exe!)
-
- for ( quoted = 0; (*argstr) && ( !IS_WHITESPACE(*argstr) || quoted ); argstr++ )
- if (*argstr == '"') quoted = !quoted;
-
- // pass through all the arguments
-
- if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD )
- DIE( "command line string too long:\n%s%s\n", cmdline, argstr );
- strcat( cmdline, argstr );
-
- // create child process
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESTDHANDLES;// | STARTF_USESHOWWINDOW;
- //si.dwFlags = STARTF_USESHOWWINDOW;
- //si.wShowWindow = SW_HIDE ; // can be used to hide console window (requires STARTF_USESHOWWINDOW flag)
- si.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
- si.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE );
- si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
- ZeroMemory( &pi, sizeof(pi) );
- if( !CreateProcess(
- NULL, // module name (uses command line if NULL)
- cmdline, // command line
- NULL, // process security atrributes
- NULL, // thread security atrributes
- TRUE, // handle inheritance
- 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS
- NULL, // pointer to environment block (uses parent if NULL)
- NULL, // starting directory (uses parent if NULL)
- &si, // STARTUPINFO structure
- &pi ) // PROCESS_INFORMATION structure
- ) DIE( "command execution failed: %s\n", cmdline );
- DWORD ret = 0;
- CloseHandle( pi.hThread ); // thread handle is not needed
- if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) {
- if ( !GetExitCodeProcess( pi.hProcess, &ret) )
- DIE( "unable to retrieve process exit code: %s\n", cmdline );
- } else DIE( "failed to wait for process termination: %s\n", cmdline );
- CloseHandle( pi.hProcess );
-
- // propagate exit code from the child process
- return ret;
-
-}
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c
deleted file mode 100644
index 0c27c272e37..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// This is the .exe part of the mtxrun program, see mtxrun_dll.c
-// for more details.
-
-#include <windows.h>
-
-__declspec(dllimport) int dllrunscript( int argc, char *argv[] );
-
-int main( int argc, char *argv[] ) { return dllrunscript( argc, argv ); }
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt b/Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt
deleted file mode 100644
index 72892ee2f11..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Copyright:
-
-The originally 'runscript' program was written by in 2009 by T.M.Trzeciak and is
-public domain. This derived mtxrun program is an adapted version by Hans Hagen and
-Luigi Scarso.
-
-Comment:
-
-In ConTeXt MkIV we have two core scripts: luatools.lua and mtxrun.lua where the
-second one is used to launch other scripts. The mtxrun.exe program calls luatex.exe.
-
-Normally a user will use a call like:
-
- mtxrun --script font --reload
-
-Here mtxrun is a lua script. In order to avoid the usage of a cmd file on windows this
-runner will start texlua directly. In TeXlive a runner is added for each cmd file but
-we don't want that overhead (and extra files). By using an exe we can call these
-scripts in batch files without the need for using call.
-
-The mtxrun.exe file can be copied to a mtxrunjit.exe file in which case luajittex.exe
-is called.
-
- mtxrunjit --script font --reload
-
-We also don't want to use other runners, like those that use kpse to locate the script
-as this is exactly what mtxrun itself is doing already. Therefore the runscript program
-is adapted to a more direct approach suitable for mtxrun.
-
-Compilation:
-
-with gcc (size optimized):
-
- gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
- gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun
-
-with tcc (ver. 0.9.24), extra small size
-
- tcc -shared -o runscript.dll runscript_dll.c
- tcc -o runscript.exe runscript_exe.c runscript.def
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dll b/Build/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dll
deleted file mode 100755
index d821e4a30a4..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/readme.txt b/Build/source/texk/texlive/w64_mingw_wrapper/readme.txt
deleted file mode 100644
index a4637d812ae..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/readme.txt
+++ /dev/null
@@ -1,229 +0,0 @@
-
- Script wrappers in TeX Live on Windows
-
- Rationale
-
- Wrappers enable use of scripts on Windows as regular programs.
- They are also required for some binary programs to set up the
- right environment for them.
-
- Batch scripts can be used for wrapping but they are not as universal
- as binaries (there are some odd cases where they don't work) and
- it is hard to make them robust and secure. Compiled binary wrappers
- don't suffer from these problems but they are harder to write, debug
- and maintain in comparison to scripts. For these reasons a hybrid
- approach is taken that combines a binary stub with a launcher script.
-
- Adding wrappers for user scripts
-
- The script wrapping machinery is not limited to scripts shipped with
- TeX Live. You can also use it for script programs from manually
- installed packages. This should minimize problems when using them
- with TeX Live.
-
- First, make sure that there is an interpreter program available on
- your system for the script you want to use. Interpreters for Perl
- and Lua are bundled with TeX Live, all others have to be installed
- independently. Lua scripts are the most efficient to run, so if you
- consider writing a new script, that would be the recommended choice.
-
- The following script types and their file extensions are currently
- supported and searched in that order:
-
- Lua (.tlu;.texlua;.lua) -- included
- Perl (.pl) -- included
- Ruby (.rb) -- requires installation
- Python (.py) -- requires installation
- Tcl (.tcl) -- requires installation
- Java (.jar) -- requires installation
- VBScript (.vbs) -- part of Windows
- JScript (.js) -- part of Windows
- Batch (.bat;.cmd) -- part of Windows
-
- Finally, Unix-style extensionless scripts are searched as last and
- the interpreter program is established based on the she-bang (#!)
- specification on the very first line of the script. This can be
- an arbitrary program but it must be present on the search path.
-
- Next, the script program needs to be installed somewhere below the
- 'scripts' directory under one of the TEXMF trees (consult the
- documentation or texmf/web2c/texmf.cnf file for a list). You may
- need to update the file search database afterwards with:
-
- mktexlsr [TEXMFDIR]
-
- It is also possible to use scripts that are outside of TEXMF hierarchy
- by adjusting TEXMFSCRIPTS environment or kpathsea variable, see
- kpathsea documentation for more information on setting its variables.
-
- Test if the script can be located with:
-
- kpsewhich --format=texmfscripts <script-name>.<ext>
-
- This should output the full path to the script if everything is
- properly installed and configured. If this test is successful,
- the script can be run immediately with:
-
- runscript <script-name> [script arguments]
-
- If you prefer to call the script program simply by its name, copy
- and rename bin/win32/runscript.exe to <script-name>.exe and put it
- somewhere on the search path.
-
- Wrapper structure
-
- Wrappers consist of small binary stubs and a common texlua script.
- The binary stubs are all the same, just different names (but CLI
- and GUI stubs differ, see below, and GUI stubs are actually all
- different due to different embedded icons).
-
- The job of the binary stub is twofold: (a) call the texlua launcher
- script 'runscript.tlu' from the same directory (or more precisely
- from the directory containing 'runscript.dll') and (b) pass to it
- argv[0] and the unparsed argument string as the last two arguments
- (after adding a sentinel argument, which ends with a new line
- character). Arbitrary C strings can be passed, because the script
- is executed by linking with luatex.dll and calling the lua
- interpreter internally rather than by spawning a new process.
-
- There are two flavours of the binary stub: one for CLI programs
- and another one for GUI programs. The GUI variant does not open
- a console window nor does it block the command prompt if started
- from there. It also uses a dialog box to display an error message
- in addition to outputting to stderr.
-
- The stubs are further split into a common DLL and EXE proxies
- to it. This is for maintenance reasons - updates can be done by
- replacement of a single DLL rather than all binary stubs.
-
- The launcher script knows, which variant has been used to invoke it
- based on the sentinel argument. The lack of this argument means
- that it was invoked in a standard way, i.e., through texlua.exe.
-
- All the hard work of locating a script/program to execute happens
- in the launcher script. The located script/program is always
- executed directly by spawning its interpreter (or binary) in a new
- process. The system shell (cmd.exe) is never called (except for
- batch scripts, of course). If the located script happens to be
- a (tex)lua script, it is loaded and called internally from within
- this script, i.e. no new process is spawned. Execution is done
- using a protected call, so any compile or runtime errors are catched.
-
- Source files
-
- runscript.tlu launcher script for locating and dispatching
- target scripts/programs
- runscript_dll.c common DLL part of the binary stubs; locates and
- calls the launcher script
- runscript_exe.c EXE proxy to the common DLL for CLI mode stubs
- wrunscript_exe.c EXE proxy to the common DLL for GUI mode stubs
-
- Compilation of binaries (requires luatex.dll in the same directory)
-
- with gcc (size optimized):
-
- x86_64-w64-mingw32-gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -ltexlua
- x86_64-w64-mingw32-gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript
-Untested (todo):
- x86_64-w64-mingw32-gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript
-
-Untested (todo):
- with tcc (extra small size):
-
- tiny_impdef texlua.dll
- tcc -shared -o runscript.dll runscript_dll.c luatex.def
- tcc -o runscript.exe runscript_exe.c runscript.def
- tcc -o wrunscript.exe wrunscript_exe.c runscript.def
-
- License
-
- Originally written in 2009 by Tomasz M. Trzeciak, Public Domain.
-
- Prior work:
- 'tl-w32-wrapper.texlua' by Reinhard Kotucha and Norbert Preining.
- 'tl-w32-wrapper.cmd' by Tomasz M. Trzeciak.
-
- Changelog
-
- 2009/12/04
- - initial version
- 2009/12/15
- - minor fixes for path & extension list parsing
- 2010/01/09
- - added support for GUI mode stubs
- 2010/02/28
- - enable GUI mode stubs for dviout, psv and texworks;
- - added generic handling of sys programs
- - added restricted repstopdf to alias_table
- 2010/03/13
- - added 'readme.txt' and changelog
- - added support and docs for calling user added scripts;
- (use path of 'runscript.dll' instead of .exe stub to
- locate 'runscript.tlu' script)
- - limit search for shell_escape_commands to system trees
- - added function for creating directory hierarchy
- - fixed directory creation for dviout & texworks aliases
- - fixed arg[0] of repstopdf & rpdfcrop
- 2010/03/28
- - restructured docs, added --help and --version options
- (available only when invoked under 'runscript' name)
- - use TEXMF_RESTRICTED_SCRIPTS kpse var for searching
- shell_escape_commands
- - changed command validation to handle a list of commands
- - prepend GUI mode command(s) to the command list
- - added support for .tcl scripts
- 2010/03/31
- - fixed fatal bug in extention_map definition for GUI mode
- 2010/04/15
- - encapsulated main chunk in a function to execute with
- pcall for more robustness and better error catching
- - added texdoctk to scripts4tlperl table
- - added tlgs and tlperl to alias_table; callable as e.g.:
- runscript tlperl ...
- - doc tweaks
- 2010/04/22
- - ensure only backslash is used in USERPROFILE variable
- (Adobe Reader crash case)
- - fixed argument processing for direct execution under texlua
- - more doc tweaks
- 2010/05/30
- - Windows XP or newer required to run TeXworks
- 2010/06/04
- - added support for Perl scripts starting with eval-exec-perl
- construct in place of she-bang (#!)
- 2010/06/25
- - run internal tlperl only with our Perl
- - added fontinst to alias_table
- - added support for all tex4ht commands from mk4ht.pl
- - removed some unsued aliases
- - some code refactoring and cleanup
- 2010/12/28
- - use of external Perl now requires kpathsea variable
- TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL to be explicitly set to 1
- - alias_table replaced with if-elseif-end tests to streamline
- special cases and to avoid hardcoding of texmf* file paths
- - added a2ping to special cases (requires -x switch to Perl)
- - set ASYMPTOTE_GS (for asy) to full path to tlgs
- 2011/01/09
- - removed tex4ht commands starting with ht from mk4ht aliases;
- they have their own scripts and mk4ht calls them internally,
- so aliasing results in an infinite recursion
- - removed alias for fontinst (no fontinst.exe any more)
- - fixed GUI-mode interpreter for Ruby
- 2011/09/10
- - added -dDisableFAPI=true to psview argument list. Needed by
- gs-9.xx
- 2012/03/12
- - added '-i', '.' to psview argument list (author's request)
- - added environment clean up from Perl specific variables
- (when not using external Perl)
- 2012/08/05
- - added alias for fmtutil
- 2013/05/09
- - added alias mkluatexfontdb -> luaotfload-tool
- 2013/07/03
- - fix for psview and UNC paths in unix-style
- - remove not needed is_abs_path function
- 2019/02/19
- - patches for cross-compiled texlive with Mingw x86_64 from Ubuntu
-
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.dll b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.dll
deleted file mode 100755
index aa418b5d4f6..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.exe b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.exe
deleted file mode 100755
index d765cdf75a5..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.exe
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.tlu b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.tlu
deleted file mode 100755
index 0f94c5603aa..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.tlu
+++ /dev/null
@@ -1,928 +0,0 @@
-
-
-local svnrevision = string.match("$Revision: 49485 $", "%d+") or "0"
-local svndate = string.match("$Date: 2018-12-23 16:28:08 +0100 (Sun, 23 Dec 2018) $", "[-%d]+") or "2009-12-04"
-local bannerstr = "runscript wrapper utility (rev. " ..
- svnrevision .. ", " .. svndate .. ")\n" ..
- "usage: runscript script-name [arguments]\n" ..
- "try -help [-v] for more information"
-
-local helpstr = [[
-
- Script wrappers in TeX Live on Windows
-
- Rationale
-
- Wrappers enable use of scripts on Windows as regular programs.
- They are also required for some binary programs to set up the
- right environment for them.
-
- Batch scripts can be used for wrapping but they are not as universal
- as binaries (there are some odd cases where they don't work) and
- it is hard to make them robust and secure. Compiled binary wrappers
- don't suffer from these problems but they are harder to write, debug
- and maintain in comparison to scripts. For these reasons a hybrid
- approach is taken that combines a binary stub with a launcher script.
-
- Adding wrappers for user scripts
-
- The script wrapping machinery is not limited to scripts shipped with
- TeX Live. You can also use it for script programs from manually
- installed packages. This should minimize problems when using them
- with TeX Live.
-
- First, make sure that there is an interpreter program available
- on your system for the script you want to use. Interpreters for
- Perl, Lua and Tcl/Tk (GUI scripts only) are bundled with TeX
- Live, all others have to be installed independently. Lua
- scripts are the most efficient to run, so if you consider
- writing a new script, that would be the recommended choice.
-
- The following script types and their file extensions are currently
- supported and searched in that order:
-
- Lua (.tlu;.texlua;.lua) -- included
- Perl (.pl) -- included
- Ruby (.rb) -- requires installation
- Python (.py) -- requires installation
- Tcl (.tcl) -- included (GUI scripts only)
- Java (.jar) -- requires installation
- VBScript (.vbs) -- part of Windows
- JScript (.js) -- part of Windows
- Batch (.bat;.cmd) -- part of Windows
-
- Finally, Unix-style extensionless scripts are searched as last and
- the interpreter program is established based on the she-bang (#!)
- specification on the very first line of the script. This can be
- an arbitrary program but it must be present on the search path.
-
- Next, the script program needs to be installed somewhere below the
- 'scripts' directory under one of the TEXMF trees (consult the
- documentation or texmf/web2c/texmf.cnf file for a list). You may
- need to update the file search database afterwards with:
-
- mktexlsr [TEXMFDIR]
-
- It is also possible to use scripts that are outside of TEXMF hierarchy
- by adjusting TEXMFSCRIPTS environment or kpathsea variable, see
- kpathsea documentation for more information on setting its variables.
-
- Test if the script can be located with:
-
- kpsewhich --format=texmfscripts <script-name>.<ext>
-
- This should output the full path to the script if everything is
- properly installed and configured. If this test is successful,
- the script can be run immediately with:
-
- runscript <script-name> [script arguments]
-
- If you prefer to call the script program simply by its name, copy
- and rename bin/win32/runscript.exe (or bin/win64/runscript.exe for
- 64-bit Windows) to <script-name>.exe and put it somewhere on the
- search path.]]
-
-local docstr = [[
-
- Wrapper structure
-
- Wrappers consist of small binary stubs and a common texlua script.
- The binary stubs are all the same, just different names (but CLI
- and GUI stubs differ, see below, and GUI stubs are actually all
- different due to different embedded icons).
-
- The job of the binary stub is twofold: (a) call the texlua launcher
- script 'runscript.tlu' from the same directory (or more precisely
- from the directory containing 'runscript.dll') and (b) pass to it
- argv[0] and the unparsed argument string as the last two arguments
- (after adding a sentinel argument, which ends with a new line
- character). Arbitrary C strings can be passed, because the script
- is executed by linking with luatex.dll and calling the lua
- interpreter internally rather than by spawning a new process.
-
- There are two flavours of the binary stub: one for CLI programs
- and another one for GUI programs. The GUI variant does not open
- a console window nor does it block the command prompt if started
- from there. It also uses a dialog box to display an error message
- in addition to outputting to stderr.
-
- The stubs are further split into a common DLL and EXE proxies
- to it. This is for maintenance reasons - updates can be done by
- replacement of a single DLL rather than all binary stubs.
-
- The launcher script knows, which variant has been used to invoke it
- based on the sentinel argument. The lack of this argument means
- that it was invoked in a standard way, i.e., through texlua.exe.
-
- All the hard work of locating a script/program to execute happens
- in the launcher script. The located script/program is always
- executed directly by spawning its interpreter (or binary) in a new
- process. The system shell (cmd.exe) is never called (except for
- batch scripts, of course). If the located script happens to be
- a (tex)lua script, it is loaded and called internally from within
- this script, i.e. no new process is spawned. Execution is done
- using a protected call, so any compile or runtime errors are caught.
-
- Source files
-
- runscript.tlu launcher script for locating and dispatching
- target scripts/programs
- runscript_dll.c common DLL part of the binary stubs; locates and
- calls the launcher script
- runscript_exe.c EXE proxy to the common DLL for CLI mode stubs
- wrunscript_exe.c EXE proxy to the common DLL for GUI mode stubs
-
- Compilation of binaries (requires luatex.dll in the same directory)
-
- with gcc (size optimized):
-
- gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -lluatex
- gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript
- gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript
-
- with tcc (extra small size):
-
- tiny_impdef luatex.dll
- tcc -shared -o runscript.dll runscript_dll.c luatex.def
- tcc -o runscript.exe runscript_exe.c runscript.def
- tcc -o wrunscript.exe wrunscript_exe.c runscript.def
-
- License
-
- Originally written in 2009 by Tomasz M. Trzeciak, Public Domain.
-
- Prior work:
- 'tl-w32-wrapper.texlua' by Reinhard Kotucha and Norbert Preining.
- 'tl-w32-wrapper.cmd' by Tomasz M. Trzeciak.
-
- Changelog
-
- 2009/12/04
- - initial version
- 2009/12/15
- - minor fixes for path & extension list parsing
- 2010/01/09
- - added support for GUI mode stubs
- 2010/02/28
- - enable GUI mode stubs for dviout, psv and texworks;
- - added generic handling of sys programs
- - added restricted repstopdf to alias_table
- 2010/03/13
- - added 'readme.txt' and changelog
- - added support and docs for calling user added scripts;
- (use path of 'runscript.dll' instead of .exe stub to
- locate 'runscript.tlu' script)
- - limit search for shell_escape_commands to system trees
- - added function for creating directory hierarchy
- - fixed directory creation for dviout & texworks aliases
- - fixed arg[0] of repstopdf & rpdfcrop
- 2010/03/28
- - restructured docs, added --help and --version options
- (available only when invoked under 'runscript' name)
- - use TEXMF_RESTRICTED_SCRIPTS kpse var for searching
- shell_escape_commands
- - changed command validation to handle a list of commands
- - prepend GUI mode command(s) to the command list
- - added support for .tcl scripts
- 2010/03/31
- - fixed fatal bug in extention_map definition for GUI mode
- 2010/04/15
- - encapsulated main chunk in a function to execute with
- pcall for more robustness and better error catching
- - added texdoctk to scripts4tlperl table
- - added tlgs and tlperl to alias_table; callable as e.g.:
- runscript tlperl ...
- - doc tweaks
- 2010/04/22
- - ensure only backslash is used in USERPROFILE variable
- (Adobe Reader crash case)
- - fixed argument processing for direct execution under texlua
- - more doc tweaks
- 2010/05/30
- - Windows XP or newer required to run TeXworks
- 2010/06/04
- - added support for Perl scripts starting with eval-exec-perl
- construct in place of she-bang (#!)
- 2010/06/25
- - run internal tlperl only with our Perl
- - added fontinst to alias_table
- - added support for all tex4ht commands from mk4ht.pl
- - removed some unsued aliases
- - some code refactoring and cleanup
- 2010/12/28
- - use of external Perl now requires kpathsea variable
- TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL to be explicitly set to 1
- - alias_table replaced with if-elseif-end tests to streamline
- special cases and to avoid hardcoding of texmf* file paths
- - added a2ping to special cases (requires -x switch to Perl)
- - set ASYMPTOTE_GS (for asy) to full path to tlgs
- 2011/01/09
- - removed tex4ht commands starting with ht from mk4ht aliases;
- they have their own scripts and mk4ht calls them internally,
- so aliasing results in an infinite recursion
- - removed alias for fontinst (no fontinst.exe any more)
- - fixed GUI-mode interpreter for Ruby
- 2011/09/10
- - added -dDisableFAPI=true to psview argument list. Needed by
- gs-9.xx
- 2012/03/12
- - added '-i', '.' to psview argument list (author's request)
- - added environment clean up from Perl specific variables
- (when not using external Perl)
- 2012/08/05
- - added alias for fmtutil
- 2013/05/09
- - added alias mkluatexfontdb -> luaotfload-tool
- 2013/07/03
- - fix for psview and UNC paths in unix-style
- - remove not needed is_abs_path function
- 2013/08/07
- - handle updmap-sys via updmap --sys
- 2013/08/08
- - allow overriding gs/gs_dll/gs_lib with kpse variables
- TEXLIVE_WINDOWS_EXTERNAL_GS, ..._GS_LIB, ..._GS_DLL
- 2013/08/30
- - do not pass -NULL to dviout, to allow users changing and
- saving settings. Patch by Yusuke KUROKI
- 2013/09/22
- - add TEXMFDIST/fonts to the GS_LIB path. Patch by Yusuke KUROKI
- 2014/04/30
- - fix for argument duplication in fmtutil
- 2015/04/12
- - handle fmtutil-sys via fmtutil --sys
- 2015/09/10
- - more slash flipping for the sake of vbscript and unc paths
- 2015/12/11
- - fix spurious arguments for updmap and fmtutil
- 2016/04/22
- - Warning if external perl is requested but missing
- 2017/04/22 (exactly one year later ;-)
- - Cater for fmtutil-user and updmap-user => -user arg
- 2017/04/24
- - GS_LIB setting for tlgs.
- 2017/05/06
- - introduce sys_user_progs, make checks for updmap/fmtutil
- use sys_user_progs instead, add kanji-config-updmap
- 2018/03/12
- - introduce a new function gettexmfdist() for security.
- 2018/04/06
- - introduce a new function is_64bit_windows_os() to
- check Windows OS.
- 2018/06/20
- - support also scripts in trees other than TEXMFDIST:
- https://tug.org/pipermail/tex-live/2018-June/041922.html
- 2018/10/10
- - support cluttex scripts
- 2018/11/08
- - use included tcltk interpreter
-
-]]
-
--- HELPER SUBROUTINES --
-
-local TEXDIR
-local guimode
-
-local function show_error(msg)
- if guimode then
- os.setenv('RUNSCRIPT_ERROR_MESSAGE', msg)
- if lfs.isfile(TEXDIR..'/tlpkg/tltcl/tclkit.exe') and
- lfs.isfile(TEXDIR..'/tlpkg/tltcl/gui_err.tcl') then
- os.spawn{TEXDIR..'/tlpkg/tltcl/tclkit.exe',
- TEXDIR..'/tlpkg/tltcl/gui_err.tcl'}
- end
- else
- io.stderr:write(msg, '\n')
- end
-end
-
--- quotes string with spaces
-local function _q(str)
- str = string.gsub(str, '"', '') -- disallow embedded double quotes
- return string.find(str, "%s") and '"'..str..'"' or str
-end
-
--- prepends directories to path if they are not already there
-local function prepend_path(path, ...)
- local pathcmp = string.lower(string.gsub(path, '/', '\\'))..';'
- for k = 1, select('#', ...) do
- local dir = string.lower(string.gsub(select(k, ...), '/', '\\'))..';'
- if not string.find(pathcmp, dir, 1, true) then path = dir..path end
- end
- return path
-end
-
--- searches the PATH for a file
-local function search_path(fname, PATH, PATHEXT)
- if string.find(fname, '[/\\]') then
- return nil, "directory part not allowed for PATH search: "..fname
- end
- PATH = PATH or os.getenv('PATH')
- PATHEXT = PATHEXT or '\0' -- '\0' for no extension
- for dir in string.gmatch(PATH, '[^;]+') do
- local dirsep = (string.find(dir, '\\') and '\\' or '/')
- for ext in string.gmatch(PATHEXT, '[^;]+') do
- local f = dir..dirsep..fname..ext
- if lfs.isfile(f) then return f, ext end
- end
- end
- return nil, "file or program not on PATH: "..fname
-end
-
--- tests for tex4ht command (as given in mk4ht.pl)
--- except for commands starting with 'ht' (they have their own scripts)
-local function is_tex4ht_command(progname)
- local prefixes = 'xh uxh xhm mz oo es js jm tei teim db dbm w jh jh1'
- local formats = 'context latex tex texi xelatex xetex'
- for p in string.gmatch(prefixes, '%S+') do
- for q in string.gmatch(formats, '%S+') do
- if (progname == p..q) then
- -- we have a hit, but not all combinations are valid
- return (p ~= 'teim' and p ~= 'dbm') or (q ~= 'xelatex' and q~= 'xetex')
- end
- end
- end
- return false
-end
-
--- checks whether an item is in an array
-local function contains (tab, val)
- for index, value in ipairs(tab) do
- if value == val then
- return true
- end
- end
- return false
-end
-
--- locates texmfscript to execute
-local function find_texmfscript(progname, ext_list)
- ext_list = ext_list or '\0'
- for ext in string.gmatch(ext_list, '[^;]+') do
- local progfullname = kpse.find_file(progname..ext, 'texmfscripts')
- if progfullname then return progfullname, ext end
- end
- return nil, "no appropriate script or program found: "..progname
-end
-
--- converts the #! line to arg table
--- used for scripts w/o extension
--- only the two most common cases are considered:
--- #! /path/to/command [options]
--- #! /usr/bin/env command [options]
--- ([options] after the command are retained as well)
-local function shebang_to_argv(progfullname)
- local fid, errmsg = io.open(progfullname, 'r')
- if not fid then return nil, errmsg end
- local fstln = fid:read('*line')
- fid:close()
- if string.find(fstln, "eval.*exit.*exec.*perl") then
- -- special case of Perl's time-honoured "totally devious construct":
- -- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
- return {"perl"}
- elseif (string.sub(fstln, 1, 2) ~= '#!') then
- return nil, "don't know how to execute script: "..progfullname
- end
- local argv = string.explode( string.sub(fstln, 3) ) -- split on spaces
- argv[1] = string.match(argv[1], '[^/]+$')
- if (argv[1] == 'env') then table.remove(argv, 1) end
- return argv
-end
-
--- checks if command exists on the path and returns its full path
-local function check_command(cmdlist, PATH)
- for cmd in string.gmatch(cmdlist, '%S+') do
- local cmdext = cmd..(string.find(cmd, '%.[^\\/.]*$') and '' or '.exe')
- local fullcmd = search_path(cmdext, PATH)
- if fullcmd then
- return fullcmd, cmd
- end
- end
- return nil, 'program not found (not part of TeX Live): '..cmdlist
-end
-
--- creates directory or directory hierarchy
-local function mkdir_plus(dir)
- if lfs.mkdir(dir) then
- return true
- end
- -- try with system's mkdir in case we need to create intermediate dirs too
- local ret = os.spawn({[0]=search_path("cmd.exe"),
- string.format('cmd.exe /x /c mkdir "%s"', dir)})
- if ret == 0 then
- return true
- else
- return nil, string.format("cannot create directory (error code %d): %s", ret, dir)
- end
-end
-
---
--- return the TEXMFDIST directory in TeX Live
---
-local function gettexmfdist()
- local ffi = require("ffi")
- ffi.cdef[[
- typedef void* HANDLE;
- typedef char* LPCSTR;
- int GetModuleFileNameA(HANDLE h, LPCSTR l, int i);
- HANDLE GetModuleHandleA(const char *a);
- ]]
- local buffer = ffi.new("char[?]", 512)
- local runscripthandle = ffi.C.GetModuleHandleA("runscript.dll")
- if runscripthandle == nil then
- return nil
- end
- local err = ffi.C.GetModuleFileNameA(runscripthandle, buffer, 256)
- if err == 0 then
- return nil
- end
- local str = ffi.string(buffer)
- str = string.gsub(str, "\\","/")
- str = string.reverse(str)
- local a, b
--- remove '/runscript.dll'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
--- remove '/win32'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
--- remove '/bin'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
- str = string.reverse(str)
- str = str .. '/texmf-dist'
- return str
-end
-
---
--- Is the Windows OS 64bit?
---
-local function is_64bit_windows_os()
- local return_val = false
- -- 32 bit binaries always work, thus the default is false
- local architecture = os.getenv('PROCESSOR_ARCHITECTURE')
- if architecture ~= nil then
- if architecture == 'x86' then
- local is_wow64 = os.getenv('PROCESSOR_ARCHITEW6432')
- if is_wow64 == nil then
- return_val = false
- else
- return_val = true
- end
- else
- return_val = true
- end
- end
- return return_val
-end
-
--- MAIN_CHUNK -- encapsulated in a function for more robust execution with pcall
-
-local function MAIN_CHUNK()
-
---[[
-
-OVERVIEW OF MAIN_CHUNK
-
-We start out with a lot of housekeeping, especially with respect to
-perl and ghostscript: if we are going to use the built-in versions,
-then the search path and other environment variables must be set or
-unset to make these findable and working right.
-
-Next we compose an ARGV table for os.spawn, unless the script turns
-out to be a [tex]lua script; see further down this comment block.
-
-The parameter table ARGV can have the following elements (see the
-luatex manual on os.exec and os.spawn):
-
-- ARGV[0]: the full path to the interpreter
-- ARGV[1]: the filename part of the interpreter. The interpreter choice
- depends on the detected script extension and also on gui mode.
-- ARGV[2]: progfulname, the full path to the script
-- ARGV[3]: argline, i.e. the unparsed arguments for the script.
- This is normally the last argument passed to runscript.tlu.
- See the actual code for when this is not the case.
-
-ARGV[0] gets priority over ARGV[1] if it is present.
-
-After everything has been set up, a call os.spawn(ARGV) runs the
-right program with the right arguments.
-
-But in case the script to be run is a texlua script, we run the script
-in the current texlua process using the dofile function. The original arg
-argument table may have been modified before then.
-
-Some variables:
-
-- ARGV, see above
-- arg, the texlua argument table of runscript.tlu
-- progname, the name under which [w]runscript.exe was called
-- progfullname, the full path of the script to be run. This variable
- is introduced only after some special cases have been dealt with.
-- argline, unparsed arguments to the script; may get modified
-
---]]
-
--- set the system-default value for LC_CTYPE
--- http://tug.org/pipermail/tex-live/2018-May/041628.html
-os.setlocale("", "ctype")
-
--- preprocess arguments: arg[-1] => texlua.exe, arg[0] => scriptname
-
--- guimode already declared local
-guimode = false
-local argline = ''
--- check for the sentinel argment coming from the .exe stub
-if arg[#arg-2] and ( string.sub(arg[#arg-2], -1) == '\n' ) then
- -- argv[0] and unparsed argument line are passed
- -- from the .exe stub as the two last arguments
- -- pop them up from the arg table
- argline = table.remove(arg) -- pop unparsed arguments
- arg[0] = table.remove(arg) -- pop C stub's argv[0]
- guimode = (table.remove(arg) == 'GUI_MODE\n') -- pop sentinel argument
-else
- -- we must be called as: texlua runscript.tlu progname ...
- -- this is treated the same as: runscript[.exe] progname ...
- -- we don't have the unparsed arument line in this case, so construct one
- for k = #arg, 1, -1 do argline = _q(arg[k]) .. ' ' .. argline end
-end
-
--- program name
-
--- lower arg[0] : get file name part : remove extension
-local progname, substcount = string.lower(arg[0]):gsub('^.*[\\/]', ''):gsub('%.[^.]*$', '')
--- special behaviour when called under 'runscript' name
-if (progname == 'runscript') then
- -- we are called as: runscript progname ...
- -- or as: runscript --help|-h|--version ...
- -- handle options first (only --help and --version)
- local opt, param = {}, nil
- while true do
- -- remove the first argument from the arg table and from the argline string
- -- (this argument should have no embedded spaces!)
- param = table.remove(arg, 1)
- if not param then break end
- argline = string.gsub(argline, '^%S+%s*', '')
- local optname = string.lower(param):match('^%-%-?(.*)$')
- if not optname then
- break
- elseif (optname == 'h') or (optname == 'help') then
- opt.help = true
- elseif (optname == 'v') then
- opt.v = true
- elseif (optname == 'version') then
- opt.version = true
- else
- error("unknown option: "..param.."\n"..bannerstr)
- end
- end
- if opt.help then
- print(helpstr)
- if opt.v then print(docstr) end
- os.exit(0)
- elseif opt.version or opt.v then
- print(bannerstr)
- os.exit(0)
- end
- -- make sure progname is valid
- arg[0] = assert(param, "not enough arguments!\n"..bannerstr)
- progname = string.lower(arg[0]):gsub('^.*[\\/]', ''):gsub('%.[^.]*$', '')
- assert(progname == string.lower(arg[0]), "bad command name: " .. arg[0])
-end
--- special case of sys programs
-progname, substcount = string.gsub(progname, '%-sys$', '')
-local sysprog = (substcount > 0) -- true if there was a -sys suffix removed
--- special case of user programs
--- we do not guard against programs foobar-user-sys ... we don't ship them
-progname, substcount = string.gsub(progname, '%-user$', '')
-local userprog = (substcount > 0) -- true if there was a -user suffix removed
--- prevent recursive calls to this script
-assert(progname ~= 'runscript', "oops! wrapping the wrapper?")
-
-
--- kpse and environment set-up
-
--- init kpathsea
-local k = -1
-while arg[k-1] do k = k - 1 end -- in case of a call: luatex --luaonly ...
-local lua_binary = arg[k]
-kpse.set_program_name(lua_binary, progname)
-
--- various dir-vars
--- TEXDIR already declared local
-TEXDIR = kpse.var_value('SELFAUTOPARENT')
--- local TEXMFDIST = kpse.var_value('TEXMFDIST')
--- use a new function to obtain TEXMFDIST
-local TEXMFDIST = gettexmfdist()
-if TEXMFDIST == nil then
- TEXMFDIST = kpse.var_value('TEXMFDIST')
-end
-local BINDIR = kpse.var_value('SELFAUTOLOC')
-local PATH = os.getenv('PATH') or ''
-
--- list of programs that have -sys and -user variants
-local sys_user_progs = { 'updmap', 'fmtutil', 'kanji-config-updmap' }
-
--- restricted programs
-local shell_escape_commands = string.lower(kpse.var_value('shell_escape_commands') or '')
-local is_restricted_progname = string.find( ','..shell_escape_commands..',',
- ','..progname..',', 1, true)
-if is_restricted_progname then
- -- limit search path to the restricted (system) trees
- -- (not really necessary for entries in the alias_table,
- -- because they are not searched for with kpathsea)
- os.setenv('TEXMFSCRIPTS', kpse.var_value('TEXMF_RESTRICTED_SCRIPTS'))
-end
--- perl stuff
-local scripts4tlperl = {
- tlperl = true,
- updmap = true,
- fmtutil = true,
- ['updmap-sys'] = true,
- ['fmtutil-sys'] = true,
-}
-local try_extern_perl = (kpse.var_value('TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL') == '1') and
- not (guimode or is_restricted_progname or scripts4tlperl[progname])
-local PERLEXE = try_extern_perl and search_path('perl.exe', PATH)
-local extperl_warn
-if not PERLEXE then
- if try_extern_perl then extperl_warn = [[
-External Perl missing or outdated. Please install a recent Perl, or configure
-TeX Live to always use the builtin Perl:
- tlmgr conf texmf TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL 0
-Meanwhile, continuing with built-in Perl...
-]]
- end -- if try_extern_perl
- PERLEXE = TEXDIR..'/tlpkg/tlperl/bin/perl.exe'
- os.setenv('PERL5LIB', TEXDIR..'/tlpkg/tlperl/lib')
- PATH = prepend_path(PATH, TEXDIR..'/tlpkg/tlperl/bin')
- local PERLENV = 'PERL5OPT;PERLIO;PERLIO_DEBUG;PERLLIB;PERL5DB;PERL5DB_THREADED;' ..
- 'PERL5SHELL;PERL_ALLOW_NON_IFS_LSP;PERL_DEBUG_MSTATS;' ..
- 'PERL_DESTRUCT_LEVEL;PERL_DL_NONLAZY;PERL_ENCODING;PERL_HASH_SEED;' ..
- 'PERL_HASH_SEED_DEBUG;PERL_ROOT;PERL_SIGNALS;PERL_UNICODE'
- for var in string.gmatch(PERLENV, '[^;]+') do os.setenv(var, nil) end
-end
--- gs stuff
-local override_gs
-if not is_restricted_progname then
- override_gs = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS')
-end
--- the full path to the executable
-local GSEXE
--- the directory where the gs executable resides
-local GSDIR
--- the name of the gs executable
-local GSNAME
-if override_gs then
- -- first check whether we got an absolute path or only executable name
- if string.find(override_gs, '[/\\]') then
- GSEXE = override_gs
- else
- -- search in the path
- GSEXE = search_path(override_gs, PATH)
- end
-end
-if GSEXE then
- -- split the dir and progname part so that we can set the path
- -- work on a string with all forward slashes
- local foo = string.lower(string.gsub(GSEXE, '\\', '/'))
- GSNAME = string.gsub(foo, '^.*[\\/]', '')
- GSDIR = string.gsub(foo, '^(.*)[\\/].*$', '%1')
- -- search also for a GS_DLL setting
- -- we do not need to check for is_restricted_progname, since
- -- GSEXE is only defined when it is not set
- local GSDLL = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS_DLL')
- if GSDLL then
- os.setenv('GS_DLL', GSDLL)
- end
- local GSLIB = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS_LIB')
- if GSLIB then
- os.setenv('GS_LIB', GSLIB)
- end
-else
- -- use built in gs
- os.setenv('GS_LIB', TEXDIR..'/tlpkg/tlgs/lib;'
- ..TEXDIR..'/tlpkg/tlgs/fonts;'
- ..TEXDIR..'/tlpkg/tlgs/Resource/Init;'
- ..TEXDIR..'/tlpkg/tlgs/Resource;'
- ..TEXDIR..'/tlpkg/tlgs/kanji;'
- ..os.getenv('WINDIR')..'/Fonts;'..TEXMFDIST..'/fonts')
- os.setenv('GS_DLL', TEXDIR..'/tlpkg/tlgs/bin/gsdll32.dll')
- GSEXE = TEXDIR..'/tlpkg/tlgs/bin/gswin32c.exe'
- GSNAME = 'gswin32c.exe'
- GSDIR = TEXDIR..'/tlpkg/tlgs/bin'
-end
--- now setup the path so that the gs program will be found
-PATH = prepend_path(PATH, GSDIR, BINDIR)
-os.setenv('PATH', PATH);
-
--- sys stuff
-if (sysprog and not contains(sys_user_progs, progname)) then
- os.setenv('TEXMFVAR', kpse.var_value('TEXMFSYSVAR'))
- os.setenv('TEXMFCONFIG', kpse.var_value('TEXMFSYSCONFIG'))
-end
--- Adobe Reader crash case: make sure USERPROFILE is not "slashed"
-os.setenv("USERPROFILE", os.getenv("USERPROFILE"):gsub('/', '\\'))
-
--- extension to interpreter mapping
-
--- the extension is mapped to an argument table.
--- the command to execute is given as the first element of the table,
--- which can be a whitespace separated list of names to try.
-local extension_map = {
- ['.bat'] = {'cmd', '/c', 'call'},
- ['.jar'] = {'java.exe', '-jar'},
- ['.pl' ] = {'perl.exe'},
- ['.py' ] = {'python.exe'},
- ['.rb' ] = {'ruby.exe'},
- ['.tcl'] = {'tclsh.exe tclsh86.exe tclsh85.exe tclkitsh.exe'},
- ['.vbs'] = {'cscript.exe', '-nologo'},
-}
-if guimode then
- -- for GUI mode wrappers we try GUI mode interpeters where possible
- extension_map['.jar'][1] = 'javaw.exe ' .. extension_map['.jar'][1]
- extension_map['.pl' ][1] = 'wperl.exe ' .. extension_map['.pl' ][1]
- extension_map['.py' ][1] = 'pythonw.exe ' .. extension_map['.py' ][1]
- extension_map['.rb' ][1] = 'rubyw.exe ' .. extension_map['.rb' ][1]
- -- gui tcl shares no interpreters with non-gui tcl
- extension_map['.tcl'] = {'wish.exe wish86.exe wish85.exe tclkit.exe'}
- extension_map['.vbs'][1] = 'wscript.exe ' .. extension_map['.vbs'][1]
-end
-extension_map['.cmd'] = extension_map['.bat']
-extension_map['.js'] = extension_map['.vbs']
-
--- set up ARGV table
-
-local ARGV = nil
-
--- special cases (aliases)
-
-if is_tex4ht_command(progname) then
- argline = progname .. ' ' .. argline
- progname = 'mk4ht'
-elseif progname == 'a2ping' then
- table.insert(extension_map['.pl'], '-x')
-elseif contains(sys_user_progs, progname) then
- if sysprog then
- argline = ' --sys ' .. argline
- elseif userprog then
- argline = ' --user ' .. argline
- end
- -- do not guess input encoding in format creation for ptex
- -- and friends since guessing is not complete
- os.setenv('GUESS_INPUT_KANJI_ENCODING', '0')
-elseif progname == 'asy' then
- os.setenv('ASYMPTOTE_GS', GSEXE)
- os.setenv('CYGWIN', 'nodosfilewarning')
- if is_64bit_windows_os() then
- ARGV = {[0]=TEXDIR..'/tlpkg/asymptote64/asy.exe', 'asy'}
- else
- ARGV = {[0]=TEXDIR..'/tlpkg/asymptote/asy.exe', 'asy'}
- end
-elseif progname == 'dviout' then
- local fontsdir = kpse.var_value('TEXMFVAR') .. '/fonts'
- if (lfs.attributes(fontsdir, 'mode') ~= 'directory') then
- assert(mkdir_plus(fontsdir))
- end
- local tfmpath = kpse.show_path('tfm')
- tfmpath = string.gsub(tfmpath, '!!', '')
- tfmpath = string.gsub(tfmpath, '/', '\\')
- local texrt = {}
- for d in string.gmatch(tfmpath, '([^;]+\\fonts)\\tfm[^;]*') do
- if (lfs.attributes(d, 'mode') == 'directory') then
- table.insert(texrt, d)
- end
- end
- local par = [["-gen=']] .. string.gsub(TEXDIR, '/', '\\') ..
- [[\tlpkg\dviout\gen_pk'" "-TEXROOT=']] ..
- table.concat(texrt, ';') .. [['" "-gsx=']] .. GSEXE .. [['"]];
- ARGV = {[0]=TEXDIR..'/tlpkg/dviout/dviout.exe', 'dviout', par}
-elseif progname == 'mkluatexfontdb' then
- progname = 'luaotfload-tool'
- table.insert(arg, '--alias=mkluatexfontdb')
-elseif progname == 'psv' then
- argline = '-sINPUT='..argline
- ARGV = {[0]=TEXDIR..'/tlpkg/tlpsv/gswxlua.exe', 'gswxlua',
- '-dDisableFAPI=true',
- '-l', (_q(TEXDIR..'/tlpkg/tlpsv/psv.wx.lua'):gsub('/','\\')),
- '-p', (_q(TEXDIR..'/tlpkg/tlpsv/psv_view.ps'):gsub('/','\\')),
- '-i', '.'}
-elseif progname == 'repstopdf' or progname == 'rpdfcrop' then
- argline = '--restricted ' .. argline
- progname = string.sub(progname, 2, -1)
-elseif progname == 'texworks' then
- local winver = tonumber(string.match(os.uname().version, '%D*(%d+%.?%d*)'))
- assert(winver >= 5.01, "Windows XP or newer required to run TeXworks")
- local TW_LIBPATH = kpse.var_value('TW_LIBPATH') or
- kpse.var_value('TEXMFCONFIG')..'/texworks'
- local TW_INIPATH = kpse.var_value('TW_INIPATH') or TW_LIBPATH
- os.setenv('TW_LIBPATH', TW_LIBPATH)
- os.setenv('TW_INIPATH', TW_INIPATH)
- if (TW_INIPATH and lfs.attributes(TW_INIPATH, 'mode') ~= 'directory') then
- -- TeXworks needs directory holding its configuration to exist
- assert(mkdir_plus(TW_INIPATH))
- end
- ARGV = {[0]=TEXDIR..'/tlpkg/texworks/texworks.exe', 'texworks'}
-elseif progname == 'tlgs' then
- ARGV = {[0]=GSEXE, GSNAME}
-elseif progname == 'tlperl' then
- ARGV = {[0]=PERLEXE, 'perl'}
-elseif progname == 'latexdef' then
- progname = 'texdef'
- argline = ' --tex latex ' .. argline
-elseif progname == 'cllualatex' then
- progname = 'cluttex'
- argline = ' --engine=lualatex ' .. argline
-elseif progname == 'clxelatex' then
- progname = 'cluttex'
- argline = ' --engine=xelatex ' .. argline
-end
-
--- general case
-
-if not ARGV then
- os.setenv('TEXMF', TEXMFDIST)
- local extlist = '.tlu;.texlua;.pl;.lua;.rb;.py;.tcl;.jar;.vbs;.js;.bat;.cmd;\0'
- local progfullname = search_path(progname, BINDIR, '.tlu;.bat;.cmd') or
- find_texmfscript(progname, extlist)
- os.setenv('TEXMF', nil)
- if progfullname == nil then
- -- scripts in $TEXMFLOCAL etc. can't be found without the following
- -- line !!
- kpse.set_program_name('runscript')
- progfullname = assert(find_texmfscript(progname, extlist))
- end
- local ext = string.match(string.lower(progfullname), '%.[^\\/.]*$') or ''
- if (ext == '.lua') or (ext == '.tlu') or (ext == '.texlua') then -- lua script
- arg[0] = progfullname
- elseif (ext == '.tcl' and guimode) then -- tcl script; use built-in tclkit?
- local try_extern_tcl =
- (kpse.var_value('TEXLIVE_WINDOWS_TRY_EXTERNAL_TCL') == '1') and
- not is_restricted_progname
- local TCLEXENAME, TCLEXE
- if try_extern_tcl then
- TCLEXENAME, TCLEXE = check_command(extension_map['.tcl'][1], PATH)
- end
- if try_extern_tcl and not TCLEXENAME then
- local exttcl_warn = [[
-External Tcl missing or outdated. Please install a recent Tcl, or configure
-TeX Live to always use the builtin Tcl for gui scripts:
- tlmgr conf texmf TEXLIVE_WINDOWS_TRY_EXTERNAL_TCL 0
-Meanwhile, continuing with built-in Tcl...
-]]
- show_error(exttcl_warn)
- else -- did find something
- ARGV = {[0]=TCLEXE, TCLEXENAME}
- end
- if not TCLEXENAME then
- ARGV = {[0]=TEXDIR..'/tlpkg/tltcl/tclkit.exe', 'tclkit.exe'}
- PATH = prepend_path(PATH, TEXDIR:gsub('/','\\')..'\\tlpkg\\tltcl')
- end
- table.insert(ARGV, _q(progfullname:gsub('/','\\')))
- if (argline and argline ~= '') then argline = '-- '..argline end
- else -- not gui tcl or not tcl at all
- ARGV = extension_map[ext] or assert(shebang_to_argv(progfullname))
- -- [w|c]script, for one, mistakes a forward-slashed UNC script path
- -- for an option even when quoted
- table.insert(ARGV, _q(progfullname:gsub('/','\\')))
- if not ARGV[0] then
- ARGV[0], ARGV[1] = assert(check_command(ARGV[1], PATH))
- end
- end
-end
-
--- run the program/script
-
-if ARGV then
- table.insert(ARGV, argline) -- pass through original arguments
- if string.find (table.concat(ARGV, ' '), 'perl.exe') and extperl_warn then
-
- show_error(extperl_warn)
- end
- local ret = assert(os.spawn(ARGV))
- if ret ~= 0 then
- local dbginfo = debug.getinfo(1)
- local errormsg = string.format("%s:%d: command failed with exit code %d:\n%s",
- dbginfo.short_src, dbginfo.currentline - 2,
- ret, table.concat(ARGV, ' ') )
- show_error(errormsg)
- end
- os.exit(ret)
-else -- must be a lua script
- dofile(arg[0])
-end
-
-end -- MAIN_CHUNK
-
--- execute MAIN_CHUNK with pcall to catch any runtime errors
-
-local success, errormsg = pcall(MAIN_CHUNK)
-if not success then
- os.setenv('RUNSCRIPT_ERROR_MESSAGE', errormsg)
- error(errormsg)
-end
-
--- about RUNSCRIPT_ERROR_MESSAGE environment variable:
--- it stores an error message that is caught and displayed
--- in a message box on the C side at process exit
--- (currently used only by gui mode stubs)
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c b/Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c
deleted file mode 100644
index 588c84b95bc..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/************************************************************************
-
- This file is a part of the wrapper program for launching scripts
- and programs in TeX Live on Windows. See readme.txt for more details.
-
- This file was originally written in 2009 by Tomasz M. Trzeciak and
- was placed in the Public Domain.
-
-************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t'))
-#define MAX_MSG 2*MAX_PATH
-#define DIE(...) { _snprintf( msg_buf, MAX_MSG - 1, __VA_ARGS__ ); goto DIE; }
-
-char module_name[] = "runscript.dll";
-char script_name[] = "runscript.tlu";
-char texlua_name[] = "texlua"; // just a bare name, luatex strips the rest anyway
-char subsys_mode[] = "CUI_MODE\n";
-char err_env_var[] = "RUNSCRIPT_ERROR_MESSAGE";
-char msg_buf[MAX_MSG];
-
-
-__declspec(dllexport) int dllrunscript( int argc, char *argv[] )
-{
- static char own_path[MAX_PATH];
- static char fpath[MAX_PATH];
- char *fname, *argline, **lua_argv;
- char *quoted_argline;
- int k, quoted, lua_argc;
- HMODULE module_handle = NULL;
-
- // file path of the executable
- k = (int) GetModuleFileName(NULL, own_path, MAX_PATH);
- if ( !k || (k == MAX_PATH) )
- DIE("cannot get own path (may be too long): %s\n", own_path);
-
- // script path (the dir of this library)
- module_handle = GetModuleHandle(module_name);
- // if ( module_handle == NULL ) exe path will be used, which is OK too
- k = (int) GetModuleFileName(module_handle, fpath, MAX_PATH);
- if ( !k || (k == MAX_PATH) )
- DIE("cannot get module path (may be too long): %s\n", fpath);
- fname = strrchr(fpath, '\\');
- if ( fname == NULL ) DIE("no directory part in module path: %s\n", fpath);
- fname++;
- if ( fname + strlen(script_name) >= fpath + MAX_PATH - 1 )
- DIE("path too long: %s\n", fpath);
- strcpy(fname, script_name);
- if ( GetFileAttributes(fpath) == INVALID_FILE_ATTRIBUTES )
- DIE("main lua script not found: %s\n", fpath);
-
- // get command line of this process
- argline = GetCommandLine();
-
- if ( argline == NULL ) DIE("failed to retrieve command line string\n");
- quoted_argline = malloc((1+strlen(argline)+1 + 1)*sizeof(char));
- if ( quoted_argline == NULL ) DIE("failed to quote command line string\n");
- // skip over argv[0] (it can contain embedded double quotes if launched from cmd.exe!)
- for ( quoted = 0; (*argline) && ( !IS_WHITESPACE(*argline) || quoted ); argline++ )
- if ( *argline == '"' ) quoted = !quoted;
- while ( IS_WHITESPACE(*argline) ) argline++; // remove leading whitespace if any
- // we need to quote our string , it seems.
- snprintf(quoted_argline, (size_t)(1+strlen(argline)+1 + 1), "\"%s\"", argline);
-
- // set up argument list for texlua script
- lua_argv = (char **)malloc( (argc + 6) * sizeof(char *) );
- lua_argv[lua_argc=0] = texlua_name;
- lua_argv[++lua_argc] = fpath; // script to execute
- for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k]; // copy argument list
- lua_argv[++lua_argc] = subsys_mode; // sentinel argument
- lua_argv[++lua_argc] = argc ? argv[0] : own_path; // original argv[0]
- //lua_argv[++lua_argc] = argline; // unparsed arguments
- lua_argv[++lua_argc] = quoted_argline; // unparsed arguments
- lua_argv[++lua_argc] = NULL;
-
- // call texlua interpreter
- // for(int j=0; j<lua_argc; j++){printf("lua_argv[%d]=%s\n",j,lua_argv[j]);}
- k = _spawnvp(_P_WAIT, "texlua", (const char * const *)lua_argv);
- if (lua_argv) free(lua_argv);
- return k;
-
-DIE:
- fprintf(stderr, "%s: ", module_name);
- fprintf(stderr, msg_buf);
- if (*subsys_mode == 'G')
- MessageBox( NULL, msg_buf, module_name, MB_ICONERROR | MB_SETFOREGROUND );
- return 1;
-}
-
-void finalize( void )
-{
- // check for and display error message if any
- char *err_msg;
- if ( err_msg = (char *) getenv(err_env_var) )
- MessageBox( NULL, err_msg, script_name, MB_ICONERROR | MB_SETFOREGROUND );
-}
-
-__declspec(dllexport) int dllwrunscript(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- char *argline,
- int winshow
-) {
- // set sentinel argument (G for GUI_MODE)
- *subsys_mode = 'G';
- // clear error var in case it exists already
- SetEnvironmentVariable(err_env_var, NULL);
- // register atexit handler to recover control before terminating
- atexit( finalize );
- // call the console entry point routine
-#if defined(__MSVCRT__) && !defined(__MINGW32__)
- // WinMain doesn't provide argc & argv, call MSVCRT proc to get them
- int argc = 0;
- char **argv, **env;
- int expand_wildcards = 0;
- int new_mode;
- __getmainargs(&argc, &argv, &env, expand_wildcards, &new_mode);
- return dllrunscript( argc, argv );
-#else
- return dllrunscript( 0, NULL );
-#endif
-}
-
-
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript_exe.c b/Build/source/texk/texlive/w64_mingw_wrapper/runscript_exe.c
deleted file mode 100644
index 29d04a93a43..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/runscript_exe.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/************************************************************************
-
- This file is a part of the wrapper program for launching scripts
- and programs in TeX Live on Windows. See readme.txt for more details.
-
- This file was originally written in 2009 by Tomasz M. Trzeciak and
- was placed in the Public Domain.
-
-************************************************************************/
-
-#include <windows.h>
-
-__declspec(dllimport) int dllrunscript( int argc, char *argv[] );
-
-int main( int argc, char *argv[] ) { return dllrunscript( argc, argv ); }
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/texlua.dll b/Build/source/texk/texlive/w64_mingw_wrapper/texlua.dll
deleted file mode 100755
index 0a4d2e638bf..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/texlua.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/texlua.exe b/Build/source/texk/texlive/w64_mingw_wrapper/texlua.exe
deleted file mode 100755
index daf7cd29ecb..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/texlua.exe
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c b/Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c
deleted file mode 100644
index fe65d54515a..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
-
-Simple tray menu
-
-Originally written in 2011 by Tomasz M. Trzeciak, Public Domain
-
-compiling with gcc (size optimized):
-echo 1 ICON "tl-tray-menu.ico">tl-tray-menu.rc
-windres tl-tray-menu.rc tl-tray-menu-rc.o
-gcc -Os -s -mwindows -o tl-tray-menu.exe tl-tray-menu-rc.o tl-tray-menu.c
-
-*/
-
-#define _WIN32_IE 0X0500 // minimum support for tray baloon (IE5)
-
-#include <windows.h>
-#include <process.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define MAX_STR 32768
-
-static char strBuf[MAX_STR];
-
-#define DIE(...) { \
- _snprintf( strBuf, 4*MAX_PATH, __VA_ARGS__ ); \
- MessageBox( NULL, strBuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\
- return 1; \
-}
-
-#define IDI_ICON 1 // resource number of icon
-#define IDI_TRAY 100
-#define WM_TRAYMSG 101
-
-#define MAX_MENU_ENTRIES 31
-#define MENU_CONFIG ( MAX_MENU_ENTRIES + 1 )
-#define MENU_EXIT ( MAX_MENU_ENTRIES + 2 )
-
-// buffer holding menu labels and commands
-// (used only with config file)
-static char menuStrings[MAX_STR];
-
-// default menu labels
-char *menuLabels[MAX_MENU_ENTRIES] = {
-"&Package Manager",
-"&Documentation",
-"&Editor",
-"PostScript/PDF &Viewer",
-"&Command Prompt",
-NULL };
-
-// default menu commands
-char *menuCommands[MAX_MENU_ENTRIES] = {
-"bin\\win32\\tlmgr-gui.exe",
-"bin\\win32\\texdoctk.exe",
-"bin\\win32\\texworks.exe",
-"bin\\win32\\psv.exe",
-"tlpkg\\installer\\tl-cmd.bat",
-NULL };
-
-char configInfo[4*MAX_PATH] = "\
-The menu can be customized with a configuration file.\n\
-For an example and instructions see:\n";
-
-HMENU hPopMenu;
-NOTIFYICONDATA nid;
-
-LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
-{
- switch ( msg )
- {
- case WM_CREATE:
- {
- hPopMenu = CreatePopupMenu();
- int i;
- for ( i = 0; menuLabels[i]; i++ )
- {
- if ( menuCommands[i] )
- AppendMenu( hPopMenu, MF_STRING, i, menuLabels[i] );
- }
- AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
- AppendMenu( hPopMenu, MF_STRING, MENU_CONFIG, "More..." );
- AppendMenu( hPopMenu, MF_STRING, MENU_EXIT, "E&xit" );
- }
- break;
-
- case WM_TRAYMSG:
- {
- switch ( lParam )
- {
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- {
- POINT pnt;
- GetCursorPos( &pnt );
- SetForegroundWindow( hWnd ); // needed to get keyboard focus
- TrackPopupMenu( hPopMenu, TPM_LEFTALIGN, pnt.x, pnt.y, 0, hWnd, NULL );
- }
- break;
- }
- }
- break;
-
- case WM_COMMAND:
- {
- switch ( LOWORD( wParam ) )
- {
- case MENU_CONFIG:
- MessageBox( NULL, configInfo, nid.szTip, MB_SETFOREGROUND );
- break;
-
- case MENU_EXIT:
- Shell_NotifyIcon( NIM_DELETE, &nid );
- ExitProcess(0);
- break;
-
- default:
- {
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- //si.dwFlags = STARTF_USESHOWWINDOW;
- //si.wShowWindow = SW_HIDE ;
- ZeroMemory( &pi, sizeof(pi) );
- if( !CreateProcess(
- NULL, // module name (uses command line if NULL)
- menuCommands[LOWORD(wParam)], // command line
- NULL, // process security atrributes
- NULL, // thread security atrributes
- TRUE, // handle inheritance
- 0, // creation flags, e.g. CREATE_NO_WINDOW, DETACHED_PROCESS
- NULL, // pointer to environment block (uses parent if NULL)
- NULL, // starting directory (uses parent if NULL)
- &si, // STARTUPINFO structure
- &pi ) // PROCESS_INFORMATION structure
- ) DIE( "Failed to spawn command (error code %d):\n%s",
- GetLastError(), menuCommands[LOWORD(wParam)] );
- }
- }
- }
- break;
-
- default:
- return DefWindowProc( hWnd, msg, wParam, lParam );
-
- }
-
- return 0;
-}
-
-int APIENTRY WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow )
-{
-
- // scratch variables
-
- char *s;
-
- // get file name of this executable
-
- static char dirSelf[MAX_PATH];
- DWORD nchars = GetModuleFileName(NULL, dirSelf, MAX_PATH);
- if ( !nchars || ( nchars == MAX_PATH ) ) DIE( "Cannot get own path." );
- if ( s = strrchr( dirSelf, '\\' ) ) *s = '\0'; // remove file name part
-
- // set current directory
-
- if ( !SetCurrentDirectory( dirSelf ) )
- DIE( "Failed to change current directory to:\n%s", dirSelf );
-
- // prepend bin/win32 to PATH
-
- strcpy( strBuf, dirSelf );
- strcat( strBuf, "\\bin\\win32;" );
- strcat( strBuf, getenv( "PATH" ) );
- SetEnvironmentVariable( "PATH", strBuf );
-
- // configuration
-
- static char fileConfig[MAX_PATH];
- s = dirSelf + strlen(dirSelf) + 1;
- strcpy( fileConfig, s );
- if ( s = strrchr( fileConfig, '.' ) ) *s = '\0'; // remove file extension part
- strcat( fileConfig, ".ini" );
-
- strcat( configInfo, dirSelf );
- strcat( configInfo, "\\tlpkg\\installer\\" );
- strcat( configInfo, fileConfig );
-
- if ( GetFileAttributes( fileConfig ) == INVALID_FILE_ATTRIBUTES ) {
-
- // validate default configuration (menuCommands should be existing files)
-
- int i;
- for ( i = 0; menuLabels[i]; i++ )
- if ( GetFileAttributes( menuCommands[i] ) == INVALID_FILE_ATTRIBUTES )
- menuCommands[i] = NULL;
-
- } else {
-
- // read menu configuration from ini file
-
- FILE *CONFIG = fopen( fileConfig, "rt" );
- if ( CONFIG == NULL )
- DIE( "Failed to open configuration file:\n%s\\%s", dirSelf, fileConfig );
-
- char strSect[] = "[menu]";
- int menuItem = -1;
- int i = 0;
- int lineNo;
- for ( lineNo = 1 ; fgets( strBuf, MAX_STR, CONFIG )
- && menuItem < MAX_MENU_ENTRIES ; lineNo++ )
- {
- if ( menuItem < 0 )
- {
- if ( *strBuf == '[' &&
- strncmp( strBuf, strSect, strlen( strSect ) ) == 0 ) menuItem++;
- continue;
- }
- if ( *strBuf == ';' ) continue; // skip comments
- if ( *strBuf == '[' ) break; // next section
- s = &menuStrings[i];
- i += ExpandEnvironmentStrings( strBuf, s, MAX_STR - i );
- if ( i >= MAX_STR )
- DIE( "Exceeded 32KB limit for configuration." );
- if ( i-2 && menuStrings[i-2] == '\n' ) { menuStrings[i-2] = '\0'; i--; }
- menuLabels[menuItem] = s;
- while ( *s && *s != '=' ) s++;
- if ( *s == '\0' )
- DIE( "Missing '=' on line %d in configuration file:\n%s\\%s",
- lineNo, dirSelf, fileConfig );
- *s++ = '\0'; // assign first, then increment
- menuCommands[menuItem] = s;
- menuItem++;
- }
- if ( menuItem < 0 )
- DIE( "Missing [menu] section in configuration file:\n%s\\%s",
- dirSelf, fileConfig );
- menuLabels[menuItem] = NULL;
- menuCommands[menuItem] = NULL;
-
- fclose( CONFIG );
-
- }
-
- // create a hidden window for messaging
-
- MSG msg;
- WNDCLASS wc;
- HWND hWnd;
- char szAppName[] = "TrayMenu";
-
- ZeroMemory( &wc, sizeof wc );
- wc.hInstance = hInstance;
- wc.lpszClassName = szAppName;
- wc.lpfnWndProc = (WNDPROC)WndProc;
- wc.style = 0;
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
-
- if ( FALSE == RegisterClass( &wc ) ) DIE( "Failed to register window class" );
-
- hWnd = CreateWindow(
- szAppName,
- "",
- 0,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- 0,
- 0,
- hInstance,
- 0);
-
- if ( hWnd == NULL ) DIE( "Failed to create window" );
-
- // tray icon stuff
-
- nid.cbSize = sizeof nid;
- nid.hWnd = hWnd;
- nid.uID = IDI_TRAY;
- nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
- nid.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON ) );
- nid.uCallbackMessage = WM_TRAYMSG;
- strcpy( nid.szTip, "TeX Live Menu" );
-#if (_WIN32_IE >= 0X0500)
- nid.uFlags |= NIF_INFO;
- nid.dwInfoFlags = NIIF_INFO;
- strcpy( nid.szInfo, "Click on the tray icon\nto activate the menu." );
- strcpy( nid.szInfoTitle, nid.szTip );
-#endif
- Shell_NotifyIcon( NIM_ADD, &nid );
-
- // main message loop:
-
- while ( GetMessage( &msg, NULL, 0, 0 ) > 0 )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
-
- return msg.wParam;
-}
-
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt
deleted file mode 100644
index 559d97ed3f2..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-
-Launcher stub for tlmgr gui (with hidden console window)
-
-//////////////////////////////////////////////////
-
-This version has been replaced with a version which triggers a UAC
-prompt when appropriate. See Master/source/tlmgr-gui_UAC.zip.
-
-//////////////////////////////////////////////////
-
-Originally written in 2011 by Tomasz M. Trzeciak, Public Domain
-
-compiling with gcc (size optimized):
-echo 1 ICON "tlmgr-gui.ico">tlmgr-gui.rc
-windres tlmgr-gui.rc tlmgr-gui-rc.o
-gcc -Os -s -mwindows -o tlmgr-gui.exe tlmgr-gui-rc.o tlmgr-gui.c
-
-compiling with tcc (ver. 0.9.25), extra small size
-windres tlmgr-gui.rc tlmgr-gui-rc.o
-tcc -o tlmgr-gui.exe tlmgr-gui-rc.o tlmgr-gui.c
-
-*/
-
-#include <windows.h>
-
-static char msgbuf[4*MAX_PATH];
-#define DIE(...) { \
- _snprintf( msgbuf, 4*MAX_PATH, __VA_ARGS__ ); \
- MessageBox( NULL, msgbuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\
- return 1; \
-}
-
-static char cmdln[2*MAX_PATH];
-
-int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShowint ) {
-
- // get file name of this executable
-
- static char selfdir[MAX_PATH];
- char *name, *ext, *s;
- DWORD nchars = GetModuleFileName(NULL, selfdir, MAX_PATH);
- if ( !nchars || (nchars == MAX_PATH) ) DIE( "cannot get own path" );
-
- // make command to execute
-
- if ( s = strrchr(selfdir, '\\') ) *s = '\0'; // remove file name part
- strcat( cmdln, "\"" );
- strcat( cmdln, selfdir );
- strcat( cmdln, "\\tlmgr.bat\" -gui" );
-
- // create child process
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE ;
- ZeroMemory( &pi, sizeof(pi) );
-
- if( !CreateProcess(
- NULL, // module name (uses command line if NULL)
- cmdln, // command line
- NULL, // process security atrributes
- NULL, // thread security atrributes
- TRUE, // handle inheritance
- 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS
- NULL, // pointer to environment block (uses parent if NULL)
- NULL, // starting directory (uses parent if NULL)
- &si, // STARTUPINFO structure
- &pi ) // PROCESS_INFORMATION structure
- ) DIE( "command execution failed: %s", cmdln );
-
- return 0;
-
-}
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.ico b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.ico
deleted file mode 100644
index 6f0c37f54e0..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.ico
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg
deleted file mode 100644
index 6e60a8f273c..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg
+++ /dev/null
@@ -1,245 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 10.0.3, SVG Export Plug-In . SVG Version: 3.0.0 Build 77) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="270"
- height="270"
- viewBox="0 0 270.00001 270"
- style="display:inline;overflow:visible"
- xml:space="preserve"
- id="svg2816"
- version="1.1"
- inkscape:version="0.48.1 r9760"
- sodipodi:docname="tlmgr.svg"><metadata
- id="metadata2851"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
- id="defs2849"><linearGradient
- id="linearGradient5749"><stop
- id="stop5751"
- offset="0"
- style="stop-color:#c8bb2c;stop-opacity:1" /><stop
- id="stop5753"
- offset="0.42938474"
- style="stop-color:#c8ab37;stop-opacity:1" /><stop
- id="stop5755"
- offset="1"
- style="stop-color:#786721;stop-opacity:1" /></linearGradient><linearGradient
- id="linearGradient5739"><stop
- style="stop-color:#33b850;stop-opacity:1;"
- offset="0"
- id="stop5741" /><stop
- id="stop5747"
- offset="0.5"
- style="stop-color:#c8ab37;stop-opacity:0.49803922;" /><stop
- style="stop-color:#c8ab37;stop-opacity:0"
- offset="1"
- id="stop5743" /></linearGradient><linearGradient
- id="linearGradient4223"><stop
- id="stop3656"
- offset="0"
- style="stop-color:#6a5c22;stop-opacity:1;" /><stop
- id="stop3654"
- offset="0.70769727"
- style="stop-color:#c8ab37;stop-opacity:1" /><stop
- style="stop-color:#dac15a;stop-opacity:1;"
- offset="1"
- id="stop4227" /></linearGradient><linearGradient
- inkscape:collect="always"
- id="linearGradient4215"><stop
- style="stop-color:#786721;stop-opacity:1;"
- offset="0"
- id="stop4217" /><stop
- style="stop-color:#786721;stop-opacity:0;"
- offset="1"
- id="stop4219" /></linearGradient><linearGradient
- id="linearGradient3682"><stop
- style="stop-color:#f1e671;stop-opacity:1;"
- offset="0"
- id="stop4231" /><stop
- style="stop-color:#c8ab37;stop-opacity:1"
- offset="0.66298664"
- id="stop4213" /><stop
- style="stop-color:#786721;stop-opacity:1"
- offset="1"
- id="stop3686" /></linearGradient><inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 114.031 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="248.47099 : 114.031 : 1"
- inkscape:persp3d-origin="124.2355 : 76.020665 : 1"
- id="perspective2853" /><inkscape:perspective
- id="perspective2856"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" /><inkscape:perspective
- id="perspective2997"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" /><radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3682"
- id="radialGradient3688"
- cx="59.357792"
- cy="136.64711"
- fx="59.357792"
- fy="136.64711"
- r="113.49914"
- gradientTransform="matrix(1.3152342,0.04522208,-0.04703422,1.3679372,-5.8498181,-59.579928)"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4215"
- id="linearGradient4221"
- x1="180.77203"
- y1="71.763046"
- x2="199.85242"
- y2="97.362198"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0809402,0,0,1.0204074,-3.223564,-12.087424)" /><radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4223"
- id="radialGradient3652"
- cx="44.960342"
- cy="223.34352"
- fx="44.960342"
- fy="223.34352"
- r="55.639721"
- gradientTransform="matrix(1.4022312,0.35120986,-0.153588,0.61321069,30.002569,-17.284415)"
- gradientUnits="userSpaceOnUse" /><inkscape:perspective
- id="perspective3667"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" /><linearGradient
- id="linearGradient3682-0"><stop
- style="stop-color:#f1e671;stop-opacity:1;"
- offset="0"
- id="stop4231-6" /><stop
- style="stop-color:#c8ab37;stop-opacity:1"
- offset="0.66298664"
- id="stop4213-1" /><stop
- style="stop-color:#786721;stop-opacity:1"
- offset="1"
- id="stop3686-5" /></linearGradient><linearGradient
- id="linearGradient4223-6"><stop
- id="stop3656-9"
- offset="0"
- style="stop-color:#6a5c22;stop-opacity:1;" /><stop
- id="stop3654-3"
- offset="0.70769727"
- style="stop-color:#c8ab37;stop-opacity:1" /><stop
- style="stop-color:#dac15a;stop-opacity:1;"
- offset="1"
- id="stop4227-7" /></linearGradient><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5749"
- id="linearGradient5745"
- x1="106.28487"
- y1="31.718859"
- x2="125.58268"
- y2="20.102272"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.98036388,-0.19719702,0.19719702,0.98036388,-4.0195208,24.162963)" /></defs><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1096"
- inkscape:window-height="908"
- id="namedview2847"
- showgrid="false"
- inkscape:zoom="2.6219511"
- inkscape:cx="133.1416"
- inkscape:cy="126.24304"
- inkscape:window-x="474"
- inkscape:window-y="50"
- inkscape:window-maximized="0"
- inkscape:current-layer="g2910"
- inkscape:object-nodes="true"
- inkscape:snap-global="false" />
-
-<g
- inkscape:groupmode="layer"
- id="layer1"
- inkscape:label="red"
- transform="translate(0,41.938005)"><path
- sodipodi:type="arc"
- style="fill:#b3faec;fill-opacity:1;stroke:none"
- id="path3763"
- sodipodi:cx="137.88635"
- sodipodi:cy="123.53212"
- sodipodi:rx="101.42695"
- sodipodi:ry="101.42695"
- d="m 239.3133,123.53212 c 0,56.01656 -45.41039,101.42695 -101.42695,101.42695 -56.016554,0 -101.426946,-45.41039 -101.426946,-101.42695 0,-56.016557 45.410392,-101.426949 101.426946,-101.426949 56.01656,0 101.42695,45.410392 101.42695,101.426949 z"
- transform="matrix(0.99808795,0,0,0.99808795,18.430079,-34.438385)" /></g><g
- style="display:inline"
- inkscape:label="New"
- id="g2910"
- inkscape:groupmode="layer"
- transform="translate(0,41.938005)"><path
- id="path2952"
- style="fill:#00612b;fill-opacity:1"
- d="m 200.81661,54.986631 c -3.64879,2.893622 -10.27939,-2.561778 -14.8154,-12.182166 -4.53602,-9.620387 -5.25062,-19.762511 -1.60288,-22.654025 3.64936,-2.890703 10.2794,2.561778 14.81703,12.182977 4.53497,9.622496 5.24956,19.764615 1.60125,22.653214 z"
- inkscape:connector-curvature="0" /><path
- id="path2950"
- style="fill:#00612b;fill-opacity:1"
- d="m 153.95812,24.495879 c -1.18398,8.821918 -6.30211,15.415312 -11.43224,14.7268 -5.1285,-0.688295 -8.32837,-8.400188 -7.14467,-17.219999 1.1837,-8.81981 6.30346,-15.412986 11.43196,-14.724692 5.13012,0.688514 8.32865,8.398081 7.14495,17.217891 z"
- inkscape:connector-curvature="0" /><path
- id="path2920"
- style="fill:url(#linearGradient5745);fill-opacity:1"
- d="m 113.89971,44.482838 c -9.42833,-5.583098 -10.97803,-16.545947 -8.95458,-25.701693 10.78651,-1.879166 15.62267,0.417141 22.40109,4.811931 4.62503,5.334319 8.89665,21.164927 8.89665,21.164927 0,0 -12.91818,5.304769 -22.34316,-0.275165 z"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" /><g
- id="g2914"
- transform="translate(9.9926697,-9.9615949)" /><path
- id="path2932"
- style="fill:#ffffff;fill-opacity:1"
- d="m 129.71368,59.616405 c 0,11.815 -9.941,21.394 -22.20501,21.394 -12.265,0 -22.206,-9.578 -22.206,-21.394 0,-11.816 9.941,-21.393 22.206,-21.393 12.26301,10e-4 22.20501,9.578 22.20501,21.393 z" /><path
- id="path2936"
- d="m 119.60176,60.722511 c 0,6.584565 -5.33607,11.922075 -11.92207,11.922075 -6.58457,0 -11.920639,-5.33751 -11.920639,-11.922075 0,-6.583123 5.336069,-11.919189 11.920639,-11.919189 6.586,0 11.92207,5.336066 11.92207,11.919189 z" /><path
- id="path2938"
- style="fill:url(#radialGradient3688);fill-opacity:1"
- d="m 20.248693,126.38723 c -4.875,13.539 16.851977,38.11817 32.067977,43.40217 -1.406,13.13 18.633,35.877 28.653,41.022 0.271,-6.771 1.083,-12.186 4.062,-16.519 21.935,15.436 36.82901,17.061 53.66101,21.721 -10.862,-3.007 -10.008,-16.379 -15.479,-23.616 23.614,0.197 35.204,12.728 69.596,14.623 l -12.998,-17.331 c 14.352,3.521 34.933,2.708 43.057,4.874 -4.333,-13.811 -3.521,-41.433 -6.77,-55.784 l 18.414,3.52 c -9.749,-17.602 1.103,-75.441995 -43.87,-95.591995 -2.883,-2.148 -12.252,-5.109 -23.536,-6.479 1.331,-3.271 5.393,-2.458 7.289,-5.707 -22.206,-13.54 -53.6787,5.024694 -62.67916,27.983771 C 90.500287,59.627637 62.753824,68.608484 49.688055,76.479943 24.650591,75.107481 -8.7789229,95.442386 20.248693,126.38723 z"
- sodipodi:nodetypes="ccccscccccccccccc" /><path
- id="path2942"
- style="fill:#c8ab37"
- d="m 209.64295,79.922477 c -10.45927,8.654008 -27.04449,11.508862 -32.31327,5.958928 -5.729,-7.866 -0.576,-22.424 12.321,-31.361 11.012,-7.632 23.739,-8.173 33.089,-2.856 0,0 -0.56773,18.814072 -13.09673,28.258072 z"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" /><path
- id="path2944"
- style="fill:#ffffff;fill-opacity:1"
- d="m 161.14537,72.186106 c 0,14.031212 -12.05212,25.405391 -26.91875,25.405391 -14.86662,0 -26.91764,-11.374179 -26.91764,-25.405391 0,-14.030094 12.05102,-25.405393 26.91764,-25.405393 14.86663,0 26.91875,11.374182 26.91875,25.405393 z"
- inkscape:connector-curvature="0" /><path
- id="path2948"
- d="m 152.13337,81.364785 c 0,7.213238 -5.84788,13.062625 -13.06111,13.062625 -7.21172,0 -13.0596,-5.849387 -13.0596,-13.062625 0,-7.210206 5.84788,-13.061111 13.0596,-13.061111 7.21172,0 13.06111,5.847874 13.06111,13.061111 z"
- inkscape:connector-curvature="0" /><path
- style="fill:url(#linearGradient4221);fill-opacity:1;stroke:none"
- d="m 176.24831,85.215715 c 3.96315,-12.290584 9.03724,-17.823025 17.89563,-24.272687 8.8584,-6.449663 21.66306,-9.307376 28.22124,-9.202043 0.9601,6.584307 -4.34708,25.269778 -16.81208,31.477156 -12.465,6.207378 -22.71034,7.847933 -29.30479,1.997574 z"
- id="path2905"
- sodipodi:nodetypes="csczc"
- inkscape:connector-curvature="0" /><path
- style="fill:#786721;fill-opacity:1;stroke:none"
- d="m 48.005001,111.71852 c -2.949904,3.53909 -16.95113,7.33888 -20.126512,4.65943 -2.992792,-2.5254 -7.802482,-14.27033 -5.418417,-18.576378 2.384068,-4.30606 10.357411,-5.39957 17.411449,-1.5565 7.054037,3.843048 11.083384,11.934348 8.13348,15.473448 z"
- id="path2907"
- sodipodi:nodetypes="czzsz" /><path
- style="fill:url(#radialGradient3652);fill-opacity:1;stroke:none;display:inline;overflow:visible"
- d="m 120.72419,134.27017 c 4.7296,4.0489 -17.95314,35.05629 -26.638897,26.20018 -22.634334,14.42744 -49.517528,17.54845 -70.511913,-17.46598 -3.196841,-2.19714 -2.880626,-8.47284 -6.330991,-11.78012 -4.712545,-5.28371 -5.115009,-9.41834 -5.948895,-17.41712 3.637076,7.79459 9.056496,10.69899 14.761583,14.12161 31.651372,43.90812 56.905665,23.7243 64.676686,20.10385 16.608687,12.57492 27.313777,-16.37878 29.992427,-13.76242 z"
- id="path2986"
- sodipodi:nodetypes="cccccccc" /></g></svg> \ No newline at end of file
diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c b/Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c
deleted file mode 100644
index 573501ae757..00000000000
--- a/Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/************************************************************************
-
- This file is a part of the wrapper program for launching scripts
- and programs in TeX Live on Windows. See readme.txt for more details.
-
- This file was originally written in 2009 by Tomasz M. Trzeciak and
- was placed in the Public Domain.
-
-************************************************************************/
-
-#include <windows.h>
-
-__declspec(dllimport) int dllwrunscript(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- char *argline,
- int winshow
- );
-
-int APIENTRY WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- char *argline,
- int winshow
-){
- return dllwrunscript( hInstance, hPrevInstance, argline, winshow );
-}
diff --git a/Build/source/texk/texlive/w64_wrapper/context/mtxrun.dll b/Build/source/texk/texlive/w64_wrapper/context/mtxrun.dll
deleted file mode 100755
index 91050273583..00000000000
--- a/Build/source/texk/texlive/w64_wrapper/context/mtxrun.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_wrapper/context/mtxrun.exe b/Build/source/texk/texlive/w64_wrapper/context/mtxrun.exe
deleted file mode 100755
index 93290a6e0a8..00000000000
--- a/Build/source/texk/texlive/w64_wrapper/context/mtxrun.exe
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_wrapper/runscript.dll b/Build/source/texk/texlive/w64_wrapper/runscript.dll
deleted file mode 100755
index 2294fb59591..00000000000
--- a/Build/source/texk/texlive/w64_wrapper/runscript.dll
+++ /dev/null
Binary files differ
diff --git a/Build/source/texk/texlive/w64_wrapper/runscript.exe b/Build/source/texk/texlive/w64_wrapper/runscript.exe
deleted file mode 100755
index baa241d679c..00000000000
--- a/Build/source/texk/texlive/w64_wrapper/runscript.exe
+++ /dev/null
Binary files differ