summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiep Kroonenberg <siepo@cybercomm.nl>2023-12-13 10:01:49 +0000
committerSiep Kroonenberg <siepo@cybercomm.nl>2023-12-13 10:01:49 +0000
commit88cdfb91453e609121eaa91ebeeff5f080a185ab (patch)
treefac3df72cb6adfca4ebcfbb29ce791b9598d0c63
parentf84e1a4bb9038eb64830d3e23edf63f7695810c8 (diff)
context-legacy
git-svn-id: svn://tug.org/texlive/trunk@69109 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/ctxtools.html64
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man75
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/ctxtools.xml31
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.html55
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man48
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.xml22
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pdftools.html55
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pdftools.man48
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pdftools.xml22
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pstopdf.html49
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man30
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/pstopdf.xml16
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/rlxtools.html49
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man30
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/rlxtools.xml16
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texexec.html63
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texexec.man72
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texexec.xml30
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texmfstart.html102
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man153
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texmfstart.xml80
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/textools.html63
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/textools.man72
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/textools.xml30
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texutil.html54
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texutil.man45
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/texutil.xml21
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/tmftools.html50
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/tmftools.man30
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/tmftools.xml18
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/xmltools.html54
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/xmltools.man45
-rw-r--r--Master/texmf-dist/doc/context/scripts/mkii/xmltools.xml21
-rw-r--r--Master/texmf-dist/doc/man/man1/luatools.178
-rw-r--r--Master/texmf-dist/doc/man/man1/luatools.man1.pdfbin0 -> 18048 bytes
-rw-r--r--Master/texmf-dist/doc/man/man1/texmfstart.1153
-rw-r--r--Master/texmf-dist/doc/man/man1/texmfstart.man1.pdfbin0 -> 19982 bytes
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/cmin.enc258
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/cmit.enc258
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/cmitt.enc258
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/cmrm.enc258
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/cmsc.enc258
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/cmtt.enc258
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/ec-2004.enc82
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/q-8r.enc264
-rw-r--r--Master/texmf-dist/fonts/enc/dvips/context/teff-trinite.enc260
-rw-r--r--Master/texmf-dist/fonts/map/dvips/context/contnav.map1
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/8r-base.map135
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/ec-base.map135
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/ec-os-public-lm.map69
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/mkiv-base.map224
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/mkiv-px.map51
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/mkiv-tx.map94
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-adobe-euro.map25
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-ams-base.map47
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-ams-cmr.map97
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-ams-euler.map25
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-base.map62
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-context-symbol.map3
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-dummy.map1
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-empty.map4
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-micropress-informal.map7
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-public-csr.map56
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-public-lm.map182
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-public-plr.map77
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-public-vnr.map59
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-vogel-symbol.map2
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-wasy.map7
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-px.map51
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-tx.map94
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/qx-base.map55
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/qx-os-public-lm.map69
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/t5-base.map72
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/t5-os-public-lm.map69
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/texnansi-base.map142
-rw-r--r--Master/texmf-dist/fonts/map/pdftex/context/texnansi-os-public-lm.map69
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/metafun.mpii65
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-back.mpii205
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-base.mpii598
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-butt.mpii77
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-char.mpii1006
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-core.mpii1418
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-figs.mpii47
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-fobg.mpii87
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-form.mpii392
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-func.mpii58
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-grid.mpii149
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-grph.mpii310
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-page.mpii659
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-shap.mpii206
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-spec.mpii782
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-step.mpii317
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-symb.mpii351
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-text.mpii274
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii2819
-rw-r--r--Master/texmf-dist/metapost/context/base/mpii/mp-txts.mpii66
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/ctx.rb462
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/exa.rb407
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/file.rb150
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpse.rb399
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpse/drb.rb57
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpse/soap.rb79
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpse/trees.rb84
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpsedirect.rb34
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpsefast.rb934
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpseremote.rb116
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/kpserunner.rb87
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/logger.rb105
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/merge.rb139
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/mp.rb167
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/pdf.rb83
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/state.rb75
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/switch.rb637
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/system.rb121
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/tex.rb2182
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/texutil.rb1097
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/tool.rb291
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/variables.rb132
-rw-r--r--Master/texmf-dist/scripts/context/ruby/concheck.rb471
-rw-r--r--Master/texmf-dist/scripts/context/ruby/ctxtools.rb2779
-rw-r--r--Master/texmf-dist/scripts/context/ruby/graphics/gs.rb684
-rw-r--r--Master/texmf-dist/scripts/context/ruby/graphics/inkscape.rb113
-rw-r--r--Master/texmf-dist/scripts/context/ruby/graphics/magick.rb161
-rw-r--r--Master/texmf-dist/scripts/context/ruby/imgtopdf.rb86
-rw-r--r--Master/texmf-dist/scripts/context/ruby/pdftools.rb861
-rw-r--r--Master/texmf-dist/scripts/context/ruby/pstopdf.rb533
-rw-r--r--Master/texmf-dist/scripts/context/ruby/rlxtools.rb368
-rw-r--r--Master/texmf-dist/scripts/context/ruby/rscortool.rb63
-rw-r--r--Master/texmf-dist/scripts/context/ruby/rsfiltool.rb341
-rw-r--r--Master/texmf-dist/scripts/context/ruby/rslb/base.rb270
-rw-r--r--Master/texmf-dist/scripts/context/ruby/rslibtool.rb114
-rw-r--r--Master/texmf-dist/scripts/context/ruby/runtools.rb506
-rw-r--r--Master/texmf-dist/scripts/context/ruby/texexec.rb791
-rw-r--r--Master/texmf-dist/scripts/context/ruby/texmfstart.rb1271
-rw-r--r--Master/texmf-dist/scripts/context/ruby/textools.rb1033
-rw-r--r--Master/texmf-dist/scripts/context/ruby/texutil.rb93
-rw-r--r--Master/texmf-dist/scripts/context/ruby/tmftools.rb165
-rw-r--r--Master/texmf-dist/scripts/context/ruby/xmltools.rb656
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs-mkiv/unix/contextjit3
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs-mkiv/unix/luatools2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs-mkiv/unix/mtxrunjit3
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs-mkiv/win64/contextjit.cmd4
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs-mkiv/win64/luatools.cmd2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs-mkiv/win64/mtxrunjit.cmd4
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/unix/ctxtools2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/unix/pstopdf2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/unix/texexec2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/unix/texmfstart2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/win64/ctxtools.cmd2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/win64/pstopdf.cmd2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/win64/texexec.cmd2
-rwxr-xr-xMaster/texmf-dist/scripts/context/stubs/win64/texmfstart.cmd2
152 files changed, 35099 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.html b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.html
new file mode 100644
index 00000000000..06acff7e043
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>CtxTools 1.3.5</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">CtxTools 1.3.5 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--touchcontextfile</th><td></td><td>update context version</td></tr>
+ <tr><th>--contextversion</th><td></td><td>report context version</td></tr>
+ <tr><th>--jeditinterface</th><td></td><td>generate jedit syntax files [--pipe]</td></tr>
+ <tr><th>--bbeditinterface</th><td></td><td>generate bbedit syntax files [--pipe]</td></tr>
+ <tr><th>--sciteinterface</th><td></td><td>generate scite syntax files [--pipe]</td></tr>
+ <tr><th>--rawinterface</th><td></td><td>generate raw syntax files [--pipe]</td></tr>
+ <tr><th>--translateinterface</th><td></td><td>generate interface files (xml) [nl de ..]</td></tr>
+ <tr><th>--purgefiles</th><td></td><td>remove temporary files [--all --recurse] [basename]</td></tr>
+ <tr><th>--documentation generate documentation [--type</th><td>]</td><td>[filename]</td></tr>
+ <tr><th>--filterpages'</th><td></td><td>) # no help, hidden temporary feature</td></tr>
+ <tr><th>--dpxmapfiles</th><td></td><td>convert pdftex mapfiles to dvipdfmx [--force] [texmfroot]</td></tr>
+ <tr><th>--listentities</th><td></td><td>create doctype entity definition from enco-uc.tex</td></tr>
+ <tr><th>--brandfiles</th><td></td><td>add context copyright notice [--force]</td></tr>
+ <tr><th>--platformize</th><td></td><td>replace line-endings [--recurse --force] [pattern]</td></tr>
+ <tr><th>--dependencies analyze depedencies within context [--save --compact --filter</th><td>[macros|filenames] ]</td><td>[filename]</td></tr>
+ <tr><th>--updatecontext</th><td></td><td>download latest version and remake formats [--proxy]</td></tr>
+ <tr><th>--disarmutfbom</th><td></td><td>remove utf bom [--force]</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man
new file mode 100644
index 00000000000..8b79a7ad7b1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.man
@@ -0,0 +1,75 @@
+.TH "ctxtools" "1" "01-01-2023" "version 1.3.5" "CtxTools"
+.SH NAME
+ ctxtools - CtxTools
+.SH SYNOPSIS
+.B ctxtools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B CtxTools
+.SH OPTIONS
+.TP
+.B --touchcontextfile
+update context version
+.TP
+.B --contextversion
+report context version
+.TP
+.B --jeditinterface
+generate jedit syntax files [--pipe]
+.TP
+.B --bbeditinterface
+generate bbedit syntax files [--pipe]
+.TP
+.B --sciteinterface
+generate scite syntax files [--pipe]
+.TP
+.B --rawinterface
+generate raw syntax files [--pipe]
+.TP
+.B --translateinterface
+generate interface files (xml) [nl de ..]
+.TP
+.B --purgefiles
+remove temporary files [--all --recurse] [basename]
+.TP
+.B --documentation generate documentation [--type=]
+[filename]
+.TP
+.B --filterpages'
+) # no help, hidden temporary feature
+.TP
+.B --dpxmapfiles
+convert pdftex mapfiles to dvipdfmx [--force] [texmfroot]
+.TP
+.B --listentities
+create doctype entity definition from enco-uc.tex
+.TP
+.B --brandfiles
+add context copyright notice [--force]
+.TP
+.B --platformize
+replace line-endings [--recurse --force] [pattern]
+.TP
+.B --dependencies analyze depedencies within context [--save --compact --filter=[macros|filenames] ]
+[filename]
+.TP
+.B --updatecontext
+download latest version and remake formats [--proxy]
+.TP
+.B --disarmutfbom
+remove utf bom [--force]
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.xml b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.xml
new file mode 100644
index 00000000000..8f51cd93a0d
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/ctxtools.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">ctxtools</entry>
+ <entry name="detail">CtxTools</entry>
+ <entry name="version">1.3.5</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="touchcontextfile"><short>update context version</short></flag>
+ <flag name="contextversion"><short>report context version</short></flag>
+ <flag name="jeditinterface"><short>generate jedit syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="bbeditinterface"><short>generate bbedit syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="sciteinterface"><short>generate scite syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="rawinterface"><short>generate raw syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="translateinterface"><short>generate interface files (xml) [nl de ..]</short></flag>
+ <flag name="purgefiles"><short>remove temporary files [<ref name="all"/> <ref name="recurse]"/> [basename]</short></flag>
+ <flag name="documentation generate documentation [--type" value="]"><short>[filename]</short></flag>
+ <flag name="filterpages'"><short>) # no help, hidden temporary feature</short></flag>
+ <flag name="dpxmapfiles"><short>convert pdftex mapfiles to dvipdfmx [<ref name="force]"/> [texmfroot]</short></flag>
+ <flag name="listentities"><short>create doctype entity definition from enco-uc.tex</short></flag>
+ <flag name="brandfiles"><short>add context copyright notice [<ref name="force]"/></short></flag>
+ <flag name="platformize"><short>replace line-endings [<ref name="recurse"/> <ref name="force]"/> [pattern]</short></flag>
+ <flag name="dependencies analyze depedencies within context [--save --compact --filter" value="[macros|filenames] ]"><short>[filename]</short></flag>
+ <flag name="updatecontext"><short>download latest version and remake formats [<ref name="proxy]"/></short></flag>
+ <flag name="disarmutfbom"><short>remove utf bom [<ref name="force]"/></short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.html b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.html
new file mode 100644
index 00000000000..acf64598168
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>ImgToPdf 1.1.2</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">ImgToPdf 1.1.2 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--convert</th><td></td><td>convert image into pdf</td></tr>
+ <tr><th>--compression</th><td></td><td>level of compression in percent</td></tr>
+ <tr><th>--depth</th><td></td><td>image depth in bits</td></tr>
+ <tr><th>--colorspace</th><td></td><td> colorspace (rgb,cmyk,gray)</td></tr>
+ <tr><th>--quality</th><td></td><td>quality in percent</td></tr>
+ <tr><th>--inputpath</th><td></td><td>path where files are looked for</td></tr>
+ <tr><th>--outputpath</th><td></td><td>path where files end up</td></tr>
+ <tr><th>--auto</th><td></td><td>determine settings automatically</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man
new file mode 100644
index 00000000000..829678e92af
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.man
@@ -0,0 +1,48 @@
+.TH "imgtopdf" "1" "01-01-2023" "version 1.1.2" "ImgToPdf"
+.SH NAME
+ imgtopdf - ImgToPdf
+.SH SYNOPSIS
+.B imgtopdf [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B ImgToPdf
+.SH OPTIONS
+.TP
+.B --convert
+convert image into pdf
+.TP
+.B --compression
+level of compression in percent
+.TP
+.B --depth
+image depth in bits
+.TP
+.B --colorspace
+ colorspace (rgb,cmyk,gray)
+.TP
+.B --quality
+quality in percent
+.TP
+.B --inputpath
+path where files are looked for
+.TP
+.B --outputpath
+path where files end up
+.TP
+.B --auto
+determine settings automatically
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.xml b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.xml
new file mode 100644
index 00000000000..b516852c3d2
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/imgtopdf.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">imgtopdf</entry>
+ <entry name="detail">ImgToPdf</entry>
+ <entry name="version">1.1.2</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="convert"><short>convert image into pdf</short></flag>
+ <flag name="compression"><short>level of compression in percent</short></flag>
+ <flag name="depth"><short>image depth in bits</short></flag>
+ <flag name="colorspace"><short> colorspace (rgb,cmyk,gray)</short></flag>
+ <flag name="quality"><short>quality in percent</short></flag>
+ <flag name="inputpath"><short>path where files are looked for</short></flag>
+ <flag name="outputpath"><short>path where files end up</short></flag>
+ <flag name="auto"><short>determine settings automatically</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pdftools.html b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.html
new file mode 100644
index 00000000000..7c147425852
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>PDFTools 1.2.1</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">PDFTools 1.2.1 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--spotimage filename --colorspec</th><td></td><td>--colorname= [--retain --invert --subpath=]</td></tr>
+ <tr><th>--colorimage filename --colorspec</th><td></td><td>[--retain --invert --colorname= ]</td></tr>
+ <tr><th>--convertimage</th><td></td><td>filename [--retain --subpath]</td></tr>
+ <tr><th>--downsampleimage</th><td></td><td>filename [--retain --subpath --lowres --normal]</td></tr>
+ <tr><th>--info</th><td></td><td>filename</td></tr>
+ <tr><th>--countpages</th><td></td><td>[--pattern --threshold]</td></tr>
+ <tr><th>--checkembedded</th><td></td><td>[--pattern]</td></tr>
+ <tr><th>--analyzefile</th><td></td><td>filename</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pdftools.man b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.man
new file mode 100644
index 00000000000..fbb70791066
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.man
@@ -0,0 +1,48 @@
+.TH "pdftools" "1" "01-01-2023" "version 1.2.1" "PDFTools"
+.SH NAME
+ pdftools - PDFTools
+.SH SYNOPSIS
+.B pdftools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B PDFTools
+.SH OPTIONS
+.TP
+.B --spotimage filename --colorspec
+--colorname= [--retain --invert --subpath=]
+.TP
+.B --colorimage filename --colorspec
+[--retain --invert --colorname= ]
+.TP
+.B --convertimage
+filename [--retain --subpath]
+.TP
+.B --downsampleimage
+filename [--retain --subpath --lowres --normal]
+.TP
+.B --info
+filename
+.TP
+.B --countpages
+[--pattern --threshold]
+.TP
+.B --checkembedded
+[--pattern]
+.TP
+.B --analyzefile
+filename
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pdftools.xml b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.xml
new file mode 100644
index 00000000000..292ef4f88f2
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pdftools.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">pdftools</entry>
+ <entry name="detail">PDFTools</entry>
+ <entry name="version">1.2.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="spotimage filename --colorspec" value=""><short><ref name="colorname="/> [<ref name="retain"/> <ref name="invert"/> <ref name="subpath=]"/></short></flag>
+ <flag name="colorimage filename --colorspec" value=""><short>[<ref name="retain"/> <ref name="invert"/> <ref name="colorname="/> ]</short></flag>
+ <flag name="convertimage"><short>filename [<ref name="retain"/> <ref name="subpath]"/></short></flag>
+ <flag name="downsampleimage"><short>filename [<ref name="retain"/> <ref name="subpath"/> <ref name="lowres"/> <ref name="normal]"/></short></flag>
+ <flag name="info"><short>filename</short></flag>
+ <flag name="countpages"><short>[<ref name="pattern"/> <ref name="threshold]"/></short></flag>
+ <flag name="checkembedded"><short>[<ref name="pattern]"/></short></flag>
+ <flag name="analyzefile"><short>filename</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.html b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.html
new file mode 100644
index 00000000000..4470e61766e
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>PStoPDF 2.0.1</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">PStoPDF 2.0.1 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--request</th><td></td><td>handles exa request file</td></tr>
+ <tr><th>--watch</th><td></td><td>watch folders for conversions (untested)</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man
new file mode 100644
index 00000000000..3d38ac3bbbc
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.man
@@ -0,0 +1,30 @@
+.TH "pstopdf" "1" "01-01-2023" "version 2.0.1" "PStoPDF"
+.SH NAME
+ pstopdf - PStoPDF
+.SH SYNOPSIS
+.B pstopdf [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B PStoPDF
+.SH OPTIONS
+.TP
+.B --request
+handles exa request file
+.TP
+.B --watch
+watch folders for conversions (untested)
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.xml b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.xml
new file mode 100644
index 00000000000..d7a7de0ae87
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/pstopdf.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">pstopdf</entry>
+ <entry name="detail">PStoPDF</entry>
+ <entry name="version">2.0.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="request"><short>handles exa request file</short></flag>
+ <flag name="watch"><short>watch folders for conversions (untested)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.html b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.html
new file mode 100644
index 00000000000..6af4c595402
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>RlxTools 1.0.1</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">RlxTools 1.0.1 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--manipulate</th><td></td><td>[--test] manipulatorfile resourselog</td></tr>
+ <tr><th>--identify</th><td></td><td>[--collect] filename</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man
new file mode 100644
index 00000000000..1f4066adc0b
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.man
@@ -0,0 +1,30 @@
+.TH "rlxtools" "1" "01-01-2023" "version 1.0.1" "RlxTools"
+.SH NAME
+ rlxtools - RlxTools
+.SH SYNOPSIS
+.B rlxtools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B RlxTools
+.SH OPTIONS
+.TP
+.B --manipulate
+[--test] manipulatorfile resourselog
+.TP
+.B --identify
+[--collect] filename
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.xml b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.xml
new file mode 100644
index 00000000000..8a221eccf63
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/rlxtools.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">rlxtools</entry>
+ <entry name="detail">RlxTools</entry>
+ <entry name="version">1.0.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="manipulate"><short>[<ref name="test]"/> manipulatorfile resourselog</short></flag>
+ <flag name="identify"><short>[<ref name="collect]"/> filename</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texexec.html b/Master/texmf-dist/doc/context/scripts/mkii/texexec.html
new file mode 100644
index 00000000000..5f775068cc8
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texexec.html
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>TeXExec 6.2.1</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">TeXExec 6.2.1 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--make</th><td></td><td>make formats</td></tr>
+ <tr><th>--check</th><td></td><td>check versions</td></tr>
+ <tr><th>--process</th><td></td><td>process file</td></tr>
+ <tr><th>--mptex</th><td></td><td>process mp file</td></tr>
+ <tr><th>--mpxtex</th><td></td><td>process mpx file</td></tr>
+ <tr><th>--mpgraphic</th><td></td><td>process mp file to stand-alone graphics</td></tr>
+ <tr><th>--mpstatic</th><td></td><td>process mp/ctx file to stand-alone graphics</td></tr>
+ <tr><th>--listing</th><td></td><td>list of file content</td></tr>
+ <tr><th>--figures</th><td></td><td>generate overview of figures</td></tr>
+ <tr><th>--modules</th><td></td><td>generate module documentation</td></tr>
+ <tr><th>--pdfarrange</th><td></td><td>impose pages (booklets)</td></tr>
+ <tr><th>--pdfselect</th><td></td><td>select pages from file(s)</td></tr>
+ <tr><th>--pdfcopy</th><td></td><td>copy pages from file(s)</td></tr>
+ <tr><th>--pdftrim</th><td></td><td>trim pages from file(s)</td></tr>
+ <tr><th>--pdfcombine</th><td></td><td>combine multiple pages</td></tr>
+ <tr><th>--pdfsplit</th><td></td><td>split file in pages</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texexec.man b/Master/texmf-dist/doc/context/scripts/mkii/texexec.man
new file mode 100644
index 00000000000..ebaa8fe97a3
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texexec.man
@@ -0,0 +1,72 @@
+.TH "texexec" "1" "01-01-2023" "version 6.2.1" "TeXExec"
+.SH NAME
+ texexec - TeXExec
+.SH SYNOPSIS
+.B texexec [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B TeXExec
+.SH OPTIONS
+.TP
+.B --make
+make formats
+.TP
+.B --check
+check versions
+.TP
+.B --process
+process file
+.TP
+.B --mptex
+process mp file
+.TP
+.B --mpxtex
+process mpx file
+.TP
+.B --mpgraphic
+process mp file to stand-alone graphics
+.TP
+.B --mpstatic
+process mp/ctx file to stand-alone graphics
+.TP
+.B --listing
+list of file content
+.TP
+.B --figures
+generate overview of figures
+.TP
+.B --modules
+generate module documentation
+.TP
+.B --pdfarrange
+impose pages (booklets)
+.TP
+.B --pdfselect
+select pages from file(s)
+.TP
+.B --pdfcopy
+copy pages from file(s)
+.TP
+.B --pdftrim
+trim pages from file(s)
+.TP
+.B --pdfcombine
+combine multiple pages
+.TP
+.B --pdfsplit
+split file in pages
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texexec.xml b/Master/texmf-dist/doc/context/scripts/mkii/texexec.xml
new file mode 100644
index 00000000000..8f85a4f2502
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texexec.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">texexec</entry>
+ <entry name="detail">TeXExec</entry>
+ <entry name="version">6.2.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="make"><short>make formats</short></flag>
+ <flag name="check"><short>check versions</short></flag>
+ <flag name="process"><short>process file</short></flag>
+ <flag name="mptex"><short>process mp file</short></flag>
+ <flag name="mpxtex"><short>process mpx file</short></flag>
+ <flag name="mpgraphic"><short>process mp file to stand-alone graphics</short></flag>
+ <flag name="mpstatic"><short>process mp/ctx file to stand-alone graphics</short></flag>
+ <flag name="listing"><short>list of file content</short></flag>
+ <flag name="figures"><short>generate overview of figures</short></flag>
+ <flag name="modules"><short>generate module documentation</short></flag>
+ <flag name="pdfarrange"><short>impose pages (booklets)</short></flag>
+ <flag name="pdfselect"><short>select pages from file(s)</short></flag>
+ <flag name="pdfcopy"><short>copy pages from file(s)</short></flag>
+ <flag name="pdftrim"><short>trim pages from file(s)</short></flag>
+ <flag name="pdfcombine"><short>combine multiple pages</short></flag>
+ <flag name="pdfsplit"><short>split file in pages</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.html b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.html
new file mode 100644
index 00000000000..fc3dbb68530
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.html
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>texmfstart 7.0.0</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">texmfstart 7.0.0 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--script</th><td></td><td>run an mtx script (lua prefered method) (--noquotes), no script gives list</td></tr>
+ <tr><th>--evaluate</th><td></td><td>run code passed on the commandline (between quotes) (=loop) (exit|quit aborts)</td></tr>
+ <tr><th>--execute</th><td></td><td>run a script or program (texmfstart method) (--noquotes)</td></tr>
+ <tr><th>--resolve</th><td></td><td>resolve prefixed arguments</td></tr>
+ <tr><th>--ctxlua</th><td></td><td>run internally (using preloaded libs)</td></tr>
+ <tr><th>--internal</th><td></td><td>run script using built in libraries (same as --ctxlua)</td></tr>
+ <tr><th>--locate</th><td></td><td>locate given filename in database (default) or system (--first --all --detail)</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--tree</th><td>pathtotree</td><td>use given texmf tree (default file: setuptex.tmf)</td></tr>
+ <tr><th>--path</th><td>runpath</td><td>go to given path before execution</td></tr>
+ <tr><th>--ifchanged</th><td>filename</td><td>only execute when given file has changed (md checksum)</td></tr>
+ <tr><th>--iftouched</th><td>old,new</td><td>only execute when given file has changed (time stamp)</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--makestubs</th><td></td><td>create stubs for (context related) scripts</td></tr>
+ <tr><th>--removestubs</th><td></td><td>remove stubs (context related) scripts</td></tr>
+ <tr><th>--stubpath</th><td>binpath</td><td>paths where stubs wil be written</td></tr>
+ <tr><th>--windows</th><td></td><td>create windows (mswin) stubs</td></tr>
+ <tr><th>--unix</th><td></td><td>create unix (linux) stubs</td></tr>
+ <tr><th>--addbinarypath</th><td></td><td>prepend the (found) binarypath to runners</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--verbose</th><td></td><td>give a bit more info</td></tr>
+ <tr><th>--trackers</th><td>list</td><td>enable given trackers</td></tr>
+ <tr><th>--progname</th><td>str</td><td>format or backend</td></tr>
+ <tr><th>--systeminfo</th><td>str</td><td>show current operating system, processor, etc</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--edit</th><td></td><td>launch editor with found file</td></tr>
+ <tr><th>--launch</th><td></td><td>launch files like manuals, assumes os support (--all,--list)</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--timedrun</th><td></td><td>run a script and time its run</td></tr>
+ <tr><th>--autogenerate</th><td></td><td>regenerate databases if needed (handy when used to run context in an editor)</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--usekpse</th><td></td><td>use kpse as fallback (when no mkiv and cache installed, often slower)</td></tr>
+ <tr><th>--forcekpse</th><td></td><td>force using kpse (handy when no mkiv and cache installed but less functionality)</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--prefixes</th><td></td><td>show supported prefixes</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--generate</th><td></td><td>generate file database</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--variables</th><td></td><td>show configuration variables</td></tr>
+ <tr><th>--configurations</th><td></td><td>show configuration order</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--directives</th><td></td><td>show (known) directives</td></tr>
+ <tr><th>--trackers</th><td></td><td>show (known) trackers</td></tr>
+ <tr><th>--experiments</th><td></td><td>show (known) experiments</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--expand-braces</th><td></td><td>expand complex variable</td></tr>
+ <tr><th>--resolve-path</th><td></td><td>expand variable (completely resolve paths)</td></tr>
+ <tr><th>--expand-path</th><td></td><td>expand variable (resolve paths)</td></tr>
+ <tr><th>--expand-var</th><td></td><td>expand variable (resolve references)</td></tr>
+ <tr><th>--show-path</th><td></td><td>show path expansion of ...</td></tr>
+ <tr><th>--var-value</th><td></td><td>report value of variable</td></tr>
+ <tr><th>--find-file</th><td></td><td>report file location</td></tr>
+ <tr><th>--find-path</th><td></td><td>report path of file</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--pattern</th><td>string</td><td>filter variables</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man
new file mode 100644
index 00000000000..644ceefd1e2
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.man
@@ -0,0 +1,153 @@
+.TH "mtxrun" "1" "01-01-2023" "version 1.33" "ConTeXt TDS Runner Tool"
+.SH NAME
+ mtxrun - ConTeXt TDS Runner Tool
+.SH SYNOPSIS
+.B mtxrun [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B ConTeXt TDS Runner Tool
+.SH OPTIONS
+.TP
+.B --script
+run an mtx script (lua prefered method) (--noquotes), no script gives list
+.TP
+.B --evaluate
+run code passed on the commandline (between quotes) (=loop) (exit|quit aborts)
+.TP
+.B --execute
+run a script or program (texmfstart method) (--noquotes)
+.TP
+.B --resolve
+resolve prefixed arguments
+.TP
+.B --ctxlua
+run internally (using preloaded libs)
+.TP
+.B --internal
+run script using built in libraries (same as --ctxlua)
+.TP
+.B --locate
+locate given filename in database (default) or system (--first --all --detail)
+.TP
+.B --tree=pathtotree
+use given texmf tree (default file: setuptex.tmf)
+.TP
+.B --path=runpath
+go to given path before execution
+.TP
+.B --ifchanged=filename
+only execute when given file has changed (md checksum)
+.TP
+.B --iftouched=old,new
+only execute when given file has changed (time stamp)
+.TP
+.B --makestubs
+create stubs for (context related) scripts
+.TP
+.B --removestubs
+remove stubs (context related) scripts
+.TP
+.B --stubpath=binpath
+paths where stubs wil be written
+.TP
+.B --windows
+create windows (mswin) stubs
+.TP
+.B --unix
+create unix (linux) stubs
+.TP
+.B --addbinarypath
+prepend the (found) binarypath to runners
+.TP
+.B --verbose
+give a bit more info
+.TP
+.B --trackers=list
+enable given trackers
+.TP
+.B --progname=str
+format or backend
+.TP
+.B --systeminfo=str
+show current operating system, processor, etc
+.TP
+.B --edit
+launch editor with found file
+.TP
+.B --launch
+launch files like manuals, assumes os support (--all,--list)
+.TP
+.B --timedrun
+run a script and time its run
+.TP
+.B --autogenerate
+regenerate databases if needed (handy when used to run context in an editor)
+.TP
+.B --usekpse
+use kpse as fallback (when no mkiv and cache installed, often slower)
+.TP
+.B --forcekpse
+force using kpse (handy when no mkiv and cache installed but less functionality)
+.TP
+.B --prefixes
+show supported prefixes
+.TP
+.B --generate
+generate file database
+.TP
+.B --variables
+show configuration variables
+.TP
+.B --configurations
+show configuration order
+.TP
+.B --directives
+show (known) directives
+.TP
+.B --trackers
+show (known) trackers
+.TP
+.B --experiments
+show (known) experiments
+.TP
+.B --expand-braces
+expand complex variable
+.TP
+.B --resolve-path
+expand variable (completely resolve paths)
+.TP
+.B --expand-path
+expand variable (resolve paths)
+.TP
+.B --expand-var
+expand variable (resolve references)
+.TP
+.B --show-path
+show path expansion of ...
+.TP
+.B --var-value
+report value of variable
+.TP
+.B --find-file
+report file location
+.TP
+.B --find-path
+report path of file
+.TP
+.B --pattern=string
+filter variables
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.xml b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.xml
new file mode 100644
index 00000000000..5e5958e16fd
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texmfstart.xml
@@ -0,0 +1,80 @@
+<?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> \ No newline at end of file
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/textools.html b/Master/texmf-dist/doc/context/scripts/mkii/textools.html
new file mode 100644
index 00000000000..9bd9ac5c9e9
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/textools.html
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>TeXTools 1.3.1</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">TeXTools 1.3.1 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--removemapnames</th><td></td><td>[pattern] [--recurse]</td></tr>
+ <tr><th>--restoremapnames</th><td></td><td>[pattern] [--recurse]</td></tr>
+ <tr><th>--hidemapnames</th><td></td><td>[pattern] [--recurse]</td></tr>
+ <tr><th>--videmapnames</th><td></td><td>[pattern] [--recurse]</td></tr>
+ <tr><th>--findfile</th><td></td><td>filename [--recurse]</td></tr>
+ <tr><th>--unzipfiles</th><td></td><td>[pattern] [--recurse]</td></tr>
+ <tr><th>--fixafmfiles</th><td></td><td>[pattern] [--recurse]</td></tr>
+ <tr><th>--mactodos</th><td></td><td>[pattern] [--recurse]</td></tr>
+ <tr><th>--fixtexmftrees</th><td></td><td>[texmfroot] [--force]</td></tr>
+ <tr><th>--replacefile</th><td></td><td>filename [--force]</td></tr>
+ <tr><th>--updatetree</th><td></td><td>fromroot toroot [--force --nocheck --merge --delete]</td></tr>
+ <tr><th>--downcasefilenames</th><td></td><td>[--recurse] [--force]</td></tr>
+ <tr><th>--stripformfeeds</th><td></td><td>[--recurse] [--force]</td></tr>
+ <tr><th>--showfont</th><td></td><td>filename</td></tr>
+ <tr><th>--encmake</th><td></td><td>afmfile encodingname</td></tr>
+ <tr><th>--tpmmake</th><td></td><td>tpm file (run in texmf root)</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/textools.man b/Master/texmf-dist/doc/context/scripts/mkii/textools.man
new file mode 100644
index 00000000000..d040d7d0d20
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/textools.man
@@ -0,0 +1,72 @@
+.TH "textools" "1" "01-01-2023" "version 1.3.1" "TeXTools"
+.SH NAME
+ textools - TeXTools
+.SH SYNOPSIS
+.B textools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B TeXTools
+.SH OPTIONS
+.TP
+.B --removemapnames
+[pattern] [--recurse]
+.TP
+.B --restoremapnames
+[pattern] [--recurse]
+.TP
+.B --hidemapnames
+[pattern] [--recurse]
+.TP
+.B --videmapnames
+[pattern] [--recurse]
+.TP
+.B --findfile
+filename [--recurse]
+.TP
+.B --unzipfiles
+[pattern] [--recurse]
+.TP
+.B --fixafmfiles
+[pattern] [--recurse]
+.TP
+.B --mactodos
+[pattern] [--recurse]
+.TP
+.B --fixtexmftrees
+[texmfroot] [--force]
+.TP
+.B --replacefile
+filename [--force]
+.TP
+.B --updatetree
+fromroot toroot [--force --nocheck --merge --delete]
+.TP
+.B --downcasefilenames
+[--recurse] [--force]
+.TP
+.B --stripformfeeds
+[--recurse] [--force]
+.TP
+.B --showfont
+filename
+.TP
+.B --encmake
+afmfile encodingname
+.TP
+.B --tpmmake
+tpm file (run in texmf root)
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/textools.xml b/Master/texmf-dist/doc/context/scripts/mkii/textools.xml
new file mode 100644
index 00000000000..963c4a3a4d9
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/textools.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">textools</entry>
+ <entry name="detail">TeXTools</entry>
+ <entry name="version">1.3.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="removemapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="restoremapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="hidemapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="videmapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="findfile"><short>filename [<ref name="recurse]"/></short></flag>
+ <flag name="unzipfiles"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="fixafmfiles"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="mactodos"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="fixtexmftrees"><short>[texmfroot] [<ref name="force]"/></short></flag>
+ <flag name="replacefile"><short>filename [<ref name="force]"/></short></flag>
+ <flag name="updatetree"><short>fromroot toroot [<ref name="force"/> <ref name="nocheck"/> <ref name="merge"/> <ref name="delete]"/></short></flag>
+ <flag name="downcasefilenames"><short>[<ref name="recurse]"/> [<ref name="force]"/></short></flag>
+ <flag name="stripformfeeds"><short>[<ref name="recurse]"/> [<ref name="force]"/></short></flag>
+ <flag name="showfont"><short>filename</short></flag>
+ <flag name="encmake"><short>afmfile encodingname</short></flag>
+ <flag name="tpmmake"><short>tpm file (run in texmf root)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texutil.html b/Master/texmf-dist/doc/context/scripts/mkii/texutil.html
new file mode 100644
index 00000000000..4dd23fa3aee
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texutil.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>TeXUtil 9.1.0</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">TeXUtil 9.1.0 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--references</th><td></td><td>convert tui file into tuo file</td></tr>
+ <tr><th>--figures</th><td></td><td>generate figure dimensions file</td></tr>
+ <tr><th>--logfile</th><td></td><td>filter essential log messages</td></tr>
+ <tr><th>--purgefiles</th><td></td><td>remove most temporary files</td></tr>
+ <tr><th>--purgeallfiles</th><td></td><td>remove all temporary files</td></tr>
+ <tr><th>--documentation</th><td></td><td>generate documentation file from source</td></tr>
+ <tr><th>--analyzefile</th><td></td><td>analyze pdf file</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texutil.man b/Master/texmf-dist/doc/context/scripts/mkii/texutil.man
new file mode 100644
index 00000000000..dd27460f821
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texutil.man
@@ -0,0 +1,45 @@
+.TH "texutil" "1" "01-01-2023" "version 9.1.0" "TeXUtil"
+.SH NAME
+ texutil - TeXUtil
+.SH SYNOPSIS
+.B texutil [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B TeXUtil
+.SH OPTIONS
+.TP
+.B --references
+convert tui file into tuo file
+.TP
+.B --figures
+generate figure dimensions file
+.TP
+.B --logfile
+filter essential log messages
+.TP
+.B --purgefiles
+remove most temporary files
+.TP
+.B --purgeallfiles
+remove all temporary files
+.TP
+.B --documentation
+generate documentation file from source
+.TP
+.B --analyzefile
+analyze pdf file
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/texutil.xml b/Master/texmf-dist/doc/context/scripts/mkii/texutil.xml
new file mode 100644
index 00000000000..fde9abd586a
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/texutil.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">texutil</entry>
+ <entry name="detail">TeXUtil</entry>
+ <entry name="version">9.1.0</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="references"><short>convert tui file into tuo file</short></flag>
+ <flag name="figures"><short>generate figure dimensions file</short></flag>
+ <flag name="logfile"><short>filter essential log messages</short></flag>
+ <flag name="purgefiles"><short>remove most temporary files</short></flag>
+ <flag name="purgeallfiles"><short>remove all temporary files</short></flag>
+ <flag name="documentation"><short>generate documentation file from source</short></flag>
+ <flag name="analyzefile"><short>analyze pdf file</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application> \ No newline at end of file
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/tmftools.html b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.html
new file mode 100644
index 00000000000..17a18289686
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>TMFTools 1.2.1</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">TMFTools 1.2.1 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--analyze</th><td></td><td>[--strict --sort --rootpath --treepath --delete --force] [pattern]</td></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--serve</th><td></td><td>act as kpse server</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/tmftools.man b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.man
new file mode 100644
index 00000000000..1355bae1687
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.man
@@ -0,0 +1,30 @@
+.TH "tmftools" "1" "01-01-2023" "version 1.1.0" "TMFTools"
+.SH NAME
+ tmftools - TMFTools
+.SH SYNOPSIS
+.B tmftools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B TMFTools
+.SH OPTIONS
+.TP
+.B --analyze
+[--strict --sort --rootpath --treepath --delete --force] [pattern]
+.TP
+.B --serve
+act as kpse server
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/tmftools.xml b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.xml
new file mode 100644
index 00000000000..c52aa30673d
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/tmftools.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">tmftools</entry>
+ <entry name="detail">TMFTools</entry>
+ <entry name="version">1.1.0</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="analyze"><short>[<ref name="strict"/> <ref name="sort"/> <ref name="rootpath"/> <ref name="treepath"/> <ref name="delete"/> <ref name="force"/>] [pattern]</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="serve"><short>act as kpse server</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/xmltools.html b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.html
new file mode 100644
index 00000000000..d6733ae7a18
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!-- compare with lmx framework variant -->
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>XMLTools 1.2.1</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
+ </style>
+ <style type="text/css">
+ </style>
+ </head>
+ <body>
+ <div id="top"> <div id="top-one">
+ <div id="top-two">XMLTools 1.2.1 </div>
+ </div>
+ </div>
+ <div id="bottom"> <div id="bottom-one">
+ <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
+ </div>
+ </div>
+ <div id="left"></div>
+ <div id="right"></div>
+ <div id="main">
+ <div id='main-settings'>
+ <h1>Command line options</h1>
+<table>
+ <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
+ <tr><th/><td/><td/></tr>
+ <tr><th>--dir</th><td></td><td>generate directory listing</td></tr>
+ <tr><th>--mmlpages</th><td></td><td>generate graphic from mathml</td></tr>
+ <tr><th>--analyze</th><td></td><td>report entities and elements [--utf --process]</td></tr>
+ <tr><th>--cleanup</th><td></td><td>cleanup xml file [--force]</td></tr>
+ <tr><th>--enhance</th><td></td><td>enhance xml file (partial)</td></tr>
+ <tr><th>--filter</th><td></td><td>filter elements from xml file [--element]</td></tr>
+ <tr><th>--dir</th><td></td><td>generate ddirectory listing</td></tr>
+ </table>
+<br/>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/xmltools.man b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.man
new file mode 100644
index 00000000000..5a4840add40
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.man
@@ -0,0 +1,45 @@
+.TH "xmltools" "1" "01-01-2023" "version 1.2.2" "XMLTools"
+.SH NAME
+ xmltools - XMLTools
+.SH SYNOPSIS
+.B xmltools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B XMLTools
+.SH OPTIONS
+.TP
+.B --dir
+generate directory listing
+.TP
+.B --mmlpages
+generate graphic from mathml
+.TP
+.B --analyze
+report entities and elements [--utf --process]
+.TP
+.B --cleanup
+cleanup xml file [--force]
+.TP
+.B --enhance
+enhance xml file (partial)
+.TP
+.B --filter
+filter elements from xml file [--element]
+.TP
+.B --dir
+generate ddirectory listing
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/context/scripts/mkii/xmltools.xml b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.xml
new file mode 100644
index 00000000000..4b784c4e721
--- /dev/null
+++ b/Master/texmf-dist/doc/context/scripts/mkii/xmltools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">xmltools</entry>
+ <entry name="detail">XMLTools</entry>
+ <entry name="version">1.2.2</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="dir"><short>generate directory listing</short></flag>
+ <flag name="mmlpages"><short>generate graphic from mathml</short></flag>
+ <flag name="analyze"><short>report entities and elements [<ref name="utf"/> <ref name="process"/>]</short></flag>
+ <flag name="cleanup"><short>cleanup xml file [<ref name="force"/>]</short></flag>
+ <flag name="enhance"><short>enhance xml file (partial)</short></flag>
+ <flag name="filter"><short>filter elements from xml file [<ref name="element"/>]</short></flag>
+ <flag name="dir"><short>generate ddirectory listing</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
diff --git a/Master/texmf-dist/doc/man/man1/luatools.1 b/Master/texmf-dist/doc/man/man1/luatools.1
new file mode 100644
index 00000000000..58de54abfa2
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/luatools.1
@@ -0,0 +1,78 @@
+.TH "luatools" "1" "01-01-2023" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.SH NAME
+ luatools - ConTeXt TDS Management Tool (aka luatools)
+.SH SYNOPSIS
+.B luatools [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B ConTeXt TDS Management Tool (aka luatools)
+.SH OPTIONS
+.TP
+.B --generate
+generate file database
+.TP
+.B --variables
+show configuration variables
+.TP
+.B --configurations
+show configuration order
+.TP
+.B --expand-braces
+expand complex variable
+.TP
+.B --expand-path
+expand variable (resolve paths)
+.TP
+.B --expand-var
+expand variable (resolve references)
+.TP
+.B --show-path
+show path expansion of ...
+.TP
+.B --var-value
+report value of variable
+.TP
+.B --find-file
+report file location
+.TP
+.B --find-path
+report path of file
+.TP
+.B --make
+[or --ini] make luatex format
+.TP
+.B --run
+[or --fmt] run luatex format
+.TP
+.B --compile
+assemble and compile lua inifile
+.TP
+.B --verbose
+give a bit more info
+.TP
+.B --all
+show all found files
+.TP
+.B --format=str
+filter cf format specification (default 'tex', use 'any' for any match)
+.TP
+.B --pattern=str
+filter variables
+.TP
+.B --trackers=list
+enable given trackers
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/man/man1/luatools.man1.pdf b/Master/texmf-dist/doc/man/man1/luatools.man1.pdf
new file mode 100644
index 00000000000..65b6508dd9d
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/luatools.man1.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/man/man1/texmfstart.1 b/Master/texmf-dist/doc/man/man1/texmfstart.1
new file mode 100644
index 00000000000..644ceefd1e2
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/texmfstart.1
@@ -0,0 +1,153 @@
+.TH "mtxrun" "1" "01-01-2023" "version 1.33" "ConTeXt TDS Runner Tool"
+.SH NAME
+ mtxrun - ConTeXt TDS Runner Tool
+.SH SYNOPSIS
+.B mtxrun [
+.I OPTIONS ...
+.B ] [
+.I FILENAMES
+.B ]
+.SH DESCRIPTION
+.B ConTeXt TDS Runner Tool
+.SH OPTIONS
+.TP
+.B --script
+run an mtx script (lua prefered method) (--noquotes), no script gives list
+.TP
+.B --evaluate
+run code passed on the commandline (between quotes) (=loop) (exit|quit aborts)
+.TP
+.B --execute
+run a script or program (texmfstart method) (--noquotes)
+.TP
+.B --resolve
+resolve prefixed arguments
+.TP
+.B --ctxlua
+run internally (using preloaded libs)
+.TP
+.B --internal
+run script using built in libraries (same as --ctxlua)
+.TP
+.B --locate
+locate given filename in database (default) or system (--first --all --detail)
+.TP
+.B --tree=pathtotree
+use given texmf tree (default file: setuptex.tmf)
+.TP
+.B --path=runpath
+go to given path before execution
+.TP
+.B --ifchanged=filename
+only execute when given file has changed (md checksum)
+.TP
+.B --iftouched=old,new
+only execute when given file has changed (time stamp)
+.TP
+.B --makestubs
+create stubs for (context related) scripts
+.TP
+.B --removestubs
+remove stubs (context related) scripts
+.TP
+.B --stubpath=binpath
+paths where stubs wil be written
+.TP
+.B --windows
+create windows (mswin) stubs
+.TP
+.B --unix
+create unix (linux) stubs
+.TP
+.B --addbinarypath
+prepend the (found) binarypath to runners
+.TP
+.B --verbose
+give a bit more info
+.TP
+.B --trackers=list
+enable given trackers
+.TP
+.B --progname=str
+format or backend
+.TP
+.B --systeminfo=str
+show current operating system, processor, etc
+.TP
+.B --edit
+launch editor with found file
+.TP
+.B --launch
+launch files like manuals, assumes os support (--all,--list)
+.TP
+.B --timedrun
+run a script and time its run
+.TP
+.B --autogenerate
+regenerate databases if needed (handy when used to run context in an editor)
+.TP
+.B --usekpse
+use kpse as fallback (when no mkiv and cache installed, often slower)
+.TP
+.B --forcekpse
+force using kpse (handy when no mkiv and cache installed but less functionality)
+.TP
+.B --prefixes
+show supported prefixes
+.TP
+.B --generate
+generate file database
+.TP
+.B --variables
+show configuration variables
+.TP
+.B --configurations
+show configuration order
+.TP
+.B --directives
+show (known) directives
+.TP
+.B --trackers
+show (known) trackers
+.TP
+.B --experiments
+show (known) experiments
+.TP
+.B --expand-braces
+expand complex variable
+.TP
+.B --resolve-path
+expand variable (completely resolve paths)
+.TP
+.B --expand-path
+expand variable (resolve paths)
+.TP
+.B --expand-var
+expand variable (resolve references)
+.TP
+.B --show-path
+show path expansion of ...
+.TP
+.B --var-value
+report value of variable
+.TP
+.B --find-file
+report file location
+.TP
+.B --find-path
+report path of file
+.TP
+.B --pattern=string
+filter variables
+.SH AUTHOR
+More information about ConTeXt and the tools that come with it can be found at:
+
+
+.B "maillist:"
+ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+
+.B "webpage:"
+http://www.pragma-ade.nl / http://tex.aanhet.net
+
+.B "wiki:"
+http://contextgarden.net
diff --git a/Master/texmf-dist/doc/man/man1/texmfstart.man1.pdf b/Master/texmf-dist/doc/man/man1/texmfstart.man1.pdf
new file mode 100644
index 00000000000..146c7e8b439
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/texmfstart.man1.pdf
Binary files differ
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/cmin.enc b/Master/texmf-dist/fonts/enc/dvips/context/cmin.enc
new file mode 100644
index 00000000000..dc2b063a615
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/cmin.enc
@@ -0,0 +1,258 @@
+/enccmin[
+/.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
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/zero
+/one
+/two
+/three
+/four
+/five
+/six
+/seven
+/eight
+/nine
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/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
+/.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
+/.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
+/.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
+/.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
+/.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
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/cmit.enc b/Master/texmf-dist/fonts/enc/dvips/context/cmit.enc
new file mode 100644
index 00000000000..40fd82f77ce
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/cmit.enc
@@ -0,0 +1,258 @@
+/enccmit[
+/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
+/sterling
+/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
+/.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
+/.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
+/.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
+/.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
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/cmitt.enc b/Master/texmf-dist/fonts/enc/dvips/context/cmitt.enc
new file mode 100644
index 00000000000..971187c32da
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/cmitt.enc
@@ -0,0 +1,258 @@
+/enccmitt[
+/Gamma
+/Delta
+/Theta
+/Lambda
+/Xi
+/Pi
+/Sigma
+/Upsilon
+/Phi
+/Psi
+/Omega
+/arrowup
+/arrowdown
+/quotesingle
+/exclamdown
+/questiondown
+/dotlessi
+/dotlessj
+/grave
+/acute
+/caron
+/breve
+/macron
+/ring
+/cedilla
+/germandbls
+/ae
+/oe
+/oslash
+/AE
+/OE
+/Oslash
+/visiblespace
+/exclam
+/quotedbl
+/numbersign
+/sterling
+/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
+/dieresis
+/.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
+/.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
+/.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
+/.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
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/cmrm.enc b/Master/texmf-dist/fonts/enc/dvips/context/cmrm.enc
new file mode 100644
index 00000000000..3a1ab23ddd9
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/cmrm.enc
@@ -0,0 +1,258 @@
+/enccmrm[
+/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
+/.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
+/.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
+/.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
+/.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
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/cmsc.enc b/Master/texmf-dist/fonts/enc/dvips/context/cmsc.enc
new file mode 100644
index 00000000000..b8ab09121a0
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/cmsc.enc
@@ -0,0 +1,258 @@
+/enccmsc[
+/Gamma
+/Delta
+/Theta
+/Lambda
+/Xi
+/Pi
+/Sigma
+/Upsilon
+/Phi
+/Psi
+/Omega
+/arrowup
+/arrowdown
+/quotesingle
+/exclamdown
+/questiondown
+/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
+/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
+/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
+/.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
+/.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
+/.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
+/.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
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/cmtt.enc b/Master/texmf-dist/fonts/enc/dvips/context/cmtt.enc
new file mode 100644
index 00000000000..3c3a9f74b3a
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/cmtt.enc
@@ -0,0 +1,258 @@
+/enccmtt[
+/Gamma
+/Delta
+/Theta
+/Lambda
+/Xi
+/Pi
+/Sigma
+/Upsilon
+/Phi
+/Psi
+/Omega
+/arrowup
+/arrowdown
+/quotesingle
+/exclamdown
+/questiondown
+/dotlessi
+/dotlessj
+/grave
+/acute
+/caron
+/breve
+/macron
+/ring
+/cedilla
+/germandbls
+/ae
+/oe
+/oslash
+/AE
+/OE
+/Oslash
+/visiblespace
+/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
+/dieresis
+/.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
+/.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
+/.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
+/.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
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/ec-2004.enc b/Master/texmf-dist/fonts/enc/dvips/context/ec-2004.enc
new file mode 100644
index 00000000000..f092a34a2fe
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/ec-2004.enc
@@ -0,0 +1,82 @@
+%
+% This is the EC encoding.
+%
+% These are the ligs and kerns in addition to those found in the
+% AFM file. (The only ligs in the Times-Roman.afm file are the
+% fi and fl ligatures.)
+%
+% LIGKERN space l =: lslash ; space L =: Lslash ;
+% LIGKERN question quoteleft =: questiondown ; exclam quoteleft =: exclamdown ;
+% LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ;
+% LIGKERN quoteleft quoteleft =: quotedblleft ;
+% LIGKERN quoteright quoteright =: quotedblright ;
+%
+% We blow away kerns to and from spaces (TeX doesn't have a
+% space) and also remove any kerns from the numbers (although
+% the only kern pair that mentions a number in Times-Roman.afm
+% is one one.)
+%
+% LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ;
+% LIGKERN one {} * ; * {} one ; two {} * ; * {} two ;
+% LIGKERN three {} * ; * {} three ; four {} * ; * {} four ;
+% LIGKERN five {} * ; * {} five ; six {} * ; * {} six ;
+% LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ;
+% LIGKERN nine {} * ; * {} nine ;
+% LIGKERN comma comma =: quotedblbase ; less less =: guillemotleft ;
+% LIGKERN greater greater =: guillemotright ;
+%
+/ECEncoding [ % now 256 chars follow
+% 0x00
+ /grave /acute /circumflex /tilde /dieresis /hungarumlaut /ring /caron
+ /breve /macron /dotaccent /cedilla
+ /ogonek /quotesinglbase /guilsinglleft /guilsinglright
+% 0x10
+ /quotedblleft /quotedblright /quotedblbase /guillemotleft
+ /guillemotright /endash /emdash /cwm
+ /zeroinferior /dotlessi /dotlessj /ff /fi /fl /ffi /ffl
+% 0x20
+ /visualspace /exclam /quotedbl /numbersign
+ /dollar /percent /ampersand /quoteright
+ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+% 0x30
+ /zero /one /two /three /four /five /six /seven
+ /eight /nine /colon /semicolon /less /equal /greater /question
+% 0x40
+ /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
+% 0x50
+ /P /Q /R /S /T /U /V /W
+ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+% 0x60
+ /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+% 0x70
+ /p /q /r /s /t /u /v /w
+ /x /y /z /braceleft /bar /braceright /asciitilde /hyphen
+% 0x80
+ /Abreve /Aogonek /Cacute /Ccaron /Dcaron /Ecaron /Eogonek /Gbreve
+ /Lacute /Lcaron /Lslash /Nacute /Ncaron /Ng /Ohungarumlaut /Racute
+% 0x90
+ /Rcaron /Sacute /Scaron /Scedilla
+ /Tcaron /Tcedilla /Uhungarumlaut /Uring
+ /Ydieresis /Zacute /Zcaron /Zdotaccent /IJ /Idotaccent /dbar /section
+% 0xA0
+ /abreve /aogonek /cacute /ccaron /dcaron /ecaron /eogonek /gbreve
+ /lacute /lcaron /lslash /nacute /ncaron /ng /ohungarumlaut /racute
+% 0xB0
+ /rcaron /sacute /scaron /scedilla
+ /tquoteright /tcedilla /uhungarumlaut /uring
+ /ldot /zacute /zcaron /zdotaccent /ij /exclamdown /questiondown /sterling
+% 0xC0
+ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+ /Egrave /Eacute /Ecircumflex /Edieresis
+ /Igrave /Iacute /Icircumflex /Idieresis
+% 0xD0
+ /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /OE
+ /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /Germandbls
+% 0xE0
+ /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+ /egrave /eacute /ecircumflex /edieresis
+ /igrave /iacute /icircumflex /idieresis
+% 0xF0
+ /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /oe
+ /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /germandbls
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/q-8r.enc b/Master/texmf-dist/fonts/enc/dvips/context/q-8r.enc
new file mode 100644
index 00000000000..be8b3261327
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/q-8r.enc
@@ -0,0 +1,264 @@
+% This file could belong to the TeX Gyre collection of fonts,
+% but is only needed and thus distributed with ConTeXt macro package.
+%
+% It provides 8r encoding compatible with TeX Gyre fonts and is used to enable
+% substituting Adobe fonts by TeX Gyre in pxfonts & txfonts.
+%
+/encq8r [
+/.notdef
+/dotaccent
+/fi
+/fl
+/fraction
+/hungarumlaut
+/Lslash
+/lslash
+/ogonek
+/ring
+/.notdef
+/breve
+/minus
+/.notdef
+/Zcaron
+/zcaron
+/caron
+/dotlessi
+/dotlessj
+/ff
+/ffi
+/ffl
+/notequal
+/infinity
+/lessequal
+/greaterequal
+/partialdiff
+/summation
+/product
+/pi
+/grave
+/quotesingle
+/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
+/Euro
+/integral
+/quotesinglbase
+/florin
+/quotedblbase
+/ellipsis
+/dagger
+/daggerdbl
+/circumflex
+/perthousand
+/Scaron
+/guilsinglleft
+/OE
+/Omega
+/radical
+/approxequal
+/.notdef
+/.notdef
+/.notdef
+/quotedblleft
+/quotedblright
+/bullet
+/endash
+/emdash
+/tilde
+/trademark
+/scaron
+/guilsinglright
+/oe
+/Delta
+/lozenge
+/Ydieresis
+/.notdef
+/exclamdown
+/cent
+/sterling
+/currency
+/yen
+/brokenbar
+/section
+/dieresis
+/copyright
+/ordfeminine
+/guillemotleft
+/logicalnot
+/hyphen
+/registered
+/macron
+/degree
+/plusminus
+/two.superior
+/three.superior
+/acute
+/mu
+/paragraph
+/periodcentered
+/cedilla
+/one.superior
+/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
+] def
diff --git a/Master/texmf-dist/fonts/enc/dvips/context/teff-trinite.enc b/Master/texmf-dist/fonts/enc/dvips/context/teff-trinite.enc
new file mode 100644
index 00000000000..ea0e2651e2d
--- /dev/null
+++ b/Master/texmf-dist/fonts/enc/dvips/context/teff-trinite.enc
@@ -0,0 +1,260 @@
+% Encoding file, generated by textools.rb from TriniteNo2RomCon-Regular.afm
+
+/tefftriniteencoding [
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /breve
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /caron
+ /dotlessi
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /fraction
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /space
+ /exclam
+ /quotedbl
+ /numbersign
+ /dollar
+ /percent
+ /ampersand
+ /quotesingle
+ /parenleft
+ /parenright
+ /asterisk
+ /plus
+ /comma
+ /hyphen
+ /period
+ /slash
+ /zero
+ /one
+ /two
+ /three
+ /four
+ /five
+ /six
+ /seven
+ /eight
+ /nine
+ /colon
+ /semicolon
+ /less
+ /equal
+ /greater
+ /question
+ /at
+ /A
+ /B
+ /C
+ /D
+ /E
+ /F
+ /G
+ /H
+ /I
+ /J
+ /K
+ /L
+ /M
+ /N
+ /O
+ /P
+ /Q
+ /R
+ /S
+ /T
+ /U
+ /V
+ /W
+ /X
+ /Y
+ /Z
+ /bracketleft
+ /backslash
+ /bracketright
+ /.notdef
+ /underscore
+ /grave
+ /a
+ /b
+ /c
+ /d
+ /e
+ /f
+ /g
+ /h
+ /i
+ /j
+ /k
+ /l
+ /m
+ /n
+ /o
+ /p
+ /q
+ /r
+ /s
+ /t
+ /u
+ /v
+ /w
+ /x
+ /y
+ /z
+ /braceleft
+ /bar
+ /braceright
+ /.notdef
+ /.notdef
+ /Euro
+ /.notdef
+ /.notdef
+ /florin
+ /quotedblbase
+ /ellipsis
+ /dagger
+ /daggerdbl
+ /circumflex
+ /perthousand
+ /.notdef
+ /guilsinglleft
+ /OE
+ /.notdef
+ /.notdef
+ /.notdef
+ /.notdef
+ /quoteleft
+ /quoteright
+ /quotedblleft
+ /quotedblright
+ /bullet
+ /endash
+ /emdash
+ /tilde
+ /.notdef
+ /.notdef
+ /guilsinglright
+ /oe
+ /.notdef
+ /.notdef
+ /Ydieresis
+ /.notdef
+ /exclamdown
+ /cent
+ /sterling
+ /.notdef
+ /.notdef
+ /.notdef
+ /section
+ /dieresis
+ /copyright
+ /.notdef
+ /guillemotleft
+ /.notdef
+ /.notdef
+ /.notdef
+ /macron
+ /degree
+ /.notdef
+ /.notdef
+ /.notdef
+ /acute
+ /.notdef
+ /paragraph
+ /multiply
+ /cedilla
+ /.notdef
+ /.notdef
+ /guillemotright
+ /.notdef
+ /.notdef
+ /.notdef
+ /questiondown
+ /Agrave
+ /Aacute
+ /Acircumflex
+ /Atilde
+ /Adieresis
+ /Aring
+ /AE
+ /Ccedilla
+ /Egrave
+ /Eacute
+ /Ecircumflex
+ /Edieresis
+ /Igrave
+ /Iacute
+ /Icircumflex
+ /Idieresis
+ /.notdef
+ /Ntilde
+ /Ograve
+ /Oacute
+ /Ocircumflex
+ /Otilde
+ /Odieresis
+ /.notdef
+ /Oslash
+ /Ugrave
+ /Uacute
+ /Ucircumflex
+ /Udieresis
+ /.notdef
+ /.notdef
+ /germandbls
+ /agrave
+ /aacute
+ /acircumflex
+ /atilde
+ /adieresis
+ /aring
+ /ae
+ /ccedilla
+ /egrave
+ /eacute
+ /ecircumflex
+ /edieresis
+ /igrave
+ /iacute
+ /icircumflex
+ /idieresis
+ /.notdef
+ /ntilde
+ /ograve
+ /oacute
+ /ocircumflex
+ /otilde
+ /odieresis
+ /.notdef
+ /oslash
+ /ugrave
+ /uacute
+ /ucircumflex
+ /udieresis
+ /.notdef
+ /.notdef
+ /ydieresis
+] def
diff --git a/Master/texmf-dist/fonts/map/dvips/context/contnav.map b/Master/texmf-dist/fonts/map/dvips/context/contnav.map
new file mode 100644
index 00000000000..942798c579f
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/dvips/context/contnav.map
@@ -0,0 +1 @@
+contnav ContextNavigation <contnav.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/8r-base.map b/Master/texmf-dist/fonts/map/pdftex/context/8r-base.map
new file mode 100644
index 00000000000..e1611cfe8a9
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/8r-base.map
@@ -0,0 +1,135 @@
+% courier / urw
+
+ucrb8r NimbusMonL-Bold <8r.enc <ucrb8a.pfb
+ucrbo8r NimbusMonL-BoldObli <8r.enc <ucrbo8a.pfb
+ucrr8r NimbusMonL-Regu <8r.enc <ucrr8a.pfb
+ucrro8r NimbusMonL-ReguObli <8r.enc <ucrro8a.pfb
+
+% courier / adobe
+
+pcrb8r NimbusMonL-Bold <8r.enc <ucrb8a.pfb
+pcrbo8r NimbusMonL-BoldObli <8r.enc <ucrbo8a.pfb
+pcrr8r NimbusMonL-Regu <8r.enc <ucrr8a.pfb
+pcrro8r NimbusMonL-ReguObli <8r.enc <ucrro8a.pfb
+
+% helvetica / urw
+
+uhvb8r NimbusSanL-Bold <8r.enc <uhvb8a.pfb
+uhvbo8r NimbusSanL-BoldItal <8r.enc <uhvbo8a.pfb
+uhvr8r NimbusSanL-Regu <8r.enc <uhvr8a.pfb
+uhvro8r NimbusSanL-ReguItal <8r.enc <uhvro8a.pfb
+
+% helvetica / adobe
+
+phvb8r NimbusSanL-Bold <8r.enc <uhvb8a.pfb
+phvbo8r NimbusSanL-BoldItal <8r.enc <uhvbo8a.pfb
+phvr8r NimbusSanL-Regu <8r.enc <uhvr8a.pfb
+phvro8r NimbusSanL-ReguItal <8r.enc <uhvro8a.pfb
+
+% times / urw
+
+utmb8r NimbusRomNo9L-Medi <8r.enc <utmb8a.pfb
+utmbi8r NimbusRomNo9L-MediItal <8r.enc <utmbi8a.pfb
+utmr8r NimbusRomNo9L-Regu <8r.enc <utmr8a.pfb
+utmri8r NimbusRomNo9L-ReguItal <8r.enc <utmri8a.pfb
+
+utmbo8r NimbusRomNo9L-Medi ".167 SlantFont" <8r.enc <utmb8a.pfb
+utmro8r NimbusRomNo9L-Regu ".167 SlantFont" <8r.enc <utmr8a.pfb
+
+% times / adobe
+
+ptmb8r NimbusRomNo9L-Medi <8r.enc <utmb8a.pfb
+ptmbi8r NimbusRomNo9L-MediItal <8r.enc <utmbi8a.pfb
+ptmr8r NimbusRomNo9L-Regu <8r.enc <utmr8a.pfb
+ptmri8r NimbusRomNo9L-ReguItal <8r.enc <utmri8a.pfb
+
+ptmbo8r NimbusRomNo9L-Medi ".167 SlantFont" <8r.enc <utmb8a.pfb
+ptmro8r NimbusRomNo9L-Regu ".167 SlantFont" <8r.enc <utmr8a.pfb
+
+% palatino / urw
+
+uplb8r URWPalladioL-Bold <8r.enc <uplb8a.pfb
+uplbi8r URWPalladioL-BoldItal <8r.enc <uplbi8a.pfb
+uplr8r URWPalladioL-Roma <8r.enc <uplr8a.pfb
+uplri8r URWPalladioL-Ital <8r.enc <uplri8a.pfb
+
+uplbo8r URWPalladioL-Bold ".167 SlantFont" <8r.enc <uplb8a.pfb
+uplro8r URWPalladioL-Roma ".167 SlantFont" <8r.enc <uplr8a.pfb
+
+% palatino / adobe
+
+pplb8r URWPalladioL-Bold <8r.enc <uplb8a.pfb
+pplbi8r URWPalladioL-BoldItal <8r.enc <uplbi8a.pfb
+pplr8r URWPalladioL-Roma <8r.enc <uplr8a.pfb
+pplri8r URWPalladioL-Ital <8r.enc <uplri8a.pfb
+
+pplbo8r URWPalladioL-Bold ".167 SlantFont" <8r.enc <uplb8a.pfb
+pplro8r URWPalladioL-Roma ".167 SlantFont" <8r.enc <uplr8a.pfb
+
+% bookman / urw
+
+ubkd8r URWBookmanL-DemiBold <8r.enc <ubkd8a.pfb
+ubkdi8r URWBookmanL-DemiBoldItal <8r.enc <ubkdi8a.pfb
+ubkl8r URWBookmanL-Ligh <8r.enc <ubkl8a.pfb
+ubkli8r URWBookmanL-LighItal <8r.enc <ubkli8a.pfb
+
+ubkdo8r URWBookmanL-DemiBold ".167 SlantFont" <8r.enc <ubkd8a.pfb
+ubklo8r URWBookmanL-Ligh ".167 SlantFont" <8r.enc <ubkl8a.pfb
+
+% bookman / adobe
+
+pbkd8r URWBookmanL-DemiBold <8r.enc <ubkd8a.pfb
+pbkdi8r URWBookmanL-DemiBoldItal <8r.enc <ubkdi8a.pfb
+pbkl8r URWBookmanL-Ligh <8r.enc <ubkl8a.pfb
+pbkli8r URWBookmanL-LighItal <8r.enc <ubkli8a.pfb
+
+pbkdo8r URWBookmanL-DemiBold ".167 SlantFont" <8r.enc <ubkd8a.pfb
+pbklo8r URWBookmanL-Ligh ".167 SlantFont" <8r.enc <ubkl8a.pfb
+
+% chancery / urw
+
+uzcmi8r URWChanceryL-MediItal <8r.enc <uzcmi8a.pfb
+
+% chancery / adobe
+
+pzcmi8r URWChanceryL-MediItal <8r.enc <uzcmi8a.pfb
+
+% schoolbook / urw
+
+uncb8r CenturySchL-Bold <8r.enc <uncb8a.pfb
+uncbi8r CenturySchL-BoldItal <8r.enc <uncbi8a.pfb
+uncr8r CenturySchL-Roma <8r.enc <uncr8a.pfb
+uncri8r CenturySchL-Ital <8r.enc <uncri8a.pfb
+
+uncbo8r CenturySchL-Bold ".167 SlantFont" <8r.enc <uncb8a.pfb
+uncro8r CenturySchL-Roma ".167 SlantFont" <8r.enc <uncr8a.pfb
+
+% schoolbook / adobe
+
+pncb8r CenturySchL-Bold <8r.enc <uncb8a.pfb
+pncbi8r CenturySchL-BoldItal <8r.enc <uncbi8a.pfb
+pncr8r CenturySchL-Roma <8r.enc <uncr8a.pfb
+pncri8r CenturySchL-Ital <8r.enc <uncri8a.pfb
+
+pncbo8r CenturySchL-Bold ".167 SlantFont" <8r.enc <uncb8a.pfb
+pncro8r CenturySchL-Roma ".167 SlantFont" <8r.enc <uncr8a.pfb
+
+% utopia
+
+putb8r Utopia-Bold <8r.enc <putb8a.pfb
+putbi8r Utopia-BoldItalic <8r.enc <putbi8a.pfb
+putr8r Utopia-Regular <8r.enc <putr8a.pfb
+putri8r Utopia-Italic <8r.enc <putri8a.pfb
+
+putbo8r Utopia-Bold ".167 SlantFont" <8r.enc <putb8a.pfb
+putro8r Utopia-Regular ".167 SlantFont" <8r.enc <putr8a.pfb
+
+% charter
+
+bchb8r CharterBT-Bold <8r.enc <bchb8a.pfb
+bchbi8r CharterBT-BoldItalic <8r.enc <bchbi8a.pfb
+bchr8r CharterBT-Roman <8r.enc <bchr8a.pfb
+bchri8r CharterBT-Italic <8r.enc <bchri8a.pfb
+
+bchbo8r CharterBT-Bold ".167 SlantFont" <8r.enc <bchb8a.pfb
+bchro8r CharterBT-Roman ".167 SlantFont" <8r.enc <bchr8a.pfb \ No newline at end of file
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/ec-base.map b/Master/texmf-dist/fonts/map/pdftex/context/ec-base.map
new file mode 100644
index 00000000000..5011a22ca04
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/ec-base.map
@@ -0,0 +1,135 @@
+% courier / urw
+
+ucrb8t NimbusMonL-Bold <ec.enc <ucrb8a.pfb
+ucrbo8t NimbusMonL-BoldObli <ec.enc <ucrbo8a.pfb
+ucrr8t NimbusMonL-Regu <ec.enc <ucrr8a.pfb
+ucrro8t NimbusMonL-ReguObli <ec.enc <ucrro8a.pfb
+
+% courier / adobe
+
+pcrb8t NimbusMonL-Bold <ec.enc <ucrb8a.pfb
+pcrbo8t NimbusMonL-BoldObli <ec.enc <ucrbo8a.pfb
+pcrr8t NimbusMonL-Regu <ec.enc <ucrr8a.pfb
+pcrro8t NimbusMonL-ReguObli <ec.enc <ucrro8a.pfb
+
+% helvetica / urw
+
+uhvb8t NimbusSanL-Bold <ec.enc <uhvb8a.pfb
+uhvbo8t NimbusSanL-BoldItal <ec.enc <uhvbo8a.pfb
+uhvr8t NimbusSanL-Regu <ec.enc <uhvr8a.pfb
+uhvro8t NimbusSanL-ReguItal <ec.enc <uhvro8a.pfb
+
+% helvetica / adobe
+
+phvb8t NimbusSanL-Bold <ec.enc <uhvb8a.pfb
+phvbo8t NimbusSanL-BoldItal <ec.enc <uhvbo8a.pfb
+phvr8t NimbusSanL-Regu <ec.enc <uhvr8a.pfb
+phvro8t NimbusSanL-ReguItal <ec.enc <uhvro8a.pfb
+
+% times / urw
+
+utmb8t NimbusRomNo9L-Medi <ec.enc <utmb8a.pfb
+utmbi8t NimbusRomNo9L-MediItal <ec.enc <utmbi8a.pfb
+utmr8t NimbusRomNo9L-Regu <ec.enc <utmr8a.pfb
+utmri8t NimbusRomNo9L-ReguItal <ec.enc <utmri8a.pfb
+
+utmbo8t NimbusRomNo9L-Medi ".167 SlantFont" <ec.enc <utmb8a.pfb
+utmro8t NimbusRomNo9L-Regu ".167 SlantFont" <ec.enc <utmr8a.pfb
+
+% times / adobe
+
+ptmb8t NimbusRomNo9L-Medi <ec.enc <utmb8a.pfb
+ptmbi8t NimbusRomNo9L-MediItal <ec.enc <utmbi8a.pfb
+ptmr8t NimbusRomNo9L-Regu <ec.enc <utmr8a.pfb
+ptmri8t NimbusRomNo9L-ReguItal <ec.enc <utmri8a.pfb
+
+ptmbo8t NimbusRomNo9L-Medi ".167 SlantFont" <ec.enc <utmb8a.pfb
+ptmro8t NimbusRomNo9L-Regu ".167 SlantFont" <ec.enc <utmr8a.pfb
+
+% palatino / urw
+
+uplb8t URWPalladioL-Bold <ec.enc <uplb8a.pfb
+uplbi8t URWPalladioL-BoldItal <ec.enc <uplbi8a.pfb
+uplr8t URWPalladioL-Roma <ec.enc <uplr8a.pfb
+uplri8t URWPalladioL-Ital <ec.enc <uplri8a.pfb
+
+uplbo8t URWPalladioL-Bold ".167 SlantFont" <ec.enc <uplb8a.pfb
+uplro8t URWPalladioL-Roma ".167 SlantFont" <ec.enc <uplr8a.pfb
+
+% palatino / adobe
+
+pplb8t URWPalladioL-Bold <ec.enc <uplb8a.pfb
+pplbi8t URWPalladioL-BoldItal <ec.enc <uplbi8a.pfb
+pplr8t URWPalladioL-Roma <ec.enc <uplr8a.pfb
+pplri8t URWPalladioL-Ital <ec.enc <uplri8a.pfb
+
+pplbo8t URWPalladioL-Bold ".167 SlantFont" <ec.enc <uplb8a.pfb
+pplro8t URWPalladioL-Roma ".167 SlantFont" <ec.enc <upplr8a.pfb
+
+% bookman / urw
+
+ubkd8t URWBookmanL-DemiBold <ec.enc <ubkd8a.pfb
+ubkdi8t URWBookmanL-DemiBoldItal <ec.enc <ubkdi8a.pfb
+ubkl8t URWBookmanL-Ligh <ec.enc <ubkl8a.pfb
+ubkli8t URWBookmanL-LighItal <ec.enc <ubkli8a.pfb
+
+ubkdo8t URWBookmanL-DemiBold ".167 SlantFont" <ec.enc <ubkd8a.pfb
+ubklo8t URWBookmanL-Ligh ".167 SlantFont" <ec.enc <ubkl8a.pfb
+
+% bookman / adobe
+
+pbkd8t URWBookmanL-DemiBold <ec.enc <ubkd8a.pfb
+pbkdi8t URWBookmanL-DemiBoldItal <ec.enc <ubkdi8a.pfb
+pbkl8t URWBookmanL-Ligh <ec.enc <ubkl8a.pfb
+pbkli8t URWBookmanL-LighItal <ec.enc <ubkli8a.pfb
+
+pbkdo8t URWBookmanL-DemiBold ".167 SlantFont" <ec.enc <ubkd8a.pfb
+pbklo8t URWBookmanL-Ligh ".167 SlantFont" <ec.enc <ubkl8a.pfb
+
+% chancery / urw
+
+uzcmi8t URWChanceryL-MediItal <ec.enc <uzcmi8a.pfb
+
+% chancery / adobe
+
+pzcmi8t URWChanceryL-MediItal <ec.enc <uzcmi8a.pfb
+
+% schoolbook / urw
+
+uncb8t CenturySchL-Bold <ec.enc <uncb8a.pfb
+uncbi8t CenturySchL-BoldItal <ec.enc <uncbi8a.pfb
+uncr8t CenturySchL-Roma <ec.enc <uncr8a.pfb
+uncri8t CenturySchL-Ital <ec.enc <uncri8a.pfb
+
+uncbo8t CenturySchL-Bold ".167 SlantFont" <ec.enc <uncb8a.pfb
+uncro8t CenturySchL-Roma ".167 SlantFont" <ec.enc <uncr8a.pfb
+
+% schoolbook / adobe
+
+pncb8t CenturySchL-Bold <ec.enc <uncb8a.pfb
+pncbi8t CenturySchL-BoldItal <ec.enc <uncbi8a.pfb
+pncr8t CenturySchL-Roma <ec.enc <uncr8a.pfb
+pncri8t CenturySchL-Ital <ec.enc <uncri8a.pfb
+
+pncbo8t CenturySchL-Bold ".167 SlantFont" <ec.enc <uncb8a.pfb
+pncro8t CenturySchL-Roma ".167 SlantFont" <ec.enc <uncr8a.pfb
+
+% utopia
+
+putb8t Utopia-Bold <ec.enc <putb8a.pfb
+putbi8t Utopia-BoldItalic <ec.enc <putbi8a.pfb
+putr8t Utopia-Regular <ec.enc <putr8a.pfb
+putri8t Utopia-Italic <ec.enc <putri8a.pfb
+
+putbo8t Utopia-Bold ".167 SlantFont" <ec.enc <putb8a.pfb
+putro8t Utopia-Regular ".167 SlantFont" <ec.enc <putr8a.pfb
+
+% charter
+
+bchb8t CharterBT-Bold <ec.enc <bchb8a.pfb
+bchbi8t CharterBT-BoldItalic <ec.enc <bchbi8a.pfb
+bchr8t CharterBT-Roman <ec.enc <bchr8a.pfb
+bchri8t CharterBT-Italic <ec.enc <bchri8a.pfb
+
+bchbo8t CharterBT-Bold ".167 SlantFont" <ec.enc <bchb8a.pfb
+bchro8t CharterBT-Roman ".167 SlantFont" <ec.enc <bchr8a.pfb \ No newline at end of file
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/ec-os-public-lm.map b/Master/texmf-dist/fonts/map/pdftex/context/ec-os-public-lm.map
new file mode 100644
index 00000000000..d68013c36f3
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/ec-os-public-lm.map
@@ -0,0 +1,69 @@
+ec-lmb10 LMRoman10-Demi "enclmecos ReEncodeFont" <lm-ec-os.enc <lmb10.pfb
+ec-lmbo10 LMRoman10-DemiOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbo10.pfb
+ec-lmbx10 LMRoman10-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbx10.pfb
+ec-lmbx12 LMRoman12-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbx12.pfb
+ec-lmbx5 LMRoman5-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbx5.pfb
+ec-lmbx6 LMRoman6-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbx6.pfb
+ec-lmbx7 LMRoman7-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbx7.pfb
+ec-lmbx8 LMRoman8-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbx8.pfb
+ec-lmbx9 LMRoman9-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbx9.pfb
+ec-lmbxi10 LMRoman10-BoldItalic "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbxi10.pfb
+ec-lmbxo10 LMRoman10-BoldOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmbxo10.pfb
+ec-lmcsc10 LMRoman10-CapsRegular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmcsc10.pfb
+ec-lmcsco10 LMRoman10-CapsOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmcsco10.pfb
+ec-lmr10 LMRoman10-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr10.pfb
+ec-lmr12 LMRoman12-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr12.pfb
+ec-lmr17 LMRoman17-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr17.pfb
+ec-lmr5 LMRoman5-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr5.pfb
+ec-lmr6 LMRoman6-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr6.pfb
+ec-lmr7 LMRoman7-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr7.pfb
+ec-lmr8 LMRoman8-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr8.pfb
+ec-lmr9 LMRoman9-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmr9.pfb
+ec-lmri10 LMRoman10-Italic "enclmecos ReEncodeFont" <lm-ec-os.enc <lmri10.pfb
+ec-lmri12 LMRoman12-Italic "enclmecos ReEncodeFont" <lm-ec-os.enc <lmri12.pfb
+ec-lmri7 LMRoman7-Italic "enclmecos ReEncodeFont" <lm-ec-os.enc <lmri7.pfb
+ec-lmri8 LMRoman8-Italic "enclmecos ReEncodeFont" <lm-ec-os.enc <lmri8.pfb
+ec-lmri9 LMRoman9-Italic "enclmecos ReEncodeFont" <lm-ec-os.enc <lmri9.pfb
+ec-lmro10 LMRoman10-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmro10.pfb
+ec-lmro12 LMRoman12-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmro12.pfb
+ec-lmro17 LMRoman17-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmro17.pfb
+ec-lmro8 LMRoman8-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmro8.pfb
+ec-lmro9 LMRoman9-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmro9.pfb
+ec-lmss10 LMSans10-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmss10.pfb
+ec-lmss12 LMSans12-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmss12.pfb
+ec-lmss17 LMSans17-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmss17.pfb
+ec-lmss8 LMSans8-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmss8.pfb
+ec-lmss9 LMSans9-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmss9.pfb
+ec-lmssbo10 LMSans10-BoldOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssbo10.pfb
+ec-lmssbx10 LMSans10-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssbx10.pfb
+ec-lmssdc10 LMSans10-DemiCondensed "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssdc10.pfb
+ec-lmssdo10 LMSans10-DemiCondensedOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssdo10.pfb
+ec-lmsso10 LMSans10-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmsso10.pfb
+ec-lmsso12 LMSans12-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmsso12.pfb
+ec-lmsso17 LMSans17-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmsso17.pfb
+ec-lmsso8 LMSans8-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmsso8.pfb
+ec-lmsso9 LMSans9-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmsso9.pfb
+ec-lmssq8 LMSansQuotation8-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssq8.pfb
+ec-lmssqbo8 LMSansQuotation8-BoldOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssqbo8.pfb
+ec-lmssqbx8 LMSansQuotation8-Bold "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssqbx8.pfb
+ec-lmssqo8 LMSansQuotation8-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmssqo8.pfb
+ec-lmtcsc10 LMTypewriter10-CapsRegular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtcsc10.pfb
+ec-lmtcso10 LMTypewriter10-CapsOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtcso10.pfb
+ec-lmtl10 LMTypewriter10-Light "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtl10.pfb
+ec-lmtlo10 LMTypewriter10-LightOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtlo10.pfb
+ec-lmtlc10 LMTypewriter10-LightCondensed "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtlc10.pfb
+ec-lmtlco10 LMTypewriter10-LightCondensedOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtlco10.pfb
+ec-lmtk10 LMTypewriter10-Dark "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtk10.pfb
+ec-lmtko10 LMTypewriter10-DarkOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtko10.pfb
+ec-lmtt10 LMTypewriter10-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtt10.pfb
+ec-lmtt12 LMTypewriter12-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtt12.pfb
+ec-lmtt8 LMTypewriter8-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtt8.pfb
+ec-lmtt9 LMTypewriter9-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtt9.pfb
+ec-lmtti10 LMTypewriter10-Italic "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtti10.pfb
+ec-lmtto10 LMTypewriter10-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmtto10.pfb
+ec-lmvtt10 LMTypewriterVarWd10-Regular "enclmecos ReEncodeFont" <lm-ec-os.enc <lmvtt10.pfb
+ec-lmvtto10 LMTypewriterVarWd10-Oblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmvtto10.pfb
+ec-lmvtl10 LMTypewriterVarWd10-Light "enclmecos ReEncodeFont" <lm-ec-os.enc <lmvtl10.pfb
+ec-lmvtlo10 LMTypewriterVarWd10-LightOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmvtlo10.pfb
+ec-lmvtk10 LMTypewriterVarWd10-Dark "enclmecos ReEncodeFont" <lm-ec-os.enc <lmvtk10.pfb
+ec-lmvtko10 LMTypewriterVarWd10-DarkOblique "enclmecos ReEncodeFont" <lm-ec-os.enc <lmvtko10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/mkiv-base.map b/Master/texmf-dist/fonts/map/pdftex/context/mkiv-base.map
new file mode 100644
index 00000000000..fc2aa643b39
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/mkiv-base.map
@@ -0,0 +1,224 @@
+% some left-overs
+
+% context
+
+contnav ContextNavigation <contnav.pfb
+hans Hans-Regular <hans.pfb
+hans-sh Hans-sh-Regular <hans-sh.pfb
+
+% dingbats
+
+uzdr Dingbats <uzdr.pfb
+pzdr Dingbats <pzdr.pfb
+
+% symbols
+
+usyr StandardSymL <usyr.pfb
+
+% ralph
+
+rsfs7 rsfs5 <rsfs7.pfb
+rsfs5 rsfs7 <rsfs5.pfb
+rsfs10 rsfs10 <rsfs10.pfb
+
+% marvosym
+
+fmvr8x MarVoSym <marvosym.pfb
+fmvri8x MarVoSym ".167 SlantFont" <marvosym.pfb
+
+% xypic
+
+xyatip10 XYATIP10 <xyatip10.pfb
+xybsql10 XYBSQL10 <xybsql10.pfb
+xybtip10 XYBTIP10 <xybtip10.pfb
+xycirc10 XYCIRC10 <xycirc10.pfb
+xydash10 XYDASH10 <xydash10.pfb
+
+xycmat10 XYCMAT10 <xycmat10.pfb
+xycmbt10 XYCMBT10 <xycmbt10.pfb
+xyeuat10 XYEUAT10 <xyeuat10.pfb
+xyeubt10 XYEUBT10 <xyeubt10.pfb
+
+xycmat11 XYCMAT10 "1.1 ExtendFont" <xycmat10.pfb
+xycmbt11 XYCMBT10 "1.1 ExtendFont" <xycmbt10.pfb
+xyeuat11 XYEUAT10 "1.1 ExtendFont" <xyeuat10.pfb
+xyeubt11 XYEUBT10 "1.1 ExtendFont" <xyeubt10.pfb
+
+xycmat12 XYCMAT10 "1.2 ExtendFont" <xycmat10.pfb
+xycmbt12 XYCMBT10 "1.2 ExtendFont" <xycmbt10.pfb
+xyeuat12 XYEUAT10 "1.2 ExtendFont" <xyeuat10.pfb
+xyeubt12 XYEUBT10 "1.2 ExtendFont" <xyeubt10.pfb
+
+% euro
+
+zpeub EuroSerif-Bold <zpeub.pfb
+zpeubi EuroSerif-BoldItalic <zpeubi.pfb
+zpeubis EuroSans-BoldItalic <zpeubis.pfb
+zpeubit EuroMono-BoldItalic <zpeubit.pfb
+zpeubs EuroSans-Bold <zpeubs.pfb
+zpeubt EuroMono-Bold <zpeubt.pfb
+zpeur EuroSerif-Regular <zpeur.pfb
+zpeuri EuroSerif-Italic <zpeuri.pfb
+zpeuris EuroSans-Italic <zpeuris.pfb
+zpeurit EuroMono-Italic <zpeurit.pfb
+zpeurs EuroSans-Regular <zpeurs.pfb
+zpeurt EuroMono-Regular <zpeurt.pfb
+
+% not used i think
+
+lasy5 LASY5 <lasy5.pfb
+lasy6 LASY6 <lasy6.pfb
+lasy7 LASY7 <lasy7.pfb
+lasy8 LASY8 <lasy8.pfb
+lasy9 LASY9 <lasy9.pfb
+lasy10 LASY10 <lasy10.pfb
+
+lasyb10 LASYB10 <lasyb10.pfb
+lcircle10 LCIRCLE10 <lcircle1.pfb
+lcirclew10 LCIRCLEW10 <lcirclew.pfb
+lcmss8 LCMSS8 <lcmss8.pfb
+lcmssb8 LCMSSB8 <lcmssb8.pfb
+lcmssi8 LCMSSI8 <lcmssi8.pfb
+line10 LINE10 <line10.pfb
+linew10 LINEW10 <linew10.pfb
+
+wncyb10 WNCYB10 <wncyb10.pfb
+wncyi10 WNCYI10 <wncyi10.pfb
+wncyr10 WNCYR10 <wncyr10.pfb
+wncysc10 WNCYSC10 <wncysc10.pfb
+wncyss10 WNCYSS10 <wncyss10.pfb
+
+manfnt MANFNT <manfnt.pfb
+
+% ams
+
+msam5 MSAM5 <msam5.pfb
+msam7 MSAM7 <msam7.pfb
+msam10 MSAM10 <msam10.pfb
+msbm5 MSBM5 <msbm5.pfb
+msbm7 MSBM7 <msbm7.pfb
+msbm10 MSBM10 <msbm10.pfb
+
+% metapost
+
+logo8 LOGO8 <logo8.pfb
+logo9 LOGO9 <logo9.pfb
+logo10 LOGO10 <logo10.pfb
+logobf10 LOGOBF10 <logobf10.pfb
+logosl10 LOGOSL10 <logosl10.pfb
+
+% euler .. used for manuals
+
+euex10 EUEX10 <euex10.pfb
+
+eufb5 EUFB5 <eufb5.pfb
+eufb7 EUFB7 <eufb7.pfb
+eufb10 EUFB10 <eufb10.pfb
+
+eufm5 EUFM5 <eufm5.pfb
+eufm7 EUFM7 <eufm7.pfb
+eufm10 EUFM10 <eufm10.pfb
+
+eurb5 EURB5 <eurb5.pfb
+eurb7 EURB7 <eurb7.pfb
+eurb10 EURB10 <eurb10.pfb
+
+eurm5 EURM5 <eurm5.pfb
+eurm7 EURM7 <eurm7.pfb
+eurm10 EURM10 <eurm10.pfb
+
+eusb5 EUSB5 <eusb5.pfb
+eusb7 EUSB7 <eusb7.pfb
+eusb10 EUSB10 <eusb10.pfb
+
+eusm5 EUSM5 <eusm5.pfb
+eusm7 EUSM7 <eusm7.pfb
+eusm10 EUSM10 <eusm10.pfb
+
+% original
+
+cmtex10 CMTEX10 <cmtex10.pfb
+cmtex8 CMTEX8 <cmtex8.pfb
+cmtex9 CMTEX9 <cmtex9.pfb
+
+cmff10 CMFF10 <cmff10.pfb
+cmfi10 CMFI10 <cmfi10.pfb
+cmfib8 CMFIB8 <cmfib8.pfb
+
+% the latest gust list
+
+cmb10 LMRomanDemi10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmb10.pfb
+cmbx10 LMRoman10-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmbx10.pfb
+cmbx5 LMRoman5-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmbx5.pfb
+cmbx6 LMRoman6-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmbx6.pfb
+cmbx7 LMRoman7-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmbx7.pfb
+cmbx8 LMRoman8-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmbx8.pfb
+cmbx9 LMRoman9-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmbx9.pfb
+cmbxsl10 LMRomanSlant10-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmbxo10.pfb
+cmbxti10 LMRoman10-BoldItalic "enclmrepcmit ReEncodeFont" <lm-rep-cmit.enc <lmbxi10.pfb
+cmcsc10 LMRomanCaps10-Regular "enclmrepcmsc ReEncodeFont" <lm-rep-cmsc.enc <lmcsc10.pfb
+cmcscsl10 LMRomanCaps10-Oblique "enclmrepcmsc ReEncodeFont" <lm-rep-cmsc.enc <lmcsco10.pfb
+cmdunh10 LMRomanDunh10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmdunh10.pfb
+cminch LMSans10-Bold "enclmrepcmin ReEncodeFont" <lm-rep-cmin.enc <lmssbx10.pfb
+cmitt10 LMMono10-Italic "enclmrepcmitt ReEncodeFont" <lm-rep-cmitt.enc <lmtti10.pfb
+cmr10 LMRoman10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmr10.pfb
+cmr12 LMRoman12-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmr12.pfb
+cmr17 LMRoman17-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmr17.pfb
+cmr5 LMRoman5-Regular "enclmrepcmsc ReEncodeFont" <lm-rep-cmsc.enc <lmr5.pfb
+cmr6 LMRoman6-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmr6.pfb
+cmr7 LMRoman7-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmr7.pfb
+cmr8 LMRoman8-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmr8.pfb
+cmr9 LMRoman9-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmr9.pfb
+cmsl10 LMRomanSlant10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmro10.pfb
+cmsl12 LMRomanSlant12-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmro12.pfb
+cmsl8 LMRomanSlant8-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmro8.pfb
+cmsl9 LMRomanSlant9-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmro9.pfb
+cmsltt10 LMMonoSlant10-Regular "enclmrepcmtt ReEncodeFont" <lm-rep-cmtt.enc <lmtto10.pfb
+cmss10 LMSans10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmss10.pfb
+cmss12 LMSans12-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmss12.pfb
+cmss17 LMSans17-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmss17.pfb
+cmss8 LMSans8-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmss8.pfb
+cmss9 LMSans9-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmss9.pfb
+cmssbx10 LMSans10-Bold "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmssbx10.pfb
+cmssbxo10 LMSans10-BoldOblique "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmssbo10.pfb
+cmssdc10 LMSansDemiCond10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmssdc10.pfb
+cmssi10 LMSans10-Oblique "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmsso10.pfb
+cmssi12 LMSans12-Oblique "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmsso12.pfb
+cmssi17 LMSans17-Oblique "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmsso17.pfb
+cmssi8 LMSans8-Oblique "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmsso8.pfb
+cmssi9 LMSans9-Oblique "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmsso9.pfb
+cmssq8 LMSansQuot8-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmssq8.pfb
+cmssqi8 LMSansQuot8-Oblique "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmssqo8.pfb
+cmtcsc10 LMMonoCaps10-Regular "enclmrepcmtt ReEncodeFont" <lm-rep-cmtt.enc <lmtcsc10.pfb
+cmti10 LMRoman10-Italic "enclmrepcmit ReEncodeFont" <lm-rep-cmit.enc <lmri10.pfb
+cmti12 LMRoman12-Italic "enclmrepcmit ReEncodeFont" <lm-rep-cmit.enc <lmri12.pfb
+cmti7 LMRoman7-Italic "enclmrepcmit ReEncodeFont" <lm-rep-cmit.enc <lmri7.pfb
+cmti8 LMRoman8-Italic "enclmrepcmit ReEncodeFont" <lm-rep-cmit.enc <lmri8.pfb
+cmti9 LMRoman9-Italic "enclmrepcmit ReEncodeFont" <lm-rep-cmit.enc <lmri9.pfb
+cmtt10 LMMono10-Regular "enclmrepcmtt ReEncodeFont" <lm-rep-cmtt.enc <lmtt10.pfb
+cmtt12 LMMono12-Regular "enclmrepcmtt ReEncodeFont" <lm-rep-cmtt.enc <lmtt12.pfb
+cmtt8 LMMono8-Regular "enclmrepcmtt ReEncodeFont" <lm-rep-cmtt.enc <lmtt8.pfb
+cmtt9 LMMono9-Regular "enclmrepcmtt ReEncodeFont" <lm-rep-cmtt.enc <lmtt9.pfb
+cmu10 LMRomanUnsl10-Regular "enclmrepcmit ReEncodeFont" <lm-rep-cmit.enc <lmu10.pfb
+cmvtt10 LMMonoProp10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmvtt10.pfb
+
+cmbsy5 LMMathSymbols5-Bold "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy5.pfb
+cmbsy7 LMMathSymbols7-Bold "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy7.pfb
+cmbsy10 LMMathSymbols10-Bold "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy10.pfb
+cmsy5 LMMathSymbols5-Regular "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy5.pfb
+cmsy6 LMMathSymbols6-Regular "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy6.pfb
+cmsy7 LMMathSymbols7-Regular "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy7.pfb
+cmsy8 LMMathSymbols8-Regular "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy8.pfb
+cmsy9 LMMathSymbols9-Regular "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy9.pfb
+cmsy10 LMMathSymbols10-Regular "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy10.pfb
+cmex10 LMMathExtension10-Regular "enclmmathex ReEncodeFont" <lm-mathex.enc <lmex10.pfb
+cmmi5 LMMathItalic5-Regular "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi5.pfb
+cmmi6 LMMathItalic6-Regular "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi6.pfb
+cmmi7 LMMathItalic7-Regular "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi7.pfb
+cmmi8 LMMathItalic8-Regular "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi8.pfb
+cmmi9 LMMathItalic9-Regular "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi9.pfb
+cmmi10 LMMathItalic10-Regular "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi10.pfb
+cmmi12 LMMathItalic12-Regular "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi12.pfb
+cmmib5 LMMathItalic5-Bold "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib5.pfb
+cmmib7 LMMathItalic7-Bold "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib7.pfb
+cmmib10 LMMathItalic10-Bold "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/mkiv-px.map b/Master/texmf-dist/fonts/map/pdftex/context/mkiv-px.map
new file mode 100644
index 00000000000..6ed671fb18a
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/mkiv-px.map
@@ -0,0 +1,51 @@
+% This file a (slightly adapted) copy of the map file
+% that comes with the PX fonts by Young Ryu.
+
+% URW fonts replaced by TeX Gyre
+
+% TeX Gyre Pagella (Palatino)
+
+% rpxpplr TeXGyrePagella-Regular "encq8r ReEncodeFont" <q-8r.enc <qplr.pfb
+% rpxpplb TeXGyrePagella-Bold "encq8r ReEncodeFont" <q-8r.enc <qplb.pfb
+% rpxpplri TeXGyrePagella-Italic "encq8r ReEncodeFont" <q-8r.enc <qplri.pfb
+% rpxpplbi TeXGyrePagella-BoldItalic "encq8r ReEncodeFont" <q-8r.enc <qplbi.pfb
+% % no idea why these were added
+% rpxpplro TeXGyrePagella-Oblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qplr.pfb
+% rpxpplbo TeXGyrePagella-BoldOblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qplb.pfb
+
+% PX Text
+
+rpxr rpxr <rpxr.pfb
+rpxsl rpxr ".167 SlantFont" <rpxr.pfb
+rpxi rpxi <rpxi.pfb
+rpxsc rpxsc <rpxsc.pfb
+rpxb rpxb <rpxb.pfb
+rpxbsl rpxb ".167 SlantFont" <rpxb.pfb
+rpxbi rpxbi <rpxbi.pfb
+rpxbsc rpxbsc <rpxbsc.pfb
+rpcxb rpcxb <rpcxb.pfb
+rpcxbsl rpcxb ".167 SlantFont" <rpcxb.pfb
+rpcxbi rpcxbi <rpcxbi.pfb
+rpcxi rpcxi <rpcxi.pfb
+rpcxr rpcxr <rpcxr.pfb
+rpcxsl rpcxsl ".167 SlantFont" <rpcxr.pfb
+
+% PX Math
+
+rpxbmi rpxbmi <rpxbmi.pfb
+rpxmi rpxmi <rpxmi.pfb
+
+pxbex pxbex <pxbex.pfb
+pxbexa pxbexa <pxbexa.pfb
+pxbmia pxbmia <pxbmia.pfb
+pxbsy pxbsy <pxbsy.pfb
+pxbsya pxbsya <pxbsya.pfb
+pxbsyb pxbsyb <pxbsyb.pfb
+pxbsyc pxbsyc <pxbsyc.pfb
+pxex pxex <pxex.pfb
+pxexa pxexa <pxexa.pfb
+pxmia pxmia <pxmia.pfb
+pxsy pxsy <pxsy.pfb
+pxsya pxsya <pxsya.pfb
+pxsyb pxsyb <pxsyb.pfb
+pxsyc pxsyc <pxsyc.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/mkiv-tx.map b/Master/texmf-dist/fonts/map/pdftex/context/mkiv-tx.map
new file mode 100644
index 00000000000..bd2430da7cd
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/mkiv-tx.map
@@ -0,0 +1,94 @@
+% This file is a (slightly adapted) copy of the map file
+% that comes with the TX fonts by Young Ryu.
+
+% URW fonts replaced by TeX Gyre
+
+% TeX Gyre Termes (Times)
+
+% rtxptmr TeXGyreTermes-Regular "encq8r ReEncodeFont" <q-8r.enc <qtmr.pfb
+% rtxptmb TeXGyreTermes-Bold "encq8r ReEncodeFont" <q-8r.enc <qtmb.pfb
+% rtxptmri TeXGyreTermes-Italic "encq8r ReEncodeFont" <q-8r.enc <qtmri.pfb
+% rtxptmbi TeXGyreTermes-BoldItalic "encq8r ReEncodeFont" <q-8r.enc <qtmbi.pfb
+% % no idea why these were added
+% rtxptmro TeXGyreTermes-Oblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qtmr.pfb
+% rtxptmbo TeXGyreTermes-BoldOblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qtmb.pfb
+%
+% % TeX Gyre Heros (Helvetica)
+%
+% rtxphvr TeXGyreHeros-Regular "encqrm ReEncodeFont" <q-rm.enc <qtmr.pfb
+% rtxphvb TeXGyreHeros-Bold "encqrm ReEncodeFont" <q-rm.enc <qtmb.pfb
+% % probably not used by txfonts
+% % rtxphvri TeXGyreHeros-Italic "encqrm ReEncodeFont" <q-rm.enc <qtmri.pfb
+% % rtxphvbi TeXGyreHeros-BoldItalic "encqrm ReEncodeFont" <q-rm.enc <qtmbi.pfb
+% % followed original definitions; one could also use the italic version
+% rtxphvro TeXGyreHeros-Oblique ".167 SlantFont encqrm ReEncodeFont" <q-rm.enc <qtmr.pfb
+% rtxphvbo TeXGyreHeros-BoldOblique ".167 SlantFont encqrm ReEncodeFont" <q-rm.enc <qtmb.pfb
+
+% TX Text
+
+rtxr rtxr <rtxr.pfb
+rtxsl rtxr ".167 SlantFont" <rtxr.pfb
+rtxi rtxi <rtxi.pfb
+rtxsc rtxsc <rtxsc.pfb
+rtxb rtxb <rtxb.pfb
+rtxbsl rtxb ".167 SlantFont" <rtxb.pfb
+rtxbi rtxbi <rtxbi.pfb
+rtxbsc rtxbsc <rtxbsc.pfb
+rtcxb rtcxb <rtcxb.pfb
+rtcxbsl rtcxb ".167 SlantFont" <rtcxb.pfb
+rtcxbi rtcxbi <rtcxbi.pfb
+rtcxi rtcxi <rtcxi.pfb
+rtcxr rtcxr <rtcxr.pfb
+rtcxsl rtcx ".167 SlantFont" <rtcxr.pfb
+
+% TX Math
+
+rtxbmi rtxbmi <rtxbmi.pfb
+rtxmi rtxmi <rtxmi.pfb
+
+txbex txbex <txbex.pfb
+txbexa txbexa <txbexa.pfb
+txbmia txbmia <txbmia.pfb
+txbsy txbsy <txbsy.pfb
+txbsya txbsya <txbsya.pfb
+txbsyb txbsyb <txbsyb.pfb
+txbsyc txbsyc <txbsyc.pfb
+txex txex <txex.pfb
+txexa txexa <txexa.pfb
+txmia txmia <txmia.pfb
+txsy txsy <txsy.pfb
+txsya txsya <txsya.pfb
+txsyb txsyb <txsyb.pfb
+txsyc txsyc <txsyc.pfb
+
+% TX TT Text
+
+txtt txtt <txtt.pfb
+txttsl txtt ".167 SlantFont" <txtt.pfb
+txttsc txttsc <txttsc.pfb
+txbtt txbtt <txbtt.pfb
+txbttsl txbtt ".167 SlantFont" <txbtt.pfb
+txbttsc txbttsc <txbttsc.pfb
+t1xtt t1xtt <t1xtt.pfb
+t1xttsl t1xtt ".167 SlantFont" <t1xtt.pfb
+t1xttsc t1xttsc <t1xttsc.pfb
+t1xbtt t1xbtt <t1xbtt.pfb
+t1xbttsl t1xbtt ".167 SlantFont" <t1xbtt.pfb
+t1xbttsc t1xbttsc <t1xbttsc.pfb
+tcxtt tcxtt <tcxtt.pfb
+tcxttsl tcxtt ".167 SlantFont" <tcxtt.pfb
+tcxbtt tcxbtt <tcxbtt.pfb
+tcxbttsl tcxbtt ".167 SlantFont" <tcxbtt.pfb
+
+% TX SS Text
+
+rtxss rtxss <rtxss.pfb
+rtxsssl rtxss ".167 SlantFont" <rtxss.pfb
+rtxsssc rtxsssc <rtxsssc.pfb
+rtxbss rtxbss <rtxbss.pfb
+rtxbsssl rtxbss ".167 SlantFont" <rtxbss.pfb
+rtxbsssc rtxbsssc <rtxbsssc.pfb
+rtcxss rtcxss <rtcxss.pfb
+rtcxbss rtcxbss <rtcxbss.pfb
+rtcxsssl rtcxss ".167 SlantFont" <rtcxss.pfb
+rtcxbsso rtcxbss ".167 SlantFont" <rtcxbss.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-adobe-euro.map b/Master/texmf-dist/fonts/map/pdftex/context/original-adobe-euro.map
new file mode 100644
index 00000000000..5ba47a50aa7
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-adobe-euro.map
@@ -0,0 +1,25 @@
+euromo EuroMono-Regular <euromo.pfb
+euromob EuroMono-Bold <euromob.pfb
+euromoi EuroMono-Italic <euromoi.pfb
+euromobi EuroMono-BoldItalic <euromobi.pfb
+eurosa EuroSans-Regular <eurosa.pfb
+eurosab EuroSans-Bold <eurosab.pfb
+eurosai EuroSans-Italic <eurosai.pfb
+eurosabi EuroSans-BoldItalic <eurosebi.pfb
+eurose EuroSerif-Regular <eurose.pfb
+euroseb EuroSerif-Bold <euroseb.pfb
+eurosei EuroSerif-Italic <eurosei.pfb
+eurosebi EuroSerif-BoldItalic <eurosebi.pfb
+
+% euromo <_2______.pfb
+% euromob <_2b_____.pfb
+% euromoi <_2i_____.pfb
+% euromobi <_2bi____.pfb
+% eurosa <_1______.pfb
+% eurosab <_1b_____.pfb
+% eurosai <_1i_____.pfb
+% eurosabi <_1bi____.pfb
+% eurose <_3______.pfb
+% euroseb <_3b_____.pfb
+% eurosei <_3i_____.pfb
+% eurosebi <_3bi____.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-ams-base.map b/Master/texmf-dist/fonts/map/pdftex/context/original-ams-base.map
new file mode 100644
index 00000000000..aa8818ec0e0
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-ams-base.map
@@ -0,0 +1,47 @@
+lasy5 LASY5 <lasy5.pfb
+lasy6 LASY6 <lasy6.pfb
+lasy7 LASY7 <lasy7.pfb
+lasy8 LASY8 <lasy8.pfb
+lasy9 LASY9 <lasy9.pfb
+lasy10 LASY10 <lasy10.pfb
+
+lasyb10 LASYB10 <lasyb10.pfb
+lcircle10 LCIRCLE10 <lcircle1.pfb
+lcirclew10 LCIRCLEW10 <lcirclew.pfb
+lcmss8 LCMSS8 <lcmss8.pfb
+lcmssb8 LCMSSB8 <lcmssb8.pfb
+lcmssi8 LCMSSI8 <lcmssi8.pfb
+line10 LINE10 <line10.pfb
+linew10 LINEW10 <linew10.pfb
+
+logo8 LOGO8 <logo8.pfb
+logo9 LOGO9 <logo9.pfb
+logo10 LOGO10 <logo10.pfb
+logobf10 LOGOBF10 <logobf10.pfb
+logosl10 LOGOSL10 <logosl10.pfb
+
+msam5 MSAM5 <msam5.pfb
+msam7 MSAM7 <msam7.pfb
+msam10 MSAM10 <msam10.pfb
+msbm5 MSBM5 <msbm5.pfb
+msbm7 MSBM7 <msbm7.pfb
+msbm10 MSBM10 <msbm10.pfb
+
+wncyb10 WNCYB10 <wncyb10.pfb
+wncyi10 WNCYI10 <wncyi10.pfb
+wncyr10 WNCYR10 <wncyr10.pfb
+wncysc10 WNCYSC10 <wncysc10.pfb
+wncyss10 WNCYSS10 <wncyss10.pfb
+
+manfnt MANFNT <manfnt.pfb
+
+% i dunno what this is
+
+icmex10 <icmex10.pfb
+icmmi8 <icmmi8.pfb
+icmsy8 <icmsy8.pfb
+icmtt8 <icmtt8.pfb
+ilasy8 <ilasy8.pfb
+ilcmss8 <ilcmss8.pfb
+ilcmssb8 <ilcmssb8.pfb
+ilcmssi8 <ilcmssi8.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-ams-cmr.map b/Master/texmf-dist/fonts/map/pdftex/context/original-ams-cmr.map
new file mode 100644
index 00000000000..6139ad754b8
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-ams-cmr.map
@@ -0,0 +1,97 @@
+cmb10 CMB10 <cmb10.pfb
+
+cmbsy6 CMBSY6 <cmbsy6.pfb
+cmbsy7 CMBSY7 <cmbsy7.pfb
+cmbsy8 CMBSY8 <cmbsy8.pfb
+cmbsy9 CMBSY9 <cmbsy9.pfb
+cmbsy10 CMBSY10 <cmbsy10.pfb
+
+cmbx5 CMBX5 <cmbx5.pfb
+cmbx6 CMBX6 <cmbx6.pfb
+cmbx7 CMBX7 <cmbx7.pfb
+cmbx8 CMBX8 <cmbx8.pfb
+cmbx9 CMBX9 <cmbx9.pfb
+cmbx10 CMBX10 <cmbx10.pfb
+cmbx12 CMBX10 <cmbx12.pfb
+
+cmbxsl10 CMBXSL10 <cmbxsl10.pfb
+cmbxti10 CMBXTI10 <cmbxti10.pfb
+
+cmcsc10 CMCSC10 <cmcsc10.pfb
+cmdunh10 CMDUNH10 <cmdunh10.pfb
+cmex10 CMEX10 <cmex10.pfb
+cmff10 CMFF10 <cmff10.pfb
+cmfi10 CMFI10 <cmfi10.pfb
+cmfib8 CMFIB8 <cmfib8.pfb
+cminch CMINCH <cminch.pfb
+cmitt10 CMITT10 <cmitt10.pfb
+cmmib10 CMMIB10 <cmmib10.pfb
+
+cmmi5 CMMI5 <cmmi5.pfb
+cmmi6 CMMI6 <cmmi6.pfb
+cmmi7 CMMI7 <cmmi7.pfb
+cmmi8 CMMI8 <cmmi8.pfb
+cmmi9 CMMI9 <cmmi9.pfb
+cmmi10 CMMI10 <cmmi10.pfb
+cmmi12 CMMI12 <cmmi12.pfb
+
+cmr5 CMR5 <cmr5.pfb
+cmr6 CMR6 <cmr6.pfb
+cmr7 CMR7 <cmr7.pfb
+cmr8 CMR8 <cmr8.pfb
+cmr9 CMR9 <cmr9.pfb
+cmr10 CMR10 <cmr10.pfb
+cmr12 CMR12 <cmr12.pfb
+cmr17 CMR17 <cmr17.pfb
+
+cmsl8 CMSL8 <cmsl8.pfb
+cmsl9 CMSL9 <cmsl9.pfb
+cmsl10 CMSL10 <cmsl10.pfb
+cmsl12 CMSL12 <cmsl12.pfb
+
+cmsltt10 CMSLTT10 <cmsltt10.pfb
+
+cmss8 CMSS8 <cmss8.pfb
+cmss9 CMSS9 <cmss9.pfb
+cmss10 CMSS10 <cmss10.pfb
+cmss12 CMSS12 <cmss12.pfb
+cmss17 CMSS17 <cmss17.pfb
+
+cmssbx10 CMSSBX10 <cmssbx10.pfb
+cmssdc10 CMSSDC10 <cmssdc10.pfb
+
+cmssi8 CMSSI8 <cmssi8.pfb
+cmssi9 CMSSI9 <cmssi9.pfb
+cmssi10 CMSSI10 <cmssi10.pfb
+cmssi12 CMSSI12 <cmssi12.pfb
+cmssi17 CMSSI17 <cmssi17.pfb
+
+cmssq8 CMSSQ8 <cmssq8.pfb
+cmssqi8 CMSSQI8 <cmssqi8.pfb
+
+cmsy5 CMSY5 <cmsy5.pfb
+cmsy6 CMSY6 <cmsy6.pfb
+cmsy7 CMSY7 <cmsy7.pfb
+cmsy8 CMSY8 <cmsy8.pfb
+cmsy9 CMSY9 <cmsy9.pfb
+cmsy10 CMSY10 <cmsy10.pfb
+
+cmtcsc10 CMTCSC10 <cmtcsc10.pfb
+
+cmtex8 CMTEX8 <cmtex8.pfb
+cmtex9 CMTEX9 <cmtex9.pfb
+cmtex10 CMTEX10 <cmtex10.pfb
+
+cmti7 CMTI7 <cmti7.pfb
+cmti8 CMTI8 <cmti8.pfb
+cmti9 CMTI9 <cmti9.pfb
+cmti10 CMTI10 <cmti10.pfb
+cmti12 CMTI12 <cmti12.pfb
+
+cmtt8 CMTT8 <cmtt8.pfb
+cmtt9 CMTT9 <cmtt9.pfb
+cmtt10 CMTT10 <cmtt10.pfb
+cmtt12 CMTT12 <cmtt12.pfb
+
+cmu10 CMU10 <cmu10.pfb
+cmvtt10 CMVTT10 <cmvtt10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-ams-euler.map b/Master/texmf-dist/fonts/map/pdftex/context/original-ams-euler.map
new file mode 100644
index 00000000000..34b94c34c05
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-ams-euler.map
@@ -0,0 +1,25 @@
+euex10 EUEX10 <euex10.pfb
+
+eufb5 EUFB5 <eufb5.pfb
+eufb7 EUFB7 <eufb7.pfb
+eufb10 EUFB10 <eufb10.pfb
+
+eufm5 EUFM5 <eufm5.pfb
+eufm7 EUFM7 <eufm7.pfb
+eufm10 EUFM10 <eufm10.pfb
+
+eurb5 EURB5 <eurb5.pfb
+eurb7 EURB7 <eurb7.pfb
+eurb10 EURB10 <eurb10.pfb
+
+eurm5 EURM5 <eurm5.pfb
+eurm7 EURM7 <eurm7.pfb
+eurm10 EURM10 <eurm10.pfb
+
+eusb5 EUSB5 <eusb5.pfb
+eusb7 EUSB7 <eusb7.pfb
+eusb10 EUSB10 <eusb10.pfb
+
+eusm5 EUSM5 <eusm5.pfb
+eusm7 EUSM7 <eusm7.pfb
+eusm10 EUSM10 <eusm10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-base.map b/Master/texmf-dist/fonts/map/pdftex/context/original-base.map
new file mode 100644
index 00000000000..4958426c522
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-base.map
@@ -0,0 +1,62 @@
+% ralph
+
+rsfs7 rsfs5 <rsfs7.pfb
+rsfs5 rsfs7 <rsfs5.pfb
+rsfs10 rsfs10 <rsfs10.pfb
+
+% marvosym
+
+umvs MarVoSym <marvosym.pfb
+
+% context
+
+contnav ContextNavigation <contnav.pfb
+hans Hans-Regular <hans.pfb
+hans-sh Hans-sh-Regular <hans-sh.pfb
+
+% dingbats
+
+uzdr Dingbats <uzdr.pfb
+pzdr Dingbats <pzdr.pfb
+
+% symbols
+
+usyr StandardSymL <usyr.pfb
+
+% xypic
+
+xyatip10 XYATIP10 <xyatip10.pfb
+xybsql10 XYBSQL10 <xybsql10.pfb
+xybtip10 XYBTIP10 <xybtip10.pfb
+xycirc10 XYCIRC10 <xycirc10.pfb
+xydash10 XYDASH10 <xydash10.pfb
+
+xycmat10 XYCMAT10 <xycmat10.pfb
+xycmbt10 XYCMBT10 <xycmbt10.pfb
+xyeuat10 XYEUAT10 <xyeuat10.pfb
+xyeubt10 XYEUBT10 <xyeubt10.pfb
+
+xycmat11 XYCMAT10 "1.1 ExtendFont" <xycmat10.pfb
+xycmbt11 XYCMBT10 "1.1 ExtendFont" <xycmbt10.pfb
+xyeuat11 XYEUAT10 "1.1 ExtendFont" <xyeuat10.pfb
+xyeubt11 XYEUBT10 "1.1 ExtendFont" <xyeubt10.pfb
+
+xycmat12 XYCMAT10 "1.2 ExtendFont" <xycmat10.pfb
+xycmbt12 XYCMBT10 "1.2 ExtendFont" <xycmbt10.pfb
+xyeuat12 XYEUAT10 "1.2 ExtendFont" <xyeuat10.pfb
+xyeubt12 XYEUBT10 "1.2 ExtendFont" <xyeubt10.pfb
+
+% euro
+
+zpeub EuroSerif-Bold <zpeub.pfb
+zpeubi EuroSerif-BoldItalic <zpeubi.pfb
+zpeubis EuroSans-BoldItalic <zpeubis.pfb
+zpeubit EuroMono-BoldItalic <zpeubit.pfb
+zpeubs EuroSans-Bold <zpeubs.pfb
+zpeubt EuroMono-Bold <zpeubt.pfb
+zpeur EuroSerif-Regular <zpeur.pfb
+zpeuri EuroSerif-Italic <zpeuri.pfb
+zpeuris EuroSans-Italic <zpeuris.pfb
+zpeurit EuroMono-Italic <zpeurit.pfb
+zpeurs EuroSans-Regular <zpeurs.pfb
+zpeurt EuroMono-Regular <zpeurt.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-context-symbol.map b/Master/texmf-dist/fonts/map/pdftex/context/original-context-symbol.map
new file mode 100644
index 00000000000..ace5cfe8e49
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-context-symbol.map
@@ -0,0 +1,3 @@
+contnav ContextNavigation <contnav.pfb
+hans Hans-Regular <hans.pfb
+hans-sh Hans-sh-Regular <hans-sh.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-dummy.map b/Master/texmf-dist/fonts/map/pdftex/context/original-dummy.map
new file mode 100644
index 00000000000..c4843945cdf
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-dummy.map
@@ -0,0 +1 @@
+% no entries in here
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-empty.map b/Master/texmf-dist/fonts/map/pdftex/context/original-empty.map
new file mode 100644
index 00000000000..84d22b78228
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-empty.map
@@ -0,0 +1,4 @@
+
+
+% this is an empty map file
+
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-micropress-informal.map b/Master/texmf-dist/fonts/map/pdftex/context/original-micropress-informal.map
new file mode 100644
index 00000000000..01a61516fd6
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-micropress-informal.map
@@ -0,0 +1,7 @@
+ifrm10cm Informal Regular <cm.enc <ifrg.pfb
+ifrb10cm InformalBold <cm.enc <ifb.pfb
+ifro10cm InformalOblique <cm.enc <ifo.pfb
+ifbo10cm InformalBoldOblique <cm.enc <ifbo.pfb
+ifex10 InformalExtendedMathSymbols <ifex10.pfb
+ifmi10 InformalMathItalics <ifmi10.pfb
+ifsy10 InformalMathSymbols <ifsy10.pfb \ No newline at end of file
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-public-csr.map b/Master/texmf-dist/fonts/map/pdftex/context/original-public-csr.map
new file mode 100644
index 00000000000..4814d375dfb
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-public-csr.map
@@ -0,0 +1,56 @@
+csr5 CSR5 <csr1.enc <csr5.pfb
+csr6 CSR6 <csr.enc <csr6.pfb
+csr7 CSR7 <csr.enc <csr7.pfb
+csr8 CSR8 <csr.enc <csr8.pfb
+csr9 CSR9 <csr.enc <csr9.pfb
+csr10 CSR10 <csr.enc <csr10.pfb
+csr12 CSR12 <csr.enc <csr12.pfb
+csr17 CSR17 <csr.enc <csr17.pfb
+csbx5 CSBX5 <csr.enc <csbx5.pfb
+csbx6 CSBX6 <csr.enc <csbx6.pfb
+csbx7 CSBX7 <csr.enc <csbx7.pfb
+csbx8 CSBX8 <csr.enc <csbx8.pfb
+csbx9 CSBX9 <csr.enc <csbx9.pfb
+csbx10 CSBX10 <csr.enc <csbx10.pfb
+csbx12 CSBX12 <csr.enc <csbx12.pfb
+csb10 CSB10 <csr.enc <csb10.pfb
+csti7 CSTI7 <csr.enc <csti7.pfb
+csti8 CSTI8 <csr.enc <csti8.pfb
+csti9 CSTI9 <csr.enc <csti9.pfb
+csti10 CSTI10 <csr.enc <csti10.pfb
+csti12 CSTI12 <csr.enc <csti12.pfb
+cstt8 CSTT8 <cstt.enc <cstt8.pfb
+cstt9 CSTT9 <cstt.enc <cstt9.pfb
+cstt10 CSTT10 <cstt.enc <cstt10.pfb
+cstt12 CSTT12 <cstt.enc <cstt12.pfb
+cssltt10 CSSLTT10 <cstt.enc <cssltt10.pfb
+csvtt10 CSVTT10 <cstt.enc <csvtt10.pfb
+csss8 CSSS8 <csr.enc <csss8.pfb
+csss9 CSSS9 <csr.enc <csss9.pfb
+csss10 CSSS10 <csr.enc <csss10.pfb
+csss12 CSSS12 <csr.enc <csss12.pfb
+csss17 CSSS17 <csr.enc <csss17.pfb
+csssi8 CSSSI8 <csr.enc <csssi8.pfb
+csssi9 CSSSI9 <csr.enc <csssi9.pfb
+csssi10 CSSSI10 <csr.enc <csssi10.pfb
+csssi12 CSSSI12 <csr.enc <csssi12.pfb
+csssi17 CSSSI17 <csr.enc <csssi17.pfb
+cssl8 CSSL8 <csr.enc <cssl8.pfb
+cssl9 CSSL9 <csr.enc <cssl9.pfb
+cssl10 CSSL10 <csr.enc <cssl10.pfb
+cssl12 CSSL12 <csr.enc <cssl12.pfb
+csssq8 CSSSQ8 <csr.enc <csssq8.pfb
+csssqi8 CSSSQI8 <csr.enc <csssqi8.pfb
+csssdc10 CSSSDC10 <csr.enc <csssdc10.pfb
+csssbx10 CSSSBX10 <csr.enc <csssbx10.pfb
+csinch CSINCH <csin.enc <csinch.pfb
+csdunh10 CSDUNH10 <csr.enc <csdunh10.pfb
+csbxsl10 CSBXSL10 <csr.enc <csbxsl10.pfb
+csff10 CSFF10 <csr.enc <csff10.pfb
+csfib8 CSFIB8 <csr.enc <csfib8.pfb
+csbxti10 CSBXTI10 <csr.enc <csbxti10.pfb
+csitt10 CSITT10 <cstt.enc <csitt10.pfb
+csu10 CSU10 <csr.enc <csu10.pfb
+csfi10 CSFI10 <csr.enc <csfi10.pfb
+cscsc10 CSCSC10 <csr1.enc <cscsc10.pfb
+cstcsc10 CSTCSC10 <cstt.enc <cstcsc10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-public-lm.map b/Master/texmf-dist/fonts/map/pdftex/context/original-public-lm.map
new file mode 100644
index 00000000000..83fccd0aa95
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-public-lm.map
@@ -0,0 +1,182 @@
+% LM replacement, thanks to Jacko
+
+% official
+
+% cmb10 LMRomanDemi10-Regular <lm-rep-cmrm.enc <lmb10.pfb
+% cmbx10 LMRoman10-Bold <lm-rep-cmrm.enc <lmbx10.pfb
+% cmbx12 LMRoman12-Bold <lm-rep-cmrm.enc <lmbx12.pfb
+% cmbx5 LMRoman5-Bold <lm-rep-cmrm.enc <lmbx5.pfb
+% cmbx6 LMRoman6-Bold <lm-rep-cmrm.enc <lmbx6.pfb
+% cmbx7 LMRoman7-Bold <lm-rep-cmrm.enc <lmbx7.pfb
+% cmbx8 LMRoman8-Bold <lm-rep-cmrm.enc <lmbx8.pfb
+% cmbx9 LMRoman9-Bold <lm-rep-cmrm.enc <lmbx9.pfb
+% cmbxsl10 LMSlanted10-BoldItalic <lm-rep-cmrm.enc <lmbxo10.pfb
+% cmbxti10 LMRoman10-BoldItalic <lm-rep-cmit.enc <lmbxi10.pfb
+% cmbxti12 LMRoman10-BoldItalic <lm-rep-cmit.enc <lmbxti10.pfb
+% cmbxti7 LMRoman10-BoldItalic <lm-rep-cmit.enc <lmbxti10.pfb
+% cmcsc10 LMCaps10-Regular <lm-rep-cmsc.enc <lmcsc10.pfb
+% cmcsc8 LMCaps10-Regular <lm-rep-cmsc.enc <lmcsc10.pfb
+% cmcsc9 LMCaps10-Regular <lm-rep-cmsc.enc <lmcsc10.pfb
+% cminch LMSans10-Bold <lm-rep-cmin.enc <lmssbx10.pfb
+% cmitt10 LMTypewriter10-Italic <lm-rep-cmitt.enc <lmtti10.pfb
+% cmitt12 LMTypewriter10-Italic <lm-rep-cmitt.enc <lmtti10.pfb
+% cmitt9 LMTypewriter10-Italic <lm-rep-cmitt.enc <lmtti10.pfb
+% cmr10 LMRoman10-Regular <lm-rep-cmrm.enc <lmr10.pfb
+% cmr12 LMRoman12-Regular <lm-rep-cmrm.enc <lmr12.pfb
+% cmr17 LMRoman17-Regular <lm-rep-cmrm.enc <lmr17.pfb
+% cmr5 LMRoman5-Regular <lm-rep-cmsc.enc <lmr5.pfb
+% cmr6 LMRoman6-Regular <lm-rep-cmrm.enc <lmr6.pfb
+% cmr7 LMRoman7-Regular <lm-rep-cmrm.enc <lmr7.pfb
+% cmr8 LMRoman8-Regular <lm-rep-cmrm.enc <lmr8.pfb
+% cmr9 LMRoman9-Regular <lm-rep-cmrm.enc <lmr9.pfb
+% cmsl10 LMSlanted10-Italic <lm-rep-cmrm.enc <lmro10.pfb
+% cmsl12 LMSlanted12-Italic <lm-rep-cmrm.enc <lmro12.pfb
+% cmsl6 LMSlanted8-Italic <lm-rep-cmrm.enc <lmro8.pfb
+% cmsl8 LMSlanted8-Italic <lm-rep-cmrm.enc <lmro8.pfb
+% cmsl9 LMSlanted9-Italic <lm-rep-cmrm.enc <lmro9.pfb
+% cmsltt10 LMTypewriterSlanted10-Italic <lm-rep-cmtt.enc <lmtto10.pfb
+% cmsltt9 LMTypewriterSlanted10-Italic <lm-rep-cmtt.enc <lmtto10.pfb
+% cmss10 LMSans10-Regular <lm-rep-cmrm.enc <lmss10.pfb
+% cmss12 LMSans12-Regular <lm-rep-cmrm.enc <lmss12.pfb
+% cmss17 LMSans17-Regular <lm-rep-cmrm.enc <lmss17.pfb
+% cmss8 LMSans8-Regular <lm-rep-cmrm.enc <lmss8.pfb
+% cmss9 LMSans9-Regular <lm-rep-cmrm.enc <lmss9.pfb
+% cmssbx10 LMSans10-Bold <lm-rep-cmrm.enc <lmssbx10.pfb
+% cmssbxo10 LMSans10-BoldItalic <lm-rep-cmrm.enc <lmssbo10.pfb
+% cmssdc10 LMSansDemiCond10-Regular <lm-rep-cmrm.enc <lmssdc10.pfb
+% cmssi10 LMSans10-Italic <lm-rep-cmrm.enc <lmsso10.pfb
+% cmssi12 LMSans12-Italic <lm-rep-cmrm.enc <lmsso12.pfb
+% cmssi17 LMSans17-Italic <lm-rep-cmrm.enc <lmsso17.pfb
+% cmssi8 LMSans8-Italic <lm-rep-cmrm.enc <lmsso8.pfb
+% cmssi9 LMSans9-Italic <lm-rep-cmrm.enc <lmsso9.pfb
+% cmssq8 LMSansQuotation8-Regular <lm-rep-cmrm.enc <lmssq8.pfb
+% cmssqi8 LMSansQuotation8-Italic <lm-rep-cmrm.enc <lmssqo8.pfb
+% cmtcsc10 LMTypewriterCaps10-Regular <lm-rep-cmtt.enc <lmtcsc10.pfb
+% cmti10 LMRoman10-Italic <lm-rep-cmit.enc <lmri10.pfb
+% cmti12 LMRoman12-Italic <lm-rep-cmit.enc <lmri12.pfb
+% cmti7 LMRoman7-Italic <lm-rep-cmit.enc <lmri7.pfb
+% cmti8 LMRoman8-Italic <lm-rep-cmit.enc <lmri8.pfb
+% cmti9 LMRoman9-Italic <lm-rep-cmit.enc <lmri9.pfb
+% cmtt10 LMTypewriter10-Regular <lm-rep-cmtt.enc <lmtt10.pfb
+% cmtt12 LMTypewriter12-Regular <lm-rep-cmtt.enc <lmtt12.pfb
+% cmtt8 LMTypewriter8-Regular <lm-rep-cmtt.enc <lmtt8.pfb
+% cmtt9 LMTypewriter9-Regular <lm-rep-cmtt.enc <lmtt9.pfb
+% cmvtt10 LMTypewriterVarWd10-Regular <lm-rep-cmrm.enc <lmvtt10.pfb
+%
+% but more efficient since to-be-included old files have those names
+
+cmb10 CMB10 <lm-rep-cmrm.enc <lmb10.pfb
+cmbx10 CMBX10 <lm-rep-cmrm.enc <lmbx10.pfb
+cmbx12 CMBX12 <lm-rep-cmrm.enc <lmbx12.pfb
+cmbx5 CMBX5 <lm-rep-cmrm.enc <lmbx5.pfb
+cmbx6 CMBX6 <lm-rep-cmrm.enc <lmbx6.pfb
+cmbx7 CMBX7 <lm-rep-cmrm.enc <lmbx7.pfb
+cmbx8 CMBX8 <lm-rep-cmrm.enc <lmbx8.pfb
+cmbx9 CMBX9 <lm-rep-cmrm.enc <lmbx9.pfb
+cmbxsl10 CMBXSL10 <lm-rep-cmrm.enc <lmbxo10.pfb
+cmbxti10 CMBXTI10 <lm-rep-cmit.enc <lmbxi10.pfb
+cmbxti12 CMBXTI12 <lm-rep-cmit.enc <lmbxti10.pfb
+cmbxti7 CMBXTI7 <lm-rep-cmit.enc <lmbxti10.pfb
+cmcsc10 CMCSC10 <lm-rep-cmsc.enc <lmcsc10.pfb
+cmcsc8 CMCSC8 <lm-rep-cmsc.enc <lmcsc10.pfb
+cmcsc9 CMCSC9 <lm-rep-cmsc.enc <lmcsc10.pfb
+cminch CMINCH <lm-rep-cmin.enc <lmssbx10.pfb
+cmitt10 CMITT10 <lm-rep-cmitt.enc <lmtti10.pfb
+cmitt12 CMITT12 <lm-rep-cmitt.enc <lmtti10.pfb
+cmitt9 CMITT9 <lm-rep-cmitt.enc <lmtti10.pfb
+cmr10 CMR10 <lm-rep-cmrm.enc <lmr10.pfb
+cmr12 CMR12 <lm-rep-cmrm.enc <lmr12.pfb
+cmr17 CMR17 <lm-rep-cmrm.enc <lmr17.pfb
+cmr5 CMR5 <lm-rep-cmsc.enc <lmr5.pfb
+cmr6 CMR6 <lm-rep-cmrm.enc <lmr6.pfb
+cmr7 CMR7 <lm-rep-cmrm.enc <lmr7.pfb
+cmr8 CMR8 <lm-rep-cmrm.enc <lmr8.pfb
+cmr9 CMR9 <lm-rep-cmrm.enc <lmr9.pfb
+cmsl10 CMSL10 <lm-rep-cmrm.enc <lmro10.pfb
+cmsl12 CMSL12 <lm-rep-cmrm.enc <lmro12.pfb
+cmsl6 CMSL6 <lm-rep-cmrm.enc <lmro8.pfb
+cmsl8 CMSL8 <lm-rep-cmrm.enc <lmro8.pfb
+cmsl9 CMSL9 <lm-rep-cmrm.enc <lmro9.pfb
+cmsltt10 CMSLTT10 <lm-rep-cmtt.enc <lmtto10.pfb
+cmsltt9 CMSLTT9 <lm-rep-cmtt.enc <lmtto10.pfb
+cmss10 CMS10 <lm-rep-cmrm.enc <lmss10.pfb
+cmss12 CMS12 <lm-rep-cmrm.enc <lmss12.pfb
+cmss17 CMS17 <lm-rep-cmrm.enc <lmss17.pfb
+cmss8 CMS8 <lm-rep-cmrm.enc <lmss8.pfb
+cmss9 CMS9 <lm-rep-cmrm.enc <lmss9.pfb
+cmssbx10 CMSSBX10 <lm-rep-cmrm.enc <lmssbx10.pfb
+cmssbxo10 CMSSBXO10 <lm-rep-cmrm.enc <lmssbo10.pfb
+cmssdc10 CMSSDC10 <lm-rep-cmrm.enc <lmssdc10.pfb
+cmssi10 CMSI10 <lm-rep-cmrm.enc <lmsso10.pfb
+cmssi12 CMSI12 <lm-rep-cmrm.enc <lmsso12.pfb
+cmssi17 CMSI17 <lm-rep-cmrm.enc <lmsso17.pfb
+cmssi8 CMSSI8 <lm-rep-cmrm.enc <lmsso8.pfb
+cmssi9 CMSSI9 <lm-rep-cmrm.enc <lmsso9.pfb
+cmssq8 CMSQ8 <lm-rep-cmrm.enc <lmssq8.pfb
+cmssqi8 CMSSQI8 <lm-rep-cmrm.enc <lmssqo8.pfb
+cmtcsc10 CMTCSC10 <lm-rep-cmtt.enc <lmtcsc10.pfb
+cmti10 CMTI10 <lm-rep-cmit.enc <lmri10.pfb
+cmti12 CMTI12 <lm-rep-cmit.enc <lmri12.pfb
+cmti7 CMTI7 <lm-rep-cmit.enc <lmri7.pfb
+cmti8 CMTI8 <lm-rep-cmit.enc <lmri8.pfb
+cmti9 CMTI9 <lm-rep-cmit.enc <lmri9.pfb
+cmtt10 CMTT10 <lm-rep-cmtt.enc <lmtt10.pfb
+cmtt12 CMTT12 <lm-rep-cmtt.enc <lmtt12.pfb
+cmtt8 CMTT8 <lm-rep-cmtt.enc <lmtt8.pfb
+cmtt9 CMTT9 <lm-rep-cmtt.enc <lmtt9.pfb
+cmvtt10 CMVTT10 <lm-rep-cmrm.enc <lmvtt10.pfb
+
+% Math
+
+cmex10 LMMathExtension10-Regular "enclmmathex ReEncodeFont" <lm-mathex.enc <lmex10.pfb
+cmex9 LMMathExtension10-Regular "enclmmathex ReEncodeFont" <lm-mathex.enc <lmex10.pfb
+cmex8 LMMathExtension10-Regular "enclmmathex ReEncodeFont" <lm-mathex.enc <lmex10.pfb
+cmex7 LMMathExtension10-Regular "enclmmathex ReEncodeFont" <lm-mathex.enc <lmex10.pfb
+
+cmmi5 LMMathItalic5-Italic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi5.pfb
+cmmi6 LMMathItalic6-Italic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi6.pfb
+cmmi7 LMMathItalic7-Italic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi7.pfb
+cmmi8 LMMathItalic8-Italic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi8.pfb
+cmmi9 LMMathItalic9-Italic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi9.pfb
+cmmi10 LMMathItalic10-Italic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi10.pfb
+cmmi12 LMMathItalic12-Italic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmi12.pfb
+
+cmmib5 LMMathItalic5-BoldItalic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib5.pfb
+cmmib6 LMMathItalic6-BoldItalic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib6.pfb
+cmmib7 LMMathItalic7-BoldItalic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib7.pfb
+cmmib8 LMMathItalic8-BoldItalic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib8.pfb
+cmmib9 LMMathItalic9-BoldItalic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib9.pfb
+cmmib10 LMMathItalic10-BoldItalic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib10.pfb
+cmmib12 LMMathItalic12-BoldItalic "enclmmathit ReEncodeFont" <lm-mathit.enc <lmmib12.pfb
+
+cmsy5 LMMathSymbols5-Italic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy5.pfb
+cmsy6 LMMathSymbols6-Italic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy6.pfb
+cmsy7 LMMathSymbols7-Italic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy7.pfb
+cmsy8 LMMathSymbols8-Italic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy8.pfb
+cmsy9 LMMathSymbols9-Italic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy9.pfb
+cmsy10 LMMathSymbols10-Italic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmsy10.pfb
+
+cmbsy5 LMMathSymbols5-BoldItalic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy5.pfb
+cmbsy6 LMMathSymbols6-BoldItalic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy6.pfb
+cmbsy7 LMMathSymbols7-BoldItalic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy7.pfb
+cmbsy8 LMMathSymbols8-BoldItalic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy8.pfb
+cmbsy9 LMMathSymbols9-BoldItalic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy9.pfb
+cmbsy10 LMMathSymbols10-BoldItalic "enclmmathsy ReEncodeFont" <lm-mathsy.enc <lmbsy10.pfb
+
+
+% original
+
+cmdunh10 CMDUNH10 <cmdunh10.pfb
+
+cmtex10 CMTEX10 <cmtex10.pfb
+cmtex8 CMTEX8 <cmtex8.pfb
+cmtex9 CMTEX9 <cmtex9.pfb
+
+cmff10 CMFF10 <cmff10.pfb
+cmfi10 CMFI10 <cmfi10.pfb
+cmfib8 CMFIB8 <cmfib8.pfb
+
+
+% a weird one, not used in context
+
+cmu10 LMRoman10-Italic "-0.25 SlantFont" <lm-rep-cmit.enc <lmri10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-public-plr.map b/Master/texmf-dist/fonts/map/pdftex/context/original-public-plr.map
new file mode 100644
index 00000000000..4fce40d3fba
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-public-plr.map
@@ -0,0 +1,77 @@
+plb10 PLB10 <plrm.enc <plb10.pfb
+plbsy10 PLBSY10 <plms.enc <plbsy10.pfb
+plbx5 PLBX5 <plrm.enc <plbx5.pfb
+plbx6 PLBX6 <plrm.enc <plbx6.pfb
+plbx7 PLBX7 <plrm.enc <plbx7.pfb
+plbx8 PLBX8 <plrm.enc <plbx8.pfb
+plbx9 PLBX9 <plrm.enc <plbx9.pfb
+plbx10 PLBX10 <plrm.enc <plbx10.pfb
+plbx12 PLBX12 <plrm.enc <plbx12.pfb
+plbxsl10 PLBXSL10 <plrm.enc <plbxsl10.pfb
+plbxti10 PLBXTI10 <plit.enc <plbxti10.pfb
+plcsc10 PLCSC10 <plsc.enc <plcsc10.pfb
+pldunh10 PLDUNH10 <plrm.enc <pldunh10.pfb
+plex9 PLEX9 <plme.enc <plex9.pfb
+plex10 PLEX10 <plme.enc <plex10.pfb
+plff10 PLFF10 <plrm.enc <plff10.pfb
+plfi10 PLFI10 <plit.enc <plfi10.pfb
+plfib8 PLFIB8 <plrm.enc <plfib8.pfb
+plinch PLINCH <plin.enc <plinch.pfb
+plitt10 PLITT10 <plitt.enc <plitt10.pfb
+plmi5 PLMI5 <plmi.enc <plmi5.pfb
+plmi6 PLMI6 <plmi.enc <plmi6.pfb
+plmi7 PLMI7 <plmi.enc <plmi7.pfb
+plmi8 PLMI8 <plmi.enc <plmi8.pfb
+plmi9 PLMI9 <plmi.enc <plmi9.pfb
+plmi10 PLMI10 <plmi.enc <plmi10.pfb
+plmi12 PLMI12 <plmi.enc <plmi12.pfb
+plmib10 PLMIB10 <plmi.enc <plmib10.pfb
+plr5 PLR5 <plsc.enc <plr5.pfb
+plr6 PLR6 <plrm.enc <plr6.pfb
+plr7 PLR7 <plrm.enc <plr7.pfb
+plr8 PLR8 <plrm.enc <plr8.pfb
+plr9 PLR9 <plrm.enc <plr9.pfb
+plr10 PLR10 <plrm.enc <plr10.pfb
+plr12 PLR12 <plrm.enc <plr12.pfb
+plr17 PLR17 <plrm.enc <plr17.pfb
+plsl8 PLSL8 <plrm.enc <plsl8.pfb
+plsl9 PLSL9 <plrm.enc <plsl9.pfb
+plsl10 PLSL10 <plrm.enc <plsl10.pfb
+plsl12 PLSL12 <plrm.enc <plsl12.pfb
+plsltt10 PLSLTT10 <pltt.enc <plsltt10.pfb
+plss8 PLSS8 <plrm.enc <plss8.pfb
+plss9 PLSS9 <plrm.enc <plss9.pfb
+plss10 PLSS10 <plrm.enc <plss10.pfb
+plss12 PLSS12 <plrm.enc <plss12.pfb
+plss17 PLSS17 <plrm.enc <plss17.pfb
+plssbi10 PLSSBI10 <plrm.enc <plssbi10.pfb
+plssbx10 PLSSBX10 <plrm.enc <plssbx10.pfb
+plssdc10 PLSSDC10 <plrm.enc <plssdc10.pfb
+plssi8 PLSSI8 <plrm.enc <plssi8.pfb
+plssi9 PLSSI9 <plrm.enc <plssi9.pfb
+plssi10 PLSSI10 <plrm.enc <plssi10.pfb
+plssi12 PLSSI12 <plrm.enc <plssi12.pfb
+plssi17 PLSSI17 <plrm.enc <plssi17.pfb
+plssq8 PLSSQ8 <plrm.enc <plssq8.pfb
+plssqi8 PLSSQI8 <plrm.enc <plssqi8.pfb
+plsy5 PLSY5 <plms.enc <plsy5.pfb
+plsy6 PLSY6 <plms.enc <plsy6.pfb
+plsy7 PLSY7 <plms.enc <plsy7.pfb
+plsy8 PLSY8 <plms.enc <plsy8.pfb
+plsy9 PLSY9 <plms.enc <plsy9.pfb
+plsy10 PLSY10 <plms.enc <plsy10.pfb
+pltcsc10 PLTCSC10 <pltt.enc <pltcsc10.pfb
+pltex8 PLTEX8 <plte.enc <pltex8.pfb
+pltex9 PLTEX9 <plte.enc <pltex9.pfb
+pltex10 PLTEX10 <plte.enc <pltex10.pfb
+plti7 PLTI7 <plit.enc <plti7.pfb
+plti8 PLTI8 <plit.enc <plti8.pfb
+plti9 PLTI9 <plit.enc <plti9.pfb
+plti10 PLTI10 <plit.enc <plti10.pfb
+plti12 PLTI12 <plit.enc <plti12.pfb
+pltt8 PLTT8 <pltt.enc <pltt8.pfb
+pltt9 PLTT9 <pltt.enc <pltt9.pfb
+pltt10 PLTT10 <pltt.enc <pltt10.pfb
+pltt12 PLTT12 <pltt.enc <pltt12.pfb
+plu10 PLU10 <plit.enc <plu10.pfb
+plvtt10 PLVTT10 <plrm.enc <plvtt10.pfb \ No newline at end of file
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-public-vnr.map b/Master/texmf-dist/fonts/map/pdftex/context/original-public-vnr.map
new file mode 100644
index 00000000000..9b6018de126
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-public-vnr.map
@@ -0,0 +1,59 @@
+% this is the original file, i don't want to be surprised by changes,
+% so we copied it; some day soon we will use pdfmapline instead; well
+% we'll use latin modern in the end
+
+vnb10 VNB10 <vnb10.pfb
+vnbx10 VNBX10 <vnbx10.pfb
+vnbx12 VNBX12 <vnbx12.pfb
+vnbx5 VNBX5 <vnbx5.pfb
+vnbx6 VNBX6 <vnbx6.pfb
+vnbx7 VNBX7 <vnbx7.pfb
+vnbx8 VNBX8 <vnbx8.pfb
+vnbx9 VNBX9 <vnbx9.pfb
+vnbxsl10 VNBXSL10 <vnbxsl10.pfb
+vnbxti10 VNBXTI10 <vnbxti10.pfb
+vncsc10 VNCSC10 <vncsc10.pfb
+vndunh10 VNDUNH10 <vndunh10.pfb
+vnff10 VNFF10 <vnff10.pfb
+vnfi10 VNFI10 <vnfi10.pfb
+vnfib8 VNFIB8 <vnfib8.pfb
+vnitt10 VNITT10 <vnitt10.pfb
+vnr10 VNR10 <vnr10.pfb
+vnr12 VNR12 <vnr12.pfb
+vnr17 VNR17 <vnr17.pfb
+vnr5 VNR5 <vnr5.pfb
+vnr6 VNR6 <vnr6.pfb
+vnr7 VNR7 <vnr7.pfb
+vnr8 VNR8 <vnr8.pfb
+vnr9 VNR9 <vnr9.pfb
+vnsl10 VNSL10 <vnsl10.pfb
+vnsl12 VNSL12 <vnsl12.pfb
+vnsl8 VNSL8 <vnsl8.pfb
+vnsl9 VNSL9 <vnsl9.pfb
+vnsltt10 VNSLTT10 <vnsltt10.pfb
+vnss10 VNSS10 <vnss10.pfb
+vnss12 VNSS12 <vnss12.pfb
+vnss17 VNSS17 <vnss17.pfb
+vnss8 VNSS8 <vnss8.pfb
+vnss9 VNSS9 <vnss9.pfb
+vnssbx10 VNSSBX10 <vnssbx10.pfb
+vnssdc10 VNSSDC10 <vnssdc10.pfb
+vnssi10 VNSSI10 <vnssi10.pfb
+vnssi12 VNSSI12 <vnssi12.pfb
+vnssi17 VNSSI17 <vnssi17.pfb
+vnssi8 VNSSI8 <vnssi8.pfb
+vnssi9 VNSSI9 <vnssi9.pfb
+vnssq8 VNSSQ8 <vnssq8.pfb
+vnssqi8 VNSSQI8 <vnssqi8.pfb
+vntcsc10 VNTCSC10 <vntcsc10.pfb
+vnti10 VNTI10 <vnti10.pfb
+vnti12 VNTI12 <vnti12.pfb
+vnti7 VNTI7 <vnti7.pfb
+vnti8 VNTI8 <vnti8.pfb
+vnti9 VNTI9 <vnti9.pfb
+vntt10 VNTT10 <vntt10.pfb
+vntt12 VNTT12 <vntt12.pfb
+vntt8 VNTT8 <vntt8.pfb
+vntt9 VNTT9 <vntt9.pfb
+vnu10 VNU10 <vnu10.pfb
+vnvtt10 VNVTT10 <vnvtt10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-vogel-symbol.map b/Master/texmf-dist/fonts/map/pdftex/context/original-vogel-symbol.map
new file mode 100644
index 00000000000..601d0317dab
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-vogel-symbol.map
@@ -0,0 +1,2 @@
+fmvr8x Marvosym < marvosym.pfb
+
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-wasy.map b/Master/texmf-dist/fonts/map/pdftex/context/original-wasy.map
new file mode 100644
index 00000000000..4a439634b1c
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-wasy.map
@@ -0,0 +1,7 @@
+wasy5 WASY5 <wasy5.pfb
+wasy6 WASY6 <wasy6.pfb
+wasy7 WASY7 <wasy7.pfb
+wasy8 WASY8 <wasy8.pfb
+wasy9 WASY9 <wasy9.pfb
+wasy10 WASY10 <wasy10.pfb
+wasyb10 WASYB10 <wasyb10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-px.map b/Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-px.map
new file mode 100644
index 00000000000..6a27e357d61
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-px.map
@@ -0,0 +1,51 @@
+% This file a (slightly adapted) copy of the map file
+% that comes with the PX fonts by Young Ryu.
+
+% URW fonts replaced by TeX Gyre
+
+% TeX Gyre Pagella (Palatino)
+
+rpxpplr TeXGyrePagella-Regular "encq8r ReEncodeFont" <q-8r.enc <qplr.pfb
+rpxpplb TeXGyrePagella-Bold "encq8r ReEncodeFont" <q-8r.enc <qplb.pfb
+rpxpplri TeXGyrePagella-Italic "encq8r ReEncodeFont" <q-8r.enc <qplri.pfb
+rpxpplbi TeXGyrePagella-BoldItalic "encq8r ReEncodeFont" <q-8r.enc <qplbi.pfb
+% no idea why these were added
+rpxpplro TeXGyrePagella-Oblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qplr.pfb
+rpxpplbo TeXGyrePagella-BoldOblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qplb.pfb
+
+% PX Text
+
+rpxr rpxr <rpxr.pfb
+rpxsl rpxr ".167 SlantFont" <rpxr.pfb
+rpxi rpxi <rpxi.pfb
+rpxsc rpxsc <rpxsc.pfb
+rpxb rpxb <rpxb.pfb
+rpxbsl rpxb ".167 SlantFont" <rpxb.pfb
+rpxbi rpxbi <rpxbi.pfb
+rpxbsc rpxbsc <rpxbsc.pfb
+rpcxb rpcxb <rpcxb.pfb
+rpcxbsl rpcxb ".167 SlantFont" <rpcxb.pfb
+rpcxbi rpcxbi <rpcxbi.pfb
+rpcxi rpcxi <rpcxi.pfb
+rpcxr rpcxr <rpcxr.pfb
+rpcxsl rpcxsl ".167 SlantFont" <rpcxr.pfb
+
+% PX Math
+
+rpxbmi rpxbmi <rpxbmi.pfb
+rpxmi rpxmi <rpxmi.pfb
+
+pxbex pxbex <pxbex.pfb
+pxbexa pxbexa <pxbexa.pfb
+pxbmia pxbmia <pxbmia.pfb
+pxbsy pxbsy <pxbsy.pfb
+pxbsya pxbsya <pxbsya.pfb
+pxbsyb pxbsyb <pxbsyb.pfb
+pxbsyc pxbsyc <pxbsyc.pfb
+pxex pxex <pxex.pfb
+pxexa pxexa <pxexa.pfb
+pxmia pxmia <pxmia.pfb
+pxsy pxsy <pxsy.pfb
+pxsya pxsya <pxsya.pfb
+pxsyb pxsyb <pxsyb.pfb
+pxsyc pxsyc <pxsyc.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-tx.map b/Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-tx.map
new file mode 100644
index 00000000000..d2600fa787d
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/original-youngryu-tx.map
@@ -0,0 +1,94 @@
+% This file is a (slightly adapted) copy of the map file
+% that comes with the TX fonts by Young Ryu.
+
+% URW fonts replaced by TeX Gyre
+
+% TeX Gyre Termes (Times)
+
+rtxptmr TeXGyreTermes-Regular "encq8r ReEncodeFont" <q-8r.enc <qtmr.pfb
+rtxptmb TeXGyreTermes-Bold "encq8r ReEncodeFont" <q-8r.enc <qtmb.pfb
+rtxptmri TeXGyreTermes-Italic "encq8r ReEncodeFont" <q-8r.enc <qtmri.pfb
+rtxptmbi TeXGyreTermes-BoldItalic "encq8r ReEncodeFont" <q-8r.enc <qtmbi.pfb
+% no idea why these were added
+rtxptmro TeXGyreTermes-Oblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qtmr.pfb
+rtxptmbo TeXGyreTermes-BoldOblique ".167 SlantFont encq8r ReEncodeFont" <q-8r.enc <qtmb.pfb
+
+% TeX Gyre Heros (Helvetica)
+
+rtxphvr TeXGyreHeros-Regular "encqrm ReEncodeFont" <q-rm.enc <qtmr.pfb
+rtxphvb TeXGyreHeros-Bold "encqrm ReEncodeFont" <q-rm.enc <qtmb.pfb
+% probably not used by txfonts
+% rtxphvri TeXGyreHeros-Italic "encqrm ReEncodeFont" <q-rm.enc <qtmri.pfb
+% rtxphvbi TeXGyreHeros-BoldItalic "encqrm ReEncodeFont" <q-rm.enc <qtmbi.pfb
+% followed original definitions; one could also use the italic version
+rtxphvro TeXGyreHeros-Oblique ".167 SlantFont encqrm ReEncodeFont" <q-rm.enc <qtmr.pfb
+rtxphvbo TeXGyreHeros-BoldOblique ".167 SlantFont encqrm ReEncodeFont" <q-rm.enc <qtmb.pfb
+
+% TX Text
+
+rtxr rtxr <rtxr.pfb
+rtxsl rtxr ".167 SlantFont" <rtxr.pfb
+rtxi rtxi <rtxi.pfb
+rtxsc rtxsc <rtxsc.pfb
+rtxb rtxb <rtxb.pfb
+rtxbsl rtxb ".167 SlantFont" <rtxb.pfb
+rtxbi rtxbi <rtxbi.pfb
+rtxbsc rtxbsc <rtxbsc.pfb
+rtcxb rtcxb <rtcxb.pfb
+rtcxbsl rtcxb ".167 SlantFont" <rtcxb.pfb
+rtcxbi rtcxbi <rtcxbi.pfb
+rtcxi rtcxi <rtcxi.pfb
+rtcxr rtcxr <rtcxr.pfb
+rtcxsl rtcx ".167 SlantFont" <rtcxr.pfb
+
+% TX Math
+
+rtxbmi rtxbmi <rtxbmi.pfb
+rtxmi rtxmi <rtxmi.pfb
+
+txbex txbex <txbex.pfb
+txbexa txbexa <txbexa.pfb
+txbmia txbmia <txbmia.pfb
+txbsy txbsy <txbsy.pfb
+txbsya txbsya <txbsya.pfb
+txbsyb txbsyb <txbsyb.pfb
+txbsyc txbsyc <txbsyc.pfb
+txex txex <txex.pfb
+txexa txexa <txexa.pfb
+txmia txmia <txmia.pfb
+txsy txsy <txsy.pfb
+txsya txsya <txsya.pfb
+txsyb txsyb <txsyb.pfb
+txsyc txsyc <txsyc.pfb
+
+% TX TT Text
+
+txtt txtt <txtt.pfb
+txttsl txtt ".167 SlantFont" <txtt.pfb
+txttsc txttsc <txttsc.pfb
+txbtt txbtt <txbtt.pfb
+txbttsl txbtt ".167 SlantFont" <txbtt.pfb
+txbttsc txbttsc <txbttsc.pfb
+t1xtt t1xtt <t1xtt.pfb
+t1xttsl t1xtt ".167 SlantFont" <t1xtt.pfb
+t1xttsc t1xttsc <t1xttsc.pfb
+t1xbtt t1xbtt <t1xbtt.pfb
+t1xbttsl t1xbtt ".167 SlantFont" <t1xbtt.pfb
+t1xbttsc t1xbttsc <t1xbttsc.pfb
+tcxtt tcxtt <tcxtt.pfb
+tcxttsl tcxtt ".167 SlantFont" <tcxtt.pfb
+tcxbtt tcxbtt <tcxbtt.pfb
+tcxbttsl tcxbtt ".167 SlantFont" <tcxbtt.pfb
+
+% TX SS Text
+
+rtxss rtxss <rtxss.pfb
+rtxsssl rtxss ".167 SlantFont" <rtxss.pfb
+rtxsssc rtxsssc <rtxsssc.pfb
+rtxbss rtxbss <rtxbss.pfb
+rtxbsssl rtxbss ".167 SlantFont" <rtxbss.pfb
+rtxbsssc rtxbsssc <rtxbsssc.pfb
+rtcxss rtcxss <rtcxss.pfb
+rtcxbss rtcxbss <rtcxbss.pfb
+rtcxsssl rtcxss ".167 SlantFont" <rtcxss.pfb
+rtcxbsso rtcxbss ".167 SlantFont" <rtcxbss.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/qx-base.map b/Master/texmf-dist/fonts/map/pdftex/context/qx-base.map
new file mode 100644
index 00000000000..242426bdd79
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/qx-base.map
@@ -0,0 +1,55 @@
+% courier / urw
+
+qcrb <qcr.enc <qcrb.pfb
+qcrbi <qcr.enc <qcrbi.pfb
+qcrr <qcr.enc <qcrr.pfb
+qcrri <qcr.enc <qcrri.pfb
+
+% helvetica / urw
+
+qhvb <qhv.enc <qhvb.pfb
+qhvbi <qhv.enc <qhvbi.pfb
+qhvcb <qhv.enc <qhvcb.pfb
+qhvcbi <qhv.enc <qhvcbi.pfb
+qhvcr <qhv.enc <qhvcr.pfb
+qhvcri <qhv.enc <qhvcri.pfb
+qhvr <qhv.enc <qhvr.pfb
+qhvri <qhv.enc <qhvri.pfb
+
+% times / urw
+
+qtmb <qtm.enc <qtmb.pfb
+qtmbi <qtm.enc <qtmbi.pfb
+qtmr <qtm.enc <qtmr.pfb
+qtmri <qtm.enc <qtmri.pfb
+
+% palatino / urw
+
+qplb <qpl.enc <qplb.pfb
+qplbi <qpl.enc <qplbi.pfb
+qplr <qpl.enc <qplr.pfb
+qplri <qpl.enc <qplri.pfb
+
+% bookman / urw
+
+qbkb <qbk.enc <qbkb.pfb
+qbkbi <qbk.enc <qbkbi.pfb
+qbkr <qbk.enc <qbkr.pfb
+qbkri <qbk.enc <qbkri.pfb
+
+% chancery / urw
+
+qzcmi <qzc.enc <qzcmi.pfb
+
+% schoolbook / urw
+%
+% not available
+
+% utopia
+%
+% not available
+
+% charter
+%
+% not available
+
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/qx-os-public-lm.map b/Master/texmf-dist/fonts/map/pdftex/context/qx-os-public-lm.map
new file mode 100644
index 00000000000..57ddc0ebfc1
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/qx-os-public-lm.map
@@ -0,0 +1,69 @@
+qx-lmb10 LMRoman10-Demi "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmb10.pfb
+qx-lmbo10 LMRoman10-DemiOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbo10.pfb
+qx-lmbx10 LMRoman10-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbx10.pfb
+qx-lmbx12 LMRoman12-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbx12.pfb
+qx-lmbx5 LMRoman5-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbx5.pfb
+qx-lmbx6 LMRoman6-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbx6.pfb
+qx-lmbx7 LMRoman7-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbx7.pfb
+qx-lmbx8 LMRoman8-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbx8.pfb
+qx-lmbx9 LMRoman9-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbx9.pfb
+qx-lmbxi10 LMRoman10-BoldItalic "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbxi10.pfb
+qx-lmbxo10 LMRoman10-BoldOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmbxo10.pfb
+qx-lmcsc10 LMRoman10-CapsRegular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmcsc10.pfb
+qx-lmcsco10 LMRoman10-CapsOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmcsco10.pfb
+qx-lmr10 LMRoman10-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr10.pfb
+qx-lmr12 LMRoman12-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr12.pfb
+qx-lmr17 LMRoman17-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr17.pfb
+qx-lmr5 LMRoman5-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr5.pfb
+qx-lmr6 LMRoman6-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr6.pfb
+qx-lmr7 LMRoman7-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr7.pfb
+qx-lmr8 LMRoman8-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr8.pfb
+qx-lmr9 LMRoman9-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmr9.pfb
+qx-lmri10 LMRoman10-Italic "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmri10.pfb
+qx-lmri12 LMRoman12-Italic "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmri12.pfb
+qx-lmri7 LMRoman7-Italic "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmri7.pfb
+qx-lmri8 LMRoman8-Italic "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmri8.pfb
+qx-lmri9 LMRoman9-Italic "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmri9.pfb
+qx-lmro10 LMRoman10-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmro10.pfb
+qx-lmro12 LMRoman12-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmro12.pfb
+qx-lmro17 LMRoman17-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmro17.pfb
+qx-lmro8 LMRoman8-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmro8.pfb
+qx-lmro9 LMRoman9-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmro9.pfb
+qx-lmss10 LMSans10-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmss10.pfb
+qx-lmss12 LMSans12-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmss12.pfb
+qx-lmss17 LMSans17-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmss17.pfb
+qx-lmss8 LMSans8-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmss8.pfb
+qx-lmss9 LMSans9-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmss9.pfb
+qx-lmssbo10 LMSans10-BoldOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssbo10.pfb
+qx-lmssbx10 LMSans10-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssbx10.pfb
+qx-lmssdc10 LMSans10-DemiCondensed "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssdc10.pfb
+qx-lmssdo10 LMSans10-DemiCondensedOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssdo10.pfb
+qx-lmsso10 LMSans10-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmsso10.pfb
+qx-lmsso12 LMSans12-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmsso12.pfb
+qx-lmsso17 LMSans17-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmsso17.pfb
+qx-lmsso8 LMSans8-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmsso8.pfb
+qx-lmsso9 LMSans9-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmsso9.pfb
+qx-lmssq8 LMSansQuotation8-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssq8.pfb
+qx-lmssqbo8 LMSansQuotation8-BoldOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssqbo8.pfb
+qx-lmssqbx8 LMSansQuotation8-Bold "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssqbx8.pfb
+qx-lmssqo8 LMSansQuotation8-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmssqo8.pfb
+qx-lmtcsc10 LMTypewriter10-CapsRegular "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtcsc10.pfb
+qx-lmtcso10 LMTypewriter10-CapsOblique "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtcso10.pfb
+qx-lmtl10 LMTypewriter10-Light "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtl10.pfb
+qx-lmtlo10 LMTypewriter10-LightOblique "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtlo10.pfb
+qx-lmtlc10 LMTypewriter10-LightCondensed "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtlc10.pfb
+qx-lmtlco10 LMTypewriter10-LightCondensedOblique "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtlco10.pfb
+qx-lmtk10 LMTypewriter10-Dark "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtk10.pfb
+qx-lmtko10 LMTypewriter10-DarkOblique "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtko10.pfb
+qx-lmtt10 LMTypewriter10-Regular "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtt10.pfb
+qx-lmtt12 LMTypewriter12-Regular "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtt12.pfb
+qx-lmtt8 LMTypewriter8-Regular "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtt8.pfb
+qx-lmtt9 LMTypewriter9-Regular "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtt9.pfb
+qx-lmtti10 LMTypewriter10-Italic "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtti10.pfb
+qx-lmtto10 LMTypewriter10-Oblique "enclmqxostt ReEncodeFont" <lm-qxtt.enc <lmtto10.pfb
+qx-lmvtt10 LMTypewriterVarWd10-Regular "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmvtt10.pfb
+qx-lmvtto10 LMTypewriterVarWd10-Oblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmvtto10.pfb
+qx-lmvtl10 LMTypewriterVarWd10-Light "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmvtl10.pfb
+qx-lmvtlo10 LMTypewriterVarWd10-LightOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmvtlo10.pfb
+qx-lmvtk10 LMTypewriterVarWd10-Dark "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmvtk10.pfb
+qx-lmvtko10 LMTypewriterVarWd10-DarkOblique "enclmqxos ReEncodeFont" <lm-qx-os.enc <lmvtko10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/t5-base.map b/Master/texmf-dist/fonts/map/pdftex/context/t5-base.map
new file mode 100644
index 00000000000..da05cafebb2
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/t5-base.map
@@ -0,0 +1,72 @@
+% courier / urw
+
+ucrr8v VnNimbusMonL-Regu "T5Encoding ReEncodeFont" <t5.enc <ucrr8v.pfb
+ucrro8v VnNimbusMonL-ReguObli "T5Encoding ReEncodeFont" <t5.enc <ucrro8v.pfb
+ucrb8v VnNimbusMonL-Bold "T5Encoding ReEncodeFont" <t5.enc <ucrb8v.pfb
+ucrbo8v VnNimbusMonL-BoldObli "T5Encoding ReEncodeFont" <t5.enc <ucrbo8v.pfb
+
+% helvetica / urw
+
+uhvr8v VnNimbusSanL-Regu "T5Encoding ReEncodeFont" <t5.enc <uhvr8v.pfb
+uhvro8v VnNimbusSanL-ReguItal "T5Encoding ReEncodeFont" <t5.enc <uhvro8v.pfb
+uhvb8v VnNimbusSanL-Bold "T5Encoding ReEncodeFont" <t5.enc <uhvb8v.pfb
+uhvbo8v VnNimbusSanL-BoldItal "T5Encoding ReEncodeFont" <t5.enc <uhvbo8v.pfb
+
+% times / urw
+
+utmr8v VnNimbusRomNo9L-Regu "T5Encoding ReEncodeFont" <t5.enc <utmr8v.pfb
+utmri8v VnNimbusRomNo9L-ReguItal "T5Encoding ReEncodeFont" <t5.enc <utmri8v.pfb
+utmb8v VnNimbusRomNo9L-Medi "T5Encoding ReEncodeFont" <t5.enc <utmb8v.pfb
+utmbi8v VnNimbusRomNo9L-MediItal "T5Encoding ReEncodeFont" <t5.enc <utmbi8v.pfb
+
+utmro8v VnNimbusRomNo9L-Regu "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <utmr8v.pfb
+utmbo8v VnNimbusRomNo9L-Medi "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <utmb8v.pfb
+
+% palatino / urw
+
+uplr8v VnURWPalladioL-Roma "T5Encoding ReEncodeFont" <t5.enc <uplr8v.pfb
+uplri8v VnURWPalladioL-Ital "T5Encoding ReEncodeFont" <t5.enc <uplri8v.pfb
+uplb8v VnURWPalladioL-Bold "T5Encoding ReEncodeFont" <t5.enc <uplb8v.pfb
+uplbi8v VnURWPalladioL-BoldItal "T5Encoding ReEncodeFont" <t5.enc <uplbi8v.pfb
+
+uplro8v VnURWPalladioL-Roma "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <uplr8v.pfb
+uplbo8v VnURWPalladioL-Bold "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <uplb8v.pfb
+
+% bookman / urw
+
+ubkl8v VnURWBookmanL-Ligh "T5Encoding ReEncodeFont" <t5.enc <ubkl8v.pfb
+ubkli8v VnURWBookmanL-LighItal "T5Encoding ReEncodeFont" <t5.enc <ubkli8v.pfb
+ubkd8v VnURWBookmanL-DemiBold "T5Encoding ReEncodeFont" <t5.enc <ubkd8v.pfb
+ubkdi8v VnURWBookmanL-DemiBoldItal "T5Encoding ReEncodeFont" <t5.enc <ubkdi8v.pfb
+
+ubklo8v VnURWBookmanL-Ligh "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <ubkl8v.pfb
+ubkdo8v VnURWBookmanL-DemiBold "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <ubkd8v.pfb
+
+% chancery / urw
+
+% not supported
+%
+% schoolbook / urw
+
+uncr8v VnCenturySchL-Roma "T5Encoding ReEncodeFont" <t5.enc <uncr8v.pfb
+uncri8v VnCenturySchL-Ital "T5Encoding ReEncodeFont" <t5.enc <uncri8v.pfb
+uncb8v VnCenturySchL-Bold "T5Encoding ReEncodeFont" <t5.enc <uncb8v.pfb
+uncbi8v VnCenturySchL-BoldItal "T5Encoding ReEncodeFont" <t5.enc <uncbi8v.pfb
+
+uncro8v VnCenturySchL-Roma "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <uncr8v.pfb
+uncbo8v VnCenturySchL-Bold "0.277 SlantFont T5Encoding ReEncodeFont" <t5.enc <uncb8v.pfb
+
+% utopia
+%
+% not supported
+
+% charter
+%
+% not supported
+
+% gothic / urw
+
+uagk8v VnURWGothicL-Book "T5Encoding ReEncodeFont" <t5.enc <uagk8v.pfb
+uagko8v VnURWGothicL-BookObli "T5Encoding ReEncodeFont" <t5.enc <uagko8v.pfb
+uagd8v VnURWGothicL-Demi "T5Encoding ReEncodeFont" <t5.enc <uagd8v.pfb
+uagdo8v VnURWGothicL-DemiObli "T5Encoding ReEncodeFont" <t5.enc <uagdo8v.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/t5-os-public-lm.map b/Master/texmf-dist/fonts/map/pdftex/context/t5-os-public-lm.map
new file mode 100644
index 00000000000..c9e3c4dcb8f
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/t5-os-public-lm.map
@@ -0,0 +1,69 @@
+t5-lmb10 LMRoman10-Demi "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmb10.pfb
+t5-lmbo10 LMRoman10-DemiOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbo10.pfb
+t5-lmbx10 LMRoman10-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbx10.pfb
+t5-lmbx12 LMRoman12-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbx12.pfb
+t5-lmbx5 LMRoman5-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbx5.pfb
+t5-lmbx6 LMRoman6-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbx6.pfb
+t5-lmbx7 LMRoman7-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbx7.pfb
+t5-lmbx8 LMRoman8-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbx8.pfb
+t5-lmbx9 LMRoman9-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbx9.pfb
+t5-lmbxi10 LMRoman10-BoldItalic "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbxi10.pfb
+t5-lmbxo10 LMRoman10-BoldOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmbxo10.pfb
+t5-lmcsc10 LMRoman10-CapsRegular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmcsc10.pfb
+t5-lmcsco10 LMRoman10-CapsOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmcsco10.pfb
+t5-lmr10 LMRoman10-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr10.pfb
+t5-lmr12 LMRoman12-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr12.pfb
+t5-lmr17 LMRoman17-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr17.pfb
+t5-lmr5 LMRoman5-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr5.pfb
+t5-lmr6 LMRoman6-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr6.pfb
+t5-lmr7 LMRoman7-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr7.pfb
+t5-lmr8 LMRoman8-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr8.pfb
+t5-lmr9 LMRoman9-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmr9.pfb
+t5-lmri10 LMRoman10-Italic "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmri10.pfb
+t5-lmri12 LMRoman12-Italic "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmri12.pfb
+t5-lmri7 LMRoman7-Italic "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmri7.pfb
+t5-lmri8 LMRoman8-Italic "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmri8.pfb
+t5-lmri9 LMRoman9-Italic "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmri9.pfb
+t5-lmro10 LMRoman10-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmro10.pfb
+t5-lmro12 LMRoman12-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmro12.pfb
+t5-lmro17 LMRoman17-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmro17.pfb
+t5-lmro8 LMRoman8-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmro8.pfb
+t5-lmro9 LMRoman9-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmro9.pfb
+t5-lmss10 LMSans10-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmss10.pfb
+t5-lmss12 LMSans12-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmss12.pfb
+t5-lmss17 LMSans17-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmss17.pfb
+t5-lmss8 LMSans8-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmss8.pfb
+t5-lmss9 LMSans9-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmss9.pfb
+t5-lmssbo10 LMSans10-BoldOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssbo10.pfb
+t5-lmssbx10 LMSans10-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssbx10.pfb
+t5-lmssdc10 LMSans10-DemiCondensed "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssdc10.pfb
+t5-lmssdo10 LMSans10-DemiCondensedOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssdo10.pfb
+t5-lmsso10 LMSans10-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmsso10.pfb
+t5-lmsso12 LMSans12-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmsso12.pfb
+t5-lmsso17 LMSans17-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmsso17.pfb
+t5-lmsso8 LMSans8-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmsso8.pfb
+t5-lmsso9 LMSans9-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmsso9.pfb
+t5-lmssq8 LMSansQuotation8-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssq8.pfb
+t5-lmssqbo8 LMSansQuotation8-BoldOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssqbo8.pfb
+t5-lmssqbx8 LMSansQuotation8-Bold "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssqbx8.pfb
+t5-lmssqo8 LMSansQuotation8-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmssqo8.pfb
+t5-lmtcsc10 LMTypewriter10-CapsRegular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtcsc10.pfb
+t5-lmtcso10 LMTypewriter10-CapsOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtcso10.pfb
+t5-lmtl10 LMTypewriter10-Light "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtl10.pfb
+t5-lmtlo10 LMTypewriter10-LightOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtlo10.pfb
+t5-lmtlc10 LMTypewriter10-LightCondensed "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtlc10.pfb
+t5-lmtlco10 LMTypewriter10-LightCondensedOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtlco10.pfb
+t5-lmtk10 LMTypewriter10-Dark "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtk10.pfb
+t5-lmtko10 LMTypewriter10-DarkOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtko10.pfb
+t5-lmtt10 LMTypewriter10-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtt10.pfb
+t5-lmtt12 LMTypewriter12-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtt12.pfb
+t5-lmtt8 LMTypewriter8-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtt8.pfb
+t5-lmtt9 LMTypewriter9-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtt9.pfb
+t5-lmtti10 LMTypewriter10-Italic "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtti10.pfb
+t5-lmtto10 LMTypewriter10-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmtto10.pfb
+t5-lmvtt10 LMTypewriterVarWd10-Regular "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmvtt10.pfb
+t5-lmvtto10 LMTypewriterVarWd10-Oblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmvtto10.pfb
+t5-lmvtl10 LMTypewriterVarWd10-Light "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmvtl10.pfb
+t5-lmvtlo10 LMTypewriterVarWd10-LightOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmvtlo10.pfb
+t5-lmvtk10 LMTypewriterVarWd10-Dark "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmvtk10.pfb
+t5-lmvtko10 LMTypewriterVarWd10-DarkOblique "enclmt5os ReEncodeFont" <lm-t5-os.enc <lmvtko10.pfb
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/texnansi-base.map b/Master/texmf-dist/fonts/map/pdftex/context/texnansi-base.map
new file mode 100644
index 00000000000..3078a1d1f9b
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/texnansi-base.map
@@ -0,0 +1,142 @@
+% author: Hans Hagen
+%
+% This map file defines the texnansi alternatives of the public fonts,
+% beware, these are seldom present on your system. If you really want
+% to use these fonts, uncomment the relevant lines. If no fonts are
+% present, pdftex may get confused.
+
+% courier / urw
+
+% ucrb8y NimbusMonL-Bold <texnansi.enc <ucrb8a.pfb
+% ucrbo8y NimbusMonL-BoldObli <texnansi.enc <ucrbo8a.pfb
+% ucrr8y NimbusMonL-Regu <texnansi.enc <ucrr8a.pfb
+% ucrro8y NimbusMonL-ReguObli <texnansi.enc <ucrro8a.pfb
+
+% courier / adobe
+
+% pcrb8y NimbusMonL-Bold <texnansi.enc <ucrb8a.pfb
+% pcrbo8y NimbusMonL-BoldObli <texnansi.enc <ucrbo8a.pfb
+% pcrr8y NimbusMonL-Regu <texnansi.enc <ucrr8a.pfb
+% pcrro8y NimbusMonL-ReguObli <texnansi.enc <ucrro8a.pfb
+
+% helvetica / urw
+
+% uhvb8y NimbusSanL-Bold <texnansi.enc <uhvb8a.pfb
+% uhvbo8y NimbusSanL-BoldItal <texnansi.enc <uhvbo8a.pfb
+% uhvr8y NimbusSanL-Regu <texnansi.enc <uhvr8a.pfb
+% uhvro8y NimbusSanL-ReguItal <texnansi.enc <uhvro8a.pfb
+
+% helvetica / adobe
+
+% phvb8y NimbusSanL-Bold <texnansi.enc <uhvb8a.pfb
+% phvbo8y NimbusSanL-BoldItal <texnansi.enc <uhvbo8a.pfb
+% phvr8y NimbusSanL-Regu <texnansi.enc <uhvr8a.pfb
+% phvro8y NimbusSanL-ReguItal <texnansi.enc <uhvro8a.pfb
+
+% times / urw
+
+% utmb8y NimbusRomNo9L-Medi <texnansi.enc <utmb8a.pfb
+% utmbi8y NimbusRomNo9L-MediItal <texnansi.enc <utmbi8a.pfb
+% utmr8y NimbusRomNo9L-Regu <texnansi.enc <utmr8a.pfb
+% utmri8y NimbusRomNo9L-ReguItal <texnansi.enc <utmri8a.pfb
+
+% utmbo8y NimbusRomNo9L-Medi ".167 SlantFont" <texnansi.enc <utmb8a.pfb
+% utmro8y NimbusRomNo9L-Regu ".167 SlantFont" <texnansi.enc <utmr8a.pfb
+
+% times / adobe
+
+% ptmb8y NimbusRomNo9L-Medi <texnansi.enc <utmb8a.pfb
+% ptmbi8y NimbusRomNo9L-MediItal <texnansi.enc <utmbi8a.pfb
+% ptmr8y NimbusRomNo9L-Regu <texnansi.enc <utmr8a.pfb
+% ptmri8y NimbusRomNo9L-ReguItal <texnansi.enc <utmri8a.pfb
+
+% ptmbo8y NimbusRomNo9L-Medi ".167 SlantFont" <texnansi.enc <utmb8a.pfb
+% ptmro8y NimbusRomNo9L-Regu ".167 SlantFont" <texnansi.enc <utmr8a.pfb
+
+% palatino / urw
+
+% uplb8y URWPalladioL-Bold <texnansi.enc <uplb8a.pfb
+% uplbi8y URWPalladioL-BoldItal <texnansi.enc <uplbi8a.pfb
+% uplr8y URWPalladioL-Roma <texnansi.enc <uplr8a.pfb
+% uplri8y URWPalladioL-Ital <texnansi.enc <uplri8a.pfb
+
+% uplbo8y URWPalladioL-Bold ".167 SlantFont" <texnansi.enc <uplb8a.pfb
+% uplro8y URWPalladioL-Roma ".167 SlantFont" <texnansi.enc <uplr8a.pfb
+
+% palatino / adobe
+
+% pplb8y URWPalladioL-Bold <texnansi.enc <uplb8a.pfb
+% pplbi8y URWPalladioL-BoldItal <texnansi.enc <uplbi8a.pfb
+% pplr8y URWPalladioL-Roma <texnansi.enc <uplr8a.pfb
+% pplri8y URWPalladioL-Ital <texnansi.enc <uplri8a.pfb
+
+% pplbo8y URWPalladioL-Bold ".167 SlantFont" <texnansi.enc <uplb8a.pfb
+% pplro8y URWPalladioL-Roma ".167 SlantFont" <texnansi.enc <uplr8a.pfb
+
+% bookman / urw
+
+% ubkd8y URWBookmanL-DemiBold <texnansi.enc <ubkd8a.pfb
+% ubkdi8y URWBookmanL-DemiBoldItal <texnansi.enc <ubkdi8a.pfb
+% ubkl8y URWBookmanL-Ligh <texnansi.enc <ubkl8a.pfb
+% vubkli8y URWBookmanL-LighItal <texnansi.enc <ubkli8a.pfb
+
+% ubkdo8y URWBookmanL-DemiBold ".167 SlantFont" <texnansi.enc <ubkd8a.pfb
+% ubklo8y URWBookmanL-Ligh ".167 SlantFont" <texnansi.enc <ubkl8a.pfb
+
+% bookman / adobe
+
+% pbkd8y URWBookmanL-DemiBold <texnansi.enc <ubkd8a.pfb
+% pbkdi8y URWBookmanL-DemiBoldItal <texnansi.enc <ubkdi8a.pfb
+% pbkl8y URWBookmanL-Ligh <texnansi.enc <ubkl8a.pfb
+% pbkli8y URWBookmanL-LighItal <texnansi.enc <ubkli8a.pfb
+
+% pbkdo8y URWBookmanL-DemiBold ".167 SlantFont" <texnansi.enc <ubkd8a.pfb
+% pbklo8y URWBookmanL-Ligh ".167 SlantFont" <texnansi.enc <ubkl8a.pfb
+
+% chancery / urw
+
+% uzcmi8y URWChanceryL-MediItal <texnansi.enc <uzcmi8a.pfb
+
+% chancery / adobe
+
+% pzcmi8y URWChanceryL-MediItal <texnansi.enc <uzcmi8a.pfb
+
+% schoolbook / urw
+
+% uncb8y CenturySchL-Bold <texnansi.enc <uncb8a.pfb
+% uncbi8y CenturySchL-BoldItal <texnansi.enc <uncbi8a.pfb
+% uncr8y CenturySchL-Roma <texnansi.enc <uncr8a.pfb
+% uncri8y CenturySchL-Ital <texnansi.enc <uncri8a.pfb
+
+% uncbo8y CenturySchL-Bold ".167 SlantFont" <texnansi.enc <uncb8a.pfb
+% uncro8y CenturySchL-Roma ".167 SlantFont" <texnansi.enc <uncr8a.pfb
+
+% schoolbook / adobe
+
+% pncb8y CenturySchL-Bold <texnansi.enc <uncb8a.pfb
+% pncbi8y CenturySchL-BoldItal <texnansi.enc <uncbi8a.pfb
+% pncr8y CenturySchL-Roma <texnansi.enc <uncr8a.pfb
+% pncri8y CenturySchL-Ital <texnansi.enc <uncri8a.pfb
+
+% pncbo8y CenturySchL-Bold ".167 SlantFont" <texnansi.enc <uncb8a.pfb
+% pncro8y CenturySchL-Roma ".167 SlantFont" <texnansi.enc <uncr8a.pfb
+
+% utopia
+
+% putb8y Utopia-Bold <texnansi.enc <putb8a.pfb
+% putbi8y Utopia-BoldItalic <texnansi.enc <putbi8a.pfb
+% putr8y Utopia-Regular <texnansi.enc <putr8a.pfb
+% putri8y Utopia-Italic <texnansi.enc <putri8a.pfb
+
+% putbo8y Utopia-Bold ".167 SlantFont" <texnansi.enc <putb8a.pfb
+% putro8y Utopia-Regular ".167 SlantFont" <texnansi.enc <putr8a.pfb
+
+% charter
+
+% bchb8y CharterBT-Bold <texnansi.enc <bchb8a.pfb
+% bchbi8y CharterBT-BoldItalic <texnansi.enc <bchbi8a.pfb
+% bchr8y CharterBT-Roman <texnansi.enc <bchr8a.pfb
+% bchri8y CharterBT-Italic <texnansi.enc <bchri8a.pfb
+
+% bchbo8y CharterBT-Bold ".167 SlantFont" <texnansi.enc <bchb8a.pfb
+% bchro8y CharterBT-Roman ".167 SlantFont " <texnansi.enc <bchr8a.pfb \ No newline at end of file
diff --git a/Master/texmf-dist/fonts/map/pdftex/context/texnansi-os-public-lm.map b/Master/texmf-dist/fonts/map/pdftex/context/texnansi-os-public-lm.map
new file mode 100644
index 00000000000..85ba31a063d
--- /dev/null
+++ b/Master/texmf-dist/fonts/map/pdftex/context/texnansi-os-public-lm.map
@@ -0,0 +1,69 @@
+texnansi-lmb10 LMRoman10-Demi "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmb10.pfb
+texnansi-lmbo10 LMRoman10-DemiOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbo10.pfb
+texnansi-lmbx10 LMRoman10-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbx10.pfb
+texnansi-lmbx12 LMRoman12-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbx12.pfb
+texnansi-lmbx5 LMRoman5-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbx5.pfb
+texnansi-lmbx6 LMRoman6-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbx6.pfb
+texnansi-lmbx7 LMRoman7-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbx7.pfb
+texnansi-lmbx8 LMRoman8-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbx8.pfb
+texnansi-lmbx9 LMRoman9-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbx9.pfb
+texnansi-lmbxi10 LMRoman10-BoldItalic "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbxi10.pfb
+texnansi-lmbxo10 LMRoman10-BoldOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmbxo10.pfb
+texnansi-lmcsc10 LMRoman10-CapsRegular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmcsc10.pfb
+texnansi-lmcsco10 LMRoman10-CapsOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmcsco10.pfb
+texnansi-lmr10 LMRoman10-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr10.pfb
+texnansi-lmr12 LMRoman12-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr12.pfb
+texnansi-lmr17 LMRoman17-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr17.pfb
+texnansi-lmr5 LMRoman5-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr5.pfb
+texnansi-lmr6 LMRoman6-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr6.pfb
+texnansi-lmr7 LMRoman7-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr7.pfb
+texnansi-lmr8 LMRoman8-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr8.pfb
+texnansi-lmr9 LMRoman9-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmr9.pfb
+texnansi-lmri10 LMRoman10-Italic "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmri10.pfb
+texnansi-lmri12 LMRoman12-Italic "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmri12.pfb
+texnansi-lmri7 LMRoman7-Italic "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmri7.pfb
+texnansi-lmri8 LMRoman8-Italic "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmri8.pfb
+texnansi-lmri9 LMRoman9-Italic "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmri9.pfb
+texnansi-lmro10 LMRoman10-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmro10.pfb
+texnansi-lmro12 LMRoman12-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmro12.pfb
+texnansi-lmro17 LMRoman17-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmro17.pfb
+texnansi-lmro8 LMRoman8-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmro8.pfb
+texnansi-lmro9 LMRoman9-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmro9.pfb
+texnansi-lmss10 LMSans10-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmss10.pfb
+texnansi-lmss12 LMSans12-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmss12.pfb
+texnansi-lmss17 LMSans17-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmss17.pfb
+texnansi-lmss8 LMSans8-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmss8.pfb
+texnansi-lmss9 LMSans9-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmss9.pfb
+texnansi-lmssbo10 LMSans10-BoldOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssbo10.pfb
+texnansi-lmssbx10 LMSans10-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssbx10.pfb
+texnansi-lmssdc10 LMSans10-DemiCondensed "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssdc10.pfb
+texnansi-lmssdo10 LMSans10-DemiCondensedOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssdo10.pfb
+texnansi-lmsso10 LMSans10-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmsso10.pfb
+texnansi-lmsso12 LMSans12-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmsso12.pfb
+texnansi-lmsso17 LMSans17-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmsso17.pfb
+texnansi-lmsso8 LMSans8-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmsso8.pfb
+texnansi-lmsso9 LMSans9-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmsso9.pfb
+texnansi-lmssq8 LMSansQuotation8-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssq8.pfb
+texnansi-lmssqbo8 LMSansQuotation8-BoldOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssqbo8.pfb
+texnansi-lmssqbx8 LMSansQuotation8-Bold "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssqbx8.pfb
+texnansi-lmssqo8 LMSansQuotation8-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmssqo8.pfb
+texnansi-lmtcsc10 LMTypewriter10-CapsRegular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtcsc10.pfb
+texnansi-lmtcso10 LMTypewriter10-CapsOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtcso10.pfb
+texnansi-lmtl10 LMTypewriter10-Light "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtl10.pfb
+texnansi-lmtlo10 LMTypewriter10-LightOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtlo10.pfb
+texnansi-lmtlc10 LMTypewriter10-LightCondensed "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtlc10.pfb
+texnansi-lmtlco10 LMTypewriter10-LightCondensedOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtlco10.pfb
+texnansi-lmtk10 LMTypewriter10-Dark "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtk10.pfb
+texnansi-lmtko10 LMTypewriter10-DarkOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtko10.pfb
+texnansi-lmtt10 LMTypewriter10-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtt10.pfb
+texnansi-lmtt12 LMTypewriter12-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtt12.pfb
+texnansi-lmtt8 LMTypewriter8-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtt8.pfb
+texnansi-lmtt9 LMTypewriter9-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtt9.pfb
+texnansi-lmtti10 LMTypewriter10-Italic "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtti10.pfb
+texnansi-lmtto10 LMTypewriter10-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmtto10.pfb
+texnansi-lmvtt10 LMTypewriterVarWd10-Regular "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmvtt10.pfb
+texnansi-lmvtto10 LMTypewriterVarWd10-Oblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmvtto10.pfb
+texnansi-lmvtl10 LMTypewriterVarWd10-Light "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmvtl10.pfb
+texnansi-lmvtlo10 LMTypewriterVarWd10-LightOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmvtlo10.pfb
+texnansi-lmvtk10 LMTypewriterVarWd10-Dark "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmvtk10.pfb
+texnansi-lmvtko10 LMTypewriterVarWd10-DarkOblique "enclmtexnansios ReEncodeFont" <lm-texnansi-os.enc <lmvtko10.pfb
diff --git a/Master/texmf-dist/metapost/context/base/mpii/metafun.mpii b/Master/texmf-dist/metapost/context/base/mpii/metafun.mpii
new file mode 100644
index 00000000000..9c55191f773
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/metafun.mpii
@@ -0,0 +1,65 @@
+%D \module
+%D [ file=metafun.mp,
+%D version=2000.07.15,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=format generation file,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D When generating many graphics at runtime, it can save run
+%D time to use a format file. We could have named this file
+%D \type {context}, but this is error prone, because it forces
+%D to use the progname \type {mpost} or \type {context}
+%D explicitly, depending on the needs. When using the format,
+%D a mismatch in the memory specification of \type {mpost} or
+%D \type {context} (the \TEX\ one) could lead to lost strings
+%D (and as a result in buggy boundingbox and special
+%D handling). By using the name \type {metatex} we make sure
+%D that we use (unless overloaded) the settings of \type
+%D {mpost}.
+
+%D First we input John Hobby's metapost plain file. However,
+%D because we want to prevent dependency problems and in the
+%D end even may use a patched version, we prefer to use a
+%D copy.
+
+input "mp-base.mpii" ;
+input "mp-tool.mpii" ;
+input "mp-spec.mpii" ;
+input "mp-core.mpii" ;
+input "mp-page.mpii" ;
+input "mp-text.mpii" ;
+input "mp-txts.mpii" ;
+input "mp-shap.mpii" ;
+input "mp-butt.mpii" ;
+input "mp-char.mpii" ;
+input "mp-step.mpii" ;
+input "mp-grph.mpii" ;
+input "mp-figs.mpii" ;
+%%%%% "mp-form.mpii" ;
+input "mp-grid.mpii" ;
+input "mp-func.mpii" ;
+
+string metafunversion ;
+
+metafunversion = "metafun ii" & " " &
+ decimal year & "-" &
+ decimal month & "-" &
+ decimal day & " " &
+ if ((time div 60) < 10) : "0" & fi
+ decimal (time div 60) & ":" &
+ if ((time-(time div 60)*60) < 10) : "0" & fi
+ decimal (time-(time div 60)*60) ;
+
+let normalend = end ;
+
+def end =
+ ; message "" ; message metafunversion ; message "" ; normalend ;
+enddef ;
+
+% dump ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-back.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-back.mpii
new file mode 100644
index 00000000000..f588adea9c4
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-back.mpii
@@ -0,0 +1,205 @@
+%D \module
+%D [ file=mp-back.mp,
+%D version=2000.05.31,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=backgrounds,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+if known context_back : endinput ; fi ;
+
+boolean context_back ; context_back := true ;
+
+def some_hash ( expr hash_width ,
+ hash_height ,
+ hash_linewidth ,
+ hash_linecolor ,
+ hash_angle ,
+ hash_gap ) =
+
+ stripe_gap := hash_gap ;
+ stripe_angle := hash_angle ;
+ drawoptions (withpen pencircle scaled hash_linewidth
+ withcolor hash_linecolor) ;
+ path p ; p := unitsquare xscaled hash_width yscaled hash_height ;
+ stripe_path_a () (draw) p ; % next we move it all to quadrant 1
+ currentpicture := currentpicture shifted urcorner currentpicture ;
+
+enddef ;
+
+def some_double_back (expr back_type ,
+ back_width ,
+ back_height ,
+ back_delta ,
+ back_linewidth ,
+ back_linecolor ,
+ back_fillcolor ,
+ back_topcolor ,
+ back_bottomcolor ,
+ back_leftcolor ,
+ back_rightcolor ) =
+
+ numeric ww ; ww := back_width ;
+ numeric hh ; hh := back_height ;
+ numeric dd ; dd := back_delta ;
+
+ color back_nillcolor ; back_nillcolor := back_topcolor ;
+
+ path p ; p := fullsquare xscaled ww yscaled hh ;
+ path q ; q := fullsquare xscaled (ww-2dd) yscaled (hh-2dd) ;
+ path r ; r := llcorner p --
+ lrcorner p shifted (-3dd,0) .. controls lrcorner p ..
+ lrcorner p shifted (0, 3dd) --
+ urcorner p shifted (0,-3dd) .. controls urcorner p ..
+ urcorner p shifted (-3dd,0) --
+ ulcorner p -- cycle ;
+ path s ; s := r xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ;
+ path t ; t := llcorner p --
+ lrcorner p --
+ urcorner p shifted (0,-3dd) .. controls urcorner p ..
+ urcorner p shifted (-3dd,0) --
+ ulcorner p shifted ( 3dd,0) .. controls ulcorner p ..
+ ulcorner p shifted (0,-3dd) --
+ llcorner p -- cycle ;
+ path u ; u := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ;
+ path v ; v := llcorner p shifted ( 3dd,0) --
+ lrcorner p shifted (-3dd,0) .. controls lrcorner p ..
+ lrcorner p shifted (0, 3dd) --
+ urcorner p shifted (0,-3dd) .. controls urcorner p ..
+ urcorner p shifted (-3dd,0) --
+ ulcorner p shifted ( 3dd,0) .. controls ulcorner p ..
+ ulcorner p shifted (0,-3dd) ..
+ llcorner p shifted (0, 3dd) .. controls llcorner p .. cycle ; % {down} .. cycle ;
+ path w ; w := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ;
+ path a ; a := llcorner p -- ulcorner p --
+ ulcorner q -- llcorner q -- cycle ;
+ path b ; b := llcorner p -- lrcorner p --
+ lrcorner q -- llcorner q -- cycle ;
+ path c ; c := lrcorner p -- urcorner p --
+ urcorner q -- lrcorner q -- cycle ;
+ path d ; d := ulcorner p -- urcorner p --
+ urcorner q -- ulcorner q -- cycle ;
+ path e ; e := llcorner p -- lrcorner p --
+ urcorner p -- urcorner q --
+ lrcorner q -- llcorner q -- cycle ;
+ path f ; f := llcorner p -- ulcorner p --
+ urcorner p -- urcorner q --
+ ulcorner q -- llcorner q -- cycle ;
+
+ linecap := butt ; pickup pencircle scaled back_linewidth ;
+
+ if back_type=1 :
+
+ fill p withcolor back_fillcolor ;
+ fill a withcolor back_leftcolor ;
+ fill b withcolor back_bottomcolor ;
+ fill c withcolor back_rightcolor ;
+ fill d withcolor back_topcolor ;
+ draw a withcolor back_linecolor ;
+ draw d withcolor back_linecolor ;
+ draw b withcolor back_linecolor ;
+ draw c withcolor back_linecolor ;
+
+ elseif back_type=2 :
+
+ fill p withcolor back_fillcolor ;
+ fill e withcolor back_bottomcolor ;
+ fill f withcolor back_topcolor ;
+ draw e withcolor back_linecolor ;
+ draw f withcolor back_linecolor ;
+
+ elseif back_type=3 :
+
+ fill v withcolor back_nillcolor ;
+ fill w withcolor back_fillcolor ;
+ draw v withcolor back_linecolor ;
+ draw w withcolor back_linecolor ;
+
+ elseif back_type=4 :
+
+ fill t withcolor back_nillcolor ;
+ fill u withcolor back_fillcolor ;
+ draw t withcolor back_linecolor ;
+ draw u withcolor back_linecolor ;
+
+ elseif back_type=5 :
+
+ t := t rotatedaround(center t,180) ;
+ u := u rotatedaround(center u,180) ;
+
+ fill t withcolor back_nillcolor ;
+ fill u withcolor back_fillcolor ;
+ draw t withcolor back_linecolor ;
+ draw u withcolor back_linecolor ;
+
+ elseif back_type=6 :
+
+ r := r rotatedaround(center r,180) ;
+ s := s rotatedaround(center s,180) ;
+
+ fill r withcolor back_nillcolor ;
+ fill s withcolor back_fillcolor ;
+ draw r withcolor back_linecolor ;
+ draw s withcolor back_linecolor ;
+
+ elseif back_type=7 :
+
+ fill r withcolor back_nillcolor ;
+ fill s withcolor back_fillcolor ;
+ draw r withcolor back_linecolor ;
+ draw s withcolor back_linecolor ;
+
+fi ;
+
+enddef ;
+
+endinput ;
+
+beginfig (1) ;
+
+some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, .6white, .7white, .6white)
+
+currentpicture := currentpicture shifted (0,-3cm) ;
+
+some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, .6white, white, white)
+
+currentpicture := currentpicture shifted (0,-3cm) ;
+
+some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, white, white, white)
+
+currentpicture := currentpicture shifted (0,-3cm) ;
+
+some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, white, white, white)
+
+currentpicture := currentpicture shifted (0,-3cm) ;
+
+some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, white, white, white)
+
+currentpicture := currentpicture shifted (0,-3cm) ;
+
+some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, white, white, white)
+
+currentpicture := currentpicture shifted (0,-3cm) ;
+
+some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, white, white, white)
+
+currentpicture := currentpicture shifted (0,-3cm) ;
+
+some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm,
+ .5white, .8white, .7white, white, white, white)
+
+endfig ;
+
+end .
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-base.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-base.mpii
new file mode 100644
index 00000000000..894af63f1e0
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-base.mpii
@@ -0,0 +1,598 @@
+% This is (currently) a copy of the plain.mp file. We use a copy
+% because (1) we want to make sure that there are no unresolved
+% dependencies, and (2) we may patch this file eventually.
+%
+% colorpart will be overloaded later (we already had that one)
+% _findarr now has a filldraw, was fill in 0.63
+
+% This file gives the macros for plain MetaPost
+% It contains all the features of plain METAFONT except those specific to
+% font-making. (See The METAFONTbook by D.E. Knuth).
+% There are also a number of macros for labeling figures, etc.
+string base_name, base_version; base_name="plain"; base_version="1.004 for metafun ii";
+
+message "Preloading the plain mem file, version "&base_version;
+
+delimiters (); % this makes parentheses behave like parentheses
+def upto = step 1 until enddef; % syntactic sugar
+def downto = step -1 until enddef;
+def exitunless expr c = exitif not c enddef;
+let relax = \; % ignore the word `relax', as in TeX
+let \\ = \; % double relaxation is like single
+def ]] = ] ] enddef; % right brackets should be loners
+def -- = {curl 1}..{curl 1} enddef;
+def --- = .. tension infinity .. enddef;
+def ... = .. tension atleast 1 .. enddef;
+
+def gobble primary g = enddef;
+primarydef g gobbled gg = enddef;
+def hide(text t) = exitif numeric begingroup t;endgroup; enddef;
+def ??? = hide(interim showstopping:=1; showdependencies) enddef;
+def stop expr s = message s; gobble readstring enddef;
+
+warningcheck:=1;
+tracinglostchars:=1;
+
+def interact = % sets up to make "show" commands stop
+ hide(showstopping:=1; tracingonline:=1) enddef;
+
+def loggingall = % puts tracing info into the log
+ tracingcommands:=3; tracingtitles:=1; tracingequations:=1;
+ tracingcapsules:=1; tracingspecs:=2; tracingchoices:=1; tracinglostchars:=1;
+ tracingstats:=1; tracingoutput:=1; tracingmacros:=1; tracingrestores:=1;
+ enddef;
+
+def tracingall = % turns on every form of tracing
+ tracingonline:=1; showstopping:=1; loggingall enddef;
+
+def tracingnone = % turns off every form of tracing
+ tracingcommands:=0; tracingtitles:=0; tracingequations:=0;
+ tracingcapsules:=0; tracingspecs:=0; tracingchoices:=0; tracinglostchars:=0;
+ tracingstats:=0; tracingoutput:=0; tracingmacros:=0; tracingrestores:=0;
+ enddef;
+
+
+
+%% dash patterns
+
+vardef dashpattern(text t) =
+ save on, off, w;
+ let on=_on_;
+ let off=_off_;
+ w = 0;
+ nullpicture t
+enddef;
+
+tertiarydef p _on_ d =
+ begingroup save pic;
+ picture pic; pic=p;
+ addto pic doublepath (w,w)..(w+d,w);
+ w := w+d;
+ pic shifted (0,d)
+ endgroup
+enddef;
+
+tertiarydef p _off_ d =
+ begingroup w:=w+d;
+ p shifted (0,d)
+ endgroup
+enddef;
+
+
+
+%% basic constants and mathematical macros
+
+% numeric constants
+newinternal eps,epsilon,infinity,_;
+eps := .00049; % this is a pretty small positive number
+epsilon := 1/256/256; % but this is the smallest
+infinity := 4095.99998; % and this is the largest
+_ := -1; % internal constant to make macros unreadable but shorter
+
+newinternal mitered, rounded, beveled, butt, squared;
+mitered:=0; rounded:=1; beveled:=2; % linejoin types
+butt:=0; rounded:=1; squared:=2; % linecap types
+
+
+% pair constants
+pair right,left,up,down,origin;
+origin=(0,0); up=-down=(0,1); right=-left=(1,0);
+
+% path constants
+path quartercircle,halfcircle,fullcircle,unitsquare;
+fullcircle = makepath pencircle;
+halfcircle = subpath (0,4) of fullcircle;
+quartercircle = subpath (0,2) of fullcircle;
+unitsquare=(0,0)--(1,0)--(1,1)--(0,1)--cycle;
+
+% transform constants
+transform identity;
+for z=origin,right,up: z transformed identity = z; endfor
+
+% color constants
+color black, white, red, green, blue, cyan, magenta, yellow, background;
+black = (0,0,0);
+white = (1,1,1);
+red = (1,0,0);
+green = (0,1,0);
+blue = (0,0,1);
+cyan = (0,1,1);
+magenta = (1,0,1);
+yellow = (1,1,0);
+background = white; % The user can reset this
+
+% color part selection for within
+
+newinternal nocolormodel ; nocolormodel := 1 ;
+newinternal greycolormodel ; greycolormodel := 3 ;
+newinternal graycolormodel ; graycolormodel := 3 ;
+newinternal rgbcolormodel ; rgbcolormodel := 5 ;
+newinternal cmykcolormodel ; cmykcolormodel := 7 ;
+
+def colorpart primary t =
+ if colormodel t=cmykcolormodel:
+ (cyanpart t, magentapart t, yellowpart t, blackpart t)
+ elseif colormodel t=rgbcolormodel:
+ (redpart t, greenpart t, bluepart t)
+ elseif colormodel t=graycolormodel:
+ (greypart t)
+ elseif colormodel t=nocolormodel:
+ false
+ else:
+ %%% For clipping and bounding paths, etc.
+ if defaultcolormodel=cmykcolormodel: (0,0,0,1)
+ elseif defaultcolormodel=rgbcolormodel: black
+ elseif defaultcolormodel=graycolormodel: 0
+ else: false
+ fi
+ fi
+enddef;
+
+% picture constants
+picture blankpicture,evenly,withdots;
+blankpicture=nullpicture; % `display blankpicture...'
+evenly=dashpattern(on 3 off 3); % `dashed evenly'
+withdots=dashpattern(off 2.5 on 0 off 2.5); % `dashed withdots'
+
+% string constants
+string ditto, EOF;
+ditto = char 34; % ASCII double-quote mark
+EOF = char 0; % end-of-file for readfrom and write..to
+
+% pen constants
+pen pensquare,penrazor,penspeck;
+pensquare = makepen(unitsquare shifted -(.5,.5));
+penrazor = makepen((-.5,0)--(.5,0)--cycle);
+penspeck=pensquare scaled eps;
+
+% nullary operators
+vardef whatever = save ?; ? enddef;
+
+% unary operators
+let abs = length;
+
+vardef round primary u =
+ if numeric u: floor(u+.5)
+ elseif pair u: (round xpart u, round ypart u)
+ else: u fi enddef;
+
+vardef ceiling primary x = -floor(-x) enddef;
+
+vardef byte primary s =
+ if string s: ASCII fi s enddef;
+
+vardef dir primary d = right rotated d enddef;
+
+vardef unitvector primary z = z/abs z enddef;
+
+vardef inverse primary T =
+ transform T_; T_ transformed T = identity; T_ enddef;
+
+vardef counterclockwise primary c =
+ if turningnumber c <= 0: reverse fi c enddef;
+
+vardef tensepath expr r =
+ for k=0 upto length r - 1: point k of r --- endfor
+ if cycle r: cycle else: point infinity of r fi enddef;
+
+vardef center primary p = .5[llcorner p, urcorner p] enddef;
+
+
+
+% binary operators
+
+primarydef x mod y = (x-y*floor(x/y)) enddef;
+primarydef x div y = floor(x/y) enddef;
+primarydef w dotprod z = (xpart w * xpart z + ypart w * ypart z) enddef;
+
+primarydef x**y = if y=2: x*x else: takepower y of x fi enddef;
+def takepower expr y of x =
+ if x>0: mexp(y*mlog x)
+ elseif (x=0) and (y>0): 0
+ else: 1
+ if y=floor y:
+ if y>=0: for n=1 upto y: *x endfor
+ else: for n=_ downto y: /x endfor
+ fi
+ else: hide(errmessage "Undefined power: " & decimal x&"**"&decimal y)
+ fi fi enddef;
+
+vardef direction expr t of p =
+ postcontrol t of p - precontrol t of p enddef;
+
+vardef directionpoint expr z of p =
+ a_:=directiontime z of p;
+ if a_<0: errmessage("The direction doesn't occur"); fi
+ point a_ of p enddef;
+
+secondarydef p intersectionpoint q =
+ begingroup save x_,y_; (x_,y_)=p intersectiontimes q;
+ if x_<0: errmessage("The paths don't intersect"); origin
+ else: .5[point x_ of p, point y_ of q] fi endgroup
+enddef;
+
+tertiarydef p softjoin q =
+ begingroup c_:=fullcircle scaled 2join_radius shifted point 0 of q;
+ a_:=ypart(c_ intersectiontimes p); b_:=ypart(c_ intersectiontimes q);
+ if a_<0:point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi
+ ... if b_<0:{direction infinity of q}point infinity of q
+ else: subpath(b_,infinity) of q fi endgroup enddef;
+newinternal join_radius,a_,b_; path c_;
+
+
+path cuttings; % what got cut off
+
+tertiarydef a cutbefore b = % tries to cut as little as possible
+ begingroup save t;
+ (t, whatever) = a intersectiontimes b;
+ if t<0:
+ cuttings:=point 0 of a;
+ a
+ else: cuttings:= subpath (0,t) of a;
+ subpath (t,length a) of a
+ fi
+ endgroup
+enddef;
+
+tertiarydef a cutafter b =
+ reverse (reverse a cutbefore b)
+ hide(cuttings:=reverse cuttings)
+enddef;
+
+
+
+% special operators
+vardef incr suffix $ = $:=$+1; $ enddef;
+vardef decr suffix $ = $:=$-1; $ enddef;
+
+def reflectedabout(expr w,z) = % reflects about the line w..z
+ transformed
+ begingroup transform T_;
+ w transformed T_ = w; z transformed T_ = z;
+ xxpart T_ = -yypart T_; xypart T_ = yxpart T_; % T_ is a reflection
+ T_ endgroup enddef;
+
+def rotatedaround(expr z, d) = % rotates d degrees around z
+ shifted -z rotated d shifted z enddef;
+let rotatedabout = rotatedaround; % for roundabout people
+
+vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings
+ save u_; setu_ u; for uu = t: if uu<u_: u_:=uu; fi endfor
+ u_ enddef;
+
+vardef max(expr u)(text t) = % t is a list of numerics, pairs, or strings
+ save u_; setu_ u; for uu = t: if uu>u_: u_:=uu; fi endfor
+ u_ enddef;
+
+def setu_ primary u =
+ if pair u: pair u_ elseif string u: string u_ fi;
+ u_=u enddef;
+
+def flex(text t) = % t is a list of pairs
+ hide(n_:=0; for z=t: z_[incr n_]:=z; endfor
+ dz_:=z_[n_]-z_1)
+ z_1 for k=2 upto n_-1: ...z_[k]{dz_} endfor ...z_[n_] enddef;
+newinternal n_; pair z_[],dz_;
+
+def superellipse(expr r,t,l,b,s)=
+ r{up}...(s[xpart t,xpart r],s[ypart r,ypart t]){t-r}...
+ t{left}...(s[xpart t,xpart l],s[ypart l,ypart t]){l-t}...
+ l{down}...(s[xpart b,xpart l],s[ypart l,ypart b]){b-l}...
+ b{right}...(s[xpart b,xpart r],s[ypart r,ypart b]){r-b}...cycle enddef;
+
+vardef interpath(expr a,p,q) =
+ for t=0 upto length p-1: a[point t of p, point t of q]
+ ..controls a[postcontrol t of p, postcontrol t of q]
+ and a[precontrol t+1 of p, precontrol t+1 of q] .. endfor
+ if cycle p: cycle
+ else: a[point infinity of p, point infinity of q] fi enddef;
+
+vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false
+ tx_:=true_x; fx_:=false_x;
+ forever: x_:=.5[tx_,fx_]; exitif abs(tx_-fx_)<=tolerance;
+ if @#(x_): tx_ else: fx_ fi :=x_; endfor
+ x_ enddef; % now x_ is near where @# changes from true to false
+newinternal tolerance, tx_,fx_,x_; tolerance:=.01;
+
+vardef buildcycle(text ll) =
+ save ta_, tb_, k_, i_, pp_; path pp_[];
+ k_=0;
+ for q=ll: pp_[incr k_]=q; endfor
+ i_=k_;
+ for i=1 upto k_:
+ (ta_[i], length pp_[i_]-tb_[i_]) =
+ pp_[i] intersectiontimes reverse pp_[i_];
+ if ta_[i]<0:
+ errmessage("Paths "& decimal i &" and "& decimal i_ &" don't intersect");
+ fi
+ i_ := i;
+ endfor
+ for i=1 upto k_: subpath (ta_[i],tb_[i]) of pp_[i] .. endfor
+ cycle
+enddef;
+
+
+
+%% units of measure
+
+mm=2.83464; pt=0.99626; dd=1.06601; bp:=1;
+cm=28.34645; pc=11.95517; cc=12.79213; in:=72;
+
+vardef magstep primary m = mexp(46.67432m) enddef;
+
+
+
+%% macros for drawing and filling
+
+def drawoptions(text t) =
+ def _op_ = t enddef
+enddef;
+
+linejoin:=rounded; % parameters that effect drawing
+linecap:=rounded;
+miterlimit:=10;
+
+drawoptions();
+
+pen currentpen;
+picture currentpicture;
+
+def fill expr c = addto currentpicture contour c _op_ enddef;
+def draw expr p =
+ addto currentpicture
+ if picture p:
+ also p
+ else:
+ doublepath p withpen currentpen
+ fi
+ _op_
+enddef;
+def filldraw expr c =
+ addto currentpicture contour c withpen currentpen
+ _op_ enddef;
+% def drawdot expr z =
+% addto currentpicture contour makepath currentpen shifted z
+% _op_ enddef;
+
+def drawdot expr p =
+ if pair p :
+ addto currentpicture doublepath p withpen currentpen _op_
+ else :
+ errmessage("drawdot only accepts a pair expression")
+ fi
+enddef ;
+
+def unfill expr c = fill c withcolor background enddef;
+def undraw expr p = draw p withcolor background enddef;
+def unfilldraw expr c = filldraw c withcolor background enddef;
+def undrawdot expr z = drawdot z withcolor background enddef;
+def erase text t =
+ def _e_ = withcolor background hide(def _e_=enddef;) enddef;
+ t _e_
+enddef;
+def _e_= enddef;
+
+def cutdraw text t =
+ begingroup interim linecap:=butt; draw t _e_; endgroup enddef;
+
+vardef image(text t) =
+ save currentpicture;
+ picture currentpicture;
+ currentpicture := nullpicture;
+ t;
+ currentpicture
+enddef;
+
+def pickup secondary q =
+ if numeric q: numeric_pickup_ else: pen_pickup_ fi q enddef;
+def numeric_pickup_ primary q =
+ if unknown pen_[q]: errmessage "Unknown pen"; clearpen
+ else: currentpen:=pen_[q];
+ pen_lft:=pen_lft_[q];
+ pen_rt:=pen_rt_[q];
+ pen_top:=pen_top_[q];
+ pen_bot:=pen_bot_[q];
+ currentpen_path:=pen_path_[q] fi; enddef;
+def pen_pickup_ primary q =
+ currentpen:=q;
+ pen_lft:=xpart penoffset down of currentpen;
+ pen_rt:=xpart penoffset up of currentpen;
+ pen_top:=ypart penoffset left of currentpen;
+ pen_bot:=ypart penoffset right of currentpen;
+ path currentpen_path; enddef;
+newinternal pen_lft,pen_rt,pen_top,pen_bot,pen_count_;
+
+vardef savepen = pen_[incr pen_count_]=currentpen;
+ pen_lft_[pen_count_]=pen_lft;
+ pen_rt_[pen_count_]=pen_rt;
+ pen_top_[pen_count_]=pen_top;
+ pen_bot_[pen_count_]=pen_bot;
+ pen_path_[pen_count_]=currentpen_path;
+ pen_count_ enddef;
+
+def clearpen = currentpen:=nullpen;
+ pen_lft:=pen_rt:=pen_top:=pen_bot:=0;
+ path currentpen_path;
+ enddef;
+def clear_pen_memory =
+ pen_count_:=0;
+ numeric pen_lft_[],pen_rt_[],pen_top_[],pen_bot_[];
+ pen currentpen,pen_[];
+ path currentpen_path, pen_path_[];
+ enddef;
+
+vardef lft primary x = x + if pair x: (pen_lft,0) else: pen_lft fi enddef;
+vardef rt primary x = x + if pair x: (pen_rt,0) else: pen_rt fi enddef;
+vardef top primary y = y + if pair y: (0,pen_top) else: pen_top fi enddef;
+vardef bot primary y = y + if pair y: (0,pen_bot) else: pen_bot fi enddef;
+
+vardef penpos@#(expr b,d) =
+ (x@#r-x@#l,y@#r-y@#l)=(b,0) rotated d;
+ x@#=.5(x@#l+x@#r); y@#=.5(y@#l+y@#r) enddef;
+
+def penstroke text t =
+ forsuffixes e = l,r: path_.e:=t; endfor
+ fill path_.l -- reverse path_.r -- cycle enddef;
+path path_.l,path_.r;
+
+
+
+%% High level drawing commands
+
+newinternal ahlength, ahangle;
+ahlength := 4; % default arrowhead length 4bp
+ahangle := 45; % default head angle 45 degrees
+
+vardef arrowhead expr p =
+ save q,e; path q; pair e;
+ e = point length p of p;
+ q = gobble(p shifted -e cutafter makepath(pencircle scaled 2ahlength))
+ cuttings;
+ (q rotated .5ahangle & reverse q rotated -.5ahangle -- cycle) shifted e
+enddef;
+
+path _apth;
+def drawarrow expr p = _apth:=p; _finarr enddef;
+def drawdblarrow expr p = _apth:=p; _findarr enddef;
+
+def _finarr text t =
+ draw _apth t;
+ filldraw arrowhead _apth t
+enddef;
+
+def _findarr text t =
+ draw _apth t;
+ filldraw arrowhead _apth withpen currentpen t;
+ filldraw arrowhead reverse _apth withpen currentpen t
+enddef;
+
+
+
+%% macros for labels
+
+newinternal bboxmargin; bboxmargin:=2bp;
+
+vardef bbox primary p =
+ llcorner p-(bboxmargin,bboxmargin) -- lrcorner p+(bboxmargin,-bboxmargin)
+ -- urcorner p+(bboxmargin,bboxmargin) -- ulcorner p+(-bboxmargin,bboxmargin)
+ -- cycle
+enddef;
+
+string defaultfont;
+newinternal defaultscale, labeloffset;
+defaultfont = "cmr10";
+defaultscale := 1;
+labeloffset := 3bp;
+
+vardef thelabel@#(expr s,z) = % Position s near z
+ save p; picture p;
+ if picture s: p=s
+ else: p = s infont defaultfont scaled defaultscale
+ fi;
+ p shifted (z + labeloffset*laboff@# -
+ (labxf@#*lrcorner p + labyf@#*ulcorner p
+ + (1-labxf@#-labyf@#)*llcorner p
+ )
+ )
+enddef;
+
+def label = draw thelabel enddef;
+newinternal dotlabeldiam; dotlabeldiam:=3bp;
+vardef dotlabel@#(expr s,z) text t_ =
+ label@#(s,z) t_;
+ interim linecap:=rounded;
+ draw z withpen pencircle scaled dotlabeldiam t_;
+enddef;
+def makelabel = dotlabel enddef;
+
+pair laboff, laboff.lft, laboff.rt, laboff.top, laboff.bot;
+pair laboff.ulft, laboff.llft, laboff.urt, laboff.lrt;
+laboff =(0,0); labxf =.5; labyf =.5;
+laboff.lft=(-1,0); labxf.lft=1; labyf.lft=.5;
+laboff.rt =(1,0); labxf.rt =0; labyf.rt =.5;
+laboff.bot=(0,-1); labxf.bot=.5; labyf.bot=1;
+laboff.top=(0,1); labxf.top=.5; labyf.top=0;
+laboff.ulft=(-.7,.7);labxf.ulft=1; labyf.ulft=0;
+laboff.urt=(.7,.7); labxf.urt=0; labyf.urt=0;
+laboff.llft=-(.7,.7);labxf.llft=1; labyf.llft=1;
+laboff.lrt=(.7,-.7); labxf.lrt=0; labyf.lrt=1;
+
+vardef labels@#(text t) =
+ forsuffixes $=t:
+ label@#(str$,z$); endfor
+ enddef;
+vardef dotlabels@#(text t) =
+ forsuffixes $=t:
+ dotlabel@#(str$,z$); endfor
+ enddef;
+vardef penlabels@#(text t) =
+ forsuffixes $$=l,,r: forsuffixes $=t:
+ makelabel@#(str$.$$,z$.$$); endfor endfor
+ enddef;
+
+
+def range expr x = numtok[x] enddef;
+def numtok suffix x=x enddef;
+tertiarydef m thru n =
+ m for x=m+1 step 1 until n: , numtok[x] endfor enddef;
+
+
+
+%% Overall adminstration
+
+string extra_beginfig, extra_endfig;
+extra_beginfig = extra_endfig = "" ;
+
+def beginfig(expr c) =
+ begingroup
+ charcode:=c;
+ clearxy; clearit; clearpen;
+ pickup defaultpen;
+ drawoptions();
+ scantokens extra_beginfig;
+enddef;
+
+def endfig =
+ ; % added by HH
+ scantokens extra_endfig;
+ shipit ;
+ endgroup
+enddef;
+
+
+%% last-minute items
+
+vardef z@#=(x@#,y@#) enddef;
+
+def clearxy = save x,y enddef;
+def clearit = currentpicture:=nullpicture enddef;
+def shipit = shipout currentpicture enddef;
+
+let bye = end; outer end,bye;
+
+clear_pen_memory; % initialize the `savepen' mechanism
+clearit;
+
+newinternal defaultpen;
+pickup pencircle scaled .5bp; % set default line width
+defaultpen := savepen;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-butt.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-butt.mpii
new file mode 100644
index 00000000000..107886bb5c4
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-butt.mpii
@@ -0,0 +1,77 @@
+%D \module
+%D [ file=mp-butt.mpii,
+%D version=2000.05.31,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=buttons,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+if known context_butt : endinput ; fi ;
+
+boolean context_butt ; context_butt := true ;
+
+def predefinedbutton (expr button_type, button_size, button_linecolor, button_fillcolor) =
+
+ begingroup ;
+
+ save button_linewidth, p, d, l ;
+
+ numeric button_linewidth ; button_linewidth := button_size/10 ;
+
+ drawoptions (withpen pencircle scaled button_linewidth withcolor button_linecolor) ;
+
+ path p ; p := unitsquare scaled button_size ;
+ numeric d ; d := button_size ;
+ numeric l ; l := button_linewidth ;
+
+ fill p withcolor button_fillcolor ;
+ draw p ;
+
+ if button_type = 101 :
+ draw (d-2l,2l)--(2l,.5d)--(d-2l,d-2l)--cycle ;
+ elseif button_type = 102 :
+ draw (2l,2l)--(d-2l,.5d)--(2l,d-2l)--cycle ;
+ elseif button_type = 103 :
+ for i=2l step 2l until d-2l :
+ draw (2l,i)--(2l ,i) ;
+ draw (4l,i)--(d-2l,i) ;
+ endfor ;
+ elseif button_type = 104 :
+ for i=2l step 2l until d-2l :
+ draw (2l ,i)--(d/2-l,i) ;
+ draw (d/2+l,i)--(d-2l ,i) ;
+ endfor ;
+ elseif button_type = 105 :
+ fill fullcircle scaled (.2d) shifted (.5d,.7d) ;
+ fill fullcircle xscaled (.6d) yscaled d shifted (.5d,0) ;
+ clip currentpicture to p ;
+ draw p ;
+ elseif button_type = 106 :
+ draw (2l,2l)--(d-2l,d-2l) ;
+ draw (d-2l,2l)--(2l,d-2l) ;
+ elseif button_type = 107 :
+ p := (3l,d-2l)--(d-3l,d-2l)--(.5d,4l)--cycle ;
+ fill p ; draw p ;
+ draw (.5d,2l) ;
+ elseif button_type = 108 :
+ draw (.5d,2l)--(d-2l,d-2l)--(2l,d-2l)--cycle ;
+ elseif button_type = 109 :
+ draw (.5d,d-2l)--(d-2l,2l)--(2l,2l)--cycle ;
+ elseif button_type = 110 :
+ button_linewidth := button_linewidth/2 ;
+ draw p enlarged (-2l,-l) ;
+ for i=2l step l until d-2l :
+ draw (3l,i)--(d-3l,i) ;
+ endfor ;
+ fi ;
+
+ endgroup ;
+
+enddef ;
+
+let some_button = predefinedbutton
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-char.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-char.mpii
new file mode 100644
index 00000000000..63a71eff860
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-char.mpii
@@ -0,0 +1,1006 @@
+% to be cleaned up, namespace needed ! ! ! ! !
+
+%D \module
+%D [ file=mp-char.mpii,
+%D version=1998.10.10,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=charts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+if unknown context_shap : input "mp-shap.mpii" ; fi ;
+if known context_flow : endinput ; fi ;
+
+boolean context_char ; context_char := true ;
+
+% kan naar elders
+
+current_position := 0 ;
+
+def save_text_position (expr p) = % beware: clip shift needed
+ current_position := current_position + 1 ;
+ savedata
+ "\MPposition{" & decimal current_position & "}{"
+ & decimal xpart p & "}{"
+ & decimal ypart p & "}%" ;
+enddef ;
+
+%D settings
+
+grid_width := 60pt ; grid_height := 40pt ;
+shape_width := 45pt ; shape_height := 30pt ;
+
+chart_offset := 2pt ;
+color chart_background_color ; chart_background_color := white ;
+
+%D test mode
+
+boolean show_mid_points ; show_mid_points := false ;
+boolean show_con_points ; show_con_points := false ;
+boolean show_all_points ; show_all_points := false ;
+
+%D shapes
+
+color shape_line_color, shape_fill_color ;
+
+shape_line_width := 2pt ;
+shape_line_color := .5white ;
+shape_fill_color := .9white ;
+
+shape_node := 0 ;
+shape_action := 24 ;
+shape_procedure := 5 ;
+shape_product := 12 ;
+shape_decision := 14 ;
+shape_archive := 19 ;
+shape_loop := 35 ;
+shape_wait := 6 ;
+shape_subprocedure := 20 ; shape_sub_procedure := 20 ;
+shape_singledocument := 32 ; shape_single_document := 32 ;
+shape_multidocument := 33 ; shape_multi_document := 33 ;
+shape_right := 66 ;
+shape_left := 67 ;
+shape_up := 68 ;
+shape_down := 69 ;
+
+% vardef some_shape_path (expr type) == imported from mp-shap
+
+def show_shapes (expr n) =
+
+ begin_chart(n,8,10) ;
+ show_con_points := true ;
+ for i=0 upto 7 :
+ for j=0 upto 9 :
+ new_shape(i+1,j+1,i*10+j);
+ endfor ;
+ endfor ;
+ end_chart ;
+
+enddef ;
+
+%D connections
+
+def new_chart =
+
+ color connection_line_color ;
+
+ connection_line_width := shape_line_width ;
+ connection_line_color := .8white ;
+ connection_smooth_size := 5pt ;
+ connection_arrow_size := 4pt ;
+ connection_dash_size := 3pt ;
+
+ max_x := 6 ;
+ max_y := 4 ;
+
+ numeric xypoint ; xypoint := 0 ;
+
+ pair xypoints [] ;
+
+ boolean xyfree [][] ;
+ path xypath [][] ;
+ numeric xysx [][] ;
+ numeric xysy [][] ;
+ color xyfill [][] ;
+ color xydraw [][] ;
+ numeric xyline [][] ;
+ boolean xypeep [][] ;
+ picture xypicture[][] ;
+
+ numeric cpath ; cpath := 0 ;
+ path cpaths [] ;
+ numeric cline [] ;
+ color ccolor [] ;
+ boolean carrow [] ;
+ boolean cdash [] ;
+ boolean ccross [] ;
+
+ boolean smooth ; smooth := true ;
+ boolean peepshape ; peepshape := false ;
+ boolean arrowtip ; arrowtip := true ;
+ boolean dashline ; dashline := false ;
+ boolean forcevalid ; forcevalid := false ;
+ boolean touchshape ; touchshape := false ;
+ boolean showcrossing ; showcrossing := false ;
+
+ picture dash_pattern ;
+
+ boolean reverse_y ; reverse_y := true ;
+
+enddef ;
+
+new_chart ;
+
+def y_pos (expr y) =
+ if reverse_y : max_y + 1 - y else : y fi
+enddef ;
+
+def initialize_grid (expr maxx, maxy) =
+ begingroup ;
+ save i, j ;
+ max_x := maxx ;
+ max_y := maxy ;
+ dsp_x := 0 ;
+ dsp_y := 0 ;
+ for x=1 upto max_x :
+ for y=1 upto max_y :
+ xyfree [x][y] := true ;
+ xyfill [x][y] := shape_fill_color ;
+ xydraw [x][y] := shape_line_color ;
+ xyline [x][y] := shape_line_width ;
+ endfor ;
+ endfor ;
+ endgroup ;
+enddef ;
+
+def scaled_to_grid =
+ xscaled grid_width yscaled grid_height
+enddef ;
+
+def xy_offset (expr x, y) =
+ (x+.5,y+.5)
+enddef ;
+
+def draw_shape (expr x, yy, p, sx, sy) =
+ begingroup ;
+ save y ;
+ y := y_pos(yy) ;
+ xypath [x][y] := (p xscaled sx yscaled sy) shifted xy_offset(x,y) ;
+ xyfree [x][y] := false ;
+ xysx [x][y] := sx ;
+ xysy [x][y] := sy ;
+ xyfill [x][y] := shape_fill_color ;
+ xydraw [x][y] := shape_line_color ;
+ xyline [x][y] := shape_line_width ;
+ xypeep [x][y] := peepshape ;
+ endgroup ;
+enddef ;
+
+vardef i_point (expr x, y, p, t) =
+ begingroup ;
+ save q, ok ;
+ pair q ;
+ boolean ok ;
+ q := xypath[x][y] intersection_point ((p) shifted xy_offset(x,y)) ;
+ ok := true ;
+% if xpart q < -.5 : ok := false ; q := (-.45,ypart q) fi ;
+% if xpart q > .5 : ok := false ; q := ( .45,ypart q) fi ;
+% if ypart q < -.5 : ok := false ; q := (xpart q,-.45) fi ;
+% if ypart q > .5 : ok := false ; q := (xpart q, .45) fi ;
+ if not ok :
+ message (t & " of shape (" & decimal x & "," & decimal y & ") limited") ;
+ fi ;
+ q
+ endgroup
+enddef ;
+
+vardef trimmed (expr x, y, z, t) =
+ if touchshape and t : xyline[x][y]/z else : epsilon fi
+enddef ;
+
+zfactor := 1/3 ;
+
+vardef xy_bottom (expr x, y, z, t) =
+ i_point (x, y, ((0,0)--(0,-2)) shifted (zfactor*z*xysx[x][y],0), "bottom")
+ shifted(0,-trimmed(x,y,grid_height,t))
+enddef ;
+
+vardef xy_top (expr x, y, z, t) =
+ i_point (x, y, ((0,0)--(0,2)) shifted (zfactor*z*xysx[x][y],0), "top")
+ shifted(0,trimmed(x,y,grid_height,t))
+enddef ;
+
+vardef xy_left (expr x, y, z, t) =
+ i_point (x, y, ((0,0)--(-2,0)) shifted (0,zfactor*z*xysy[x][y]), "left")
+ shifted(-trimmed(x,y,grid_width,t),0)
+enddef ;
+
+vardef xy_right (expr x, y, z, t) =
+ i_point (x, y, ((0,0)--(2,0)) shifted (0,zfactor*z*xysy[x][y]), "right")
+ shifted(trimmed(x,y,grid_width,t),0)
+enddef ;
+
+def flush_shapes =
+ for x=1 upto max_x :
+ for y=1 upto max_y :
+ flush_shape (x, y) ;
+ endfor ;
+ endfor ;
+enddef ;
+
+def flush_pictures =
+ for x=1 upto max_x :
+ for y=1 upto max_y :
+ flush_picture (x, y) ;
+ endfor ;
+ endfor ;
+enddef ;
+
+
+def draw_connection_point (expr x, y, z) =
+ pickup pencircle scaled if (z=0): 2 fi xyline[x][y] ;
+ drawdot xy_bottom(x,y,z,false) scaled_to_grid withcolor (1,0,0) ;
+ drawdot xy_top (x,y,z,false) scaled_to_grid withcolor (0,1,0) ;
+ drawdot xy_left (x,y,z,false) scaled_to_grid withcolor (0,0,1) ;
+ drawdot xy_right (x,y,z,false) scaled_to_grid withcolor (1,1,0) ;
+enddef ;
+
+def flush_shape (expr x, yy) =
+ begingroup ;
+ save y ;
+ y := y_pos(yy) ;
+ if not xyfree[x][y] :
+ pickup pencircle scaled xyline[x][y] ;
+ if xypeep[x][y] :
+ fill (xypath[x][y] peepholed (unitsquare shifted (x,y)))
+ scaled_to_grid withpen pencircle scaled 0
+ withcolor chart_background_color ;
+ else :
+ fill xypath[x][y] scaled_to_grid withcolor xyfill[x][y] ;
+ fi ;
+ draw xypath[x][y] scaled_to_grid withcolor xydraw[x][y] ;
+ if show_con_points or show_all_points :
+ draw_connection_point (x, y, 0) ;
+ fi ;
+ if show_all_points :
+ for i=-1 upto 1 :
+ draw_connection_point (x, y, i) ;
+ endfor ;
+ fi ;
+ fi ;
+ endgroup ;
+enddef ;
+
+vardef points_initialized (expr xfrom, yfrom, xto, yto, n) =
+ if not xyfree[xfrom][yfrom] and not xyfree[xto][yto] :
+ xypoint := n ; true
+ else :
+ xypoint := 0 ; false
+ fi
+enddef ;
+
+def collapse_points =
+ % remove redundant points
+ n := 1 ;
+ for i=2 upto xypoint:
+ if not (xypoints[i]=xypoints[n]) :
+ n := n + 1 ;
+ xypoints[n] := xypoints[i]
+ fi ;
+ endfor ;
+ xypoint := n ;
+ % make straight lines
+ if xypoints[2]=xypoints[xypoint-1] :
+ xypoints[3] := xypoints[xypoint] ;
+ xypoint := 3 ;
+ fi ;
+enddef ;
+
+vardef smooth_connection (expr a,b) =
+ sx := connection_smooth_size/grid_width ;
+ sy := connection_smooth_size/grid_height ;
+ if ypart a = ypart b :
+ a shifted (if xpart a >= xpart b : - fi sx,0)
+% a shifted (sx*xpart unitvector(b-a),0)
+ else :
+ a shifted (0,if ypart a >= ypart b : - fi sy)
+% a shifted (0,sy*ypart unitvector(b-a))
+ fi
+enddef ;
+
+vardef trim_points =
+ begingroup
+ save p, a, b, d, i ; path p ; pair d ;
+ p := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ;
+ if touchshape :
+ a := shape_line_width/grid_width ;
+ b := shape_line_width/grid_height ;
+ else :
+ a := epsilon ;
+ b := epsilon ;
+ fi ;
+ d := direction infinity of p ;
+ xypoints[xypoint] := xypoints[xypoint] shifted
+ if xpart d < 0 : (+a,0) ;
+ elseif xpart d > 0 : (-a,0) ;
+ elseif ypart d < 0 : (0,+b) ;
+ elseif ypart d > 0 : (0,-b) ;
+ else : origin ;
+ fi ;
+ d := direction 0 of p ;
+ xypoints[1] := xypoints[1] shifted
+ if xpart d < 0 : (-a,0) ;
+ elseif xpart d > 0 : (+a,0) ;
+ elseif ypart d < 0 : (0,-b) ;
+ elseif ypart d > 0 : (0,+b) ;
+ else : origin ;
+ fi ;
+ endgroup
+enddef ;
+
+vardef trim_points = enddef ;
+
+vardef connection_path =
+ if reverse_connection : reverse fi (xypoints[1]--
+ for i=2 upto xypoint-1 :
+ if smooth :
+ smooth_connection(xypoints[i],xypoints[i-1]) ..
+ controls xypoints[i] and xypoints[i] ..
+ smooth_connection(xypoints[i],xypoints[i+1]) --
+ else :
+ xypoints[i]--
+ fi
+ endfor
+ xypoints[xypoint])
+enddef ;
+
+% vardef connection_path =
+% sx := connection_smooth_size/grid_width ;
+% sy := connection_smooth_size/grid_height ;
+% if reverse_connection : reverse fi
+% (for i=1 upto xypoint-1 : xypoints[i] -- endfor xypoints[xypoint])
+% if smooth : cornered max(sx,sy) fi
+% enddef ;
+%
+% primarydef p cornered c =
+% if cycle p :
+% ((point 0 of p) shifted (c*(unitvector(point 1 of p - point 0 of p))) --
+% for i=1 upto length(p) :
+% (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) --
+% (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) ..
+% controls point i of p ..
+% endfor cycle)
+% else :
+% ((point 0 of p) --
+% for i=1 upto length(p)-1 :
+% (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) --
+% (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) ..
+% controls point i of p ..
+% endfor
+% (point length(p) of p))
+% fi
+% enddef ;
+
+def draw_connection =
+ if xypoint>0 :
+ collapse_points ;
+ trim_points ;
+ cpath := cpath + 1 ;
+ cpaths[cpath] := connection_path scaled_to_grid ;
+ cline[cpath] := connection_line_width ;
+ ccolor[cpath] := connection_line_color ;
+ carrow[cpath] := arrowtip ;
+ cdash[cpath] := dashline ;
+ ccross[cpath] := showcrossing ;
+ else :
+ message("no connection defined") ;
+ fi ;
+ reverse_connection := false ;
+enddef ;
+
+def flush_connections =
+ pair ip ;
+ boolean crossing ;
+ ahlength := connection_arrow_size ;
+ dash_pattern := dashpattern(on connection_dash_size off connection_dash_size ) ;
+ for i=1 upto cpath :
+ if ccross[i] :
+ crossing := false ;
+ for j=1 upto i :
+ %if not ((point infinity of cpaths[i] = point infinity of cpaths[j]) or
+ % (point 0 of cpaths[i] = point 0 of cpaths[j])) :
+ if not (point infinity of cpaths[i] = point infinity of cpaths[j]) :
+ ip := cpaths[i] intersection_point cpaths[j] ;
+ if intersection_found : crossing := true fi ;
+ fi ;
+ endfor ;
+ if crossing :
+ pickup pencircle scaled 2cline[i] ;
+ %draw cpaths[i] withcolor chart_background_color ;
+ path cp ; cp := cpaths[i] ;
+ cp := cp cutbefore point .05 length cp of cp ;
+ cp := cp cutafter point .95 length cp of cp ;
+ draw cp withcolor chart_background_color ;
+ fi ;
+ fi ;
+ pickup pencircle scaled cline[i] ;
+ if carrow[i] :
+ if cdash[i] :
+ drawarrow cpaths[i] withcolor ccolor[i] dashed dash_pattern ;
+ else :
+ drawarrow cpaths[i] withcolor ccolor[i] ;
+ fi ;
+ else :
+ if cdash[i] :
+ draw cpaths[i] withcolor ccolor[i] dashed dash_pattern ;
+ else :
+ draw cpaths[i] withcolor ccolor[i] ;
+ fi ;
+ fi ;
+ draw_midpoint (i) ;
+ endfor ;
+enddef ;
+
+def draw_midpoint (expr n) =
+ begingroup
+ save p ;
+ pair p ;
+ p := point .5*length(cpaths[n]) of cpaths[n];
+ pickup pencircle scaled 2cline[n] ;
+ save_text_position (p) ;
+ if show_mid_points :
+ drawdot p withcolor .7white ;
+ fi ;
+ endgroup ;
+enddef ;
+
+def flush_picture(expr x, y) =
+ if known xypicture[x][y]:
+ draw xypicture[x][y] shifted xy_offset((x+0.5)*grid_width,(max_y-y+1.5)*grid_height) ;
+ fi ;
+enddef ;
+
+def chart_draw_picture(expr x, y, p) =
+ xypicture[x][y] := p ;
+enddef ;
+
+boolean reverse_connection ; reverse_connection := false ;
+
+vardef up_on_grid (expr n) =
+ (xpart xypoints[n],(ypart xypoints[n]+1) div 1)
+enddef ;
+
+vardef down_on_grid (expr n) =
+ (xpart xypoints[n],(ypart xypoints[n]) div 1)
+enddef ;
+
+vardef left_on_grid (expr n) =
+ ((xpart xypoints[n]) div 1, ypart xypoints[n])
+enddef ;
+
+vardef right_on_grid (expr n) =
+ ((xpart xypoints[n]+1) div 1, ypart xypoints[n])
+enddef ;
+
+vardef x_on_grid (expr n, xfrom, xto, zfrom) =
+ if (xfrom=xto) and not (zfrom=0) :
+ if (zfrom=1) : right_on_grid(2) else : left_on_grid(2) fi
+ elseif xpart xypoints[1] < xpart xypoints[6] :
+ right_on_grid(n)
+ else :
+ left_on_grid(n)
+ fi
+enddef ;
+
+vardef y_on_grid (expr n, yfrom, yto, zfrom) =
+ if (yfrom=yto) and not (zfrom=0) :
+ if (zfrom=1) : up_on_grid(2) else : down_on_grid(2) fi
+ elseif ypart xypoints[1] < ypart xypoints[6] :
+ up_on_grid(n)
+ else :
+ down_on_grid(n)
+ fi
+enddef ;
+
+vardef xy_on_grid (expr n, m) =
+ (xpart xypoints[n], ypart xypoints[m])
+enddef ;
+
+vardef down_to_grid (expr a,b) =
+ (xpart xypoints[a],
+ ypart xypoints[if ypart xypoints[a]<ypart xypoints[b]:a else:b fi])
+enddef ;
+
+vardef up_to_grid (expr a,b) =
+ (xpart xypoints[a],
+ ypart xypoints[if ypart xypoints[a]>ypart xypoints[b]:a else:b fi])
+enddef ;
+
+vardef left_to_grid (expr a,b) =
+ (xpart xypoints[if xpart xypoints[a]<xpart xypoints[b]:a else:b fi],
+ ypart xypoints[a])
+enddef ;
+
+vardef right_to_grid (expr a,b) =
+ (xpart xypoints[if xpart xypoints[a]>xpart xypoints[b]:a else:b fi],
+ ypart xypoints[a])
+enddef ;
+
+% vardef boundingboxfraction(expr p, f) =
+% ((boundingbox p) enlarged (-f*bbwidth(p),-f*bbheight(p)))
+% enddef ;
+
+vardef valid_connection (expr xfrom, yfrom, xto, yto) =
+ begingroup ;
+ save ok, vc, pp ;
+ boolean ok ;
+ % check for slanted lines
+ ok := true ;
+ for i=1 upto xypoint-1 :
+ if not ((xpart xypoints[i]=xpart xypoints[i+1]) or
+ (ypart xypoints[i]=ypart xypoints[i+1])) : ok := false ;
+ fi ;
+ endfor ;
+ if not ok :
+ %message("slanted");
+ false
+ elseif forcevalid :
+ %message("force");
+ true
+ elseif (xfrom=xto) and (yfrom=yto) :
+ %message("self");
+ false
+ else :
+ % check for crossing shapes
+ pair vc ;
+ path pp ;
+
+ pair xyfirst, xylast ;
+ xyfirst := xypoints[1] ;
+ xylast := xypoints[xypoint] ;
+ trim_points ;
+ pp := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ;
+ xypoints[1] := xyfirst ;
+ xypoints[xypoint] := xylast ;
+
+ for i=1 upto max_x :
+ for j=1 upto max_y : % was bug: xfrom,yto
+ if not ( ( (i,j)=(xfrom,yfrom) ) or ( (i,j)=(xto,yto) ) ) :
+ if not xyfree[i][j] :
+ vc := pp intersection_point xypath[i][j] ;
+ if intersection_found : ok := false fi ;
+ fi ;
+ fi ;
+ endfor ;
+ endfor ;
+ %if not ok: message("crossing") ; fi ;
+ ok
+ fi
+ endgroup
+enddef ;
+
+def connect_top_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,6) :
+ xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ;
+ xypoints[6] := xy_bottom(xto,yto,zto,true) ;
+ xypoints[2] := up_on_grid(1) ;
+ xypoints[5] := down_on_grid(6) ;
+ xypoints[3] := up_to_grid(2,5) ;
+ xypoints[4] := up_to_grid(2,5) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ;
+ xypoints[4] := xy_on_grid(3,5) ;
+ fi ;
+ %%%% begin experiment
+ xypoints[3] := xypoints[3] shifted (dsp_x,0) ;
+ xypoints[4] := xypoints[4] shifted (dsp_x,0) ;
+ if dsp_y>0 :
+ xypoints[2] := xypoints[2] shifted (0,dsp_y) ;
+ xypoints[3] := xypoints[3] shifted (0,dsp_y) ;
+ elseif dsp_y<0 :
+ xypoints[4] := xypoints[4] shifted (0,dsp_y) ;
+ xypoints[5] := xypoints[5] shifted (0,dsp_y) ;
+ fi
+ %%%% end experiment
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_left_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,6) :
+ xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ;
+ xypoints[6] := xy_right(xto,yto,zto,true) ;
+ xypoints[2] := left_on_grid(1) ;
+ xypoints[5] := right_on_grid(6) ;
+ xypoints[3] := left_to_grid(2,5) ;
+ xypoints[4] := left_to_grid(2,5) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ;
+ xypoints[4] := xy_on_grid(5,3) ;
+ fi ;
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_left_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,5) :
+ xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ;
+ xypoints[5] := xy_top(xto,yto,zto,true) ;
+ xypoints[2] := left_on_grid(1) ;
+ xypoints[4] := up_on_grid(5) ;
+ xypoints[3] := left_to_grid(2,5) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := xy_on_grid(2,4) ;
+ fi ;
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_left_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,5) :
+ xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ;
+ xypoints[5] := xy_bottom(xto,yto,zto,true) ;
+ xypoints[2] := left_on_grid(1) ;
+ xypoints[4] := down_on_grid(5) ;
+ xypoints[3] := left_to_grid(2,5) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := xy_on_grid(2,4) ;
+ fi ;
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_right_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,5) :
+ xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ;
+ xypoints[5] := xy_top(xto,yto,zto,true) ;
+ xypoints[2] := right_on_grid(1) ;
+ xypoints[4] := up_on_grid(5) ;
+ xypoints[3] := right_to_grid(2,5) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := xy_on_grid(2,4) ;
+ fi ;
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_right_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,5) :
+ xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ;
+ xypoints[5] := xy_bottom(xto,yto,zto,true) ;
+ xypoints[2] := right_on_grid(1) ;
+ xypoints[4] := down_on_grid(5) ;
+ xypoints[3] := right_to_grid(2,5) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := xy_on_grid(2,4) ;
+ fi ;
+ %%%% begin experiment
+ xypoints[2] := xypoints[2] shifted (dsp_x,0) ;
+ xypoints[3] := xypoints[3] shifted (dsp_x,0) ;
+ if dsp_y>0 :
+ xypoints[3] := xypoints[3] shifted (0,-dsp_y) ;
+ xypoints[4] := xypoints[4] shifted (0,-dsp_y) ;
+ elseif dsp_y<0 :
+ xypoints[3] := xypoints[3] shifted (0,dsp_y) ;
+ xypoints[4] := xypoints[4] shifted (0,dsp_y) ;
+ fi
+ %%%% end experiment
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_left_left (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,6) :
+ xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ;
+ xypoints[6] := xy_left(xto,yto,zto,true) ;
+ xypoints[2] := left_on_grid(1) ;
+ xypoints[5] := left_on_grid(6) ;
+ xypoints[3] := left_to_grid(2,5) ;
+ xypoints[4] := left_to_grid(5,2) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ;
+ xypoints[4] := xy_on_grid(5,3) ;
+ fi ;
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_right_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,6) :
+ xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ;
+ xypoints[6] := xy_right(xto,yto,zto,true) ;
+ xypoints[2] := right_on_grid(1) ;
+ xypoints[5] := right_on_grid(6) ;
+ xypoints[3] := right_to_grid(2,5) ;
+ xypoints[4] := right_to_grid(5,2) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ;
+ xypoints[4] := xy_on_grid(5,3) ;
+ fi ;
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_top_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,6) :
+ xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ;
+ xypoints[6] := xy_top(xto,yto,zto,true) ;
+ xypoints[2] := up_on_grid(1) ;
+ xypoints[5] := up_on_grid(6) ;
+ xypoints[3] := up_to_grid(2,5) ;
+ xypoints[4] := up_to_grid(5,2) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ;
+ xypoints[4] := xy_on_grid(3,5) ;
+ fi ;
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_bottom_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) =
+ yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ;
+ if points_initialized(xfrom,yfrom,xto,yto,6) :
+ xypoints[1] := xy_bottom(xfrom,yfrom,zfrom,true) ;
+ xypoints[6] := xy_bottom(xto,yto,zto,true) ;
+ xypoints[2] := down_on_grid(1) ;
+ xypoints[5] := down_on_grid(6) ;
+ xypoints[3] := down_to_grid(2,5) ;
+ xypoints[4] := down_to_grid(5,2) ;
+ if not valid_connection(xfrom,yfrom,xto,yto) :
+ xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ;
+ xypoints[4] := xy_on_grid(3,5) ;
+ fi ;
+ %%%% begin experiment
+ xypoints[3] := xypoints[3] shifted (dsp_x,0) ;
+ xypoints[4] := xypoints[4] shifted (dsp_x,0) ;
+ if dsp_y<0 :
+ xypoints[2] := xypoints[2] shifted (0,-dsp_y) ;
+ xypoints[3] := xypoints[3] shifted (0,-dsp_y) ;
+ elseif dsp_y>0 :
+ xypoints[4] := xypoints[4] shifted (0,dsp_y) ;
+ xypoints[5] := xypoints[5] shifted (0,dsp_y) ;
+ fi
+ %%%% end experiment
+ draw_connection ;
+ fi ;
+enddef ;
+
+def connect_bottom_top (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) =
+ reverse_connection := true ;
+ connect_top_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ;
+enddef ;
+
+def connect_right_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) =
+ reverse_connection := true ;
+ connect_left_right (xto,yto,zto) (xfrom,yfrom,zfrom) ;
+enddef ;
+
+def connect_top_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) =
+ reverse_connection := true ;
+ connect_left_top (xto,yto,zto) (xfrom,yfrom,zfrom) ;
+enddef ;
+
+def connect_bottom_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) =
+ reverse_connection := true ;
+ connect_left_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ;
+enddef ;
+
+def connect_top_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) =
+ reverse_connection := true ;
+ connect_right_top (xto,yto,zto) (xfrom,yfrom,zfrom) ;
+enddef ;
+
+def connect_bottom_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) =
+ reverse_connection := true ;
+ connect_right_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ;
+enddef ;
+
+def draw_test_shape (expr x, y) =
+ draw_shape(x,y,fullcircle, .7, .7) ;
+enddef ;
+
+def draw_test_shapes =
+ for i=1 upto max_x :
+ for j=1 upto max_y :
+ draw_test_shape(i,j) ;
+ endfor ;
+ endfor ;
+enddef;
+
+def draw_test_area =
+ pickup pencircle scaled .5shape_line_width ;
+ draw (unitsquare xscaled max_x yscaled max_y shifted (1,1))
+ scaled_to_grid withcolor blue ;
+enddef ;
+
+def show_connection (expr n, m) =
+
+ begin_chart(100+n,6,6) ;
+
+ draw_test_area ;
+
+ smooth := true ;
+ arrowtip := true ;
+ dashline := true ;
+
+ draw_test_shape(2,2) ; draw_test_shape(4,5) ;
+ draw_test_shape(3,3) ; draw_test_shape(5,1) ;
+ draw_test_shape(2,5) ; draw_test_shape(1,3) ;
+ draw_test_shape(6,2) ; draw_test_shape(4,6) ;
+
+ if (m=1) :
+ connect_top_bottom (2,2,0) (4,5,0) ;
+ connect_top_bottom (3,3,0) (5,1,0) ;
+ connect_top_bottom (2,5,0) (1,3,0) ;
+ connect_top_bottom (6,2,0) (4,6,0) ;
+ elseif (m=2) :
+ connect_top_top (2,2,0) (4,5,0) ;
+ connect_top_top (3,3,0) (5,1,0) ;
+ connect_top_top (2,5,0) (1,3,0) ;
+ connect_top_top (6,2,0) (4,6,0) ;
+ elseif (m=3) :
+ connect_bottom_bottom (2,2,0) (4,5,0) ;
+ connect_bottom_bottom (3,3,0) (5,1,0) ;
+ connect_bottom_bottom (2,5,0) (1,3,0) ;
+ connect_bottom_bottom (6,2,0) (4,6,0) ;
+ elseif (m=4) :
+ connect_left_right (2,2,0) (4,5,0) ;
+ connect_left_right (3,3,0) (5,1,0) ;
+ connect_left_right (2,5,0) (1,3,0) ;
+ connect_left_right (6,2,0) (4,6,0) ;
+ elseif (m=5) :
+ connect_left_left (2,2,0) (4,5,0) ;
+ connect_left_left (3,3,0) (5,1,0) ;
+ connect_left_left (2,5,0) (1,3,0) ;
+ connect_left_left (6,2,0) (4,6,0) ;
+ elseif (m=6) :
+ connect_right_right (2,2,0) (4,5,0) ;
+ connect_right_right (3,3,0) (5,1,0) ;
+ connect_right_right (2,5,0) (1,3,0) ;
+ connect_right_right (6,2,0) (4,6,0) ;
+ elseif (m=7) :
+ connect_left_top (2,2,0) (4,5,0) ;
+ connect_left_top (3,3,0) (5,1,0) ;
+ connect_left_top (2,5,0) (1,3,0) ;
+ connect_left_top (6,2,0) (4,6,0) ;
+ elseif (m=8) :
+ connect_left_bottom (2,2,0) (4,5,0) ;
+ connect_left_bottom (3,3,0) (5,1,0) ;
+ connect_left_bottom (2,5,0) (1,3,0) ;
+ connect_left_bottom (6,2,0) (4,6,0) ;
+ elseif (m=9) :
+ connect_right_top (2,2,0) (4,5,0) ;
+ connect_right_top (3,3,0) (5,1,0) ;
+ connect_right_top (2,5,0) (1,3,0) ;
+ connect_right_top (6,2,0) (4,6,0) ;
+ else :
+ connect_right_bottom (2,2,0) (4,5,0) ;
+ connect_right_bottom (3,3,0) (5,1,0) ;
+ connect_right_bottom (2,5,0) (1,3,0) ;
+ connect_right_bottom (6,2,0) (4,6,0) ;
+ fi ;
+
+ end_chart ;
+
+enddef ;
+
+def show_connections =
+ for f=1 upto 10 :
+ show_connection(f,f) ;
+ endfor ;
+enddef ;
+
+%D charts
+
+def clip_chart (expr minx, miny, maxx, maxy) =
+ cmin_x := minx ;
+ cmax_x := maxx ;
+ cmin_y := miny ;
+ cmax_y := maxy ;
+enddef ;
+
+def begin_chart (expr n, maxx, maxy) =
+ new_chart ;
+ chart_figure := n ;
+ chart_scale := 1 ;
+ if chart_figure>0: beginfig(chart_figure) ; fi ;
+ startsavingdata ;
+ initialize_grid (maxx, maxy) ;
+ bboxmargin := 0 ;
+ cmin_x := 1 ;
+ cmax_x := maxx ;
+ cmin_y := 1 ;
+ cmax_y := maxy ;
+enddef ;
+
+def end_chart =
+ flush_shapes ;
+ flush_connections ;
+ flush_pictures ;
+ cmin_x := cmin_x ;
+ cmax_x := cmin_x+cmax_x ;
+ cmin_y := cmin_y-1 ;
+ cmax_y := cmin_y+cmax_y ;
+ if reverse_y :
+ cmin_y := y_pos(cmin_y) ;
+ cmax_y := y_pos(cmax_y) ;
+ fi ;
+ path p ;
+ p := (((cmin_x,cmin_y)--(cmax_x,cmin_y)--
+ (cmax_x,cmax_y)--(cmin_x,cmax_y)--cycle))
+ scaled_to_grid ;
+ %draw p withcolor red ;
+ p := p enlarged chart_offset ;
+ clip currentpicture to p ;
+ setbounds currentpicture to p ;
+ savedata
+ "\MPclippath{" &
+ decimal xpart llcorner p & "}{" &
+ decimal ypart llcorner p & "}{" &
+ decimal xpart urcorner p & "}{" &
+ decimal ypart urcorner p & "}%" ;
+ savedata
+ "\MPareapath{" &
+ decimal (xpart llcorner p + 2chart_offset) & "}{" &
+ decimal (ypart llcorner p + 2chart_offset) & "}{" &
+ decimal (xpart urcorner p - 2chart_offset) & "}{" &
+ decimal (ypart urcorner p - 2chart_offset) & "}%" ;
+ currentpicture := currentpicture scaled chart_scale ;
+ stopsavingdata ;
+ if chart_figure>0: endfig ; fi ;
+enddef ;
+
+def new_shape (expr x, y, n) =
+ if known n :
+ if (x>0) and (x<=max_x) and (y>0) and (y<=max_y) :
+ sx := shape_width/grid_width ;
+ sy := shape_height/grid_height ;
+ draw_shape(x,y,some_shape_path(n), sx, sy) ;
+ else :
+ message ("shape outside grid ignored") ;
+ fi ;
+ else
+ message ("shape not known" ) ;
+ fi ;
+enddef ;
+
+def begin_sub_chart =
+ begingroup ;
+ save shape_line_width , connection_line_width ;
+ save shape_line_color, shape_fill_color, connection_line_color ;
+ color shape_line_color, shape_fill_color, connection_line_color ;
+ save smooth, arrowtip, dashline, peepshape ;
+ boolean smooth, arrowtip, dashline, peepshape ;
+enddef ;
+
+def end_sub_chart =
+ endgroup ;
+enddef ;
+
+% show_shapes(100) ;
+%
+% show_connections ;
+%
+% begin_chart (1,4,5) ;
+% %clip_chart(1,1,1,2) ;
+% new_shape (1,1,31) ;
+% new_shape (1,2,3) ;
+% new_shape (4,4,5) ;
+% connect_top_left (1,1,0) (4,4,0) ;
+% connect_bottom_top (1,2,0) (4,4,0) ;
+% connect_left_right (1,2,0) (1,1,0) ;
+% end_chart ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-core.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-core.mpii
new file mode 100644
index 00000000000..79b5d2ab7a3
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-core.mpii
@@ -0,0 +1,1418 @@
+if known context_core : endinput ; fi ;
+
+boolean context_core ; context_core := true ;
+
+pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ;
+path pxy[] ;
+numeric hxy[], wxy[], dxy[], nxy[] ;
+
+def box_found (expr n,x,y,w,h,d) =
+ not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0))
+enddef ;
+
+def initialize_box_pos (expr pos,n,x,y,w,h,d) =
+ pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ;
+ path pxy ; numeric hxy, wxy, dxy, nxy;
+ lxy := (x,y) ;
+ llxy := (x,y-d) ;
+ lrxy := (x+w,y-d) ;
+ urxy := (x+w,y+h) ;
+ ulxy := (x,y+h) ;
+ wxy := w ;
+ hxy := h ;
+ dxy := d ;
+ rxy := lxy shifted (wxy,0) ;
+ pxy := llxy--lrxy--urxy--ulxy--cycle ;
+ cxy := center pxy ;
+ nxy := n ;
+ freeze_box(pos) ;
+enddef ;
+
+def freeze_box (expr pos) =
+ lxy[pos] := lxy ;
+ llxy[pos] := llxy ;
+ lrxy[pos] := lrxy ;
+ urxy[pos] := urxy ;
+ ulxy[pos] := ulxy ;
+ wxy[pos] := wxy ;
+ hxy[pos] := hxy ;
+ dxy[pos] := dxy ;
+ rxy[pos] := rxy ;
+ pxy[pos] := pxy ;
+ cxy[pos] := cxy ;
+ nxy[pos] := nxy ;
+enddef ;
+
+def initialize_box (expr n,x,y,w,h,d) =
+
+ numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ;
+
+enddef ;
+
+def initialize_area (expr fn,fx,fy,fw,fh,fd,
+ tn,tx,ty,tw,th,td) =
+
+ numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ;
+ numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ;
+
+ do_initialize_area (fpos, tpos) ;
+
+enddef ;
+
+def do_initialize_area (expr fpos, tpos) =
+ lxy := lxy[fpos] ;
+ llxy := (xpart llxy[fpos], ypart llxy[tpos]) ;
+ lrxy := lrxy[tpos] ;
+ urxy := (xpart urxy[tpos], ypart urxy[fpos]) ;
+ ulxy := ulxy[fpos] ;
+ wxy := xpart lrxy - xpart llxy ;
+ hxy := hxy[fpos] ;
+ dxy := dxy[tpos] ;
+ rxy := lxy shifted (wxy,0) ;
+ pxy := llxy--lrxy--urxy--ulxy--cycle ;
+ cxy := center pxy ;
+enddef ;
+
+def set_par_line_height (expr ph, pd) =
+ par_strut_height :=
+ if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ;
+ par_strut_depth :=
+ if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ;
+ par_line_height :=
+ par_strut_height + par_strut_depth ;
+enddef ;
+
+def initialize_par (expr fn,fx,fy,fw,fh,fd,
+ tn,tx,ty,tw,th,td,
+ mn,mx,my,mw,mh,md,
+ pn,px,py,pw,ph,pd,
+ rw,rl,rr,rh,ra,ri) =
+
+ numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ;
+ numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ;
+ numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ;
+ numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ;
+
+ numeric par_strut_height, par_strut_depth, par_line_height ;
+
+ set_par_line_height (ph, pd) ;
+
+ do_initialize_area (fpos, tpos) ;
+ do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ;
+
+enddef ;
+
+def initialize_area_par (expr fn,fx,fy,fw,fh,fd,
+ tn,tx,ty,tw,th,td,
+ wn,wx,wy,ww,wh,wd) =
+
+ numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ;
+ numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ;
+ numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ;
+
+ numeric par_strut_height, par_strut_depth, par_line_height ;
+
+ set_par_line_height (wh, wd) ;
+
+ numeric ffpos ; ffpos := 4 ; initialize_box_pos(ffpos,wn,wx,fy,0,wh,wd) ;
+ numeric ttpos ; ttpos := 5 ; initialize_box_pos(ttpos,wn,wx+ww,ty,0,wh,wd) ;
+
+ do_initialize_area (ffpos, ttpos) ;
+
+ numeric mpos ; mpos := 6 ; freeze_box(mpos) ;
+
+ do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ;
+
+enddef ;
+
+def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) =
+
+ pair lref, rref, pref, lhref, rhref ;
+
+ % clip the page area to the left and right skips
+
+ llxy[mpos] := llxy[mpos] shifted (+rl,0) ;
+ lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ;
+ urxy[mpos] := urxy[mpos] shifted (-rr,0) ;
+ ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ;
+
+ % fixate the leftskip, rightskip and hanging indentation
+
+ lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ;
+ rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ;
+
+ pref := lxy[ppos] ;
+
+ if nxy[tpos] > nxy[fpos] :
+ if nxy[fpos] = nxy[mpos] :
+ % first of multiple pages
+ llxy[tpos] := llxy[mpos] ;
+ lrxy[tpos] := lrxy[mpos] ;
+ urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ;
+ ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ;
+ boxgriddirection := down ;
+ elseif nxy[tpos] = nxy[mpos] :
+ % last of multiple pages
+ llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ;
+ lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ;
+ urxy[fpos] := urxy[mpos] ;
+ ulxy[fpos] := ulxy[mpos] ;
+ boxgriddirection := up ;
+ else :
+ % middle of multiple pages
+ llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ;
+ lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ;
+ urxy[fpos] := urxy[mpos] ;
+ ulxy[fpos] := ulxy[mpos] ;
+ llxy[tpos] := llxy[mpos] ;
+ lrxy[tpos] := lrxy[mpos] ;
+ urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ;
+ ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ;
+ boxgriddirection := up ;
+ fi ;
+ else :
+ % just one page
+ boxgriddirection := up ;
+ fi ;
+
+ path txy, bxy, pxy, mxy ;
+
+ txy := originpath ; % top
+ bxy := originpath ; % bottom
+ pxy := originpath ; % composed
+
+ boolean lefthang, righthang, somehang ;
+
+ % we only hang on the first of a multiple page background
+
+ if nxy[mpos] > nxy[fpos] :
+ lefthang := righthang := somehang := false ;
+ else :
+ lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ;
+ fi ;
+
+ if lefthang :
+ mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ;
+ elseif righthang :
+ mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ;
+ else :
+ mxy := originpath ;
+ fi ;
+
+ if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) :
+
+ % We have a one-liner. Watch how er use the bottom pos for
+ % determining the height.
+
+ llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ;
+ ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ;
+
+ else :
+
+ % We have a multi-liner. For convenience we now correct the
+ % begin and end points for indentation.
+
+ if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) :
+ llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ;
+ ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ;
+ else :
+ llxy[tpos] := (xpart lref, ypart llxy[tpos]) ;
+ ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ;
+ fi ;
+
+ if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) :
+ lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ;
+ urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ;
+ else :
+ lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ;
+ urxy[fpos] := (xpart rref, ypart urxy[fpos]) ;
+ fi ;
+
+ fi ;
+
+ somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and
+ (ypart llxy[tpos]<ypart llcorner mxy) ;
+
+ if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) :
+
+ % A (short) one-liner goes into the top box.
+
+ txy := llxy[fpos] -- lrxy[tpos] -- urxy[tpos] -- ulxy[fpos] -- cycle ;
+
+ elseif (round(ypart llxy[fpos]) = round(ypart ulxy[tpos])) and
+ (round(xpart lrxy[tpos]) < round(xpart llxy[fpos])) :
+
+ % We have a sentence that spans two lines but with only end
+ % of line and begin of line segments. We need to take care of
+ % indentation.
+
+ txy := llxy[fpos] -- lrxy[fpos] -- urxy[fpos] -- ulxy[fpos] -- cycle ;
+ bxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] -- ulxy[tpos] -- cycle ;
+
+ elseif (round(ypart llxy[fpos]) = round(ypart ulxy[tpos])) :
+
+ % We have a sentence that spans two lines but with overlap.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] -- lrxy[fpos] --
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] -- ulxy[tpos] -- cycle ;
+
+ elseif lefthang and somehang :
+
+ % We have a sentence that spans more than two lines with
+ % left hanging indentation.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] --
+ (xpart urxy[fpos],ypart urxy[tpos]) --
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] --
+ if round(ypart urxy[tpos]) < round(ypart llcorner mxy) :
+ (xpart lrcorner mxy,ypart llxy[fpos]) --
+ lrcorner mxy --
+ (xpart llxy[tpos],ypart llcorner mxy) --
+ else :
+ (xpart llxy[tpos],ypart llxy[fpos]) --
+ fi
+ cycle ;
+
+ elseif righthang and somehang :
+
+ % We have a sentence that spans more than two lines with
+ % right hanging indentation.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] --
+ if round(ypart urxy[tpos]) < round(ypart llcorner mxy) :
+ (xpart lrcorner mxy,ypart urxy[tpos]) --
+ lrcorner mxy -- llcorner mxy --
+ else :
+ (xpart urxy[fpos],ypart urxy[tpos]) --
+ fi
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] --
+ (xpart llxy[tpos],ypart llxy[fpos]) --
+ cycle ;
+
+ else :
+
+ % We have a sentence that spans more than two lines with
+ % no hanging indentation.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] --
+ (xpart urxy[fpos],ypart urxy[tpos]) --
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] --
+ (xpart llxy[tpos],ypart llxy[fpos]) -- cycle ;
+
+ fi ;
+
+ pxy := simplified pxy ;
+ pxy := unspiked pxy ;
+
+enddef ;
+
+TopSkip := 0 ; % will move
+StrutHeight := 0 ; % will move
+
+pair last_multi_par_shift ; last_multi_par_shift := origin ;
+
+def relocate_multipars (expr xy) =
+ last_multi_par_shift := xy ;
+ for i=1 upto nofmultipars :
+ multipars[i] := multipars[i] shifted last_multi_par_shift ;
+ endfor ;
+enddef ;
+
+boolean compensate_multi_par_topskip ;
+boolean span_multi_column_pars ;
+boolean auto_multi_par_hsize ;
+boolean enable_multi_par_fallback ;
+
+compensate_multi_par_topskip := true ;
+span_multi_column_pars := false ;
+auto_multi_par_hsize := false ; % true ;
+enable_multi_par_fallback := true ;
+
+vardef multi_par_at_top (expr i) =
+ (round (ypart ulcorner multipars[i]) = round (ypart ulcorner
+ (TextAreas[multirefs[i]] shifted last_multi_par_shift)))
+enddef ;
+
+numeric nofmultipars ; nofmultipars := 0 ;
+
+boolean obey_multi_par_hang ; obey_multi_par_hang := true ;
+boolean obey_multi_par_more ; obey_multi_par_more := true ;
+boolean snap_multi_par_tops ; snap_multi_par_tops := true ;
+boolean local_multi_par_area ; local_multi_par_area := false ;
+boolean ignore_multi_par_page ; ignore_multi_par_page := false ;
+boolean force_multi_par_chain ; force_multi_par_chain := true ;
+boolean one_piece_multi_par ; one_piece_multi_par := false ;
+boolean check_multi_par_chain ; check_multi_par_chain := true ; % extra page check
+
+boolean multi_column_first_page_hack; multi_column_first_page_hack := true ; % seems to work ok
+
+if unknown NOfTextColumns : numeric NOfTextColumns ; NOfTextColumns := 0 ; fi ;
+if unknown NOfTextAreas : numeric NOfTextAreas ; NOfTextAreas := 0 ; fi ;
+
+def simplify_multi_pars = % boundingbox ipv shape als optie
+ for i := 1 upto nofmultipars :
+ multipars[i] := boundingbox multipars[i] ;
+ endfor ;
+enddef ;
+
+def save_multipar (expr i, l, p) =
+ nofmultipars := nofmultipars + 1 ;
+ multirefs[nofmultipars] := i ;
+ multilocs[nofmultipars] := l ;
+ multipars[nofmultipars] := unspiked (simplified p) ;
+enddef ;
+
+def prepare_multi_pars (expr fn,fx,fy,fw,fh,fd,
+ tn,tx,ty,tw,th,td,
+ wn,wx,wy,ww,wh,wd,
+ pn,px,py,pw,ph,pd,
+ rw,rl,rr,rh,ra,ri) =
+
+% if span_multi_column_pars :
+% begingroup ;
+% save TextAreas ; path TextAreas[] ;
+% save NOfTextAreas ; numeric NOfTextAreas ;
+% for i=1 upto NOfTextColumns :
+% TextAreas[i] := TextColumns[i] ;
+% endfor ;
+% NOfTextAreas := NOfTextColumns ;
+% fi ;
+
+ last_multi_par_shift := origin ;
+
+ numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ;
+ numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ;
+ numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ;
+ numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ;
+
+ if local_multi_par_area :
+ RealPageNumber := fn ;
+ NOfTextAreas := 1 ;
+ NOfSavedTextAreas := 0 ;
+ TextAreas[1] := TextAreas[0] ;
+ TextColumns[1] := TextColumns[0] ;
+ nxy[fpos] := nxy[tpos] := nxy[wpos] := nxy[ppos] := RealPageNumber ;
+ % draw TextColumns[1] withcolor green ;
+ % draw TextAreas[1] withcolor green ;
+ elseif ignore_multi_par_page :
+ RealPageNumber := fn ;
+ nxy[fpos] := nxy[tpos] := nxy[wpos] := nxy[ppos] := RealPageNumber ;
+ fi ;
+
+ numeric par_strut_height, par_strut_depth, par_line_height ;
+
+ set_par_line_height (ph, pd) ;
+
+ numeric par_hang_indent, par_hang_after, par_indent, par_left_skip, par_right_skip ;
+
+ par_hang_indent := rh ;
+ par_hang_after := ra ;
+ par_indent := ri ;
+ par_left_skip := rl ;
+ par_right_skip := rr ;
+
+ pair par_start_pos ;
+ pair par_stop_pos ;
+
+ par_start_pos := llxy[fpos]
+ if par_indent <0: shifted (-par_indent, 0) fi
+ if par_left_skip<0: shifted (-par_left_skip,0) fi ;
+ par_stop_pos := lrxy[tpos]
+ if par_right_skip<0: shifted (par_right_skip,0) fi ; % nasty as the endpos can be shifted by rightskip
+
+ if wxy[wpos]>0 :
+ left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ;
+ right_skip := rw - left_skip - ww ;
+ else :
+ left_skip := rl ;
+ right_skip := rr ;
+ fi ;
+
+ path multipar, multipars[] ;
+ numeric multiref, multirefs[] ;
+ numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end
+
+ numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ;
+
+ % locals .. why can't i move these outside?
+
+vardef _pmp_set_multipar_ (expr i) =
+ ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip
+ if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) )
+enddef ;
+
+vardef _pmp_snapped_multi_pos_ (expr p) =
+ if snap_multi_par_tops :
+ if abs(ypart p - ypart ulcorner multipar) < par_line_height :
+ (xpart p,ypart ulcorner multipar)
+ else :
+ p
+ fi
+ else :
+ p
+ fi
+enddef ;
+
+vardef _pmp_estimated_par_lines_ (expr h) =
+ round(h/par_line_height)
+enddef ;
+
+vardef _pmp_top_multi_par_(expr p) =
+ (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p)))
+enddef ;
+
+vardef _pmp_multi_par_tsc_(expr p) =
+ if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi
+enddef ;
+
+vardef _pmp_estimated_multi_par_height_ (expr n, t) =
+ if round(par_line_height)=0 :
+ 0
+ else :
+ save ok, h ; boolean ok ;
+ numeric h ; h := 0 ;
+ ok := false ;
+ if (nxy[fpos]=RealPageNumber-1) :
+ for i := 1 upto NOfSavedTextAreas :
+ if (InsideSavedTextArea(i,par_start_pos)) :
+ ok := true ;
+ h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] -
+ ypart llcorner SavedTextAreas[i]) ;
+ elseif ok :
+ h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ;
+ fi ;
+ endfor ;
+ fi ;
+ if ok :
+ for i := 1 upto n-1 :
+ h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ;
+ endfor ;
+ else :
+ % already: ok := false ;
+ for i := 1 upto n-1 :
+ if (InsideTextArea(i,par_start_pos)) :
+ ok := true ;
+ h := h + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ;
+ elseif ok :
+ h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ;
+ fi ;
+ endfor ;
+ fi ;
+ h
+ fi
+enddef ;
+
+vardef _pmp_left_top_hang_ (expr same_area) =
+
+ par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ;
+
+ if (par_hang_indent>0) and (par_hang_after<0) and obey_multi_par_hang :
+ pair _ul_ ; _ul_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos]));
+ pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ;
+ if same_area :
+ _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llxy[tpos])) ;
+ fi ;
+ if obey_multi_par_more and (round(par_line_height)>0) :
+ par_hang_after := min(0,round(par_hang_after +
+ (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ;
+ fi ;
+ (xpart _ul_ + par_hang_indent, ypart lrxy[fpos]) --
+ (xpart _ul_ + par_hang_indent, ypart _pa_) --
+ (xpart ulcorner multipar, ypart _pa_)
+ else :
+ (xpart ulcorner multipar, ypart lrxy[fpos])
+ fi
+enddef ;
+
+vardef _pmp_right_top_hang_ (expr same_area) =
+
+ par_hang_after := ra + _pmp_estimated_par_lines_(py-fy) ;
+
+ if (par_hang_indent<0) and (par_hang_after<0) and obey_multi_par_hang :
+ pair _ur_ ; _ur_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ;
+ pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ;
+ if same_area :
+ _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ;
+ fi ;
+ if obey_multi_par_more and (round(par_line_height)>0) :
+ par_hang_after := min(0,round(par_hang_after +
+ (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ;
+ fi ;
+ (xpart urcorner multipar, ypart _pa_) --
+ (xpart _ur_ + par_hang_indent, ypart _pa_) --
+ (xpart _ur_ + par_hang_indent, ypart _pmp_snapped_multi_pos_(urxy[fpos]))
+ else :
+ (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos]))
+ fi
+enddef ;
+
+vardef _pmp_x_left_top_hang_ (expr i, t) =
+ par_hang_after := min(0,ra + _pmp_estimated_multi_par_height_(i,t)) ;
+ if (par_hang_indent>0) and (par_hang_after<0) :
+ pair _ul_ ; _ul_ := ulcorner multipar ;
+ pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ;
+ if t :
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos]));
+ fi ;
+ if abs(ypart _pa_-ypart llxy[tpos])<par_line_height :
+ _pa_ := (xpart _pa_,ypart llxy[tpos]);
+ fi ;
+ if abs(ypart _pa_-ypart llcorner multipar)<par_line_height :
+ _pa_ := (xpart _pa_,ypart llcorner multipar);
+ fi ;
+ (xpart _ul_, ypart _pa_) --
+ (xpart _ul_ + par_hang_indent, ypart _pa_) --
+ (xpart _ul_ + par_hang_indent, ypart _ul_)
+ else :
+ ulcorner multipar
+ fi
+enddef ;
+
+vardef _pmp_x_right_top_hang_ (expr i, t) =
+ par_hang_after := min(0,ra + _pmp_estimated_multi_par_height_(i,t)) ;
+ if (par_hang_indent<0) and (par_hang_after<0) :
+ pair _ur_ ; _ur_ := urcorner multipar ;
+ pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ;
+ if t :
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart _pmp_snapped_multi_pos_(urxy[tpos]))) ;
+ fi ;
+ (xpart _ur_ + par_hang_indent, ypart _ur_) --
+ (xpart _ur_ + par_hang_indent, ypart _pa_) --
+ (xpart _ur_, ypart _pa_)
+ else :
+ urcorner multipar
+ fi
+enddef ;
+
+vardef _pmp_left_bottom_hang_ (expr same_area) =
+ pair _ll_, _sa_, _pa_ ;
+ _sa_ := if same_area : llxy[tpos] else : lrcorner multipar fi ;
+ if (par_hang_indent>0) and (par_hang_after>0) and obey_multi_par_hang :
+ _ll_ := (xpart ulcorner multipar, ypart _pmp_snapped_multi_pos_(ulxy[fpos])) ;
+ _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ;
+ if same_area :
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ;
+ fi ;
+ if obey_multi_par_more and (round(par_line_height)>0) :
+ par_hang_after := max(0,round(par_hang_after -
+ (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ;
+ fi ;
+ _pa_ --
+ (xpart _pa_ + par_hang_indent,ypart _pa_) --
+ (xpart _pa_ + par_hang_indent,ypart _sa_)
+ else :
+ (xpart llcorner multipar, ypart _sa_)
+ fi
+enddef ;
+
+vardef _pmp_right_bottom_hang_ (expr same_area) =
+ pair _lr_, _sa_, _pa_ ;
+ _sa_ := if same_area : _pmp_snapped_multi_pos_(ulxy[tpos]) else : lrcorner multipar fi ;
+ if (par_hang_indent<0) and (par_hang_after>0) and obey_multi_par_hang :
+ _lr_ := (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) ;
+ _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ;
+ if same_area :
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart _pmp_snapped_multi_pos_(ulxy[tpos]))) ;
+ fi ;
+ if obey_multi_par_more and (round(par_line_height)>0) :
+ par_hang_after := max(0,round(par_hang_after -
+ (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ;
+ fi ;
+ (xpart _pa_ + par_hang_indent,ypart _sa_) --
+ (xpart _pa_ + par_hang_indent,ypart _pa_) --
+ _pa_
+ else :
+ (xpart lrcorner multipar, ypart _sa_)
+ fi
+enddef ;
+
+vardef _pmp_x_left_bottom_hang_ (expr i, t) =
+ pair _ll_, _sa_, _pa_ ;
+ _sa_ := if t : llxy[tpos] else : llcorner multipar fi ;
+ if (par_hang_indent>0) and (ra>0) :
+ par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i,t)) ;
+ _ll_ := ulcorner multipar ;
+ _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ;
+ % we need to compensate for topskip enlarged areas
+ if abs(ypart _pa_ - ypart _sa_) > par_line_height :
+ (xpart _pa_ + par_hang_indent,ypart _sa_) --
+ (xpart _pa_ + par_hang_indent,ypart _pa_) --
+ fi
+ _pa_
+ else :
+ (xpart llcorner multipar, ypart _sa_)
+ fi
+enddef ;
+
+vardef _pmp_x_right_bottom_hang_ (expr i, t) =
+ pair _lr_, _sa_, _pa_ ;
+ _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ;
+ if (par_hang_indent<0) and (ra>0) :
+ par_hang_after := max(0,ra - _pmp_estimated_multi_par_height_(i, t)) ;
+ _lr_ := urcorner multipar ;
+ _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ;
+ _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ;
+ % we need to compensate for topskip enlarged areas
+ _pa_
+ if abs(ypart _pa_ - ypart _sa_) > par_line_height :
+ -- (xpart _pa_ + par_hang_indent,ypart _pa_)
+ -- (xpart _pa_ + par_hang_indent,ypart _sa_)
+ fi
+ else :
+ (xpart lrcorner multipar, ypart _sa_)
+ fi
+enddef ;
+
+% def _pmp_test_multipar_ =
+% multipar := boundingbox multipar ;
+% enddef ;
+
+ % first loop
+
+ ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ;
+
+ if enable_multi_par_fallback and
+ (nxy[fpos]=RealPageNumber) and
+ (nxy[tpos]=RealPageNumber) and not
+ (InsideSomeTextArea(lxy[fpos]) and
+ InsideSomeTextArea(rxy[tpos])) :
+
+ % fallback
+
+ % multipar :=
+ % llxy[fpos] --
+ % lrxy[tpos] --
+ % urxy[tpos] --
+ % ulxy[fpos] -- cycle ;
+ %
+ % save_multipar (1,1,multipar) ;
+
+ % we need to take the boundingbox because there can be
+ % more lines and we want a proper rectange
+
+ multipar :=
+ ulxy[fpos] --
+ urxy[tpos] --
+ lrxy[fpos] --
+ llxy[tpos] -- cycle ;
+
+ save_multipar (1,1,boundingbox(multipar)) ;
+
+ else :
+
+ % normal
+
+ for i=1 upto NOfTextAreas :
+
+ TopSkipCorrection := 0 ;
+
+ multipar := _pmp_set_multipar_(i) ;
+
+ % watch how we compensate for negative indentation
+
+ if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) :
+
+ % first one in chain
+
+ ii := i ;
+
+% if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) :
+ if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) :
+
+ % in same area
+
+ nn := i ;
+
+ if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) :
+
+ TopSkipCorrection := TopSkip - StrutHeight ;
+
+ if round(ypart ulxy[fpos] + TopSkipCorrection) =
+ round(ypart ulcorner TextAreas[i]) :
+ ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ;
+ urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ;
+ else :
+ TopSkipCorrection := 0 ;
+ fi ;
+
+ fi ;
+
+ if ypart llxy[fpos] = ypart llxy[tpos] :
+
+ multipar :=
+ llxy[fpos] --
+ lrxy[tpos] --
+ %urxy[tpos] --
+ _pmp_snapped_multi_pos_(urxy[tpos]) --
+ %ulxy[fpos] --
+ _pmp_snapped_multi_pos_(ulxy[fpos]) --
+ cycle ;
+
+ save_multipar (i,1,multipar) ;
+
+ elseif (ypart llxy[fpos] = ypart ulxy[tpos]) and
+ (xpart llxy[tpos] < xpart llxy[fpos]) :
+
+ % two loners
+
+ multipar := if obey_multi_par_hang :
+
+ _pmp_right_bottom_hang_(true) --
+ _pmp_right_top_hang_(true) --
+ _pmp_snapped_multi_pos_(urxy[fpos]) --
+ lrxy[fpos] --
+
+ else :
+
+ llxy[fpos] --
+ (xpart urcorner multipar, ypart llxy[fpos]) --
+ (xpart urcorner multipar, ypart ulxy[fpos]) --
+ _pmp_snapped_multi_pos_(ulxy[fpos]) --
+
+ fi cycle ;
+
+ save_multipar (i,1,multipar) ;
+
+ multipar := _pmp_set_multipar_(i) ;
+
+ multipar := if obey_multi_par_hang :
+
+ _pmp_left_bottom_hang_(true) --
+ llxy[tpos] --
+ _pmp_snapped_multi_pos_(ulxy[tpos]) --
+ _pmp_left_top_hang_(true) --
+
+ else :
+
+ (xpart llcorner multipar, ypart llxy[tpos]) --
+ llxy[tpos] --
+ _pmp_snapped_multi_pos_(ulxy[tpos]) --
+ (xpart llcorner multipar, ypart ulxy[tpos]) --
+
+ fi cycle ;
+
+ save_multipar (i,1,multipar) ;
+
+ else :
+
+ multipar := if obey_multi_par_hang :
+
+ _pmp_left_bottom_hang_(true) --
+ llxy[tpos] --
+ %ulxy[tpos] --
+ _pmp_snapped_multi_pos_(ulxy[tpos]) --
+ _pmp_right_bottom_hang_(true) --
+ _pmp_right_top_hang_(true) --
+ %urxy[fpos] --
+ _pmp_snapped_multi_pos_(urxy[fpos]) --
+ lrxy[fpos] --
+ _pmp_left_top_hang_(true) --
+
+ else :
+
+ (xpart llcorner multipar, ypart llxy[tpos]) --
+ llxy[tpos] --
+ %ulxy[tpos] --
+ _pmp_snapped_multi_pos_(ulxy[tpos]) --
+ (xpart lrcorner multipar, ypart ulxy[tpos]) --
+ (xpart urcorner multipar, ypart urxy[fpos]) --
+ %urxy[fpos] --
+ _pmp_snapped_multi_pos_(urxy[fpos]) --
+ lrxy[fpos] --
+ (xpart ulcorner multipar, ypart lrxy[fpos]) --
+
+ fi cycle ;
+
+ save_multipar (i,1,multipar) ;
+
+ fi ;
+
+ else :
+
+ multipar := if obey_multi_par_hang :
+
+ _pmp_left_bottom_hang_(false) --
+ _pmp_right_bottom_hang_(false) --
+ _pmp_right_top_hang_(false) --
+ %urxy[fpos] --
+ _pmp_snapped_multi_pos_(urxy[fpos]) --
+ lrxy[fpos] --
+ _pmp_left_top_hang_(false) --
+
+ else :
+
+ llcorner multipar --
+ lrcorner multipar --
+ (xpart urcorner multipar, ypart urxy[fpos]) --
+ %urxy[fpos] --
+ _pmp_snapped_multi_pos_(urxy[fpos]) --
+ lrxy[fpos] --
+ (xpart ulcorner multipar, ypart lrxy[fpos]) --
+
+ fi cycle ;
+
+ save_multipar (i,1,multipar) ;
+
+ fi ;
+
+% elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) :
+ elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) :
+
+ % last one in chain
+
+ nn := i ;
+
+ if obey_multi_par_hang and obey_multi_par_more :
+
+ multipar :=
+ _pmp_x_left_top_hang_(i,true) --
+ _pmp_x_right_top_hang_(i,true) --
+ _pmp_x_right_bottom_hang_(i,true) --
+ _pmp_snapped_multi_pos_(ulxy[tpos]) --
+ llxy[tpos] --
+ _pmp_x_left_bottom_hang_(i,true) --
+ cycle ;
+
+ else :
+
+ multipar :=
+ ulcorner multipar --
+ urcorner multipar --
+ (xpart lrcorner multipar, ypart urxy[tpos]) --
+ _pmp_snapped_multi_pos_(ulxy[tpos]) --
+ llxy[tpos] --
+ (xpart llcorner multipar, ypart llxy[tpos]) --
+ cycle ;
+
+ fi ;
+
+ save_multipar (i,3,multipar) ;
+
+ elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber)) : % and (NOfTextColumns>1)) :
+
+ save_multipar (i,2,multipar) ;
+
+ else :
+ % handled later
+ fi ;
+
+ endfor ;
+
+ % second loop
+
+ if force_multi_par_chain or (ii > 1) :
+
+ for i=ii+1 upto nn-1 :
+
+ % rest of chain / todo : hang
+
+% hm, the second+ column in column sets now gets lost in a NOfTextColumns
+
+ if (not check_multi_par_chain) or
+ ((nxy[fpos]<RealPageNumber) and (nxy[tpos]>RealPageNumber))
+ :
+
+ multipar := _pmp_set_multipar_(i) ;
+
+ if obey_multi_par_hang and obey_multi_par_more :
+
+ multipar :=
+ _pmp_x_left_top_hang_(i,false) --
+ _pmp_x_right_top_hang_(i,false) --
+ _pmp_x_right_bottom_hang_(i,false) --
+ _pmp_x_left_bottom_hang_(i,false) --
+ cycle ;
+
+ fi ;
+
+ save_multipar(i,2,multipar) ;
+
+ fi ;
+
+ endfor ;
+
+ fi ;
+
+ % end of normal/fallback
+
+fi ;
+
+% if span_multi_column_pars :
+% endgroup ;
+% fi ;
+
+ % potential safeguard:
+
+ % for i=1 upto nofmultipars :
+ % if length p <= 4 :
+ % multipars[i] := boundingbox(multipars[i]) ;
+ % fi ;
+ % end ;
+
+ % quick hack for gb:
+
+ one_piece_multi_par := (nofmultipars=1) and (pn=tn) ;
+
+enddef ;
+
+color boxgridcolor ; boxgridcolor := .8red ;
+color boxlinecolor ; boxlinecolor := .8blue ;
+color boxfillcolor ; boxfillcolor := .8white ;
+numeric boxgridtype ; boxgridtype := 0 ;
+numeric boxlinetype ; boxlinetype := 1 ;
+numeric boxfilltype ; boxfilltype := 1 ;
+numeric boxdashtype ; boxdashtype := 0 ;
+pair boxgriddirection ; boxgriddirection := up ;
+numeric boxgridwidth ; boxgridwidth := 1pt ;
+numeric boxlinewidth ; boxlinewidth := 1pt ;
+numeric boxlineradius ; boxlineradius := 0pt ;
+numeric boxfilloffset ; boxfilloffset := 0pt ;
+numeric boxgriddistance ; boxgriddistance := .5cm ;
+numeric boxgridshift ; boxgridshift := 0pt ;
+
+def draw_box =
+ draw pxy withcolor boxlinecolor withpen pencircle scaled boxlinewidth ;
+ draw lxy -- rxy withcolor boxlinecolor withpen pencircle scaled boxgridwidth ;
+enddef ;
+
+def draw_par = % 1 2 3 11 12
+ do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ;
+ for i = pxy, txy, bxy :
+ if boxgridtype = 1 :
+ boxgriddirection := origin ;
+ draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ;
+ elseif boxgridtype = 2 :
+ boxgriddirection := origin ;
+ draw baseline_grid (i,boxgriddirection,false) withcolor boxgridcolor ;
+ elseif boxgridtype = 3 :
+ boxgriddirection := origin ;
+ draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ;
+ draw baseline_grid (i,boxgriddirection,true )
+ shifted (0,ExHeight) withcolor boxgridcolor ;
+ elseif boxgridtype = 4 :
+ boxgriddirection := origin ;
+ draw baseline_grid (i,boxgriddirection,true )
+ shifted (0,ExHeight/2) withcolor boxgridcolor ;
+ elseif boxgridtype = 11 :
+ draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ;
+ elseif boxgridtype = 12 :
+ draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ;
+ fi ;
+ endfor ;
+enddef ;
+
+def do_show_par (expr p, r, c) =
+ if length(p) > 2 : for i=0 upto length(p) :
+ draw fullcircle scaled r shifted point i of p
+ withpen pencircle scaled .5pt withcolor c ;
+ endfor ; fi ;
+ draw p withpen pencircle scaled .5pt withcolor c ;
+enddef ;
+
+def show_par =
+ if length(mxy) > 2 :
+ draw mxy dashed evenly
+ withpen pencircle scaled .5pt withcolor .5white ;
+ fi ;
+ do_show_par(txy, 4pt, .5green) ;
+ do_show_par(bxy, 6pt, .5blue ) ;
+ do_show_par(pxy, 8pt, .5red ) ;
+ draw pref withpen pencircle scaled 2pt ;
+enddef ;
+
+def sort_multi_pars =
+ if nofmultipars>1 :
+ begingroup ; save _p_, _n_ ; path _p_ ; numeric _n_ ;
+ for i := 1 upto nofmultipars :
+ if multilocs[i] = 3 :
+ _p_ := multipars[nofmultipars] ;
+ multipars[nofmultipars] := multipars[i] ;
+ multipars[i] := _p_ ;
+ _n_ := multirefs[nofmultipars] ;
+ multirefs[nofmultipars] := multirefs[i] ;
+ multirefs[i] := _n_ ;
+ _n_ := multilocs[nofmultipars] ;
+ multilocs[nofmultipars] := multilocs[i] ;
+ multilocs[i] := _n_ ;
+ fi ;
+ endfor ;
+ endgroup ;
+ fi ;
+enddef ;
+
+
+def collapse_multi_pars =
+ if nofmultipars>1 :
+ begingroup ; save _nofmultipars_ ; numeric _nofmultipars_ ;
+ _nofmultipars_ := 1 ;
+ sort_multi_pars ; % block not in order: 1, 3, 2....
+ for i:=1 upto nofmultipars-1 :
+ if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and
+ (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) :
+multilocs[_nofmultipars_] := multilocs[i+1] ;
+multirefs[_nofmultipars_] := multirefs[i+1] ;
+ multipars[_nofmultipars_] :=
+ ulcorner multipars[_nofmultipars_] --
+ urcorner multipars[_nofmultipars_] --
+ lrcorner multipars[i+1] --
+ llcorner multipars[i+1] -- cycle ;
+ else :
+ _nofmultipars_ := _nofmultipars_ + 1 ;
+ multipars[_nofmultipars_] := multipars[i+1] ;
+ multilocs[_nofmultipars_] := multilocs[i+1] ;
+ multirefs[_nofmultipars_] := multirefs[i+1] ;
+ fi ;
+ endfor ;
+ nofmultipars := _nofmultipars_ ;
+ endgroup ;
+ fi ;
+enddef ;
+
+% def draw_multi_pars =
+% for i=1 upto nofmultipars :
+% do_draw_par(multipars[i]) ;
+% if boxgridtype= 1 :
+% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ;
+% elseif boxgridtype= 2 :
+% draw baseline_grid (multipars[i],up,false) ; % withcolor boxgridcolor ;
+% elseif boxgridtype= 3 :
+% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ;
+% draw baseline_grid (multipars[i],up,true )
+% shifted (0,ExHeight) ; % withcolor boxgridcolor ;
+% elseif boxgridtype= 4 :
+% draw baseline_grid (multipars[i],up,true )
+% shifted (0,ExHeight/2) ; % withcolor boxgridcolor ;
+% elseif boxgridtype=11 :
+% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ;
+% elseif boxgridtype=12 :
+% draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ;
+% fi ;
+% endfor ;
+% enddef ;
+
+def draw_multi_pars =
+ for i=1 upto nofmultipars :
+ do_draw_par(multipars[i]) ;
+ if boxgridtype= 1 :
+ draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ;
+ elseif boxgridtype= 2 :
+ draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; % withcolor boxgridcolor ;
+ elseif boxgridtype= 3 :
+ draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ;
+ draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; % withcolor boxgridcolor ;
+ elseif boxgridtype= 4 :
+ draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; % withcolor boxgridcolor ;
+ elseif boxgridtype=11 :
+ draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ;
+ elseif boxgridtype=12 :
+ draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ;
+ fi ;
+ endfor ;
+enddef ;
+
+def show_multi_pars =
+ for i=1 upto nofmultipars :
+ do_show_par(multipars[i], 6pt, .5blue) ;
+ endfor ;
+enddef ;
+
+vardef do_draw_par (expr p) =
+ if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) :
+ save pp ; path pp ;
+ if (boxlineradius>0) and (boxlinetype=2) :
+ pp := p cornered boxlineradius ;
+ else :
+ pp := p ;
+ fi ;
+ if boxfilltype>0 :
+ if boxfilloffset>0 :
+ % temporary hack
+ begingroup ; interim linejoin := mitered ;
+ filldraw pp withcolor boxfillcolor withpen pencircle scaled (2*boxfilloffset) ;
+ endgroup ;
+ else :
+ fill pp withcolor boxfillcolor ;
+ fi ;
+ fi ;
+ if boxlinetype>0 :
+ draw pp withcolor boxlinecolor withpen pencircle scaled boxlinewidth ;
+ fi ;
+ fi ;
+enddef ;
+
+vardef baseline_grid (expr pxy, pdir, at_baseline) =
+ if (par_line_height>0) and (bbheight(pxy)>1) and (bbwidth(pxy)>1) and (boxgridwidth>0) :
+ save i, grid, bb ; picture grid ; pair start ; path bb ;
+ def _do_ (expr start) =
+ % 1 = normal, 2 = with background (i.e. no shine-through)
+ if boxdashtype = 2 :
+ draw start -- start shifted (bbwidth(pxy),0)
+ withpen pencircle scaled boxgridwidth
+ withcolor boxfillcolor ;
+ fi ;
+ draw start -- start shifted (bbwidth(pxy),0)
+ if boxdashtype > 0 : dashed evenly fi
+ withpen pencircle scaled boxgridwidth
+ withcolor boxgridcolor ;
+ enddef ;
+ grid := image
+ ( %fails with inlinespace
+ %
+ if pdir=up :
+ for i = if at_baseline : par_strut_depth else : 0 fi
+ step par_line_height
+ until max(bbheight(pxy),par_line_height) :
+ _do_ (llcorner pxy shifted (0,+i)) ;
+ endfor ;
+ else :
+ for i = if at_baseline : par_strut_height else : 0 fi
+ step par_line_height
+ until bbheight(pxy) :
+ _do_ (ulcorner pxy shifted (0,-i)) ;
+ endfor ;
+ fi ;
+ ) ;
+ clip grid to pxy ;
+ bb := boundingbox grid ;
+ grid := grid shifted (0,boxgridshift) ;
+ setbounds grid to bb ;
+ grid
+ else :
+ nullpicture
+ fi
+enddef ;
+
+vardef graphic_grid (expr pxy, dx, dy, x, y) =
+ if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) :
+ save grid ; picture grid ;
+ grid := image
+ ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy :
+ draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy)
+ withpen pencircle scaled boxgridwidth ;
+ endfor ;
+ for i = ypart llcorner pxy step dy until ypart ulcorner pxy :
+ draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i)
+ withpen pencircle scaled boxgridwidth ;
+ endfor ) shifted (x,y) ;
+ clip grid to pxy ;
+ grid
+ else :
+ nullpicture
+ fi
+enddef ;
+
+def anchor_box (expr n,x,y,w,h,d) =
+ currentpicture := currentpicture shifted (-x,-y) ;
+enddef ;
+
+let draw_area = draw_box ;
+let anchor_area = anchor_box ;
+let anchor_par = anchor_box ;
+
+
+numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ;
+pair sync_xy[][] ; color sync_c[][] ;
+
+def ResetSyncTasks =
+ path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ;
+ NOfSyncPaths := CurrentSyncClass := 0 ;
+ if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ;
+ if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ;
+ if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ;
+ if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ;
+ if (SyncLeftOffset = 0) and (SyncWidth = 0) :
+ SyncWidth := if known TextWidth : TextWidth else : -1cm fi ;
+ fi ;
+enddef ;
+
+ResetSyncTasks ;
+
+vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) =
+ save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ;
+ o shifted (leftoffset,sync_h[n][i]+topoffset) --
+ o shifted (width+leftoffset,sync_h[n][i]+topoffset) --
+ o shifted (width+leftoffset,bottomoffset) --
+ o shifted (leftoffset,bottomoffset) -- cycle
+enddef ;
+
+def SetSyncColor(expr n, i, c) =
+ sync_c[n][i] := c ;
+enddef ;
+
+def SetSyncThreshold(expr n, i, th) =
+ sync_th[n][i] := th ;
+enddef ;
+
+vardef TheSyncColor(expr n, i) =
+ if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi
+enddef ;
+
+vardef TheSyncThreshold(expr n, i) =
+ if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi
+enddef ;
+
+vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) =
+ ResetSyncTasks ;
+ if known sync_n[n] :
+ CurrentSyncClass := n ;
+ save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ;
+ for i=1 upto sync_n[n] :
+ if RealPageNumber > sync_p[n][i] :
+ l := i ;
+ elseif RealPageNumber = sync_p[n][i] :
+ NOfSyncPaths := NOfSyncPaths + 1 ;
+ if not ok :
+ if i>1 :
+ if sync_t[n][i-1] = sync_t[n][i] :
+ SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ;
+ SyncTasks[NOfSyncPaths] := i ;
+ else :
+ SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ;
+ SyncTasks[NOfSyncPaths] := i-1 ;
+ NOfSyncPaths := NOfSyncPaths + 1 ;
+ SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ;
+ SyncTasks[NOfSyncPaths] := i ;
+ fi ;
+ else :
+ SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ;
+ SyncTasks[NOfSyncPaths] := i ;
+ fi ;
+ else :
+ SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ;
+ SyncTasks[NOfSyncPaths] := i ;
+ fi ;
+ ok := true ;
+ fi ;
+ endfor ;
+ if (NOfSyncPaths = 0) and (l > 0) :
+ NOfSyncPaths := 1 ;
+ SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ;
+ SyncTasks[NOfSyncPaths] := l ;
+ fi ;
+ if NOfSyncPaths > 0 :
+ for i = 1 upto NOfSyncPaths-1 :
+ SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ;
+ endfor ;
+ if unknown SyncThresholdMethod :
+ numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ;
+ fi ;
+ if extendtop :
+ if SyncThresholdMethod = 1 :
+ if NOfSyncPaths>1 :
+ d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ;
+ if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) :
+ SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ;
+ fi ;
+ fi ;
+ else :
+ for i = 1 upto NOfSyncPaths :
+ d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ;
+ if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) :
+ SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ;
+ fi ;
+ endfor ;
+ fi ;
+ fi ;
+ if prestartnext :
+ if NOfSyncPaths>1 :
+ if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one
+ d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ;
+ if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) :
+ SyncPaths[NOfSyncPaths+1] :=
+ (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) --
+ (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) --
+ lrcorner SyncPaths[NOfSyncPaths] --
+ llcorner SyncPaths[NOfSyncPaths] -- cycle ;
+ SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ;
+ NOfSyncPaths := NOfSyncPaths + 1 ;
+ fi ;
+ fi ;
+ fi ;
+ else :
+ if NOfSyncPaths>1 :
+ d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ;
+ if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) :
+ NOfSyncPaths := NOfSyncPaths - 1 ;
+ SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ;
+ fi ;
+ fi ;
+ fi ;
+ if (NOfSyncPaths>1) and collapse :
+ save j ; numeric j ; j := 1 ;
+ for i = 2 upto NOfSyncPaths :
+ if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] :
+ SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ;
+ SyncTasks[j] := SyncTasks[i] ;
+ else :
+ j := j + 1 ;
+ SyncPaths[j] := SyncPaths[i] ;
+ SyncTasks[j] := SyncTasks[i] ;
+ fi ;
+ endfor ;
+ NOfSyncPaths := j ;
+ fi ;
+ fi ;
+ fi ;
+enddef ;
+
+def SyncTask(expr n) =
+ if known SyncTasks[n] : SyncTasks[n] else : 0 fi
+enddef ;
+
+def FlushSyncTasks =
+ for i = 1 upto NOfSyncPaths :
+ ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ;
+ endfor ;
+enddef ;
+
+def ProcessSyncTask(expr p, c) =
+ fill p withcolor c ;
+enddef ;
+
+% for Jelle Huisman
+%
+% \setupcolors[state=start]
+% \dontcomplain
+% \definecolumnset[example][n=3,distance=5mm]
+% \startMPextensions
+% multi_column_first_page_hack := true ;
+% \stopMPextensions
+% \startuseMPgraphic{mpos:par:trick}
+% for i=1 upto nofmultipars-1 : draw (rightboundary multipars[i]) shifted (2.5mm, 0) ; endfor ;
+% \stopuseMPgraphic
+% \definetextbackground[test][mp=mpos:par:trick,method=mpos:par:columnset]
+% \starttext
+% \definecolumnsetspan[chapter][n=3]
+% \startcolumnset[example]
+% \startcolumnsetspan[chapter]
+% \chapter{Chapter One}
+% \stopcolumnsetspan
+% \starttextbackground[test] \dorecurse {3}{\input knuth } \stoptextbackground
+% \stopcolumnset
+% \startcolumnset[example]
+% \startcolumnsetspan[chapter]
+% \chapter{Chapter One}
+% \stopcolumnsetspan
+% \starttextbackground[test] \dorecurse {10}{\input knuth } \stoptextbackground
+% \stopcolumnset
+% \stoptext
+%
+% fast variant:
+%
+% \startuseMPgraphic{whatever}
+% for i=1 upto NOfTextColumns-1 :
+% draw (rightboundary TextColumns[i]) shifted (2.5mm,0) shifted -\MPxy\textanchor ;
+% endfor ;
+% setbounds currentpicture to OverlayBox ;
+% \stopuseMPgraphic
+% \defineoverlay[whatever][\useMPgraphic{whatever}]
+% \setupbackgrounds[text][background=whatever]
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-figs.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-figs.mpii
new file mode 100644
index 00000000000..d4fcc2b3564
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-figs.mpii
@@ -0,0 +1,47 @@
+%D \module
+%D [ file=mp-figs.mpii,
+%D version=2003.01.15,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=figures,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+if known context_figs : endinput ; fi ;
+
+boolean context_figs ; context_figs := true ;
+
+% todo: check defined
+
+def registerfigure(expr name,width,height) =
+ begingroup ;
+ save s ; string s ; s := cleanstring(name) ;
+ scantokens( s & "_width := " & decimal(width )) ;
+ scantokens( s & "_height := " & decimal(height)) ;
+ endgroup ;
+enddef ;
+
+vardef figuresize(expr name) =
+ save s, p ; string s ; pair p ;
+ s := cleanstring(name) ;
+ scantokens( "p := " & "(" & s & "_width" & "," & s & "_height" & ")" ) ;
+ p
+enddef ;
+
+vardef figurewidth(expr name) =
+ xpart figuresize(name)
+enddef ;
+
+vardef figureheight(expr name) =
+ ypart figuresize(name)
+enddef ;
+
+let figuredimensions = figuresize ; % for old times sake
+
+def naturalfigure(expr name) =
+ externalfigure name xyscaled(figuresize(name))
+enddef ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-fobg.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-fobg.mpii
new file mode 100644
index 00000000000..f8b709572bb
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-fobg.mpii
@@ -0,0 +1,87 @@
+%D \module
+%D [ file=mp-fobg.mp,
+%D version=2004.03.12,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=Formatting Objects,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+if known context_fobg : endinput ; fi ;
+
+boolean context_fobg ; context_fobg := true ;
+
+FoNone := 0 ; FoHidden := 1 ; FoDotted := 2 ; FoDashed := 3 ; FoSolid := 4 ;
+FoDouble := 5 ; FoGroove := 6 ; FoRidge := 7 ; FoInset := 8 ; FoOutset := 9 ;
+FoAll := 0 ; FoTop := 1 ; FoBottom := 2 ; FoLeft := 3 ; FoRight := 4 ;
+FoMedium := .5pt ; FoThin := FoMedium/2 ; FoThick := FoMedium*2 ;
+
+color FoBackgroundColor, FoNoColor, FoLineColor[] ; FoNoColor := (-1,-1,-1) ;
+numeric FoLineWidth[], FoLineStyle[] ;
+boolean FoFrame, FoBackground, FoSplit ;
+
+FoFrame := FoBackground := FoSplit := false ;
+FoBackgroundColor := white ;
+FoDashFactor := .5 ;
+FoDotFactor := .375 ;
+
+for i = FoAll upto FoRight :
+ FoLineColor[i] := black ;
+ FoLineWidth[i] := .5pt ;
+ FoLineStyle[i] := FoNone ;
+endfor ;
+
+def DrawFoFrame(expr n, p) =
+ drawoptions(withcolor FoLineColor[n] withpen pencircle scaled FoLineWidth[n]) ;
+ if FoLineStyle[n] = FoNone :
+ % nothing
+ elseif FoLineStyle[n] = FoHidden :
+ % nothing
+ elseif FoLineStyle[n] = FoDotted :
+ draw p dashed (withdots scaled (FoDotFactor*FoLineWidth[n])) ;
+ elseif FoLineStyle[n] = FoDashed :
+ draw p dashed (evenly scaled (FoDashFactor*FoLineWidth[n])) ;
+ elseif FoLineStyle[n] = FoSolid :
+ draw p ;
+ elseif FoLineStyle[n] = FoDouble :
+ draw p enlarged FoLineWidth[n] ; draw p enlarged -FoLineWidth[n] ;
+ elseif FoLineStyle[n] = FoGroove :
+ draw p ;
+ draw p withpen pencircle scaled .5FoLineWidth[n] withcolor (inverted FoLineColor[n] softened .5) ;
+ elseif FoLineStyle[n] = FoRidge :
+ draw p withcolor (inverted FoLineColor[n] softened .5) ;
+ draw p withpen pencircle scaled .5FoLineWidth[n] ;
+ elseif FoLineStyle[n] = FoInset :
+ draw p ; draw p inset 2.5FoLineWidth[n] ;
+ elseif FoLineStyle[n] = FoOutset :
+ draw p ; draw p outset 2.5FoLineWidth[n] ;
+ fi ;
+enddef ;
+
+primarydef p outset d =
+ ((lrcorner p -- urcorner p -- ulcorner p -- llcorner p -- cycle)
+ shifted (d*(-1,1)) cutbefore topboundary p) cutafter leftboundary p
+enddef ;
+
+primarydef p inset d =
+ ((ulcorner p -- llcorner p -- lrcorner p -- urcorner p -- cycle)
+ shifted (d*(1,-1)) cutbefore bottomboundary p) cutafter rightboundary p
+enddef ;
+
+vardef equalpaths(expr p, q) =
+ if length(p) = length(q) :
+ save ok ; boolean ok ; ok := true ;
+ for i = 0 upto length(p)-1 :
+ ok := ok and (round(point i of p) = round(point i of q)) ;
+ endfor ;
+ ok
+ else :
+ false
+ fi
+enddef ;
+
+endinput ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-form.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-form.mpii
new file mode 100644
index 00000000000..d1dac32db23
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-form.mpii
@@ -0,0 +1,392 @@
+% Hans Hagen / October 2000
+%
+% This file is mostly a copy from the file format.mp, that
+% comes with MetaPost and is written by John Hobby. This file
+% is meant to be compatible, but has a few more features,
+% controlled by the variables:
+%
+% fmt_initialize when false, initialization is skipped
+% fmt_precision the default accuracy (default=3)
+% fmt_separator the pattern separator (default=%)
+% fmt_zerocheck activate extra sci notation zero check
+%
+% instead of a picture, one can format a number in a for TeX
+% acceptable input string
+
+boolean mant_font ; mant_font := true ; % signals graph not to load form
+
+if known context_form : endinput ; fi ;
+
+boolean context_form ; context_form := true ;
+
+if unknown fmt_metapost : boolean fmt_metapost ; fmt_metapost := true ; fi ; % == use old method
+if unknown fmt_precision : numeric fmt_precision ; fmt_precision := 3 ; fi ;
+if unknown fmt_initialize : boolean fmt_initialize ; fmt_initialize := true ; fi ;
+if unknown fmt_separator : string fmt_separator ; fmt_separator := "%" ; fi ;
+if unknown fmt_zerocheck : boolean fmt_zerocheck ; fmt_zerocheck := false ; fi ;
+
+% As said, all clever code is from John, the more stupid
+% extensions are mine. The following string variables are
+% responsible for the TeX formatting.
+
+% TeX specs when using TeX instead of pseudo TeX.
+
+string sFebraise_ ; sFebraise_ := "{" ;
+string sFeeraise_ ; sFeeraise_ := "}" ;
+string sFebmath_ ; sFebmath_ := "$" ;
+string sFeemath_ ; sFeemath_ := "$" ;
+
+string sFmneg_ ; sFmneg_ := "-" ;
+string sFemarker_ ; sFemarker_ := "{\times}10^" ;
+string sFeneg_ ; sFeneg_ := "-" ;
+string sFe_plus ; sFe_plus := "" ; % "+"
+
+def sFe_base = Fline_up_("1", sFemarker_) enddef ;
+
+% Macros for generating typeset pictures of computed numbers
+%
+% format(f,x) typeset generalized number x using format string f
+% Mformat(f,x) like format, but x is in Mlog form (see marith.mp)
+% init_numbers(s,m,x,sn,e) choose typeset style given sample sign, mantissa,...
+% roundd(x,d) round numeric x to d places right of decimal point
+% Fe_base what precedes the exponent for typeset powers of 10
+% Fe_plus plus sign if any for typesetting positive exponents
+% Ten_to[] powers of ten for indices 0,1,2,3,4
+%
+% New are:
+%
+% formatstr(f,x) TeX string representing x using format f
+% Mformatstr(f,x) like Mformatstr, but x is in Mlog form
+
+% Other than the above-documented user interface, all
+% externally visible names start with F and end with _.
+
+% Allow big numbers in token lists
+
+begingroup interim warningcheck := 0 ;
+
+%%% Load auxiliary macros.
+
+input string ;
+input marith ;
+
+%%% Choosing the Layout %%%
+
+picture Fmneg_, Femarker_, Feneg_, Fe_base, Fe_plus ;
+string Fmfont_, Fefont_ ;
+numeric Fmscale_, Fescale_, Feraise_ ;
+
+% Argument
+%
+% s is a leading minus sign
+% m is a 1-digit mantissa
+% x is whatever follows the mantissa
+% sn is a leading minus for the exponent, and
+% e is a 1-digit exponent.
+%
+% Numbers in scientific notation are constructed by placing
+% these pieces side-by-side; decimal numbers use only m
+% and/or s. To get exponents with leading plus signs, assign
+% to Fe_plus after calling init_numbers. To do something
+% special with a unit mantissa followed by x, assign to
+% Fe_base after calling init_numbers.
+
+vardef init_numbers(expr s, m, x, sn, e) =
+ Fmneg_ := s ;
+ for p within m :
+ Fmfont_ := fontpart p ;
+ Fmscale_ := xxpart p ;
+ exitif true ;
+ endfor
+ Femarker_ := x ;
+ Feneg_ := sn ;
+ for p within e :
+ Fefont_ := fontpart p ;
+ Fescale_ := xxpart p ;
+ Feraise_ := ypart llcorner p ;
+ exitif true ;
+ endfor
+ if fmt_metapost :
+ Fe_base := Fline_up_("1" infont Fmfont_ scaled Fmscale_, Femarker_) ;
+ % else :
+ % sFe_base := Fline_up_("1", sFemarker_) ;
+ fi ;
+ Fe_plus := nullpicture ;
+enddef ;
+
+%%% Low-Level Typesetting %%%
+
+vardef Fmant_(expr x) = %%% adapted by HH %%%
+ if fmt_metapost :
+ (decimal abs x infont Fmfont_ scaled Fmscale_)
+ else :
+ (decimal abs x)
+ fi
+enddef ;
+
+vardef Fexp_(expr x) = %%% adapted by HH %%%
+ if fmt_metapost :
+ (decimal x infont Fefont_ scaled Fescale_ shifted (0,Feraise_))
+ else :
+ (decimal x)
+ fi
+enddef ;
+
+vardef Fline_up_(text t_) = %%% adapted by HH %%%
+ if fmt_metapost :
+ save p_, c_ ;
+ picture p_ ; p_ = nullpicture ;
+ pair c_ ; c_ = (0,0) ;
+ for q_ = t_ :
+ addto p_ also q_ if string q_ : infont defaultfont scaled defaultscale fi
+ shifted c_ ;
+ c_ := (xpart lrcorner p_, 0) ;
+ endfor
+ p_
+ else :
+ "" for q_ = t_ : & q_ endfor
+ fi
+enddef ;
+
+vardef Fdec_o_(expr x) = %%% adapted by HH %%%
+ if x<0 :
+ Fline_up_(if fmt_metapost : Fmneg_ else : sFmneg_ fi, Fmant_(x))
+ else :
+ Fmant_(x)
+ fi
+enddef ;
+
+vardef Fsci_o_(expr x, e) = %%% adapted by HH %%%
+ if fmt_metapost :
+ Fline_up_
+ (if x < 0 : Fmneg_,fi
+ if abs x = 1 : Fe_base else : Fmant_(x), Femarker_ fi,
+ if e < 0 : Feneg_ else : Fe_plus fi,
+ Fexp_(abs e))
+ else :
+ Fline_up_
+ (if x < 0 : sFmneg_, fi
+ if abs x = 1 : sFe_base else : Fmant_(x), sFemarker_ fi,
+ sFebraise_,
+ if e < 0 : sFeneg_ else : sFe_plus fi,
+ Fexp_(abs e),
+ sFeeraise_)
+ fi
+enddef ;
+
+% Assume prologues=1 implies troff mode. TeX users who want
+% prologues on should use some other positive value. The mpx
+% file mechanism requires separate input files here.
+%
+% if fmt_initialize : %%% adapted by HH
+% if prologues = 1 : input troffnum else : input texnum fi
+% fi ;
+%
+% wrong assumption, so we need:
+
+if fmt_initialize :
+ input texnum ;
+fi ;
+
+%%% Scaling and Rounding %%%
+
+% Find a pair p where x = xpart p*10**ypart p and either p =
+% (0,0) or xpart p is between 1000 and 9999.99999. This is
+% the `exponent form' of x.
+
+vardef Feform_(expr x) =
+ interim warningcheck := 0 ;
+ if string x :
+ Meform(Mlog_str x)
+ else :
+ save b, e ;
+ b = x ; e = 0 ;
+ if abs b >= 10000 :
+ (b/10, 1)
+ elseif b = 0 :
+ origin
+ else :
+ forever :
+ exitif abs b >= 1000 ;
+ b := b*10 ; e := e-1 ;
+ endfor
+ (b, e)
+ fi
+ fi
+enddef ;
+
+% The marith.mp macros include a similar macro Meform that
+% converts from `Mlog form' to exponent form. In case
+% rounding has made the xpart of an exponent form number too
+% large, fix it.
+
+vardef Feadj_(expr x, y) =
+ if abs x >= 10000 : (x/10, y+1) else : (x,y) fi
+enddef ;
+
+% Round x to d places right of the decimal point. When d<0,
+% round to the nearest multiple of 10 to the -d.
+
+vardef roundd(expr x, d) =
+ if abs d > 4 :
+ if d > 0 : x else : 0 fi
+ elseif d > 0 :
+ save i ; i = floor x ;
+ i + round(Ten_to[d]*(x-i))/Ten_to[d]
+ else :
+ round(x/Ten_to[-d])*Ten_to[-d]
+ fi
+enddef ;
+
+Ten_to0 = 1 ;
+Ten_to1 = 10 ;
+Ten_to2 = 100 ;
+Ten_to3 = 1000 ;
+Ten_to4 = 10000 ;
+
+% Round an exponent form number p to k significant figures.
+
+primarydef p Fprec_ k =
+ Feadj_(roundd(xpart p,k-4), ypart p)
+enddef ;
+
+% Round an exponent form number p to k digits right of the
+% decimal point.
+
+primarydef p Fdigs_ k =
+ Feadj_(roundd(xpart p,k+ypart p), ypart p)
+enddef ;
+
+%%% High-Level Routines %%%
+
+% The following operators convert z from exponent form and
+% produce typeset output: Formsci_ generates scientific
+% notation; Formdec_ generates decimal notation; and
+% Formgen_ generates whatever is likely to be most compact.
+
+vardef Formsci_(expr z) = %%% adapted by HH %%%
+ if fmt_zerocheck and (z = origin) :
+ Fsci_o_(0,0)
+ else :
+ Fsci_o_(xpart z/1000, ypart z + 3)
+ fi
+enddef ;
+
+vardef Formdec_(expr z) =
+ if ypart z > 0 :
+ Formsci_(z)
+ else :
+ Fdec_o_
+ (xpart z if ypart z >= -4 :
+ /Ten_to[-ypart z]
+ else :
+ for i = ypart z upto -5 : /(10) endfor /10000
+ fi)
+ fi
+enddef ;
+
+vardef Formgen_(expr q) =
+ clearxy ; (x,y) = q ;
+ if x = 0 : Formdec_
+ elseif y >= -6 : Formdec_
+ else : Formsci_
+ fi (q)
+enddef ;
+
+def Fset_item_(expr s) = %%% adapted by HH %%%
+ if s <> "" :
+ if fmt_metapost :
+ s infont defaultfont scaled defaultscale,
+ else :
+ s,
+ fi
+ fi
+enddef ;
+
+% For each format letter, the table below tells how to
+% round and typeset a quantity z in exponent form.
+%
+% e scientific, p significant figures
+% f decimal, p digits right of the point
+% g decimal or scientific, p sig. figs.
+% G decimal or scientific, p digits
+
+string fmt_[] ;
+
+fmt_[ASCII "e"] = "Formsci_(z Fprec_ p)" ;
+fmt_[ASCII "f"] = "Formdec_(z Fdigs_ p)" ;
+fmt_[ASCII "g"] = "Formgen_(z Fprec_ p)" ;
+fmt_[ASCII "G"] = "Formgen_(z Fdigs_ p)" ;
+
+% The format and Mformat macros take a format string f and
+% generate typeset output for a numeric quantity x. String f
+% should contain a `%' followed by an optional number and one
+% of the format letters defined above. The number should be
+% an integer giving the precision (default 3).
+
+vardef isfmtseparator primary c = %%% added by HH %%%
+ ((c <> fmt_separator) and (c <> "%"))
+enddef ;
+
+def initialize_form_numbers =
+ initialize_numbers ; % in context: do_initialize_numbers ;
+enddef ;
+
+vardef dofmt_@#(expr f, x) = %%% adapted by HH %%%
+ initialize_form_numbers ;
+ if f = "" :
+ if fmt_metapost : nullpicture else : "" fi
+ else :
+ interim warningcheck := 0 ;
+ save k, l, s, p, z ;
+ pair z ; z = @#(x) ;
+ % the next adaption is okay
+ % k = 1 + cspan(f, fmt_separator <> ) ;
+ % but best is to support both % and fmt_separator
+ k = 1 + cspan(f, isfmtseparator) ;
+ %
+ l-k = cspan(substring(k,infinity) of f, isdigit) ;
+ p = if l > k :
+ scantokens substring(k,l) of f
+ else :
+ fmt_precision
+ fi ;
+ string s ; s = fmt_[ASCII substring (l,l+1) of f] ;
+ if unknown s :
+ if k <= length f :
+ errmessage("No valid format letter found in "&f) ;
+ fi
+ s = if fmt_metapost : "nullpicture" else : "" fi ;
+ fi
+ Fline_up_
+ (Fset_item_(substring (0,k-1) of f)
+ if not fmt_metapost : sFebmath_, fi
+ scantokens s,
+ if not fmt_metapost : sFeemath_, fi
+ Fset_item_(substring (l+1,infinity) of f)
+ if fmt_metapost : nullpicture else : "" fi)
+ fi
+ hide (fmt_metapost := true)
+enddef ;
+
+%%% so far %%%
+
+vardef format (expr f, x) =
+ fmt_metapost := true ; dofmt_.Feform_(f,x)
+enddef ;
+
+vardef Mformat(expr f, x) =
+ fmt_metapost := true ; dofmt_.Meform (f,x)
+enddef ;
+
+vardef formatstr (expr f, x) =
+ fmt_metapost := false ; dofmt_.Feform_(f,x)
+enddef ;
+
+vardef Mformatstr(expr f, x) =
+ fmt_metapost := false ; dofmt_.Meform (f,x)
+enddef ;
+
+% Restore warningcheck to previous value.
+
+endgroup ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-func.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-func.mpii
new file mode 100644
index 00000000000..94e400b91a2
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-func.mpii
@@ -0,0 +1,58 @@
+%D \module
+%D [ file=mp-func.mpii,
+%D version=2001.12.29,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=function hacks,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+%D Under construction.
+
+if known context_func : endinput ; fi ;
+
+boolean context_func ; context_func := true ;
+
+string pathconnectors[] ;
+
+pathconnectors[0] := "," ;
+pathconnectors[1] := "--" ;
+pathconnectors[2] := ".." ;
+pathconnectors[3] := "..." ;
+
+vardef function (expr f) (expr u, t, b, e, s) = save x ; numeric x ;
+ for xx := b step s until e :
+ hide (x := xx ;) if xx>b : scantokens(pathconnectors[f]) fi
+ (scantokens(u),scantokens(t))
+ endfor
+enddef ;
+
+def punkedfunction = function (1) enddef ;
+def curvedfunction = function (2) enddef ;
+def tightfunction = function (3) enddef ;
+
+vardef constructedpath (expr f) (text t) =
+ save ok ; boolean ok ; ok := false ;
+ for i=t :
+ if ok : scantokens(pathconnectors[f]) else : ok := true ; fi i
+ endfor
+enddef ;
+
+def punkedpath = constructedpath (1) enddef ;
+def curvedpath = constructedpath (2) enddef ;
+def tightpath = constructedpath (3) enddef ;
+
+vardef constructedpairs (expr f) (text p) =
+ save i ; i := -1 ;
+ forever : exitif unknown p[incr(i)] ;
+ if i>0 : scantokens(pathconnectors[f]) fi p[i]
+ endfor
+enddef ;
+
+def punkedpairs = constructedpairs (1) enddef ;
+def curvedpairs = constructedpairs (2) enddef ;
+def tightpairs = constructedpairs (3) enddef ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-grid.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-grid.mpii
new file mode 100644
index 00000000000..ea28d60afd1
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-grid.mpii
@@ -0,0 +1,149 @@
+%D \module
+%D [ file=mp-grid.mpii,
+%D version=2000.07.10,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=grid support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+%D Under construction.
+
+if known context_grid : endinput ; fi ;
+
+boolean context_grid ; context_grid := true ;
+
+string fmt_separator ; fmt_separator := "@" ;
+numeric fmt_precision ; fmt_precision := 3 ;
+boolean fmt_initialize ; fmt_initialize := false ;
+boolean fmt_zerocheck ; fmt_zerocheck := true ;
+
+if unknown fmt_loaded : input "mp-form.mpii" ; fi ;
+
+boolean fmt_pictures ; fmt_pictures := true ;
+
+def do_format = if fmt_pictures : format else : formatstr fi enddef ;
+def do_mformat = if fmt_pictures : Mformat else : Mformatstr fi enddef ;
+
+numeric grid_eps ; grid_eps = eps ;
+
+def hlingrid (expr Min, Max, Step, Length, Width) text t =
+ image ( for i=Min step Step until Max+grid_eps :
+ draw (origin--(Width,0)) shifted (0,i*(Length/Max)) t ;
+ endfor ; ) ;
+enddef ;
+
+def vlingrid (expr Min, Max, Step, Length, Height) text t =
+ image ( for i=Min step Step until Max+grid_eps :
+ draw (origin--(0,Height)) shifted (i*(Length/Max),0) t ;
+ endfor ; ) ;
+enddef ;
+
+def hloggrid (expr Min, Max, Step, Length, Width) text t =
+ image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps :
+ draw (origin--(Width,0)) shifted (0,Length*log(i)) t ;
+ endfor ; ) ;
+enddef ;
+
+def vloggrid (expr Min, Max, Step, Length, Height) text t =
+ image ( for i=max(Min,1) step Step until min(Max,10)+grid_eps :
+ draw (origin--(0,Height)) shifted (Length*log(i),0) t ;
+ endfor ; ) ;
+enddef ;
+
+vardef hlintext@#(expr Min, Max, Step, Length, Format) text t =
+ image ( do_initialize_numbers ;
+ for i=Min step Step until Max+grid_eps :
+ draw textext@#(do_format(Format,i)) shifted (0,i*(Length/Max)) t ;
+ endfor ; )
+enddef ;
+
+vardef vlintext@#(expr Min, Max, Step, Length, Format) text t =
+ image ( do_initialize_numbers ;
+ for i=Min step Step until Max+grid_eps :
+ draw textext@#(do_format(Format,i)) shifted (i*(Length/Max),0) t ;
+ endfor ; )
+enddef ;
+
+vardef hlogtext@#(expr Min, Max, Step, Length, Format) text t =
+ image ( do_initialize_numbers ;
+ for i=max(Min,1) step Step until min(Max,10)+grid_eps :
+ draw textext@#(do_format(Format,i)) shifted (0,Length*log(i)) t ;
+ endfor ; )
+enddef ;
+
+vardef vlogtext@#(expr Min, Max, Step, Length, Format) text t =
+ image ( do_initialize_numbers ;
+ for i=max(Min,1) step Step until min(Max,10)+grid_eps :
+ draw textext@#(do_format(Format,i)) shifted (Length*log(i),0) t ;
+ endfor ; )
+enddef ;
+
+vardef hlinlabel@#(expr Min, Max, Step, Length) text t =
+ image (
+ for i=Min step Step until Max+grid_eps :
+ draw thelabel@#(decimal i,(0,i*(Length/Max))) t ;
+ endfor ; )
+enddef ;
+
+vardef vlinlabel@#(expr Min, Max, Step, Length) text t =
+ image (
+ for i=Min step Step until Max+grid_eps :
+ draw thelabel@#(decimal i,(i*(Length/Max),0)) t ;
+ endfor ; )
+enddef ;
+
+boolean numbers_initialized ; numbers_initialized := false ;
+
+def do_initialize_numbers =
+ if not numbers_initialized :
+ init_numbers ( textext.raw("$-$") ,
+ textext.raw("$1$") ,
+ textext.raw("${\times}10$") ,
+ textext.raw("${}^-$") ,
+ textext.raw("${}^2$") ) ;
+ if unknown _trial_run_ :
+ numbers_initialized := true ;
+ else :
+ % no reset, otherwise textexts get out of sync
+ % slows down graphics a bit but not much
+ fi ;
+ fi ;
+enddef ;
+
+def initialize_numbers =
+ numbers_initialized := false ; do_initialize_numbers ;
+enddef ;
+
+vardef linlog(expr xy) = ( xpart xy, log(ypart xy)) enddef ;
+vardef loglin(expr xy) = (log(xpart xy), ypart xy) enddef ;
+vardef loglog(expr xy) = (log(xpart xy), log(ypart xy)) enddef ;
+vardef linlin(expr xy) = ( (xpart xy), (ypart xy)) enddef ;
+
+vardef loglinpath primary p = processpath (p) (loglin) enddef ;
+vardef linlogpath primary p = processpath (p) (linlog) enddef ;
+vardef loglogpath primary p = processpath (p) (loglog) enddef ;
+vardef linlinpath primary p = processpath (p) (linlin) enddef ;
+
+def processpath (expr p) (text pp) =
+ if path p :
+ for i=0 upto length(p)-1 :
+ (pp(point i of p)) .. controls
+ (pp(postcontrol i of p)) and
+ (pp(precontrol (i+1) of p)) ..
+ endfor
+ if cycle p :
+ cycle
+ else :
+ (pp(point length(p) of p))
+ fi
+ elseif pair p :
+ (pp(p))
+ else :
+ p
+ fi
+enddef ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-grph.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-grph.mpii
new file mode 100644
index 00000000000..78294294624
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-grph.mpii
@@ -0,0 +1,310 @@
+%D \module
+%D [ file=mp-grph.mpii,
+%D version=2000.12.14,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=graphic text support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+%D Under construction.
+
+if known context_grph : endinput ; fi ;
+
+boolean context_grph ; context_grph := true ;
+
+string CRLF ; CRLF := char 10 & char 13 ;
+
+picture _currentpicture_ ;
+
+numeric _fig_nesting_ ; _fig_nesting_ := 0 ;
+
+def beginfig (expr c) =
+ _fig_nesting_ := _fig_nesting_ + 1 ;
+ if _fig_nesting_ = 1 :
+ begingroup
+ charcode := c ;
+ resetfig ;
+ scantokens extra_beginfig ;
+ fi ;
+enddef ;
+
+def endfig =
+ ; % safeguard
+ if _fig_nesting_ = 1 :
+ scantokens extra_endfig;
+ shipit ;
+ endgroup ;
+ fi ;
+ _fig_nesting_ := _fig_nesting_ - 1 ;
+enddef;
+
+
+def resetfig =
+ clearxy ;
+ clearit ;
+ clearpen ;
+ pickup defaultpen ;
+ interim linecap := linecap ;
+ interim linejoin := linejoin ;
+ interim miterlimit := miterlimit ;
+ save _background_ ; color _background_ ; _background_ := background ;
+ save background ; color background ; background := _background_ ;
+ drawoptions () ;
+enddef ;
+
+def protectgraphicmacros =
+ save showtext ;
+ save beginfig ; let beginfig = begingraphictextfig ;
+ save endfig ; let endfig = endgraphictextfig ;
+ save end ; let end = relax ;
+ interim prologues := prologues ;
+ resetfig ; % resets currentpicture
+enddef ;
+
+numeric currentgraphictext ; currentgraphictext := 0 ;
+string graphictextformat ; graphictextformat := "plain" ;
+string graphictextstring ; graphictextstring := "" ;
+string graphictextfile ; graphictextfile := "dummy.mpo" ;
+
+def data_mpo_file = job_name & "-mpgraph.mpo" enddef ;
+def data_mpy_file = job_name & "-mpgraph.mpy" enddef ;
+
+if unknown mplib :
+
+ def savegraphictext (expr str) =
+ if (graphictextstring<>"") :
+ write graphictextstring to data_mpo_file ;
+ graphictextstring := "" ;
+ fi ;
+ write str to data_mpo_file ;
+ let erasegraphictextfile = relax ;
+ enddef ;
+
+ def erasegraphictextfile =
+ write EOF to data_mpo_file ;
+ let erasegraphictextfile = relax ;
+ enddef ;
+
+ extra_beginfig := extra_beginfig & " erasegraphictextfile ;" ;
+
+fi ;
+
+def begingraphictextfig (expr n) =
+ foundpicture := n ; scratchpicture := nullpicture ;
+enddef ;
+
+def endgraphictextfig =
+ if foundpicture = currentgraphictext :
+ expandafter endinput
+ else :
+ scratchpicture := nullpicture ;
+ fi ;
+enddef ;
+
+def loadfigure primary filename =
+ doloadfigure (filename)
+enddef ;
+
+def doloadfigure (expr filename) text figureattributes =
+ begingroup ;
+ save figurenumber, figurepicture, number, fixedplace ;
+ numeric figurenumber ; figurenumber := 0 ;
+ boolean figureshift ; figureshift := true ;
+ picture figurepicture ; figurepicture := currentpicture ;
+ def number primary n = hide(figurenumber := n) enddef ;
+ def fixedplace = hide(figureshift := false) enddef ;
+ protectgraphicmacros ;
+ % defaults
+ interim linecap := rounded ;
+ interim linejoin := rounded ;
+ interim miterlimit := 10 ;
+ %
+ currentpicture := nullpicture ;
+ draw fullcircle figureattributes ; % expand number
+ currentpicture := nullpicture ;
+ def beginfig (expr n) =
+ currentpicture := nullpicture ;
+ if (figurenumber=n) or (figurenumber=0) :
+ let endfig = endinput ;
+ fi ;
+ enddef ;
+ let endfig = relax ;
+ readfile(filename) ;
+ if figureshift :
+ currentpicture := currentpicture shifted -llcorner currentpicture ;
+ fi ;
+ addto figurepicture also currentpicture figureattributes ;
+ currentpicture := figurepicture ;
+ endgroup ;
+enddef ;
+
+def graphictext primary t =
+ dographictext(t)
+enddef ;
+
+def dographictext (expr t) =
+ begingroup ;
+ save figurepicture ; picture figurepicture ;
+ figurepicture := currentpicture ; currentpicture := nullpicture ;
+ if graphictextformat<>"" :
+ graphictextstring :=
+ "% format=" & graphictextformat & CRLF & graphictextstring ;
+ graphictextformat := "" ;
+ fi ;
+ currentgraphictext := currentgraphictext + 1 ;
+ if unknown mplib :
+ savegraphictext ("\startTEXpage[scale=10000]" & t & "\stopTEXpage") ;
+ fi ;
+ dofinishgraphictext
+enddef ;
+
+def redographictext primary t =
+ regraphictext(t)
+enddef ;
+
+def regraphictext (expr t) =
+ begingroup ;
+ save figurepicture ; picture figurepicture ;
+ figurepicture := currentpicture ; currentpicture := nullpicture ;
+ save currentgraphictext ; numeric currentgraphictext ;
+ currentgraphictext := t ;
+ dofinishgraphictext
+enddef ;
+
+%D Believe it or not, but it took me half a day to uncover
+%D the following neccessity:
+%D
+%D \starttypen
+%D save withfillcolor, withdrawcolor ;
+%D \stoptypen
+%D
+%D When we have more than one graphictext, these will be
+%D defined after the first graphic. For some obscure reason,
+%D this means that in the next graphic they will be called, but
+%D afterwards the data and boolean are not set. Don't ask me
+%D why.
+
+def dofinishgraphictext text x_op_x =
+ protectgraphicmacros ; % resets currentpicture
+ interim linecap := butt ; % normally rounded
+ interim linejoin := mitered ; % normally rounded
+ interim miterlimit := 10 ; % todo
+ let normalwithshade = withshade ;
+ save foundpicture, scratchpicture, str ;
+ save fill, draw, withshade, reversefill, outlinefill ;
+ save withfillcolor, withdrawcolor ; % quite important
+ numeric foundpicture ; picture scratchpicture ; string str ;
+ def draw expr p =
+ % the first, naive implementation was:
+ % addto scratchpicture doublepath p withpen currentpen ;
+ % but it is better to turn lines into fills
+ addto scratchpicture contour boundingbox
+ image (addto currentpicture doublepath p withpen currentpen) ;
+ enddef ;
+ def fill expr p =
+ addto scratchpicture contour p withpen currentpen ;
+ enddef ;
+ def f_op_f = enddef ; boolean f_color ; f_color := false ;
+ def d_op_d = enddef ; boolean d_color ; d_color := false ;
+ def s_op_s = enddef ; boolean s_color ; s_color := false ;
+ boolean reverse_fill ; reverse_fill := false ;
+ boolean outline_fill ; outline_fill := false ;
+ def reversefill =
+ hide(reverse_fill := true )
+ enddef ;
+ def outlinefill =
+ hide(outline_fill := true )
+ enddef ;
+ def withshade primary c =
+ hide(def s_op_s = normalwithshade c enddef ; s_color := true )
+ enddef ;
+ def withfillcolor primary c =
+ hide(def f_op_f = withcolor c enddef ; f_color := true )
+ enddef ;
+ def withdrawcolor primary c =
+ hide(def d_op_d = withcolor c enddef ; d_color := true )
+ enddef ;
+ scratchpicture := nullpicture ;
+ addto scratchpicture doublepath origin x_op_x ; % pre-roll
+ for i within scratchpicture : % Below here is a dirty tricky test!
+ if (urcorner dashpart i) = origin : outline_fill := false ; fi ;
+ endfor ;
+ scratchpicture := nullpicture ;
+ readfile(data_mpy_file) ;
+ scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ;
+ if not d_color and not f_color : d_color := true ; fi
+ if s_color : d_color := false ; f_color := false ; fi ;
+ currentpicture := figurepicture ;
+ if d_color and not reverse_fill :
+ for i within scratchpicture :
+ if f_color and outline_fill :
+ addto currentpicture doublepath pathpart i _op_ x_op_x f_op_f
+ dashed nullpicture ;
+ fi ;
+ if filled i :
+ addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ;
+ fi ;
+ endfor ;
+ fi ;
+ if f_color :
+ for i within scratchpicture :
+ if filled i :
+ addto currentpicture contour pathpart i _op_ x_op_x f_op_f
+ withpen pencircle scaled 0 ;
+ fi ;
+ endfor ;
+ fi ;
+ if d_color and reverse_fill :
+ for i within scratchpicture :
+ if filled i :
+ addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ;
+ fi ;
+ endfor ;
+ fi ;
+ if s_color :
+ for i within scratchpicture :
+ if filled i :
+ addto currentpicture contour pathpart i _op_ x_op_x s_op_s ;
+ fi ;
+ endfor ;
+ else :
+ for i within scratchpicture :
+ if stroked i :
+ addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ;
+ fi ;
+ endfor ;
+ fi ;
+ endgroup ;
+enddef ;
+
+def resetgraphictextdirective =
+ graphictextstring := "" ;
+enddef ;
+
+def graphictextdirective text t =
+ graphictextstring := graphictextstring & t & CRLF ;
+enddef ;
+
+% example
+%
+% % graphictextformat := "context" ;
+% % graphictextformat := "plain" ;
+%
+% beginfig (1) ;
+% graphictext
+% "\vbox{\hsize10cm \input tufte }"
+% scaled 8
+% withdrawcolor blue
+% withfillcolor red
+% withpen pencircle scaled 2pt ;
+% endfig ;
+%
+% beginfig(1) ;
+% loadfigure "gracht.mp" rotated 20 ;
+% loadfigure "koe.mp" number 1 scaled 2 ;
+% endfig ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-page.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-page.mpii
new file mode 100644
index 00000000000..456ee61cc31
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-page.mpii
@@ -0,0 +1,659 @@
+%D \module
+%D [ file=mp-page.mpii,
+%D version=1999.03.10,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=page enhancements,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module is rather preliminary and subjected to
+%D changes.
+
+if known context_page : endinput ; fi ;
+
+boolean context_page ; context_page := true ;
+
+if unknown PageStateAvailable :
+ boolean PageStateAvailable ; PageStateAvailable := false ;
+fi ;
+
+if unknown OnRightPage :
+ boolean OnRightPage ; OnRightPage := true ;
+fi ;
+
+if unknown OnOddPage :
+ boolean OnOddPage ; OnOddPage := true ;
+fi ;
+
+if unknown InPageBody :
+ boolean InPageBody ; InPageBody := false ;
+fi ;
+
+def SaveTextAreas =
+ path SavedTextAreas [] ;
+ path SavedTextColumns[] ;
+ numeric NOfSavedTextAreas ;
+ numeric NOfSavedTextColumns ;
+ for i=1 upto NOfTextAreas :
+ SavedTextAreas[i] := TextAreas[i] ;
+ endfor ;
+ for i=1 upto NOfTextColumns :
+ SavedTextColumns[i] := TextColumns[i] ;
+ endfor ;
+ NOfSavedTextAreas := NOfTextAreas ;
+ NOfSavedTextColumns := NOfTextColumns ;
+enddef ;
+
+def ResetTextAreas =
+ path TextAreas[], TextColumns[] ;
+ numeric NOfTextAreas ; NOfTextAreas := 0 ;
+ numeric NOfTextColumns ; NOfTextColumns := 0 ;
+ numeric nofmultipars ; nofmultipars := 0 ;
+ TextAreas[0] := TextColumns[0] := origin -- cycle ;
+enddef ;
+
+ResetTextAreas ; SaveTextAreas ; ;
+
+def RegisterTextArea (expr x, y, w, h, d) =
+ begingroup ; save p ; path p ;
+ p := unitsquare xyscaled(w,h+d) shifted (x,y-d) ;
+ if NOfTextAreas>0 :
+ % if needed, concatenate areas
+ if (round(llcorner TextAreas[NOfTextAreas]) = round(ulcorner p)) and
+ (round(lrcorner TextAreas[NOfTextAreas]) = round(urcorner p)) :
+ p := ulcorner TextAreas[NOfTextAreas] --
+ urcorner TextAreas[NOfTextAreas] --
+ lrcorner p --
+ llcorner p --
+ cycle ;
+ else :
+ NOfTextAreas := NOfTextAreas + 1 ;
+ fi ;
+ else :
+ NOfTextAreas := NOfTextAreas + 1 ;
+ fi ;
+ TextAreas[NOfTextAreas] := p ;
+ if NOfTextColumns>0 :
+ if (round(xpart llcorner TextColumns[NOfTextColumns]) = round(xpart ulcorner p)) and
+ (round(xpart lrcorner TextColumns[NOfTextColumns]) = round(xpart urcorner p)) :
+ p := ulcorner TextColumns[NOfTextColumns] --
+ urcorner TextColumns[NOfTextColumns] --
+ lrcorner p --
+ llcorner p --
+ cycle ;
+ else :
+ NOfTextColumns := NOfTextColumns + 1 ;
+ fi ;
+ else :
+ NOfTextColumns := NOfTextColumns + 1 ;
+ fi ;
+ TextColumns[NOfTextColumns] := p ;
+ endgroup ;
+enddef ;
+
+%D We store a local area in slot zero.
+
+def RegisterLocalTextArea (expr x, y, w, h, d) =
+ TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ;
+enddef ;
+
+def ResetLocalTextArea =
+ TextAreas[0] := TextColumns[0] := origin -- cycle ;
+enddef ;
+
+ResetLocalTextArea ;
+
+vardef InsideTextArea (expr _i_, _xy_) =
+ ( (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and
+ (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and
+ (round(ypart _xy_) >= round(ypart llcorner TextAreas[_i_])) and
+ (round(ypart _xy_) <= round(ypart urcorner TextAreas[_i_])) )
+enddef ;
+
+vardef InsideSavedTextArea (expr _i_, _xy_) =
+ ( (round(xpart _xy_) >= round(xpart llcorner SavedTextAreas[_i_])) and
+ (round(xpart _xy_) <= round(xpart lrcorner SavedTextAreas[_i_])) and
+ (round(ypart _xy_) >= round(ypart llcorner SavedTextAreas[_i_])) and
+ (round(ypart _xy_) <= round(ypart urcorner SavedTextAreas[_i_])) )
+enddef ;
+
+vardef InsideSomeTextArea (expr _xy_) =
+ save ok ; boolean ok ; ok := false ;
+ for i := 1 upto NOfTextAreas :
+ if InsideTextArea(i,_xy_) : ok := true ; fi ;
+ exitif ok ;
+ endfor ;
+ ok
+enddef ;
+
+vardef InsideSomeSavedTextArea (expr _xy_) =
+ save ok ; boolean ok ; ok := false ;
+ for i := 1 upto NOfSavedTextAreas :
+ if InsideSavedTextArea(i,_xy_) : ok := true ; fi ;
+ exitif ok ;
+ endfor ;
+ ok
+enddef ;
+
+vardef TextAreaX (expr x) =
+ numeric _TextAreaX_ ; _TextAreaX_ := 0 ;
+ for i := 1 upto NOfTextAreas :
+ if (round(x) >= round(xpart llcorner TextAreas[i])) and
+ (round(x) <= round(xpart lrcorner TextAreas[i])) :
+ _TextAreaX_ := xpart llcorner TextAreas[i] ;
+ fi ;
+ endfor ;
+ _TextAreaX_
+enddef ;
+
+vardef TextAreaY (expr y) =
+ numeric _TextAreaY_ ; _TextAreaY_ := 0 ;
+ for i := 1 upto NOfTextAreas :
+ if (round(y) >= round(ypart llcorner TextAreas[NOfTextAreas])) and
+ (round(y) <= round(ypart ulcorner TextAreas[NOfTextAreas])) :
+ _TextAreaY_ := ypart llcorner TextAreas[NOfTextAreas] ;
+ fi ;
+ endfor ;
+ _TextAreaY_
+enddef ;
+
+vardef TextAreaXY (expr x, y) =
+ pair _TextAreaXY_ ; _TextAreaXY_ := origin ;
+ for i := 1 upto NOfTextAreas :
+ if (round(x) >= round(xpart llcorner TextAreas[i])) and
+ (round(x) <= round(xpart lrcorner TextAreas[i])) and
+ (round(y) >= round(ypart llcorner TextAreas[i])) and
+ (round(y) <= round(ypart ulcorner TextAreas[i])) :
+ _TextAreaXY_ := llconer TextAreas[i] ;
+ fi ;
+ endfor ;
+ _TextAreaXY_
+enddef ;
+
+vardef TextAreaW (expr x) =
+ numeric _TextAreaW_ ; _TextAreaW_ := 0 ;
+ for i := 1 upto NOfTextAreas :
+ if (round(x) >= round(xpart llcorner TextAreas[i])) and
+ (round(x) <= round(xpart lrcorner TextAreas[i])) :
+ _TextAreaW_ := bbwidth(TextAreas[i]) ;
+ fi ;
+ endfor ;
+ _TextAreaW_
+enddef ;
+
+vardef TextAreaH (expr y) =
+ numeric _TextAreaH_ ; _TextAreaH_ := 0 ;
+ for i := 1 upto NOfTextAreas :
+ if (round(y) >= round(ypart llcorner TextAreas[i])) and
+ (round(y) <= round(ypart ulcorner TextAreas[i])) :
+ _TextAreaH_ := bbheight(TextAreas[i]) ;
+ fi ;
+ endfor ;
+ _TextAreaH_
+enddef ;
+
+vardef TextAreaWH (expr x, y) =
+ pair _TextAreaWH_ ; _TextAreaWH_ := origin ;
+ for i := 1 upto NOfTextAreas :
+ if (round(x) >= round(xpart llcorner TextAreas[i])) and
+ (round(x) <= round(xpart lrcorner TextAreas[i])) and
+ (round(y) >= round(ypart llcorner TextAreas[i])) and
+ (round(y) <= round(ypart ulcorner TextAreas[i])) :
+ _TextAreaWH_ := (bbwidth(TextAreas[i]),bbheight(TextAreas[i])) ;
+ fi ;
+ endfor ;
+ _TextAreaWH_
+enddef ;
+
+string CurrentLayout ;
+
+CurrentLayout := "default" ;
+
+PageNumber := 0 ;
+PaperHeight := 845.04684pt ;
+PaperWidth := 597.50787pt ;
+PrintPaperHeight := 845.04684pt ;
+PrintPaperWidth := 597.50787pt ;
+TopSpace := 71.12546pt ;
+BottomSpace := 0.0pt ;
+BackSpace := 71.13275pt ;
+CutSpace := 0.0pt ;
+MakeupHeight := 711.3191pt ;
+MakeupWidth := 426.78743pt ;
+TopHeight := 0.0pt ;
+TopDistance := 0.0pt ;
+HeaderHeight := 56.90294pt ;
+HeaderDistance := 0.0pt ;
+TextHeight := 597.51323pt ;
+FooterDistance := 0.0pt ;
+FooterHeight := 56.90294pt ;
+BottomDistance := 0.0pt ;
+BottomHeight := 0.0pt ;
+LeftEdgeWidth := 0.0pt ;
+LeftEdgeDistance := 0.0pt ;
+LeftMarginWidth := 75.58197pt ;
+LeftMarginDistance := 11.99829pt ;
+TextWidth := 426.78743pt ;
+RightMarginDistance := 11.99829pt ;
+RightMarginWidth := 75.58197pt ;
+RightEdgeDistance := 0.0pt ;
+RightEdgeWidth := 0.0pt ;
+
+PageOffset := 0.0pt ;
+PageDepth := 0.0pt ;
+
+LayoutColumns := 0 ;
+LayoutColumnDistance:= 0.0pt ;
+LayoutColumnWidth := 0.0pt ;
+
+LeftEdge := -4 ; Top := -40 ;
+LeftEdgeSeparator := -3 ; TopSeparator := -30 ;
+LeftMargin := -2 ; Header := -20 ;
+LeftMarginSeparator := -1 ; HeaderSeparator := -10 ;
+Text := 0 ; Text := 0 ;
+RightMarginSeparator := +1 ; FooterSeparator := +10 ;
+RightMargin := +2 ; Footer := +20 ;
+RightEdgeSeparator := +3 ; BottomSeparator := +30 ;
+RightEdge := +4 ; Bottom := +40 ;
+
+Margin := LeftMargin ; % obsolete
+Edge := LeftEdge ; % obsolete
+InnerMargin := RightMargin ; % obsolete
+InnerEdge := RightEdge ; % obsolete
+OuterMargin := LeftMargin ; % obsolete
+OuterEdge := LeftEdge ; % obsolete
+
+InnerMarginWidth := 0pt ;
+OuterMarginWidth := 0pt ;
+InnerMarginDistance := 0pt ;
+OuterMarginDistance := 0pt ;
+
+InnerEdgeWidth := 0pt ;
+OuterEdgeWidth := 0pt ;
+InnerEdgeDistance := 0pt ;
+OuterEdgeDistance := 0pt ;
+
+path Area [][] ; pair Location [][] ; path Field [][] ; path Page ;
+numeric HorPos ; numeric Hstep [] ; numeric Hsize [] ;
+numeric VerPos ; numeric Vstep [] ; numeric Vsize [] ;
+
+for VerPos=Top step 10 until Bottom:
+ for HorPos=LeftEdge step 1 until RightEdge:
+ Area[HorPos][VerPos] := origin--cycle ;
+ Area[VerPos][HorPos] := Area[HorPos][VerPos] ;
+ Location[HorPos][VerPos] := origin ;
+ Location[VerPos][HorPos] := Location[HorPos][VerPos] ;
+ Field[HorPos][VerPos] := origin--cycle ;
+ Field[VerPos][HorPos] := Field[HorPos][VerPos] ;
+ endfor ;
+endfor ;
+
+% def LoadPageState =
+% scantokens "input mp-state.tmp" ;
+% enddef ;
+
+def SwapPageState =
+ if not OnRightPage :
+ BackSpace := PaperWidth-MakeupWidth-BackSpace ;
+ CutSpace := PaperWidth-MakeupWidth-CutSpace ;
+ i := LeftMarginWidth ;
+ LeftMarginWidth := RightMarginWidth ;
+ RightMarginWidth := i ;
+ i := LeftMarginDistance ;
+ LeftMarginDistance := RightMarginDistance ;
+ RightMarginDistance := i ;
+ i := LeftEdgeWidth ;
+ LeftEdgeWidth := RightEdgeWidth ;
+ RightEdgeWidth := i ;
+ i := LeftEdgeDistance ;
+ LeftEdgeDistance := RightEdgeDistance ;
+ RightEdgeDistance := i ;
+
+% these are now available as ..Width and ..Distance
+
+ Margin := LeftMargin ;
+ Edge := LeftEdge ;
+ InnerMargin := RightMargin ;
+ InnerEdge := RightEdge ;
+ OuterMargin := LeftMargin ;
+ OuterEdge := LeftEdge ;
+ else :
+ Margin := RightMargin ;
+ Edge := RightEdge ;
+ InnerMargin := LeftMargin ;
+ InnerEdge := LeftEdge ;
+ OuterMargin := RightMargin ;
+ OuterEdge := RightEdge ;
+ fi ;
+enddef ;
+
+def SetPageAreas =
+
+ numeric Vsize[], Hsize[], Vstep[], Hstep[] ;
+
+ Vsize[Top] = TopHeight ;
+ Vsize[TopSeparator] = TopDistance ;
+ Vsize[Header] = HeaderHeight ;
+ Vsize[HeaderSeparator] = HeaderDistance ;
+ Vsize[Text] = TextHeight ;
+ Vsize[FooterSeparator] = FooterDistance ;
+ Vsize[Footer] = FooterHeight ;
+ Vsize[BottomSeparator] = BottomDistance ;
+ Vsize[Bottom] = BottomHeight ;
+
+ Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ;
+ Vstep[TopSeparator] = PaperHeight-TopSpace ;
+ Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ;
+ Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ;
+ Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ;
+ Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ;
+ Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ;
+ Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ;
+ Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ;
+
+ Hsize[LeftEdge] = LeftEdgeWidth ;
+ Hsize[LeftEdgeSeparator] = LeftEdgeDistance ;
+ Hsize[LeftMargin] = LeftMarginWidth ;
+ Hsize[LeftMarginSeparator] = LeftMarginDistance ;
+ Hsize[Text] = MakeupWidth ;
+ Hsize[RightMarginSeparator] = RightMarginDistance ;
+ Hsize[RightMargin] = RightMarginWidth ;
+ Hsize[RightEdgeSeparator] = RightEdgeDistance ;
+ Hsize[RightEdge] = RightEdgeWidth ;
+
+ Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ;
+ Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ;
+ Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ;
+ Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ;
+ Hstep[Text] = BackSpace ;
+ Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ;
+ Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ;
+ Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ;
+ Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ;
+
+ for VerPos=Top step 10 until Bottom:
+ for HorPos=LeftEdge step 1 until RightEdge:
+ Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ;
+ Area[VerPos][HorPos] := Area[HorPos][VerPos] ;
+ Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ;
+ Location[VerPos][HorPos] := Location[HorPos][VerPos] ;
+ Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ;
+ Field[VerPos][HorPos] := Field[HorPos][VerPos] ;
+ endfor ;
+ endfor ;
+
+ Page := unitsquare xscaled PaperWidth yscaled PaperHeight ;
+
+enddef ;
+
+def BoundPageAreas =
+
+ % pickup pencircle scaled 0pt ;
+
+ bboxmargin := 0 ; setbounds currentpicture to Page ;
+
+enddef ;
+
+def StartPage =
+
+ begingroup ;
+
+ if PageStateAvailable :
+ LoadPageState ;
+ SwapPageState ;
+ fi ;
+
+ SetPageAreas ;
+ BoundPageAreas ;
+
+enddef ;
+
+def StopPage =
+
+ BoundPageAreas ;
+
+ endgroup ;
+
+enddef ;
+
+def OverlayBox =
+ (unitsquare xyscaled (OverlayWidth,OverlayHeight))
+enddef ;
+
+% handy
+
+def innerenlarged =
+ hide(LoadPageState)
+ if OnRightPage : leftenlarged else : rightenlarged fi
+enddef ;
+
+def outerenlarged =
+ hide(LoadPageState)
+ if OnRightPage : rightenlarged else : leftenlarged fi
+enddef ;
+
+% obsolete
+
+def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ;
+def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ;
+def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ;
+def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ;
+
+def Enlarged (expr p, d) =
+ (llEnlarged (p,d) --
+ lrEnlarged (p,d) --
+ urEnlarged (p,d) --
+ ulEnlarged (p,d) -- cycle)
+enddef ;
+
+% New:
+
+def position_anchor_bar(expr p_b_self, p_e_self, y_b_self, y_e_self, h_b_self, d_e_self,
+ distance, linewidth, linecolor) =
+ StartPage ;
+ path p ; p :=
+ if p_b_self=p_e_self :
+ (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) --
+ (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ;
+ elseif RealPageNumber=p_b_self :
+ (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) --
+ (llcorner Field[Text][Text]) ;
+ elseif RealPageNumber=p_e_self :
+ (ulcorner Field[Text][Text]) --
+ (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ;
+ else :
+ (ulcorner Field[Text][Text]) --
+ (llcorner Field[Text][Text]) ;
+ fi ;
+ p := p shifted (-llcorner Field[Text][Text]-(distance,0)) ;
+ interim linecap := butt ;
+ draw p
+ withpen pencircle scaled linewidth
+ withcolor linecolor ;
+ StopPage ;
+enddef ;
+
+% Crop stuff
+
+vardef crop_marks_lines (expr box, length, offset, nx, ny) =
+ save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ;
+ p := image (
+ x := if nx = 0 : 1 else : nx - 1 fi ;
+ y := if ny = 0 : 1 else : ny - 1 fi ;
+ w := bbwidth (box) / x ;
+ h := bbheight(box) / y ;
+ for i=0 upto y :
+ draw ((llcorner box) -- (llcorner box) shifted (-length,0)) shifted (-offset,i*h) ;
+ draw ((lrcorner box) -- (lrcorner box) shifted ( length,0)) shifted ( offset,i*h) ;
+ endfor ;
+ for i=0 upto x :
+ draw ((llcorner box) -- (llcorner box) shifted (0,-length)) shifted (i*w,-offset) ;
+ draw ((ulcorner box) -- (ulcorner box) shifted (0, length)) shifted (i*w, offset) ;
+ endfor ;
+ ) ;
+ setbounds p to box ;
+ p
+enddef ;
+
+vardef crop_marks_cmyk =
+ save p ; picture p ; p := image (
+ fill ulcircle scaled 12.5 withcolor (1,0,0,0) ;
+ fill urcircle scaled 12.5 withcolor (0,1,0,0) ;
+ fill lrcircle scaled 12.5 withcolor (0,0,1,0) ;
+ fill llcircle scaled 12.5 withcolor (0,0,0,1) ;
+ draw (-10,0) -- (10,0) ;
+ draw (0,-10) -- (0,10) ;
+ draw fullcircle scaled 12.5 ;
+ ) ;
+ setbounds p to fullsquare scaled 20 ;
+ p
+enddef ;
+
+vardef crop_marks_gray =
+ save p ; picture p ; p := image (
+ fill ulcircle scaled 12.5 withcolor (0.00) ;
+ fill urcircle scaled 12.5 withcolor (0.25) ;
+ fill lrcircle scaled 12.5 withcolor (0.50) ;
+ fill llcircle scaled 12.5 withcolor (0.75) ;
+ draw (-10,0) -- (10,0) ;
+ draw (0,-10) -- (0,10) ;
+ draw (-6,0) -- (6,0) withcolor white ;
+ draw (0,-6) -- (0,6) withcolor white ;
+ draw fullcircle scaled 12.5 ;
+ ) ;
+ setbounds p to fullsquare scaled 20 ;
+ p
+enddef ;
+
+vardef crop_marks_cmykrgb =
+ save p ; picture p ; p := image (
+ fill ulcircle scaled 15 withcolor (1,0,0) ;
+ fill urcircle scaled 15 withcolor (0,1,0) ;
+ fill lrcircle scaled 15 withcolor (0,0,1) ;
+ fill llcircle scaled 15 withcolor (.5,.5,.5) ;
+ fill ulcircle scaled 10 withcolor (1,0,0,0) ;
+ fill urcircle scaled 10 withcolor (0,1,0,0) ;
+ fill lrcircle scaled 10 withcolor (0,0,1,0) ;
+ fill llcircle scaled 10 withcolor (0,0,0,1) ;
+ draw (-10,0) -- (10,0) ;
+ draw (0,-10) -- (0,10) ;
+ draw fullcircle scaled 10 ;
+ draw fullcircle scaled 15 ;
+ ) ;
+ setbounds p to fullsquare scaled 20 ;
+ p
+enddef ;
+
+vardef crop_color(expr c, h, w, dx, dy, ts) =
+ image (
+ save p ; path p ;
+ for i=1 upto 6 :
+ p := fullsquare
+ xscaled w
+ yscaled h
+ shifted (dx,dy-i*h) ;
+ fill p
+ withcolor (crop_colors[i]*c) ;
+ draw textext("\format{'@0.2f'," & decimal crop_colors[i] & "}")
+ scaled ts
+ shifted center p withcolor white ;
+ endfor ;
+ )
+enddef ;
+
+vardef crop_gray(expr c, h, w, dx, dy, ts) =
+ image (
+ save p ; path p ;
+ for i=.05 step .05 until 1 :
+ p := fullsquare
+ xscaled w
+ yscaled h
+ shifted (20*(i-1)*w+dx,dy) ;
+ fill p
+ withcolor (i*c) ;
+ draw textext("\format{'@0.2f'," & decimal i & "}")
+ scaled ts
+ shifted center p withcolor white ;
+ endfor ;
+ )
+enddef ;
+
+% draw crop_marks_cmyk shifted llcorner more ;
+% draw crop_marks_cmyk shifted lrcorner more ;
+% draw crop_marks_cmyk shifted ulcorner more ;
+% draw crop_marks_cmyk shifted urcorner more ;
+
+def page_marks_add_color(expr width, height, length, offset) = % todo: namespace
+
+ path page ; page := fullsquare xscaled width yscaled height ;
+ path more ; more := page enlarged (offset+length/2,offset+length/2) ;
+
+ numeric crop_colors[] ;
+ crop_colors[1] := 1 ;
+ crop_colors[2] := 0.95 ;
+ crop_colors[3] := 0.75 ;
+ crop_colors[4] := 0.50 ;
+ crop_colors[5] := 0.25 ;
+ crop_colors[6] := 0.05 ;
+
+ numeric h ; h := height / 20 ;
+ numeric w ; w := width / 20 ;
+ numeric d ; d := offset + length/2 ;
+
+ draw crop_color((1,0,0,0),h,length,xpart ulcorner page - d, 10h,length/20) ;
+ draw crop_color((0,1,0,0),h,length,xpart ulcorner page - d,3.5h,length/20) ;
+ draw crop_color((0,0,1,0),h,length,xpart ulcorner page - d, -3h,length/20) ;
+
+ draw crop_color((0,1,1,0),h,length,xpart urcorner page + d, 10h,length/20) ;
+ draw crop_color((1,0,1,0),h,length,xpart urcorner page + d,3.5h,length/20) ;
+ draw crop_color((1,1,0,0),h,length,xpart urcorner page + d, -3h,length/20) ;
+
+ draw crop_gray((0,0,0,1),length, w,-xpart llcorner page,-ypart llcorner page + d ,w/20) ;
+ draw crop_gray((1,0,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d + 1length/3,w/20) ;
+ draw crop_gray((0,1,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 0length/3,w/20) ;
+ draw crop_gray((0,0,1,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 1length/3,w/20) ;
+
+ setbounds currentpicture to page ;
+
+enddef ;
+
+def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace
+
+ path page ; page := fullsquare xscaled width yscaled height ;
+ path more ; more := page enlarged (offset+length/2,offset+length/2) ;
+
+ draw crop_marks_gray shifted center(topboundary more) shifted (0, offset+length);
+ draw crop_marks_cmyk shifted center(bottomboundary more) shifted (0,-offset-length);
+
+ setbounds currentpicture to page ;
+
+enddef ;
+
+def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace
+
+ path page ; page := fullsquare xscaled width yscaled height ;
+ path more ; more := page enlarged (offset+length/2,offset+length/2) ;
+
+ draw crop_marks_lines(page,length,offset,nx,ny) ;
+
+ setbounds currentpicture to page ;
+
+enddef ;
+
+def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace
+
+ path page ; page := fullsquare xscaled width yscaled height ;
+ path more ; more := page enlarged (offset+length/2,offset+length/2) ;
+
+ for s=llcorner more, lrcorner more, ulcorner more, urcorner more :
+ draw textext(decimal n) shifted s ;
+ endfor ;
+
+ setbounds currentpicture to page ;
+
+enddef ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-shap.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-shap.mpii
new file mode 100644
index 00000000000..17d21314c32
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-shap.mpii
@@ -0,0 +1,206 @@
+%D \module
+%D [ file=mp-shap.mpii,
+%D version=2000.05.31,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=shapes,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+if known context_shap : endinput ; fi ;
+
+boolean context_shap ; context_shap := true ;
+
+path predefined_shapes[] ;
+
+begingroup ;
+
+save xradius, yradius, xxradius, yyradius ;
+save ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ;
+
+numeric xradius, yradius, xxradius, yyradius ;
+pair ll, lr, ur, ul, llx, lly, lrx, lry, urx, ury, ulx, uly, llxx, llyy, lrxx, lryy, urxx, uryy, ulxx, ulyy, lc, rc, tc, bc ;
+
+xradius := .15 ;
+yradius := .15 ;
+xxradius := .10 ;
+yyradius := .10 ;
+
+ll := llcorner (unitsquare shifted (-.5,-.5)) ;
+lr := lrcorner (unitsquare shifted (-.5,-.5)) ;
+ur := urcorner (unitsquare shifted (-.5,-.5)) ;
+ul := ulcorner (unitsquare shifted (-.5,-.5)) ;
+
+llx := ll shifted (xradius,0) ;
+lly := ll shifted (0,yradius) ;
+
+lrx := lr shifted (-xradius,0) ;
+lry := lr shifted (0,yradius) ;
+
+urx := ur shifted (-xradius,0) ;
+ury := ur shifted (0,-yradius) ;
+
+ulx := ul shifted (xradius,0) ;
+uly := ul shifted (0,-yradius) ;
+
+llxx := ll shifted (xxradius,0) ;
+llyy := ll shifted (0,yyradius) ;
+
+lrxx := lr shifted (-xxradius,0) ;
+lryy := lr shifted (0,yyradius) ;
+
+urxx := ur shifted (-xxradius,0) ;
+uryy := ur shifted (0,-yyradius) ;
+
+ulxx := ul shifted (xxradius,0) ;
+ulyy := ul shifted (0,-yyradius) ;
+
+lc := ll shifted (0,.5) ;
+rc := lr shifted (0,.5) ;
+tc := ul shifted (.5,0) ;
+bc := ll shifted (.5,0) ;
+
+predefined_shapes[ 0] := (origin--cycle) ;
+predefined_shapes[ 5] := (llx--lrx{right}...rc...{left}urx--ulx{left}...lc...{right}cycle) ;
+predefined_shapes[ 6] := (ll--lrx{right}...rc...{left}urx--ul--cycle) ;
+predefined_shapes[ 7] := (ll--lrx{right}...rc...{left}urx--ul--cycle) rotatedaround(origin,180) ;
+predefined_shapes[ 8] := (lr--ury{up}...tc...{down}uly--ll--cycle) ;
+predefined_shapes[ 9] := (lr--ury{up}...tc...{down}uly--ll--cycle) rotatedaround(origin,180) ;
+predefined_shapes[10] := (ll--lr--ur--ul--ll--ur--ul--ll--cycle) ;
+predefined_shapes[11] := (ll--lr--ur--ul--ll--lr--ul--ll--cycle) ;
+predefined_shapes[12] := (ll--lrx--ur--ulx--cycle) ;
+predefined_shapes[13] := (llx--lr--urx--ul--cycle) ;
+predefined_shapes[14] := (lly--bc--lry--ury--tc--uly--cycle) ;
+predefined_shapes[15] := (llx--lrx--rc--urx--ulx--lc--cycle) ;
+predefined_shapes[16] := (ll--lrx--rc--urx--ul--cycle) ;
+predefined_shapes[17] := (ll--lrx--rc--urx--ul--cycle) rotatedaround(origin,180) ;
+predefined_shapes[18] := (lr--ury--tc--uly--ll--cycle) ;
+predefined_shapes[19] := (lr--ury--tc--uly--ll--cycle) rotatedaround(origin,180) ;
+predefined_shapes[20] := (ll--lr--ur--ul--ll--llxx--ulxx--ul--ll--lr--ur--urxx--lrxx--cycle) ;
+predefined_shapes[21] := (ul--ll--lr--ur--ul--ulyy--uryy--ur--ul--ll--lr--lryy--llyy--cycle) ;
+predefined_shapes[22] := (ll--lrx--lry--ur--ulx--uly--cycle) ;
+predefined_shapes[23] := (llx--lr--ury--urx--ul--lly--cycle) ;
+predefined_shapes[24] := (ll--lr--ur--ul--cycle) ;
+predefined_shapes[25] := (llx--lrx--lry--ury--urx--ulx--uly--lly--cycle) ;
+predefined_shapes[26] := (ll--lrx--lry--ur--ul--cycle) ;
+predefined_shapes[27] := (ll--lr--ury--urx--ul--cycle) rotatedaround(origin,180) ;
+predefined_shapes[28] := (ll--lr--ury--urx--ul--cycle) ;
+predefined_shapes[29] := (ll--lrx--lry--ur--ul--cycle) rotatedaround(origin,180) ;
+predefined_shapes[30] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) rotated 45;
+predefined_shapes[31] := (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & bc--tc & tc{left}..{down}lc & lc--rc & rc{up}..tc{left}...{down}lc...{right}bc & cycle) ;
+predefined_shapes[32] := (ll{right}...{right}lry--ur--ul--ll--cycle) ;
+predefined_shapes[33] := (ll{right}...{right}lry--ur--ul--ll--cycle--ul--ulx--ulx shifted(0,yyradius)--ur shifted(yyradius,yyradius)--lry shifted(yyradius,yyradius)--lry shifted(0,yyradius)--ur--ul--cycle ) ;
+predefined_shapes[34] := (uly..tc..ury & ury..tc shifted (0,-2yradius)..uly & uly--lly & lly..bc..lry & lry--ury & ury..tc shifted (0,-2yradius)..uly & cycle ) ;
+predefined_shapes[35] := (bc{right}...rc{up}...tc{left}...lc{down}...cycle) ;
+predefined_shapes[36] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) ;
+predefined_shapes[37] := (ul--tc{right}..rc{down}..{left}bc--ll & ll..(xpart llx, ypart lc)..ul & cycle) rotatedaround(origin,180) ;
+predefined_shapes[38] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) ;
+predefined_shapes[39] := (ll--lc{up}..tc{right}..{down}rc--lr & lr..(xpart bc, ypart lly)..ll & cycle) rotatedaround(origin,180) ;
+predefined_shapes[40] := (ll--lr--ur--ul--ll--ur--ul--ll--lr--ul--ll--cycle) ;
+predefined_shapes[41] := (ll--lr--ur--ul--ll--lr--rc--lc--ll--bc--tc--ul--ll & cycle) ;
+predefined_shapes[42] := (ll--lr--origin shifted (+epsilon,0)--ur--ul--origin shifted (-epsilon,0)--cycle) ;
+predefined_shapes[43] := (ll--ul--origin shifted (0,+epsilon)--ur--lr--origin shifted (0,-epsilon)--cycle) ;
+predefined_shapes[45] := (bc--rc--tc--lc--cycle) ;
+predefined_shapes[46] := (ll--ul--rc--cycle) ;
+predefined_shapes[47] := (ll--ul--rc--cycle) rotatedaround(origin,180) ;
+predefined_shapes[48] := (ul--ur--bc--cycle) rotatedaround(origin,180) ;
+predefined_shapes[49] := (ul--ur--bc--cycle) ;
+predefined_shapes[56] := (ll--lry--ury--ul--cycle) ;
+predefined_shapes[57] := (ll--lry--ury--ul--cycle) rotatedaround(origin,180) ;
+predefined_shapes[58] := (ll--ulx--urx--lr--cycle) ;
+predefined_shapes[59] := (ll--ulx--urx--lr--cycle) rotatedaround(origin,180);
+predefined_shapes[66] := (rc--origin shifted ( epsilon,0) --cycle & rc--origin--cycle ) ;
+predefined_shapes[67] := (lc--origin shifted (-epsilon,0) --cycle & lc--origin--cycle ) ;
+predefined_shapes[68] := (tc--origin shifted (0, epsilon) --cycle & tc--origin--cycle ) ;
+predefined_shapes[69] := (bc--origin shifted (0,-epsilon) --cycle & bc--origin--cycle ) ;
+predefined_shapes[75] := (lly--lry--ury--uly--cycle) rotatedaround(origin,180) ;
+predefined_shapes[76] := (ll--lr--ur--uly--cycle) rotatedaround(origin,180) ;
+predefined_shapes[77] := (ll--lr--ury--ul--cycle) rotatedaround(origin,180) ;
+predefined_shapes[78] := (lly--lr--ur--ul--cycle) rotatedaround(origin,180) ;
+predefined_shapes[79] := (ll--lry--ur--ul--cycle) rotatedaround(origin,180) ;
+
+numeric predefined_shapes_xradius ; predefined_shapes_xradius := xradius ;
+numeric predefined_shapes_yradius ; predefined_shapes_yradius := yradius ;
+numeric predefined_shapes_xxradius ; predefined_shapes_xxradius := xxradius ;
+numeric predefined_shapes_yyradius ; predefined_shapes_yyradius := yyradius ;
+
+endgroup ;
+
+vardef some_shape_path (expr type) =
+ if known predefined_shapes[type] : predefined_shapes[type] else : predefined_shapes[0] fi
+enddef ;
+
+def some_shape (expr shape_type, shape_width, shape_height, shape_linewidth, shape_linecolor, shape_fillcolor) =
+ begingroup ;
+ save p ; path p ;
+ p := some_shape_path (shape_type) xscaled shape_width yscaled shape_height ;
+ pickup pencircle scaled shape_linewidth ;
+ fill p withcolor shape_fillcolor ;
+ draw p withcolor shape_linecolor ;
+ endgroup ;
+enddef ;
+
+vardef drawpredefinedshape (expr t, p, lw, lc, fc) =
+ save pp ;
+ if t>1 : % normal shape
+ path pp ;
+ pp := some_shape_path(t) xyscaled(bbwidth(p), bbheight(p)) shifted center p ;
+ fill pp withcolor fc ;
+ draw pp withpen pencircle scaled lw withcolor lc ;
+ elseif t=1 : % background only
+ path pp ;
+ pp := fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ;
+ fill pp withcolor fc ;
+ else : % dimensions only
+ picture pp ; pp := nullpicture ;
+ setbounds pp to fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ;
+ draw pp ;
+ fi ;
+enddef ;
+
+vardef drawpredefinedline (expr t, p, lw, lc) =
+ if (t>0) and (length(p)>1) :
+ saveoptions ;
+ drawoptions(withpen pencircle scaled lw withcolor lc) ;
+ draw p ;
+ if t = 1 :
+ draw arrowheadonpath(p,1) ;
+ elseif t = 2 :
+ draw arrowheadonpath(reverse p,1) ;
+ elseif t = 3 :
+ for $ = p,reverse p :
+ draw arrowheadonpath($,1) ;
+ endfor ;
+ elseif t = 11 :
+ draw arrowheadonpath(p,1/2) ;
+ elseif t = 12 :
+ draw arrowheadonpath(reverse p,1/2) ;
+ elseif t = 13 :
+ for $=p,reverse p :
+ draw arrowheadonpath($,1) ;
+ endfor ;
+ for $=p,reverse p :
+ draw arrowheadonpath($,3/4) ;
+ endfor ;
+ elseif t = 21 :
+ for $=1/5,1/2,4/5 :
+ draw arrowheadonpath(p,$) ;
+ endfor ;
+ elseif t = 22 :
+ for $=1/5,1/2,4/5 :
+ draw arrowheadonpath(reverse p,$) ;
+ endfor ;
+ elseif t = 23 :
+ for $=p,reverse p :
+ draw arrowheadonpath($,1/4) ;
+ endfor ;
+ fi ;
+ fi ;
+enddef ;
+
+let drawshape = drawpredefinedshape ;
+let drawline = drawpredefinedline ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-spec.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-spec.mpii
new file mode 100644
index 00000000000..19d81f31254
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-spec.mpii
@@ -0,0 +1,782 @@
+%D \module
+%D [ file=mp-spec.mpii,
+%D version=1999.6.26,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=special extensions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+% Spot colors are not handled by mptopdf !
+
+% let graycolor = numeric ;
+% let greycolor = numeric ;
+% let withanycolor = withcolor ;
+
+% rgbcolor red ; red := (1,0,0) ;
+% rgbcolor green ; green := (0,1,0) ;
+% rgbcolor blue ; blue := (0,0,1) ;
+% cmykcolor cyan ; cyan := (1,0,0,0) ;
+% cmykcolor magenta ; magenta := (0,1,0,0) ;
+% cmykcolor yellow ; yellow := (0,0,1,0) ;
+% graycolor black ; black := 0 ; % (0) ;
+% graycolor white ; white := 1 ; % (1) ;
+
+% primarydef p withcolor c =
+% p withanycolor (c)
+% enddef ;
+
+% fill fullcircle scaled 10cm withcolor cyan ;
+% fill fullcircle scaled 7cm withcolor red ;
+% fill fullcircle scaled 4cm withcolor white ;
+
+% (r,g,b) => cmyk : r=123 g= 1 b=hash
+% => spot : r=123 g= 2 b=hash
+% => transparent rgb : r=123 g= 3 b=hash
+% => transparent cmyk : r=123 g= 4 b=hash
+% => transparent spot : r=123 g= 5 b=hash
+% => rest : r=123 g=n>10 b=whatever
+
+%D This module is rather preliminary and subjected to
+%D changes. Here we closely cooperates with the \METAPOST\
+%D to \PDF\ converter module built in \CONTEXT\ and provides
+%D for instance shading. More information can be found in
+%D type {supp-mpe.tex}.
+
+if known context_spec : endinput ; fi ;
+
+boolean context_spec ; context_spec := true ;
+
+numeric _special_counter_ ; _special_counter_ := 0 ;
+numeric _color_counter_ ; _color_counter_ := 11 ; % < 10 reserved
+numeric _special_signal_ ; _special_signal_ := 123 ;
+
+numeric _special_div_ ; _special_div_ := 1000 ;
+
+%D When set to \type {true}, shading will be supported. Some
+%D day I will also write an additional directive.
+
+boolean _inline_specials_ ; _inline_specials_ := false ;
+
+%D Because we want to output only those specials that are
+%D actually used in a figure, we need a bit complicated
+%D bookkeeping and collection of specials. At the cost of some
+%D obscurity, we now have rather efficient resources.
+
+string _global_specials_ ; _global_specials_ := "" ;
+string _local_specials_ ; _local_specials_ := "" ;
+
+% vardef add_special_signal = % write the version number
+% if (length _global_specials_>0) or (length _local_specials_ >0) :
+% special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ;
+% fi ;
+% enddef ;
+%
+% After some reported problems at the \CONTEXT\ mailing list,
+% Taco's came up with:
+
+% TH: \quotation {Ok, got it. There is a bug in mp-spec.mp (inside metafun).
+% Because of a wrapping number, it fails to recognize the fact that there
+% are embedded specials at all.} The corrected definition is:
+
+vardef add_special_signal = % write the version number
+ if (length _global_specials_ <> 0) or (length _local_specials_ <> 0) :
+ special ("%%MetaPostSpecials: 2.0 " & decimal _special_signal_ & " " & decimal _special_div_) ;
+ fi ;
+enddef ;
+
+% \quotation {It now tests for \quote {not equal to zero} instead of
+% \quote {larger than zero}: because of all the included files, the
+% string \type {_local_specials_} becomes longer than the maximum number
+% \quote {length} can return, so it returns -32768 instead, and that is
+% of course less than zero.}
+
+vardef add_extra_specials =
+ scantokens _global_specials_ ;
+ scantokens _local_specials_ ;
+enddef ;
+
+vardef reset_extra_specials =
+ % only local ones
+ _local_specials_ := "" ;
+enddef ;
+
+boolean insidefigure ; insidefigure := false ;
+
+% todo: alleen als special gebruikt flush
+
+extra_beginfig :=
+ " insidefigure := true ; " &
+ " reset_extra_specials ; " &
+ extra_beginfig &
+ " ; " ;
+
+extra_endfig :=
+ " ; " &
+ " add_special_signal ; " &
+ extra_endfig &
+ " add_extra_specials ; " &
+ " reset_extra_specials ; " &
+ " insidefigure := false ; " ;
+
+def set_extra_special (expr s) =
+ if insidefigure :
+ _local_specials_ := _local_specials_ & s ;
+ else :
+ _global_specials_ := _global_specials_ & s ;
+ fi
+enddef ;
+
+def flush_special (expr typ, siz, dat) =
+ _special_counter_ := _special_counter_ + 1 ;
+ if _inline_specials_ :
+ set_extra_special
+ ( "special "
+ & "(" & ditto
+ & dat & " "
+ & decimal _special_counter_ & " "
+ & decimal typ & " "
+ & decimal siz
+ & " special"
+ & ditto & ");" ) ;
+ else :
+ set_extra_special
+ ( "special "
+ & "(" & ditto
+ & "%%MetaPostSpecial: "
+ & decimal siz & " "
+ & dat & " "
+ & decimal _special_counter_ & " "
+ & decimal typ
+ & ditto & ");" ) ;
+ fi ;
+enddef ;
+
+%D The next hack is needed in case you use a version of
+%D \METAPOST\ that does not provide you the means to configure
+%D the buffer size. Patrick Gundlach suggested to use arrays
+%D in this case.
+
+boolean bufferhack ; bufferhack := false ; % true ;
+
+if bufferhack :
+
+ string _global_specials_[] ; numeric _nof_global_specials_ ;
+ string _local_specials_[] ; numeric _nof_local_specials_ ;
+
+ _nof_global_specials_ := _nof_local_specials_ := 0 ;
+
+ vardef add_special_signal = % write the version number
+ if (_nof_global_specials_>0) or (_nof_local_specials_>0) :
+ special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ;
+ fi ;
+ enddef ;
+
+ vardef add_extra_specials =
+ for i=1 upto _nof_global_specials_ :
+ scantokens _global_specials_[i] ;
+ endfor;
+ for i=1 upto _nof_local_specials_ :
+ scantokens _local_specials_[i] ;
+ endfor;
+ enddef ;
+
+ vardef reset_extra_specials =
+ string _local_specials_[] ; _nof_local_specials_ := 0 ;
+ enddef ;
+
+ def set_extra_special (expr s) =
+ if insidefigure :
+ _local_specials_[incr(_nof_local_specials_)] := s ;
+ else :
+ _global_specials_[incr(_nof_global_specials_)] := s ;
+ fi
+ enddef ;
+
+fi ;
+
+%D So far for this hack.
+
+%D Shade allocation.
+
+newinternal shadefactor ; shadefactor := 1 ;
+
+pair shadeoffset ; shadeoffset := origin ;
+
+% vardef define_linear_shade (expr a, b, ca, cb) =
+% flush_special(30, 15, "0 1 " & decimal shadefactor & " " &
+% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " &
+% dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ;
+% _special_counter_
+% enddef ;
+
+% vardef define_circular_shade (expr a, b, ra, rb, ca, cb) =
+% flush_special(31, 17, "0 1 " & decimal shadefactor & " " &
+% dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " &
+% dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ;
+% _special_counter_
+% enddef ;
+
+% these tests are not yet robust for new gray/cmyk features;
+%
+% - we need to get rid of cmykcolor() and
+
+vardef _is_cmyk_(expr c) =
+ (redpart c = _special_signal_/_special_div_) and (greenpart c = 1/_special_div_)
+enddef ;
+vardef _is_spot_(expr c) =
+ (redpart c = _special_signal_/_special_div_) and (greenpart c = 2/_special_div_)
+enddef ;
+vardef _is_gray_(expr c) =
+ (redpart c = greenpart c) and (greenpart c = bluepart c)
+enddef ;
+
+numeric mp_shade_version ; mp_shade_version := 2 ; % more colors, needs new backend
+
+vardef define_linear_shade (expr a, b, ca, cb) =
+ save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ;
+ save gray_a, gray_b ; boolean gray_a, gray_b ;
+ cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ;
+ cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ;
+ if (mp_shade_version > 1) and cmyk_a and cmyk_b :
+ flush_special(32, 17, "0 1 " & decimal shadefactor & " " &
+ cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " &
+ cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ;
+ elseif (mp_shade_version > 1) and cmyk_a and gray_b :
+ save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ;
+ flush_special(32, 17, "0 1 " & decimal shadefactor & " " &
+ cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " &
+ cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) ) ;
+ elseif (mp_shade_version > 1) and gray_a and cmyk_b :
+ save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ;
+ flush_special(32, 17, "0 1 " & decimal shadefactor & " " &
+ cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " &
+ cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ;
+ elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) :
+ flush_special(34, 17, "0 1 " & decimal shadefactor & " " &
+ spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " &
+ spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ;
+ else :
+ flush_special(30, 15, "0 1 " & decimal shadefactor & " " &
+ dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " &
+ dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ;
+ fi ;
+ _special_counter_
+enddef ;
+
+vardef define_circular_shade (expr a, b, ra, rb, ca, cb) =
+ save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ;
+ save gray_a, gray_b ; boolean gray_a, gray_b ;
+ cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ;
+ cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ;
+ if (mp_shade_version > 1) and cmyk_a and cmyk_b :
+ flush_special(33, 19, "0 1 " & decimal shadefactor & " " &
+ cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " &
+ cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ;
+ elseif (mp_shade_version > 1) and cmyk_a and gray_b :
+ save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ;
+ flush_special(33, 19, "0 1 " & decimal shadefactor & " " &
+ cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " &
+ cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ;
+ elseif (mp_shade_version > 1) and gray_a and cmyk_b :
+ save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ;
+ flush_special(33, 19, "0 1 " & decimal shadefactor & " " &
+ cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " &
+ cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ;
+ elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) :
+ flush_special(35, 19, "0 1 " & decimal shadefactor & " " &
+ spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " &
+ spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ;
+ else :
+ flush_special(31, 17, "0 1 " & decimal shadefactor & " " &
+ dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " &
+ dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ;
+ fi ;
+ _special_counter_
+enddef ;
+
+%D A few predefined shading macros.
+
+boolean trace_shades ; trace_shades := false ;
+
+% if (n=1) : a := llcorner p ; b := urcorner p ;
+% elseif (n=2) : a := llcorner p ; b := ulcorner p ;
+% elseif (n=3) : a := lrcorner p ; b := ulcorner p ;
+% else : a := llcorner p ; b := lrcorner p ;
+% fi ;
+
+def set_linear_vector (suffix a,b)(expr p,n) =
+ if (n=1) : a := llcorner p ;
+ b := urcorner p ;
+ elseif (n=2) : a := lrcorner p ;
+ b := ulcorner p ;
+ elseif (n=3) : a := urcorner p ;
+ b := llcorner p ;
+ elseif (n=4) : a := ulcorner p ;
+ b := lrcorner p ;
+ elseif (n=5) : a := .5[ulcorner p,llcorner p] ;
+ b := .5[urcorner p,lrcorner p] ;
+ elseif (n=6) : a := .5[llcorner p,lrcorner p] ;
+ b := .5[ulcorner p,urcorner p] ;
+ elseif (n=7) : a := .5[lrcorner p,urcorner p] ;
+ b := .5[llcorner p,ulcorner p] ;
+ elseif (n=8) : a := .5[urcorner p,ulcorner p] ;
+ b := .5[lrcorner p,llcorner p] ;
+ else : a := .5[ulcorner p,llcorner p] ;
+ b := .5[urcorner p,lrcorner p] ;
+ fi ;
+enddef ;
+
+def set_circular_vector (suffix ab, r)(expr p,n) =
+ if (n=1) : ab := llcorner p ;
+ elseif (n=2) : ab := lrcorner p ;
+ elseif (n=3) : ab := urcorner p ;
+ elseif (n=4) : ab := ulcorner p ;
+ else : ab := center p ; r := .5r ;
+ fi ;
+enddef ;
+
+def linear_shade (expr p, n, ca, cb) =
+ begingroup ;
+ save a, b, sh ; pair a, b ;
+ set_linear_vector(a,b)(p,n) ;
+ fill p withshade define_linear_shade (a,b,ca,cb) ;
+ if trace_shades :
+ drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ;
+ fi ;
+ endgroup ;
+enddef ;
+
+def circular_shade (expr p, n, ca, cb) =
+ begingroup ;
+ save ab, r ; pair ab ; numeric r ;
+ r := (xpart lrcorner p - xpart llcorner p) ++
+ (ypart urcorner p - ypart lrcorner p) ;
+ set_circular_vector(ab,r)(p,n) ;
+ fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ;
+ if trace_shades :
+ drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ;
+ fi ;
+ endgroup ;
+enddef ;
+
+vardef predefined_linear_shade (expr p, n, ca, cb) =
+ save a, b, sh ; pair a, b ;
+ set_linear_vector(a,b)(p,n) ;
+ define_linear_shade (a,b,ca,cb)
+enddef ;
+
+vardef predefined_circular_shade (expr p, n, ca, cb) =
+ save ab, r ; pair ab ; numeric r ;
+ r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ;
+ set_circular_vector(ab,r)(p,n) ;
+ define_circular_shade(ab,ab,0,r,ca,cb)
+enddef ;
+
+%D Since a \type {fill p withshade s} syntax looks better
+%D than some macro, we implement a new primary.
+
+primarydef p withshade sc = % == p withcolor shadecolor(sh)
+ hide (_color_counter_ := _color_counter_ + 1)
+ p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_)
+enddef ;
+
+vardef shadecolor(expr sc) =
+ hide (_color_counter_ := _color_counter_ + 1)
+ (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_)
+enddef ;
+
+%D Figure inclusion.
+
+%numeric cef ; cef := 0 ;
+
+def externalfigure primary filename =
+ doexternalfigure (filename)
+enddef ;
+
+def doexternalfigure (expr filename) text transformation =
+ begingroup ; save p, t ; picture p ; transform t ;
+ p := nullpicture ; t := identity transformation ;
+ flush_special(10, 9,
+ dddecimal (xxpart t, yxpart t, xypart t) & " " &
+ dddecimal (yypart t, xpart t, ypart t) & " " & filename) ;
+ addto p contour unitsquare scaled 0 ;
+ setbounds p to unitsquare transformed t ;
+ _color_counter_ := _color_counter_ + 1 ;
+ draw p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ;
+ endgroup ;
+enddef ;
+
+%D Experimental:
+
+%numeric currenthyperlink ; currenthyperlink := 0 ;
+
+def hyperlink primary t = dohyperlink(t) enddef ;
+def hyperpath primary t = dohyperpath(t) enddef ;
+
+def dohyperlink (expr destination) text transformation =
+ begingroup ; save somepath ; path somepath ;
+ somepath := fullsquare transformation ;
+ dohyperpath(destination) somepath ;
+ endgroup ;
+enddef ;
+
+def dohyperpath (expr destination) expr somepath =
+ begingroup ;
+ flush_special(20, 7,
+ ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " &
+ ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ;
+ _color_counter_ := _color_counter_ + 1 ;
+ fill boundingbox unitsquare scaled 0 withcolor
+ (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ;
+ endgroup ;
+enddef ;
+
+% \setupinteraction[state=start]
+% \setupcolors [state=start]
+%
+% Hello There! \blank
+%
+% \startMPcode
+% pickup pencircle scaled 5 ;
+% draw fullcircle scaled 4cm withcolor red ;
+% hyperpath "nextpage" boundingbox currentpicture ;
+% draw origin withcolor blue ;
+% \stopMPcode
+%
+% \blank Does it work or not?
+%
+% \startMPcode
+% pickup pencircle scaled 5 ;
+% draw fullcircle scaled 4cm withcolor red ;
+% hyperpath "nextpage" fullcircle scaled 4cm ;
+% draw origin withcolor blue ;
+% draw fullcircle scaled 4cm shifted (1cm,1cm);
+% \stopMPcode
+%
+% \blank Does it work or not? \page Hello There! \blank
+%
+% \startMPcode
+% pickup pencircle scaled 5 ;
+% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ;
+% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ;
+% draw fullcircle scaled 1cm ;
+% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ;
+% draw origin withcolor blue ;
+% \stopMPcode
+%
+% \blank Does it work or not?
+
+_cmyk_counter_ := 0 ;
+
+extra_endfig := " ; resetcmykcolors ; " & extra_endfig ;
+
+def resetcmykcolors =
+ numeric cmykcolorhash[][][][] ;
+enddef ;
+
+resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true
+
+string cmykcolorpattern[] ; % needed for transparancies
+
+vardef cmyk(expr c,m,y,k) =
+ if cmykcolors :
+ save ok ; boolean ok ;
+ if unknown cmykcolorhash[c][m][y][k] :
+ ok := false ; % not yet defined
+ elseif cmykcolorhash[c][m][y][k] = -1 :
+ ok := false ; % locally defined and undefined
+ else :
+ ok := true ; % globally already defined
+ fi ;
+ if not ok :
+% save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ;
+ save s ; string s ; s := ddddecimal (c,m,y,k) ;
+ _cmyk_counter_ := _cmyk_counter_ + 1 ;
+ cmykcolorpattern[_cmyk_counter_/_special_div_] := s ;
+ cmykcolorhash[c][m][y][k] := _cmyk_counter_ ;
+ flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ;
+ _local_specials_ := _local_specials_ &
+ " cmykcolorhash[" & decimal c & "][" & decimal m &
+ "][" & decimal y & "][" & decimal k & "] := -1 ; " ;
+ fi ;
+ (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_)
+ else :
+ (1-c-k,1-m-k,1-y-k)
+ fi
+enddef ;
+
+% newcolor truecyan, truemagenta, trueyellow ;
+%
+% truecyan = (1,0,0,0) ;
+% truemagenta = (0,1,0,0) ;
+% trueyellow = (0,0,1,0) ;
+
+%D Spot colors
+
+_spotcolor_counter_ := 0 ;
+_spotcolor_number_ := 0 ;
+
+extra_endfig := " ; resetspotcolors ; " & extra_endfig ;
+
+def resetspotcolors =
+ numeric spotcolorhash[][] ;
+enddef ;
+
+resetspotcolors ; boolean spotcolors ; spotcolors := false ; % true
+
+string spotcolorpattern[] ; % needed for transparancies
+
+vardef spotcolor(expr p, s) =
+ multitonecolor(p, 1, "", decimal s)
+enddef ;
+
+vardef multitonecolor(expr n, f, d, p) = % name fractions names factors
+ if spotcolors :
+ save ok, pc_tag ; boolean ok ; string pc_tag ;
+ pc_tag := "_pct_" & n ;
+ if not unstringed(pc_tag) :
+ _spotcolor_number_ := _spotcolor_number_ + 1 ;
+ setunstringed(pc_tag,_spotcolor_number_) ;
+ fi ;
+ pp := getunstringed(pc_tag) ;
+ pc_tag := "_pct_"& decimal f & "_" & if d = "" : n else : d fi & "_" & p ; % check for d empty
+ if not unstringed(pc_tag) :
+ _spotcolor_number_ := _spotcolor_number_ + 1 ;
+ setunstringed(pc_tag,_spotcolor_number_) ;
+ fi ;
+ ps := getunstringed(pc_tag) ;
+ if unknown spotcolorhash[pp][ps] :
+ ok := false ; % not yet defined
+ elseif spotcolorhash[pp][ps] = -1 :
+ ok := false ; % locally defined and undefined
+ else :
+ ok := true ; % globally already defined
+ fi ;
+ if not ok :
+ save ss ; string ss ; ss := n & " " & decimal f & " " & if d = "" : n else : d fi & " " & p ;
+ _spotcolor_counter_ := _spotcolor_counter_ + 1 ;
+ spotcolorpattern[_spotcolor_counter_/_special_div_] := ss ;
+ spotcolorhash[pp][ps] := _spotcolor_counter_ ;
+ flush_special(2, 7, decimal _spotcolor_counter_ & " " & ss) ;
+ _local_specials_ := _local_specials_ &
+ "spotcolorhash["&decimal pp&"]["&decimal ps&"]:=-1;" ;
+ fi ;
+ (_special_signal_/_special_div_,2/_special_div_,spotcolorhash[pp][ps]/_special_div_)
+ else :
+ .5white
+ fi
+enddef ;
+
+%D Transparency
+
+normaltransparent := 1 ; multiplytransparent := 2 ;
+screentransparent := 3 ; overlaytransparent := 4 ;
+softlighttransparent := 5 ; hardlighttransparent := 6 ;
+colordodgetransparent := 7 ; colorburntransparent := 8 ;
+darkentransparent := 9 ; lightentransparent := 10 ;
+differencetransparent := 11 ; exclusiontransparent := 12 ;
+
+% nottransparent := 0 ;
+% compatibletransparent := 99 ;
+
+% fill fullcircle scaled 10cm withcolor transparant(8,.3,red) ;
+
+vardef transparent(expr n, t, c) =
+ save s, ss, nn, cc, is_cmyk, is_spot, ok ;
+ string s, ss ; numeric nn ; color cc ; boolean is_cmyk, is_spot, ok ;
+ % transparancy type
+ if string n :
+ if expandafter known scantokens(n&"transparent") :
+ nn := scantokens(n&"transparent") ;
+ else :
+ nn := 0 ;
+ fi
+ else : % nn := min(n,13)
+ nn := if n<13 : n else : nn := 0 fi ;
+ fi ;
+ % we need to expand the color (can be cmyk(..) or predefined)
+ cc := c ; % expand color
+ % check for cmyk special
+ is_cmyk := (redpart cc = _special_signal_/_special_div_)
+ and (greenpart cc = 1/_special_div_) ;
+ is_spot := (redpart cc = _special_signal_/_special_div_)
+ and (greenpart cc = 2/_special_div_) ;
+ % build special string, fetch cmyk components
+ s := decimal nn & " " & decimal t & " " &
+ if is_cmyk : cmykcolorpattern[bluepart cc]
+ elseif is_spot : spotcolorpattern[bluepart cc]
+ else : dddecimal cc fi ;
+ % check if this one is already used
+ ss := cleanstring("tr_" & s) ;
+ % we now have rather unique names, i.e. a color spec of .234 becomes
+ % tr..._234.... and metapost gives a number overflow (parse error)
+ % for variables like tr_12345678 which may result from many decimal
+ % positions (imo mp bug)
+ ss := asciistring(ss) ;
+ % efficiency hack
+ if expandafter unknown scantokens(ss) :
+ ok := false ; % not yet defined
+ elseif scantokens(ss) < 0 :
+ ok := false ; % locally defined and undefined
+ else :
+ ok := true ; % globally already defined
+ fi ;
+ if not ok :
+ if is_spot :
+ flush_special(5, 8, s) ;
+ elseif is_cmyk :
+ flush_special(4, 8, s) ;
+ else :
+ flush_special(3, 7, s) ;
+ fi ;
+ scantokens(ss) := _special_counter_ ;
+ _local_specials_ := _local_specials_ & "scantokens(" & ditto & ss & ditto & ") := -1 ;" ;
+ fi ;
+ % go ahead
+ if is_spot :
+ (_special_signal_/_special_div_,5/_special_div_,scantokens(ss)/_special_div_)
+ elseif is_cmyk :
+ (_special_signal_/_special_div_,4/_special_div_,scantokens(ss)/_special_div_)
+ else :
+ (_special_signal_/_special_div_,3/_special_div_,scantokens(ss)/_special_div_)
+ fi
+enddef ;
+
+%D This function returns true of false, dependent on transparency.
+
+vardef is_transparent(text t) =
+ begingroup ; save transparent ; save _c_, _b_ ;
+ vardef transparent(expr nn, tt, cc) = _b_ := true ; cc enddef ;
+ boolean _b_ ; _b_ := false ;
+ color _c_ ; _c_ := t ; _b_
+ endgroup
+enddef ;
+
+% boolean _b_ ; better namespacing
+% color _c_ ;
+% vardef _transparent_(expr nn, tt, cc) = _b_ := true ; cc enddef ;
+% vardef is_transparent(text t) =
+% begingroup ;
+% save transparent ;
+% transparent := _transparent_ ;
+% _b_ := false ;
+% _c_ := t ; _b_
+% endgroup
+% enddef ;
+
+%D This function returns the not transparent color.
+
+vardef not_transparent(text t) =
+ begingroup ; save transparent ;
+ vardef transparent(expr nn, tt, cc) = cc enddef ;
+ t endgroup
+enddef ;
+
+%D Basic position tracking:
+
+def register (expr label, width, height, offset) =
+ begingroup ;
+ flush_special(50, 7,
+ ddecimal offset & " " &
+ decimal width & " " &
+ decimal height & " " & label) ;
+ endgroup ;
+enddef ;
+
+%D We cannot scale cmyk colors directly since this spoils
+%D the trigger signal (such colors are no real colors).
+
+vardef scaledcmyk(expr c,m,y,k,sf) =
+ cmyk(sf*c,sf*m,sf*y,sf*k)
+enddef ;
+
+vardef scaledcmykasrgb(expr c,m,y,k,sf) =
+ (sf*(1-c-k,1-m-k,1-y-k))
+enddef ;
+
+vardef scaledrgbascmyk(expr c,m,y,k,sf) =
+ scaledcmyk(1-c,1-m,1-y,0,sf)
+enddef ;
+
+vardef scaledrgb(expr r,g,b,sf) =
+ (sf*(r,g,b))
+enddef ;
+
+vardef scaledgray(expr s,sf) =
+ (sf*(s,s,s))
+enddef ;
+
+% spotcolor is already scaled
+
+% just an exercise (due to a question by Chof on the context mailing list); scaling of
+% 'special' colors is not possible and the next solution is incomplete (spot colors,
+% transparency, etc); watch the the tricky chained macro construction
+
+% vardef normalgray(expr s ) = (s,s,s) enddef ;
+% vardef normalrgb (expr r,g,b ) = (r,g,b) enddef ;
+% vardef normalcmyk(expr c,m,y,k) = if cmykcolors : save ok ; boolean ok ; if unknown cmykcolorhash[c][m][y][k] : ok := false ; elseif cmykcolorhash[c][m][y][k] = -1 : ok := false ; else : ok := true ; fi ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; _cmyk_counter_ := _cmyk_counter_ + 1 ; cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" & decimal c & "][" & decimal m & "][" & decimal y & "][" & decimal k & "] := -1 ; " ; fi ; (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) else : (1-c-k,1-m-k,1-y-k) fi enddef ;
+
+% vardef gray(expr s) = normalgray(s ) enddef ;
+% vardef rgb (expr r,g,b) = normalrgb (r,g,b ) enddef ;
+% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ;
+
+% numeric _scaled_color_t_ ;
+% color _scaled_color_c_ ;
+
+% def withscaledcolor =
+% hide (
+% _scaled_color_t_ := 0 ; % direct
+% def gray(expr s) =
+% hide (
+% _gray_s_ := s ;
+% _scaled_color_t_ := 1; % gray
+% )
+% 0
+% enddef ;
+% def rgb (expr r,g,b) =
+% hide (
+% _rgb_r_ := r ; _rgb_g_ := g ; _rgb_b_ := b ;
+% _scaled_color_t_ := 2 ; % rgb
+% )
+% 0
+% enddef ;
+% def cmyk (expr c,m,y,k) =
+% hide (
+% _cmyk_c_ := c ; _cmyk_m_ := m ; _cmyk_y_ := y ; _cmyk_k_ := k ;
+% _scaled_color_t_ := 3 ; % cmyk
+% )
+% 0
+% enddef ; )
+% dowithscaledcolor
+% enddef ;
+
+% def dowithscaledcolor expr t =
+% hide (
+% if color t : _scaled_color_c_ := t fi ;
+% vardef gray(expr s) = normalgray(s) enddef ;
+% vardef rgb (expr r,g,b) = normalrgb (r,g,b) enddef ;
+% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ;
+% )
+% enddef ;
+
+% def by expr s =
+% if _scaled_color_t_ = 0 :
+% withcolor s*_scaled_color_c_
+% elseif _scaled_color_t_ = 1 :
+% withcolor gray(s*_gray_s_)
+% elseif _scaled_color_t_ = 2 :
+% withcolor rgb (s*_rgb_r_, s*_rgb_g_, s*_rgb_b_)
+% elseif _scaled_color_t_ = 3 :
+% withcolor cmyk(s*_cmyk_c_, s*_cmyk_m_, s*_cmyk_y_, s*_cmyk_k_)
+% fi
+% enddef ;
+
+% fill fullcircle scaled 10cm withscaledcolor cmyk(0,0,1,0) by .5 ;
+% fill fullcircle scaled 8cm withscaledcolor rgb (0,0,1) by .5 ;
+% fill fullcircle scaled 6cm withscaledcolor gray(1) by .5 ;
+% fill fullcircle scaled 4cm withscaledcolor (0,1,0) by .5 ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-step.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-step.mpii
new file mode 100644
index 00000000000..e05f00b6e0f
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-step.mpii
@@ -0,0 +1,317 @@
+%D \module
+%D [ file=mp-step.mpii,
+%D version=2001.05.22,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=steps,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+if known context_step : endinput ; fi ;
+
+boolean context_step ; context_step := true ;
+
+%D In the associated \TEX\ module \type {m-steps}, we describe
+%D three methods. The first method uses a different kind of
+%D code than the other two. The method we decided to use,
+%D is based on positional information (paths) provided by
+%D \CONTEXT.
+
+def initialize_step_variables =
+ save line_method, line_h_offset, line_v_offset ;
+ numeric line_method ; line_method := 1 ;
+ numeric line_h_offset ; line_h_offset := 3pt ;
+ numeric line_v_offset ; line_v_offset := 3pt ;
+enddef ;
+
+def begin_step_chart =
+ initialize_step_variables ;
+ save steps, texts, t, b, tb, nofcells ;
+ picture cells[][], texts[][][], lines[][][] ;
+ numeric t, b ; t := 1 ; b := 2 ;
+ numeric nofcells ; nofcells := 0 ;
+enddef ;
+
+def analyze_step_chart =
+ numeric n[], l[][], r[][] ; pair p[] ;
+ n[t] := n[b] := 0 ; numeric tb ;
+ for i=1 upto nofcells : for nn = t, b :
+ if bbwidth(cells[nn][i])>0 : n[nn] := n[nn] + 1 ; fi ;
+ l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ;
+ endfor ; endfor ;
+ % count left and right points
+ for i=1 upto nofcells-1 : for j=i upto nofcells-1 : for nn = t, b :
+ if bbwidth(texts[nn][i][j])>0 :
+ l[nn][i] := l[nn][i] + 1 ;
+ r[nn][j+1] := r[nn][j+1] + 1 ;
+ fi ;
+ endfor ; endfor ; endfor ;
+ % calculate left and right points
+ vardef do (expr nn, mm, ii, ss) =
+ if (l[nn][ii] + r[nn][ii]) > 1 : ss else : .5 fi
+ [ ulcorner cells[mm][ii], urcorner cells[mm][ii] ]
+ enddef ;
+ % combined rows
+ tb := if n[t]>0 : t else : b fi ;
+enddef ;
+
+vardef get_step_chart_top_line (expr i, j) =
+ if bbwidth(cells[tb][i])>0 :
+ if bbwidth(texts[t][i][j])>0 :
+ if bbwidth(cells[tb][j+1])>0 :
+ p[1] := top do(t, tb, i, .6) ;
+ p[3] := top do(t, tb, j+1, .4) ;
+ p[2] := .5[p[1],p[3]] ;
+ if line_method = 1 :
+ p[2] := p[2] shifted (0, ypart
+ (llcorner texts[t][i][j] - ulcorner cells[tb][j+1])) ;
+ elseif line_method = 2 :
+ p[2] := center texts[t][i][j] ;
+ else :
+ % nothing
+ fi ;
+ p[1] := p[1] shifted (0,+line_v_offset) ;
+ p[2] := p[2] shifted (0,-line_v_offset) ;
+ p[3] := p[3] shifted (0,+line_v_offset) ;
+ (p[1] {up} ... p[2] ... {down} p[3])
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+enddef ;
+
+vardef get_step_chart_bot_line (expr i, j) =
+ if bbwidth(cells[b][i])>0 :
+ if bbwidth(texts[b][i][j])>0 :
+ if bbwidth(cells[b][j+1])>0 :
+ p[1] := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ;
+ p[3] := (bot do(b, b, j+1, .4)) shifted (0,-bbheight(cells[b][j+1])) ;
+ p[2] := .5[p[1],p[3]] ;
+ if line_method = 1 :
+ p[2] := p[2] shifted (0, -ypart
+ (llcorner cells[b][j+1] - ulcorner texts[b][i][j])) ;
+ elseif line_method = 2 :
+ p[2] := center texts[b][i][j] ;
+ fi ;
+ p[1] := p[1] shifted (0,-line_v_offset) ;
+ p[2] := p[2] shifted (0,+line_v_offset) ;
+ p[3] := p[3] shifted (0,-line_v_offset) ;
+ (p[1] {down} ... p[2] ... {up} p[3])
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+enddef ;
+
+def end_step_chart =
+ for i=1 upto nofcells : for nn = t, b :
+ if bbwidth(cells[nn][i]) >0 : draw cells[nn][i] ; fi ;
+ endfor ; endfor ;
+ for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b :
+ if known lines[nn][i][j] :
+ if bbwidth(lines[nn][i][j])>0 : draw lines[nn][i][j] ; fi ;
+ fi ;
+ endfor ; endfor ; endfor ;
+ for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b :
+ if bbwidth(texts[nn][i][j])>0 : draw texts[nn][i][j] ; fi ;
+ endfor ; endfor ; endfor ;
+enddef ;
+
+%D Step tables.
+
+def begin_step_table =
+ initialize_step_variables ;
+ picture cells[], texts[], lines[] ;
+ numeric nofcells ; nofcells := 0 ;
+enddef ;
+
+def end_step_table =
+ for i=1 upto nofcells : if known cells[i] : if bbwidth(cells[i])>0 :
+ draw cells[i] ;
+ fi ; fi ; endfor ;
+ for i=1 upto nofcells : if known lines[i] : if bbwidth(lines[i])>0 :
+ draw lines[i] ;
+ fi ; fi ; endfor ;
+ for i=1 upto nofcells : if known texts[i] : if bbwidth(texts[i])>0 :
+ draw texts[i] ;
+ fi ; fi ; endfor ;
+enddef ;
+
+vardef get_step_table_line (expr i) =
+ pair prev, self, next ;
+ if known texts[i] :
+ self := lft .5[llcorner texts[i], ulcorner texts[i] ] ;
+ prev := rt if known texts[i-1] : .3 else : .5 fi [lrcorner cells[i] , urcorner cells[i] ] ;
+ next := rt if known texts[i+1] : .7 else : .5 fi [lrcorner cells[i+1], urcorner cells[i+1]] ;
+ self := self shifted (-line_h_offset,0) ;
+ prev := prev shifted (+line_h_offset,0) ;
+ next := next shifted (+line_h_offset,0) ;
+ prev {right} ... self ... {left} next
+ else :
+ origin
+ fi
+enddef ;
+
+%D The older method let \METAPOST\ do the typesetting. The
+%D macros needed for that are included here for educational
+%D purposes.
+%D
+%D \starttypen
+%D def initialize_step_variables =
+%D save line_color, line_width, arrow_alternative,
+%D text_fill_color, text_line_color, text_line_width, text_offset,
+%D cell_fill_color, cell_line_color, cell_line_width, cell_offset,
+%D line_h_offset, line_v_offset ;
+%D color line_color ; line_color := .4white ;
+%D numeric line_width ; line_width := 1.5pt ;
+%D color text_fill_color ; text_fill_color := white ;
+%D color text_line_color ; text_line_color := red ;
+%D numeric text_line_width ; text_line_width := 1pt ;
+%D numeric text_offset ; text_offset := 2pt ;
+%D color cell_fill_color ; cell_fill_color := white ;
+%D color cell_line_color ; cell_line_color := blue ;
+%D numeric cell_line_width ; cell_line_width := 1pt ;
+%D numeric cell_offset ; cell_offset := 2pt ;
+%D numeric line_alternative ; line_alternative := 1 ;
+%D numeric line_h_offset ; line_h_offset := 3pt ;
+%D numeric line_v_offset ; line_v_offset := 3pt ;
+%D enddef ;
+%D
+%D def begin_step_chart =
+%D begingroup ;
+%D initialize_step_variables ;
+%D save steps, texts, t, b ;
+%D picture cells[][] ; numeric nofcells ; nofcells := 0 ;
+%D picture texts[][][] ; numeric noftexts ; noftexts := 0 ;
+%D numeric t, b ; t := 1 ; b := 2 ;
+%D enddef ;
+%D \stoptypen
+%D
+%D We use a couple of macros to store the content. In the
+%D second (third) alternative we will directly fill the
+%D cells.
+%D
+%D \starttypen
+%D def set_step_chart_cells (expr one, two) =
+%D nofcells := nofcells + 1 ; noftexts := 0 ;
+%D cells[t][nofcells] := textext.rt(one) ;
+%D cells[b][nofcells] := textext.rt(two) ;
+%D enddef ;
+%D
+%D def set_step_chart_texts (expr one, two) =
+%D noftexts := noftexts + 1 ;
+%D texts[t][nofcells][noftexts] := textext.rt(one) ;
+%D texts[b][nofcells][noftexts] := textext.rt(two) ;
+%D enddef ;
+%D \stoptypen
+%D
+%D If you compare the building macro with the later
+%D alternative, you will notice that here we explicitly
+%D have to calculate the distances and positions.
+%D
+%D \starttypen
+%D def end_step_chart =
+%D numeric dx ; dx := 0 ; path p ;
+%D numeric n[] ; n[t] := n[b] := 0 ;
+%D numeric stepsvdistance[] ;
+%D vardef bbwidth (expr p) = (xpart (lrcorner p - llcorner p)) enddef ;
+%D vardef bbheight (expr p) = (ypart (urcorner p - lrcorner p)) enddef ;
+%D stepsvdistance[t] := stepsvdistance[b] := 0 ;
+%D for i=1 upto nofcells :
+%D % find largest bbox
+%D p := boundingbox steps
+%D [if bbwidth(cells[t][i])>bbwidth(cells[b][i]): t else: b fi][i] ;
+%D % assign largest bbox
+%D for nn = t, b :
+%D if bbwidth(cells[nn][i])>0 :
+%D setbounds cells[nn][i] to p enlarged cell_offset ;
+%D n[nn] := n[nn] + 1 ;
+%D fi ;
+%D endfor ;
+%D % determine height
+%D if n[t]>0 :
+%D stepsvdistance[t] := bbheight(cells[t][1]) + intertextdistance ;
+%D fi ;
+%D % add to row
+%D for nn = t, b :
+%D cells[nn][i] := cells[nn][i] shifted (dx,stepsvdistance[nn]) ;
+%D if bbwidth(cells[nn][i])>0 :
+%D dowithpath (boundingbox cells[nn][i],
+%D cell_line_width, cell_line_color, cell_background_color) ;
+%D fi ;
+%D endfor ;
+%D % calculate position
+%D dx := dx + interstepdistance + bbwidth(cells[b][i]) ;
+%D endfor ;
+%D boolean stacked ; stacked := false ;
+%D numeric l[][], r[][], l[][], r[][] ;
+%D pair pa, pb, pc ; path p[] ;
+%D for i=1 upto nofcells :
+%D l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ;
+%D endfor ;
+%D % count left and right points
+%D for i=1 upto nofcells : for j=1 upto nofcells : for nn = t, b :
+%D if known texts[nn][i][j] : if bbwidth(texts[nn][i][j])>0 :
+%D l[nn][i] := l[nn][i] + 1 ;
+%D r[nn][j+i] := r[nn][j+i] + 1 ;
+%D stacked := (stacked or (j>1)) ;
+%D setbounds texts[nn][i][j] to boundingbox texts[nn][i][j] enlarged cell_offset ;
+%D fi fi ;
+%D endfor ; endfor ; endfor ;
+%D % calculate left and right points
+%D vardef do (expr nn, mm, ii, ss) =
+%D if (l[nn][ii] > 0) and (r[nn][ii] > 0) : ss else : .5 fi
+%D [ ulcorner cells[mm][ii],urcorner cells[mm][ii] ]
+%D enddef ;
+%D % draw arrow from left to right point
+%D def dodo (expr nn, ii, jj, dd) =
+%D drawarrow p[nn]
+%D withpen pencircle scaled arrow_line_width
+%D withcolor arrow_line_color ;
+%D transform tr ; tr := identity
+%D shifted point .5 along p[nn]
+%D shifted -center texts[nn][ii][jj]
+%D if not stacked : shifted (0,dd) fi ;
+%D dowithpath ((boundingbox texts[nn][ii][jj]) transformed tr,
+%D text_line_width, text_line_color, text_fill_color) ;
+%D enddef ;
+%D % draw top and bottom text boxes
+%D for i=1 upto nofcells : for j=1 upto nofcells :
+%D pickup pencircle scaled arrow_line_width ;
+%D if known texts[t][i][j] : if bbwidth(texts[t][i][j]) > 0 :
+%D pa := top do(t, if n[t]>0 : t else : b fi, i, .6) ;
+%D pb := top do(t, if n[t]>0 : t else : b fi, j+i, .4) ;
+%D pc := .5[pa,pb] shifted (0,+step_arrow_depth) ;
+%D p[t] := pa {up} .. if not stacked : pc .. fi {down} pb ;
+%D dodo(t, i, j, +intertextdistance) ;
+%D fi fi ;
+%D if known texts[b][i][j] : if bbwidth(texts[b][i][j]) > 0 :
+%D pa := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ;
+%D pb := (bot do(b, b, j+i, .4)) shifted (0,-bbheight(cells[b][j+i])) ;
+%D pc := .5[pa,pb] shifted (0,-step_arrow_depth) ;
+%D p[b] := pa {down} .. if not stacked : pc .. fi {up} pb ;
+%D dodo(b, i, j, -intertextdistance) ;
+%D fi fi ;
+%D endfor ; endfor ;
+%D endgroup ;
+%D enddef ;
+%D \stoptypen
+%D
+%D If you compare both methods, you will notice that the
+%D first method is the cleanest, but not the most efficient
+%D (since it needs \TEX\ runs within \METAPOST\ runs within
+%D \TEX\ runs).
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-symb.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-symb.mpii
new file mode 100644
index 00000000000..40681adf171
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-symb.mpii
@@ -0,0 +1,351 @@
+%D \module
+%D [ file=mp-symb.mp,
+%D version=very old,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=navigation symbol macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Instead of these symbols, you can use the \type {contnav}
+%D font by Taco Hoekwater that is derived form this file.
+
+u := 3;
+h := 5u;
+wt := 5u;
+wb := .25wt;
+o := .1u;
+pw := .5u;
+
+drawoptions (withpen pencircle scaled pw);
+
+path lefttriangle, righttriangle, sublefttriangle, subrighttriangle;
+
+pair s ; s = (2wb,0) ;
+
+x1t = x2t = 0;
+x3t = wt;
+y3t = .5h;
+z1t-z2t = (z3t-z2t) rotated 60;
+
+z4t = (z2t--z3t) intersectionpoint ((z1t--z2t) shifted s) ;
+z5t = (z3t--z1t) intersectionpoint ((z1t--z2t) shifted s) ;
+
+righttriangle = z1t--z2t--z3t--cycle;
+lefttriangle = righttriangle rotatedaround((0,.5h), 180) shifted (wt,0);
+
+subrighttriangle = z4t--((z2t--z3t--z1t) shifted s)--z5t ;
+sublefttriangle = subrighttriangle rotatedaround((0,.5h), 180) shifted (wt,0);
+
+path sidebar;
+
+x1b = x4b = 0;
+x2b = x3b = wb;
+y1b = y2b = y1t;
+y3b = y4b = y2t;
+
+sidebar = z1b--z2b--z3b--z4b--cycle;
+
+path midbar, onebar, twobar;
+
+hh = abs(y1t-y2t);
+
+%midbar := unitsquare scaled 2hh/3;
+midbar := unitsquare scaled hh;
+onebar := unitsquare xscaled (hh/3) yscaled hh;
+twobar := onebar;
+
+def prepareglyph =
+ drawoptions (withpen pencircle scaled .5u);
+enddef;
+
+def finishglyph =
+ set_outer_boundingbox currentpicture;
+ bboxmargin := o;
+ setbounds currentpicture to bbox currentpicture;
+% draw boundingbox currentpicture withcolor red withpen pencircle scaled 1;
+enddef;
+
+beginfig (1);
+ prepareglyph;
+ fill lefttriangle;
+ draw lefttriangle; % draw gets the bbox right, filldraw doesn't
+ finishglyph;
+endfig;
+
+beginfig (2);
+ prepareglyph;
+ fill righttriangle;
+ draw righttriangle;
+ finishglyph;
+endfig;
+
+beginfig (3);
+ prepareglyph;
+ fill sidebar;
+ draw sidebar;
+ fill lefttriangle shifted (.5s);
+ draw lefttriangle shifted (.5s);
+ finishglyph;
+endfig;
+
+beginfig (4);
+ prepareglyph;
+ fill righttriangle;
+ draw righttriangle;
+ fill sidebar shifted (wt,0);
+ draw sidebar shifted (wt,0);
+ finishglyph;
+endfig;
+
+beginfig (5);
+ prepareglyph;
+ fill lefttriangle;
+ draw lefttriangle;
+ fill lefttriangle shifted s;
+ draw lefttriangle shifted s;
+ finishglyph;
+endfig;
+
+beginfig (6);
+ prepareglyph;
+ fill righttriangle;
+ draw righttriangle;
+ fill righttriangle shifted s;
+ draw righttriangle shifted s;
+ finishglyph;
+endfig;
+
+beginfig (7);
+ prepareglyph;
+ fill midbar;
+ draw midbar;
+ finishglyph;
+endfig;
+
+beginfig (8);
+ prepareglyph;
+ fill onebar;
+ draw onebar;
+ finishglyph;
+endfig;
+
+beginfig (9);
+ prepareglyph;
+ fill twobar;
+ draw twobar;
+ fill twobar shifted (pw+hh/2,0);
+ draw twobar shifted (pw+hh/2,0);
+ finishglyph;
+endfig;
+
+beginfig(101);
+ prepareglyph;
+ draw lefttriangle;
+ finishglyph;
+endfig;
+
+beginfig(102);
+ prepareglyph;
+ draw righttriangle;
+ finishglyph;
+endfig;
+
+beginfig(103);
+ prepareglyph;
+ draw sidebar;
+ draw lefttriangle shifted (.5s);
+ finishglyph;
+endfig;
+
+beginfig(104);
+ prepareglyph;
+ draw righttriangle;
+ draw sidebar shifted (wt,0);
+ finishglyph;
+endfig;
+
+beginfig(105);
+ prepareglyph;
+ draw lefttriangle;
+ draw lefttriangle shifted s;
+ finishglyph;
+endfig;
+
+beginfig(106);
+ prepareglyph;
+ draw righttriangle;
+ draw righttriangle shifted s;
+ finishglyph;
+endfig;
+
+beginfig(107);
+ prepareglyph;
+ draw midbar;
+ finishglyph;
+endfig;
+
+beginfig(108);
+ prepareglyph;
+ draw onebar;
+ finishglyph;
+endfig;
+
+beginfig(109);
+ prepareglyph;
+ draw twobar;
+ draw twobar shifted (pw+hh/2,0);
+ finishglyph;
+endfig;
+
+beginfig(201);
+ prepareglyph;
+ draw lefttriangle;
+ finishglyph;
+endfig;
+
+beginfig(202);
+ prepareglyph;
+ draw righttriangle;
+ finishglyph;
+endfig;
+
+beginfig(203);
+ prepareglyph;
+ draw sidebar;
+ draw lefttriangle shifted (.5s);
+ finishglyph;
+endfig;
+
+beginfig(204);
+ prepareglyph;
+ draw righttriangle;
+ draw sidebar shifted (wt,0);
+ finishglyph;
+endfig;
+
+beginfig(205);
+ prepareglyph;
+ draw sublefttriangle shifted s;
+ draw lefttriangle shifted s;
+ finishglyph;
+endfig;
+
+beginfig(206);
+ prepareglyph;
+ draw subrighttriangle;
+ draw righttriangle;
+ finishglyph;
+endfig;
+
+beginfig(207);
+ prepareglyph;
+ draw midbar;
+ finishglyph;
+endfig;
+
+beginfig(208);
+ prepareglyph;
+ draw onebar;
+ finishglyph;
+endfig;
+
+beginfig(209);
+ prepareglyph;
+ draw twobar;
+ draw twobar shifted (pw+hh/2,0);
+ finishglyph;
+endfig;
+
+
+beginfig(999);
+
+picture collection [] ;
+
+prepareglyph ;
+draw lefttriangle ;
+finishglyph ;
+collection[201] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw righttriangle ;
+finishglyph ;
+collection[202] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw sidebar ;
+draw lefttriangle shifted (.5s) ;
+finishglyph ;
+collection[203] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw righttriangle ;
+draw sidebar shifted (wt,0) ;
+finishglyph ;
+collection[204] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw sublefttriangle shifted s ;
+draw lefttriangle shifted s ;
+finishglyph ;
+collection[205] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw subrighttriangle ;
+draw righttriangle ;
+finishglyph ;
+collection[206] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw midbar ;
+finishglyph ;
+collection[207] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw onebar ;
+finishglyph ;
+collection[208] := currentpicture ;
+currentpicture := nullpicture ;
+
+prepareglyph ;
+draw twobar ;
+draw twobar shifted (pw+hh/2,0) ;
+finishglyph ;
+collection[209] := currentpicture ;
+currentpicture := nullpicture ;
+
+for i=201 upto 209 :
+ collection[i] := collection[i] shifted - center collection[i] ;
+endfor ;
+
+addto currentpicture also collection[205] shifted ( 0, 0)
+ withcolor (.3,.4,.5) ;
+addto currentpicture also collection[202] shifted ( 0,1.5h)
+ withcolor (.5,.6,.7) ;
+addto currentpicture also collection[201] shifted (1.5h, 0)
+ withcolor (.6,.7,.8) ;
+addto currentpicture also collection[206] shifted (1.5h,1.5h)
+ withcolor (.4,.5,.6) ;
+
+collection[210] := currentpicture ;
+currentpicture := nullpicture ;
+
+bboxmargin := .25u;
+
+fill bbox collection[210] withcolor .95(1,1,0);
+addto currentpicture also collection[210] ;
+
+endfig ;
+
+end
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-text.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-text.mpii
new file mode 100644
index 00000000000..b7787a42d65
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-text.mpii
@@ -0,0 +1,274 @@
+%D \module
+%D [ file=mp-text.mpii,
+%D version=2000.07.10,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=text support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
+%C details.
+
+%D Under construction.
+
+if known context_text : endinput ; fi ;
+
+boolean context_text ; context_text := true ;
+
+if unknown noftexpictures :
+ numeric noftexpictures ; noftexpictures := 0 ;
+fi ;
+
+if unknown texpictures[1] :
+ picture texpictures[] ;
+fi ;
+
+numeric textextoffset ; textextoffset := 0 ;
+
+% vardef textext@#(expr txt) =
+% interim labeloffset := textextoffset ;
+% noftexpictures := noftexpictures + 1 ;
+% if string txt :
+% write "% figure " & decimal charcode & " : " &
+% "texpictures[" & decimal noftexpictures & "] := btex " &
+% txt & " etex ;" to jobname & ".mpt" ;
+% if unknown texpictures[noftexpictures] :
+% thelabel@#("unknown",origin)
+% else :
+% thelabel@#(texpictures[noftexpictures],origin)
+% fi
+% else :
+% thelabel@#(txt,origin)
+% fi
+% enddef ;
+
+boolean hobbiestextext ; hobbiestextext := false ;
+% string textextstring ; textextstring := "" ;
+
+% def resettextextdirective =
+% textextstring := "" ;
+% enddef ;
+
+% def textextdirective text t =
+% textextstring := textextstring & t ;
+% enddef ;
+
+vardef textext@#(expr txt) =
+ interim labeloffset := textextoffset ;
+ noftexpictures := noftexpictures + 1 ;
+ if string txt :
+ if hobbiestextext : % the tex.mp method as fallback (see tex.mp)
+ write "btex " & txt & " etex" to "mptextmp.mp" ;
+ write EOF to "mptextmp.mp" ;
+ scantokens "input mptextmp"
+ else :
+ write "% figure " & decimal charcode & " : " &
+ "texpictures[" & decimal noftexpictures & "] := btex " &
+ txt & " etex ;" to jobname & ".mpt" ;
+ if unknown texpictures[noftexpictures] :
+ thelabel@#("unknown",origin)
+ else :
+ thelabel@#(texpictures[noftexpictures],origin)
+ fi
+ fi
+ else :
+ thelabel@#(txt,origin)
+ fi
+enddef ;
+
+string laboff_ ; laboff_ := "" ;
+string laboff_c ; laboff_c := "" ;
+string laboff_l ; laboff_l := ".lft" ;
+string laboff_r ; laboff_r := ".rt" ;
+string laboff_b ; laboff_b := ".bot" ;
+string laboff_t ; laboff_t := ".top" ;
+
+string laboff_lt ; laboff_lt := ".ulft" ;
+string laboff_rt ; laboff_rt := ".urt" ; % bugged, conflict with r
+string laboff_lb ; laboff_lb := ".llft" ;
+string laboff_rb ; laboff_rb := ".lrt" ;
+string laboff_tl ; laboff_tl := ".ulft" ;
+string laboff_tr ; laboff_tr := ".urt" ;
+string laboff_bl ; laboff_bl := ".llft" ;
+string laboff_br ; laboff_br := ".lrt" ;
+
+vardef textextstr(expr s, a) =
+ save ss ; string ss ;
+ ss := "laboff_" & a ;
+ ss := scantokens ss ;
+ ss := "textext" & ss & "(" & ditto & s & ditto & ")" ;
+ scantokens ss
+enddef ;
+
+pair laboff.origin ; laboff.origin = (0,0) ; % (infinity,infinity) ;
+pair laboff.raw ; laboff.raw = (0,0) ; % (infinity,infinity) ;
+
+laboff.origin = (0,0) ; labxf.origin := 0 ; labyf.origin := 0 ;
+laboff.raw = (0,0) ; labxf.raw := 0 ; labyf.raw := 0 ;
+
+vardef installlabel@# (expr type, x, y, offset) =
+ numeric labtype@# ; labtype@# := type ;
+ pair laboff @# ; laboff @# := offset ;
+ numeric labxf @# ; labxf @# := x ;
+ numeric labyf @# ; labyf @# := y ;
+enddef ;
+
+vardef thelabel@#(expr s, z) =
+ save p ; picture p ;
+ p = s if not picture s : infont defaultfont scaled defaultscale fi ;
+% wrong, see myway textext
+% if laboff@#<>laboff.origin :
+ (p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p +
+ labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)))
+% else :
+% (p shifted z)
+% fi
+enddef;
+
+def build_parshape (expr p, offset_or_path, dx, dy,
+ baselineskip, strutheight, strutdepth, topskip) =
+
+ if unknown trace_parshape :
+ boolean trace_parshape ; trace_parshape := false ;
+ fi ;
+
+ begingroup ;
+
+ save q, l, r, line, tt, bb,
+ n, hsize, vsize, vvsize, voffset, hoffset, width, indent,
+ ll, lll, rr, rrr, cp, cq, t, b ;
+
+ path q, l, r, line, tt, bb ;
+ numeric n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ;
+ pair ll, lll, rr, rrr, cp, cq, t, b ;
+
+ n := 0 ; cp := center p ;
+
+ if path offset_or_path :
+ q := offset_or_path ; cq := center q ;
+ voffset := dy ;
+ hoffset := dx ;
+ else :
+ q := p ; cq := center q ;
+ hoffset := offset_or_path + dx ;
+ voffset := offset_or_path + dy ;
+ fi ;
+
+ hsize := xpart lrcorner q - xpart llcorner q ;
+ vsize := ypart urcorner q - ypart lrcorner q ;
+
+ q := p shifted - cp ;
+
+ startsavingdata ;
+
+ savedata "\global\parvoffset " & decimal voffset&"bp " ;
+ savedata "\global\parhoffset " & decimal hoffset&"bp " ;
+ savedata "\global\parwidth " & decimal hsize&"bp " ;
+ savedata "\global\parheight " & decimal vsize&"bp " ;
+
+ if not path offset_or_path :
+ q := q xscaled ((hsize-2hoffset)/hsize)
+ yscaled ((vsize-2voffset)/vsize) ;
+ fi ;
+
+ hsize := xpart lrcorner q - xpart llcorner q ;
+ vsize := ypart urcorner q - ypart lrcorner q ;
+
+ t := (ulcorner q -- urcorner q) intersection_point q ;
+ b := (llcorner q -- lrcorner q) intersection_point q ;
+
+ if xpart directionpoint t of q < 0 :
+ q := reverse q ;
+ fi ;
+
+ l := q cutbefore t ;
+ l := l if xpart point 0 of q < 0 : & q fi cutafter b ;
+
+ r := q cutbefore b ;
+ r := r if xpart point 0 of q > 0 : & q fi cutafter t ;
+
+% tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ;
+% bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ;
+%
+% l := l cutbefore (l intersection_point tt) ;
+% l := l cutafter (l intersection_point bb) ;
+% r := r cutbefore (r intersection_point bb) ;
+% r := r cutafter (r intersection_point tt) ;
+
+ if trace_parshape :
+ drawarrow p withpen pencircle scaled 2pt withcolor red ;
+ drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ;
+ fi ;
+
+ vardef found_point (expr lin, pat, sig) =
+ pair a, b ;
+ a := pat intersection_point (lin shifted (0,strutheight)) ;
+ if intersection_found :
+ a := a shifted (0,-strutheight) ;
+ else :
+ a := pat intersection_point lin ;
+ fi ;
+ b := pat intersection_point (lin shifted (0,-strutdepth)) ;
+ if intersection_found :
+ if sig :
+ if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
+ else :
+ if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
+ fi ;
+ fi ;
+ a
+ enddef ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i-eps) ;
+
+ ll := found_point(line,l,true ) ;
+ rr := found_point(line,r,false) ;
+
+ if trace_parshape :
+ fill (ll--rr--rr shifted (0,strutheight)--ll
+ shifted (0,strutheight)--cycle) shifted cp withcolor .5white ;
+ fill (ll--rr--rr shifted (0,-strutdepth)--ll
+ shifted (0,-strutdepth)--cycle) shifted cp withcolor .7white ;
+ draw ll shifted cp withpen pencircle scaled 2pt ;
+ draw rr shifted cp withpen pencircle scaled 2pt ;
+ draw (ll--rr) shifted cp withpen pencircle scaled .5pt ;
+ fi ;
+
+ n := n + 1 ;
+ indent[n] := abs(xpart ll - xpart llcorner q) ;
+ width[n] := abs(xpart rr - xpart ll) ;
+
+ if (i=strutheight) and (width[n]<baselineskip) :
+ n := n - 1 ;
+ savedata "\global\chardef\parfirst=1 " ;
+ fi ;
+
+ endfor ;
+
+ savedata "\global\parlines " & decimal n ;
+ savedata "\global\partoks{ " ;
+ for i=1 upto n:
+ savedata decimal indent[i]&"bp " & decimal width[i]&"bp " ;
+ endfor ;
+ savedata "}" ;
+
+ stopsavingdata ;
+
+ endgroup ;
+
+enddef ;
+
+vardef verbatim(expr str) =
+ ditto & "\detokenize{" & str & "}" & ditto
+enddef ;
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii
new file mode 100644
index 00000000000..1e45b6fba75
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-tool.mpii
@@ -0,0 +1,2819 @@
+%D \module
+%D [ file=mp-tool.mpii,
+%D version=1998.02.15,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=auxiliary macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% def loadfile(expr name) = scantokens("input " & name & ";") enddef ;
+
+if known context_tool : endinput ; fi ;
+
+boolean context_tool ; context_tool := true ;
+
+let @## = @# ;
+
+%D New, version number testing:
+%D
+%D \starttyping
+%D fill fullcircle scaled 2cm withcolor if mpversiongt("0.6") : red else : green fi ;
+%D fill fullcircle scaled 1cm withcolor if mpversionlt(0.6) : blue else : white fi ;
+%D \stoptyping
+
+if not known mpversion : string mpversion ; mpversion := "0.641" ; fi ;
+
+% newinternal metapostversion ; metapostversion := scantokens(mpversion) ;
+
+newinternal metapostversion ; metapostversion := 2.0 ;
+
+% vardef mpversiongt(expr s) =
+% scantokens (mpversion & " > " & if numeric s : decimal s else : s fi)
+% enddef ;
+% vardef mpversionlt(expr s) =
+% scantokens (mpversion & " < " & if numeric s : decimal s else : s fi)
+% enddef ;
+% vardef mpversioneq(expr s) =
+% scantokens (mpversion & " = " & if numeric s : decimal s else : s fi)
+% enddef ;
+
+%D More interesting:
+%D
+%D \starttyping
+%D fill fullcircle scaled 4cm withcolor if mpversiongt("0.6") : red else : green fi ;
+%D fill fullcircle scaled 2cm withcolor if mpversionlt(0.6) : blue else : white fi ;
+%D fill fullcircle scaled 1cm withcolor if mpversioncmp(0.6,">=") : yellow else : black fi ;
+%D \stoptyping
+
+vardef mpversioncmp(expr s, c) =
+ scantokens (mpversion & c & if numeric s : decimal s else : s fi)
+enddef ;
+
+vardef mpversionlt (expr s) = mpversioncmp(s, "<") enddef ;
+vardef mpversioneq (expr s) = mpversioncmp(s, "=") enddef ;
+vardef mpversiongt (expr s) = mpversioncmp(s, ">") enddef ;
+
+%D We always want \EPS\ conforming output, so we say:
+
+prologues := 1 ;
+warningcheck := 0 ;
+mpprocset := 1 ;
+
+%D Namespace handling:
+
+% let exclamationmark = ! ;
+% let questionmark = ? ;
+%
+% def unprotect =
+% let ! = relax ;
+% let ? = relax ;
+% enddef ;
+%
+% def protect =
+% let ! = exclamationmark ;
+% let ? = questionmark ;
+% enddef ;
+%
+% unprotect ;
+%
+% mp!some!module = 10 ; show mp!some!module ; show somemodule ;
+%
+% protect ;
+
+string space ; space := char 32 ;
+string CRLF ; CRLF := char 10 & char 13 ;
+
+vardef ddecimal primary p =
+ decimal xpart p & " " & decimal ypart p
+enddef ;
+
+%D Plain compatibility:
+
+string plain_compatibility_data ; plain_compatibility_data := "" ;
+
+def startplaincompatibility =
+ begingroup ;
+ scantokens plain_compatibility_data ;
+enddef ;
+
+def stopplaincompatibility =
+ endgroup ;
+enddef ;
+
+% is now built in
+%
+% extra_endfig := extra_endfig
+% & "special "
+% & "("
+% & ditto
+% & "%%HiResBoundingBox: "
+% & ditto
+% & "&ddecimal llcorner currentpicture"
+% & "&space"
+% & "&ddecimal urcorner currentpicture"
+% & ");";
+
+%D More neutral:
+
+let triplet = rgbcolor ;
+let quadruplet = cmykcolor ;
+
+%D Crap (experimental, not used):
+
+def forcemultipass =
+ % extra_endfig := extra_endfig & "special(" & ditto & "%%MetaPostOption: multipass" & ditto & ");" ;
+enddef ;
+
+%D Colors:
+
+let grayscale = numeric ;
+let greyscale = numeric ;
+
+vardef colorpart expr c =
+ if not picture c :
+ 0
+ elseif colormodel c = greycolormodel :
+ greypart c
+ elseif colormodel c = rgbcolormodel :
+ (redpart c,greenpart c,bluepart c)
+ elseif colormodel c = cmykcolormodel :
+ (cyanpart c,magentapart c,yellowpart c,blackpart c)
+ else :
+ 0 % black
+ fi
+enddef ;
+
+vardef colorlike(text c) text v = % colorlike(a) b, c, d ;
+ save _p_ ; picture _p_ ;
+ forsuffixes i=v :
+ _p_ := image(draw origin withcolor c ;) ; % intercept pre and postscripts
+ if (colormodel _p_ = cmykcolormodel) :
+ cmykcolor i ;
+ elseif (colormodel _p_ = rgbcolormodel) :
+ rgbcolor i ;
+ else :
+ greycolor i ;
+ fi ;
+ endfor ;
+enddef ;
+
+%D Also handy (when we flush colors):
+
+vardef dddecimal primary c =
+ decimal redpart c & " " & decimal greenpart c & " " & decimal bluepart c
+enddef ;
+
+vardef ddddecimal primary c =
+ decimal cyanpart c & " " & decimal magentapart c & " " & decimal yellowpart c & " " & decimal blackpart c
+enddef ;
+
+vardef colordecimals primary c =
+ if cmykcolor c :
+ decimal cyanpart c & ":" & decimal magentapart c & ":" & decimal yellowpart c & ":" & decimal blackpart c
+ elseif rgbcolor c :
+ decimal redpart c & ":" & decimal greenpart c & ":" & decimal bluepart c
+ else :
+ decimal c
+ fi
+enddef ;
+
+%D We have standardized data file names:
+
+def job_name =
+ jobname
+enddef ;
+
+def data_mpd_file =
+ job_name & "-mp.mpd"
+enddef ;
+
+%D Because \METAPOST\ has a hard coded limit of 4~datafiles,
+%D we need some trickery when we have multiple files.
+
+if unknown collapse_data :
+ boolean collapse_data ;
+ collapse_data := false ;
+fi ;
+
+boolean savingdata ; savingdata := false ;
+boolean savingdatadone ; savingdatadone := false ;
+
+def savedata expr txt =
+ write if collapse_data :
+ txt
+ else :
+ if savingdata : txt else : "\MPdata{" & decimal charcode & "}{" & txt & "}" fi & "%"
+ fi to data_mpd_file ;
+enddef ;
+
+def startsavingdata =
+ savingdata := true ;
+ savingdatadone := true ;
+ if collapse_data :
+ write "\MPdata{" & decimal charcode & "}{%" to data_mpd_file ;
+ fi ;
+enddef ;
+
+def stopsavingdata =
+ if collapse_data :
+ write "}%" to data_mpd_file ;
+ fi ;
+ savingdata := false ;
+enddef ;
+
+def finishsavingdata =
+ if savingdatadone :
+ write EOF to data_mpd_file ;
+ savingdatadone := false ;
+ fi ;
+enddef ;
+
+%D Instead of a keystroke eating save and allocation
+%D sequence, you can use the \citeer {new} alternatives to
+%D save and allocate in one command.
+
+def newcolor text v = forsuffixes i=v : save i ; color i ; endfor ; enddef ;
+def newnumeric text v = forsuffixes i=v : save i ; numeric i ; endfor ; enddef ;
+def newboolean text v = forsuffixes i=v : save i ; boolean i ; endfor ; enddef ;
+def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; enddef ;
+def newpath text v = forsuffixes i=v : save i ; path i ; endfor ; enddef ;
+def newpicture text v = forsuffixes i=v : save i ; picture i ; endfor ; enddef ;
+def newstring text v = forsuffixes i=v : save i ; string i ; endfor ; enddef ;
+def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; enddef ;
+
+%D Sometimes we don't want parts of the graphics add to the
+%D bounding box. One way of doing this is to save the bounding
+%D box, draw the graphics that may not count, and restore the
+%D bounding box.
+%D
+%D \starttyping
+%D push_boundingbox currentpicture;
+%D pop_boundingbox currentpicture;
+%D \stoptyping
+%D
+%D The bounding box can be called with:
+%D
+%D \starttyping
+%D boundingbox currentpicture
+%D inner_boundingbox currentpicture
+%D outer_boundingbox currentpicture
+%D \stoptyping
+%D
+%D Especially the latter one can be of use when we include
+%D the graphic in a document that is clipped to the bounding
+%D box. In such occasions one can use:
+%D
+%D \starttyping
+%D set_outer_boundingbox currentpicture;
+%D \stoptyping
+%D
+%D Its counterpart is:
+%D
+%D \starttyping
+%D set_inner_boundingbox p
+%D \stoptyping
+
+path mfun_boundingbox_stack ;
+numeric mfun_boundingbox_stack_depth ;
+
+mfun_boundingbox_stack_depth := 0 ;
+
+def pushboundingbox text p =
+ mfun_boundingbox_stack_depth := mfun_boundingbox_stack_depth + 1 ;
+ mfun_boundingbox_stack[mfun_boundingbox_stack_depth] := boundingbox p ;
+enddef ;
+
+def popboundingbox text p =
+ setbounds p to mfun_boundingbox_stack[mfun_boundingbox_stack_depth] ;
+ mfun_boundingbox_stack[mfun_boundingbox_stack_depth] := origin ;
+ mfun_boundingbox_stack_depth := mfun_boundingbox_stack_depth - 1 ;
+enddef ;
+
+let push_boundingbox = pushboundingbox ; % downward compatible
+let pop_boundingbox = popboundingbox ; % downward compatible
+
+vardef boundingbox primary p =
+ if (path p) or (picture p) :
+ llcorner p -- lrcorner p -- urcorner p -- ulcorner p
+ else :
+ origin
+ fi -- cycle
+enddef;
+
+vardef innerboundingbox primary p =
+ top rt llcorner p --
+ top lft lrcorner p --
+ bot lft urcorner p --
+ bot rt ulcorner p -- cycle
+enddef;
+
+vardef outerboundingbox primary p =
+ bot lft llcorner p --
+ bot rt lrcorner p --
+ top rt urcorner p --
+ top lft ulcorner p -- cycle
+enddef;
+
+def inner_boundingbox = innerboundingbox enddef ;
+def outer_boundingbox = outerboundingbox enddef ;
+
+vardef set_inner_boundingbox text q = % obsolete
+ setbounds q to innerboundingbox q;
+enddef;
+
+vardef set_outer_boundingbox text q = % obsolete
+ setbounds q to outerboundingbox q;
+enddef;
+
+%D Some missing functions can be implemented rather straightforward (thanks to
+%D Taco and others):
+
+pi := 3.14159265358979323846 ; radian := 180/pi ; % 2pi*radian = 360 ;
+
+% let +++ = ++ ;
+
+numeric Pi ; Pi := pi ; % for some old compatibility reasons i guess
+
+vardef sqr primary x = x*x enddef ;
+vardef log primary x = if x=0: 0 else: mlog(x)/mlog(10) fi enddef ;
+vardef ln primary x = if x=0: 0 else: mlog(x)/256 fi enddef ;
+vardef exp primary x = (mexp 256)**x enddef ;
+vardef inv primary x = if x=0: 0 else: x**-1 fi enddef ;
+
+vardef pow (expr x,p) = x**p enddef ;
+
+vardef tand primary x = sind(x)/cosd(x) enddef ;
+vardef cotd primary x = cosd(x)/sind(x) enddef ;
+
+vardef sin primary x = sind(x*radian) enddef ;
+vardef cos primary x = cosd(x*radian) enddef ;
+vardef tan primary x = sin(x)/cos(x) enddef ;
+vardef cot primary x = cos(x)/sin(x) enddef ;
+
+vardef asin primary x = angle((1+-+x,x)) enddef ;
+vardef acos primary x = angle((x,1+-+x)) enddef ;
+vardef atan primary x = angle(1,x) enddef ;
+
+vardef invsin primary x = (asin(x))/radian enddef ;
+vardef invcos primary x = (acos(x))/radian enddef ;
+vardef invtan primary x = (atan(x))/radian enddef ;
+
+vardef acosh primary x = ln(x+(x+-+1)) enddef ;
+vardef asinh primary x = ln(x+(x++1)) enddef ;
+
+vardef sinh primary x = save xx ; xx = exp x ; (xx-1/xx)/2 enddef ;
+vardef cosh primary x = save xx ; xx = exp x ; (xx+1/xx)/2 enddef ;
+
+%D Sometimes this is handy:
+
+def undashed =
+ dashed nullpicture
+enddef ;
+
+%D We provide two macros for drawing stripes across a shape.
+%D The first method (with the n suffix) uses another method,
+%D slower in calculation, but more efficient when drawn. The
+%D first macro divides the sides into n equal parts. The
+%D first argument specifies the way the lines are drawn, while
+%D the second argument identifier the way the shape is to be
+%D drawn.
+%D
+%D \starttyping
+%D stripe_path_n
+%D (dashed evenly withcolor blue)
+%D (filldraw)
+%D fullcircle xscaled 100 yscaled 40 shifted (50,50) withpen pencircle scaled 4;
+%D \stoptyping
+%D
+%D The a (or angle) alternative supports arbitrary angles and
+%D is therefore more versatile.
+%D
+%D \starttyping
+%D stripe_path_a
+%D (withpen pencircle scaled 2 withcolor red)
+%D (draw)
+%D fullcircle xscaled 100 yscaled 40 withcolor blue;
+%D \stoptyping
+%D
+%D We have two alternatives, controlled by arguments or defaults (when arguments
+%D are zero).
+%D
+%D The newer and nicer interface is used as follows (triggered by a question by Mari):
+%D
+%D \starttyping
+%D draw image (draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green) numberstriped (1,10,3) withcolor red ;
+%D draw image (draw fullcircle scaled 3cm shifted (3cm,0cm) withcolor green) numberstriped (2,20,3) withcolor green ;
+%D draw image (draw fullcircle scaled 3cm shifted (3cm,3cm) withcolor green) numberstriped (3,10,5) withcolor blue ;
+%D draw image (draw fullcircle scaled 3cm shifted (0cm,3cm) withcolor green) numberstriped (4,20,5) withcolor yellow ;
+%D
+%D draw image (draw fullcircle scaled 3cm shifted (6cm,0cm) withcolor green) anglestriped (1,20,2) withcolor red ;
+%D draw image (draw fullcircle scaled 3cm shifted (9cm,0cm) withcolor green) anglestriped (2,40,2) withcolor green ;
+%D draw image (draw fullcircle scaled 3cm shifted (9cm,3cm) withcolor green) anglestriped (3,60,2) withcolor blue ;
+%D draw image (draw fullcircle scaled 3cm shifted (6cm,3cm) withcolor green) anglestriped (4,80,2) withcolor yellow ;
+%D
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (9cm,0cm) numberstriped (1,10,3) withcolor red ;
+%D
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (12cm,0cm) numberstriped (2,10,3) withcolor red ;
+%D
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (9cm,5cm) numberstriped (3,10,3) withcolor red ;
+%D
+%D draw image (
+%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ;
+%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ;
+%D ) shifted (12cm,5cm) numberstriped (4,10,3) withcolor red ;
+%D \stoptyping
+
+stripe_n := 10;
+stripe_slot := 3;
+stripe_gap := 5;
+stripe_angle := 45;
+
+def mfun_tool_striped_number_action text extra =
+ for i = 1/used_n step 1/used_n until 1 :
+ draw point (1+i) of bounds -- point (3-i) of bounds withpen pencircle scaled penwidth extra ;
+ endfor ;
+ for i = 0 step 1/used_n until 1 :
+ draw point (3+i) of bounds -- point (1-i) of bounds withpen pencircle scaled penwidth extra ;
+ endfor ;
+enddef ;
+
+def mfun_tool_striped_set_options(expr option) =
+ save isinner, swapped ;
+ boolean isinner, swapped ;
+ if option = 1 :
+ isinner := false ;
+ swapped := false ;
+ elseif option = 2 :
+ isinner := true ;
+ swapped := false ;
+ elseif option = 3 :
+ isinner := false ;
+ swapped := true ;
+ elseif option = 4 :
+ isinner := true ;
+ swapped := true ;
+ else :
+ isinner := false ;
+ swapped := false ;
+ fi ;
+enddef ;
+
+vardef mfun_tool_striped_number(expr option, p, s_n, s_slot) text extra =
+ image (
+ begingroup ;
+ save pattern, shape, bounds, penwidth, used_n, used_slot ;
+ picture pattern, shape ; path bounds ; numeric used_s, used_slot ;
+ mfun_tool_striped_set_options(option) ;
+ used_slot := if s_slot = 0 : stripe_slot else : s_slot fi ;
+ used_n := if s_n = 0 : stripe_n else : s_n fi ;
+ shape := image(draw p) ;
+ bounds := boundingbox shape ;
+ penwidth := min(ypart urcorner shape - ypart llcorner shape, xpart urcorner shape - xpart llcorner shape) / (used_slot * used_n) ;
+ pattern := image (
+ if isinner :
+ mfun_tool_striped_number_action extra ;
+ for s within shape :
+ if stroked s or filled s :
+ clip currentpicture to pathpart s ;
+ fi
+ endfor ;
+ else :
+ for s within shape :
+ if stroked s or filled s :
+ draw image (
+ mfun_tool_striped_number_action extra ;
+ clip currentpicture to pathpart s ;
+ ) ;
+ fi ;
+ endfor ;
+ fi ;
+ ) ;
+ if swapped :
+ addto currentpicture also shape ;
+ addto currentpicture also pattern ;
+ else :
+ addto currentpicture also pattern ;
+ addto currentpicture also shape ;
+ fi ;
+ endgroup ;
+ )
+enddef ;
+
+def mfun_tool_striped_angle_action text extra =
+ for i = minimum -.5used_gap step used_gap until maximum :
+ draw (minimum,i) -- (maximum,i) extra ;
+ endfor ;
+ currentpicture := currentpicture rotated used_angle ;
+enddef ;
+
+vardef mfun_tool_striped_angle(expr option, p, s_angle, s_gap) text extra =
+ image (
+ begingroup ;
+ save pattern, shape, mask, maximum, minimum, centrum, used_angle, used_gap ;
+ picture pattern, shape, mask ; numeric maximum, minimum ; pair centrum ; numeric used_angle, used_gap ;
+ mfun_tool_striped_set_options(option) ;
+ used_angle := if s_angle = 0 : stripe_angle else : s_angle fi ;
+ used_gap := if s_gap = 0 : stripe_gap else : s_gap fi ;
+ shape := image(draw p) ;
+ centrum := center shape ;
+ shape := shape shifted - centrum ;
+ mask := shape rotated used_angle ;
+ maximum := max (xpart llcorner mask, xpart urcorner mask, ypart llcorner mask, ypart urcorner mask) ;
+ minimum := min (xpart llcorner mask, xpart urcorner mask, ypart llcorner mask, ypart urcorner mask) ;
+ pattern := image (
+ if isinner :
+ mfun_tool_striped_angle_action extra ;
+ for s within shape :
+ if stroked s or filled s :
+ clip currentpicture to pathpart s ;
+ fi
+ endfor ;
+ else :
+ for s within shape :
+ if stroked s or filled s :
+ draw image (
+ mfun_tool_striped_angle_action extra ;
+ clip currentpicture to pathpart s ;
+ ) ;
+ fi ;
+ endfor ;
+ fi ;
+ ) ;
+ if swapped :
+ addto currentpicture also shape ;
+ addto currentpicture also pattern ;
+ else :
+ addto currentpicture also pattern ;
+ addto currentpicture also shape ;
+ fi ;
+ currentpicture := currentpicture shifted centrum ;
+ endgroup ;
+ )
+enddef;
+
+newinternal striped_normal_inner ; striped_normal_inner := 1 ;
+newinternal striped_reverse_inner ; striped_reverse_inner := 2 ;
+newinternal striped_normal_outer ; striped_normal_outer := 3 ;
+newinternal striped_reverse_outer ; striped_reverse_outer := 4 ;
+
+secondarydef p anglestriped s =
+ mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s)
+enddef ;
+
+secondarydef p numberstriped s =
+ mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s)
+enddef ;
+
+% for old times sake:
+
+def stripe_path_n (text s_spec) (text s_draw) expr s_path =
+ do_stripe_path_n (s_spec) (s_draw) (s_path)
+enddef;
+
+def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text =
+ draw image(s_draw s_path s_text) numberstriped(3,0,0) s_spec ;
+enddef ;
+
+def stripe_path_a (text s_spec) (text s_draw) expr s_path =
+ do_stripe_path_a (s_spec) (s_draw) (s_path)
+enddef;
+
+def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text =
+ draw image(s_draw s_path s_text) anglestriped(3,0,0) s_spec ;
+enddef ;
+
+%D A few normalizing macros:
+%D
+%D \starttypen
+%D xscale_currentpicture ( width )
+%D yscale_currentpicture ( height )
+%D xyscale_currentpicture ( width, height )
+%D scale_currentpicture ( width, height )
+%D \stoptypen
+
+% def xscale_currentpicture(expr the_width) =
+% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture;
+% currentpicture := currentpicture scaled (the_width/natural_width) ;
+% enddef;
+%
+% def yscale_currentpicture(expr the_height ) =
+% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture;
+% currentpicture := currentpicture scaled (the_height/natural_height) ;
+% enddef;
+%
+% def xyscale_currentpicture(expr the_width, the_height) =
+% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture;
+% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture;
+% currentpicture := currentpicture
+% xscaled (the_width/natural_width)
+% yscaled (the_height/natural_height) ;
+% enddef;
+%
+% def scale_currentpicture(expr the_width, the_height) =
+% xscale_currentpicture(the_width) ;
+% yscale_currentpicture(the_height) ;
+% enddef;
+
+% nog eens uitbreiden zodat path en pic worden afgehandeld.
+
+% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture;
+% currentpicture := currentpicture scaled (the_width/natural_width) ;
+
+primarydef p xsized w =
+ (p if (bbwidth (p)>0) and (w>0) : scaled (w/bbwidth (p)) fi)
+enddef ;
+
+primarydef p ysized h =
+ (p if (bbheight(p)>0) and (h>0) : scaled (h/bbheight(p)) fi)
+enddef ;
+
+primarydef p xysized s =
+ begingroup
+ save wh, w, h ; pair wh ; numeric w, h ;
+ wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ;
+ p
+ if (w>0) and (h>0) :
+ if xpart wh > 0 : xscaled (xpart wh/w) fi
+ if ypart wh > 0 : yscaled (ypart wh/h) fi
+ fi
+ endgroup
+enddef ;
+
+let sized = xysized ;
+
+def xscale_currentpicture(expr w) = % obsolete
+ currentpicture := currentpicture xsized w ;
+enddef;
+
+def yscale_currentpicture(expr h) = % obsolete
+ currentpicture := currentpicture ysized h ;
+enddef;
+
+def xyscale_currentpicture(expr w, h) = % obsolete
+ currentpicture := currentpicture xysized (w,h) ;
+enddef;
+
+def scale_currentpicture(expr w, h) = % obsolete
+ currentpicture := currentpicture xsized w ;
+ currentpicture := currentpicture ysized h ;
+enddef;
+
+%D A full circle is centered at the origin, while a unitsquare
+%D is located in the first quadrant. Now guess what kind of
+%D path fullsquare and unitcircle do return.
+
+path fullsquare, unitcircle ;
+
+fullsquare := unitsquare shifted - center unitsquare ;
+unitcircle := fullcircle shifted urcorner fullcircle ;
+
+%D Some more paths:
+
+path urcircle, ulcircle, llcircle, lrcircle ;
+
+urcircle := origin -- (+.5,0) & (+.5,0){up} .. (0,+.5) & (0,+.5) -- cycle ;
+ulcircle := origin -- (0,+.5) & (0,+.5){left} .. (-.5,0) & (-.5,0) -- cycle ;
+llcircle := origin -- (-.5,0) & (-.5,0){down} .. (0,-.5) & (0,-.5) -- cycle ;
+lrcircle := origin -- (0,-.5) & (0,-.5){right} .. (+.5,0) & (+.5,0) -- cycle ;
+
+path tcircle, bcircle, lcircle, rcircle ;
+
+tcircle = origin -- (+.5,0) & (+.5,0) {up} .. (0,+.5) .. {down} (-.5,0) -- cycle ;
+bcircle = origin -- (-.5,0) & (-.5,0) {down} .. (0,-.5) .. {up} (+.5,0) -- cycle ;
+lcircle = origin -- (0,+.5) & (0,+.5) {left} .. (-.5,0) .. {right} (0,-.5) -- cycle ;
+rcircle = origin -- (0,-.5) & (0,-.5) {right} .. (+.5,0) .. {left} (0,+.5) -- cycle ;
+
+path urtriangle, ultriangle, lltriangle, lrtriangle ; % watch out: it's contrary to what you expect and starts in the origin
+
+urtriangle := origin -- (+.5,0) -- (0,+.5) -- cycle ;
+ultriangle := origin -- (0,+.5) -- (-.5,0) -- cycle ;
+lltriangle := origin -- (-.5,0) -- (0,-.5) -- cycle ;
+lrtriangle := origin -- (0,-.5) -- (+.5,0) -- cycle ;
+
+path unitdiamond, fulldiamond ;
+
+unitdiamond := (.5,0) -- (1,.5) -- (.5,1) -- (0,.5) -- cycle ;
+fulldiamond := unitdiamond shifted - center unitdiamond ;
+
+%D More robust:
+
+% let normalscaled = scaled ;
+% let normalxscaled = xscaled ;
+% let normalyscaled = yscaled ;
+%
+% def scaled expr s = normalscaled (s) enddef ;
+% def xscaled expr s = normalxscaled (s) enddef ;
+% def yscaled expr s = normalyscaled (s) enddef ;
+
+%D Shorter
+
+primarydef p xyscaled q = % secundarydef does not work out well
+ begingroup
+ save qq ; pair qq ;
+ qq = paired(q) ;
+ p
+ if xpart qq <> 0 : xscaled (xpart qq) fi
+ if ypart qq <> 0 : yscaled (ypart qq) fi
+ endgroup
+enddef ;
+
+%D Some personal code that might move to another module
+
+def set_grid(expr w, h, nx, ny) =
+ boolean grid[][] ; boolean grid_full ;
+ numeric grid_w, grid_h, grid_nx, grid_ny, grid_x, grid_y, grid_left ;
+ grid_w := w ;
+ grid_h := h ;
+ grid_nx := nx ;
+ grid_ny := ny ;
+ grid_x := round(w/grid_nx) ; % +.5) ;
+ grid_y := round(h/grid_ny) ; % +.5) ;
+ grid_left := (1+grid_x)*(1+grid_y) ;
+ grid_full := false ;
+ for i=0 upto grid_x :
+ for j=0 upto grid_y :
+ grid[i][j] := false ;
+ endfor ;
+ endfor ;
+enddef ;
+
+vardef new_on_grid(expr _dx_, _dy_) =
+ dx := _dx_ ;
+ dy := _dy_ ;
+ ddx := min(round(dx/grid_nx),grid_x) ; % +.5),grid_x) ;
+ ddy := min(round(dy/grid_ny),grid_y) ; % +.5),grid_y) ;
+ if not grid_full and not grid[ddx][ddy] :
+ grid[ddx][ddy] := true ;
+ grid_left := grid_left-1 ;
+ grid_full := (grid_left=0) ;
+ true
+ else :
+ false
+ fi
+enddef ;
+
+%D usage: \type{innerpath peepholed outerpath}.
+%D
+%D beginfig(1);
+%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ;
+%D fill (fullsquare scaled 200) withcolor red ;
+%D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ;
+%D fill p peepholed bbox p ;
+%D endfig;
+
+secondarydef p peepholed q =
+ begingroup
+ save start ; pair start ;
+ start := point 0 of p ;
+ if xpart start >= xpart center p :
+ if ypart start >= ypart center p :
+ urcorner q -- ulcorner q -- llcorner q -- lrcorner q --
+ reverse p -- lrcorner q -- cycle
+ else :
+ lrcorner q -- urcorner q -- ulcorner q -- llcorner q --
+ reverse p -- llcorner q -- cycle
+ fi
+ else :
+ if ypart start > ypart center p :
+ ulcorner q -- llcorner q -- lrcorner q -- urcorner q --
+ reverse p -- urcorner q -- cycle
+ else :
+ llcorner q -- lrcorner q -- urcorner q -- ulcorner q --
+ reverse p -- ulcorner q -- cycle
+ fi
+ fi
+ endgroup
+enddef ;
+
+boolean intersection_found ;
+
+secondarydef p intersection_point q =
+ begingroup
+ save x_, y_ ;
+ (x_,y_) = p intersectiontimes q ;
+ if x_<0 :
+ intersection_found := false ;
+ center p % origin
+ else :
+ intersection_found := true ;
+ .5[point x_ of p, point y_ of q]
+ fi
+ endgroup
+enddef ;
+
+%D New, undocumented, experimental:
+
+vardef tensecircle (expr width, height, offset) =
+ (-width/2,-height/2) ... (0,-height/2-offset) ...
+ (+width/2,-height/2) ... (+width/2+offset,0) ...
+ (+width/2,+height/2) ... (0,+height/2+offset) ...
+ (-width/2,+height/2) ... (-width/2-offset,0) ... cycle
+enddef ;
+
+vardef roundedsquare (expr width, height, offset) =
+ (offset,0) -- (width-offset,0) {right} ..
+ (width,offset) -- (width,height-offset) {up} ..
+ (width-offset,height) -- (offset,height) {left} ..
+ (0,height-offset) -- (0,offset) {down} .. cycle
+enddef ;
+
+%D Some colors.
+
+def colortype(expr c) =
+ if cmykcolor c : cmykcolor elseif rgbcolor c : rgbcolor else : grayscale fi
+enddef ;
+
+vardef whitecolor(expr c) =
+ if cmykcolor c : (0,0,0,0) elseif rgbcolor c : (1,1,1) else : 1 fi
+enddef ;
+
+vardef blackcolor(expr c) =
+ if cmykcolor c : (0,0,0,1) elseif rgbcolor c : (0,0,0) else : 0 fi
+enddef ;
+
+%D Well, this is the dangerous and naive version:
+
+def drawfill text t =
+ fill t ;
+ draw t ;
+enddef;
+
+%D This two step approach saves the path first, since it can
+%D be a function. Attributes must not be randomized.
+
+def drawfill expr c =
+ path _c_ ; _c_ := c ;
+ mfun_do_drawfill
+enddef ;
+
+def mfun_do_drawfill text t =
+ draw _c_ t ;
+ fill _c_ t ;
+enddef;
+
+def undrawfill expr c =
+ drawfill c withcolor background % rather useless
+enddef ;
+
+%D Moved from mp-char.mp
+
+vardef paired primary d =
+ if pair d : d else : (d,d) fi
+enddef ;
+
+vardef tripled primary d =
+ if color d : d else : (d,d,d) fi
+enddef ;
+
+% maybe secondaries:
+
+primarydef p enlarged d = ( p llmoved d -- p lrmoved d -- p urmoved d -- p ulmoved d -- cycle ) enddef ;
+primarydef p llenlarged d = ( p llmoved d -- lrcorner p -- urcorner p -- ulcorner p -- cycle ) enddef ;
+primarydef p lrenlarged d = ( llcorner p -- p lrmoved d -- urcorner p -- ulcorner p -- cycle ) enddef ;
+primarydef p urenlarged d = ( llcorner p -- lrcorner p -- p urmoved d -- ulcorner p -- cycle ) enddef ;
+primarydef p ulenlarged d = ( llcorner p -- lrcorner p -- urcorner p -- p ulmoved d -- cycle ) enddef ;
+
+primarydef p llmoved d = ( (llcorner p) shifted (-xpart paired(d),-ypart paired(d)) ) enddef ;
+primarydef p lrmoved d = ( (lrcorner p) shifted (+xpart paired(d),-ypart paired(d)) ) enddef ;
+primarydef p urmoved d = ( (urcorner p) shifted (+xpart paired(d),+ypart paired(d)) ) enddef ;
+primarydef p ulmoved d = ( (ulcorner p) shifted (-xpart paired(d),+ypart paired(d)) ) enddef ;
+
+primarydef p leftenlarged d = ( (llcorner p) shifted (-d,0) -- lrcorner p -- urcorner p -- (ulcorner p) shifted (-d,0) -- cycle ) enddef ;
+primarydef p rightenlarged d = ( llcorner p -- (lrcorner p) shifted (d,0) -- (urcorner p) shifted (d,0) -- ulcorner p -- cycle ) enddef ;
+primarydef p topenlarged d = ( llcorner p -- lrcorner p -- (urcorner p) shifted (0,d) -- (ulcorner p) shifted (0,d) -- cycle ) enddef ;
+primarydef p bottomenlarged d = ( llcorner p shifted (0,-d) -- lrcorner p shifted (0,-d) -- urcorner p -- ulcorner p -- cycle ) enddef ;
+
+%D Handy for testing/debugging:
+
+primarydef p crossed d = (
+ if pair p :
+ p shifted (-d, 0) -- p --
+ p shifted ( 0,-d) -- p --
+ p shifted (+d, 0) -- p --
+ p shifted ( 0,+d) -- p -- cycle
+ else :
+ center p shifted (-d, 0) -- llcorner p --
+ center p shifted ( 0,-d) -- lrcorner p --
+ center p shifted (+d, 0) -- urcorner p --
+ center p shifted ( 0,+d) -- ulcorner p -- cycle
+ fi
+) enddef ;
+
+%D Also handy (math ladders):
+
+vardef laddered primary p = % was expr
+ point 0 of p
+ for i=1 upto length(p) :
+ -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p)
+ endfor
+enddef ;
+
+%D Saves typing:
+
+% vardef bottomboundary primary p = (llcorner p -- lrcorner p) enddef ;
+% vardef rightboundary primary p = (lrcorner p -- urcorner p) enddef ;
+% vardef topboundary primary p = (urcorner p -- ulcorner p) enddef ;
+% vardef leftboundary primary p = (ulcorner p -- llcorner p) enddef ;
+
+vardef bottomboundary primary p = if pair p : p else : (llcorner p -- lrcorner p) fi enddef ;
+vardef rightboundary primary p = if pair p : p else : (lrcorner p -- urcorner p) fi enddef ;
+vardef topboundary primary p = if pair p : p else : (urcorner p -- ulcorner p) fi enddef ;
+vardef leftboundary primary p = if pair p : p else : (ulcorner p -- llcorner p) fi enddef ;
+
+%D Nice too:
+
+primarydef p superellipsed s =
+ superellipse (
+ .5[lrcorner p,urcorner p],
+ .5[urcorner p,ulcorner p],
+ .5[ulcorner p,llcorner p],
+ .5[llcorner p,lrcorner p],
+ s
+ )
+enddef ;
+
+primarydef p squeezed s = (
+ (llcorner p .. .5[llcorner p,lrcorner p] shifted ( 0, ypart paired(s)) .. lrcorner p) &
+ (lrcorner p .. .5[lrcorner p,urcorner p] shifted (-xpart paired(s), 0) .. urcorner p) &
+ (urcorner p .. .5[urcorner p,ulcorner p] shifted ( 0,-ypart paired(s)) .. ulcorner p) &
+ (ulcorner p .. .5[ulcorner p,llcorner p] shifted ( xpart paired(s), 0) .. llcorner p) & cycle
+) enddef ;
+
+primarydef p randomshifted s =
+ begingroup ;
+ save ss ; pair ss ;
+ ss := paired(s) ;
+ p shifted (-.5xpart ss + uniformdeviate xpart ss,-.5ypart ss + uniformdeviate ypart ss)
+ endgroup
+enddef ;
+
+primarydef p randomized s = (
+ if path p :
+ for i=0 upto length(p)-1 :
+ ((point i of p) randomshifted s) .. controls
+ ((postcontrol i of p) randomshifted s) and
+ ((precontrol (i+1) of p) randomshifted s) ..
+ endfor
+ if cycle p :
+ cycle
+ else :
+ ((point length(p) of p) randomshifted s)
+ fi
+ elseif pair p :
+ p randomshifted s
+ elseif cmykcolor p :
+ if color s :
+ ((uniformdeviate cyanpart s) * cyanpart p,
+ (uniformdeviate magentapart s) * magentapart p,
+ (uniformdeviate yellowpart s) * yellowpart p,
+ (uniformdeviate blackpart s) * blackpart p)
+ elseif pair s :
+ ((xpart s + (uniformdeviate (ypart s - xpart s))) * p)
+ else :
+ ((uniformdeviate s) * p)
+ fi
+ elseif rgbcolor p :
+ if color s :
+ ((uniformdeviate redpart s) * redpart p,
+ (uniformdeviate greenpart s) * greenpart p,
+ (uniformdeviate bluepart s) * bluepart p)
+ elseif pair s :
+ ((xpart s + (uniformdeviate (ypart s - xpart s))) * p)
+ else :
+ ((uniformdeviate s) * p)
+ fi
+ elseif color p :
+ if color s :
+ ((uniformdeviate greypart s) * greypart p)
+ elseif pair s :
+ ((xpart s + (uniformdeviate (ypart s - xpart s))) * p)
+ else :
+ ((uniformdeviate s) * p)
+ fi
+ else :
+ p + uniformdeviate s
+ fi
+) enddef ;
+
+%D Not perfect (alternative for interpath)
+
+vardef interpolated(expr s, p, q) =
+ save m ; numeric m ;
+ m := max(length(p),length(q)) ;
+ if path p :
+ for i=0 upto m-1 :
+ s[point (i /m) along p,point (i /m) along q] .. controls
+ s[postcontrol (i /m) along p,postcontrol (i /m) along q] and
+ s[precontrol ((i+1)/m) along p,precontrol ((i+1)/m) along q] ..
+ endfor
+ if cycle p :
+ cycle
+ else :
+ s[point infinity of p,point infinity of q]
+ fi
+ else :
+ a[p,q]
+ fi
+enddef ;
+
+%D Interesting too:
+
+primarydef p paralleled d = (
+ p shifted if d < 0 : - fi ((point abs(d) on (p rotatedaround(point 0 of p,90))) - point 0 of p)
+) enddef ;
+
+vardef punked primary p =
+ point 0 of p for i=1 upto length(p)-1 : -- point i of p endfor
+ if cycle p : -- cycle else : -- point length(p) of p fi
+enddef ;
+
+vardef curved primary p =
+ point 0 of p for i=1 upto length(p)-1 : .. point i of p endfor
+ if cycle p : .. cycle else : .. point length(p) of p fi
+enddef ;
+
+primarydef p blownup s =
+ begingroup
+ save _p_ ; path _p_ ;
+ _p_ := p xysized (bbwidth(p)+2(xpart paired(s)),bbheight(p)+2(ypart paired(s))) ;
+ (_p_ shifted (center p - center _p_))
+ endgroup
+enddef ;
+
+%D Rather fundamental.
+
+% not yet ok
+
+vardef leftrightpath(expr p, l) = % used in s-pre-19
+ save q, r, t, b ; path q, r ; pair t, b ;
+ t := (ulcorner p -- urcorner p) intersection_point p ;
+ b := (llcorner p -- lrcorner p) intersection_point p ;
+ r := if xpart directionpoint t of p < 0 : reverse p else : p fi ; % r is needed, else problems when reverse is fed
+ q := r cutbefore if l: t else: b fi ;
+ q := q if xpart point 0 of r > 0 : & r fi cutafter if l: b else: t fi ;
+ q
+enddef ;
+
+vardef leftpath expr p = leftrightpath(p,true ) enddef ;
+vardef rightpath expr p = leftrightpath(p,false) enddef ;
+
+%D Drawoptions
+
+def saveoptions =
+ save _op_ ; def _op_ = enddef ;
+enddef ;
+
+%D Tracing. (not yet in lexer)
+
+let normaldraw = draw ;
+let normalfill = fill ;
+
+% bugged in mplib so ...
+
+def normalfill expr c = addto currentpicture contour c _op_ enddef ;
+def normaldraw expr p = addto currentpicture if picture p: also p else: doublepath p withpen currentpen fi _op_ enddef ;
+
+def drawlineoptions (text t) = def _lin_opt_ = t enddef ; enddef ;
+def drawpointoptions (text t) = def _pnt_opt_ = t enddef ; enddef ;
+def drawcontroloptions(text t) = def _ctr_opt_ = t enddef ; enddef ;
+def drawlabeloptions (text t) = def _lab_opt_ = t enddef ; enddef ;
+def draworiginoptions (text t) = def _ori_opt_ = t enddef ; enddef ;
+def drawboundoptions (text t) = def _bnd_opt_ = t enddef ; enddef ;
+def drawpathoptions (text t) = def _pth_opt_ = t enddef ; enddef ;
+
+def resetdrawoptions =
+ drawlineoptions (withpen pencircle scaled 1pt withcolor .5white) ;
+ drawpointoptions (withpen pencircle scaled 4pt withcolor black) ;
+ drawcontroloptions(withpen pencircle scaled 2.5pt withcolor black) ;
+ drawlabeloptions () ;
+ draworiginoptions (withpen pencircle scaled 1pt withcolor .5white) ;
+ drawboundoptions (dashed evenly _ori_opt_) ;
+ drawpathoptions (withpen pencircle scaled 5pt withcolor .8white) ;
+enddef ;
+
+resetdrawoptions ;
+
+%D Path.
+
+def drawpath expr p =
+ normaldraw p _pth_opt_
+enddef ;
+
+%D Arrow.
+
+vardef drawarrowpath expr p =
+ save autoarrows ; boolean autoarrows ; autoarrows := true ;
+ drawarrow p _pth_opt_
+enddef ;
+
+% def drawarrowpath expr p =
+% begingroup ;
+% save autoarrows ; boolean autoarrows ; autoarrows := true ;
+% save arrowpath ; path arrowpath ; arrowpath := p ;
+% _drawarrowpath_
+% enddef ;
+%
+% def _drawarrowpath_ text t =
+% drawarrow arrowpath _pth_opt_ t ;
+% endgroup ;
+% enddef ;
+
+def midarrowhead expr p =
+ arrowhead p cutafter (point length(p cutafter point .5 along p)+ahlength on p)
+enddef ;
+
+vardef arrowheadonpath (expr p, s) =
+ save autoarrows ; boolean autoarrows ;
+ autoarrows := true ;
+ set_ahlength(scaled ahfactor) ; % added
+ arrowhead p if s<1 : cutafter (point (s*arclength(p)+.5ahlength) on p) fi
+enddef ;
+
+%D Points.
+
+def drawpoint expr c =
+ if string c :
+ string _c_ ;
+ _c_ := "(" & c & ")" ;
+ dotlabel.urt(_c_, scantokens _c_) ;
+ drawdot scantokens _c_
+ else :
+ dotlabel.urt("(" & decimal xpart c & "," & decimal ypart c & ")", c) ;
+ drawdot c
+ fi _pnt_opt_
+enddef ;
+
+%D PathPoints.
+
+def drawpoints expr c = path _c_ ; _c_ := c ; mfun_draw_points enddef ;
+def drawcontrolpoints expr c = path _c_ ; _c_ := c ; mfun_draw_controlpoints enddef ;
+def drawcontrollines expr c = path _c_ ; _c_ := c ; mfun_draw_controllines enddef ;
+def drawpointlabels expr c = path _c_ ; _c_ := c ; mfun_draw_pointlabels enddef ;
+
+def mfun_draw_points text t =
+ for _i_=0 upto length(_c_) :
+ normaldraw point _i_ of _c_ _pnt_opt_ t ;
+ endfor ;
+enddef;
+
+def mfun_draw_controlpoints text t =
+ for _i_=0 upto length(_c_) :
+ normaldraw precontrol _i_ of _c_ _ctr_opt_ t ;
+ normaldraw postcontrol _i_ of _c_ _ctr_opt_ t ;
+ endfor ;
+enddef;
+
+def mfun_draw_controllines text t =
+ for _i_=0 upto length(_c_) :
+ normaldraw point _i_ of _c_ -- precontrol _i_ of _c_ _lin_opt_ t ;
+ normaldraw point _i_ of _c_ -- postcontrol _i_ of _c_ _lin_opt_ t ;
+ endfor ;
+enddef;
+
+boolean swappointlabels ; swappointlabels := false ;
+
+def mfun_draw_pointlabels text t =
+ for _i_=0 upto length(_c_) :
+ pair _u_ ; _u_ := unitvector(direction _i_ of _c_) rotated if swappointlabels : - fi 90 ;
+ pair _p_ ; _p_ := (point _i_ of _c_) ;
+ _u_ := 12 * defaultscale * _u_ ;
+ normaldraw thelabel ( decimal _i_, _p_ shifted if cycle _c_ and (_i_=0) : - fi _u_ ) _lab_opt_ t ;
+ endfor ;
+enddef;
+
+%D Bounding box.
+
+def drawboundingbox expr p =
+ normaldraw boundingbox p _bnd_opt_
+enddef ;
+
+%D Origin.
+
+numeric originlength ; originlength := .5cm ;
+
+def draworigin text t =
+ normaldraw (origin shifted (0, originlength) -- origin shifted (0,-originlength)) _ori_opt_ t ;
+ normaldraw (origin shifted ( originlength,0) -- origin shifted (-originlength,0)) _ori_opt_ t ;
+enddef;
+
+%D Axis.
+
+numeric tickstep ; tickstep := 5mm ;
+numeric ticklength ; ticklength := 2mm ;
+
+def drawxticks expr c = path _c_ ; _c_ := c ; mfun_draw_xticks enddef ;
+def drawyticks expr c = path _c_ ; _c_ := c ; mfun_draw_yticks enddef ;
+def drawticks expr c = path _c_ ; _c_ := c ; mfun_draw_ticks enddef ;
+
+% Adding eps prevents disappearance due to rounding errors.
+
+def mfun_draw_xticks text t =
+ for i=0 step -tickstep until xpart llcorner _c_ - eps :
+ if (i<=xpart lrcorner _c_) :
+ normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ for i=0 step tickstep until xpart lrcorner _c_ + eps :
+ if (i>=xpart llcorner _c_) :
+ normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ normaldraw (llcorner _c_ -- ulcorner _c_) shifted (-xpart llcorner _c_,0) _ori_opt_ t ;
+enddef ;
+
+def mfun_draw_yticks text t =
+ for i=0 step -tickstep until ypart llcorner _c_ - eps :
+ if (i<=ypart ulcorner _c_) :
+ normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ for i=0 step tickstep until ypart ulcorner _c_ + eps :
+ if (i>=ypart llcorner _c_) :
+ normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ;
+ fi ;
+ endfor ;
+ normaldraw (llcorner _c_ -- lrcorner _c_) shifted (0,-ypart llcorner _c_) _ori_opt_ t ;
+enddef ;
+
+def mfun_draw_ticks text t =
+ drawxticks _c_ t ;
+ drawyticks _c_ t ;
+enddef ;
+
+%D All of it except axis.
+
+def drawwholepath expr p =
+ draworigin ;
+ drawpath p ;
+ drawcontrollines p ;
+ drawcontrolpoints p ;
+ drawpoints p ;
+ drawboundingbox p ;
+ drawpointlabels p ;
+enddef ;
+
+%D Tracing.
+
+def visualizeddraw expr c =
+ if picture c : normaldraw c else : path _c_ ; _c_ := c ; do_visualizeddraw fi
+enddef ;
+
+def visualizedfill expr c =
+ if picture c : normalfill c else : path _c_ ; _c_ := c ; do_visualizedfill fi
+enddef ;
+
+def do_visualizeddraw text t =
+ draworigin ;
+ drawpath _c_ t ;
+ drawcontrollines _c_ ;
+ drawcontrolpoints _c_ ;
+ drawpoints _c_ ;
+ drawboundingbox _c_ ;
+ drawpointlabels _c_ ;
+enddef ;
+
+def do_visualizedfill text t =
+ if cycle _c_ : normalfill _c_ t fi ;
+ draworigin ;
+ drawcontrollines _c_ ;
+ drawcontrolpoints _c_ ;
+ drawpoints _c_ ;
+ drawboundingbox _c_ ;
+ drawpointlabels _c_ ;
+enddef ;
+
+def visualizepaths =
+ let fill = visualizedfill ;
+ let draw = visualizeddraw ;
+enddef ;
+
+def naturalizepaths =
+ let fill = normalfill ;
+ let draw = normaldraw ;
+enddef ;
+
+extra_endfig := extra_endfig & " naturalizepaths ; " ;
+
+%D Nice tracer:
+
+def drawboundary primary p =
+ draw p dashed evenly withcolor white ;
+ draw p dashed oddly withcolor black ;
+ draw (- llcorner p) withpen pencircle scaled 3 withcolor white ;
+ draw (- llcorner p) withpen pencircle scaled 1.5 withcolor black ;
+enddef ;
+
+%D Also handy:
+
+extra_beginfig := extra_beginfig & " truecorners := 0 ; " ; % restores
+extra_beginfig := extra_beginfig & " miterlimit := 10 ; " ; % restores
+extra_beginfig := extra_beginfig & " linejoin := rounded ; " ; % restores
+extra_beginfig := extra_beginfig & " linecap := rounded ; " ; % restores
+
+%D Normally, arrowheads don't scale well. So we provide a
+%D hack.
+
+boolean autoarrows ; autoarrows := false ;
+numeric ahfactor ; ahfactor := 2.5 ;
+
+def set_ahlength (text t) =
+ % ahlength := (ahfactor*pen_size(_op_ t)) ; % _op_ added
+ % problem: _op_ can contain color so a no-go, we could apply the transform
+ % but i need to figure out the best way (fakepicture and take components).
+ ahlength := (ahfactor*pen_size(t)) ;
+enddef ;
+
+vardef pen_size (text t) =
+ save p ; picture p ; p := nullpicture ;
+ addto p doublepath (top origin -- bot origin) t ;
+ (ypart urcorner p - ypart lrcorner p)
+enddef ;
+
+%D The next two macros are adapted versions of plain
+%D \METAPOST\ definitions.
+
+vardef arrowpath expr p = % patch by Peter Rolf: supports squared pen and shifting (hh: maybe just use center of head as first)
+ (p cutafter makepath(pencircle scaled 2(ahlength*cosd(.5ahangle)) shifted point length p of p))
+enddef;
+
+% def _finarr text t =
+% if autoarrows : set_ahlength (t) fi ;
+% draw arrowpath _apth t ; % arrowpath added
+% filldraw arrowhead _apth t ;
+% enddef;
+
+def _finarr text t =
+ if autoarrows : set_ahlength (t) fi ;
+ draw arrowpath _apth t ; % arrowpath added
+ fill arrowhead _apth t ;
+ draw arrowhead _apth t ;
+enddef;
+
+def _finarr text t =
+ if autoarrows : set_ahlength (t) fi ;
+ draw arrowpath _apth t ; % arrowpath added
+ fill arrowhead _apth t ;
+ draw arrowhead _apth t undashed ;
+enddef;
+
+%D Handy too ......
+
+vardef pointarrow (expr pat, loc, len, off) =
+ save l, r, s, t ; path l, r ; numeric s ; pair t ;
+ t := if pair loc : loc else : point loc along pat fi ;
+ s := len/2 - off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ r := pat cutbefore t ;
+ r := (r cutafter point (arctime s of r) of r) ;
+ s := len/2 + off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ l := reverse (pat cutafter t) ;
+ l := (reverse (l cutafter point (arctime s of l) of l)) ;
+ (l..r)
+enddef ;
+
+def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ;
+def leftarrow (expr pat,tim,len) = pointarrow(pat,tim,len,+len) enddef ;
+def centerarrow (expr pat,tim,len) = pointarrow(pat,tim,len, 0) enddef ;
+
+%D The \type {along} and \type {on} operators can be used
+%D as follows:
+%D
+%D \starttyping
+%D drawdot point .5 along somepath ;
+%D drawdot point 3cm on somepath ;
+%D \stoptyping
+%D
+%D The number denotes a percentage (fraction).
+
+primarydef pct along pat = % also negative
+ (arctime (pct * (arclength pat)) of pat) of pat
+enddef ;
+
+primarydef len on pat = % no outer ( ) .. somehow fails
+ (arctime if len>=0 : len else : (arclength(pat)+len) fi of pat) of pat
+enddef ;
+
+% this cuts of a piece from both ends
+
+% tertiarydef pat cutends len =
+% begingroup ; save tap ; path tap ;
+% tap := pat cutbefore (point len on pat) ;
+% (tap cutafter (point -len on tap))
+% endgroup
+% enddef ;
+
+tertiarydef pat cutends len =
+ begingroup
+ save tap ; path tap ;
+ tap := pat cutbefore (point (xpart paired(len)) on pat) ;
+ (tap cutafter (point -(ypart paired(len)) on tap))
+ endgroup
+enddef ;
+
+%D To be documented.
+
+path freesquare ;
+
+freesquare := (
+ (-1,0) -- (-1,-1) -- (0,-1) -- (+1,-1) --
+ (+1,0) -- (+1,+1) -- (0,+1) -- (-1,+1) -- cycle
+) scaled .5 ;
+
+numeric freelabeloffset ; freelabeloffset := 3pt ;
+numeric freedotlabelsize ; freedotlabelsize := 3pt ;
+
+vardef thefreelabel (expr str, loc, ori) =
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ interim labeloffset := freelabeloffset ;
+ s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ;
+ setbounds s to boundingbox s enlarged freelabeloffset ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point xpart (p intersectiontimes (ori--loc shifted (loc-ori))) of q ;
+ setbounds s to boundingbox s enlarged -freelabeloffset ; % new
+ % draw boundingbox s shifted -l withpen pencircle scaled .5pt withcolor red ;
+ (s shifted -l)
+enddef ;
+
+vardef freelabel (expr str, loc, ori) =
+ draw thefreelabel(str,loc,ori) ;
+enddef ;
+
+vardef freedotlabel (expr str, loc, ori) =
+ interim linecap := rounded ;
+ draw loc withpen pencircle scaled freedotlabelsize ;
+ draw thefreelabel(str,loc,ori) ;
+enddef ;
+
+%D \starttyping
+%D drawarrow anglebetween(line_a,line_b,somelabel) ;
+%D \stoptyping
+
+newinternal angleoffset ; angleoffset := 0pt ;
+newinternal anglelength ; anglelength := 20pt ;
+newinternal anglemethod ; anglemethod := 1 ;
+
+% vardef anglebetween (expr a, b, str) = % path path string
+% save pointa, pointb, common, middle, offset ;
+% pair pointa, pointb, common, middle, offset ;
+% save curve ; path curve ;
+% save where ; numeric where ;
+% if round point 0 of a = round point 0 of b :
+% common := point 0 of a ;
+% else :
+% common := a intersectionpoint b ;
+% fi ;
+% pointa := point anglelength on a ;
+% pointb := point anglelength on b ;
+% where := turningnumber (common--pointa--pointb--cycle) ;
+% middle := ((common--pointa) rotatedaround (pointa,-where*90))
+% intersectionpoint
+% ((common--pointb) rotatedaround (pointb, where*90)) ;
+% if anglemethod = 0 :
+% curve := pointa{unitvector(middle-pointa)}.. pointb;
+% middle := point .5 along curve ;
+% curve := common ;
+% elseif anglemethod = 1 :
+% curve := pointa{unitvector(middle-pointa)}.. pointb;
+% middle := point .5 along curve ;
+% elseif anglemethod = 2 :
+% middle := common rotatedaround(.5[pointa,pointb],180) ;
+% curve := pointa--middle--pointb ;
+% elseif anglemethod = 3 :
+% curve := pointa--middle--pointb ;
+% elseif anglemethod = 4 :
+% curve := pointa..controls middle..pointb ;
+% middle := point .5 along curve ;
+% fi ;
+% draw thefreelabel(str, middle, common) withcolor black ;
+% curve
+% enddef ;
+
+vardef anglebetween (expr a, b, str) = % path path string
+ save pointa, pointb, common, middle, offset ;
+ pair pointa, pointb, common, middle, offset ;
+ save curve ; path curve ;
+ save where ; numeric where ;
+ if round point 0 of a = round point 0 of b :
+ common := point 0 of a ;
+ else :
+ common := a intersectionpoint b ;
+ fi ;
+ pointa := point anglelength on a ;
+ pointb := point anglelength on b ;
+ where := turningnumber (common--pointa--pointb--cycle) ;
+ middle := (reverse(common--pointa) rotatedaround (pointa,-where*90))
+ intersection_point
+ (reverse(common--pointb) rotatedaround (pointb, where*90)) ;
+ if not intersection_found :
+ middle := point .5 along
+ ((reverse(common--pointa) rotatedaround (pointa,-where*90)) --
+ ( (common--pointb) rotatedaround (pointb, where*90))) ;
+ fi ;
+ if anglemethod = 0 :
+ curve := pointa{unitvector(middle-pointa)}.. pointb;
+ middle := point .5 along curve ;
+ curve := common ;
+ elseif anglemethod = 1 :
+ curve := pointa{unitvector(middle-pointa)}.. pointb;
+ middle := point .5 along curve ;
+ elseif anglemethod = 2 :
+ middle := common rotatedaround(.5[pointa,pointb],180) ;
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 3 :
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 4 :
+ curve := pointa..controls middle..pointb ;
+ middle := point .5 along curve ;
+ fi ;
+ draw thefreelabel(str, middle, common) ; % withcolor black ;
+ curve
+enddef ;
+
+% Stack
+
+picture mfun_current_picture_stack[] ;
+numeric mfun_current_picture_depth ;
+
+mfun_current_picture_depth := 0 ;
+
+def pushcurrentpicture =
+ mfun_current_picture_depth := mfun_current_picture_depth + 1 ;
+ mfun_current_picture_stack[mfun_current_picture_depth] := currentpicture ;
+ currentpicture := nullpicture ;
+enddef ;
+
+def popcurrentpicture text t = % optional text
+ if mfun_current_picture_depth > 0 :
+ addto mfun_current_picture_stack[mfun_current_picture_depth] also currentpicture t ;
+ currentpicture := mfun_current_picture_stack[mfun_current_picture_depth] ;
+ mfun_current_picture_stack[mfun_current_picture_depth] := nullpicture ;
+ mfun_current_picture_depth := mfun_current_picture_depth - 1 ;
+ fi ;
+enddef ;
+
+%D colorcircle(size, red, green, blue) ;
+
+% vardef colorcircle (expr size, red, green, blue) =
+% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ;
+% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ;
+%
+% radius := 5cm ; pickup pencircle scaled (radius/25) ;
+%
+% r := g := b := fullcircle scaled radius shifted (0,radius/4) ;
+%
+% r := r rotatedaround (origin, 15) ;
+% g := g rotatedaround (origin,135) ;
+% b := b rotatedaround (origin,255) ;
+%
+% r := r rotatedaround(center r,-90) ;
+% g := g rotatedaround(center g, 90) ;
+%
+% gg := buildcycle(buildcycle(reverse r,b),g) ;
+% cc := buildcycle(buildcycle(b,reverse g),r) ;
+%
+% rr := gg rotatedaround(origin,120) ;
+% bb := gg rotatedaround(origin,240) ;
+%
+% yy := cc rotatedaround(origin,120) ;
+% mm := cc rotatedaround(origin,240) ;
+%
+% pushcurrentpicture ;
+%
+% fill fullcircle scaled radius withcolor white ;
+%
+% fill rr withcolor red ; fill cc withcolor white-red ;
+% fill gg withcolor green ; fill mm withcolor white-green ;
+% fill bb withcolor blue ; fill yy withcolor white-blue ;
+%
+% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+%
+% currentpicture := currentpicture xsized size ;
+%
+% popcurrentpicture ;
+% enddef ;
+
+% vardef colorcircle (expr size, red, green, blue) =
+% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ;
+% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ;
+%
+% radius := 5cm ; pickup pencircle scaled (radius/25) ;
+%
+% transform t ; t := identity rotatedaround(origin,120) ;
+%
+% r := fullcircle scaled radius
+% shifted (0,radius/4) rotatedaround(origin,15) ;
+%
+% g := r transformed t ; b := g transformed t ;
+%
+% r := r rotatedaround(center r,-90) ;
+% g := g rotatedaround(center g, 90) ;
+%
+% gg := buildcycle(buildcycle(reverse r,b),g) ;
+% cc := buildcycle(buildcycle(b,reverse g),r) ;
+%
+% rr := gg transformed t ; bb := rr transformed t ;
+% yy := cc transformed t ; mm := yy transformed t ;
+%
+% pushcurrentpicture ;
+%
+% fill fullcircle scaled radius withcolor white ;
+%
+% fill rr withcolor red ; fill cc withcolor white-red ;
+% fill gg withcolor green ; fill mm withcolor white-green ;
+% fill bb withcolor blue ; fill yy withcolor white-blue ;
+%
+% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+%
+% currentpicture := currentpicture xsized size ;
+%
+% popcurrentpicture ;
+% enddef ;
+
+vardef colorcircle (expr size, red, green, blue) = % might move
+ save r, g, b, c, m, y, w ; save radius ;
+ path r, g, b, c, m, y, w ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ transform t ; t := identity rotatedaround(origin,120) ;
+
+ r := fullcircle rotated 90 scaled radius shifted (0,radius/4) rotatedaround(origin,135) ;
+
+ b := r transformed t ; g := b transformed t ;
+
+ c := buildcycle(subpath(1,7) of g,subpath(1,7) of b) ;
+ y := c transformed t ; m := y transformed t ;
+
+ w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ;
+
+ pushcurrentpicture ;
+
+ fill r withcolor red ;
+ fill g withcolor green ;
+ fill b withcolor blue ;
+ fill c withcolor white - red ;
+ fill m withcolor white - green ;
+ fill y withcolor white - blue ;
+ fill w withcolor white ;
+
+ for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+
+ popcurrentpicture ;
+enddef ;
+
+% penpoint (i,2) of somepath -> inner / outer point
+
+vardef penpoint expr pnt of p =
+ save n, d ; numeric n, d ;
+ (n,d) = if pair pnt : pnt else : (pnt,1) fi ;
+ (point n of p shifted ((penoffset direction n of p of currentpen) scaled d))
+enddef ;
+
+% nice: currentpicture := inverted currentpicture ;
+
+primarydef p uncolored c =
+ if color p :
+ c - p
+ else :
+ image (
+ for i within p :
+ addto currentpicture
+ if stroked i or filled i :
+ if filled i :
+ contour
+ else :
+ doublepath
+ fi
+ pathpart i
+ dashed dashpart i withpen penpart i
+ else :
+ also i
+ fi
+ withcolor c-(redpart i, greenpart i, bluepart i) ;
+ endfor ;
+ )
+ fi
+enddef ;
+
+vardef inverted primary p =
+ p uncolored white
+enddef ;
+
+% primarydef p softened c =
+% if color p :
+% tripled(c) * p
+% else :
+% image
+% (save cc ; color cc ; cc := tripled(c) ;
+% for i within p :
+% addto currentpicture
+% if stroked i or filled i :
+% if filled i : contour else : doublepath fi pathpart i
+% dashed dashpart i withpen penpart i
+% else :
+% also i
+% fi
+% withcolor (redpart cc * redpart i,
+% greenpart cc * greenpart i,
+% bluepart cc * bluepart i) ;
+% endfor ;)
+% fi
+% enddef ;
+
+primarydef p softened c =
+ begingroup
+ save cc ; color cc ; cc := tripled(c) ;
+ if color p :
+ (redpart cc * redpart p,greenpart cc * greenpart p, bluepart cc * bluepart p)
+ else :
+ image (
+ for i within p :
+ addto currentpicture
+ if stroked i or filled i :
+ if filled i :
+ contour
+ else :
+ doublepath
+ fi
+ pathpart i
+ dashed dashpart i withpen penpart i
+ else :
+ also i
+ fi
+ withcolor (redpart cc * redpart i, greenpart cc * greenpart i, bluepart cc * bluepart i) ;
+ endfor ;
+ )
+ fi
+ endgroup
+enddef ;
+
+vardef grayed primary p =
+ if color p :
+ tripled(.30redpart p+.59greenpart p+.11bluepart p)
+ else :
+ image (
+ for i within p :
+ addto currentpicture
+ if stroked i or filled i :
+ if filled i :
+ contour
+ else :
+ doublepath
+ fi
+ pathpart i
+ dashed dashpart i
+ withpen penpart i
+ else :
+ also i
+ fi
+ withcolor tripled(.30redpart i+.59greenpart i+.11bluepart i) ;
+ endfor ;
+ )
+ fi
+enddef ;
+
+% yes or no: "text" infont "cmr12" at 24pt ;
+
+% let normalinfont = infont ;
+%
+% numeric lastfontsize ; lastfontsize = fontsize defaultfont ;
+%
+% def infont primary name = % no vardef, no expr
+% hide(lastfontsize := fontsize name) % no ;
+% normalinfont name
+% enddef ;
+%
+% def scaledat expr size =
+% scaled (size/lastfontsize)
+% enddef ;
+%
+% let at = scaledat ;
+
+% like decimal
+
+def condition primary b = if b : "true" else : "false" fi enddef ;
+
+% undocumented
+
+primarydef p stretched s =
+ begingroup
+ save pp ; path pp ; pp := p xyscaled s ;
+ (pp shifted ((point 0 of p) - (point 0 of pp)))
+ endgroup
+enddef ;
+
+% primarydef p enlonged len =
+% begingroup
+% save al ; al := arclength(p) ;
+% if al > 0 :
+% if pair p :
+% point 1 of ((origin -- p) stretched ((al+len)/al))
+% else :
+% p stretched ((al+len)/al)
+% fi
+% else :
+% p
+% fi
+% endgroup
+% enddef ;
+
+primarydef p enlonged len =
+ begingroup
+ if len == 0 :
+ p
+ elseif pair p :
+ save q ; path q ; q := origin -- p ;
+ save al ; al := arclength(q) ;
+ if al > 0 :
+ point 1 of (q stretched ((al+len)/al))
+ else :
+ p
+ fi
+ else :
+ save al ; al := arclength(p) ;
+ if al > 0 :
+ p stretched ((al+len)/al)
+ else :
+ p
+ fi
+ fi
+ endgroup
+enddef ;
+
+% path p ; p := (0,0) -- (10cm,5cm) ;
+% drawarrow p withcolor red ;
+% drawarrow p shortened 1cm withcolor green ;
+
+% primarydef p shortened d =
+% reverse ( ( reverse (p enlonged -d) ) enlonged -d )
+% enddef ;
+
+primarydef p shortened d =
+ reverse ( ( reverse (p enlonged -xpart paired(d)) ) enlonged -ypart paired(d) )
+enddef ;
+
+% yes or no, untested -)
+
+def xshifted expr dx = shifted(dx,0) enddef ;
+def yshifted expr dy = shifted(0,dy) enddef ;
+
+% also handy
+
+% right: str = readfrom ("abc" & ".def" ) ;
+% wrong: str = readfrom "abc" & ".def" ;
+
+% Every 62th read fails so we need to try again!
+
+% def readfile (expr name) =
+% if (readfrom (name) <> EOF) :
+% scantokens("input " & name & ";") ;
+% elseif (readfrom (name) <> EOF) :
+% scantokens("input " & name & ";") ;
+% fi ;
+% closefrom (name) ;
+% enddef ;
+%
+% this sometimes fails on the elseif, so :
+%
+
+def readfile (expr name) =
+ begingroup ; save ok ; boolean ok ;
+ if (readfrom (name) <> EOF) :
+ ok := false ;
+ elseif (readfrom (name) <> EOF) :
+ ok := false ;
+ else :
+ ok := true ;
+ fi ;
+ if not ok :
+ scantokens("input " & name & " ") ;
+ fi ;
+ closefrom (name) ;
+ endgroup ;
+enddef ;
+
+% permits redefinition of end in macro
+
+inner end ;
+
+% this will be redone (when needed) using scripts and backend handling
+
+let normalwithcolor = withcolor ;
+
+def remapcolors =
+ def withcolor primary c = normalwithcolor remappedcolor(c) enddef ;
+enddef ;
+
+def normalcolors =
+ let withcolor = normalwithcolor ;
+enddef ;
+
+def resetcolormap =
+ color color_map[][][] ;
+ normalcolors ;
+enddef ;
+
+resetcolormap ;
+
+% color_map_resolution := 1000 ;
+%
+% def r_color primary c = round(color_map_resolution*redpart c) enddef ;
+% def g_color primary c = round(color_map_resolution*greenpart c) enddef ;
+% def b_color primary c = round(color_map_resolution*bluepart c) enddef ;
+
+def r_color primary c = redpart c enddef ;
+def g_color primary c = greenpart c enddef ;
+def b_color primary c = bluepart c enddef ;
+
+def remapcolor(expr old, new) =
+ color_map[redpart old][greenpart old][bluepart old] := new ;
+enddef ;
+
+def remappedcolor(expr c) =
+ if known color_map[redpart c][greenpart c][bluepart c] :
+ color_map[redpart c][greenpart c][bluepart c]
+ else :
+ c
+ fi
+enddef ;
+
+% def refill suffix c = do_repath (1) (c) enddef ;
+% def redraw suffix c = do_repath (2) (c) enddef ;
+% def recolor suffix c = do_repath (0) (c) enddef ;
+%
+% color refillbackground ; refillbackground := (1,1,1) ;
+%
+% def do_repath (expr mode) (suffix c) text t = % can it be stroked and filled at the same time ?
+% begingroup ;
+% if mode=0 : save withcolor ; remapcolors ; fi ;
+% save _c_, _cc_, _f_, _b_ ; picture _c_, _cc_ ; color _f_ ; path _b_ ;
+% _c_ := c ; _b_ := boundingbox c ; c := nullpicture ;
+% for i within _c_ :
+% _f_ := (redpart i, greenpart i, bluepart i) ;
+% if bounded i :
+% setbounds c to pathpart i ;
+% elseif clipped i :
+% clip c to pathpart i ;
+% elseif stroked i :
+% addto c doublepath pathpart i
+% dashed dashpart i withpen penpart i
+% withcolor _f_ % (redpart i, greenpart i, bluepart i)
+% if mode=2 : t fi ;
+% elseif filled i :
+% addto c contour pathpart i
+% withcolor _f_
+% if (mode=1) and (_f_<>refillbackground) : t fi ;
+% else :
+% addto c also i ;
+% fi ;
+% endfor ;
+% setbounds c to _b_ ;
+% endgroup ;
+% enddef ;
+
+% Thanks to Jens-Uwe Morawski for pointing out that we need
+% to treat bounded and clipped components as local pictures.
+
+def recolor suffix p = p := repathed (0,p) enddef ;
+def refill suffix p = p := repathed (1,p) enddef ;
+def redraw suffix p = p := repathed (2,p) enddef ;
+def retext suffix p = p := repathed (3,p) enddef ;
+def untext suffix p = p := repathed (4,p) enddef ;
+
+% primarydef p recolored t = repathed(0,p) t enddef ;
+% primarydef p refilled t = repathed(1,p) t enddef ;
+% primarydef p redrawn t = repathed(2,p) t enddef ;
+% primarydef p retexted t = repathed(3,p) t enddef ;
+% primarydef p untexted t = repathed(4,p) t enddef ;
+
+color refillbackground ; refillbackground := (1,1,1) ;
+
+% vardef repathed (expr mode, p) text t =
+% begingroup ;
+% if mode=0 : save withcolor ; remapcolors ; fi ;
+% save _p_, _pp_, _f_, _b_, _t_ ;
+% picture _p_, _pp_ ; color _f_ ; path _b_ ; transform _t_ ;
+% _b_ := boundingbox p ; _p_ := nullpicture ;
+% for i within p :
+% _f_ := (redpart i, greenpart i, bluepart i) ;
+% if bounded i :
+% _pp_ := repathed(mode,i) t ;
+% setbounds _pp_ to pathpart i ;
+% addto _p_ also _pp_ ;
+% elseif clipped i :
+% _pp_ := repathed(mode,i) t ;
+% clip _pp_ to pathpart i ;
+% addto _p_ also _pp_ ;
+% elseif stroked i :
+% addto _p_ doublepath pathpart i
+% dashed dashpart i withpen penpart i
+% withcolor _f_ % (redpart i, greenpart i, bluepart i)
+% if mode=2 : t fi ;
+% elseif filled i :
+% addto _p_ contour pathpart i
+% withcolor _f_
+% if (mode=1) and (_f_<>refillbackground) : t fi ;
+% elseif textual i : % textpart i <> "" :
+% if mode <> 4 :
+% % transform _t_ ;
+% % (xpart _t_, xxpart _t_, xypart _t_) = (xpart i, xxpart i, xypart i) ;
+% % (ypart _t_, yypart _t_, yxpart _t_) = (ypart i, yypart i, yxpart i) ;
+% % addto _p_ also
+% % textpart i infont fontpart i % todo : other font
+% % transformed _t_
+% % withpen penpart i
+% % withcolor _f_
+% % if mode=3 : t fi ;
+% addto _p_ also i if mode=3 : t fi ;
+% fi ;
+% else :
+% addto _p_ also i ;
+% fi ;
+% endfor ;
+% setbounds _p_ to _b_ ;
+% _p_
+% endgroup
+% enddef ;
+
+def restroke suffix p = p := repathed (21,p) enddef ; % keep attributes
+def reprocess suffix p = p := repathed (22,p) enddef ; % no attributes
+
+% also 11 and 12
+
+vardef repathed (expr mode, p) text t =
+ begingroup ;
+ if mode = 0 :
+ save withcolor ;
+ remapcolors ;
+ fi ;
+ save _p_, _pp_, _ppp_, _f_, _b_, _t_ ;
+ picture _p_, _pp_, _ppp_ ; color _f_ ; path _b_ ; transform _t_ ;
+ _b_ := boundingbox p ;
+ _p_ := nullpicture ;
+ for i within p :
+ _f_ := (redpart i, greenpart i, bluepart i) ;
+ if bounded i :
+ _pp_ := repathed(mode,i) t ;
+ setbounds _pp_ to pathpart i ;
+ addto _p_ also _pp_ ;
+ elseif clipped i :
+ _pp_ := repathed(mode,i) t ;
+ clip _pp_ to pathpart i ;
+ addto _p_ also _pp_ ;
+ elseif stroked i :
+ if mode=21 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")
+ dashed dashpart i withpen penpart i
+ withcolor _f_ ; ) ;
+ elseif mode=22 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
+ else :
+ addto _p_ doublepath pathpart i
+ dashed dashpart i withpen penpart i
+ withcolor _f_ % (redpart i, greenpart i, bluepart i)
+ if mode = 2 :
+ t
+ fi ;
+ fi ;
+ elseif filled i :
+ if mode=11 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")
+ withcolor _f_ ; ) ;
+ elseif mode=12 :
+ _ppp_ := i ; % indirectness is needed
+ addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
+ else :
+ addto _p_ contour pathpart i
+ withcolor _f_
+ if (mode=1) and (_f_<>refillbackground) :
+ t
+ fi ;
+ fi ;
+ elseif textual i : % textpart i <> "" :
+ if mode <> 4 :
+ % transform _t_ ;
+ % (xpart _t_, xxpart _t_, xypart _t_) = (xpart i, xxpart i, xypart i) ;
+ % (ypart _t_, yypart _t_, yxpart _t_) = (ypart i, yypart i, yxpart i) ;
+ % addto _p_ also
+ % textpart i infont fontpart i % todo : other font
+ % transformed _t_
+ % withpen penpart i
+ % withcolor _f_
+ % if mode=3 : t fi ;
+ addto _p_ also i
+ if mode=3 :
+ t
+ fi ;
+ fi ;
+ else :
+ addto _p_ also i ;
+ fi ;
+ endfor ;
+ setbounds _p_ to _b_ ;
+ _p_
+ endgroup
+enddef ;
+
+% After a question of Denis on how to erase a z variable, Jacko
+% suggested to assign whatever to x and y. So a clearz
+% variable can be defined as:
+%
+% vardef clearz@# =
+% x@# := whatever ;
+% y@# := whatever ;
+% enddef ;
+%
+% but Jacko suggested a redefinition of clearxy:
+%
+% def clearxy text s =
+% clearxy_index_:=0;
+% for $:=s:
+% clearxy_index_:=clearxy_index_+1; endfor;
+% if clearxy_index_=0:
+% save x,y;
+% else:
+% forsuffixes $:=s: x$:=whatever; y$:=whatever; endfor;
+% fi
+% enddef;
+%
+% which i decided to simplify to:
+
+def clearxy text s =
+ if false for $ := s : or true endfor :
+ forsuffixes $ := s : x$ := whatever ; y$ := whatever ; endfor ;
+ else :
+ save x, y ;
+ fi
+enddef ;
+
+% so now we can say: clearxy ; as well as clearxy 1, 2, 3 ;
+
+% show x0 ; z0 = (10,10) ;
+% show x0 ; x0 := whatever ; y0 := whatever ;
+% show x0 ; z0 = (20,20) ;
+% show x0 ; clearxy 0 ;
+% show x0 ; z0 = (30,30) ;
+
+primarydef p smoothed d =
+ (p llmoved (-xpart paired(d),0) -- p lrmoved (-xpart paired(d),0) {right} ..
+ p lrmoved (0,-ypart paired(d)) -- p urmoved (0,-ypart paired(d)) {up} ..
+ p urmoved (-xpart paired(d),0) -- p ulmoved (-xpart paired(d),0) {left} ..
+ p ulmoved (0,-ypart paired(d)) -- p llmoved (0,-ypart paired(d)) {down} .. cycle)
+enddef ;
+
+primarydef p cornered c =
+ ((point 0 of p) shifted (c*(unitvector(point 1 of p - point 0 of p))) --
+ for i=1 upto length(p) :
+ (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) --
+ (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) ..
+ controls point i of p ..
+ endfor cycle)
+enddef ;
+
+% cmyk color support
+
+vardef cmyk(expr c,m,y,k) =
+ (1-c-k,1-m-k,1-y-k)
+enddef ;
+
+% handy
+
+% vardef bbwidth (expr p) = % vardef width_of primary p =
+% if known p :
+% if path p or picture p :
+% xpart (lrcorner p - llcorner p)
+% else :
+% 0
+% fi
+% else :
+% 0
+% fi
+% enddef ;
+
+vardef bbwidth primary p =
+ if unknown p :
+ 0
+ elseif path p or picture p :
+ xpart (lrcorner p - llcorner p)
+ else :
+ 0
+ fi
+enddef ;
+
+% vardef bbheight (expr p) = % vardef heigth_of primary p =
+% if known p :
+% if path p or picture p :
+% ypart (urcorner p - lrcorner p)
+% else :
+% 0
+% fi
+% else :
+% 0
+% fi
+% enddef ;
+
+vardef bbheight primary p =
+ if unknown p :
+ 0
+ elseif path p or picture p :
+ ypart (urcorner p - lrcorner p)
+ else :
+ 0
+ fi
+enddef ;
+
+color nocolor ; numeric noline ; % both unknown signals
+
+def dowithpath (expr p, lw, lc, bc) =
+ if known p :
+ if known bc :
+ fill p withcolor bc ;
+ fi ;
+ if known lw and known lc :
+ draw p withpen pencircle scaled lw withcolor lc ;
+ elseif known lw :
+ draw p withpen pencircle scaled lw ;
+ elseif known lc :
+ draw p withcolor lc ;
+ fi ;
+ fi ;
+enddef ;
+
+% result from metafont discussion list (denisr/boguslawj)
+
+def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ;
+def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ;
+
+let == = = ;
+
+% added
+
+picture oddly ; % evenly already defined
+
+evenly := dashpattern(on 3 off 3) ;
+oddly := dashpattern(off 3 on 3) ;
+
+% not perfect, but useful since it removes redundant points.
+
+vardef mfun_straightened(expr sign, p) =
+ save _p_, _q_ ; path _p_, _q_ ;
+ _p_ := p ;
+ forever :
+ _q_ := mfun_do_straightened(sign, _p_) ;
+ exitif length(_p_) = length(_q_) ;
+ _p_ := _q_ ;
+ endfor ;
+ _q_
+enddef ;
+
+vardef mfun_do_straightened(expr sign, p) =
+ if length(p)>2 : % was 1, but straight lines are ok
+ save pp ; path pp ;
+ pp := point 0 of p ;
+ for i=1 upto length(p)-1 :
+ if round(point i of p) <> round(point length(pp) of pp) :
+ pp := pp -- point i of p ;
+ fi ;
+ endfor ;
+ save n, ok ; numeric n ; boolean ok ;
+ n := length(pp) ; ok := false ;
+ if n>2 :
+ for i=0 upto n : % evt hier ook round
+ if unitvector(round(point i of pp - point if i=0 : n else : i-1 fi of pp)) <>
+ sign * unitvector(round(point if i=n : 0 else : i+1 fi of pp - point i of pp)) :
+ if ok :
+ --
+ else :
+ ok := true ;
+ fi point i of pp
+ fi
+ endfor
+ if ok and (cycle p) :
+ -- cycle
+ fi
+ else :
+ pp
+ fi
+ else :
+ p
+ fi
+enddef ;
+
+vardef simplified expr p = (
+ reverse mfun_straightened(+1,mfun_straightened(+1,reverse p))
+) enddef ;
+
+vardef unspiked expr p = (
+ reverse mfun_straightened(-1,mfun_straightened(-1,reverse p))
+) enddef ;
+
+% path p ;
+% p := (2cm,1cm) -- (2cm,1cm) -- (2cm,1cm) -- (3cm,1cm) --
+% (4cm,1cm) -- (4cm,2cm) -- (4cm,2.5cm) -- (4cm,3cm) --
+% (3cm,3cm) -- (2cm,3cm) -- (1cm,3cm) -- (-1cm,3cm) --
+% .5[(-1cm,3cm),(1cm,1cm)] -- (1cm,1cm) -- cycle ;
+%
+% p := unitcircle scaled 4cm ;
+%
+% drawpath p ; drawpoints p ; drawpointlabels p ;
+% p := p shifted (4cm,0) ; p := straightened p ;
+% drawpath p ; drawpoints p ; drawpointlabels p ;
+% p := p shifted (4cm,0) ; p := straightened p ;
+% drawpath p ; drawpoints p ; drawpointlabels p ;
+
+% new
+
+path originpath ; originpath := origin -- cycle ;
+
+vardef unitvector primary z =
+ if abs z = abs origin : z else : z/abs z fi
+enddef;
+
+% also new
+
+% vardef anchored@#(expr p, z) = % maybe use the textext variant
+% p shifted (z + (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))
+% enddef ;
+
+% epsed(1.2345)
+
+vardef epsed (expr e) =
+ e if e>0 : + eps elseif e<0 : - eps fi
+enddef ;
+
+% handy
+
+def withgray primary g =
+ withcolor (g,g,g)
+enddef ;
+
+% for metafun
+
+if unknown darkred : color darkred ; darkred := .625(1,0,0) fi ;
+if unknown darkgreen : color darkgreen ; darkgreen := .625(0,1,0) fi ;
+if unknown darkblue : color darkblue ; darkblue := .625(0,0,1) fi ;
+if unknown darkcyan : color darkcyan ; darkcyan := .625(0,1,1) fi ;
+if unknown darkmagenta : color darkmagenta ; darkmagenta := .625(1,0,1) fi ;
+if unknown darkyellow : color darkyellow ; darkyellow := .625(1,1,0) fi ;
+if unknown darkgray : color darkgray ; darkgray := .625(1,1,1) fi ;
+if unknown lightgray : color lightgray ; lightgray := .850(1,1,1) fi ;
+
+% an improved plain mp macro
+
+vardef center primary p =
+ if pair p :
+ p
+ else :
+ .5[llcorner p, urcorner p]
+ fi
+enddef;
+
+% new, yet undocumented
+
+vardef rangepath (expr p, d, a) =
+ if length p>0 :
+ (d*unitvector(direction 0 of p) rotated a) shifted point 0 of p
+ -- p --
+ (d*unitvector(direction length(p) of p) rotated a) shifted point length(p) of p
+ else :
+ p
+ fi
+enddef ;
+
+% under construction
+
+vardef straightpath (expr a, b, method) =
+ if (method<1) or (method>6) :
+ (a--b)
+ elseif method = 1 :
+ (a --
+ if xpart a > xpart b :
+ if ypart a > ypart b :
+ (xpart b,ypart a) --
+ elseif ypart a < ypart b :
+ (xpart a,ypart b) --
+ fi
+ elseif xpart a < xpart b :
+ if ypart a > ypart b :
+ (xpart a,ypart b) --
+ elseif ypart a < ypart b :
+ (xpart b,ypart a) --
+ fi
+ fi
+ b)
+ elseif method = 3 :
+ (a --
+ if xpart a > xpart b :
+ (xpart b,ypart a) --
+ elseif xpart a < xpart b :
+ (xpart a,ypart b) --
+ fi
+ b)
+ elseif method = 5 :
+ (a --
+ if ypart a > ypart b :
+ (xpart b,ypart a) --
+ elseif ypart a < ypart b :
+ (xpart a,ypart b) --
+ fi
+ b)
+ else :
+ (reverse straightpath(b,a,method-1))
+ fi
+enddef ;
+
+% handy for myself
+
+def addbackground text t =
+ begingroup ;
+ save p, b ; picture p ; path b ;
+ b := boundingbox currentpicture ;
+ p := currentpicture ; currentpicture := nullpicture ;
+ fill b t ;
+ setbounds currentpicture to b ;
+ addto currentpicture also p ;
+ endgroup ;
+enddef ;
+
+% makes a (line) into an infinite one (handy for calculating
+% intersection points
+
+vardef infinite expr p =
+ (-infinity*unitvector(direction 0 of p)
+ shifted point 0 of p
+ -- p --
+ +infinity*unitvector(direction length(p) of p)
+ shifted point length(p) of p)
+enddef ;
+
+% obscure macros: create var from string and replace - and :
+% (needed for process color id's) .. will go away
+
+string mfun_clean_ascii[] ;
+
+def register_dirty_chars(expr str) =
+ for i = 0 upto length(str)-1 :
+ mfun_clean_ascii[ASCII substring(i,i+1) of str] := "_" ;
+ endfor ;
+enddef ;
+
+register_dirty_chars("+-*/:;., ") ;
+
+vardef cleanstring (expr s) =
+ save ss ; string ss, si ; ss = "" ; save i ;
+ for i=0 upto length(s) :
+ si := substring(i,i+1) of s ;
+ ss := ss & if known mfun_clean_ascii[ASCII si] : mfun_clean_ascii[ASCII si] else : si fi ;
+ endfor ;
+ ss
+enddef ;
+
+vardef asciistring (expr s) =
+ save ss ; string ss, si ; ss = "" ; save i ;
+ for i=0 upto length(s) :
+ si := substring(i,i+1) of s ;
+ if (ASCII si >= ASCII "0") and (ASCII si <= ASCII "9") :
+ ss := ss & char(scantokens(si) + ASCII "A") ;
+ else :
+ ss := ss & si ;
+ fi ;
+ endfor ;
+ ss
+enddef ;
+
+vardef setunstringed (expr s, v) =
+ scantokens(cleanstring(s)) := v ;
+enddef ;
+
+vardef getunstringed (expr s) =
+ scantokens(cleanstring(s))
+enddef ;
+
+vardef unstringed (expr s) =
+ expandafter known scantokens(cleanstring(s))
+enddef ;
+
+% for david arnold:
+
+% showgrid(-5,10,1cm,-10,10,1cm);
+
+def showgrid (expr MinX, MaxX, DeltaX, MinY, MaxY, DeltaY) = % will move
+ begingroup
+ save size ; numeric size ; size := 2pt ;
+ for x=MinX upto MaxX :
+ for y=MinY upto MaxY :
+ draw (x*DeltaX, y*DeltaY) withpen pencircle scaled
+ if (x mod 5 = 0) and (y mod 5 = 0) :
+ 1.5size withcolor .50white
+ else :
+ size withcolor .75white
+ fi ;
+ endfor ;
+ endfor ;
+ for x=MinX upto MaxX:
+ label.bot(textext("\infofont " & decimal x), (x*DeltaX,-size)) ;
+ endfor ;
+ for y=MinY upto MaxY:
+ label.lft(textext("\infofont " & decimal y), (-size,y*DeltaY)) ;
+ endfor ;
+ endgroup
+enddef;
+
+% new, handy for:
+%
+% \startuseMPgraphic{map}{n}
+% \includeMPgraphic{map:germany} ;
+% c_phantom (\MPvar{n}<1) (
+% fill map_germany withcolor \MPcolor{lightgray} ;
+% draw map_germany withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ;
+% ) ;
+% \includeMPgraphic{map:austria} ;
+% c_phantom (\MPvar{n}<2) (
+% fill map_austria withcolor \MPcolor{lightgray} ;
+% draw map_austria withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ;
+% ) ;
+% c_phantom (\MPvar{n}<3) (
+% \includeMPgraphic{map:swiss} ;
+% fill map_swiss withcolor \MPcolor{lightgray} ;
+% draw map_swiss withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ;
+% ) ;
+% c_phantom (\MPvar{n}<4) (
+% \includeMPgraphic{map:luxembourg} ;
+% fill map_luxembourg withcolor \MPcolor{lightgray} ;
+% draw map_luxembourg withpen pencircle scaled 1pt withcolor \MPcolor{darkgray} ;
+% ) ;
+% \stopuseMPgraphic
+%
+% \useMPgraphic{map}{n=3}
+
+vardef phantom (text t) = % to be checked
+ picture _p_ ;
+ _p_ := image(t) ;
+ addto _p_ also currentpicture ;
+ setbounds currentpicture to boundingbox _p_ ;
+enddef ;
+
+vardef c_phantom (expr b) (text t) =
+ if b :
+ picture _p_ ;
+ _p_ := image(t) ;
+ addto _p_ also currentpicture ;
+ setbounds currentpicture to boundingbox _p_ ;
+ else :
+ t ;
+ fi ;
+enddef ;
+
+%D Handy:
+
+def break =
+ exitif true fi ;
+enddef ;
+
+%D New too:
+
+primarydef p xstretched w = (
+ p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi
+) enddef ;
+
+primarydef p ystretched h = (
+ p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi
+) enddef ;
+
+primarydef p snapped s =
+ hide (
+ if path p :
+ forever :
+ exitif (bbheight(p) <= s) and (bbwidth(p) <= s) ;
+ p := p scaled (1/2) ;
+ endfor ;
+ elseif numeric p :
+ forever :
+ exitif p <= s ;
+ p := p scaled (1/2) ;
+ endfor ;
+ fi ;
+ )
+ p
+enddef ;
+
+% vardef somecolor = (1,1,0,0) enddef ;
+
+% fill OverlayBox withcolor (rcomponent somecolor,gcomponent somecolor,bcomponent somecolor) ;
+% fill OverlayBox withcolor (ccomponent somecolor,mcomponent somecolor,ycomponent somecolor,bcomponent somecolor) ;
+
+% This could be standard mplib 2 behaviour:
+
+vardef rcomponent expr p = if rgbcolor p : redpart p elseif cmykcolor p : 1 - cyanpart p else : p fi enddef ;
+vardef gcomponent expr p = if rgbcolor p : greenpart p elseif cmykcolor p : 1 - magentapart p else : p fi enddef ;
+vardef bcomponent expr p = if rgbcolor p : bluepart p elseif cmykcolor p : 1 - yellowpart p else : p fi enddef ;
+vardef ccomponent expr p = if cmykcolor p : cyanpart p elseif rgbcolor p : 1 - redpart p else : p fi enddef ;
+vardef mcomponent expr p = if cmykcolor p : magentapart p elseif rgbcolor p : 1 - greenpart p else : p fi enddef ;
+vardef ycomponent expr p = if cmykcolor p : yellowpart p elseif rgbcolor p : 1 - bluepart p else : p fi enddef ;
+vardef bcomponent expr p = if cmykcolor p : blackpart p elseif rgbcolor p : 0 else : p fi enddef ;
+
+% draw image (...) ... ; % prescripts prepended to first, postscripts appended to last
+% draw decorated (...) ... ; % prescripts prepended to each, postscripts appended to each
+% draw redecorated (...) ... ; % prescripts assigned to each, postscripts assigned to each
+% draw undecorated (...) ... ; % following properties are ignored, existing properties are kept
+%
+% draw decorated (
+% draw fullcircle scaled 20cm withpen pencircle scaled 20mm withcolor red withtransparency (1,.40) ;
+% draw fullcircle scaled 15cm withpen pencircle scaled 15mm withcolor green withtransparency (1,.30) ;
+% draw fullcircle scaled 10cm withpen pencircle scaled 10mm withcolor blue withtransparency (1,.20) ;
+% )
+% withcolor blue
+% withtransparency (1,.125) % selectively applied
+% withpen pencircle scaled 10mm
+% ;
+
+% vardef image (text imagedata) = % already defined
+% save currentpicture ;
+% picture currentpicture ;
+% currentpicture := nullpicture ;
+% imagedata ;
+% currentpicture
+% enddef ;
+
+vardef undecorated (text imagedata) text decoration =
+ save currentpicture ;
+ picture currentpicture ;
+ currentpicture := nullpicture ;
+ imagedata ;
+ currentpicture
+enddef ;
+
+
+% if metapostversion < 1.770 :
+%
+% vardef decorated (text imagedata) text decoration =
+% save mfun_decorated_path, currentpicture ;
+% picture mfun_decorated_path, currentpicture ;
+% currentpicture := nullpicture ;
+% imagedata ;
+% mfun_decorated_path := currentpicture ;
+% currentpicture := nullpicture ;
+% for i within mfun_decorated_path :
+% addto currentpicture
+% if stroked i :
+% doublepath pathpart i
+% dashed dashpart i
+% withpen penpart i
+% withcolor colorpart i
+% decoration
+% elseif filled i :
+% contour pathpart i
+% withpen penpart i
+% withcolor colorpart i
+% decoration
+% elseif textual i :
+% also i
+% withcolor colorpart i
+% decoration
+% else :
+% also i
+% fi
+% ;
+% endfor ;
+% currentpicture
+% enddef ;
+%
+% else:
+
+ vardef decorated (text imagedata) text decoration =
+ save mfun_decorated_path, currentpicture ;
+ picture mfun_decorated_path, currentpicture ;
+ currentpicture := nullpicture ;
+ imagedata ;
+ mfun_decorated_path := currentpicture ;
+ currentpicture := nullpicture ;
+ for i within mfun_decorated_path :
+ addto currentpicture
+ if stroked i :
+ doublepath pathpart i
+ dashed dashpart i
+ withpen penpart i
+ withcolor colorpart i
+ withprescript prescriptpart i
+ withpostscript postscriptpart i
+ decoration
+ elseif filled i :
+ contour pathpart i
+ withpen penpart i
+ withcolor colorpart i
+ withprescript prescriptpart i
+ withpostscript postscriptpart i
+ decoration
+ elseif textual i :
+ also i
+ withcolor colorpart i
+ withprescript prescriptpart i
+ withpostscript postscriptpart i
+ decoration
+ else :
+ also i
+ fi
+ ;
+ endfor ;
+ currentpicture
+ enddef ;
+
+% fi ;
+
+vardef redecorated (text imagedata) text decoration =
+ save mfun_decorated_path, currentpicture ;
+ picture mfun_decorated_path, currentpicture ;
+ currentpicture := nullpicture ;
+ imagedata ;
+ mfun_decorated_path := currentpicture ;
+ currentpicture := nullpicture ;
+ for i within mfun_decorated_path :
+ addto currentpicture
+ if stroked i :
+ doublepath pathpart i
+ dashed dashpart i
+ withpen penpart i
+ decoration
+ elseif filled i :
+ contour pathpart i
+ withpen penpart i
+ decoration
+ elseif textual i :
+ also i
+ decoration
+ else :
+ also i
+ fi
+ ;
+ endfor ;
+ currentpicture
+enddef ;
+
+% path mfun_bleed_box ;
+
+% primarydef p bleeded d =
+% image (
+% mfun_bleed_box := boundingbox p ;
+% if pair d :
+% draw p xysized (bbwidth(p)+2*xpart d,bbheight(p)+2*ypart d) shifted -d ;
+% else :
+% draw p xysized (bbwidth(p)+2d,bbheight(p)+2d) shifted (-d,-d) ;
+% fi ;
+% setbounds currentpicture to mfun_bleed_box ;
+% )
+% enddef ;
+
+%D New helpers:
+
+def beginglyph(expr unicode, width, height, depth) =
+ beginfig(unicode) ; % the number is irrelevant
+ charcode := unicode ;
+ charwd := width ;
+ charht := height ;
+ chardp := depth ;
+enddef ;
+
+def endglyph =
+ setbounds currentpicture to (boundingbox unitsquare xscaled charwd yscaled (charht + chardp) shifted (0,-chardp)) ;
+ if known charscale :
+ currentpicture := currentpicture scaled charscale ;
+ fi ;
+ endfig ;
+enddef ;
+
+%D Dimensions have bever been an issue as traditional MP can't make that large
+%D pictures, but with double mode we need a catch:
+
+newinternal maxdimensions ; maxdimensions := 14000 ;
+
+def mfun_apply_max_dimensions = % not a generic helper, we want to protect this one
+ if bbwidth currentpicture > maxdimensions :
+ currentpicture := currentpicture if bbheight currentpicture > bbwidth currentpicture : ysized else : xsized fi maxdimensions ;
+ elseif bbheight currentpicture > maxdimensions :
+ currentpicture := currentpicture ysized maxdimensions ;
+ fi ;
+enddef;
+
+extra_endfig := extra_endfig & "mfun_apply_max_dimensions ;" ;
+
+let dump = relax ;
+
diff --git a/Master/texmf-dist/metapost/context/base/mpii/mp-txts.mpii b/Master/texmf-dist/metapost/context/base/mpii/mp-txts.mpii
new file mode 100644
index 00000000000..d3597488f10
--- /dev/null
+++ b/Master/texmf-dist/metapost/context/base/mpii/mp-txts.mpii
@@ -0,0 +1,66 @@
+%D \module
+%D [ file=mp-txts.mpii,
+%D version=2006.06.08,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=more text support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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.
+
+if known context_txts : endinput ; fi ;
+
+boolean context_txts ; context_txts := true ;
+
+%D The real code:
+
+string txtfile ; txtfile := "" ;
+string txtfont ; txtfont := defaultfont ;
+string txtpref ; txtpref := "00001::::" ;
+numeric txtnext ; txtnext := 0 ;
+numeric txtdepth ; txtdepth := 0 ;
+
+vardef nexttxt =
+ txtnext := txtnext + 1 ;
+ txtnext
+enddef ;
+
+picture savedtxts[] ;
+numeric depthtxts[] ;
+
+vardef zerofilled(expr fd) =
+ if fd<10: "0000" else :
+ if fd<100: "000" else :
+ if fd<1000: "00" else :
+ if fd<10000: "0" else :
+ fi fi fi fi & decimal fd
+enddef;
+
+vardef savetxt(expr n,w,h,d) text t =
+ depthtxts[n] := d ;
+ savedtxts[n] := ((txtpref & zerofilled(n)) infont txtfont) xysized(w,h+d) t
+enddef ;
+
+vardef sometxt(expr n) =
+ if known savedtxts[n] :
+ txtdepth := depthtxts[n] ; savedtxts[n]
+ else :
+ txtdepth := 0 ; nullpicture
+ fi
+enddef ;
+
+def loadtxts =
+ if txtfile <> "" :
+ readfile(txtfile) ;
+ fi ;
+enddef ;
+
+def StartTexts =
+ loadtxts ;
+enddef ;
+
+def StopTexts =
+enddef ;
diff --git a/Master/texmf-dist/scripts/context/ruby/base/ctx.rb b/Master/texmf-dist/scripts/context/ruby/base/ctx.rb
new file mode 100644
index 00000000000..13b4045afe0
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/ctx.rb
@@ -0,0 +1,462 @@
+# module : base/ctx
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# todo: write systemcall for mpost to file so that it can be run
+# faster
+
+# report ?
+
+require 'base/system'
+require 'base/file'
+require 'base/switch' # has needsupdate, bad place
+
+require 'rexml/document'
+
+class CtxRunner
+
+ attr_reader :environments, :modules, :filters, :flags, :modes
+
+ @@suffix = 'prep'
+
+ def initialize(jobname=nil,logger=nil)
+ if @logger = logger then
+ def report(str='')
+ @logger.report(str)
+ end
+ else
+ def report(str='')
+ puts(str)
+ end
+ end
+ @jobname = jobname
+ @ctxname = nil
+ @xmldata = nil
+ @prepfiles = Hash.new
+ @environments = Array.new
+ @modules = Array.new
+ @filters = Array.new
+ @flags = Array.new
+ @modes = Array.new
+ @local = false
+ @paths = Array.new
+ end
+
+ def register_path(str)
+ @paths << str
+ end
+
+ def manipulate(ctxname=nil,defaultname=nil)
+
+ if ctxname then
+ @ctxname = ctxname
+ @jobname = File.suffixed(@ctxname,'tex') unless @jobname
+ else
+ @ctxname = File.suffixed(@jobname,'ctx') if @jobname
+ end
+
+ if not @ctxname then
+ report('no ctx file specified')
+ return
+ end
+
+ if @ctxname !~ /\.[a-z]+$/ then
+ @ctxname += ".ctx"
+ end
+
+ # name can be kpse:res-make.ctx
+ if not FileTest.file?(@ctxname) then
+ fullname, done = '', false
+ if @ctxname =~ /^kpse:/ then
+ begin
+ if fullname = Kpse.found(@ctxname.sub(/^kpse:/,'')) then
+ @ctxname, done = fullname, true
+ end
+ rescue
+ # should not happen
+ end
+ else
+ ['..','../..'].each do |path|
+ begin
+ fullname = File.join(path,@ctxname)
+ if FileTest.file?(fullname) then
+ @ctxname, done = fullname, true
+ end
+ rescue
+ # probably strange join
+ end
+ break if done
+ end
+ if ! done then
+ fullname = Kpse.found(@ctxname)
+ if FileTest.file?(fullname) then
+ @ctxname, done = fullname, true
+ end
+ end
+ end
+ if ! done && defaultname && FileTest.file?(defaultname) then
+ report("using default ctxfile #{defaultname}")
+ @ctxname, done = defaultname, true
+ end
+ if not done then
+ report('no ctx file found')
+ return false
+ end
+ end
+
+ if FileTest.file?(@ctxname) then
+ @xmldata = IO.read(@ctxname)
+ else
+ report('no ctx file found')
+ return false
+ end
+
+ unless @xmldata =~ /^.*<\?xml.*?\?>/moi then
+ report("ctx file #{@ctxname} is no xml file, skipping")
+ return
+ else
+ report("loading ctx file #{@ctxname}")
+ end
+
+ if @xmldata then
+ # out if a sudden rexml started to be picky about namespaces
+ @xmldata.gsub!(/<ctx:job>/,"<ctx:job xmlns:ctx='http://www.pragma-ade.com/rng/ctx.rng'>")
+ end
+
+ begin
+ @xmldata = REXML::Document.new(@xmldata)
+ rescue
+ report('provide valid ctx file (xml error)')
+ return
+ else
+ include(@xmldata,'ctx:include','name')
+ end
+
+ begin
+ variables = Hash.new
+ if @jobname then
+ variables['job'] = @jobname
+ end
+ root = @xmldata.root
+ REXML::XPath.each(root,"/ctx:job//ctx:flags/ctx:flag") do |flg|
+ @flags << justtext(flg)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:environment") do |sty|
+ @environments << justtext(sty)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:module") do |mod|
+ @modules << justtext(mod)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:filter") do |fil|
+ @filters << justtext(fil)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:resources/ctx:mode") do |fil|
+ @modes << justtext(fil)
+ end
+ begin
+ REXML::XPath.each(root,"//ctx:block") do |blk|
+ if @jobname && blk.attributes['pattern'] then
+ root.delete(blk) unless @jobname =~ /#{blk.attributes['pattern']}/
+ else
+ root.delete(blk)
+ end
+ end
+ rescue
+ end
+ REXML::XPath.each(root,"//ctx:value[@name='job']") do |val|
+ substititute(val,variables['job'])
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:message") do |mes|
+ report("preprocessing: #{justtext(mes)}")
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:environment") do |sty|
+ @environments << justtext(sty)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:module") do |mod|
+ @modules << justtext(mod)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:filter") do |fil|
+ @filters << justtext(fil)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:resources/ctx:mode") do |fil|
+ @modes << justtext(fil)
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:process/ctx:flags/ctx:flag") do |flg|
+ @flags << justtext(flg)
+ end
+ commands = Hash.new
+ REXML::XPath.each(root,"/ctx:job//ctx:preprocess/ctx:processors/ctx:processor") do |pre|
+ begin
+ commands[pre.attributes['name']] = pre
+ rescue
+ end
+ end
+ suffix = @@suffix
+ begin
+ suffix = REXML::XPath.match(root,"/ctx:job//ctx:preprocess/@suffix").to_s
+ rescue
+ suffix = @@suffix
+ else
+ if suffix && suffix.empty? then suffix = @@suffix end
+ end
+ if (REXML::XPath.first(root,"/ctx:job//ctx:preprocess/ctx:processors/@local").to_s =~ /(yes|true)/io rescue false) then
+ @local = true
+ else
+ @local = false
+ end
+ REXML::XPath.each(root,"/ctx:job//ctx:preprocess/ctx:files") do |files|
+ REXML::XPath.each(files,"ctx:file") do |pattern|
+ suffix = @@suffix
+ begin
+ suffix = REXML::XPath.match(root,"/ctx:job//ctx:preprocess/@suffix").to_s
+ rescue
+ suffix = @@suffix
+ else
+ if suffix && suffix.empty? then suffix = @@suffix end
+ end
+ preprocessor = pattern.attributes['processor']
+ if preprocessor and not preprocessor.empty? then
+ begin
+ variables['old'] = @jobname
+ variables['new'] = ""
+ REXML::XPath.each(pattern,"ctx:value") do |value|
+ if name = value.attributes['name'] then
+ substititute(value,variables[name.to_s])
+ end
+ end
+ rescue
+ report('unable to resolve file pattern')
+ return
+ end
+ pattern = justtext(pattern)
+ oldfiles = Dir.glob(pattern)
+ pluspath = false
+ if oldfiles.length == 0 then
+ report("no files match #{pattern}")
+ if @paths.length > 0 then
+ @paths.each do |p|
+ oldfiles = Dir.glob("#{p}/#{pattern}")
+ if oldfiles.length > 0 then
+ pluspath = true
+ break
+ end
+ end
+ if oldfiles.length == 0 then
+ report("no files match #{pattern} on path")
+ end
+ end
+ end
+ oldfiles.each do |oldfile|
+ newfile = "#{oldfile}.#{suffix}"
+ newfile = File.basename(newfile) if @local # or pluspath
+ if File.expand_path(oldfile) != File.expand_path(newfile) && File.needsupdate(oldfile,newfile) then
+ report("#{oldfile} needs preprocessing")
+ begin
+ File.delete(newfile)
+ rescue
+ # hope for the best
+ end
+ # there can be a sequence of processors
+ preprocessor.split(',').each do |pp|
+ if command = commands[pp] then
+ # a lie: no <?xml ...?>
+ command = REXML::Document.new(command.to_s) # don't infect original
+ # command = command.deep_clone() # don't infect original
+ command = command.elements["ctx:processor"]
+ if suf = command.attributes['suffix'] then
+ newfile = "#{oldfile}.#{suf}"
+ end
+ begin
+ newfile = File.basename(newfile) if @local
+ rescue
+ end
+ REXML::XPath.each(command,"ctx:old") do |value| replace(value,oldfile) end
+ REXML::XPath.each(command,"ctx:new") do |value| replace(value,newfile) end
+ report("preprocessing #{oldfile} into #{newfile} using #{pp}")
+ variables['old'] = oldfile
+ variables['new'] = newfile
+ REXML::XPath.each(command,"ctx:value") do |value|
+ if name = value.attributes['name'] then
+ substititute(value,variables[name.to_s])
+ end
+ end
+ command = justtext(command)
+ report(command)
+ unless ok = System.run(command) then
+ report("error in preprocessing file #{oldfile}")
+ end
+ begin
+ oldfile = File.basename(oldfile) if @local
+ rescue
+ end
+ end
+ end
+ if FileTest.file?(newfile) then
+ File.syncmtimes(oldfile,newfile)
+ else
+ report("check target location of #{newfile}")
+ end
+ else
+ report("#{oldfile} needs no preprocessing (same file)")
+ end
+ @prepfiles[oldfile] = FileTest.file?(newfile)
+ end
+ end
+ end
+ end
+ rescue
+ report("fatal error in preprocessing #{@ctxname}: #{$!}")
+ end
+ end
+
+ def savelog(ctlname=nil)
+ unless ctlname then
+ if @jobname then
+ ctlname = File.suffixed(@jobname,'ctl')
+ elsif @ctxname then
+ ctlname = File.suffixed(@ctxname,'ctl')
+ else
+ return
+ end
+ end
+ if @prepfiles.length > 0 then
+ if log = File.open(ctlname,'w') then
+ log << "<?xml version='1.0' standalone='yes'?>\n\n"
+ if @local then
+ log << "<ctx:preplist local='yes'>\n"
+ else
+ log << "<ctx:preplist local='no'>\n"
+ end
+ @prepfiles.keys.sort.each do |prep|
+ # log << "\t<ctx:prepfile done='#{yes_or_no(@prepfiles[prep])}'>#{File.basename(prep)}</ctx:prepfile>\n"
+ log << "\t<ctx:prepfile done='#{yes_or_no(@prepfiles[prep])}'>#{prep}</ctx:prepfile>\n"
+ end
+ log << "</ctx:preplist>\n"
+ log.close
+ end
+ else
+ begin
+ File.delete(ctlname)
+ rescue
+ end
+ end
+ end
+
+ private
+
+ def include(xmldata,element='ctx:include',attribute='name')
+ loop do
+ begin
+ more = false
+ REXML::XPath.each(xmldata.root,element) do |e|
+ begin
+ name = e.attributes.get_attribute(attribute).to_s
+ name = e.text.to_s if name.empty?
+ name.strip! if name
+ done = false
+ if name and not name.empty? then
+ ['.',File.dirname(@ctxname),'..','../..'].each do |path|
+ begin
+ fullname = if path == '.' then name else File.join(path,name) end
+ if FileTest.file?(fullname) then
+ if f = File.open(fullname,'r') and i = REXML::Document.new(f) then
+ report("including ctx file #{name}")
+ REXML::XPath.each(i.root,"*") do |ii|
+ xmldata.root.insert_before(e,ii)
+ more = true
+ end
+ end
+ done = true
+ end
+ rescue
+ end
+ break if done
+ end
+ end
+ report("no valid ctx inclusion file #{name}") unless done
+ rescue Exception
+ # skip this file
+ ensure
+ xmldata.root.delete(e)
+ end
+ end
+ break unless more
+ rescue Exception
+ break # forget about inclusion
+ end
+ end
+ end
+
+ private
+
+ def yes_or_no(b)
+ if b then 'yes' else 'no' end
+ end
+
+ private # copied from rlxtools.rb
+
+ def justtext(str)
+ str = str.to_s
+ str.gsub!(/<[^>]*?>/o, '')
+ str.gsub!(/\s+/o, ' ')
+ str.gsub!(/&lt;/o, '<')
+ str.gsub!(/&gt;/o, '>')
+ str.gsub!(/&amp;/o, '&')
+ str.gsub!(/&quot;/o, '"')
+ str.gsub!(/[\/\\]+/o, '/')
+ return str.strip
+ end
+
+ def substititute(value,str)
+ if str then
+ begin
+ if value.attributes.key?('method') then
+ str = filtered(str.to_s,value.attributes['method'].to_s)
+ end
+ if str.empty? && value.attributes.key?('default') then
+ str = value.attributes['default'].to_s
+ end
+ value.insert_after(value,REXML::Text.new(str.to_s))
+ rescue Exception
+ end
+ end
+ end
+
+ def replace(value,str)
+ if str then
+ begin
+ value.insert_after(value,REXML::Text.new(str.to_s))
+ rescue Exception
+ end
+ end
+ end
+
+ def filtered(str,method)
+ str = str.to_s # to be sure
+ case method
+ when 'name' then # no path, no suffix
+ case str
+ when /^.*[\\\/](.+?)\..*?$/o then $1
+ when /^.*[\\\/](.+?)$/o then $1
+ when /^(.*)\..*?$/o then $1
+ else str
+ end
+ when 'path' then if str =~ /^(.+)([\\\/])(.*?)$/o then $1 else '' end
+ when 'suffix' then if str =~ /^.*\.(.*?)$/o then $1 else '' end
+ when 'nosuffix' then if str =~ /^(.*)\..*?$/o then $1 else str end
+ when 'nopath' then if str =~ /^.*[\\\/](.*?)$/o then $1 else str end
+ when 'base' then if str =~ /^.*[\\\/](.*?)$/o then $1 else str end
+ when 'full' then str
+ when 'complete' then str
+ when 'expand' then File.expand_path(str).gsub(/\\/,"/")
+ else str
+ end
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/exa.rb b/Master/texmf-dist/scripts/context/ruby/base/exa.rb
new file mode 100644
index 00000000000..7ba990cf900
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/exa.rb
@@ -0,0 +1,407 @@
+# \setuplayout[width=3cm]
+#
+# tex.setup.setuplayout.width.[integer|real|dimension|string|key]
+# tex.[mp]var.whatever.width.[integer|real|dimension|string|key]
+
+require 'fileutils'
+# require 'ftools'
+require 'digest/md5'
+
+# this can become a lua thing
+
+# no .*? but 0-9a-z\:\. because other too slow (and greedy)
+
+class Hash
+
+ def subset(pattern)
+ h = Hash.new
+ r = /^#{pattern.gsub('.','\.')}/
+ self.keys.each do |k|
+ h[k] = self[k].dup if k =~ r
+ end
+ return h
+ end
+
+end
+
+module ExaEncrypt
+
+ def ExaEncrypt.encrypt_base(logger, oldfilename, newfilename)
+ if FileTest.file?(oldfilename) then
+ logger.report("checking #{oldfilename}") if logger
+ if data = IO.read(oldfilename) then
+ done = false
+ # cfg file:
+ #
+ # banner : exa configuration file
+ # user : domain, name = password, projectlist
+ #
+ if data =~ /^\s*banner\s*\:\s*exa\s*configuration\s*file/ then
+ data.gsub!(/^(\s*user\s*\:\s*.+?\s*\,\s*.+?\s*\=\s*)(.+?)(\s*\,\s*.+\s*)$/) do
+ pre, password, post = $1, $2, $3
+ unless password =~ /MD5:/i then
+ done = true
+ password = "MD5:" + Digest::MD5.hexdigest(password).upcase
+ end
+ "#{pre}#{password}#{post}"
+ end
+ else
+ data.gsub!(/<exa:password([^>]*?)>(.*?)<\/exa:password>/moi) do
+ attributes, password = $1, $2
+ unless password =~ /^([0-9A-F][0-9A-F])+$/ then
+ done = true
+ password = Digest::MD5.hexdigest(password).upcase
+ attributes = " encryption='md5'#{attributes}"
+ end
+ "<exa:password#{attributes}>#{password}</exa:password>"
+ end
+ end
+ begin
+ File.open(newfilename,'w') do |f|
+ f.puts(data)
+ end
+ rescue
+ logger.report("#{newfilename} cannot be written") if logger
+ else
+ logger.report("#{oldfilename} encrypted into #{newfilename}") if done and logger
+ end
+ end
+ end
+ end
+
+end
+
+module ExaModes
+
+ @@modefile = 'examodes.tex'
+
+ @@request = /(<exa:request.*?)(>.*?<\/exa:request>)/mo
+ @@redone = /<exa:request[^>]*?texified=([\'\"])yes\1.*?>/mo
+ @@reload = /<(exa:variable)([^>]+?label\=)([\"\'])([0-9A-Za-z\-\.\:]+?)(\3[^\/]*?)>(.*?)<(\/exa:variable)>/mo
+ @@recalc = /<(exa:variable)([^>]+?label\=)([\"\'])([0-9A-Za-z\-\.\:]+?)([\.\:]calcmath)(\3[^\/]*?)>(.*?)<(\/exa:variable)>/mo
+ @@rename = /<(exa:variable)([^>]+?label\=)([\"\'])([0-9A-Za-z\-\.\:]+?)(\3[^\/]*?)>(.*?)<(\/exa:variable)>/mo
+ @@refile = /<(exa:filename|exa:filelist)>(.*?)<(\/\1)>/mo
+
+ def ExaModes.cleanup_request(logger,filename='request.exa',modefile=@@modefile)
+ begin File.delete(filename+'.raw') ; rescue ; end
+ begin File.delete(modefile) ; rescue ; end
+ if FileTest.file?(filename) then
+ data, done = nil, false
+ begin
+ data = IO.read(filename)
+ rescue
+ data = nil
+ end
+ if data =~ @@request and data !~ @@redone then
+ data.gsub!(@@rename) do
+ done = true
+ '<' + $1 + $2 + $3 + $4 + $5 + '>' +
+ texifiedstr($4,$6) +
+ '<' + $7 + '>'
+ end
+ data.gsub!(@@refile) do
+ done = true
+ '<' + $1 + '>' +
+ cleanpath($2) +
+ '<' + $3 + '>'
+ end
+ data.gsub!(@@recalc) do
+ done = true
+ '<' + $1 + $2 + $3 + $4 + ":raw" + $6 + '>' + $7 + '<' + $8 + '>' +
+ '<' + $1 + $2 + $3 + $4 + $6 + '>' +
+ calculatortexmath($7,false) +
+ '<' + $8 + '>'
+ end
+ if done then
+ data.gsub!(@@request) do
+ $1 + " texified='yes'" + $2
+ end
+ begin File.copy(filename, filename+'.raw') ; rescue ; end
+ begin
+ logger.report("rewriting #{filename}") if logger
+ File.open(filename,'w') do |f|
+ f.puts(data)
+ end
+ rescue
+ logger.report("#{filename} cannot be rewritten") if logger
+ end
+ end
+ else
+ logger.report("#{filename} is already ok") if logger
+ end
+ @variables = Hash.new
+ data.scan(@@reload) do
+ @variables[$4] = $5
+ end
+ vars = @variables.subset('data.tex.var')
+ mpvars = @variables.subset('data.tex.mpvar')
+ modes = @variables.subset('data.tex.mode')
+ setups = @variables.subset('data.tex.setup')
+ if not (modes.empty? and setups.empty? and vars.empty? and mpvars.empty?) then
+ begin
+ File.open(modefile,'w') do |mod|
+ logger.report("saving modes and setups in #{modefile}") if logger
+ if not modes.empty? then
+ for key in modes.keys do
+ k = key.dup
+ k.gsub!(/\./,'-')
+ mod.puts("\\enablemode[#{k}-#{modes[key]}]\n")
+ if modes[key] =~ /(on|yes|start)/o then # ! ! ! ! !
+ mod.puts("\\enablemode[#{k}]\n")
+ end
+ end
+ mod.puts("\n\\readfile{cont-mod}{}{}\n")
+ end
+ if not setups.empty? then
+ for key in setups.keys
+ if key =~ /^(.+?)\.(.+?)\.(.+?)$/o then
+ command, key, type, value = $1, $2, $3, setups[key]
+ value = cleanedup(key,type,value)
+ mod.puts("\\#{$1}[#{key}=#{value}]\n")
+ elsif key =~ /^(.+?)\.(.+?)$/o then
+ command, type, value = $1, $2, setups[key]
+ mod.puts("\\#{$1}[#{value}]\n")
+ end
+ end
+ end
+ savevaroptions(vars, 'setvariables', mod)
+ savevaroptions(mpvars,'setMPvariables',mod)
+ end
+ rescue
+ logger.report("#{modefile} cannot be saved") if logger
+ end
+ else
+ logger.report("#{modefile} is not created") if logger
+ end
+ end
+ end
+
+ private
+
+ def ExaModes.autoparenthesis(str)
+ if str =~ /[\+\-]/o then '[1]' + str + '[1]' else str end
+ end
+
+ def ExaModes.cleanedup(key,type,value)
+ if type == 'dimension' then
+ unless value =~ /(cm|mm|in|bp|sp|pt|dd|em|ex)/o
+ value + 'pt'
+ else
+ value
+ end
+ elsif type == 'calcmath' then
+ '{' + calculatortexmath(value,true) + '}'
+ elsif type =~ /^filename|filelist$/ or key =~ /^filename|filelist$/ then
+ cleanpath(value)
+ else
+ value
+ end
+ end
+
+ def ExaModes.cleanpath(str)
+ (str ||'').gsub(/\\/o,'/')
+ end
+
+ def ExaModes.texifiedstr(key,val)
+ case key
+ when 'filename' then
+ cleanpath(val)
+ when 'filelist' then
+ cleanpath(val)
+ else
+ val
+ end
+ end
+
+ def ExaModes.savevaroptions(vars,setvariables,mod)
+ if not vars.empty? then
+ for key in vars.keys do
+ # var.whatever.width.dimension.value
+ if key =~ /^(.+?)\.(.+?)\.(.+?)$/o then
+ tag, key, type, value = $1, $2, $3, vars[key]
+ value = cleanedup(key,type,value)
+ mod.puts("\\#{setvariables}[#{tag}][#{key}=#{value}]\n")
+ elsif key =~ /^(.+?)\.(.+?)$/o then
+ tag, key, value = $1, $2, vars[key]
+ mod.puts("\\#{setvariables}[#{tag}][#{key}=#{value}]\n")
+ end
+ end
+ end
+ end
+
+ def ExaModes.calculatortexmath(str,tx=true)
+ if tx then
+ bdisp, edisp = "\\displaymath\{", "\}"
+ binln, einln = "\\inlinemath\{" , "\}"
+ egraf = "\\endgraf"
+ else
+ bdisp, edisp = "<displaytexmath>", "</displaytexmath>"
+ binln, einln = "<inlinetexmath>" , "</inlinetexmath>"
+ egraf = "<p/>"
+ end
+ str.gsub!(/\n\s*\n+/moi, "\\ENDGRAF ")
+ str.gsub!(/(\[\[)\s*(.*?)\s*(\]\])/mos) do
+ $1 + docalculatortexmath($2) + $3
+ end
+ str.gsub!(/(\\ENDGRAF)+\s*(\[\[)\s*(.*?)\s*(\]\])/moi) do
+ $1 + bdisp + $3 + edisp
+ end
+ str.gsub!(/(\[\[)\s*(.*?)\s*(\]\])/o) do
+ binln + $2 + einln
+ end
+ str.gsub!(/\\ENDGRAF/mos, egraf)
+ str
+ end
+
+ def ExaModes.docalculatortexmath(str)
+ str.gsub!(/\n/o) { ' ' }
+ str.gsub!(/\s+/o) { ' ' }
+ str.gsub!(/&gt;/o) { '>' }
+ str.gsub!(/&lt;/o) { '<' }
+ str.gsub!(/&.*?;/o) { }
+ level = 0
+ str.gsub!(/([\(\)])/o) do |chr|
+ if chr == '(' then
+ level = level + 1
+ chr = '[' + level.to_s + ']'
+ elsif chr == ')' then
+ chr = '[' + level.to_s + ']'
+ level = level - 1
+ end
+ chr
+ end
+ # ...E...
+ loop do
+ break unless str.gsub!(/([\d\.]+)E([\-\+]{0,1}[\d\.]+)/o) do
+ "\{\\SCINOT\{#{$1}\}\{#{$2}\}\}"
+ end
+ end
+ # ^-..
+ loop do
+ break unless str.gsub!(/\^([\-\+]*\d+)/o) do
+ "\^\{#{$1}\}"
+ end
+ end
+ # ^(...)
+ loop do
+ break unless str.gsub!(/\^(\[\d+\])(.*?)\1/o) do
+ "\^\{#{$2}\}"
+ end
+ end
+ # 1/x^2
+ loop do
+ break unless str.gsub!(/([\d\w\.]+)\/([\d\w\.]+)\^([\d\w\.]+)/o) do
+ "@\{#{$1}\}\{#{$2}\^\{#{$3}\}\}"
+ end
+ end
+ # int(a,b,c)
+ loop do
+ break unless str.gsub!(/(int|sum|prod)(\[\d+\])(.*?),(.*?),(.*?)\2/o) do
+ "\\#{$1.upcase}\^\{#{$4}\}\_\{#{$5}\}\{#{autoparenthesis($3)}\}"
+ end
+ end
+ # int(a,b)
+ loop do
+ break unless str.gsub!(/(int|sum|prod)(\[\d+\])(.*?),(.*?)\2/o) do
+ "\\#{$1.upcase}\_\{#{$4}\}\{#{autoparenthesis($3)}\}"
+ end
+ end
+ # int(a)
+ loop do
+ break unless str.gsub!(/(int|sum|prod)(\[\d+\])(.*?)\2/o) do
+ "\\#{$1.upcase}\{#{autoparenthesis($3)}\}"
+ end
+ end
+ # sin(x) => {\sin(x)}
+ loop do
+ break unless str.gsub!(/(median|min|max|round|sqrt|sin|cos|tan|sinh|cosh|tanh|ln|log)\s*(\[\d+\])(.*?)\2/o) do
+ "\{\\#{$1.upcase}\{#{$2}#{$3}#{$2}\}\}"
+ end
+ end
+ # mean
+ str.gsub!(/(mean)(\[\d+\])(.*?)\2/o) do
+ "\{\\OVERLINE\{#{$3}\}\}"
+ end
+ # sin x => {\sin(x)}
+ # ...
+ # (1+x)/(1+x) => \frac{1+x}{1+x}
+ loop do
+ break unless str.gsub!(/(\[\d+\])(.*?)\1\/(\[\d+\])(.*?)\3/o) do
+ "@\{#{$2}\}\{#{$4}\}"
+ end
+ end
+ # (1+x)/x => \frac{1+x}{x}
+ loop do
+ break unless str.gsub!(/(\[\d+\])(.*?)\1\/([a-zA-Z0-9]+)/o) do
+ "@\{#{$2}\}\{#{$3}\}"
+ end
+ end
+ # 1/(1+x) => \frac{1}{1+x}
+ loop do
+ break unless str.gsub!(/([a-zA-Z0-9]+)\/(\[\d+\])(.*?)\2/o) do
+ "@\{#{$1}\}\{#{$3}\}"
+ end
+ end
+ # 1/x => \frac{1}{x}
+ loop do
+ break unless str.gsub!(/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)/o) do
+ "@\{#{$1}\}\{#{$2}\}"
+ end
+ end
+ #
+ str.gsub!(/\@/o) do
+ "\\FRAC "
+ end
+ str.gsub!(/\*/o) do
+ " "
+ end
+ str.gsub!(/\<\=/o) do
+ "\\LE "
+ end
+ str.gsub!(/\>\=/o) do
+ "\\GE "
+ end
+ str.gsub!(/\=/o) do
+ "\\EQ "
+ end
+ str.gsub!(/\</o) do
+ "\\LT "
+ end
+ str.gsub!(/\>/) do
+ "\\GT "
+ end
+ str.gsub!(/(D)(\[\d+\])(.*?)\2/o) do
+ "\{\\FRAC\{\\MBOX{d}\}\{\\MBOX{d}x\}\{#{$2}#{$3}#{$2}\}\}"
+ end
+ str.gsub!(/(exp)(\[\d+\])(.*?)\2/o) do
+ "\{e^\{#{$3}\}\}"
+ end
+ str.gsub!(/(abs)(\[\d+\])(.*?)\2/o) do
+ "\{\\left\|#{$3}\\right\|\}"
+ end
+ str.gsub!(/D([x|y])/o) do
+ "\\FRAC\{\{\\rm d\}#{$1}\}\{\{\\rm d\}x\}"
+ end
+ str.gsub!(/D([f|g])(\[\d+\])(.*?)\2/o) do
+ "\{\\rm #{$1}\}'#{$2}#{$3}#{$2}"
+ end
+ str.gsub!(/([f|g])(\[\d+\])(.*?)\2/o) do
+ "\{\\rm #{$1}\}#{$2}#{$3}#{$2}"
+ end
+ str.gsub!(/(pi|inf)/io) do
+ "\\#{$1} "
+ end
+ loop do
+ break unless str.gsub!(/(\[\d+?\])(.*?)\1/o) do
+ "\\left(#{$2}\\right)"
+ end
+ end
+ str.gsub!(/\\([A-Z]+?)([\s\{\^\_\\])/io) do
+ "\\#{$1.downcase}#{$2}"
+ end
+ str
+ end
+
+end
+
+# ExaModes.cleanup_request()
diff --git a/Master/texmf-dist/scripts/context/ruby/base/file.rb b/Master/texmf-dist/scripts/context/ruby/base/file.rb
new file mode 100644
index 00000000000..1aeac5fd697
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/file.rb
@@ -0,0 +1,150 @@
+# module : base/file
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+require 'fileutils'
+# require 'ftools'
+
+class File
+
+ def File.suffixed(name,sufa,sufb=nil)
+ if sufb then
+ if sufa.empty? then
+ unsuffixed(name) + ".#{sufb}"
+ else
+ unsuffixed(name) + "-#{sufa}.#{sufb}"
+ end
+ else
+ unsuffixed(name) + ".#{sufa}"
+ end
+ end
+
+ def File.unsuffixed(name)
+ name.sub(/\.[^\.]*?$/o, '')
+ end
+
+ def File.suffix(name,default='')
+ if name =~ /\.([^\.]*?)$/o then
+ $1
+ else
+ default
+ end
+ end
+
+ def File.splitname(name,suffix='')
+ if name =~ /^(.*)\.([^\.]*?)$/o then
+ [$1, $2]
+ else
+ [name, suffix]
+ end
+ end
+
+end
+
+class File
+
+ def File.silentopen(name,method='r')
+ begin
+ f = File.open(name,method)
+ rescue
+ return nil
+ else
+ return f
+ end
+ end
+
+ def File.silentread(name)
+ begin
+ data = IO.read(name)
+ rescue
+ return nil
+ else
+ return data
+ end
+ end
+
+ def File.atleast?(name,n=0)
+ begin
+ size = FileTest.size(name)
+ rescue
+ return false
+ else
+ return size > n
+ end
+ end
+
+ def File.appended(name,str='')
+ if FileTest.file?(name) then
+ begin
+ if f = File.open(name,'a') then
+ f << str
+ f.close
+ return true
+ end
+ rescue
+ end
+ end
+ return false
+ end
+
+ def File.written(name,str='')
+ begin
+ if f = File.open(name,'w') then
+ f << str
+ f.close
+ return true
+ end
+ rescue
+ end
+ return false
+ end
+
+ def File.silentdelete(filename)
+ File.delete(filename) rescue false
+ end
+
+ def File.silentcopy(oldname,newname)
+ return if File.expand_path(oldname) == File.expand_path(newname)
+ FileUtils.makedirs(File.dirname(newname)) rescue false
+ File.copy(oldname,newname) rescue false
+ end
+
+ def File.silentrename(oldname,newname)
+ # in case of troubles, we just copy the file; we
+ # maybe working over multiple file systems or
+ # apps may have mildly locked files (like gs does)
+ return if File.expand_path(oldname) == File.expand_path(newname)
+ File.delete(newname) rescue false
+ begin
+ File.rename(oldname,newname)
+ rescue
+ FileUtils.makedirs(File.dirname(newname)) rescue false
+ File.copy(oldname,newname) rescue false
+ end
+ end
+
+end
+
+class File
+
+ # handles "c:\tmp\test.tex" as well as "/${TEMP}/test.tex")
+
+ def File.unixfied(filename)
+ begin
+ str = filename.gsub(/\$\{*([a-z0-9\_]+)\}*/oi) do
+ if ENV.key?($1) then ENV[$1] else $1 end
+ end
+ str.gsub(/[\/\\]+/o, '/')
+ rescue
+ filename
+ end
+ end
+
+end
+
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpse.rb b/Master/texmf-dist/scripts/context/ruby/base/kpse.rb
new file mode 100644
index 00000000000..ec0b8810ba5
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpse.rb
@@ -0,0 +1,399 @@
+# module : base/kpse
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# rename this one to environment
+#
+# todo: web2c vs miktex module and include in kpse
+
+require 'rbconfig'
+require 'fileutils'
+
+# beware $engine is lowercase in kpse
+#
+# miktex has mem|fmt|base paths
+
+class String
+
+ def split_path
+ if self =~ /\;/o || self =~ /^[a-z]\:/io then
+ self.split(";")
+ else
+ self.split(":")
+ end
+ end
+
+ def sane_path
+ self.gsub(/\\/,'/')
+ end
+
+end
+
+class Array
+
+ def join_path
+ self.join(File::PATH_SEPARATOR)
+ end
+
+ def non_empty
+ self.delete_if do |i|
+ (i == nil || i.empty?) rescue false
+ end
+ end
+
+end
+
+module Kpse
+
+ @@located = Hash.new
+ @@paths = Hash.new
+ @@scripts = Hash.new
+ @@formats = ['tex','texmfscripts','other text files']
+ @@progname = 'context'
+ @@ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
+ @@problems = false
+ @@tracing = false
+ @@distribution = 'web2c'
+ @@crossover = true
+ @@mswindows = RbConfig::CONFIG['host_os'] =~ /mswin/
+
+ # @@distribution = 'miktex' if ENV['PATH'] =~ /miktex[\\\/]bin/o
+
+ # if ENV['PATH'] =~ /(.*?)miktex[\\\/]bin/i then
+ # @@distribution = 'miktex' unless $1 =~ /(texmf\-mswin[\/\\]bin|bin[\/\\]win32)/i
+ # end
+
+ if @@mswindows && (ENV['PATH'] =~ /(.*?)miktex[\\\/]bin/i) then
+ @@distribution = 'miktex' unless $1 =~ /(texmf\-mswin[\/\\]bin|bin[\/\\]win32)/i
+ end
+
+ @@re_true = /yes|on|true|1/i
+
+ if (ENV['KPSEFAST'] =~ @@re_true) || (ENV['CTXMINIMAL'] =~ @@re_true) then
+ @@usekpserunner = true
+ require 'base/kpsefast'
+ require 'base/kpserunner'
+ else
+ @@usekpserunner = false
+ end
+
+ if @@crossover then
+ ENV.keys.each do |k|
+ case k
+ when /\_CTX\_KPSE\_V\_(.*?)\_/io then @@located[$1] = ENV[k].dup
+ when /\_CTX\_KPSE\_P\_(.*?)\_/io then @@paths [$1] = ENV[k].dup.split(';')
+ when /\_CTX\_KPSE\_S\_(.*?)\_/io then @@scripts[$1] = ENV[k].dup
+ end
+ end
+ end
+
+ def Kpse.distribution
+ @@distribution
+ end
+
+ def Kpse.miktex?
+ @@distribution == 'miktex'
+ end
+
+ def Kpse.web2c?
+ @@distribution == 'web2c'
+ end
+
+ def Kpse.inspect
+ @@located.keys.sort.each do |k| puts("located : #{k} -> #{@@located[k]}\n") end
+ @@paths .keys.sort.each do |k| puts("paths : #{k} -> #{@@paths [k]}\n") end
+ @@scripts.keys.sort.each do |k| puts("scripts : #{k} -> #{@@scripts[k]}\n") end
+ end
+
+ def Kpse.used_path(varname)
+ begin
+ if @@mswindows then
+ path = run("--expand-path=\$#{varname}") rescue ''
+ else
+ path = run("--expand-path='$#{varname}'") rescue ''
+ end
+ rescue
+ path = ''
+ end
+ return path.sane_path
+ end
+
+ def Kpse.found(filename, progname=nil, format=nil)
+ begin
+ tag = Kpse.key(filename) # all
+ if @@located.key?(tag) then
+ return @@located[tag].sane_path
+ elsif FileTest.file?(filename) then
+ setvariable(tag,filename)
+ return filename
+ elsif FileTest.file?(File.join(@@ownpath,filename)) then
+ setvariable(tag,File.join(@@ownpath,filename))
+ return @@located[tag].sane_path
+ else
+ [progname,@@progname].flatten.compact.uniq.each do |prg|
+ [format,@@formats].flatten.compact.uniq.each do |fmt|
+ begin
+ tag = Kpse.key(filename,prg,fmt)
+ if @@located.key?(tag) then
+ return @@located[tag].sane_path
+ elsif p = Kpse.kpsewhich(filename,prg,fmt) then
+ setvariable(tag,p.chomp)
+ return @@located[tag].sane_path
+ end
+ rescue
+ end
+ end
+ end
+ setvariable(tag,filename)
+ return filename.sane_path
+ end
+ rescue
+ filename.sane_path
+ end
+ end
+
+ def Kpse.kpsewhich(filename,progname,format)
+ p = if progname && ! progname.empty? then "-progname=#{progname}" else '' end
+ f = if format && ! format.empty? then "-format=\"#{format}\"" else '' end
+ Kpse.run("#{p} #{f} #{filename}")
+ end
+
+ def Kpse.which
+ Kpse.kpsewhich
+ end
+
+ def Kpse.run(arguments)
+ puts arguments if @@tracing
+ begin
+ if @@problems then
+ results = ''
+ elsif @@usekpserunner then
+ results = KpseRunner.kpsewhich(arguments).chomp
+ else
+ results = `kpsewhich #{arguments}`.chomp
+ end
+ rescue
+ puts "unable to run kpsewhich" if @@tracing
+ @@problems, results = true, ''
+ end
+ puts results if @@tracing
+ return results
+ end
+
+
+ def Kpse.formatpaths
+ # maybe we should check for writeability
+ unless @@paths.key?('formatpaths') then
+ begin
+ setpath('formatpaths',run("--show-path=fmt").sane_path.split_path)
+ rescue
+ setpath('formatpaths',[])
+ end
+ end
+ return @@paths['formatpaths']
+ end
+
+ def Kpse.key(filename='',progname='all',format='all')
+ [progname,format,filename].join('-')
+ end
+
+ def Kpse.formatpath(engine='pdftex',enginepath=true)
+
+ # because engine support in distributions is not always
+ # as we expect, we need to check for it;
+
+ # todo: miktex
+
+ if miktex? then
+ return '.'
+ else
+ unless @@paths.key?(engine) then
+ # savedengine = ENV['engine']
+ if ENV['TEXFORMATS'] && ! ENV['TEXFORMATS'].empty? then
+ # make sure that we have a lowercase entry
+ ENV['TEXFORMATS'] = ENV['TEXFORMATS'].sub(/\$engine/io,"\$engine")
+ # well, we will append anyway, so we could also strip it
+ # ENV['TEXFORMATS'] = ENV['TEXFORMATS'].sub(/\$engine/io,"")
+ end
+ # use modern method
+ if enginepath then
+ formatpath = run("--engine=#{engine} --show-path=fmt")
+ else
+ # ENV['engine'] = engine if engine
+ formatpath = run("--show-path=fmt")
+ end
+ # use ancient method
+ if formatpath.empty? then
+ if enginepath then
+ if @@mswindows then
+ formatpath = run("--engine=#{engine} --expand-path=\$TEXFORMATS")
+ else
+ formatpath = run("--engine=#{engine} --expand-path=\\\$TEXFORMATS")
+ end
+ end
+ # either no enginepath or failed run
+ if formatpath.empty? then
+ if @@mswindows then
+ formatpath = run("--expand-path=\$TEXFORMATS")
+ else
+ formatpath = run("--expand-path=\\\$TEXFORMATS")
+ end
+ end
+ end
+ # locate writable path
+ if ! formatpath.empty? then
+ formatpaths, done = formatpath.split_path, false
+ formatpaths.collect! do |fp|
+ fp.gsub!(/\\/o,'/')
+ fp.gsub!(/\/\/$/o,'/')
+ # remove funny patterns
+ fp.sub!(/^!!/o,'')
+ fp.sub!(/\/+$/o,'')
+ fp.sub!(/(unsetengine|unset)/o,if enginepath then engine else '' end)
+ fp
+ end
+ formatpaths.delete_if do |fp|
+ fp.empty? || fp == '.'
+ end
+ # the engine path may not yet be present, find first writable
+ formatpaths.each do |fp|
+ # strip (possible engine) and test for writeability
+ fpp = fp.sub(/#{engine}\/*$/o,'')
+ if FileTest.directory?(fpp) && FileTest.writable?(fpp) then
+ # use this path
+ formatpath, done = fp.dup, true
+ break
+ end
+ end
+ unless done then
+ formatpaths.each do |fp|
+ fpp = fp.sub(/#{engine}\/*$/o,'')
+ FileUtils.makedirs(fpp) rescue false # maybe we don't have an path yet
+ if FileTest.directory?(fpp) && FileTest.writable?(fpp) then
+ # use this path
+ formatpath, done = fp.dup, true
+ break
+ end
+ end
+ end
+ unless done then
+ formatpath = '.'
+ end
+ end
+ # needed !
+ FileUtils.makedirs(formatpath) rescue false
+ # fall back to current path
+ formatpath = '.' if formatpath.empty? || ! FileTest.writable?(formatpath)
+ # append engine but prevent duplicates
+ formatpath = File.join(formatpath.sub(/\/*#{engine}\/*$/,''), engine) if enginepath
+ FileUtils.makedirs(formatpath) rescue false
+ setpath(engine,formatpath)
+ # ENV['engine'] = savedengine
+ end
+ return @@paths[engine].first
+ end
+ end
+
+ def Kpse.update
+ system('initexmf -u') if Kpse.miktex?
+ system('mktexlsr')
+ end
+
+ # engine support is either broken of not implemented in some
+ # distributions, so we need to take care of it ourselves (without
+ # delays due to kpse calls); there can be many paths in the string
+ #
+ # in a year or so, i will drop this check
+
+ def Kpse.fixtexmfvars(engine=nil)
+ ENV['ENGINE'] = engine if engine
+ texformats = if ENV['TEXFORMATS'] then ENV['TEXFORMATS'].dup else '' end
+ if texformats.empty? then
+ if engine then
+ if @@mswindows then
+ texformats = `kpsewhich --engine=#{engine} --expand-var=\$TEXFORMATS`.chomp
+ else
+ texformats = `kpsewhich --engine=#{engine} --expand-var=\\\$TEXFORMATS`.chomp
+ end
+ else
+ if @@mswindows then
+ texformats = `kpsewhich --expand-var=\$TEXFORMATS`.chomp
+ else
+ texformats = `kpsewhich --expand-var=\\\$TEXFORMATS`.chomp
+ end
+ end
+ end
+ if engine then
+ texformats.sub!(/unsetengine/,engine)
+ else
+ texformats.sub!(/unsetengine/,"\$engine")
+ end
+ if engine && (texformats =~ /web2c[\/\\].*#{engine}/o) then
+ # ok, engine is seen
+ return false
+ elsif texformats =~ /web2c[\/\\].*\$engine/io then
+ # shouldn't happen
+ return false
+ else
+ ENV['TEXFORMATS'] = texformats.gsub(/(web2c\/\{)(,\})/o) do
+ "#{$1}\$engine#{$2}"
+ end
+ if texformats !~ /web2c[\/\\].*\$engine/io then
+ ENV['TEXFORMATS'] = texformats.gsub(/web2c\/*/, "web2c/{\$engine,}")
+ end
+ return true
+ end
+ end
+
+ # def Kpse.runscript(name,filename=[],options=[])
+ # setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name)
+ # cmd = "#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}"
+ # system(cmd)
+ # end
+
+ # def Kpse.pipescript(name,filename=[],options=[])
+ # setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name)
+ # cmd = "#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}"
+ # `#{cmd}`
+ # end
+
+ def Kpse.runscript(name,filename=[],options=[])
+ cmd = "mtxrun --script #{name} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}"
+ system(cmd)
+ end
+
+ def Kpse.pipescript(name,filename=[],options=[])
+ cmd = "mtxrun --script #{name} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}"
+ `#{cmd}`
+ end
+
+ def Kpse.searchmethod
+ if @@usekpserunner then 'kpsefast' else 'kpsewhich' end
+ end
+
+ private
+
+ def Kpse.setvariable(key,value)
+ @@located[key] = value
+ ENV["_CTX_K_V_#{key}_"] = @@located[key] if @@crossover
+ end
+
+ def Kpse.setscript(key,value)
+ @@scripts[key] = value
+ ENV["_CTX_K_S_#{key}_"] = @@scripts[key] if @@crossover
+ end
+
+ def Kpse.setpath(key,value)
+ @@paths[key] = [value].flatten.uniq.collect do |p|
+ p.sub(/^!!/,'').sub(/\/*$/,'')
+ end
+ ENV["_CTX_K_P_#{key}_"] = @@paths[key].join(';') if @@crossover
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpse/drb.rb b/Master/texmf-dist/scripts/context/ruby/base/kpse/drb.rb
new file mode 100644
index 00000000000..db1ce0eec87
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpse/drb.rb
@@ -0,0 +1,57 @@
+require 'drb'
+require 'base/kpse/trees'
+
+class KpseServer
+
+ attr_accessor :port
+
+ def initialize(port=7000)
+ @port = port
+ end
+
+ def start
+ puts "starting drb service at port #{@port}"
+ DRb.start_service("druby://localhost:#{@port}", KpseTrees.new)
+ trap(:INT) do
+ DRb.stop_service
+ end
+ DRb.thread.join
+ end
+
+ def stop
+ # todo
+ end
+
+end
+
+class KpseClient
+
+ attr_accessor :port
+
+ def initialize(port=7000)
+ @port = port
+ @kpse = nil
+ end
+
+ def start
+ # only needed when callbacks are used / slow, due to Socket::getaddrinfo
+ # DRb.start_service
+ end
+
+ def object
+ @kpse = DRbObject.new(nil,"druby://localhost:#{@port}")
+ end
+
+end
+
+
+# SERVER_URI="druby://localhost:8787"
+#
+# # Start a local DRbServer to handle callbacks.
+# #
+# # Not necessary for this small example, but will be required
+# # as soon as we pass a non-marshallable object as an argument
+# # to a dRuby call.
+# DRb.start_service
+#
+# timeserver = DRbObject.new_with_uri(SERVER_URI)
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpse/soap.rb b/Master/texmf-dist/scripts/context/ruby/base/kpse/soap.rb
new file mode 100644
index 00000000000..c9ed75c446b
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpse/soap.rb
@@ -0,0 +1,79 @@
+require 'soap/rpc/standaloneServer'
+require 'soap/rpc/driver'
+
+require 'base/kpse/trees'
+
+class KpseService < SOAP::RPC::StandaloneServer
+
+ def on_init
+ kpse = KpseTrees.new
+ add_method(kpse, 'choose', 'files', 'environment')
+ add_method(kpse, 'load', 'files', 'environment')
+ add_method(kpse, 'expand_variables', 'tree')
+ add_method(kpse, 'expand_braces', 'tree', 'str')
+ add_method(kpse, 'expand_path', 'tree', 'str')
+ add_method(kpse, 'expand_var', 'tree', 'str')
+ add_method(kpse, 'show_path', 'tree', 'str')
+ add_method(kpse, 'var_value', 'tree', 'str')
+ add_method(kpse, 'find_file', 'tree', 'filename')
+ add_method(kpse, 'find_files', 'tree', 'filename', 'first')
+ end
+
+end
+
+class KpseServer
+
+ @@url = 'http://kpse.thismachine.org/KpseService'
+
+ attr_accessor :port
+
+ def initialize(port=7000)
+ @port = port
+ @server = nil
+ end
+
+ def start
+ puts "starting soap service at port #{@port}"
+ @server = KpseService.new('KpseServer', @@url, '0.0.0.0', @port.to_i)
+ trap(:INT) do
+ @server.shutdown
+ end
+ status = @server.start
+ end
+
+ def stop
+ @server.shutdown rescue false
+ end
+
+end
+
+class KpseClient
+
+ @@url = 'http://kpse.thismachine.org/KpseService'
+
+ attr_accessor :port
+
+ def initialize(port=7000)
+ @port = port
+ @kpse = nil
+ end
+
+ def start
+ @kpse = SOAP::RPC::Driver.new("http://localhost:#{port}/", @@url)
+ @kpse.add_method('choose','files', 'environment')
+ @kpse.add_method('load','files', 'environment')
+ @kpse.add_method('expand_variables', 'tree')
+ @kpse.add_method('expand_braces', 'tree', 'str')
+ @kpse.add_method('expand_path', 'tree', 'str')
+ @kpse.add_method('expand_var', 'tree', 'str')
+ @kpse.add_method('show_path', 'tree', 'str')
+ @kpse.add_method('var_value', 'tree', 'str')
+ @kpse.add_method('find_file', 'tree', 'filename')
+ @kpse.add_method('find_files', 'tree', 'filename', 'first')
+ end
+
+ def object
+ @kpse
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpse/trees.rb b/Master/texmf-dist/scripts/context/ruby/base/kpse/trees.rb
new file mode 100644
index 00000000000..9c872eb18c1
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpse/trees.rb
@@ -0,0 +1,84 @@
+require 'monitor'
+require 'base/kpsefast'
+
+class KpseTrees < Monitor
+
+ def initialize
+ @trees = Hash.new
+ end
+
+ def pattern(filenames)
+ filenames.join('|').gsub(/\\+/o,'/').downcase
+ end
+
+ def choose(filenames,environment)
+ current = pattern(filenames)
+ load(filenames,environment) unless @trees[current]
+ puts "enabling tree #{current}"
+ current
+ end
+
+ def fetch(filenames,environment) # will send whole object !
+ current = pattern(filenames)
+ load(filenames,environment) unless @trees[current]
+ puts "fetching tree #{current}"
+ @trees[current]
+ end
+
+ def load(filenames,environment)
+ current = pattern(filenames)
+ puts "loading tree #{current}"
+ @trees[current] = KpseFast.new
+ @trees[current].push_environment(environment)
+ @trees[current].load_cnf(filenames)
+ @trees[current].expand_variables
+ @trees[current].load_lsr
+ end
+
+ def set(tree,key,value)
+ case key
+ when 'progname' then @trees[tree].progname = value
+ when 'engine' then @trees[tree].engine = value
+ when 'format' then @trees[tree].format = value
+ end
+ end
+ def get(tree,key)
+ case key
+ when 'progname' then @trees[tree].progname
+ when 'engine' then @trees[tree].engine
+ when 'format' then @trees[tree].format
+ end
+ end
+
+ def load_cnf(tree)
+ @trees[tree].load_cnf
+ end
+ def load_lsr(tree)
+ @trees[tree].load_lsr
+ end
+ def expand_variables(tree)
+ @trees[tree].expand_variables
+ end
+ def expand_braces(tree,str)
+ @trees[tree].expand_braces(str)
+ end
+ def expand_path(tree,str)
+ @trees[tree].expand_path(str)
+ end
+ def expand_var(tree,str)
+ @trees[tree].expand_var(str)
+ end
+ def show_path(tree,str)
+ @trees[tree].show_path(str)
+ end
+ def var_value(tree,str)
+ @trees[tree].var_value(str)
+ end
+ def find_file(tree,filename)
+ @trees[tree].find_file(filename)
+ end
+ def find_files(tree,filename,first)
+ @trees[tree].find_files(filename,first)
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpsedirect.rb b/Master/texmf-dist/scripts/context/ruby/base/kpsedirect.rb
new file mode 100644
index 00000000000..6fa8c8601a9
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpsedirect.rb
@@ -0,0 +1,34 @@
+class KpseDirect
+
+ attr_accessor :progname, :format, :engine
+
+ def initialize
+ @progname, @format, @engine = '', '', ''
+ end
+
+ def expand_path(str)
+ clean_name(`kpsewhich -expand-path=#{str}`.chomp)
+ end
+
+ def expand_var(str)
+ clean_name(`kpsewhich -expand-var=#{str}`.chomp)
+ end
+
+ def find_file(str)
+ clean_name(`kpsewhich #{_progname_} #{_format_} #{str}`.chomp)
+ end
+
+ def _progname_
+ if @progname.empty? then '' else "-progname=#{@progname}" end
+ end
+ def _format_
+ if @format.empty? then '' else "-format=\"#{@format}\"" end
+ end
+
+ private
+
+ def clean_name(str)
+ str.gsub(/\\/,'/')
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpsefast.rb b/Master/texmf-dist/scripts/context/ruby/base/kpsefast.rb
new file mode 100644
index 00000000000..8a9f895933b
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpsefast.rb
@@ -0,0 +1,934 @@
+# module : base/kpsefast
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# todo: multiple cnf files
+#
+# todo: cleanup, string or table store (as in lua variant)
+
+class String
+
+ def split_path
+ if self =~ /\;/o || self =~ /^[a-z]\:/io then
+ self.split(";")
+ else
+ self.split(":")
+ end
+ end
+
+end
+
+class Array
+
+ def join_path
+ self.join(File::PATH_SEPARATOR)
+ end
+
+end
+
+class File
+
+ def File.locate_file(path,name)
+ begin
+ files = Dir.entries(path)
+ if files.include?(name) then
+ fullname = File.join(path,name)
+ return fullname if FileTest.file?(fullname)
+ end
+ files.each do |p|
+ fullname = File.join(path,p)
+ if p != '.' and p != '..' and FileTest.directory?(fullname) and result = locate_file(fullname,name) then
+ return result
+ end
+ end
+ rescue
+ # bad path
+ end
+ return nil
+ end
+
+ def File.glob_file(pattern)
+ return Dir.glob(pattern).first
+ end
+
+end
+
+module KpseUtil
+
+ # to be adapted, see loading cnf file
+
+ @@texmftrees = ['texmf-local','texmf.local','../..','texmf'] # '../..' is for gwtex
+ @@texmfcnf = 'texmf.cnf'
+
+ def KpseUtil::identify
+ # we mainly need to identify the local tex stuff and wse assume that
+ # the texmfcnf variable is set; otherwise we need to expand the
+ # TEXMF variable and that takes time since it may involve more
+ ownpath = File.expand_path($0)
+ if ownpath.gsub!(/texmf.*?$/o, '') then
+ ENV['SELFAUTOPARENT'] = ownpath
+ else
+ ENV['SELFAUTOPARENT'] = '.' # fall back
+ # may be too tricky:
+ #
+ # (ENV['PATH'] ||'').split_path.each do |p|
+ # if p.gsub!(/texmf.*?$/o, '') then
+ # ENV['SELFAUTOPARENT'] = p
+ # break
+ # end
+ # end
+ end
+ filenames = Array.new
+ if ENV['TEXMFCNF'] && ! ENV['TEXMFCNF'].empty? then
+ ENV['TEXMFCNF'].to_s.split_path.each do |path|
+ filenames << File.join(path,@@texmfcnf)
+ end
+ elsif ENV['SELFAUTOPARENT'] == '.' then
+ filenames << File.join('.',@@texmfcnf)
+ else
+ @@texmftrees.each do |tree|
+ filenames << File.join(ENV['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf)
+ end
+ end
+ loop do
+ busy = false
+ filenames.collect! do |f|
+ f.gsub(/\$([a-zA-Z0-9\_\-]+)/o) do
+ if (! ENV[$1]) || (ENV[$1] == $1) then
+ "$#{$1}"
+ else
+ busy = true
+ ENV[$1]
+ end
+ end
+ end
+ break unless busy
+ end
+ filenames.delete_if do |f|
+ ! FileTest.file?(f)
+ end
+ return filenames
+ end
+
+ def KpseUtil::environment
+ Hash.new.merge(ENV)
+ end
+
+end
+
+class KpseFast
+
+ # formats are an incredible inconsistent mess
+
+ @@suffixes = Hash.new
+ @@formats = Hash.new
+ @@suffixmap = Hash.new
+
+ @@texmfcnf = 'texmf.cnf'
+
+ @@suffixes['gf'] = ['.<resolution>gf'] # todo
+ @@suffixes['pk'] = ['.<resolution>pk'] # todo
+ @@suffixes['tfm'] = ['.tfm']
+ @@suffixes['afm'] = ['.afm']
+ @@suffixes['base'] = ['.base']
+ @@suffixes['bib'] = ['.bib']
+ @@suffixes['bst'] = ['.bst']
+ @@suffixes['cnf'] = ['.cnf']
+ @@suffixes['ls-R'] = ['ls-R', 'ls-r']
+ @@suffixes['fmt'] = ['.fmt', '.efmt', '.efm', '.ofmt', '.ofm', '.oft', '.eofmt', '.eoft', '.eof', '.pfmt', '.pfm', '.epfmt', '.epf', '.xpfmt', '.xpf', '.afmt', '.afm']
+ @@suffixes['map'] = ['.map']
+ @@suffixes['mem'] = ['.mem']
+ @@suffixes['mf'] = ['.mf']
+ @@suffixes['mfpool'] = ['.pool']
+ @@suffixes['mft'] = ['.mft']
+ @@suffixes['mp'] = ['.mp']
+ @@suffixes['mppool'] = ['.pool']
+ @@suffixes['ocp'] = ['.ocp']
+ @@suffixes['ofm'] = ['.ofm', '.tfm']
+ @@suffixes['opl'] = ['.opl']
+ @@suffixes['otp'] = ['.otp']
+ @@suffixes['ovf'] = ['.ovf']
+ @@suffixes['ovp'] = ['.ovp']
+ @@suffixes['graphic/figure'] = ['.eps', '.epsi']
+ @@suffixes['tex'] = ['.tex']
+ @@suffixes['texpool'] = ['.pool']
+ @@suffixes['PostScript header'] = ['.pro']
+ @@suffixes['type1 fonts'] = ['.pfa', '.pfb']
+ @@suffixes['vf'] = ['.vf']
+ @@suffixes['ist'] = ['.ist']
+ @@suffixes['truetype fonts'] = ['.ttf', '.ttc']
+ @@suffixes['web'] = ['.web', '.ch']
+ @@suffixes['cweb'] = ['.w', '.web', '.ch']
+ @@suffixes['enc files'] = ['.enc']
+ @@suffixes['cmap files'] = ['.cmap']
+ @@suffixes['subfont definition files'] = ['.sfd']
+ @@suffixes['lig files'] = ['.lig']
+ @@suffixes['bitmap font'] = []
+ @@suffixes['MetaPost support'] = []
+ @@suffixes['TeX system documentation'] = []
+ @@suffixes['TeX system sources'] = []
+ @@suffixes['Troff fonts'] = []
+ @@suffixes['dvips config'] = []
+ @@suffixes['type42 fonts'] = []
+ @@suffixes['web2c files'] = []
+ @@suffixes['other text files'] = []
+ @@suffixes['other binary files'] = []
+ @@suffixes['misc fonts'] = []
+ @@suffixes['opentype fonts'] = []
+ @@suffixes['pdftex config'] = []
+ @@suffixes['texmfscripts'] = []
+
+ # replacements
+
+ @@suffixes['fmt'] = ['.fmt']
+ @@suffixes['type1 fonts'] = ['.pfa', '.pfb', '.pfm']
+ @@suffixes['tex'] = ['.tex', '.xml']
+ @@suffixes['texmfscripts'] = ['rb','lua','py','pl']
+
+ @@suffixes.keys.each do |k| @@suffixes[k].each do |s| @@suffixmap[s] = k end end
+
+ # TTF2TFMINPUTS
+ # MISCFONTS
+ # TEXCONFIG
+ # DVIPDFMINPUTS
+ # OTFFONTS
+
+ @@formats['gf'] = ''
+ @@formats['pk'] = ''
+ @@formats['tfm'] = 'TFMFONTS'
+ @@formats['afm'] = 'AFMFONTS'
+ @@formats['base'] = 'MFBASES'
+ @@formats['bib'] = ''
+ @@formats['bst'] = ''
+ @@formats['cnf'] = ''
+ @@formats['ls-R'] = ''
+ @@formats['fmt'] = 'TEXFORMATS'
+ @@formats['map'] = 'TEXFONTMAPS'
+ @@formats['mem'] = 'MPMEMS'
+ @@formats['mf'] = 'MFINPUTS'
+ @@formats['mfpool'] = 'MFPOOL'
+ @@formats['mft'] = ''
+ @@formats['mp'] = 'MPINPUTS'
+ @@formats['mppool'] = 'MPPOOL'
+ @@formats['ocp'] = 'OCPINPUTS'
+ @@formats['ofm'] = 'OFMFONTS'
+ @@formats['opl'] = 'OPLFONTS'
+ @@formats['otp'] = 'OTPINPUTS'
+ @@formats['ovf'] = 'OVFFONTS'
+ @@formats['ovp'] = 'OVPFONTS'
+ @@formats['graphic/figure'] = ''
+ @@formats['tex'] = 'TEXINPUTS'
+ @@formats['texpool'] = 'TEXPOOL'
+ @@formats['PostScript header'] = 'TEXPSHEADERS'
+ @@formats['type1 fonts'] = 'T1FONTS'
+ @@formats['vf'] = 'VFFONTS'
+ @@formats['ist'] = ''
+ @@formats['truetype fonts'] = 'TTFONTS'
+ @@formats['web'] = ''
+ @@formats['cweb'] = ''
+ @@formats['enc files'] = 'ENCFONTS'
+ @@formats['cmap files'] = 'CMAPFONTS'
+ @@formats['subfont definition files'] = 'SFDFONTS'
+ @@formats['lig files'] = 'LIGFONTS'
+ @@formats['bitmap font'] = ''
+ @@formats['MetaPost support'] = ''
+ @@formats['TeX system documentation'] = ''
+ @@formats['TeX system sources'] = ''
+ @@formats['Troff fonts'] = ''
+ @@formats['dvips config'] = ''
+ @@formats['type42 fonts'] = 'T42FONTS'
+ @@formats['web2c files'] = 'WEB2C'
+ @@formats['other text files'] = ''
+ @@formats['other binary files'] = ''
+ @@formats['misc fonts'] = ''
+ @@formats['opentype fonts'] = 'OPENTYPEFONTS'
+ @@formats['pdftex config'] = 'PDFTEXCONFIG'
+ @@formats['texmfscripts'] = 'TEXMFSCRIPTS'
+
+ attr_accessor :progname, :engine, :format, :rootpath, :treepath,
+ :verbose, :remember, :scandisk, :diskcache, :renewcache
+
+ @@cacheversion = '1'
+
+ def initialize
+ @rootpath = ''
+ @treepath = ''
+ @progname = 'kpsewhich'
+ @engine = 'pdftex'
+ @variables = Hash.new
+ @expansions = Hash.new
+ @files = Hash.new
+ @found = Hash.new
+ @kpsevars = Hash.new
+ @lsrfiles = Array.new
+ @cnffiles = Array.new
+ @verbose = true
+ @remember = true
+ @scandisk = true
+ @diskcache = true
+ @renewcache = false
+ @isolate = false
+
+ @diskcache = false
+ @cachepath = nil
+ @cachefile = 'tmftools.log'
+
+ @environment = ENV
+ end
+
+ def set(key,value)
+ case key
+ when 'progname' then @progname = value
+ when 'engine' then @engine = value
+ when 'format' then @format = value
+ end
+ end
+
+ def push_environment(env)
+ @environment = env
+ end
+
+ # {$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}
+ #
+ # $SELFAUTOLOC : /usr/tex/bin/platform
+ # $SELFAUTODIR : /usr/tex/bin
+ # $SELFAUTOPARENT : /usr/tex
+ #
+ # since we live in scriptpath we need a slightly different method
+
+ def load_cnf(filenames=nil)
+ unless filenames then
+ ownpath = File.expand_path($0)
+ if ownpath.gsub!(/texmf.*?$/o, '') then
+ @environment['SELFAUTOPARENT'] = ownpath
+ else
+ @environment['SELFAUTOPARENT'] = '.'
+ end
+ unless @treepath.empty? then
+ unless @rootpath.empty? then
+ @treepath = @treepath.split(',').collect do |p| File.join(@rootpath,p) end.join(',')
+ end
+ @environment['TEXMF'] = @treepath
+ # only the first one
+ @environment['TEXMFCNF'] = File.join(@treepath.split(',').first,'texmf/web2c')
+ end
+ unless @rootpath.empty? then
+ @environment['TEXMFCNF'] = File.join(@rootpath,'texmf/web2c')
+ @environment['SELFAUTOPARENT'] = @rootpath
+ @isolate = true
+ end
+ filenames = Array.new
+ if @environment['TEXMFCNF'] and not @environment['TEXMFCNF'].empty? then
+ @environment['TEXMFCNF'].to_s.split_path.each do |path|
+ filenames << File.join(path,@@texmfcnf)
+ end
+ elsif @environment['SELFAUTOPARENT'] == '.' then
+ filenames << File.join('.',@@texmfcnf)
+ else
+ ['texmf-local','texmf'].each do |tree|
+ filenames << File.join(@environment['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf)
+ end
+ end
+ end
+ # <root>/texmf/web2c/texmf.cnf
+ filenames = _expanded_path_(filenames)
+ @rootpath = filenames.first
+ 3.times do
+ @rootpath = File.dirname(@rootpath)
+ end
+ filenames.collect! do |f|
+ f.gsub("\\", '/')
+ end
+ filenames.each do |fname|
+ if FileTest.file?(fname) and f = File.open(fname) then
+ @cnffiles << fname
+ while line = f.gets do
+ loop do
+ # concatenate lines ending with \
+ break unless line.sub!(/\\\s*$/o) do
+ f.gets || ''
+ end
+ end
+ case line
+ when /^[\%\#]/o then
+ # comment
+ when /^\s*(.*?)\s*\=\s*(.*?)\s*$/o then
+ key, value = $1, $2
+ unless @variables.key?(key) then
+ value.sub!(/\%.*$/,'')
+ value.sub!(/\~/, "$HOME")
+ @variables[key] = value
+ end
+ @kpsevars[key] = true
+ end
+ end
+ f.close
+ end
+ end
+ end
+
+ def load_lsr
+ @lsrfiles = []
+ simplified_list(expansion('TEXMF')).each do |p|
+ ['ls-R','ls-r'].each do |f|
+ filename = File.join(p,f)
+ if FileTest.file?(filename) then
+ @lsrfiles << [filename,File.size(filename)]
+ break
+ end
+ end
+ end
+ @files = Hash.new
+ if @diskcache then
+ ['HOME','TEMP','TMP','TMPDIR'].each do |key|
+ if @environment[key] then
+ if FileTest.directory?(@environment[key]) then
+ @cachepath = @environment[key]
+ @cachefile = [@rootpath.gsub(/[^A-Z0-9]/io, '-').gsub(/\-+/,'-'),File.basename(@cachefile)].join('-')
+ break
+ end
+ end
+ end
+ if @cachepath and not @renewcache and FileTest.file?(File.join(@cachepath,@cachefile)) then
+ begin
+ if f = File.open(File.join(@cachepath,@cachefile)) then
+ cacheversion = Marshal.load(f)
+ if cacheversion == @@cacheversion then
+ lsrfiles = Marshal.load(f)
+ if lsrfiles == @lsrfiles then
+ @files = Marshal.load(f)
+ end
+ end
+ f.close
+ end
+ rescue
+ @files = Hash.new
+ end
+ end
+ end
+ return if @files.size > 0
+ @lsrfiles.each do |filedata|
+ filename, filesize = filedata
+ filepath = File.dirname(filename)
+ begin
+ path = '.'
+ data = IO.readlines(filename)
+ if data[0].chomp =~ /% ls\-R \-\- filename database for kpathsea\; do not change this line\./io then
+ data.each do |line|
+ case line
+ when /^[a-zA-Z0-9]/o then
+ line.chomp!
+ if @files[line] then
+ @files[line] << path
+ else
+ @files[line] = [path]
+ end
+ when /^\.\/(.*?)\:$/o then
+ path = File.join(filepath,$1)
+ end
+ end
+ end
+ rescue
+ # sorry
+ end
+ end
+ if @diskcache and @cachepath and f = File.open(File.join(@cachepath,@cachefile),'wb') then
+ f << Marshal.dump(@@cacheversion)
+ f << Marshal.dump(@lsrfiles)
+ f << Marshal.dump(@files)
+ f.close
+ end
+ end
+
+ def expand_variables
+ @expansions = Hash.new
+ if @isolate then
+ @variables['TEXMFCNF'] = @environment['TEXMFCNF'].dup
+ @variables['SELFAUTOPARENT'] = @environment['SELFAUTOPARENT'].dup
+ else
+ @environment.keys.each do |e|
+ if e =~ /^([a-zA-Z]+)\_(.*)\s*$/o then
+ @expansions["#{$1}.#{$2}"] = (@environment[e] ||'').dup
+ else
+ @expansions[e] = (@environment[e] ||'').dup
+ end
+ end
+ end
+ @variables.keys.each do |k|
+ @expansions[k] = @variables[k].dup unless @expansions[k]
+ end
+ loop do
+ busy = false
+ @expansions.keys.each do |k|
+ @expansions[k].gsub!(/\$([a-zA-Z0-9\_\-]*)/o) do
+ busy = true
+ @expansions[$1] || ''
+ end
+ @expansions[k].gsub!(/\$\{([a-zA-Z0-9\_\-]*)\}/o) do
+ busy = true
+ @expansions[$1] || ''
+ end
+ end
+ break unless busy
+ end
+ @expansions.keys.each do |k|
+ @expansions[k] = @expansions[k].gsub("\\", '/')
+ end
+ end
+
+ def variable(name='')
+ (name and not name.empty? and @variables[name.sub('$','')]) or ''
+ end
+
+ def expansion(name='')
+ (name and not name.empty? and @expansions[name.sub('$','')]) or ''
+ end
+
+ def variable?(name='')
+ name and not name.empty? and @variables.key?(name.sub('$',''))
+ end
+
+ def expansion?(name='')
+ name and not name.empty? and @expansions.key?(name.sub('$',''))
+ end
+
+ def simplified_list(str)
+ lst = str.gsub(/^\{/o,'').gsub(/\}$/o,'').split(",")
+ lst.collect do |l|
+ l.sub(/^[\!]*/,'').sub(/[\/\\]*$/o,'')
+ end
+ end
+
+ def original_variable(variable)
+ if variable?("#{@progname}.#{variable}") then
+ variable("#{@progname}.#{variable}")
+ elsif variable?(variable) then
+ variable(variable)
+ else
+ ''
+ end
+ end
+
+ def expanded_variable(variable)
+ if expansion?("#{variable}.#{@progname}") then
+ expansion("#{variable}.#{@progname}")
+ elsif expansion?(variable) then
+ expansion(variable)
+ else
+ ''
+ end
+ end
+
+ def original_path(filename='')
+ _expanded_path_(original_variable(var_of_format_or_suffix(filename)).split(";"))
+ end
+
+ def expanded_path(filename='')
+ _expanded_path_(expanded_variable(var_of_format_or_suffix(filename)).split(";"))
+ end
+
+ def _expanded_path_(pathlist)
+ i, n = 0, 0
+ pathlist.collect! do |mainpath|
+ mainpath.gsub(/([\{\}])/o) do
+ if $1 == "{" then
+ i += 1 ; n = i if i > n ; "<#{i}>"
+ else
+ i -= 1 ; "</#{i+1}>"
+ end
+ end
+ end
+ n.times do |i|
+ loop do
+ more = false
+ newlist = []
+ pathlist.each do |path|
+ unless path.sub!(/^(.*?)<(#{n-i})>(.*?)<\/\2>(.*?)$/) do
+ pre, mid, post = $1, $3, $4
+ mid.gsub!(/\,$/,',.')
+ mid.split(',').each do |m|
+ more = true
+ if m == '.' then
+ newlist << "#{pre}#{post}"
+ else
+ newlist << "#{pre}#{m}#{post}"
+ end
+ end
+ end then
+ newlist << path
+ end
+ end
+ if more then
+ pathlist = [newlist].flatten # copy -)
+ else
+ break
+ end
+ end
+ end
+ pathlist = pathlist.uniq.collect do |path|
+ p = path
+ # p.gsub(/^\/+/o) do '' end
+ # p.gsub!(/(.)\/\/(.)/o) do "#{$1}/#{$2}" end
+ # p.gsub!(/\/\/+$/o) do '//' end
+ p.gsub!(/\/\/+/o) do '//' end
+ p
+ end
+ pathlist
+ end
+
+ # todo: ignore case
+
+ def var_of_format(str)
+ @@formats[str] || ''
+ end
+
+ def var_of_suffix(str) # includes .
+ if @@suffixmap.key?(str) then @@formats[@@suffixmap[str]] else '' end
+ end
+
+ def var_of_format_or_suffix(str)
+ if @@formats.key?(str) then
+ @@formats[str]
+ elsif @@suffixmap.key?(File.extname(str)) then # extname includes .
+ @@formats[@@suffixmap[File.extname(str)]] # extname includes .
+ else
+ ''
+ end
+ end
+
+end
+
+class KpseFast
+
+ # test things
+
+ def list_variables(kpseonly=true)
+ @variables.keys.sort.each do |k|
+ if kpseonly then
+ puts("#{k} = #{@variables[k]}") if @kpsevars[k]
+ else
+ puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@variables[k]}")
+ end
+ end
+ end
+
+ def list_expansions(kpseonly=true)
+ @expansions.keys.sort.each do |k|
+ if kpseonly then
+ puts("#{k} = #{@expansions[k]}") if @kpsevars[k]
+ else
+ puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@expansions[k]}")
+ end
+ end
+ end
+
+ def list_lsr
+ puts("files = #{@files.size}")
+ end
+
+ def set_test_patterns
+ @variables["KPSE_TEST_PATTERN_A"] = "foo/{1,2}/bar//"
+ @variables["KPSE_TEST_PATTERN_B"] = "!!x{A,B{1,2}}y"
+ @variables["KPSE_TEST_PATTERN_C"] = "x{A,B//{1,2}}y"
+ @variables["KPSE_TEST_PATTERN_D"] = "x{A,B//{1,2,}}//y"
+ end
+
+ def show_test_patterns
+ ['A','B','D'].each do |i|
+ puts ""
+ puts @variables ["KPSE_TEST_PATTERN_#{i}"]
+ puts ""
+ puts expand_path("KPSE_TEST_PATTERN_#{i}").split_path
+ puts ""
+ end
+ end
+
+end
+
+class KpseFast
+
+ # kpse stuff
+
+ def expand_braces(str) # output variable and brace expansion of STRING.
+ _expanded_path_(original_variable(str).split_path).join_path
+ end
+
+ def expand_path(str) # output complete path expansion of STRING.
+ _expanded_path_(expanded_variable(str).split_path).join_path
+ end
+
+ def expand_var(str) # output variable expansion of STRING.
+ expanded_variable(str)
+ end
+
+ def show_path(str) # output search path for file type NAME
+ expanded_path(str).join_path
+ end
+
+ def var_value(str) # output the value of variable $STRING.
+ original_variable(str)
+ end
+
+end
+
+class KpseFast
+
+ def _is_cnf_?(filename)
+ filename == File.basename((@cnffiles.first rescue @@texmfcnf) || @@texmfcnf)
+ end
+
+ def find_file(filename)
+ if _is_cnf_?(filename) then
+ @cnffiles.first rescue ''
+ else
+ [find_files(filename,true)].flatten.first || ''
+ end
+ end
+
+ def find_files(filename,first=false)
+ if _is_cnf_?(filename) then
+ result = @cnffiles.dup
+ else
+ if @remember then
+ # stamp = "#{filename}--#{@format}--#{@engine}--#{@progname}"
+ stamp = "#{filename}--#{@engine}--#{@progname}"
+ return @found[stamp] if @found.key?(stamp)
+ end
+ pathlist = expanded_path(filename)
+ result = []
+ filelist = if @files.key?(filename) then @files[filename].uniq else nil end
+ done = false
+ if pathlist.size == 0 then
+ if FileTest.file?(filename) then
+ done = true
+ result << '.'
+ end
+ else
+ pathlist.each do |path|
+ doscan = if path =~ /^\!\!/o then false else true end
+ recurse = if path =~ /\/\/$/o then true else false end
+ pathname = path.dup
+ pathname.gsub!(/^\!+/o, '')
+ done = false
+ if not done and filelist then
+ # checking for exact match
+ if filelist.include?(pathname) then
+ result << pathname
+ done = true
+ end
+ if not done and recurse then
+ # checking for fuzzy //
+ pathname.gsub!(/\/+$/o, '/.*')
+ # pathname.gsub!(/\/\//o,'/[\/]*/')
+ pathname.gsub!(/\/\//o,'/.*?/')
+ re = /^#{pathname}/
+ filelist.each do |f|
+ if re =~ f then
+ result << f # duplicates will be filtered later
+ done = true
+ end
+ break if done
+ end
+ end
+ end
+ if not done and doscan then
+ # checking for path itself
+ pname = pathname.sub(/\.\*$/,'')
+ if not pname =~ /\*/o and FileTest.file?(File.join(pname,filename)) then
+ result << pname
+ done = true
+ end
+ end
+ break if done and first
+ end
+ end
+ if not done and @scandisk then
+ pathlist.each do |path|
+ pathname = path.dup
+ unless pathname.gsub!(/^\!+/o, '') then # !! prevents scan
+ recurse = pathname.gsub!(/\/+$/o, '')
+ complex = pathname.gsub!(/\/\//o,'/*/')
+ if recurse then
+ if complex then
+ if ok = File.glob_file("#{pathname}/**/#{filename}") then
+ result << File.dirname(ok)
+ done = true
+ end
+ elsif ok = File.locate_file(pathname,filename) then
+ result << File.dirname(ok)
+ done = true
+ end
+ elsif complex then
+ if ok = File.glob_file("#{pathname}/#{filename}") then
+ result << File.dirname(ok)
+ done = true
+ end
+ elsif FileTest.file?(File.join(pathname,filename)) then
+ result << pathname
+ done = true
+ end
+ break if done and first
+ end
+ end
+ end
+ result = result.uniq.collect do |pathname|
+ File.join(pathname,filename)
+ end
+ @found[stamp] = result if @remember
+ end
+ return result # redundant
+ end
+
+end
+
+class KpseFast
+
+ class FileData
+ attr_accessor :tag, :name, :size, :date
+ def initialize(tag=0,name=nil,size=nil,date=nil)
+ @tag, @name, @size, @date = tag, name, size, date
+ end
+ def FileData.sizes(a)
+ a.collect do |aa|
+ aa.size
+ end
+ end
+ def report
+ case @tag
+ when 1 then "deleted | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}"
+ when 2 then "present | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}"
+ when 3 then "obsolete | #{' '*8} | #{' '*16} | #{@name}"
+ end
+ end
+ end
+
+ def analyze_files(filter='',strict=false,sort='',delete=false)
+ puts("command line = #{ARGV.join(' ')}")
+ puts("number of files = #{@files.size}")
+ puts("filter pattern = #{filter}")
+ puts("loaded cnf files = #{@cnffiles.join(' ')}")
+ puts('')
+ if filter.gsub!(/^not:/,'') then
+ def the_same(filter,filename)
+ not filter or filter.empty? or /#{filter}/ !~ filename
+ end
+ else
+ def the_same(filter,filename)
+ not filter or filter.empty? or /#{filter}/ =~ filename
+ end
+ end
+ @files.keys.each do |name|
+ if @files[name].size > 1 then
+ data = Array.new
+ @files[name].each do |path|
+ filename = File.join(path,name)
+ # if not filter or filter.empty? or /#{filter}/ =~ filename then
+ if the_same(filter,filename) then
+ if FileTest.file?(filename) then
+ if delete then
+ data << FileData.new(1,filename,File.size(filename),File.mtime(filename))
+ begin
+ File.delete(filename) if delete
+ rescue
+ end
+ else
+ data << FileData.new(2,filename,File.size(filename),File.mtime(filename))
+ end
+ else
+ # data << FileData.new(3,filename)
+ end
+ end
+ end
+ if data.length > 1 then
+ if strict then
+ # if data.collect do |d| d.size end.uniq! then
+ # data.sort! do |a,b| b.size <=> a.size end
+ # data.each do |d| puts d.report end
+ # puts ''
+ # end
+ data.sort! do |a,b|
+ if a.size and b.size then
+ b.size <=> a.size
+ else
+ 0
+ end
+ end
+ bunch = Array.new
+ done = false
+ data.each do |d|
+ if bunch.size == 0 then
+ bunch << d
+ elsif bunch[0].size == d.size then
+ bunch << d
+ else
+ if bunch.size > 1 then
+ bunch.each do |b|
+ puts b.report
+ end
+ done = true
+ end
+ bunch = [d]
+ end
+ end
+ puts '' if done
+ else
+ case sort
+ when 'size' then data.sort! do |a,b| a.size <=> b.size end
+ when 'revsize' then data.sort! do |a,b| b.size <=> a.size end
+ when 'date' then data.sort! do |a,b| a.date <=> b.date end
+ when 'revdate' then data.sort! do |a,b| b.date <=> a.date end
+ end
+ data.each do |d| puts d.report end
+ puts ''
+ end
+ end
+ end
+ end
+ end
+
+end
+
+# if false then
+
+ # k = KpseFast.new # (root)
+ # k.set_test_patterns
+ # k.load_cnf
+ # k.expand_variables
+ # k.load_lsr
+
+ # k.show_test_patterns
+
+ # puts k.list_variables
+ # puts k.list_expansions
+ # k.list_lsr
+ # puts k.expansion("$TEXMF")
+ # puts k.expanded_path("TEXINPUTS","context")
+
+ # k.progname, k.engine, k.format = 'context', 'pdftex', 'tfm'
+ # k.scandisk = false # == must_exist
+ # k.expand_variables
+
+ # 10.times do |i| puts k.find_file('texnansi-lmr10.tfm') end
+
+ # puts "expand braces $TEXMF"
+ # puts k.expand_braces("$TEXMF")
+ # puts "expand path $TEXMF"
+ # puts k.expand_path("$TEXMF")
+ # puts "expand var $TEXMF"
+ # puts k.expand_var("$TEXMF")
+ # puts "expand path $TEXMF"
+ # puts k.show_path('tfm')
+ # puts "expand value $TEXINPUTS"
+ # puts k.var_value("$TEXINPUTS")
+ # puts "expand value $TEXINPUTS.context"
+ # puts k.var_value("$TEXINPUTS.context")
+
+ # exit
+
+# end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpseremote.rb b/Master/texmf-dist/scripts/context/ruby/base/kpseremote.rb
new file mode 100644
index 00000000000..9a73b88b00e
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpseremote.rb
@@ -0,0 +1,116 @@
+require 'base/kpsefast'
+
+case ENV['KPSEMETHOD']
+ when /soap/o then require 'base/kpse/soap'
+ when /drb/o then require 'base/kpse/drb'
+ else require 'base/kpse/drb'
+end
+
+class KpseRemote
+
+ @@port = ENV['KPSEPORT'] || 7000
+ @@method = ENV['KPSEMETHOD'] || 'drb'
+
+ def KpseRemote::available?
+ @@method && @@port
+ end
+
+ def KpseRemote::start_server(port=nil)
+ kpse = KpseServer.new(port || @@port)
+ kpse.start
+ end
+
+ def KpseRemote::start_client(port=nil) # keeps object in server
+ kpseclient = KpseClient.new(port || @@port)
+ kpseclient.start
+ kpse = kpseclient.object
+ tree = kpse.choose(KpseUtil::identify, KpseUtil::environment)
+ [kpse, tree]
+ end
+
+ def KpseRemote::fetch(port=nil) # no need for defining methods but slower, send whole object
+ kpseclient = KpseClient.new(port || @@port)
+ kpseclient.start
+ kpseclient.object.fetch(KpseUtil::identify, KpseUtil::environment) rescue nil
+ end
+
+ def initialize(port=nil)
+ if KpseRemote::available? then
+ begin
+ @kpse, @tree = KpseRemote::start_client(port)
+ rescue
+ @kpse, @tree = nil, nil
+ end
+ else
+ @kpse, @tree = nil, nil
+ end
+ end
+
+ def progname=(value)
+ @kpse.set(@tree,'progname',value)
+ end
+ def format=(value)
+ @kpse.set(@tree,'format',value)
+ end
+ def engine=(value)
+ @kpse.set(@tree,'engine',value)
+ end
+
+ def progname
+ @kpse.get(@tree,'progname')
+ end
+ def format
+ @kpse.get(@tree,'format')
+ end
+ def engine
+ @kpse.get(@tree,'engine')
+ end
+
+ def load
+ @kpse.load(KpseUtil::identify, KpseUtil::environment)
+ end
+ def okay?
+ @kpse && @tree
+ end
+ def set(key,value)
+ @kpse.set(@tree,key,value)
+ end
+ def load_cnf
+ @kpse.load_cnf(@tree)
+ end
+ def load_lsr
+ @kpse.load_lsr(@tree)
+ end
+ def expand_variables
+ @kpse.expand_variables(@tree)
+ end
+ def expand_braces(str)
+ clean_name(@kpse.expand_braces(@tree,str))
+ end
+ def expand_path(str)
+ clean_name(@kpse.expand_path(@tree,str))
+ end
+ def expand_var(str)
+ clean_name(@kpse.expand_var(@tree,str))
+ end
+ def show_path(str)
+ clean_name(@kpse.show_path(@tree,str))
+ end
+ def var_value(str)
+ clean_name(@kpse.var_value(@tree,str))
+ end
+ def find_file(filename)
+ clean_name(@kpse.find_file(@tree,filename))
+ end
+ def find_files(filename,first=false)
+ # dodo: each filename
+ @kpse.find_files(@tree,filename,first)
+ end
+
+ private
+
+ def clean_name(str)
+ str.gsub(/\\/,'/')
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpserunner.rb b/Master/texmf-dist/scripts/context/ruby/base/kpserunner.rb
new file mode 100644
index 00000000000..cfc2ad4fbfd
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/kpserunner.rb
@@ -0,0 +1,87 @@
+require 'base/kpsefast'
+
+module KpseRunner
+
+ @@kpse = nil
+
+ def KpseRunner.kpsewhich(arg='')
+ options, arguments = split_args(arg)
+ unless @@kpse then
+ if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then
+ require 'base/kpseremote'
+ @@kpse = KpseRemote.new
+ else
+ @@kpse = nil
+ end
+ if @@kpse && @@kpse.okay? then
+ @@kpse.progname = options['progname'] || ''
+ @@kpse.engine = options['engine'] || ''
+ @@kpse.format = options['format'] || ''
+ else
+ require 'base/kpsefast'
+ @@kpse = KpseFast.new
+ @@kpse.load_cnf
+ @@kpse.progname = options['progname'] || ''
+ @@kpse.engine = options['engine'] || ''
+ @@kpse.format = options['format'] || ''
+ @@kpse.expand_variables
+ @@kpse.load_lsr
+ end
+ else
+ @@kpse.progname = options['progname'] || ''
+ @@kpse.engine = options['engine'] || ''
+ @@kpse.format = options['format'] || ''
+ @@kpse.expand_variables
+ end
+ if option = options['expand-braces'] and not option.empty? then
+ @@kpse.expand_braces(option)
+ elsif option = options['expand-path'] and not option.empty? then
+ @@kpse.expand_path(option)
+ elsif option = options['expand-var'] and not option.empty? then
+ @@kpse.expand_var(option)
+ elsif option = options['show-path'] and not option.empty? then
+ @@kpse.show_path(option)
+ elsif option = options['var-value'] and not option.empty? then
+ @@kpse.expand_var(option)
+ elsif arguments.size > 0 then
+ files = Array.new
+ arguments.each do |option|
+ if file = @@kpse.find_file(option) and not file.empty? then
+ files << file
+ end
+ end
+ files.join("\n")
+ else
+ ''
+ end
+ end
+
+ def KpseRunner.kpsereset
+ @@kpse = nil
+ end
+
+ private
+
+ def KpseRunner.split_args(arg)
+ vars, args = Hash.new, Array.new
+ arg.gsub!(/([\"\'])(.*?)\1/o) do
+ $2.gsub(' ','<space/>')
+ end
+ arg = arg.split(/\s+/o)
+ arg.collect! do |a|
+ a.gsub('<space/>',' ')
+ end
+ arg.each do |a|
+ if a =~ /^(.*?)\=(.*?)$/o then
+ k, v = $1, $2
+ vars[k.sub(/^\-+/,'')] = v
+ else
+ args << a
+ end
+ end
+ # puts vars.inspect
+ # puts args.inspect
+ return vars, args
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/logger.rb b/Master/texmf-dist/scripts/context/ruby/base/logger.rb
new file mode 100644
index 00000000000..2245ab331f0
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/logger.rb
@@ -0,0 +1,105 @@
+# module : base/logger
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+require 'thread'
+
+# The next calls are valid:
+
+# @log.report('a','b','c', 'd')
+# @log.report('a','b',"c #{d}")
+# @log.report("a b c #{d}")
+
+# Keep in mind that "whatever #{something}" is two times faster than
+# 'whatever ' + something or ['whatever',something].join and that
+# when verbosity is not needed the following is much faster too:
+
+# @log.report('a','b','c', 'd') if @log.verbose?
+# @log.report('a','b',"c #{d}") if @log.verbose?
+# @log.report("a b c #{d}") if @log.verbose?
+
+# The last three cases are equally fast when verbosity is turned off.
+
+# Under consideration: verbose per instance
+
+class Logger
+
+ @@length = 0
+ @@verbose = false
+
+ def initialize(tag=nil,length=0,verbose=false)
+ @tag = tag || ''
+ @@verbose = @@verbose || verbose
+ @@length = @tag.length if @tag.length > @@length
+ @@length = length if length > @@length
+ end
+
+ def report(*str)
+ begin
+ case str.length
+ when 0
+ print("\n")
+ return true
+ when 1
+ # message = str.first
+ message = str.first.join(' ')
+ else
+ message = [str].flatten.collect{|s| s.to_s}.join(' ').chomp
+ end
+ if @tag.empty? then
+ print("#{message}\n")
+ else
+ # try to avoid too many adjustments
+ @tag = @tag.ljust(@@length) unless @tag.length == @@length
+ print("#{@tag} | #{message}\n")
+ end
+ rescue
+ end
+ return true
+ end
+
+ def reportlines(*str)
+ unless @tag.empty? then
+ @tag = @tag.ljust(@@length) unless @tag.length == @@length
+ end
+ report([str].flatten.collect{|s| s.gsub(/\n/,"\n#{@tag} | ")}.join(' '))
+ end
+
+ def debug(*str)
+ report(str) if @@verbose
+ end
+
+ def error(*str)
+ if ! $! || $!.to_s.empty? then
+ report(str)
+ else
+ report(str,$!)
+ end
+ end
+
+ def verbose
+ @@verbose = true
+ end
+
+ def silent
+ @@verbose = false
+ end
+
+ def verbose?
+ @@verbose
+ end
+
+ # attr_reader :tag
+
+ # alias fatal error
+ # alias info debug
+ # alias warn debug
+ # alias debug? :verbose?
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/merge.rb b/Master/texmf-dist/scripts/context/ruby/base/merge.rb
new file mode 100644
index 00000000000..a66b97e916b
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/merge.rb
@@ -0,0 +1,139 @@
+# module : base/merge
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2006
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# --selfmerg ewill create stand alone script (--selfcleanup does the opposite)
+
+# this module will package all the used modules in the file itself
+# so that we can relocate the file at wish, usage:
+#
+# merge:
+#
+# unless SelfMerge::ok? && SelfMerge::merge then
+# puts("merging should happen on the path were the base inserts reside")
+# end
+#
+# cleanup:
+#
+# unless SelfMerge::cleanup then
+# puts("merging should happen on the path were the base inserts reside")
+# end
+
+module SelfMerge
+
+ @@kpsemergestart = "\# kpse_merge_start"
+ @@kpsemergestop = "\# kpse_merge_stop"
+ @@kpsemergefile = "\# kpse_merge_file: "
+ @@kpsemergedone = "\# kpse_merge_done: "
+
+ @@filename = File.basename($0)
+ @@ownpath = File.expand_path(File.dirname($0))
+ @@modroot = '(base|graphics|rslb|www)' # needed in regex in order not to mess up SelfMerge
+ @@modules = $".collect do |file| File.expand_path(file) end
+
+ @@modules.delete_if do |file|
+ file !~ /^#{@@ownpath}\/#{@@modroot}.*$/i
+ end
+
+ def SelfMerge::ok?
+ begin
+ @@modules.each do |file|
+ return false unless FileTest.file?(file)
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::merge
+ begin
+ if SelfMerge::ok? && rbfile = IO.read(@@filename) then
+ begin
+ inserts = "#{@@kpsemergestart}\n\n"
+ @@modules.each do |file|
+ inserts << "#{@@kpsemergefile}'#{file}'\n\n"
+ inserts << IO.read(file).gsub(/^#.*?\n$/,'')
+ inserts << "\n\n"
+ end
+ inserts << "#{@@kpsemergestop}\n\n"
+ # no gsub! else we end up in SelfMerge
+ rbfile.sub!(/#{@@kpsemergestart}\s*#{@@kpsemergestop}/moi) do
+ inserts
+ end
+ rbfile.gsub!(/^(.*)(require [\"\'].*?#{@@modroot}.*)$/) do
+ pre, post = $1, $2
+ if pre =~ /#{@@kpsemergedone}/ then
+ "#{pre}#{post}"
+ else
+ "#{pre}#{@@kpsemergedone}#{post}"
+ end
+ end
+ rescue
+ return false
+ else
+ begin
+ File.open(@@filename,'w') do |f|
+ f << rbfile
+ end
+ rescue
+ return false
+ end
+ end
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::cleanup
+ begin
+ if rbfile = IO.read(@@filename) then
+ begin
+ rbfile.sub!(/#{@@kpsemergestart}(.*)#{@@kpsemergestop}\s*/moi) do
+ "#{@@kpsemergestart}\n\n#{@@kpsemergestop}\n\n"
+ end
+ rbfile.gsub!(/^(.*#{@@kpsemergedone}.*)$/) do
+ str = $1
+ if str =~ /require [\"\']/ then
+ str.gsub(/#{@@kpsemergedone}/, '')
+ else
+ str
+ end
+ end
+ rescue
+ return false
+ else
+ begin
+ File.open(@@filename,'w') do |f|
+ f << rbfile
+ end
+ rescue
+ return false
+ end
+ end
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::replace
+ if SelfMerge::ok? then
+ SelfMerge::cleanup
+ SelfMerge::merge
+ end
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/mp.rb b/Master/texmf-dist/scripts/context/ruby/base/mp.rb
new file mode 100644
index 00000000000..d168bde1d43
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/mp.rb
@@ -0,0 +1,167 @@
+# module : base/mp
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2005-2006
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+module MPTools
+
+ @@definitions, @@start, @@stop, @@before, @@after = Hash.new, Hash.new, Hash.new, Hash.new, Hash.new
+
+
+ @@definitions['plain'] = <<EOT
+\\gdef\\mpxshipout{\\shipout\\hbox\\bgroup
+ \\setbox0=\\hbox\\bgroup}
+
+\\gdef\\stopmpxshipout{\\egroup \\dimen0=\\ht0 \\advance\\dimen0\\dp0
+ \\dimen1=\\ht0 \\dimen2=\\dp0
+ \\setbox0=\\hbox\\bgroup
+ \\box0
+ \\ifnum\\dimen0>0 \\vrule width1sp height\\dimen1 depth\\dimen2
+ \\else \\vrule width1sp height1sp depth0sp\\relax
+ \\fi\\egroup
+ \\ht0=0pt \\dp0=0pt \\box0 \\egroup}
+EOT
+
+ @@start ['plain'] = ""
+ @@before['plain'] = "\\mpxshipout"
+ @@after ['plain'] = "\\stopmpxshipout"
+ @@stop ['plain'] = "\\end{document}"
+
+ @@definitions['context'] = <<EOT
+\\ifx\\startMPXpage\\undefined
+
+ \\ifx\\loadallfontmapfiles\\undefined \\let\\loadallfontmapfiles\\relax \\fi
+
+ \\gdef\\startMPXpage
+ {\\shipout\\hbox
+ \\bgroup
+ \\setbox0=\\hbox
+ \\bgroup}
+
+ \\gdef\\stopMPXpage
+ {\\egroup
+ \\dimen0=\\ht0
+ \\advance\\dimen0\\dp0
+ \\dimen1=\\ht0
+ \\dimen2=\\dp0
+ \\setbox0=\\hbox\\bgroup
+ \\box0
+ \\ifnum\\dimen0>0
+ \\vrule width 1sp height \\dimen1 depth \\dimen2
+ \\else
+ \\vrule width 1sp height 1sp depth 0sp \\relax
+ \\fi
+ \\egroup
+ \\ht0=0pt
+ \\dp0=0pt
+ \\loadallfontmapfiles
+ \\box0
+ \\egroup}
+
+\\fi
+
+\\ifx\\starttext\\undefined
+
+ \\let\\starttext\\relax
+ \\def\\stoptext{\\end{document}}
+
+\\fi
+EOT
+
+ @@start ['context'] = "\\starttext"
+ @@before['context'] = "\\startMPXpage"
+ @@after ['context'] = "\\stopMPXpage"
+ @@stop ['context'] = "\\stoptext"
+
+ # todo: \usemodule[m-mpx ] and test fo defined
+
+ def MPTools::mptotex(from,to=nil,method='plain')
+ begin
+ if from && data = IO.read(from) then
+ f = if to then File.open(to,'w') else $stdout end
+ f.puts("% file: #{from}")
+ f.puts("")
+ f.puts(@@definitions[method])
+ unless @@start[method].empty? then
+ f.puts("")
+ f.puts(@@start[method])
+ end
+ data.gsub!(/([^\\])%.*?$/mo) do
+ $1
+ end
+ data.scan(/(verbatim|b)tex\s*(.*?)\s*etex/mo) do
+ tag, text = $1, $2
+ f.puts("")
+ if tag == 'b' then
+ f.puts(@@before[method])
+ f.puts("#{text}%")
+ f.puts(@@after [method])
+ else
+ f.puts("#{text}")
+ end
+ f.puts("")
+ end
+ f.puts("")
+ f.puts(@@stop[method])
+ f.close
+ else
+ return false
+ end
+ rescue
+ File.delete(to) rescue false
+ return false
+ else
+ return true
+ end
+ end
+
+ @@splitMPlines = false
+
+ def MPTools::splitmplines(str)
+ if @@splitMPlines then
+ btex, verbatimtex, strings, result = Array.new, Array.new, Array.new, str.dup
+ # protect texts
+ result.gsub!(/btex\s*(.*?)\s*etex/) do
+ btex << $1
+ "btex(#{btex.length-1})"
+ end
+ result.gsub!(/verbatimtex\s*(.*?)\s*etex/) do
+ verbatimtex << $1
+ "verbatimtex(#{verbatimtex.length-1})"
+ end
+ result.gsub!(/\"(.*?)\"/) do
+ strings << $1
+ "\"#{strings.length-1}\""
+ end
+ result.gsub!(/\;/) do
+ ";\n"
+ end
+ result.gsub!(/(.{80,})(\-\-\-|\-\-|\.\.\.|\.\.)/) do
+ "#{$1}#{$2}\n"
+ end
+ result.gsub!(/\n[\s\n]+/moi) do
+ "\n"
+ end
+ result.gsub!(/btex\((\d+)\)/) do
+ "btex #{btex[$1.to_i]} etex"
+ end
+ result.gsub!(/verbatimtex\((\d+)\)/) do
+ "verbatimtex #{verbatimtex[$1.to_i]} etex"
+ end
+ result.gsub!(/\"(\d+)\"/) do
+ "\"#{strings[$1.to_i]}\""
+ end
+ # return result # let's catch xetex bug
+ return result.gsub(/\^\^(M|J)/o, "\n")
+ else
+ # return str # let's catch xetex bug
+ return str.gsub(/\^\^(M|J)/o, "\n")
+ end
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/pdf.rb b/Master/texmf-dist/scripts/context/ruby/base/pdf.rb
new file mode 100644
index 00000000000..6be0d3f987e
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/pdf.rb
@@ -0,0 +1,83 @@
+module PDFview
+
+ @files = Hash.new
+ @opencalls = Hash.new
+ @closecalls = Hash.new
+ @allcalls = Hash.new
+
+ # acrobat no longer is a valid default as (1) it keeps crashing with pdfopen due to a dual acrobat/reader install (a side effect
+ # of the api changing every version, and (2) because there are all these anyoing popups with respect to signed, review, online
+ # this and that stuff ... hardly useable as fast previewer, and (3) sumatra is faster and nicer and doesn't block (okay, we have to
+ # get rid of this horrible yellow bg-coloring buts that is doable
+
+ @method = 'sumatra' # 'default' # 'xpdf'
+
+ @opencalls['default'] = "pdfopen --file" # "pdfopen --back --file"
+ @opencalls['xpdf'] = "xpdfopen"
+ @opencalls['sumatra'] = 'start "test" sumatrapdf.exe -reuse-instance -bg-color 0xCCCCCC'
+
+ @closecalls['default'] = "pdfclose --file"
+ @closecalls['xpdf'] = nil
+ @closecalls['sumatra'] = nil
+
+ @allcalls['default'] = "pdfclose --all"
+ @allcalls['xpdf'] = nil
+ @allcalls['sumatra'] = nil
+
+ def PDFview.setmethod(method)
+ @method = method
+ end
+
+ def PDFview.open(*list)
+ begin
+ [*list].flatten.each do |file|
+ filename = fullname(file)
+ if FileTest.file?(filename) then
+ if @opencalls[@method] then
+ result = `#{@opencalls[@method]} #{filename} 2>&1`
+ @files[filename] = true
+ end
+ end
+ end
+ rescue
+ end
+ end
+
+ def PDFview.close(*list)
+ [*list].flatten.each do |file|
+ filename = fullname(file)
+ begin
+ if @files.key?(filename) then
+ if @closecalls[@method] then
+ result = `#{@closecalls[@method]} #{filename} 2>&1`
+ end
+ else
+ closeall
+ return
+ end
+ rescue
+ end
+ @files.delete(filename)
+ end
+ end
+
+ def PDFview.closeall
+ begin
+ if @allcalls[@method] then
+ result = `#{@allcalls[@method]} 2>&1`
+ end
+ rescue
+ end
+ @files.clear
+ end
+
+ def PDFview.fullname(name)
+ name + if name =~ /\.pdf$/ then '' else '.pdf' end
+ end
+
+end
+
+# PDFview.open("t:/document/show-exa.pdf")
+# PDFview.open("t:/document/show-gra.pdf")
+# PDFview.close("t:/document/show-exa.pdf")
+# PDFview.close("t:/document/show-gra.pdf")
diff --git a/Master/texmf-dist/scripts/context/ruby/base/state.rb b/Master/texmf-dist/scripts/context/ruby/base/state.rb
new file mode 100644
index 00000000000..76ef50b2563
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/state.rb
@@ -0,0 +1,75 @@
+require 'digest/md5'
+
+# todo: register omissions per file
+
+class FileState
+
+ def initialize
+ @states = Hash.new
+ @omiter = Hash.new
+ end
+
+ def reset
+ @states.clear
+ @omiter.clear
+ end
+
+ def register(filename,omit=nil)
+ unless @states.key?(filename) then
+ @states[filename] = Array.new
+ @omiter[filename] = omit
+ end
+ @states[filename] << checksum(filename,@omiter[filename])
+ end
+
+ def update(filename=nil)
+ [filename,@states.keys].flatten.compact.uniq.each do |fn|
+ register(fn)
+ end
+ end
+
+ def inspect(filename=nil)
+ result = ''
+ [filename,@states.keys].flatten.compact.uniq.sort.each do |fn|
+ if @states.key?(fn) then
+ result += "#{fn}: #{@states[fn].inspect}\n"
+ end
+ end
+ result
+ end
+
+ def changed?(filename)
+ if @states.key?(filename) then
+ n = @states[filename].length
+ if n>1 then
+ changed = @states[filename][n-1] != @states[filename][n-2]
+ else
+ changed = true
+ end
+ else
+ changed = true
+ end
+ return changed
+ end
+
+ def checksum(filename,omit=nil)
+ sum = ''
+ begin
+ if FileTest.file?(filename) && (data = IO.read(filename)) then
+ data.gsub!(/\n.*?(#{[omit].flatten.join('|')}).*?\n/) do "\n" end if omit
+ sum = Digest::MD5.hexdigest(data).upcase
+ end
+ rescue
+ sum = ''
+ end
+ return sum
+ end
+
+ def stable?
+ @states.keys.each do |s|
+ return false if changed?(s)
+ end
+ return true
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/switch.rb b/Master/texmf-dist/scripts/context/ruby/base/switch.rb
new file mode 100644
index 00000000000..73f53208281
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/switch.rb
@@ -0,0 +1,637 @@
+#encoding: ASCII-8BIT
+
+# module : base/switch
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# we cannot use getoptlong because we want to be more
+# tolerant; also we want to be case insensitive (2002).
+
+# we could make each option a class itself, but this is
+# simpler; also we can put more in the array
+
+# beware: regexps/o in methods are optimized globally
+
+require "rbconfig"
+
+$mswindows = RbConfig::CONFIG['host_os'] =~ /mswin/
+$separator = File::PATH_SEPARATOR
+
+class String
+
+ def has_suffix?(suffix)
+ self =~ /\.#{suffix}$/i
+ end
+
+end
+
+# may move to another module
+
+class File
+
+ @@update_eps = 1
+
+ def File.needsupdate(oldname,newname)
+ begin
+ oldtime = File.stat(oldname).mtime.to_i
+ newtime = File.stat(newname).mtime.to_i
+ if newtime >= oldtime then
+ return false
+ elsif oldtime-newtime < @@update_eps then
+ return false
+ else
+ return true
+ end
+ rescue
+ return true
+ end
+ end
+
+ def File.syncmtimes(oldname,newname)
+ return
+ begin
+ if $mswindows then
+ # does not work (yet) / gives future timestamp
+ # t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
+ # File.utime(0,t,oldname,newname)
+ else
+ t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
+ File.utime(0,t,oldname,newname)
+ end
+ rescue
+ end
+ end
+
+ def File.timestamp(name)
+ begin
+ "#{File.stat(name).mtime}"
+ rescue
+ return 'unknown'
+ end
+ end
+
+end
+
+# main thing
+
+module CommandBase
+
+ # this module can be used as a mixin in a command handler
+
+ $stdout.sync = true
+
+ def initialize(commandline,logger,banner)
+ @commandline, @logger, @banner = commandline, logger, banner
+ @forcenewline, @versiondone, @error = false, false, false
+ version if @commandline.option('version')
+ end
+
+ def reportlines(*str)
+ @logger.reportlines(str)
+ end
+
+ # only works in 1.8
+ #
+ # def report(*str)
+ # @logger.report(str)
+ # end
+ #
+ # def version # just a bit of playing with defs
+ # report(@banner.join(' - '))
+ # def report(*str)
+ # @logger.report
+ # @logger.report(str)
+ # def report(*str)
+ # @logger.report(str)
+ # end
+ # end
+ # def version
+ # end
+ # end
+
+ def report(*str)
+ initlogger ; @logger.report(str)
+ end
+
+ def seterror
+ @error = true
+ end
+
+ def error?
+ return @error
+ end
+
+ def exit
+ if @error then Kernel.exit(1) else Kernel.exit(0) end
+ end
+
+ def execute(str=nil)
+ send(str || action || 'main')
+ exit
+ end
+
+ def debug(*str)
+ initlogger ; @logger.debug(str)
+ end
+
+ def error(*str)
+ initlogger ; @logger.error(str)
+ end
+
+ def initlogger
+ if @forcenewline then
+ @logger.report
+ @forcenewline = false
+ end
+ end
+
+ def logger
+ @logger
+ end
+
+ def version # just a bit of playing with defs
+ unless @versiondone then
+ report(@banner.join(' - '))
+ @forcenewline = true
+ @versiondone = true
+ end
+ end
+
+ def help
+ version # is nilled when already given
+ @commandline.helpkeys.each do |k|
+ if @commandline.help?(k) then
+ kstr = ('--'+k).ljust(@commandline.helplength+2)
+ message = @commandline.helptext(k)
+ message = '' if message == CommandLine::NOHELP
+ message = message.split(/\s*\n\s*/)
+ loop do
+ report("#{kstr} #{message.shift}")
+ kstr = ' '*kstr.length
+ break if message.length == 0
+ end
+ end
+ end
+ end
+
+ def option(key)
+ @commandline.option(key)
+ end
+ def oneof(*key)
+ @commandline.oneof(*key)
+ end
+
+ def globfiles(pattern='*',suffix=nil)
+ @commandline.setarguments([pattern].flatten)
+ if files = findfiles(suffix) then
+ @commandline.setarguments(files)
+ else
+ @commandline.setarguments
+ end
+ end
+
+ private
+
+ def findfiles(suffix=nil)
+
+ if @commandline.arguments.length>1 then
+ return @commandline.arguments
+ else
+ pattern = @commandline.argument('first')
+ pattern = '*' if pattern.empty?
+ if suffix && ! pattern.match(/\..+$/o) then
+ suffix = '.' + suffix
+ pattern += suffix unless pattern =~ /#{suffix}$/
+ end
+ # not {} safe
+ pattern = '**/' + pattern if @commandline.option('recurse')
+ files = Dir[pattern]
+ if files && files.length>0 then
+ return files
+ else
+ pattern = @commandline.argument('first')
+ if FileTest.file?(pattern) then
+ return [pattern]
+ else
+ report("no files match pattern #{pattern}")
+ return nil
+ end
+ end
+ end
+
+ end
+
+ def globbed(pattern,recurse=false)
+
+ files = Array.new
+ pattern.split(' ').each do |p|
+ if recurse then
+ if p =~ /^(.*)(\/.*?)$/i then
+ p = $1 + '/**' + $2
+ else
+ p = '**/' + p
+ end
+ p.gsub!(/[\\\/]+/, '/')
+ end
+ files.push(Dir.glob(p))
+ end
+ files.flatten.sort do |a,b|
+ pathcompare(a,b)
+ end
+ end
+
+ def pathcompare(a,b)
+
+ aa, bb = a.split('/'), b.split('/')
+ if aa.length == bb.length then
+ aa.each_index do |i|
+ if aa[i]<bb[i] then
+ return -1
+ elsif aa[i]>bb[i] then
+ return +1
+ end
+ end
+ return 0
+ else
+ return aa.length <=> bb.length
+ end
+
+ end
+
+end
+
+class CommandLine
+
+ VALUE, FLAG = 1, 2
+ NOHELP = 'no arguments'
+
+ def initialize(prefix='-')
+
+ @registered = Array.new
+ @options = Hash.new
+ @unchecked = Hash.new
+ @arguments = Array.new
+ @original = ARGV.join(' ')
+ @helptext = Hash.new
+ @mandated = Hash.new
+ @provided = Hash.new
+ @prefix = prefix
+ @actions = Array.new
+
+ # The quotes in --switch="some value" get lost in ARGV, so we need to do some trickery here.
+
+ @original = ''
+ ARGV.each do |a|
+ aa = a.strip.gsub(/^([#{@prefix}]+\w+\=)([^\"].*?\s+.*[^\"])$/) do
+ $1 + "\"" + $2 + "\""
+ end
+ @original += if @original.empty? then '' else ' ' end + aa
+ end
+
+ end
+
+ def setarguments(args=[])
+ @arguments = if args then args else [] end
+ end
+
+ def register(option,shortcut,kind,default=false,action=false,helptext='')
+ if kind == FLAG then
+ @options[option] = default
+ elsif not default then
+ @options[option] = ''
+ else
+ @options[option] = default
+ end
+ @registered.push([option,shortcut,kind])
+ @mandated[option] = false
+ # @provided[option] = false
+ @helptext[option] = helptext
+ @actions.push(option) if action
+ end
+
+ def registerflag(option,default=false,helptext='')
+ if default.class == String then
+ register(option,'',FLAG,false,false,default)
+ else
+ register(option,'',FLAG,false,false,helptext)
+ end
+ end
+
+ def registervalue(option,default='',helptext='')
+ register(option,'',VALUE,default,false,helptext)
+ end
+
+ def registeraction(option,helptext='')
+ register(option,'',FLAG,false,true,helptext)
+ end
+
+ def registermandate(*option)
+ [*option].each do |o|
+ [o].each do |oo|
+ @mandated[oo] = true
+ end
+ end
+ end
+
+ def actions
+ a = @actions.delete_if do |t|
+ ! option(t)
+ end
+ if a && a.length>0 then
+ return a
+ else
+ return nil
+ end
+ end
+
+ def action
+ @actions.each do |t|
+ return t if option(t)
+ end
+ return nil
+ end
+
+ def forgotten
+ @mandated.keys.sort - @provided.keys.sort
+ end
+
+ def registerhelp(option,text='')
+ @helptext['unknown'] = if text.empty? then option else text end
+ end
+
+ def helpkeys(option='.*')
+ @helptext.keys.sort.grep(/#{option}/)
+ end
+
+ def helptext(option)
+ @helptext.fetch(option,'')
+ end
+
+ def help?(option)
+ @helptext[option] && ! @helptext[option].empty?
+ end
+
+ def helplength
+ n = 0
+ @helptext.keys.each do |h|
+ n = h.length if h.length>n
+ end
+ return n
+ end
+
+ def expand
+
+ # todo : '' or false, depending on type
+ # @options.clear
+ # @arguments.clear
+
+ dirtyvalue(@original).split(' ').each do |arg|
+ case arg
+ when /^[#{@prefix}][#{@prefix}](.+?)\=(.*?)$/ then locatedouble($1,$2)
+ when /^[#{@prefix}][#{@prefix}](.+?)$/ then locatedouble($1,false)
+ when /^[#{@prefix}](.)\=(.)$/ then locatesingle($1,$2)
+ when /^[#{@prefix}](.+?)$/ then locateseries($1,false)
+ when /^[\+\-]+/o then # do nothing
+ else
+ arguments.push(arg)
+ end
+ end
+
+ @options or @unchecked or @arguments
+
+ end
+
+ def extend (str)
+ @original = @original + ' ' + str
+ end
+
+ def replace (str)
+ @original = str
+ end
+
+ def show
+ # print "-- options --\n"
+ @options.keys.sort.each do |key|
+ print "option: #{key} -> #{@options[key]}\n"
+ end
+ # print "-- arguments --\n"
+ @arguments.each_index do |key|
+ print "argument: #{key} -> #{@arguments[key]}\n"
+ end
+ end
+
+ def option(str,default=nil)
+ if @options.key?(str) then
+ @options[str]
+ elsif default then
+ default
+ else
+ @options[str]
+ end
+ end
+
+ def checkedoption(str,default='')
+ if @options.key?(str) then
+ if @options[str].empty? then default else @options[str] end
+ else
+ default
+ end
+ end
+
+ def foundoption(str,default='')
+ str = str.split(',') if str.class == String
+ str.each do |s|
+ return str if @options.key?(str)
+ end
+ return default
+ end
+
+ def oneof(*key)
+ [*key].flatten.compact.each do |k|
+ return true if @options.key?(k) && @options[k]
+ end
+ return false
+ end
+
+ def setoption(str,value)
+ @options[str] = value
+ end
+
+ def getoption(str,value='') # value ?
+ @options[str]
+ end
+
+ def argument(n=0)
+ if n.class == String then
+ case n
+ when 'first' then argument(0)
+ when 'second' then argument(1)
+ when 'third' then argument(2)
+ else
+ argument(0)
+ end
+ elsif @arguments[n] then
+ @arguments[n]
+ else
+ ''
+ end
+ end
+
+ # a few local methods, cannot be defined nested (yet)
+
+ private
+
+ def dirtyvalue(value) # \xFF suddenly doesn't work any longer
+ if value then
+ value.gsub(/([\"\'])(.*?)\1/) do
+ $2.gsub(/\s+/o, "\0xFF")
+ end
+ else
+ ''
+ end
+ end
+
+ def cleanvalue(value) # \xFF suddenly doesn't work any longer
+ if value then
+ # value.sub(/^([\"\'])(.*?)\1$/) { $2.gsub(/\xFF/o, ' ') }
+ value.gsub(/\0xFF/o, ' ')
+ else
+ ''
+ end
+ end
+
+ def locatedouble(key, value)
+
+ foundkey, foundkind = nil, nil
+
+ @registered.each do |option, shortcut, kind|
+ if option == key then
+ foundkey, foundkind = option, kind
+ break
+ end
+ end
+ unless foundkey then
+ @registered.each do |option, shortcut, kind|
+ n = 0
+ begin
+ re = /^#{key}/i
+ rescue
+ key = key.inspect.sub(/^\"(.*)\"$/) do $1 end
+ re = /^#{key}/i
+ ensure
+ if option =~ re then
+ case n
+ when 0
+ foundkey, foundkind, n = option, kind, 1
+ when 1
+ # ambiguous matches, like --fix => --fixme --fixyou
+ foundkey, foundkind = nil, nil
+ break
+ end
+ end
+ end
+ end
+ end
+ if foundkey then
+ @provided[foundkey] = true
+ if foundkind == VALUE then
+ @options[foundkey] = cleanvalue(value)
+ else
+ @options[foundkey] = true
+ end
+ else
+ if value.class == FalseClass then
+ @unchecked[key] = true
+ else
+ @unchecked[key] = cleanvalue(value)
+ end
+ end
+
+ end
+
+ def locatesingle(key, value)
+
+ @registered.each do |option, shortcut, kind|
+ if shortcut == key then
+ @provided[option] = true
+ @options[option] = if kind == VALUE then '' else cleanvalue(value) end
+ break
+ end
+ end
+
+ end
+
+ def locateseries(series, value)
+
+ series.each_char do |key| # was .each but there is no alias to each_char any longer
+ locatesingle(key,cleanvalue(value))
+ end
+
+ end
+
+ public
+
+ attr_reader :arguments, :options, :original, :unchecked
+
+end
+
+# options = CommandLine.new
+#
+# options.register("filename", "f", CommandLine::VALUE)
+# options.register("request" , "r", CommandLine::VALUE)
+# options.register("verbose" , "v", CommandLine::FLAG)
+#
+# options.expand
+# options.extend(str)
+# options.show
+#
+# c = CommandLine.new
+#
+# c.registervalue('aaaa')
+# c.registervalue('test')
+# c.registervalue('zzzz')
+#
+# c.registerhelp('aaaa','some aaaa to enter')
+# c.registerhelp('test','some text to enter')
+# c.registerhelp('zzzz','some zzzz to enter')
+#
+# c.registermandate('test')
+#
+# c.expand
+#
+# class CommandLine
+#
+# def showhelp (banner,*str)
+# if helpkeys(*str).length>0
+# print banner
+# helpkeys(*str).each do |h|
+# print helptext(h) + "\n"
+# end
+# true
+# else
+# false
+# end
+# end
+#
+# def showmandate(banner)
+# if forgotten.length>0
+# print banner
+# forgotten.each do |f|
+# print helptext(f) + "\n"
+# end
+# true
+# else
+# false
+# end
+# end
+#
+# end
+#
+# c.showhelp("you can provide:\n\n")
+# c.showmandate("you also need to provide:\n\n")
diff --git a/Master/texmf-dist/scripts/context/ruby/base/system.rb b/Master/texmf-dist/scripts/context/ruby/base/system.rb
new file mode 100644
index 00000000000..71c0af421f9
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/system.rb
@@ -0,0 +1,121 @@
+# module : base/system
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+require "rbconfig"
+
+module System
+
+ @@mswindows = RbConfig::CONFIG['host_os'] =~ /mswin/
+ @@binpaths = ENV['PATH'].split(File::PATH_SEPARATOR)
+ @@binsuffixes = if $mswindows then ['.exe','.com','.bat'] else ['','.sh','.csh'] end
+ @@located = Hash.new
+ @@binnames = Hash.new
+
+ if @@mswindows then
+ @@binnames['ghostscript'] = ['gswin32c.exe','gs.cmd','gs.bat']
+ @@binnames['imagemagick'] = ['imagemagick.exe','convert.exe']
+ @@binnames['inkscape'] = ['inkscape.exe']
+ else
+ @@binnames['ghostscript'] = ['gs']
+ @@binnames['imagemagick'] = ['convert']
+ @@binnames['inkscape'] = ['inkscape']
+ end
+
+
+ def System.null
+ if @@mswindows then 'nul' else '/dev/null' end
+ end
+
+ def System.unix?
+ not @@mswindows
+ end
+ def System.mswin?
+ @@mswindows
+ end
+
+ def System.binnames(str)
+ if @@binnames.key?(str) then
+ @@binnames[str]
+ else
+ [str]
+ end
+ end
+
+ def System.prependengine(str)
+ if str =~ /^\S+\.(pl|rb|lua|py)/io then
+ case $1
+ when 'pl' then return "perl #{str}"
+ when 'rb' then return "ruby #{str}"
+ when 'lua' then return "lua #{str}"
+ when 'py' then return "python #{str}"
+ end
+ end
+ return str
+ end
+
+ def System.locatedprogram(program)
+ if @@located.key?(program) then
+ return @@located[program]
+ else
+ System.binnames(program).each do |binname|
+ if binname =~ /\..*$/io then
+ @@binpaths.each do |path|
+ if FileTest.file?(str = File.join(path,binname)) then
+ return @@located[program] = System.prependengine(str)
+ end
+ end
+ end
+ binname.gsub!(/\..*$/io, '')
+ @@binpaths.each do |path|
+ @@binsuffixes.each do |suffix|
+ if FileTest.file?(str = File.join(path,"#{binname}#{suffix}")) then
+ return @@located[program] = System.prependengine(str)
+ end
+ end
+ end
+ end
+ end
+ return @@located[program] = "texmfstart #{program}"
+ end
+
+ def System.command(program,arguments='')
+ if program =~ /^(.*?) (.*)$/ then
+ program = System.locatedprogram($1) + ' ' + $2
+ else
+ program = System.locatedprogram(program)
+ end
+ program = program + ' ' + arguments if ! arguments.empty?
+ program.gsub!(/\s+/io, ' ')
+ #program.gsub!(/(\/\.\/)+/io, '/')
+ program.gsub!(/\\/io, '/')
+ return program
+ end
+
+ def System.run(program,arguments='',pipe=false,collect=false)
+ if pipe then
+ if collect then
+ `#{System.command(program,arguments)} 2>&1`
+ else
+ `#{System.command(program,arguments)}`
+ end
+ else
+ system(System.command(program,arguments))
+ end
+ end
+
+ def System.pipe(program,arguments='',collect=false)
+ System.run(program,arguments,true)
+ end
+
+ def System.safepath(path)
+ if path.match(/ /o) then "\"#{path}\"" else path end
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/tex.rb b/Master/texmf-dist/scripts/context/ruby/base/tex.rb
new file mode 100644
index 00000000000..9a520f3131f
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/tex.rb
@@ -0,0 +1,2182 @@
+#encoding: ASCII-8BIT
+
+# module : base/tex
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# todo:
+#
+# - write systemcall for mpost to file so that it can be run faster
+# - use -8bit and -progname
+#
+
+# report ?
+
+require 'fileutils'
+
+require 'base/variables'
+require 'base/kpse'
+require 'base/system'
+require 'base/state'
+require 'base/pdf'
+require 'base/file'
+require 'base/ctx'
+require 'base/mp'
+
+class String
+
+ def standard?
+ begin
+ self == 'standard'
+ rescue
+ false
+ end
+ end
+
+end
+
+# class String
+ # def utf_bom?
+ # self.match(/^\357\273\277/o).length>0 rescue false
+ # end
+# end
+
+class Array
+
+ def standard?
+ begin
+ self.include?('standard')
+ rescue
+ false
+ end
+ end
+
+ def join_path
+ self.join(File::PATH_SEPARATOR)
+ end
+
+end
+
+class TEX
+
+ # The make-part of this class was made on a rainy day while listening
+ # to "10.000 clowns on a rainy day" by Jan Akkerman. Unfortunately the
+ # make method is not as swinging as this live cd.
+
+ include Variables
+
+ @@texengines = Hash.new
+ @@mpsengines = Hash.new
+ @@backends = Hash.new
+ @@mappaths = Hash.new
+ @@runoptions = Hash.new
+ @@draftoptions = Hash.new
+ @@synctexcoptions = Hash.new
+ @@texformats = Hash.new
+ @@mpsformats = Hash.new
+ @@prognames = Hash.new
+ @@texmakestr = Hash.new
+ @@texprocstr = Hash.new
+ @@mpsmakestr = Hash.new
+ @@mpsprocstr = Hash.new
+ @@texmethods = Hash.new
+ @@mpsmethods = Hash.new
+ @@pdftex = 'pdftex'
+
+ @@platformslash = if System.unix? then "\\\\" else "\\" end
+
+ ['tex','etex','pdftex','standard'] .each do |e| @@texengines[e] = 'pdftex' end
+ ['aleph','omega'] .each do |e| @@texengines[e] = 'aleph' end
+ ['xetex'] .each do |e| @@texengines[e] = 'xetex' end
+ ['petex'] .each do |e| @@texengines[e] = 'petex' end
+
+ ['metapost','mpost', 'standard'] .each do |e| @@mpsengines[e] = 'mpost' end
+
+ ['pdftex','pdf','pdftex','standard'] .each do |b| @@backends[b] = 'pdftex' end
+ ['dvipdfmx','dvipdfm','dpx','dpm'] .each do |b| @@backends[b] = 'dvipdfmx' end
+ ['xetex','xtx'] .each do |b| @@backends[b] = 'xetex' end
+ ['petex'] .each do |b| @@backends[b] = 'dvipdfmx' end
+ ['aleph'] .each do |b| @@backends[b] = 'dvipdfmx' end
+ ['dvips','ps','dvi'] .each do |b| @@backends[b] = 'dvips' end
+ ['dvipsone'] .each do |b| @@backends[b] = 'dvipsone' end
+ ['acrobat','adobe','distiller'] .each do |b| @@backends[b] = 'acrobat' end
+ ['xdv','xdv2pdf'] .each do |b| @@backends[b] = 'xdv2pdf' end
+
+ ['tex','standard'] .each do |b| @@mappaths[b] = 'dvips' end
+ ['pdftex'] .each do |b| @@mappaths[b] = 'pdftex' end
+ ['aleph','omega','xetex','petex'] .each do |b| @@mappaths[b] = 'dvipdfmx' end
+ ['dvipdfm', 'dvipdfmx', 'xdvipdfmx'] .each do |b| @@mappaths[b] = 'dvipdfmx' end
+ ['xdv','xdv2pdf'] .each do |b| @@mappaths[b] = 'dvips' end
+
+ # todo norwegian (no)
+
+ ['plain'] .each do |f| @@texformats[f] = 'plain' end
+ ['cont-en','en','english','context','standard'].each do |f| @@texformats[f] = 'cont-en.mkii' end
+ ['cont-nl','nl','dutch'] .each do |f| @@texformats[f] = 'cont-nl.mkii' end
+ ['cont-de','de','german'] .each do |f| @@texformats[f] = 'cont-de.mkii' end
+ ['cont-it','it','italian'] .each do |f| @@texformats[f] = 'cont-it.mkii' end
+ ['cont-fr','fr','french'] .each do |f| @@texformats[f] = 'cont-fr.mkii' end
+ ['cont-cs','cs','cont-cz','cz','czech'] .each do |f| @@texformats[f] = 'cont-cs.mkii' end
+ ['cont-ro','ro','romanian'] .each do |f| @@texformats[f] = 'cont-ro.mkii' end
+ ['cont-gb','gb','cont-uk','uk','british'] .each do |f| @@texformats[f] = 'cont-gb.mkii' end
+ ['mptopdf'] .each do |f| @@texformats[f] = 'mptopdf' end
+
+ ['latex'] .each do |f| @@texformats[f] = 'latex.ltx' end
+
+ ['plain','mpost'] .each do |f| @@mpsformats[f] = 'mpost' end
+ ['metafun','context','standard'] .each do |f| @@mpsformats[f] = 'metafun' end
+
+ ['pdftex','aleph','omega','petex','xetex'] .each do |p| @@prognames[p] = 'context' end
+ ['mpost'] .each do |p| @@prognames[p] = 'metafun' end
+ ['latex','pdflatex'] .each do |p| @@prognames[p] = 'latex' end
+
+ ['plain','default','standard','mptopdf'] .each do |f| @@texmethods[f] = 'plain' end
+ ['cont-en','cont-en.mkii',
+ 'cont-nl','cont-nl.mkii',
+ 'cont-de','cont-de.mkii',
+ 'cont-it','cont-it.mkii',
+ 'cont-fr','cont-fr.mkii',
+ 'cont-cs','cont-cs.mkii',
+ 'cont-ro','cont-ro.mkii',
+ 'cont-gb','cont-gb.mkii'] .each do |f| @@texmethods[f] = 'context' end
+ ['latex','latex.ltx','pdflatex'] .each do |f| @@texmethods[f] = 'latex' end # untested
+
+ ['plain','default','standard'] .each do |f| @@mpsmethods[f] = 'plain' end
+ ['metafun'] .each do |f| @@mpsmethods[f] = 'metafun' end
+
+ @@texmakestr['plain'] = @@platformslash + "dump"
+ @@mpsmakestr['plain'] = @@platformslash + "dump"
+
+ ['cont-en','cont-nl','cont-de','cont-it',
+ 'cont-fr','cont-cs','cont-ro','cont-gb',
+ 'cont-pe','cont-xp'] .each do |f| @@texprocstr[f] = @@platformslash + "emergencyend" end
+
+ @@runoptions['aleph'] = ['--8bit']
+ @@runoptions['mpost'] = ['--8bit']
+ @@runoptions['pdftex'] = ['--8bit']
+ # @@runoptions['petex'] = []
+ @@runoptions['xetex'] = ['--8bit','-output-driver="xdvipdfmx -E -d 4 -V 5"']
+ @@draftoptions['pdftex'] = ['--draftmode']
+ @@synctexcoptions['pdftex'] = ['--synctex=1']
+ @@synctexcoptions['xetex'] = ['--synctex=1']
+
+ @@mainbooleanvars = [
+ 'batchmode', 'nonstopmode', 'fast', 'final',
+ 'paranoid', 'notparanoid', 'nobanner', 'once', 'allpatterns', 'draft',
+ 'nompmode', 'nomprun', 'automprun', 'combine',
+ 'nomapfiles', 'local',
+ 'arrange', 'noarrange',
+ 'forcexml', 'foxet',
+ 'alpha', 'beta',
+ 'mpyforce', 'forcempy',
+ 'forcetexutil', 'texutil',
+ 'globalfile', 'autopath',
+ 'purge', 'purgeall', 'keep', 'autopdf', 'xpdf', 'simplerun', 'verbose',
+ 'nooptionfile', 'nobackend', 'noctx', 'utfbom',
+ 'mkii','mkiv',
+ 'synctex',
+ ]
+ @@mainstringvars = [
+ 'modefile', 'result', 'suffix', 'response', 'path',
+ 'filters', 'usemodules', 'environments', 'separation', 'setuppath',
+ 'arguments', 'input', 'output', 'randomseed', 'modes', 'mode', 'filename',
+ 'ctxfile', 'printformat', 'paperformat', 'paperoffset',
+ 'timeout', 'passon', 'pdftitle'
+ ]
+ @@mainstandardvars = [
+ 'mainlanguage', 'bodyfont', 'language'
+ ]
+ @@mainknownvars = [
+ 'engine', 'distribution', 'texformats', 'mpsformats', 'progname', 'interface',
+ 'runs', 'backend'
+ ]
+
+ @@extrabooleanvars = []
+ @@extrastringvars = []
+
+ def booleanvars
+ [@@mainbooleanvars,@@extrabooleanvars].flatten.uniq
+ end
+ def stringvars
+ [@@mainstringvars,@@extrastringvars].flatten.uniq
+ end
+ def standardvars
+ [@@mainstandardvars].flatten.uniq
+ end
+ def knownvars
+ [@@mainknownvars].flatten.uniq
+ end
+ def allbooleanvars
+ [@@mainbooleanvars,@@extrabooleanvars].flatten.uniq
+ end
+ def allstringvars
+ [@@mainstringvars,@@extrastringvars,@@mainstandardvars,@@mainknownvars].flatten.uniq
+ end
+
+ def setextrastringvars(vars)
+ # @@extrastringvars << vars -- problems in 1.9
+ @@extrastringvars = [@@extrastringvars,vars].flatten
+ end
+ def setextrabooleanvars(vars)
+ # @@extrabooleanvars << vars -- problems in 1.9
+ @@extrabooleanvars = [@@extrabooleanvars,vars].flatten
+ end
+
+ # def jobvariables(names=nil)
+ # if [names ||[]].flatten.size == 0 then
+ # names = [allbooleanvars,allstringvars].flatten
+ # end
+ # data = Hash.new
+ # names.each do |name|
+ # if allbooleanvars.include?(name) then
+ # data[name] = if getvariable(name) then "yes" else "no" end
+ # else
+ # data[name] = getvariable(name)
+ # end
+ # end
+ # data
+ # end
+
+ # def setjobvariables(names=nil)
+ # assignments = Array.new
+ # jobvariables(names).each do |k,v|
+ # assignments << "#{k}=\{#{v}\}"
+ # end
+ # "\setvariables[exe][#{assignments.join(", ")}]"
+ # end
+
+ @@temprunfile = 'texexec'
+ @@temptexfile = 'texexec.tex'
+
+ def initialize(logger=nil)
+ if @logger = logger then
+ def report(str='')
+ @logger.report(str)
+ end
+ else
+ def report(str='')
+ puts(str)
+ end
+ end
+ @cleanups = Array.new
+ @variables = Hash.new
+ @startuptime = Time.now
+ # options
+ booleanvars.each do |k|
+ setvariable(k,false)
+ end
+ stringvars.each do |k|
+ setvariable(k,'')
+ end
+ standardvars.each do |k|
+ setvariable(k,'standard')
+ end
+ setvariable('distribution', Kpse.distribution)
+ setvariable('texformats', defaulttexformats)
+ setvariable('mpsformats', defaultmpsformats)
+ setvariable('progname', 'standard') # or ''
+ setvariable('interface', 'standard')
+ setvariable('engine', 'standard') # replaced by tex/mpsengine
+ setvariable('backend', 'pdftex')
+ setvariable('runs', '8')
+ setvariable('randomseed', rand(1440).to_s) # we want the same seed for one run
+ # files
+ setvariable('files', [])
+ # defaults
+ setvariable('texengine', 'standard')
+ setvariable('mpsengine', 'standard')
+ setvariable('backend', 'standard')
+ setvariable('error', '')
+ end
+
+ def error?
+ not getvariable('error').empty?
+ end
+
+ def runtime
+ Time.now - @startuptime
+ end
+
+ def reportruntime
+ report("runtime: #{runtime}")
+ end
+
+ def runcommand(something)
+ command = [something].flatten.join(' ')
+ report("running: #{command}") if getvariable('verbose')
+ system(command)
+ end
+
+ def inspect(name=nil)
+ if ! name || name.empty? then
+ name = [booleanvars,stringvars,standardvars,knownvars]
+ end
+ str = '' # allocate
+ [name].flatten.each do |n|
+ if str = getvariable(n) then
+ str = str.join(" ") if str.class == Array
+ unless (str.class == String) && str.empty? then
+ report("option '#{n}' is set to '#{str}'")
+ end
+ end
+ end
+ end
+
+ def tempfilename(suffix='')
+ @@temprunfile + if suffix.empty? then '' else ".#{suffix}" end
+ end
+
+ def cleanup
+ @cleanups.each do |name|
+ begin
+ File.delete(name) if FileTest.file?(name)
+ rescue
+ report("unable to delete #{name}")
+ end
+ end
+ end
+
+ def cleanuptemprunfiles
+ begin
+ Dir.glob("#{@@temprunfile}*").each do |name|
+ if File.file?(name) && (File.splitname(name)[1] !~ /(pdf|dvi)/o) then
+ File.delete(name) rescue false
+ end
+ end
+ rescue
+ end
+ # ['mpgraph.mp'].each do |file|
+ # (File.delete(file) if (FileTest.size?(file) rescue 10) < 10) rescue false
+ # end
+ end
+
+ def backends() @@backends.keys.sort end
+
+ def texengines() @@texengines.keys.sort end
+ def mpsengines() @@mpsengines.keys.sort end
+ def texformats() @@texformats.keys.sort end
+ def mpsformats() @@mpsformats.keys.sort end
+
+ def defaulttexformats() ['en','nl','mptopdf'] end
+ def defaultmpsformats() ['metafun'] end # no longer formats
+
+ def texmakeextras(format) @@texmakestr[format] || '' end
+ def mpsmakeextras(format) @@mpsmakestr[format] || '' end
+ def texprocextras(format) @@texprocstr[format] || '' end
+ def mpsprocextras(format) @@mpsprocstr[format] || '' end
+
+ def texmethod(format) @@texmethods[str] || @@texmethods['standard'] end
+ def mpsmethod(format) @@mpsmethods[str] || @@mpsmethods['standard'] end
+
+ def runoptions(engine)
+ options = if getvariable('draft') then @@draftoptions[engine] else [] end
+ options = if getvariable('synctex') then @@synctexcoptions[engine] else [] end
+ begin
+ if str = getvariable('passon') then
+ options = [options,str.split(' ')].flatten
+ end
+ rescue
+ end
+ if @@runoptions.key?(engine) then
+ [options,@@runoptions[engine]].flatten.join(' ')
+ else
+ options.join(' ')
+ end
+ end
+
+ # private
+
+ def cleanuplater(name)
+ begin
+ @cleanups.push(File.expand_path(name))
+ rescue
+ @cleanups.push(name)
+ end
+ end
+
+ def openedfile(name)
+ begin
+ f = File.open(name,'w')
+ rescue
+ report("file '#{File.expand_path(name)}' cannot be opened for writing")
+ return nil
+ else
+ cleanuplater(name) if f
+ return f
+ end
+ end
+
+ def prefixed(format,engine)
+ # format
+ case engine
+ when /etex|pdftex|aleph|xetex/io then
+ "*#{format}"
+ else
+ format
+ end
+ end
+
+ def quoted(str)
+ if str =~ /^[^\"].* / then "\"#{str}\"" else str end
+ end
+
+ def getarrayvariable(str='')
+ str = getvariable(str)
+ if str.class == String then str.split(',') else str.flatten end
+ end
+
+ def validsomething(str,something,type=nil)
+ if str then
+ list = [str].flatten.collect do |s|
+ if something[s] then
+ something[s]
+ elsif type && s =~ /\.#{type}$/ then
+ s
+ else
+ nil
+ end
+ end .compact.uniq
+ if list.length>0 then
+ if str.class == String then list.first else list end
+ else
+ false
+ end
+ else
+ false
+ end
+ end
+
+ def validtexformat(str) validsomething(str,@@texformats,'tex') ||
+ validsomething(str,@@texformats,'mkii') end
+ def validmpsformat(str) validsomething(str,@@mpsformats,'mp' ) end
+ def validtexengine(str) validsomething(str,@@texengines,'pdftex') end
+ def validmpsengine(str) validsomething(str,@@mpsengines,'mpost' ) end
+
+ def validtexmethod(str) [validsomething(str,@@texmethods)].flatten.first end
+ def validmpsmethod(str) [validsomething(str,@@mpsmethods)].flatten.first end
+
+ def validbackend(str)
+ if str && @@backends.key?(str) then
+ @@backends[str]
+ else
+ @@backends['standard']
+ end
+ end
+
+ def validprogname(str)
+ if str then
+ [str].flatten.each do |s|
+ s = s.sub(/\.\S*/,"")
+ return @@prognames[s] if @@prognames.key?(s)
+ end
+ return str[0].sub(/\.\S*/,"")
+ else
+ return nil
+ end
+ end
+
+ # we no longer support the & syntax
+
+ def formatflag(engine=nil,format=nil)
+ case getvariable('distribution')
+ when 'standard' then prefix = "--fmt"
+ when /web2c/io then prefix = web2cformatflag(engine)
+ when /miktex/io then prefix = "--undump"
+ else return ""
+ end
+ if format then
+ "#{prefix}=#{format.sub(/\.\S+$/,"")}"
+ else
+ prefix
+ end
+ end
+
+ def web2cformatflag(engine=nil)
+ # funny that we've standardized on the fmt suffix (at the cost of
+ # upward compatibility problems) but stuck to the bas/mem/fmt flags
+ if engine then
+ case validmpsengine(engine)
+ when /mpost/ then "-mem"
+ when /mfont/ then "-bas"
+ else "-fmt"
+ end
+ else
+ "-fmt"
+ end
+ end
+
+ def prognameflag(progname=nil)
+ case getvariable('distribution')
+ when 'standard' then prefix = "-progname"
+ when /web2c/io then prefix = "-progname"
+ when /miktex/io then prefix = "-alias"
+ else return ""
+ end
+ if progname and not progname.empty? then
+ "#{prefix}=#{progname}"
+ else
+ prefix
+ end
+ end
+
+ def iniflag() # should go to kpse and kpse should become texenv
+ if Kpse.miktex? then
+ "-initialize"
+ else
+ "--ini"
+ end
+ end
+
+ # # obsolete
+ #
+ # def tcxflag(engine)
+ # if @@tcxflag[engine] then
+ # file = "natural.tcx"
+ # if Kpse.miktex? then
+ # "-tcx=#{file}"
+ # else
+ # "-translate-file=#{file}"
+ # end
+ # else
+ # ""
+ # end
+ # end
+
+ def filestate(file)
+ File.mtime(file).strftime("%d/%m/%Y %H:%M:%S")
+ end
+
+ # will go to context/process context/listing etc
+
+ def contextversion # ook elders gebruiken
+ filename = Kpse.found('context.mkii')
+ version = 'unknown'
+ begin
+ if FileTest.file?(filename) && IO.read(filename).match(/\\contextversion\{(\d+\.\d+\.\d+.*?)\}/) then
+ version = $1
+ end
+ rescue
+ end
+ return version
+ end
+
+ # we need engine methods
+
+ def makeformats
+
+ checktestversion
+
+ report("using search method '#{Kpse.searchmethod}'")
+ if getvariable('fast') then
+ report('using existing database')
+ else
+ report('updating file database')
+ Kpse.update # obsolete here
+ end
+ # goody
+ if getvariable('texformats') == 'standard' then
+ setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty?
+ end
+ # prepare
+ texformats = validtexformat(getarrayvariable('texformats'))
+ mpsformats = validmpsformat(getarrayvariable('mpsformats'))
+ texengine = validtexengine(getvariable('texengine'))
+ mpsengine = validmpsengine(getvariable('mpsengine'))
+ # save current path
+ savedpath = Dir.getwd
+ # generate tex formats
+ unless texformats || mpsformats then
+ report('provide valid format (name.tex, name.mp, ...) or format id (metafun, en, nl, ...)')
+ setvariable('error','no format specified')
+ end
+ if texformats && texengine then
+ report("using tex engine #{texengine}")
+ texformatpath = if getvariable('local') then '.' else Kpse.formatpath(texengine,true) end
+ # can be empty, to do
+ report("using tex format path #{texformatpath}")
+ Dir.chdir(texformatpath) rescue false
+ if FileTest.writable?(texformatpath) then
+ # from now on we no longer support this; we load
+ # all patterns and if someone wants another
+ # interface language ... cook up a fmt or usr file
+ #
+ # if texformats.length > 0 then
+ # makeuserfile
+ # makeresponsefile
+ # end
+ texformats.each do |texformat|
+ report("generating tex format #{texformat}")
+ progname = validprogname([getvariable('progname'),texformat,texengine])
+ runcommand([quoted(texengine),prognameflag(progname),iniflag,prefixed(texformat,texengine),texmakeextras(texformat)])
+ end
+ else
+ report("unable to make format due to lack of permissions")
+ texformatpath = ''
+ setvariable('error','no permissions to write')
+ end
+ if not mpsformats then
+ # we want metafun to be in sync
+ setvariable('mpsformats',defaultmpsformats)
+ mpsformats = validmpsformat(getarrayvariable('mpsformats'))
+ end
+ else
+ texformatpath = ''
+ end
+ # generate mps formats
+ # if mpsformats && mpsengine then
+ # report("using mp engine #{mpsengine}")
+ # mpsformatpath = if getvariable('local') then '.' else Kpse.formatpath(mpsengine,false) end
+ # report("using mps format path #{mpsformatpath}")
+ # Dir.chdir(mpsformatpath) rescue false
+ # if FileTest.writable?(mpsformatpath) then
+ # mpsformats.each do |mpsformat|
+ # report("generating mps format #{mpsformat}")
+ # progname = validprogname([getvariable('progname'),mpsformat,mpsengine])
+ # if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then
+ # setvariable('error','no format made')
+ # end
+ # end
+ # else
+ # report("unable to make format due to lack of permissions")
+ # mpsformatpath = ''
+ # setvariable('error','file permission problem')
+ # end
+ # else
+ # mpsformatpath = ''
+ # end
+ # check for problems
+ report("")
+ report("tex engine path: #{texformatpath}") unless texformatpath.empty?
+ # report("mps engine path: #{mpsformatpath}") unless mpsformatpath.empty?
+ report("")
+ # [['fmt','tex'],['mem','mps']].each do |f|
+ # [[texformatpath,'global'],[mpsformatpath,'global'],[savedpath,'current']].each do |p|
+ [['fmt','tex']].each do |f|
+ [[texformatpath,'global'],[savedpath,'current']].each do |p|
+ begin
+ Dir.chdir(p[0])
+ rescue
+ else
+ Dir.glob("*.#{f[0]}").each do |file|
+ report("#{f[1]}: #{filestate(file)} > #{File.expand_path(file)} (#{File.size(file)})")
+ end
+ end
+ end
+ end
+ # to be sure, go back to current path
+ begin
+ Dir.chdir(savedpath)
+ rescue
+ end
+ # finalize
+ cleanup
+ report("")
+ reportruntime
+ end
+
+ def checkcontext
+
+ # todo : report texmf.cnf en problems
+
+ # basics
+ report("current distribution: #{Kpse.distribution}")
+ report("context source date: #{contextversion}")
+ formatpaths = Kpse.formatpaths
+ globpattern = "**/{#{formatpaths.join(',')}}/*/*.{fmt,efmt,ofmt,xfmt,mem}"
+ report("format path: #{formatpaths.join(' ')}")
+ # utilities
+ report('start of analysis')
+ results = Array.new
+ # ['texexec','texutil','ctxtools'].each do |program|
+ ['texexec'].each do |program|
+ result = `texmfstart #{program} --help`
+ result.sub!(/.*?(#{program}[^\n]+)\n.*/mi) do $1 end
+ results.push("#{result}")
+ end
+ # formats
+ cleanuptemprunfiles
+ if formats = Dir.glob(globpattern) then
+ formats.sort.each do |name|
+ cleanuptemprunfiles
+ if f = open(tempfilename('tex'),'w') then
+ # kind of aleph-run-out-of-par safe
+ f << "\\starttext\n"
+ f << " \\relax test \\relax\n"
+ f << "\\stoptext\n"
+ f << "\\endinput\n"
+ f.close
+ if FileTest.file?(tempfilename('tex')) then
+ format = File.basename(name)
+ engine = if name =~ /(pdftex|aleph|xetex)[\/\\]#{format}/ then $1 else '' end
+ if engine.empty? then
+ engineflag = ""
+ else
+ engineflag = "--engine=#{$1}"
+ end
+ case format
+ when /cont\-([a-z]+)/ then
+ interface = $1.sub(/cont\-/,'')
+ results.push('')
+ results.push("testing interface #{interface}")
+ flags = ['--noctx','--process','--batch','--once',"--interface=#{interface}",engineflag]
+ # result = Kpse.pipescript('texexec',tempfilename,flags)
+ result = runtexexec([tempfilename], flags, 1)
+ if FileTest.file?("#{@@temprunfile}.log") then
+ logdata = IO.read("#{@@temprunfile}.log")
+ if logdata =~ /^\s*This is (.*?)[\s\,]+(.*?)$/moi then
+ if validtexengine($1.downcase) then
+ results.push("#{$1} #{$2.gsub(/\(format.*$/,'')}".strip)
+ end
+ end
+ if logdata =~ /^\s*(ConTeXt)\s+(.*int:\s+[a-z]+.*?)\s*$/moi then
+ results.push("#{$1} #{$2}".gsub(/\s+/,' ').strip)
+ end
+ else
+ results.push("format #{format} does not work")
+ end
+ when /metafun/ then
+ # todo
+ when /mptopdf/ then
+ # todo
+ end
+ else
+ results.push("error in creating #{tempfilename('tex')}")
+ end
+ end
+ cleanuptemprunfiles
+ end
+ end
+ report('end of analysis')
+ report
+ results.each do |line|
+ report(line)
+ end
+ cleanuptemprunfiles
+
+ end
+
+ private
+
+ def makeuserfile
+ language = getvariable('language')
+ mainlanguage = getvariable('mainlanguage')
+ bodyfont = getvariable('bodyfont')
+ if f = openedfile("cont-fmt.tex") then
+ f << "\\unprotect\n"
+ case language
+ when 'all' then
+ f << "\\preloadallpatterns\n"
+ when '' then
+ f << "% no language presets\n"
+ when 'standard'
+ f << "% using defaults\n"
+ else
+ languages = language.split(',')
+ languages.each do |l|
+ f << "\\installlanguage[\\s!#{l}][\\c!state=\\v!start]\n"
+ end
+ mainlanguage = languages.first
+ end
+ unless mainlanguage == 'standard' then
+ f << "\\setupcurrentlanguage[\\s!#{mainlanguage}]\n";
+ end
+ unless bodyfont == 'standard' then
+ # ~ will become obsolete when lmr is used
+ f << "\\definetypescriptsynonym[cmr][#{bodyfont}]"
+ # ~ is already obsolete for some years now
+ f << "\\definefilesynonym[font-cmr][font-#{bodyfont}]\n"
+ end
+ f << "\\protect\n"
+ f << "\\endinput\n"
+ f.close
+ end
+ end
+
+ def makeresponsefile
+ interface = getvariable('interface')
+ if f = openedfile("mult-def.tex") then
+ case interface
+ when 'standard' then
+ f << "% using default response interface"
+ else
+ f << "\\def\\currentresponses\{#{interface}\}\n"
+ end
+ f << "\\endinput\n"
+ f.close
+ end
+ end
+
+ private # will become base/context
+
+ @@preamblekeys = [
+ ['tex','texengine'],
+ ['engine','texengine'],
+ ['program','texengine'],
+ # ['translate','tcxfilter'],
+ # ['tcx','tcxfilter'],
+ ['output','backend'],
+ ['mode','mode'],
+ ['ctx','ctxfile'],
+ ['version','contextversion'],
+ ['format','texformats'],
+ ['interface','texformats'],
+ ]
+
+ @@re_utf_bom = /^\357\273\277/o
+
+ def scantexpreamble(filename)
+ begin
+ if FileTest.file?(filename) and tex = File.open(filename,'rb') then
+ bomdone = false
+ while str = tex.gets and str.chomp! do
+ unless bomdone then
+ if str.sub!(@@re_utf_bom, '')
+ report("utf mode forced (bom found)")
+ setvariable('utfbom',true)
+ end
+ bomdone = true
+ end
+ if str =~ /^\%\s*(.*)/o then
+ # we only accept lines with key=value pairs
+ vars, ok = Hash.new, true
+ $1.split(/\s+/o).each do |s|
+ k, v = s.split('=')
+ if k && v then
+ vars[k] = v
+ else
+ ok = false
+ break
+ end
+ end
+ if ok then
+ # we have a valid line
+
+ @@preamblekeys.each do |v|
+ setvariable(v[1],vars[v[0]]) if vars.key?(v[0]) && vars[v[0]]
+ end
+
+if getvariable('given.backend') == "standard" or getvariable('given.backend') == "" then
+ setvariable('backend',@@backends[getvariable('texengine')] || 'standard')
+end
+ break
+ end
+ else
+ break
+ end
+ end
+ tex.close
+ end
+ rescue
+ # well, let's not worry too much
+ end
+ end
+
+ def scantexcontent(filename)
+ if FileTest.file?(filename) and tex = File.open(filename,'rb') then
+ while str = tex.gets do
+ case str.chomp
+ when /^\%/o then
+ # next
+ # when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then
+ when /\\(starttekst|stoptekst|startonderdeel|startoverzicht)/o then
+ setvariable('texformats','nl') ; break
+ when /\\(stelle|verwende|umgebung|benutze)/o then
+ setvariable('texformats','de') ; break
+ when /\\(stel|gebruik|omgeving)/o then
+ setvariable('texformats','nl') ; break
+ when /\\(use|setup|environment)/o then
+ setvariable('texformats','en') ; break
+ when /\\(usa|imposta|ambiente)/o then
+ setvariable('texformats','it') ; break
+ when /(height|width|style)=/o then
+ setvariable('texformats','en') ; break
+ when /(hoehe|breite|schrift)=/o then
+ setvariable('texformats','de') ; break
+ when /(hoogte|breedte|letter)=/o then
+ setvariable('texformats','nl') ; break
+ when /(altezza|ampiezza|stile)=/o then
+ setvariable('texformats','it') ; break
+ when /externfiguur/o then
+ setvariable('texformats','nl') ; break
+ when /externalfigure/o then
+ setvariable('texformats','en') ; break
+ when /externeabbildung/o then
+ setvariable('texformats','de') ; break
+ when /figuraesterna/o then
+ setvariable('texformats','it') ; break
+ end
+ end
+ tex.close
+ end
+
+ end
+
+ private # will become base/context
+
+ def pushresult(filename,resultname)
+ fname = File.unsuffixed(filename)
+ rname = File.unsuffixed(resultname)
+ if ! rname.empty? && (rname != fname) then
+ report("outputfile #{rname}")
+ ['tuo','tuc','log','dvi','pdf'].each do |s|
+ File.silentrename(File.suffixed(fname,s),File.suffixed('texexec',s))
+ end
+ ['tuo','tuc'].each do |s|
+ File.silentrename(File.suffixed(rname,s),File.suffixed(fname,s)) if FileTest.file?(File.suffixed(rname,s))
+ end
+ end
+ end
+
+ def popresult(filename,resultname)
+ fname = File.unsuffixed(filename)
+ rname = File.unsuffixed(resultname)
+ if ! rname.empty? && (rname != fname) then
+ report("renaming #{fname} to #{rname}")
+ ['tuo','tuc','log','dvi','pdf'].each do |s|
+ File.silentrename(File.suffixed(fname,s),File.suffixed(rname,s))
+ end
+ report("restoring #{fname}")
+ unless $fname == 'texexec' then
+ ['tuo','tuc','log','dvi','pdf'].each do |s|
+ File.silentrename(File.suffixed('texexec',s),File.suffixed(fname,s))
+ end
+ end
+ end
+ end
+
+ def makestubfile(rawname,rawbase,forcexml=false)
+ if tmp = openedfile(File.suffixed(rawbase,'run')) then
+ tmp << "\\starttext\n"
+ if forcexml then
+ # tmp << checkxmlfile(rawname)
+ if getvariable('mkiv') then
+ tmp << "\\xmlprocess{\\xmldocument}{#{rawname}}{}\n"
+ else
+ tmp << "\\processXMLfilegrouped{#{rawname}}\n"
+ end
+ else
+ tmp << "\\processfile{#{rawname}}\n"
+ end
+ tmp << "\\stoptext\n"
+ tmp.close
+ return "run"
+ else
+ return File.splitname(rawname)[1]
+ end
+ end
+
+ # def checkxmlfile(rawname)
+ # tmp = ''
+ # if FileTest.file?(rawname) && (xml = File.open(rawname)) then
+ # xml.each do |line|
+ # case line
+ # when /<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?>/o then
+ # category, key, value, rest = $1, $2, $3, $4
+ # case category
+ # when 'job' then
+ # case key
+ # when 'control' then
+ # setvariable(value,if rest.empty? then true else rest end)
+ # when 'mode', 'modes' then
+ # tmp << "\\enablemode[#{value}]\n"
+ # when 'stylefile', 'environment' then
+ # tmp << "\\environment #{value}\n"
+ # when 'module' then
+ # tmp << "\\usemodule[#{value}]\n"
+ # when 'interface' then
+ # contextinterface = value
+ # when 'ctxfile' then
+ # setvariable('ctxfile', value)
+ # report("using source driven ctxfile #{value}")
+ # end
+ # end
+ # when /<[a-z]+/io then # beware of order, first pi test
+ # break
+ # end
+ # end
+ # xml.close
+ # end
+ # return tmp
+ # end
+
+ def extendvariable(name,value)
+ set = getvariable(name).split(',')
+ set << value
+ str = set.uniq.join(',')
+ setvariable(name,str)
+ end
+
+ def checkxmlfile(rawname)
+ if FileTest.file?(rawname) && (xml = File.open(rawname,'rb')) then
+ xml.each do |line|
+ case line
+ when /<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?>/o then
+ category, key, value, rest = $1, $2, $3, $4
+ case category
+ when 'job' then
+ case key
+ when 'control' then
+ setvariable(value,if rest.empty? then true else rest end)
+ when /^(mode)(s|)$/ then
+ extendvariable('modes',value)
+ when /^(stylefile|environment)(s|)$/ then
+ extendvariable('environments',value)
+ when /^(use|)(module)(s|)$/ then
+ extendvariable('usemodules',value)
+ when /^(filter)(s|)$/ then
+ extendvariable('filters',value)
+ when 'interface' then
+ contextinterface = value
+ when 'ctxfile' then
+ setvariable('ctxfile', value)
+ report("using source driven ctxfile #{value}")
+ end
+ end
+ when /<[a-z]+/io then # beware of order, first pi test
+ break
+ end
+ end
+ xml.close
+ end
+ end
+
+end
+
+class TEX
+
+ def timedrun(delay, &block)
+ delay = delay.to_i rescue 0
+ if delay > 0 then
+ begin
+ report("job started with timeout '#{delay}'")
+ timeout(delay) do
+ yield block
+ end
+ rescue TimeoutError
+ report("job aborted due to timeout '#{delay}'")
+ setvariable('error','timeout')
+ rescue
+ report("job aborted due to error")
+ setvariable('error','fatal error')
+ else
+ report("job finished within timeout '#{delay}'")
+ end
+ else
+ yield block
+ end
+ end
+
+ def processtex # much to do: mp, xml, runs etc
+ setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty?
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing document '#{filename}'")
+ timedrun(getvariable('timeout')) do
+ processfile
+ end
+ end
+ reportruntime
+ end
+
+ def processmptex
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing graphic '#{filename}'")
+ runtexmp(filename)
+ end
+ reportruntime
+ end
+
+ private
+
+ def load_map_files(filename) # tui basename
+ # c \usedmapfile{=}{lm-texnansi}
+ begin
+ str = ""
+ IO.read(filename).scan(/^c\s+\\usedmapfile\{(.*?)\}\{(.*?)\}\s*$/o) do
+ str << "\\loadmapfile[#{$2}.map]\n"
+ end
+ rescue
+ return ""
+ else
+ return str
+ end
+ end
+
+ public
+
+ def processmpgraphic
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing graphic '#{filename}'")
+ runtexmp(filename,'',false) # no purge
+ mapspecs = load_map_files(File.suffixed(filename,'temp','tui'))
+ unless getvariable('keep') then
+ # not enough: purge_mpx_files(filename)
+ Dir.glob(File.suffixed(filename,'temp*','*')).each do |fname|
+ File.delete(fname) unless File.basename(filename) == File.basename(fname)
+ end
+ end
+ begin
+ data = IO.read(File.suffixed(filename,'log'))
+ basename = filename.sub(/\.mp$/, '')
+ if data =~ /output files* written\:\s*(.*)$/moi then
+ files, number, range, list = $1.split(/\s+/), 0, false, []
+ files.each do |fname|
+ if fname =~ /^.*\.(\d+)$/ then
+ if range then
+ (number+1 .. $1.to_i).each do |i|
+ list << i
+ end
+ range = false
+ else
+ number = $1.to_i
+ list << number
+ end
+ elsif fname =~ /\.\./ then
+ range = true
+ else
+ range = false
+ next
+ end
+ end
+ begin
+ if getvariable('combine') then
+ fullname = "#{basename}.#{number}"
+ File.open("texexec.tex",'w') do |f|
+ f << "\\setupoutput[pdftex]\n"
+ f << "\\setupcolors[state=start]\n"
+ f << mapspecs
+ f << "\\starttext\n"
+ list.each do |number|
+ f << "\\startTEXpage\n"
+ f << "\\convertMPtoPDF{#{fullname}}{1}{1}"
+ f << "\\stopTEXpage\n"
+ end
+ f << "\\stoptext\n"
+ end
+ report("converting graphic '#{fullname}'")
+ runtex("texexec.tex")
+ pdffile = File.suffixed(basename,'pdf')
+ File.silentrename("texexec.pdf",pdffile)
+ report ("#{basename}.* converted to #{pdffile}")
+ else
+ list.each do |number|
+ begin
+ fullname = "#{basename}.#{number}"
+ File.open("texexec.tex",'w') do |f|
+ f << "\\setupoutput[pdftex]\n"
+ f << "\\setupcolors[state=start]\n"
+ f << mapspecs
+ f << "\\starttext\n"
+ f << "\\startTEXpage\n"
+ f << "\\convertMPtoPDF{#{fullname}}{1}{1}"
+ f << "\\stopTEXpage\n"
+ f << "\\stoptext\n"
+ end
+ report("converting graphic '#{fullname}'")
+ runtex("texexec.tex")
+ if files.length>1 then
+ pdffile = File.suffixed(basename,number.to_s,'pdf')
+ else
+ pdffile = File.suffixed(basename,'pdf')
+ end
+ File.silentrename("texexec.pdf",pdffile)
+ report ("#{fullname} converted to #{pdffile}")
+ end
+ end
+ end
+ rescue
+ report ("error when converting #{fullname} (#{$!})")
+ end
+ end
+ rescue
+ report("error in converting #{filename}")
+ end
+ end
+ reportruntime
+ end
+
+ def processmpstatic
+ if filename = getvariable('filename') then
+ filename += ".mp" unless filename =~ /\..+?$/
+ if FileTest.file?(filename) then
+ begin
+ data = IO.read(filename)
+ File.open("texexec.tex",'w') do |f|
+ f << "\\setupoutput[pdftex]\n"
+ f << "\\setupcolors[state=start]\n"
+ data.sub!(/^%mpenvironment\:\s*(.*?)$/moi) do
+ f << $1
+ "\n"
+ end
+ f << "\\starttext\n"
+ f << "\\startMPpage\n"
+ f << data.gsub(/end\.*\s*$/m, '') # a bit of a hack
+ f << "\\stopMPpage\n"
+ f << "\\stoptext\n"
+ end
+ report("converting static '#{filename}'")
+ runtex("texexec.tex")
+ pdffile = File.suffixed(filename,'pdf')
+ File.silentrename("texexec.pdf",pdffile)
+ report ("#{filename} converted to #{pdffile}")
+ rescue
+ report("error in converting #{filename} (#{$!}")
+ end
+ end
+ end
+ reportruntime
+ end
+
+ def processmpxtex
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing text of graphic '#{filename}'")
+ processmpx(filename,false,true,true)
+ end
+ reportruntime
+ end
+
+ def deleteoptionfile(rawname)
+ ['top','top.keep'].each do |suffix|
+ begin
+ File.delete(File.suffixed(rawname,suffix))
+ rescue
+ end
+ end
+ end
+
+ def makeoptionfile(rawname, jobname, jobsuffix, finalrun, fastdisabled, kindofrun, currentrun=1)
+ begin
+ # jobsuffix = orisuffix
+ if topname = File.suffixed(rawname,'top') and opt = File.open(topname,'w') then
+ report("writing option file #{topname}")
+ # local handies
+ opt << "\% #{topname}\n"
+ opt << "\\unprotect\n"
+ #
+ # feedback and basic control
+ #
+ if getvariable('batchmode') then
+ opt << "\\batchmode\n"
+ end
+ if getvariable('nonstopmode') then
+ opt << "\\nonstopmode\n"
+ end
+ if getvariable('paranoid') then
+ opt << "\\def\\maxreadlevel{1}\n"
+ end
+ if getvariable('nomapfiles') then
+ opt << "\\disablemapfiles\n"
+ end
+ if getvariable('nompmode') || getvariable('nomprun') || getvariable('automprun') then
+ opt << "\\runMPgraphicsfalse\n"
+ end
+ if getvariable('utfbom') then
+ opt << "\\enableregime[utf]"
+ end
+ progname = validprogname(['metafun']) # [getvariable('progname'),mpsformat,mpsengine]
+ opt << "\\def\\MPOSTformatswitch\{#{prognameflag(progname)} #{formatflag('mpost')}=\}\n"
+ #
+ # process info
+ #
+ opt << "\\setupsystem[\\c!n=#{kindofrun},\\c!m=#{currentrun}]\n"
+ if (str = File.unixfied(getvariable('modefile'))) && ! str.empty? then
+ opt << "\\readlocfile{#{str}}{}{}\n"
+ end
+ if (str = File.unixfied(getvariable('result'))) && ! str.empty? then
+ opt << "\\setupsystem[file=#{str}]\n"
+ elsif (str = getvariable('suffix')) && ! str.empty? then
+ opt << "\\setupsystem[file=#{jobname}.#{str}]\n"
+ end
+ opt << "\\setupsystem[\\c!method=2]\n" # 1=oldtexexec 2=newtexexec (obsolete)
+ opt << "\\setupsystem[\\c!type=#{Tool.ruby_platform()}]\n"
+ if (str = File.unixfied(getvariable('path'))) && ! str.empty? then
+ opt << "\\usepath[#{str}]\n" unless str.empty?
+ end
+ if (str = getvariable('mainlanguage').downcase) && ! str.empty? && ! str.standard? then
+ opt << "\\setuplanguage[#{str}]\n"
+ end
+ if (str = getvariable('arguments')) && ! str.empty? then
+ opt << "\\setupenv[#{str}]\n"
+ end
+ if (str = getvariable('setuppath')) && ! str.empty? then
+ opt << "\\setupsystem[\\c!directory=\{#{str}\}]\n"
+ end
+ if (str = getvariable('randomseed')) && ! str.empty? then
+ report("using randomseed #{str}")
+ opt << "\\setupsystem[\\c!random=#{str}]\n"
+ end
+ if (str = getvariable('input')) && ! str.empty? then
+ opt << "\\setupsystem[inputfile=#{str}]\n"
+ else
+ opt << "\\setupsystem[inputfile=#{rawname}]\n"
+ end
+ #
+ # modes
+ #
+ # we handle both "--mode" and "--modes", else "--mode" is mapped onto "--modefile"
+ if (str = getvariable('modes')) && ! str.empty? then
+ opt << "\\enablemode[#{str}]\n"
+ end
+ if (str = getvariable('mode')) && ! str.empty? then
+ opt << "\\enablemode[#{str}]\n"
+ end
+ #
+ # options
+ #
+ opt << "\\startsetups *runtime:options\n"
+ if str = validbackend(getvariable('backend')) then
+ opt << "\\setupoutput[#{str}]\n"
+ elsif str = validbackend(getvariable('output')) then
+ opt << "\\setupoutput[#{str}]\n"
+ end
+ if getvariable('color') then
+ opt << "\\setupcolors[\\c!state=\\v!start]\n"
+ end
+ if (str = getvariable('separation')) && ! str.empty? then
+ opt << "\\setupcolors[\\c!split=#{str}]\n"
+ end
+ if (str = getvariable('paperformat')) && ! str.empty? && ! str.standard? then
+ if str =~ /^([a-z]+\d+)([a-z]+\d+)$/io then # A5A4 A4A3 A2A1 ...
+ opt << "\\setuppapersize[#{$1.upcase}][#{$2.upcase}]\n"
+ else # ...*...
+ pf = str.upcase.split(/[x\*]/o)
+ pf << pf[0] if pf.size == 1
+ opt << "\\setuppapersize[#{pf[0]}][#{pf[1]}]\n"
+ end
+ end
+ if (str = getvariable('background')) && ! str.empty? then
+ opt << "\\defineoverlay[whatever][{\\externalfigure[#{str}][\\c!factor=\\v!max]}]\n"
+ opt << "\\setupbackgrounds[\\v!page][\\c!background=whatever]\n"
+ end
+ if getvariable('centerpage') then
+ opt << "\\setuplayout[\\c!location=\\v!middle,\\c!marking=\\v!on]\n"
+ end
+ if getvariable('noarrange') then
+ opt << "\\setuparranging[\\v!disable]\n"
+ elsif getvariable('arrange') then
+ arrangement = Array.new
+ if finalrun then
+ arrangement << "\\v!doublesided" unless getvariable('noduplex')
+ case getvariable('printformat')
+ when '' then arrangement << "\\v!normal"
+ when /.*up/oi then arrangement << ["2UP","\\v!rotated"]
+ when /.*down/oi then arrangement << ["2DOWN","\\v!rotated"]
+ when /.*side/oi then arrangement << ["2SIDE","\\v!rotated"]
+ end
+ else
+ arrangement << "\\v!disable"
+ end
+ opt << "\\setuparranging[#{arrangement.flatten.join(',')}]\n" if arrangement.size > 0
+ end
+ if (str = getvariable('pages')) && ! str.empty? then
+ if str.downcase == 'odd' then
+ opt << "\\chardef\\whichpagetoshipout=1\n"
+ elsif str.downcase == 'even' then
+ opt << "\\chardef\\whichpagetoshipout=2\n"
+ else
+ pagelist = Array.new
+ str.split(/\,/).each do |page|
+ pagerange = page.split(/\D+/o)
+ if pagerange.size > 1 then
+ pagerange.first.to_i.upto(pagerange.last.to_i) do |p|
+ pagelist << p.to_s
+ end
+ else
+ pagelist << page
+ end
+ end
+ opt << "\\def\\pagestoshipout\{#{pagelist.join(',')}\}\n";
+ end
+ end
+ opt << "\\stopsetups\n"
+ #
+ # styles and modules
+ #
+ opt << "\\startsetups *runtime:modules\n"
+ begin getvariable('filters' ).split(',').uniq.each do |f| opt << "\\useXMLfilter[#{f}]\n" end ; rescue ; end
+ begin getvariable('usemodules' ).split(',').uniq.each do |m| opt << "\\usemodule [#{m}]\n" end ; rescue ; end
+ begin getvariable('environments').split(',').uniq.each do |e| opt << "\\environment #{e} \n" end ; rescue ; end
+ opt << "\\stopsetups\n"
+ #
+ opt << "\\protect \\endinput\n"
+ #
+ opt.close
+ else
+ report("unable to write option file #{topname}")
+ end
+ rescue
+ report("fatal error in writing option file #{topname} (#{$!})")
+ end
+ end
+
+ def takeprecautions
+ ENV['MPXCOMAND'] = '0' # else loop
+ if getvariable('paranoid') then
+ ENV['SHELL_ESCAPE'] = ENV['SHELL_ESCAPE'] || 'f'
+ ENV['OPENOUT_ANY'] = ENV['OPENOUT_ANY'] || 'p'
+ ENV['OPENIN_ANY'] = ENV['OPENIN_ANY'] || 'p'
+ elsif getvariable('notparanoid') then
+ ENV['SHELL_ESCAPE'] = ENV['SHELL_ESCAPE'] || 't'
+ ENV['OPENOUT_ANY'] = ENV['OPENOUT_ANY'] || 'a'
+ ENV['OPENIN_ANY'] = ENV['OPENIN_ANY'] || 'a'
+ end
+ if ENV['OPENIN_ANY'] && (ENV['OPENIN_ANY'] == 'p') then # first test redundant
+ setvariable('paranoid', true)
+ end
+ if ENV.key?('SHELL_ESCAPE') && (ENV['SHELL_ESCAPE'] == 'f') then
+ setvariable('automprun',true)
+ end
+ done = false
+ ['TXRESOURCES','MPRESOURCES','MFRESOURCES'].each do |res|
+ [getvariable('runpath'),getvariable('path')].each do |pat|
+ unless pat.empty? then
+ if ENV.key?(res) then
+ # ENV[res] = if ENV[res].empty? then pat else pat + ":" + ENV[res] end
+if ENV[res].empty? then
+ ENV[res] = pat
+elsif ENV[res] == pat || ENV[res] =~ /^#{pat}\:/ || ENV[res] =~ /\:#{pat}\:/ then
+ # skip
+else
+ ENV[res] = pat + ":" + ENV[res]
+end
+ else
+ ENV[res] = pat
+ end
+ report("setting #{res} to #{ENV[res]}") unless done
+ end
+ end
+ done = true
+ end
+ end
+
+ def checktestversion
+ #
+ # one can set TEXMFALPHA and TEXMFBETA for test versions
+ # but keep in mind that the format as well as the test files
+ # then need the --alpha or --beta flag
+ #
+ done, tree = false, ''
+ ['alpha', 'beta'].each do |what|
+ if getvariable(what) then
+ if ENV["TEXMF#{what.upcase}"] then
+ done, tree = true, ENV["TEXMF#{what.upcase}"]
+ elsif ENV["TEXMFLOCAL"] then
+ done, tree = true, File.join(File.dirname(ENV['TEXMFLOCAL']), "texmf-#{what}")
+ end
+ end
+ break if done
+ end
+ if done then
+ tree = tree.strip
+ ENV['TEXMFPROJECT'] = tree
+ report("using test tree '#{tree}'")
+ ['MP', 'MF', 'TX'].each do |ctx|
+ ENV['CTXDEV#{ctx}PATH'] = ''
+ end
+ unless (FileTest.file?(File.join(tree,'ls-r')) || FileTest.file?(File.join(tree,'ls-R'))) then
+ report("no ls-r/ls-R file for tree '#{tree}' (run: mktexlsr #{tree})")
+ end
+ end
+ # puts `kpsewhich --expand-path=$TEXMF`
+ # exit
+ end
+
+ def runtex(filename)
+ checktestversion
+ texengine = validtexengine(getvariable('texengine'))
+ texformat = validtexformat(getarrayvariable('texformats').first)
+ report("tex engine: #{texengine}")
+ report("tex format: #{texformat}")
+ if texengine && texformat then
+ fixbackendvars(@@mappaths[texengine])
+ progname = validprogname([getvariable('progname'),texformat,texengine])
+ runcommand([quoted(texengine),prognameflag(progname),formatflag(texengine,texformat),runoptions(texengine),filename,texprocextras(texformat)])
+ else
+ false
+ end
+ end
+
+ def runmp(mpname,mpx=false)
+ checktestversion
+ mpsengine = validmpsengine(getvariable('mpsengine'))
+ mpsformat = validmpsformat(getarrayvariable('mpsformats').first)
+ if mpsengine && mpsformat then
+ ENV["MPXCOMMAND"] = "0" unless mpx
+ progname = validprogname([getvariable('progname'),mpsformat,mpsengine])
+ mpname.gsub!(/\.mp$/,"") # temp bug in mp
+ runcommand([quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),runoptions(mpsengine),mpname,mpsprocextras(mpsformat)])
+ true
+ else
+ false
+ end
+ end
+
+ def runtexmp(filename,filetype='',purge=true)
+ checktestversion
+ mpname = File.suffixed(filename,filetype,'mp')
+ if File.atleast?(mpname,10) then
+ # first run needed
+ File.silentdelete(File.suffixed(mpname,'mpt'))
+ doruntexmp(mpname,nil,true,purge)
+ mpgraphics = checkmpgraphics(mpname)
+ mplabels = checkmplabels(mpname)
+ if mpgraphics || mplabels then
+ # second run needed
+ doruntexmp(mpname,mplabels,true,purge)
+ else
+ # no labels
+ end
+ end
+ end
+
+ def runtexmpjob(filename,filetype='')
+ checktestversion
+ mpname = File.suffixed(filename,filetype,'mp')
+ if File.atleast?(mpname,25) && (data = File.silentread(mpname)) then
+ textranslation = if data =~ /^\%\s+translate.*?\=([\w\d\-]+)/io then $1 else '' end
+ mpjobname = if data =~ /collected graphics of job \"(.+?)\"/io then $1 else '' end
+ if ! mpjobname.empty? and File.unsuffixed(filename) =~ /#{mpjobname}/ then # don't optimize
+ options = Array.new
+ options.push("--mptex")
+ options.push("--nomp")
+ options.push("--mpyforce") if getvariable('forcempy') || getvariable('mpyforce')
+ options.push("--translate=#{textranslation}") unless textranslation.empty?
+ options.push("--batch") if getvariable('batchmode')
+ options.push("--nonstop") if getvariable('nonstopmode')
+ options.push("--output=ps") # options.push("--dvi")
+ options.push("--nobackend")
+ return runtexexec(mpname,options,2)
+ end
+ end
+ return false
+ end
+
+ def runtexutil(filename=[], options=['--ref','--ij','--high'], old=false)
+ [filename].flatten.each do |fname|
+ if old then
+ Kpse.runscript('texutil',fname,options)
+ else
+ begin
+ logger = Logger.new('TeXUtil')
+ if tu = TeXUtil::Converter.new(logger) and tu.loaded(fname) then
+ ok = tu.processed && tu.saved && tu.finalized
+ end
+ rescue
+ Kpse.runscript('texutil',fname,options)
+ end
+ end
+ end
+ end
+
+ # 1=tex 2=mptex 3=mpxtex 4=mpgraphic 5=mpstatic
+
+ def runtexexec(filename=[], options=[], mode=nil)
+ begin
+ if mode and job = TEX.new(@logger) then
+ options.each do |option|
+ case option
+ when /^\-*(.*?)\=(.*)$/o then
+ job.setvariable($1,$2)
+ when /^\-*(.*?)$/o then
+ job.setvariable($1,true)
+ end
+ end
+ job.setvariable("files",filename)
+ case mode
+ when 1 then job.processtex
+ when 2 then job.processmptex
+ when 3 then job.processmpxtex
+ when 4 then job.processmpgraphic
+ when 5 then job.processmpstatic
+ end
+ job.inspect && Kpse.inspect if getvariable('verbose')
+ return true
+ else
+ Kpse.runscript('texexec',filename,options)
+ end
+ rescue
+ Kpse.runscript('texexec',filename,options)
+ end
+ end
+
+ def fixbackendvars(backend)
+ if backend then
+ ENV['backend'] = backend ;
+ ENV['progname'] = backend unless validtexengine(backend)
+ ENV['TEXFONTMAPS'] = ['.',"\$TEXMF/fonts/{data,map}/{#{backend},pdftex,dvips,}//",'./fonts//'].join_path
+ report("fixing backend map path for #{backend}: #{ENV['TEXFONTMAPS']}") if getvariable('verbose')
+ else
+ report("unable to fix backend map path") if getvariable('verbose')
+ end
+ end
+
+ def runbackend(rawname)
+ unless getvariable('nobackend') then
+ case validbackend(getvariable('backend'))
+ when 'dvipdfmx' then
+ fixbackendvars('dvipdfm')
+ runcommand("dvipdfmx -d 4 -V 5 #{File.unsuffixed(rawname)}")
+ when 'xetex' then
+ # xetex now runs its own backend
+ xdvfile = File.suffixed(rawname,'xdv')
+ if FileTest.file?(xdvfile) then
+ fixbackendvars('dvipdfm')
+ runcommand("xdvipdfmx -q -d 4 -V 5 -E #{xdvfile}")
+ end
+ when 'xdv2pdf' then
+ xdvfile = File.suffixed(rawname,'xdv')
+ if FileTest.file?(xdvfile) then
+ fixbackendvars('xdv2pdf')
+ runcommand("xdv2pdf #{xdvfile}")
+ end
+ when 'dvips' then
+ fixbackendvars('dvips')
+ mapfiles = ''
+ begin
+ if tuifile = File.suffixed(rawname,'tui') and FileTest.file?(tuifile) then
+ IO.read(tuifile).scan(/^c \\usedmapfile\{.\}\{(.*?)\}\s*$/o) do
+ mapfiles += "-u +#{$1} " ;
+ end
+ end
+ rescue
+ mapfiles = ''
+ end
+ runcommand("dvips #{mapfiles} #{File.unsuffixed(rawname)}")
+ when 'pdftex' then
+ # no need for postprocessing
+ else
+ report("no postprocessing needed")
+ end
+ end
+ end
+
+ def processfile
+
+ takeprecautions
+ report("using search method '#{Kpse.searchmethod}'") if getvariable('verbose')
+
+ rawname = getvariable('filename')
+ jobname = getvariable('filename')
+
+ if getvariable('autopath') then
+ jobname = File.basename(jobname)
+ inppath = File.dirname(jobname)
+ else
+ inppath = ''
+ end
+
+ jobname, jobsuffix = File.splitname(jobname,'tex')
+
+ jobname = File.unixfied(jobname)
+ inppath = File.unixfied(inppath)
+
+ orisuffix = jobsuffix # still needed ?
+
+ if jobsuffix =~ /^(htm|html|xhtml|xml|fo|fox|rlg|exa)$/io then
+ setvariable('forcexml',true)
+ end
+
+ dummyfile = false
+
+ # fuzzy code snippet: (we kunnen kpse: prefix gebruiken)
+
+ unless FileTest.file?(File.suffixed(jobname,jobsuffix)) then
+ if FileTest.file?(rawname + '.tex') then
+ jobname = rawname.dup
+ jobsuffix = 'tex'
+ end
+ end
+
+ # we can have funny names, like 2005.10.10 (given without suffix)
+
+ rawname = jobname + '.' + jobsuffix
+ rawpath = File.dirname(rawname)
+ rawbase = File.basename(rawname)
+
+ unless FileTest.file?(rawname) then
+ inppath.split(',').each do |ip|
+ break if dummyfile = FileTest.file?(File.join(ip,rawname))
+ end
+ end
+
+ forcexml = getvariable('forcexml')
+
+ if dummyfile || forcexml then # after ctx?
+ jobsuffix = makestubfile(rawname,rawbase,forcexml)
+ checkxmlfile(rawname)
+ end
+
+ # preprocess files
+
+ unless getvariable('noctx') then
+ ctx = CtxRunner.new(rawname,@logger)
+ if pth = getvariable('path') then
+ pth.split(',').each do |p|
+ ctx.register_path(p)
+ end
+ end
+ if getvariable('ctxfile').empty? then
+ if rawname == rawbase then
+ ctx.manipulate(File.suffixed(rawname,'ctx'),'jobname.ctx')
+ else
+ ctx.manipulate(File.suffixed(rawname,'ctx'),File.join(rawpath,'jobname.ctx'))
+ end
+ else
+ ctx.manipulate(File.suffixed(getvariable('ctxfile'),'ctx'))
+ end
+ ctx.savelog(File.suffixed(rawbase,'ctl'))
+
+ envs = ctx.environments
+ mods = ctx.modules
+ flags = ctx.flags
+ mdes = ctx.modes
+
+ flags.each do |f|
+ f.sub!(/^\-+/,'')
+ if f =~ /^(.*?)=(.*)$/ then
+ setvariable($1,$2)
+ else
+ setvariable(f,true)
+ end
+ end
+
+ report("using flags #{flags.join(' ')}") if flags.size > 0
+
+ # merge environment and module specs
+
+ envs << getvariable('environments') unless getvariable('environments').empty?
+ mods << getvariable('usemodules') unless getvariable('usemodules') .empty?
+ mdes << getvariable('modes') unless getvariable('modes') .empty?
+
+ envs = envs.uniq.join(',')
+ mods = mods.uniq.join(',')
+ mdes = mdes.uniq.join(',')
+
+ report("using search method '#{Kpse.searchmethod}'") if getvariable('verbose')
+
+ report("using environments #{envs}") if envs.length > 0
+ report("using modules #{mods}") if mods.length > 0
+ report("using modes #{mdes}") if mdes.length > 0
+
+ setvariable('environments', envs)
+ setvariable('usemodules', mods)
+ setvariable('modes', mdes)
+ end
+
+ # end of preprocessing and merging
+
+ setvariable('nomprun',true) if orisuffix == 'mpx' # else cylic run
+ PDFview.setmethod('xpdf') if getvariable('xpdf')
+ PDFview.closeall if getvariable('autopdf')
+
+ runonce = getvariable('once')
+ finalrun = getvariable('final') || (getvariable('arrange') && ! getvariable('noarrange'))
+ suffix = getvariable('suffix')
+ result = getvariable('result')
+ globalfile = getvariable('globalfile')
+ forcexml = getvariable('forcexml') # can be set in ctx file
+
+if dummyfile || forcexml then # after ctx?
+ jobsuffix = makestubfile(rawname,rawbase,forcexml)
+ checkxmlfile(rawname)
+end
+
+ result = File.unixfied(result)
+
+ if globalfile || FileTest.file?(rawname) then
+
+ if not dummyfile and not globalfile and not forcexml then
+ scantexpreamble(rawname)
+ scantexcontent(rawname) if getvariable('texformats').standard?
+ end
+ result = File.suffixed(rawname,suffix) unless suffix.empty?
+
+ pushresult(rawbase,result)
+
+ method = validtexmethod(validtexformat(getvariable('texformats')))
+
+ report("tex processing method: #{method}")
+
+ case method
+
+ when 'context' then
+ if getvariable('simplerun') || runonce then
+ makeoptionfile(rawbase,jobname,orisuffix,true,true,3,1) unless getvariable('nooptionfile')
+ ok = runtex(if dummyfile || forcexml then rawbase else rawname end)
+ if ok then
+ ok = runtexutil(rawbase) if getvariable('texutil') || getvariable('forcetexutil')
+ runbackend(rawbase)
+ popresult(rawbase,result)
+ end
+ if getvariable('keep') then
+ ['top','log','run'].each do |suffix|
+ File.silentrename(File.suffixed(rawbase,suffix),File.suffixed(rawbase,suffix+'.keep'))
+ end
+ end
+ else
+# goto tmp/jobname when present
+ mprundone, ok, stoprunning = false, true, false
+ texruns, nofruns = 0, getvariable('runs').to_i
+ state = FileState.new
+ ['tub','tuo','tuc'].each do |s|
+ state.register(File.suffixed(rawbase,s))
+ end
+ if getvariable('automprun') then # check this
+ ['mprun','mpgraph'].each do |s|
+ state.register(File.suffixed(rawbase,s,'mp'),'randomseed')
+ end
+ end
+ while ! stoprunning && (texruns < nofruns) && ok do
+ texruns += 1
+ report("TeX run #{texruns}")
+ unless getvariable('nooptionfile') then
+ if texruns == nofruns then
+ makeoptionfile(rawbase,jobname,orisuffix,false,false,4,texruns) # last
+ elsif texruns == 1 then
+ makeoptionfile(rawbase,jobname,orisuffix,false,false,1,texruns) # first
+ else
+ makeoptionfile(rawbase,jobname,orisuffix,false,false,2,texruns) # unknown
+ end
+ end
+# goto .
+
+ ok = runtex(File.suffixed(if dummyfile || forcexml then rawbase else rawname end,jobsuffix))
+
+if getvariable('texengine') == "xetex" then
+ ok = true
+end
+
+############################
+
+# goto tmp/jobname when present
+ if ok && (nofruns > 1) then
+ unless getvariable('nompmode') then
+ mprundone = runtexmpjob(rawbase, "mpgraph")
+ mprundone = runtexmpjob(rawbase, "mprun")
+ end
+ ok = runtexutil(rawbase)
+ state.update
+ stoprunning = state.stable?
+ end
+ end
+ if not ok then
+ setvariable('error','error in tex file')
+ end
+ if (nofruns == 1) && getvariable('texutil') then
+ ok = runtexutil(rawbase)
+ end
+ if ok && finalrun && (nofruns > 1) then
+ makeoptionfile(rawbase,jobname,orisuffix,true,finalrun,4,texruns) unless getvariable('nooptionfile')
+ report("final TeX run #{texruns}")
+# goto .
+ ok = runtex(File.suffixed(if dummyfile || forcexml then rawbase else rawname end,jobsuffix))
+# goto tmp/jobname when present
+ end
+ if getvariable('keep') then
+ ['top','log','run'].each do |suffix|
+ File.silentrename(File.suffixed(rawbase,suffix),File.suffixed(rawbase,suffix+'.keep'))
+ end
+ else
+ File.silentrename(File.suffixed(rawbase,'top'),File.suffixed(rawbase,'tmp'))
+ end
+ # ['tmp','top','log'].each do |s| # previous tuo file / runtime option file / log file
+ # File.silentdelete(File.suffixed(rawbase,s))
+ # end
+ if ok then
+# goto .
+ runbackend(rawbase)
+ popresult(rawbase,result)
+# goto tmp/jobname when present
+# skip next
+ end
+ if true then # autopurge
+ begin
+ File.open(File.suffixed(rawbase, 'tuo'),'rb') do |f|
+ ok = 0
+ f.each do |line|
+ case ok
+ when 1 then
+ # next line is empty
+ ok = 2
+ when 2 then
+ if line =~ /^\%\s+\>\s+(.*?)\s+(\d+)/moi then
+ filename, n = $1, $2
+ done = File.delete(filename) rescue false
+ if done && getvariable('verbose') then
+ report("deleting #{filename} (#{n} times used)")
+ end
+ else
+ break
+ end
+ else
+ if line =~ /^\%\s+temporary files\:\s+(\d+)/moi then
+ if $1.to_i == 0 then
+ break
+ else
+ ok = 1
+ end
+ end
+ end
+ end
+ end
+ rescue
+ # report("fatal error #{$!}")
+ end
+ end
+ end
+
+ Kpse.runscript('ctxtools',rawbase,'--purge') if getvariable('purge')
+ Kpse.runscript('ctxtools',rawbase,'--purge --all') if getvariable('purgeall')
+
+ # runcommand('mtxrun','--script','ctxtools',rawbase,'--purge') if getvariable('purge')
+ # runcommand('mtxrun','--script','ctxtools',rawbase,'--purge --all') if getvariable('purgeall')
+
+ when 'latex' then
+
+ ok = runtex(rawname)
+
+ else
+
+ ok = runtex(rawname)
+
+ end
+
+ if (dummyfile or forcexml) and FileTest.file?(rawbase) then
+ begin
+ File.delete(File.suffixed(rawbase,'run'))
+ rescue
+ report("unable to delete stub file")
+ end
+ end
+
+ if ok and getvariable('autopdf') then
+ PDFview.open(File.suffixed(if result.empty? then rawbase else result end,'pdf'))
+ end
+
+ else
+ report("nothing to process")
+ end
+
+ end
+
+ # The labels are collected in the mergebe hash. Here we merge the relevant labels
+ # into beginfig/endfig. We could as well do this in metafun itself. Maybe some
+ # day ... (it may cost a bit of string space but that is cheap nowadays).
+
+ def doruntexmp(mpname,mergebe=nil,context=true,purge=true)
+ texfound = false
+ mpname = File.suffixed(mpname,'mp')
+ mpcopy = File.suffixed(mpname,'mp.copy')
+ mpkeep = File.suffixed(mpname,'mp.keep')
+ setvariable('mp.file',mpname)
+ setvariable('mp.line','')
+ setvariable('mp.error','')
+ if mpdata = File.silentread(mpname) then
+ # mpdata.gsub!(/^\%.*\n/o,'')
+ File.silentrename(mpname,mpcopy)
+ texfound = mergebe || (mpdata =~ /btex .*? etex/mo)
+ if mp = openedfile(mpname) then
+ if mergebe then
+ mpdata.gsub!(/beginfig\s*\((\d+)\)\s*\;(.+?)endfig\s*\;/mo) do
+ n, str = $1, $2
+ if str =~ /^(.*?)(verbatimtex.*?etex)\s*\;(.*)$/mo then
+ "beginfig(#{n})\;\n#{$1}#{$2}\;\n#{mergebe[n]}\n#{$3}\;endfig\;\n"
+ else
+ "beginfig(#{n})\;\n#{mergebe[n]}\n#{str}\;endfig\;\n"
+ end
+ end
+ unless mpdata =~ /beginfig\s*\(\s*0\s*\)/o then
+ mp << mergebe['0'] if mergebe.key?('0')
+ end
+ end
+ # mp << MPTools::splitmplines(mpdata)
+ mp << mpdata
+ mp << "\n"
+ # mp << "end"
+ # mp << "\n"
+ mp.close
+ end
+ processmpx(mpname,true,true,purge) if texfound
+ if getvariable('batchmode') then
+ options = ' --interaction=batch'
+ elsif getvariable('nonstopmode') then
+ options = ' --interaction=nonstop'
+ else
+ options = ''
+ end
+ # todo plain|mpost|metafun
+ begin
+ ok = runmp(mpname)
+ rescue
+ end
+ if f = File.silentopen(File.suffixed(mpname,'log')) then
+ while str = f.gets do
+ if str =~ /^l\.(\d+)\s(.*?)\n/o then
+ setvariable('mp.line',$1)
+ setvariable('mp.error',$2)
+ break
+ end
+ end
+ f.close
+ end
+ File.silentrename(mpname, mpkeep)
+ File.silentrename(mpcopy, mpname)
+ end
+ end
+
+ # todo: use internal mptotext function and/or turn all btex/etex into textexts
+
+ def processmpx(mpname,force=false,context=true,purge=true)
+ unless force then
+ mpname = File.suffixed(mpname,'mp')
+ if File.atleast?(mpname,10) && (data = File.silentread(mpname)) then
+ if data =~ /(btex|etex|verbatimtex|textext)/o then
+ force = true
+ end
+ end
+ end
+ if force then
+ begin
+ mptex = File.suffixed(mpname,'temp','tex')
+ mpdvi = File.suffixed(mpname,'temp','dvi')
+ mplog = File.suffixed(mpname,'temp','log')
+ mpmpx = File.suffixed(mpname,'mpx')
+ File.silentdelete(mptex)
+ if true then
+ report("using internal mptotex converter")
+ ok = MPTools::mptotex(mpname,mptex,'context')
+ else
+ command = "mpto #{mpname} > #{mptex}"
+ report(command) if getvariable('verbose')
+ ok = system(command)
+ end
+ # not "ok && ..." because of potential problem with return code and redirect (>)
+ if FileTest.file?(mptex) && File.appended(mptex, "\\end\n") then
+ # to be replaced by runtexexec([filenames],options,1)
+ if localjob = TEX.new(@logger) then
+ localjob.setvariable('files',mptex)
+ localjob.setvariable('backend','dvips')
+ localjob.setvariable('engine',getvariable('engine')) unless getvariable('engine').empty?
+ localjob.setvariable('once',true)
+ localjob.setvariable('nobackend',true)
+ if context then
+ localjob.setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty?
+ elsif getvariable('interface').empty? then
+ localjob.setvariable('texformats',['plain'])
+ else
+ localjob.setvariable('texformats',[getvariable('interface')])
+ end
+ localjob.processtex
+ ok = true # todo
+ else
+ ok = false
+ end
+ # so far
+ command = "dvitomp #{mpdvi} #{mpmpx}"
+ report(command) if getvariable('verbose')
+ ok = ok && FileTest.file?(mpdvi) && system(command)
+ purge_mpx_files(mpname) if purge
+ end
+ rescue
+ # error in processing mpx file
+ end
+ end
+ end
+
+ def purge_mpx_files(mpname)
+ unless getvariable('keep') then
+ ['tex', 'log', 'tui', 'tuo', 'tuc', 'top'].each do |suffix|
+ File.silentdelete(File.suffixed(mpname,'temp',suffix))
+ end
+ end
+ end
+
+ def checkmpgraphics(mpname)
+ # in practice the checksums will differ because of multiple instances
+ # ok, we could save the mpy/mpo files by number, but not now
+ mpoptions = ''
+ if getvariable('makempy') then
+ mpoptions += " --makempy "
+ end
+ mponame = File.suffixed(mpname,'mpo')
+ mpyname = File.suffixed(mpname,'mpy')
+ pdfname = File.suffixed(mpname,'pdf')
+ tmpname = File.suffixed(mpname,'tmp')
+ if getvariable('mpyforce') || getvariable('forcempy') then
+ mpoptions += " --force "
+ else
+ return false unless File.atleast?(mponame,32)
+ mpochecksum = FileState.new.checksum(mponame)
+ return false if mpochecksum.empty?
+ # where does the checksum get into the file?
+ # maybe let texexec do it?
+ # solution: add one if not present or update when different
+ begin
+ mpydata = IO.read(mpyname)
+ if mpydata then
+ if mpydata =~ /^\%\s*mpochecksum\s*\:\s*([A-Z0-9]+)$/mo then
+ checksum = $1
+ if mpochecksum == checksum then
+ return false
+ end
+ end
+ end
+ rescue
+ # no file
+ end
+ end
+ # return Kpse.runscript('makempy',mpname)
+ # only pdftex
+ flags = ['--noctx','--process','--batch','--once']
+ result = runtexexec([mponame], flags, 1)
+ runcommand(["pstoedit","-ssp -dt -f mpost", pdfname,tmpname])
+ tmpdata = IO.read(tmpname)
+ if tmpdata then
+ if mpy = openedfile(mpyname) then
+ mpy << "% mpochecksum: #{mpochecksum}\n"
+ tmpdata.scan(/beginfig(.*?)endfig/mo) do |s|
+ mpy << "begingraphictextfig#{s}endgraphictextfig\n"
+ end
+ mpy.close()
+ end
+ end
+ File.silentdelete(tmpname)
+ File.silentdelete(pdfname)
+ return true
+ end
+
+ def checkmplabels(mpname)
+ mpname = File.suffixed(mpname,'mpt')
+ if File.atleast?(mpname,10) && (mp = File.silentopen(mpname)) then
+ labels = Hash.new
+ while str = mp.gets do
+ t = if str =~ /^%\s*setup\s*:\s*(.*)$/o then $1 else '' end
+ if str =~ /^%\s*figure\s*(\d+)\s*:\s*(.*)$/o then
+ labels[$1] = labels[$1] || ''
+ unless t.empty? then
+ labels[$1] += "#{t}\n"
+ t = ''
+ end
+ labels[$1] += "#{$2}\n"
+ end
+ end
+ mp.close
+ if labels.size>0 then
+ return labels
+ else
+ return nil
+ end
+ end
+ return nil
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/texutil.rb b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb
new file mode 100644
index 00000000000..868e3ca1625
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb
@@ -0,0 +1,1097 @@
+require "base/file"
+require "base/logger"
+
+class String
+
+ # real dirty, but inspect does a pretty good escaping but
+ # unfortunately puts quotes around the string so we need
+ # to strip these
+
+ # def escaped
+ # self.inspect[1,self.inspect.size-2]
+ # end
+
+ def escaped
+ str = self.inspect ; str[1,str.size-2]
+ end
+
+ def splitdata
+ if self =~ /^\s*(.*?)\s*\{(.*)\}\s*$/o then
+ first, second = $1, $2
+ if first.empty? then
+ [second.split(/\} \{/o)].flatten
+ else
+ [first.split(/\s+/o)] + [second.split(/\} \{/o)]
+ end
+ else
+ []
+ end
+ end
+
+end
+
+class Logger
+ def banner(str)
+ report(str)
+ return "%\n% #{str}\n%\n"
+ end
+end
+
+class TeXUtil
+
+ class Plugin
+
+ # we need to reset module data for each run; persistent data is
+ # possible, just don't reinitialize the data structures that need
+ # to be persistent; we reset afterwards becausethen we know what
+ # plugins are defined
+
+ def initialize(logger)
+ @plugins = Array.new
+ @logger = logger
+ end
+
+ def report(str)
+ @logger.report("fatal error in plugin (#{str}): #{$!}")
+ puts("\n")
+ $@.each do |line|
+ puts(" #{line}")
+ end
+ puts("\n")
+ end
+
+ def reset(name)
+ if @plugins.include?(name) then
+ begin
+ eval("#{name}").reset(@logger)
+ rescue Exception
+ report("resetting")
+ end
+ else
+ @logger.report("no plugin #{name}")
+ end
+ end
+
+ def resets
+ @plugins.each do |p|
+ reset(p)
+ end
+ end
+
+ def register(name, file=nil) # maybe also priority
+ if file then
+ begin
+ require("#{file.downcase.sub(/\.rb$/,'')}.rb")
+ rescue Exception
+ @logger.report("no plugin file #{file} for #{name}")
+ else
+ @plugins.push(name)
+ end
+ else
+ @plugins.push(name)
+ end
+ return self
+ end
+
+ def reader(name, data=[])
+ if @plugins.include?(name) then
+ begin
+ eval("#{name}").reader(@logger,data.flatten)
+ rescue Exception
+ report("reading")
+ end
+ else
+ @logger.report("no plugin #{name}")
+ end
+ end
+
+ def readers(data=[])
+ @plugins.each do |p|
+ reader(p,data.flatten)
+ end
+ end
+
+ def writers(handle)
+ @plugins.each do |p|
+ begin
+ eval("#{p}").writer(@logger,handle)
+ rescue Exception
+ report("writing")
+ end
+ end
+ end
+
+ def processors
+ @plugins.each do |p|
+ begin
+ eval("#{p}").processor(@logger)
+ rescue Exception
+ report("processing")
+ end
+ end
+ end
+
+ def finalizers
+ @plugins.each do |p|
+ begin
+ eval("#{p}").finalizer(@logger)
+ rescue Exception
+ report("finalizing")
+ end
+ end
+ end
+
+ end
+
+ class Sorter
+
+ @@downcase = true
+
+ def initialize(max=12)
+ @rep, @map, @exp, @div = Hash.new, Hash.new, Hash.new, Hash.new
+ @max = max
+ @rexa, @rexb = nil, nil
+ end
+
+ def replacer(from,to='') # and expand
+ @max = [@max,to.length+1].max if to
+ @rep[from.escaped] = to || ''
+ end
+
+ # sorter.reducer('ch', 'c')
+ # sorter.reducer('ij', 'y')
+
+ def reducer(from,to='')
+ @max = [@max,to.length+1].max if to
+ @map[from] = to || ''
+ end
+
+ # sorter.expander('aeligature', 'ae')
+ # sorter.expander('ijligature', 'y')
+
+ def expander(from,to=nil)
+ to = converted(to) # not from !!!
+ @max = [@max,to.length+1].max if to
+ @exp[from] = to || from || ''
+ end
+
+ def division(from,to=nil)
+ from, to = converted(from), converted(to)
+ @max = [@max,to.length+1].max if to
+ @div[from] = to || from || ''
+ end
+
+ # shortcut("\\ab\\cd\\e\\f", 'iacute')
+ # shortcut("\\\'\\i", 'iacute')
+ # shortcut("\\\'i", 'iacute')
+ # shortcut("\\\"e", 'ediaeresis')
+ # shortcut("\\\'o", 'oacute')
+
+ def hextoutf(str)
+ str.gsub(/^(0x[A-F\d]+)$/) do
+ [$1.hex()].pack("U")
+ end
+ end
+
+ def shortcut(from,to)
+ from = hextoutf(from)
+ replacer(from,to)
+ expander(to)
+ end
+
+ def prepare
+ if @rep.size > 0 then
+ @rexa = /(#{@rep.keys.join('|')})/ # o
+ else
+ @rexa = nil
+ end
+ if @map.size > 0 then
+ # watch out, order of match matters
+ if @@downcase then
+ @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/i # o
+ else
+ @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/ # o
+ end
+ else
+ if @@downcase then
+ @rexb = /(\\[a-zA-Z]+|.)\s*/io
+ else
+ @rexb = /(\\[a-zA-Z]+|.)\s*/o
+ end
+ end
+ if false then
+ @exp.keys.each do |e|
+ @exp[e].downcase!
+ end
+ end
+ end
+
+ def replace(str)
+ if @rexa then
+ str.gsub(@rexa) do
+ @rep[$1.escaped]
+ end
+ else
+ str
+ end
+ end
+
+ def normalize(str)
+ # replace(str).gsub(/ +/,' ')
+ replace(str).gsub(/\s\s+/," \\space")
+ end
+
+ def tokenize(str)
+ if str then
+ str.gsub(/\\strchr\{(.*?)\}/o) do "\\#{$1}" end
+ else
+ ""
+ end
+ end
+
+ def remap(str)
+ s = str.dup
+ if true then # numbers are treated special
+ s.gsub!(/(\d+)/o) do
+ $1.rjust(10,'a') # rest is b .. k
+ end
+ end
+ if @rexa then
+ s.gsub!(@rexa) do
+ @rep[$1.escaped]
+ end
+ end
+ if @rexb then
+ s.gsub!(@rexb) do
+ token = $1.sub(/\\/o, '')
+ if @@downcase then
+ token.downcase!
+ end
+ if @exp.key?(token) then
+ @exp[token].ljust(@max,' ')
+ elsif @map.key?(token) then
+ @map[token].ljust(@max,' ')
+ else
+ ''
+ end
+ end
+ end
+ s
+ end
+
+ def preset(shortcuts=[],expansions=[],reductions=[],divisions=[],language='')
+ 'a'.upto('z') do |c| expander(c) ; division(c) end
+ 'A'.upto('Z') do |c| expander(c) ; division(c) end
+ expander('1','b') ; expander('2','c') ; expander('3','e') ; expander('4','f')
+ expander('5','g') ; expander('6','h') ; expander('7','i') ; expander('8','i')
+ expander('9','j') ; expander('0','a') ; expander('-','-') ;
+ shortcuts.each do |s| shortcut(s[1],s[2]) if s[0] == '' || s[0] == language end
+ expansions.each do |e| expander(e[1],e[2]) if e[0] == '' || e[0] == language end
+ reductions.each do |r| reducer(r[1],r[2]) if r[0] == '' || r[0] == language end
+ divisions.each do |d| division(d[1],d[2]) if d[0] == '' || d[0] == language end
+ end
+
+ def simplify(str)
+ s = str.dup
+ # ^^
+ # s.gsub!(/\^\^([a-f0-9][a-f0-9])/o, $1.hex.chr)
+ # \- ||
+ s.gsub!(/(\\\-|\|\|)/o) do '-' end
+ # {}
+ s.gsub!(/\{\}/o) do '' end
+ # <*..> (internal xml entity)
+ s.gsub!(/<\*(.*?)>/o) do $1 end
+ # entities
+ s.gsub!(/\\getXMLentity\s*\{(.*?)\}/o) do $1 end
+ # elements
+ s.gsub!(/\<.*?>/o) do '' end
+ # what to do with xml and utf-8
+ # \"e etc
+ # unknown \cs
+ s.gsub!(/\\[a-zA-Z][a-zA-Z]+\s*\{(.*?)\}/o) do $1 end
+ return s
+ end
+
+ def getdivision(str)
+ @div[str] || str
+ end
+
+ def division?(str)
+ @div.key?(str)
+ end
+
+ private
+
+ def converted(str)
+ if str then
+ # puts str
+ str.gsub(/([\+\-]*\d+)/o) do
+ n = $1.to_i
+ if n > 0 then
+ 'z'*n
+ elsif n < 0 then
+ '-'*(-n) # '-' precedes 'a'
+ else
+ ''
+ end
+ end
+ else
+ nil
+ end
+ end
+
+ end
+
+ class Plugin
+
+ module MyFiles
+
+ @@files, @@temps = Hash.new, Hash.new
+
+ def MyFiles::reset(logger)
+ @@files, @@temps = Hash.new, Hash.new
+ end
+
+ def MyFiles::reader(logger,data)
+ case data[0]
+ when 'b', 'e' then
+ @@files[data[1]] = (@@files[data[1]] ||0) + 1
+ when 't' then # temporary file
+ @@temps[data[1]] = (@@temps[data[1]] ||0) + 1
+ end
+ end
+
+ def MyFiles::writer(logger,handle)
+ handle << logger.banner("loaded files: #{@@files.size}")
+ @@files.keys.sort.each do |k|
+ handle << "% > #{k} #{@@files[k]/2}\n"
+ end
+ handle << logger.banner("temporary files: #{@@temps.size}")
+ @@temps.keys.sort.each do |k|
+ handle << "% > #{k} #{@@temps[k]}\n"
+ end
+ end
+
+ def MyFiles::processor(logger)
+ @@files.keys.sort.each do |k|
+ unless (@@files[k] % 2) == 0 then
+ logger.report("check loading of file '#{k}', begin/end problem")
+ end
+ end
+ @@temps.keys.sort.each do |k|
+ # logger.report("temporary file '#{k}' can be deleted")
+ end
+ end
+
+ def MyFiles::finalizer(logger)
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyCommands
+
+ @@commands = []
+
+ def MyCommands::reset(logger)
+ @@commands = []
+ end
+
+ def MyCommands::reader(logger,data)
+ @@commands.push(data.shift+data.collect do |d| "\{#{d}\}" end.join)
+ end
+
+ def MyCommands::writer(logger,handle)
+ handle << logger.banner("commands: #{@@commands.size}")
+ @@commands.each do |c|
+ handle << "#{c}%\n"
+ end
+ end
+
+ def MyCommands::processor(logger)
+ end
+
+ def MyCommands::finalizer(logger)
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyExtras
+
+ @@programs = []
+
+ def MyExtras::reset(logger)
+ @@programs = []
+ end
+
+ def MyExtras::reader(logger,data)
+ case data[0]
+ when 'p' then
+ @@programs.push(data[1]) if data[0]
+ end
+ end
+
+ def MyExtras::writer(logger,handle)
+ handle << logger.banner("programs: #{@@programs.size}")
+ @@programs.each_with_index do |cmd, p|
+ handle << "% #{p+1} (#{cmd})\n"
+ end
+ end
+
+ def MyExtras::processor(logger)
+ @@programs.each do |p|
+ # cmd = @@programs[p.to_i]
+ # logger.report("running #{cmd}")
+ # system(cmd)
+ end
+ end
+
+ def MyExtras::finalizer(logger)
+ unless (ENV["CTX.TEXUTIL.EXTRAS"] =~ /^(no|off|false|0)$/io) || (ENV["CTX_TEXUTIL_EXTRAS"] =~ /^(no|off|false|0)$/io) then
+ @@programs.each do |cmd|
+ logger.report("running #{cmd}")
+ system(cmd)
+ end
+ end
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MySynonyms
+
+ class Synonym
+
+ @@debug = false
+
+ def initialize(t, c, k, d)
+ @type, @command, @key, @sortkey, @data = t, c, k, c, d
+ end
+
+ attr_reader :type, :command, :key, :data
+ attr_reader :sortkey
+ attr_writer :sortkey
+
+ # def build(sorter)
+ # if @key then
+ # @sortkey = sorter.normalize(sorter.tokenize(@sortkey))
+ # @sortkey = sorter.remap(sorter.simplify(@key.downcase)) # ??
+ # if @sortkey.empty? then
+ # @sortkey = sorter.remap(@command.downcase)
+ # end
+ # else
+ # @key = ""
+ # @sortkey = ""
+ # end
+ # end
+
+ def build(sorter)
+ if @sortkey and not @sortkey.empty? then
+ @sortkey = sorter.normalize(sorter.tokenize(@sortkey))
+ @sortkey = sorter.remap(sorter.simplify(@sortkey.downcase)) # ??
+ end
+ if not @sortkey or @sortkey.empty? then
+ @sortkey = sorter.normalize(sorter.tokenize(@key))
+ @sortkey = sorter.remap(sorter.simplify(@sortkey.downcase)) # ??
+ end
+ if not @sortkey or @sortkey.empty? then
+ @sortkey = @key.dup
+ end
+ end
+
+ def <=> (other)
+ @sortkey <=> other.sortkey
+ end
+
+ def Synonym.flush(list,handle)
+ if @@debug then
+ list.each do |entry|
+ handle << "% [#{entry.sortkey}]\n"
+ end
+ end
+ list.each do |entry|
+ handle << "\\synonymentry{#{entry.type}}{#{entry.command}}{#{entry.key}}{#{entry.data}}%\n"
+ end
+ end
+
+ end
+
+ @@synonyms = Hash.new
+ @@sorter = Hash.new
+ @@languages = Hash.new
+
+ def MySynonyms::reset(logger)
+ @@synonyms = Hash.new
+ @@sorter = Hash.new
+ @@languages = Hash.new
+ end
+
+ def MySynonyms::reader(logger,data)
+ case data[0]
+ when 'e' then
+ @@synonyms[data[1]] = Array.new unless @@synonyms.key?(data[1])
+ @@synonyms[data[1]].push(Synonym.new(data[1],data[2],data[3],data[4]))
+ when 'l' then
+ @@languages[data[1]] = data[2] || ''
+ end
+ end
+
+ def MySynonyms::writer(logger,handle)
+ if @@synonyms.size > 0 then
+ @@synonyms.keys.sort.each do |s|
+ handle << logger.banner("synonyms: #{s} #{@@synonyms[s].size}")
+ Synonym.flush(@@synonyms[s],handle)
+ end
+ end
+ end
+
+ def MySynonyms::processor(logger)
+ @@synonyms.keys.each do |s|
+ @@sorter[s] = Sorter.new
+ @@sorter[s].preset(
+ eval("MyKeys").shortcuts,
+ eval("MyKeys").expansions,
+ eval("MyKeys").reductions,
+ eval("MyKeys").divisions,
+ @@languages[s] || '')
+ @@sorter[s].prepare
+ @@synonyms[s].each_index do |i|
+ @@synonyms[s][i].build(@@sorter[s])
+ end
+ @@synonyms[s] = @@synonyms[s].sort
+ end
+ end
+
+ def MySynonyms::finalizer(logger)
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyRegisters
+
+ class Register
+
+ @@specialsymbol = "\000"
+ @@specialbanner = "" # \\relax"
+
+ @@debug = false
+
+ @@howto = /^(.*?)\:\:(.*)$/o
+ @@split = ' && '
+
+ def initialize(state, t, l, k, e, s, p, r)
+ @state, @type, @location, @key, @entry, @seetoo, @page, @realpage = state, t, l, k, e, s, p, r
+ if @key =~ @@howto then @pagehowto, @key = $1, $2 else @pagehowto = '' end
+ if @entry =~ @@howto then @texthowto, @entry = $1, $2 else @texthowto = '' end
+ @key = @entry.dup if @key.empty?
+ @sortkey = @key.dup
+ @nofentries, @nofpages = 0, 0
+ @normalizeentry = false
+ end
+
+ attr_reader :state, :type, :location, :key, :entry, :seetoo, :page, :realpage, :texthowto, :pagehowto
+ attr_reader :sortkey
+ attr_writer :sortkey
+
+ def build(sorter)
+ # @entry, @key = sorter.normalize(@entry), sorter.normalize(sorter.tokenize(@key))
+ @entry = sorter.normalize(sorter.tokenize(@entry)) if @normalizeentry
+ @key = sorter.normalize(sorter.tokenize(@key))
+ if false then
+ @entry, @key = [@entry, @key].collect do |target|
+ # +a+b+c &a&b&c a+b+c a&b&c
+ case target[0,1]
+ when '&' then target = target.sub(/^./o,'').gsub(/([^\\])\&/o) do "#{$1}#{@@split}" end
+ when '+' then target = target.sub(/^./o,'').gsub(/([^\\])\+/o) do "#{$1}#{@@split}" end
+ else target = target .gsub(/([^\\])[\&\+]/o) do "#{$1}#{@@split}" end
+ end
+ # {a}{b}{c}
+ # if target =~ /^\{(.*)\}$/o then
+ # $1.split(/\} \{/o).join(@@split) # space between } { is mandate
+ # else
+ target
+ # end
+ end
+ else
+ # @entry, @key = cleanupsplit(@entry), cleanupsplit(@key)
+ @entry, @key = cleanupsplit(@entry), xcleanupsplit(@key)
+ end
+ @sortkey = sorter.simplify(@key)
+ # special = @sortkey =~ /^([^a-zA-Z\\])/o
+ special = @sortkey =~ /^([\`\~\!\@\#\$\%\^\&\*\(\)\_\-\+\=\{\}\[\]\:\;\"\'\|\<\,\>\.\?\/\d])/o
+ @sortkey = @sortkey.split(@@split).collect do |c| sorter.remap(c) end.join(@@split)
+ if special then
+ @sortkey = "#{@@specialsymbol}#{@sortkey}"
+ end
+ if @realpage == 0 then
+ @realpage = 999999
+ end
+ @sortkey = [
+ @sortkey.downcase,
+ @sortkey,
+ @entry,
+ @texthowto.ljust(10,' '),
+ # @state, # no, messes up things
+ (@realpage.to_s || '').rjust(6,' ').gsub(/0/,' '),
+ # (@realpage ||'').rjust(6,' '),
+ @pagehowto
+ ].join(@@split)
+ end
+
+ def cleanupsplit(target)
+ # +a+b+c &a&b&c a+b+c a&b&c
+ case target[0,1]
+ when '&' then target.sub(/^./o,'').gsub(/([^\\])\&/o) do "#{$1}#{@@split}" end
+ when '+' then target.sub(/^./o,'').gsub(/([^\\])\+/o) do "#{$1}#{@@split}" end
+ else target .gsub(/([^\\])[\&\+]/o) do "#{$1}#{@@split}" end
+ end
+ end
+
+ def xcleanupsplit(target) # +a+b+c &a&b&c a+b+c a&b&c
+ t = Array.new
+ case target[0,1]
+ when '&' then
+ t = target.sub(/^./o,'').split(/([^\\])\&/o)
+ when '+' then
+ t = target.sub(/^./o,'').split(/([^\\])\+/o)
+ else
+ # t = target.split(/([^\\])[\&\+]/o)
+ # t = target.split(/[\&\+]/o)
+ t = target.split(/(?!\\)[\&\+]/o) # lookahead
+ end
+ if not t[1] then t[1] = " " end # we need some entry else we get subentries first
+ if not t[2] then t[2] = " " end # we need some entry else we get subentries first
+ if not t[3] then t[3] = " " end # we need some entry else we get subentries first
+ return t.join(@@split)
+ end
+ def <=> (other)
+ @sortkey <=> other.sortkey
+ end
+
+ # more module like
+
+ @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', '', ''
+ @@collapse = false
+
+ def Register.flushsavedline(handle)
+ if @@collapse && ! @@savedfrom.empty? then
+ if ! @@savedto.empty? then
+ handle << "\\registerfrom#{@@savedfrom}%"
+ handle << "\\registerto#{@@savedto}%"
+ else
+ handle << "\\registerpage#{@@savedfrom}%"
+ end
+ end
+ @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', ''
+ end
+
+ def Register.flush(list,handle,sorter)
+ # a bit messy, quite old mechanism, maybe some day ...
+ # alphaclass can go, now flushed per class
+ if list.size > 0 then
+ @nofentries, @nofpages = 0, 0
+ current, previous, howto = Array.new, Array.new, Array.new
+ lastpage, lastrealpage = '', ''
+ alphaclass, alpha = '', ''
+ @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', ''
+ if @@debug then
+ list.each do |entry|
+ handle << "% [#{entry.sortkey.gsub(/#{@@split}/o,'] [')}]\n"
+ end
+ end
+ list.each do |entry|
+# puts(entry.sortkey.gsub(/\s+/,""))
+ if entry.sortkey =~ /^(\S+)/o then
+ if sorter.division?($1) then
+ testalpha = sorter.getdivision($1)
+ else
+ testalpha = entry.sortkey[0,1].downcase
+ end
+ else
+ testalpha = entry.sortkey[0,1].downcase
+ end
+ if (testalpha != alpha.downcase) || (alphaclass != entry.class) then
+ alpha = testalpha
+ alphaclass = entry.class
+ if alpha != ' ' then
+ flushsavedline(handle)
+ if alpha =~ /^[a-zA-Z]$/o then
+ character = alpha.dup
+ elsif alpha == @@specialsymbol then
+ character = @@specialbanner
+ elsif alpha.length > 1 then
+ # character = "\\getvalue\{#{alpha}\}"
+ character = "\\#{alpha}"
+ else
+ character = "\\unknown"
+ end
+ handle << "\\registerentry{#{entry.type}}{#{character}}%\n"
+ end
+ end
+ current = [entry.entry.split(@@split),'','','',''].flatten
+ howto = current.collect do |e|
+ e + '::' + entry.texthowto
+ end
+ if howto[0] == previous[0] then
+ current[0] = ''
+ else
+ previous[0] = howto[0].dup
+ previous[1] = ''
+ previous[2] = ''
+ previous[3] = ''
+ end
+ if howto[1] == previous[1] then
+ current[1] = ''
+ else
+ previous[1] = howto[1].dup
+ previous[2] = ''
+ previous[3] = ''
+ end
+ if howto[2] == previous[2] then
+ current[2] = ''
+ else
+ previous[2] = howto[2].dup
+ previous[3] = ''
+ end
+ if howto[3] == previous[3] then
+ current[3] = ''
+ else
+ previous[3] = howto[3].dup
+ end
+ copied = false
+ unless current[0].empty? then
+ Register.flushsavedline(handle)
+ handle << "\\registerentrya{#{entry.type}}{#{current[0]}}%\n"
+ copied = true
+ end
+ unless current[1].empty? then
+ Register.flushsavedline(handle)
+ handle << "\\registerentryb{#{entry.type}}{#{current[1]}}%\n"
+ copied = true
+ end
+ unless current[2].empty? then
+ Register.flushsavedline(handle)
+ handle << "\\registerentryc{#{entry.type}}{#{current[2]}}%\n"
+ copied = true
+ end
+ unless current[3].empty? then
+ Register.flushsavedline(handle)
+ handle << "\\registerentryd{#{entry.type}}{#{current[3]}}%\n"
+ copied = true
+ end
+ @nofentries += 1 if copied
+ # if entry.realpage.to_i == 0 then
+ if entry.realpage.to_i == 999999 then
+ Register.flushsavedline(handle)
+ handle << "\\registersee{#{entry.type}}{#{entry.pagehowto},#{entry.texthowto}}{#{entry.seetoo}}{#{entry.page}}%\n" ;
+ lastpage, lastrealpage = entry.page, entry.realpage
+ copied = false # no page !
+ elsif @@savedhowto != entry.pagehowto and ! entry.pagehowto.empty? then
+ @@savedhowto = entry.pagehowto
+ end
+ # beware, we keep multiple page entries per realpage because of possible prefix usage
+ if copied || ! ((lastpage == entry.page) && (lastrealpage == entry.realpage)) then
+ nextentry = "{#{entry.type}}{#{previous[0]}}{#{previous[1]}}{#{previous[2]}}{#{previous[3]}}{#{entry.pagehowto},#{entry.texthowto}}"
+ savedline = "{#{entry.type}}{#{@@savedhowto},#{entry.texthowto}}{#{entry.location}}{#{entry.page}}{#{entry.realpage}}"
+ if entry.state == 1 then # from
+ Register.flushsavedline(handle)
+ handle << "\\registerfrom#{savedline}%\n"
+ elsif entry.state == 3 then # to
+ Register.flushsavedline(handle)
+ handle << "\\registerto#{savedline}%\n"
+ @@savedhowto = '' # test
+ elsif @@collapse then
+ if savedentry != nextentry then
+ savedFrom = savedline
+ else
+ savedTo, savedentry = savedline, nextentry
+ end
+ else
+ handle << "\\registerpage#{savedline}%\n"
+ @@savedhowto = '' # test
+ end
+ @nofpages += 1
+ lastpage, lastrealpage = entry.page, entry.realpage
+ end
+ end
+ Register.flushsavedline(handle)
+ end
+ end
+
+ end
+
+ @@registers = Hash.new
+ @@sorter = Hash.new
+ @@languages = Hash.new
+
+ def MyRegisters::reset(logger)
+ @@registers = Hash.new
+ @@sorter = Hash.new
+ @@languages = Hash.new
+ end
+
+ def MyRegisters::reader(logger,data)
+ case data[0]
+ when 'f' then
+ @@registers[data[1]] = Array.new unless @@registers.key?(data[1])
+ @@registers[data[1]].push(Register.new(1,data[1],data[2],data[3],data[4],nil,data[5],data[6]))
+ when 'e' then
+ @@registers[data[1]] = Array.new unless @@registers.key?(data[1])
+ @@registers[data[1]].push(Register.new(2,data[1],data[2],data[3],data[4],nil,data[5],data[6]))
+ when 't' then
+ @@registers[data[1]] = Array.new unless @@registers.key?(data[1])
+ @@registers[data[1]].push(Register.new(3,data[1],data[2],data[3],data[4],nil,data[5],data[6]))
+ when 's' then
+ @@registers[data[1]] = Array.new unless @@registers.key?(data[1])
+ # was this but wrong sort order (4,data[1],data[2],data[3],data[4],data[5],data[6],nil))
+ @@registers[data[1]].push(Register.new(4,data[1],data[2],data[3],data[4],data[5],data[6],0))
+ when 'l' then
+ @@languages[data[1]] = data[2] || ''
+ end
+ end
+
+ def MyRegisters::writer(logger,handle)
+ if @@registers.size > 0 then
+ @@registers.keys.sort.each do |s|
+ handle << logger.banner("registers: #{s} #{@@registers[s].size}")
+ Register.flush(@@registers[s],handle,@@sorter[s])
+ # report("register #{@@registers[s].class}: #{@@registers[s].@nofentries} entries and #{@@registers[s].@nofpages} pages")
+ end
+ end
+ end
+
+ def MyRegisters::processor(logger)
+ @@registers.keys.each do |s|
+ @@sorter[s] = Sorter.new
+ @@sorter[s].preset(
+ eval("MyKeys").shortcuts,
+ eval("MyKeys").expansions,
+ eval("MyKeys").reductions,
+ eval("MyKeys").divisions,
+ @@languages[s] || '')
+ @@sorter[s].prepare
+ @@registers[s].each_index do |i|
+ @@registers[s][i].build(@@sorter[s])
+ end
+ # @@registers[s].uniq!
+ @@registers[s] = @@registers[s].sort
+ end
+ end
+
+ def MyRegisters::finalizer(logger)
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyPlugins
+
+ @@plugins = nil
+
+ def MyPlugins::reset(logger)
+ @@plugins = nil
+ end
+
+ def MyPlugins::reader(logger,data)
+ @@plugins = Plugin.new(logger) unless @@plugins
+ case data[0]
+ when 'r' then
+ logger.report("registering plugin #{data[1]}")
+ @@plugins.register(data[1],data[2])
+ when 'd' then
+ begin
+ @@plugins.reader(data[1],data[2,data.length-1])
+ rescue
+ @@plugins.reader(data[1],['error'])
+ end
+ end
+ end
+
+ def MyPlugins::writer(logger,handle)
+ @@plugins.writers(handle) if @@plugins
+ end
+
+ def MyPlugins::processor(logger)
+ @@plugins.processors if @@plugins
+ end
+
+ def MyPlugins::finalizer(logger)
+ @@plugins.finalizers if @@plugins
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyKeys
+
+ @@shortcuts = Array.new
+ @@expansions = Array.new
+ @@reductions = Array.new
+ @@divisions = Array.new
+
+ def MyKeys::shortcuts
+ @@shortcuts
+ end
+ def MyKeys::expansions
+ @@expansions
+ end
+ def MyKeys::reductions
+ @@reductions
+ end
+ def MyKeys::divisions
+ @@divisions
+ end
+
+ def MyKeys::reset(logger)
+ @@shortcuts = Array.new
+ @@expansions = Array.new
+ @@reductions = Array.new
+ end
+
+ def MyKeys::reader(logger,data)
+ key = data.shift
+ # grp = data.shift # language code, todo
+ case key
+ when 's' then @@shortcuts.push(data)
+ when 'e' then @@expansions.push(data)
+ when 'r' then @@reductions.push(data)
+ when 'd' then @@divisions.push(data)
+ end
+ end
+
+ def MyKeys::writer(logger,handle)
+ end
+
+ def MyKeys::processor(logger)
+ logger.report("shortcuts : #{@@shortcuts.size}") # logger.report(@@shortcuts.inspect)
+ logger.report("expansions: #{@@expansions.size}") # logger.report(@@expansions.inspect)
+ logger.report("reductions: #{@@reductions.size}") # logger.report(@@reductions.inspect)
+ logger.report("divisions : #{@@divisions.size}") # logger.report(@@divisions.inspect)
+ end
+
+ def MyKeys::finalizer(logger)
+ end
+
+ end
+
+ end
+
+ class Converter
+
+ def initialize(logger=nil)
+ if @logger = logger then
+ def report(str)
+ @logger.report(str)
+ end
+ def banner(str)
+ @logger.banner(str)
+ end
+ else
+ @logger = self
+ def report(str)
+ puts(str)
+ end
+ def banner(str)
+ puts(str)
+ end
+ end
+ @filename = 'texutil'
+ @fatalerror = false
+ @plugins = Plugin.new(@logger)
+ ['MyFiles', 'MyCommands', 'MySynonyms', 'MyRegisters', 'MyExtras', 'MyPlugins', 'MyKeys'].each do |p|
+ @plugins.register(p)
+ end
+ end
+
+ def loaded(filename)
+ begin
+ tuifile = File.suffixed(filename,'tui')
+ if FileTest.file?(tuifile) then
+ report("parsing file #{tuifile}")
+ if f = File.open(tuifile,'rb') then
+ f.each do |line|
+ case line.chomp
+ when /^f (.*)$/o then @plugins.reader('MyFiles', $1.splitdata)
+ when /^c (.*)$/o then @plugins.reader('MyCommands', [$1])
+ when /^e (.*)$/o then @plugins.reader('MyExtras', $1.splitdata)
+ when /^s (.*)$/o then @plugins.reader('MySynonyms', $1.splitdata)
+ when /^r (.*)$/o then @plugins.reader('MyRegisters',$1.splitdata)
+ when /^p (.*)$/o then @plugins.reader('MyPlugins', $1.splitdata)
+ when /^x (.*)$/o then @plugins.reader('MyKeys', $1.splitdata)
+ when /^r (.*)$/o then # nothing, not handled here
+ else
+ # report("unknown entry #{line[0,1]} in line #{line.chomp}")
+ end
+ end
+ f.close
+ end
+ else
+ report("unable to locate #{tuifile}")
+ end
+ rescue
+ report("fatal error in parsing #{tuifile}")
+ @filename = 'texutil'
+ else
+ @filename = filename
+ end
+ end
+
+ def processed
+ @plugins.processors
+ return true # for the moment
+ end
+
+ def saved(filename=@filename)
+ if @fatalerror then
+ report("fatal error, no tuo file saved")
+ return false
+ else
+ begin
+ if f = File.open(File.suffixed(filename,'tuo'),'w') then
+ @plugins.writers(f)
+ f << "\\endinput\n"
+ f.close
+ end
+ rescue
+ report("fatal error when saving file (#{$!})")
+ return false
+ else
+ report("tuo file saved")
+ return true
+ end
+ end
+ end
+
+ def finalized
+ @plugins.finalizers
+ @plugins.resets
+ return true # for the moment
+ end
+
+ def reset
+ @plugins.resets
+ end
+
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/tool.rb b/Master/texmf-dist/scripts/context/ruby/base/tool.rb
new file mode 100644
index 00000000000..1f10c955654
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/tool.rb
@@ -0,0 +1,291 @@
+# module : base/tool
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+require 'timeout'
+require 'socket'
+require 'rbconfig'
+
+module Tool
+
+ $constructedtempdir = ''
+
+ def Tool.constructtempdir(create,mainpath='',fallback='')
+ begin
+ mainpath += '/' unless mainpath.empty?
+ timeout(5) do
+ begin
+ t = Time.now
+ u = t.usec.to_s % [1..2] [0..3]
+ pth = t.strftime("#{mainpath}%Y%m%d-%H%M%S-#{u}-#{Process.pid}")
+ #
+ # problems with 1.9
+ #
+ # if pth == $constructedtempdir
+ # # sleep(0.01)
+ # retry
+ # end
+ pth == $constructedtempdir
+ #
+ Dir.mkdir(pth) if create
+ $constructedtempdir = pth
+ return pth
+ rescue
+ # sleep(0.01)
+ retry
+ end
+ end
+ rescue TimeoutError
+ # ok
+ rescue
+ # ok
+ end
+ unless fallback.empty?
+ begin
+ pth = "#{mainpath}#{fallback}"
+ mkdir(pth) if create
+ $constructedtempdir = path
+ return pth
+ rescue
+ return '.'
+ end
+ else
+ return '.'
+ end
+
+ end
+
+ def Tool.findtempdir(*vars)
+ constructtempdir(false,*vars)
+ end
+
+ def Tool.maketempdir(*vars)
+ constructtempdir(true,*vars)
+ end
+
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+
+
+ def Tool.ruby_platform
+ case RUBY_PLATFORM
+ when /(mswin|bccwin|mingw|cygwin)/i then 'mswin'
+ when /(linux)/i then 'linux'
+ when /(netbsd|unix)/i then 'unix'
+ when /(darwin|rhapsody|nextstep)/i then 'macosx'
+ else 'unix'
+ end
+ end
+
+ $defaultlineseparator = $/ # $RS in require 'English'
+
+ def Tool.file_platform(filename)
+
+ begin
+ if f = open(filename,'rb') then
+ str = f.read(4000)
+ str.gsub!(/(.*?)\%\!PS/mo, "%!PS") # don't look into preamble crap
+ f.close
+ nn = str.count("\n")
+ nr = str.count("\r")
+ if nn>nr then
+ return 2
+ elsif nn<nr then
+ return 3
+ else
+ return 1
+ end
+ else
+ return 0
+ end
+ rescue
+ return 0
+ end
+
+ end
+
+ def Tool.path_separator
+ return File::PATH_SEPARATOR
+ end
+
+ def Tool.line_separator(filename)
+
+ case file_platform(filename)
+ when 1 then return $defaultlineseparator
+ when 2 then return "\n"
+ when 3 then return "\r"
+ else return $defaultlineseparator
+ end
+
+ end
+
+ def Tool.default_line_separator
+ $defaultlineseparator
+ end
+
+ def Tool.simplefilename(old)
+
+ return old # too fragile
+
+ return old if not FileTest.file?(old)
+
+ new = old.downcase
+ new.gsub!(/[^A-Za-z0-9\_\-\.\\\/]/o) do # funny chars
+ '-'
+ end
+ if old =~ /[a-zA-Z]\:/o
+ # seems like we have a dos/windows drive prefix, so roll back
+ new.sub!(/^(.)\-/) do
+ $1 + ':'
+ end
+ end
+ # fragile for a.b.c.d.bla-bla.e.eps
+ # new.gsub!(/(.+?)\.(.+?)(\..+)$/o) do # duplicate .
+ # $1 + '-' + $2 + $3
+ # end
+ new.gsub!(/\-+/o) do # duplicate -
+ '-'
+ end
+ new
+
+ end
+
+ if RbConfig::CONFIG['host_os'] =~ /mswin/ then
+
+ require 'Win32API'
+
+ GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', ['P','P','N'], 'N')
+ GetLongPathName = Win32API.new('kernel32', 'GetLongPathName', ['P','P','N'], 'N')
+
+ def Tool.dowith_pathname (filename,filemethod)
+ filename.gsub!(/\\/o,'/')
+ case filename
+ when /\;/o then
+ # could be a path spec
+ return filename
+ when /\s+/o then
+ # danger lurking
+ buffer = ' ' * 260
+ length = filemethod.call(filename,buffer,buffer.size)
+ if length>0 then
+ return buffer.slice(0..length-1)
+ else
+ # when the path or file does not exist, nothing is returned
+ # so we try to handle the path separately from the basename
+ basename = File.basename(filename)
+ pathname = File.dirname(filename)
+ length = filemethod.call(pathname,buffer,260)
+ if length>0 then
+ return buffer.slice(0..length-1) + '/' + basename
+ else
+ return filename
+ end
+ end
+ else
+ # no danger
+ return filename
+ end
+ end
+
+ def Tool.shortpathname(filename)
+ dowith_pathname(filename,GetShortPathName)
+ end
+
+ def Tool.longpathname(filename)
+ dowith_pathname(filename,GetLongPathName)
+ end
+
+ else
+
+ def Tool.shortpathname(filename)
+ filename
+ end
+
+ def Tool.longpathname(filename)
+ filename
+ end
+
+ end
+
+ # print shortpathname("C:/Program Files/ABBYY FineReader 6.0/matrix.str")+ "!\n"
+ # print shortpathname("C:/Program Files/ABBYY FineReader 6.0/matrix.strx")+ "!\n"
+
+ def Tool.checksuffix(old)
+
+ return old unless FileTest.file?(old)
+
+ new = old
+
+ unless new =~ /\./io # no suffix
+ f = open(filename,'rb')
+ if str = f.gets
+ case str
+ when /^\%\!PS/io
+ # logging.report(filename, 'analyzed as EPS')
+ new = new + '.eps'
+ when /^\%PDF/io
+ # logging.report(filename, 'analyzed as PDF')
+ new = new + '.pdf'
+ else
+ # logging.report(filename, 'fallback as TIF')
+ new = new + '.tif'
+ end
+ end
+ f.close
+ end
+
+ new.sub!(/\.jpeg$/io) do
+ '.jpg'
+ end
+ new.sub!(/\.tiff$/io) do
+ '.tif'
+ end
+ new.sub!(/\.ai$/io) do
+ '.eps'
+ end
+ new.sub!(/\.ai([a-z0-9]*)$/io) do
+ '-' + $1 + '.eps'
+ end
+ new
+
+ end
+
+ def Tool.cleanfilename(old,logging=nil)
+
+ return old if not FileTest.file?(old)
+
+ new = checksuffix(simplefilename(old))
+ unless new == old
+ begin # bugged, should only be name, not path
+ File.rename(old,new)
+ logging.report("renaming fuzzy name #{old} to #{new}") unless logging
+ return old
+ rescue
+ logging.report("unable to rename fuzzy name #{old} to #{new}") unless logging
+ end
+ end
+ return new
+
+ end
+
+ def Tool.servername
+ host = Socket::gethostname
+ begin
+ Socket::gethostbyname(host)[0]
+ rescue
+ host
+ end
+ end
+
+ # print file_platform(ARGV[0])
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/base/variables.rb b/Master/texmf-dist/scripts/context/ruby/base/variables.rb
new file mode 100644
index 00000000000..403b57716f4
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/variables.rb
@@ -0,0 +1,132 @@
+# module : base/variables
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/tool','tool'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/tool'
+
+class Hash
+
+ def nothing?(id)
+ ! self[id] || self[id].empty?
+ end
+
+ def subset(pattern)
+ h = Hash.new
+ p = pattern.gsub(/([\.\:\-])/) do "\\#{$1}" end
+ r = /^#{p}/
+ self.keys.each do |k|
+ h[k] = self[k].dup if k =~ r
+ end
+ return h
+ end
+
+end
+
+class ExtendedHash < Hash
+
+ @@re_var_a = /\%(.*?)\%/
+ @@re_var_b = /\$\((.*?)\)/
+
+ def set(key,value='',resolve=true)
+ if value then
+ self[key] = if resolve then resolved(value.to_s) else value.to_s end
+ else
+ self[key] = ''
+ end
+ end
+
+ def replace(key,value='')
+ self[key] = value if self?(key)
+ end
+
+ def get(key,default='')
+ if self.key?(key) then self[key] else default end
+ end
+
+ def true?(key)
+ self[key] =~ /^(yes|on|true|enable|enabled|y|start)$/io rescue false
+ end
+
+ def resolved(str)
+ begin
+ str.to_s.gsub(@@re_var_a) do
+ self[$1] || ''
+ end.gsub(@@re_var_b) do
+ self[$1] || ''
+ end
+ rescue
+ str.to_s rescue ''
+ end
+ end
+
+ def check(key,default='')
+ if self.key?(key) then
+ if self[key].empty? then self[key] = (default || '') end
+ else
+ self[key] = (default || '')
+ end
+ end
+
+ def checked(key,default='')
+ if self.key?(key) then
+ if self[key].empty? then default else self[key] end
+ else
+ default
+ end
+ end
+
+ def empty?(key)
+ self[key].empty?
+ end
+
+ # def downcase(key)
+ # self[key].downcase!
+ # end
+
+end
+
+# the next one is obsolete so we need to replace things
+
+module Variables
+
+ def setvariable(key,value='')
+ @variables[key] = value
+ end
+
+ def replacevariable(key,value='')
+ @variables[key] = value if @variables.key?(key)
+ end
+
+ def getvariable(key,default='')
+ if @variables.key?(key) then @variables[key] else default end
+ end
+
+ def truevariable(key)
+ @variables[key] =~ /^(yes|on|true)$/io rescue false
+ end
+
+ def checkedvariable(str,default='')
+ if @variables.key?(key) then
+ if @variables[key].empty? then default else @variables[key] end
+ else
+ default
+ end
+ end
+
+ def report(*str)
+ @logger.report(*str)
+ end
+
+ def debug(*str)
+ @logger.debug(str)
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/concheck.rb b/Master/texmf-dist/scripts/context/ruby/concheck.rb
new file mode 100644
index 00000000000..3db3e5148bf
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/concheck.rb
@@ -0,0 +1,471 @@
+# Program : concheck (tex & context syntax checker)
+# Copyright : PRAGMA ADE / Hasselt NL / www.pragma-ade.com
+# Author : Hans Hagen
+# Version : 1.1 / 2003.08.18
+
+# remarks:
+#
+# - the error messages are formatted like tex's messages so that scite can see them
+# - begin and end tags are only tested on a per line basis because we assume clean sources
+# - maybe i'll add begin{something} ... end{something} checking
+
+# # example validation file
+#
+# begin interface en
+#
+# 1 text
+# 4 Question
+# 0 endinput
+# 0 setupsomething
+# 0 chapter
+#
+# end interface en
+
+# nicer
+
+# class Interface
+
+ # def initialize (language = 'unknown')
+ # @valid = Array.new
+ # @language = language
+ # end
+
+ # def register (left, right)
+ # @valid.push([left,right])
+ # end
+
+# end
+
+# $interfaces = Hash.new
+
+# $interfaces['en'] = Interface.new('english')
+# $interfaces['nl'] = Interface.new('dutch')
+
+# $interfaces['en'].add('\\\\start','\\\\stop')
+# $interfaces['en'].add('\\\\begin','\\\\end')
+# $interfaces['en'].add('\\\\Start','\\\\Stop')
+# $interfaces['en'].add('\\\\Begin','\\\\End')
+
+# $interfaces['nl'].add('\\\\start','\\\\stop')
+# $interfaces['nl'].add('\\\\beginvan','\\\\eindvan')
+# $interfaces['nl'].add('\\\\Start','\\\\Stop')
+# $interfaces['nl'].add('\\\\BeginVan','\\\\Eindvan')
+
+# rest todo
+
+$valid = Hash.new
+
+$valid['en'] = Array.new
+$valid['nl'] = Array.new
+
+#$valid['en'].push(['',''])
+$valid['en'].push(['\\\\start','\\\\stop'])
+$valid['en'].push(['\\\\begin','\\\\end'])
+$valid['en'].push(['\\\\Start','\\\\Stop'])
+$valid['en'].push(['\\\\Begin','\\\\End'])
+
+#$valid['nl'].push(['',''])
+$valid['nl'].push(['\\\\start','\\\\stop'])
+$valid['nl'].push(['\\\\beginvan','\\\\eindvan'])
+$valid['nl'].push(['\\\\Start','\\\\Stop'])
+$valid['nl'].push(['\\\\BeginVan','\\\\Eindvan'])
+
+$valid_tex = "\\\\end\(input|insert|csname|linechar|graf|buffer|strut\)"
+$valid_mp = "(enddef||end||endinput)"
+
+$start_verbatim = Hash.new
+$stop_verbatim = Hash.new
+
+$start_verbatim['en'] = '\\\\starttyping'
+$start_verbatim['nl'] = '\\\\starttypen'
+
+$stop_verbatim['en'] = '\\\\stoptyping'
+$stop_verbatim['nl'] = '\\\\stoptypen'
+
+def message(str, filename=nil, line=nil, column=nil)
+ if filename then
+ if line then
+ if column then
+ puts("error in file #{filename} at line #{line} in column #{column}: #{str}\n")
+ else
+ puts("error in file #{filename} at line #{line}: #{str}\n")
+ end
+ else
+ puts("file #{filename}: #{str}\n")
+ end
+ else
+ puts(str+"\n")
+ end
+end
+
+def load_file (filename='')
+ begin
+ data = IO.readlines(filename)
+ data.collect! do |d|
+ if d =~ /^\s*%/o then
+ ''
+ elsif d =~ /(.*?[^\\])%.*$/o then
+ $1
+ else
+ d
+ end
+ end
+ rescue
+ message("provide proper filename")
+ return nil
+ end
+ # print data.to_s + "\n"
+ return data
+end
+
+def guess_interface(data)
+ if data.first =~ /^%.*interface\=(.*)\s*/ then
+ return $1
+ else
+ data.each do |line|
+ case line
+ when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then return 'nl'
+ when /\\(stelle|verwende|umgebung|benutze)/o then return 'de'
+ when /\\(stel|gebruik|omgeving)/ then return 'nl'
+ when /\\(use|setup|environment)/ then return 'en'
+ when /\\(usa|imposta|ambiente)/ then return 'it'
+ when /(height|width|style)=/ then return 'en'
+ when /(hoehe|breite|schrift)=/ then return 'de'
+ when /(hoogte|breedte|letter)=/ then return 'nl'
+ when /(altezza|ampiezza|stile)=/ then return 'it'
+ when /externfiguur/ then return 'nl'
+ when /externalfigure/ then return 'en'
+ when /externeabbildung/ then return 'de'
+ when /figuraesterna/ then return 'it'
+ end
+ end
+ return 'en'
+ end
+end
+
+def cleanup_data(data, interface='en')
+ verbatim = 0
+ re_start = /^\s*#{$start_verbatim[interface]}/
+ re_stop = /^\s*#{$stop_verbatim[interface]}/
+ data.collect! do |d|
+ if d =~ re_start then
+ verbatim += 1
+ if verbatim>1 then
+ ''
+ else
+ d
+ end
+ elsif d =~ re_stop then
+ verbatim -= 1
+ if verbatim>0 then
+ ''
+ else
+ d
+ end
+ elsif verbatim > 0 then
+ ''
+ else
+ d
+ end
+ end
+ return data
+end
+
+def load_valid(data, interface=nil)
+ if data && (data.first =~ /^%.*valid\=(.*)\s*/)
+ filename = $1
+ filename = '../' + filename unless test(?f,filename)
+ filename = '../' + filename unless test(?f,filename)
+ if test(?f,filename) then
+ interface = guess_interface(data) unless interface
+ if $valid.has_key?(interface) then
+ interface = $valid[interface]
+ else
+ interface = $valid['en']
+ end
+ begin
+ message("loading validation file",filename)
+ validkeys = Hash.new
+ line = 1
+ IO.readlines(filename).each do |l|
+ if l =~ /\s+[\#\%]/io then
+ # ignore line
+ elsif l =~ /^\s*(begin|end)\s+interface\s+([a-z][a-z])/o then
+ # not yet supported
+ elsif l =~ /^\s*(\d+)\s+([a-zA-Z]*)$/o then
+ type, key = $1.to_i, $2.strip
+ if interface[type] then
+ validkeys[interface[type].first+key] = true
+ validkeys[interface[type].last+key] = true
+ else
+ error_message(filename,line,nil,'wrong definition')
+ end
+ end
+ line += 1
+ end
+ if validkeys then
+ message("#{validkeys.length} validation keys loaded",filename)
+ end
+ return validkeys
+ rescue
+ message("invalid validation file",filename)
+ end
+ else
+ message("unknown validation file", filename)
+ end
+ else
+ message("no extra validation file specified")
+ end
+ return nil
+end
+
+def some_chr_error(data, filename, left, right)
+ levels = Array.new
+ for line in 0..data.length-1 do
+ str = data[line]
+ # str = data[line].gsub(/\\[\#{left}\#{right}]/,'')
+ column = 0
+ while column<str.length do
+ case str[column].chr
+ when "\%" then
+ break
+ when "\\" then
+ column += 2
+ when left then
+ levels.push([line,column])
+ column += 1
+ when right then
+ if levels.pop
+ column += 1
+ else
+ message("missing #{left} for #{right}",filename,line+1,column+1)
+ return true
+ end
+ else
+ column += 1
+ end
+ end
+ end
+ if levels && levels.length>0 then
+ levels.each do |l|
+ column = l.pop
+ line = l.pop
+ message("missing #{right} for #{left}",filename,line+1,column+1)
+ end
+ return true
+ else
+ return false
+ end
+end
+
+def some_wrd_error(data, filename, start, stop, ignore)
+ levels = Array.new
+ len = 0
+ re_start = /[^\%]*(#{start})([a-zA-Z]*)/
+ re_stop = /[^\%]*(#{stop})([a-zA-Z]*)/
+ re_ignore = /#{ignore}.*/
+ str_start = start.gsub(/\\+/,'\\')
+ str_stop = stop.gsub(/\\+/,'\\')
+ line = 0
+ while line<data.length do
+ dataline = data[line].split(/[^\\A-Za-z]/)
+ if dataline.length>0 then
+ # todo: more on one line
+ dataline.each do |dataword|
+ case dataword
+ when re_ignore then
+ # just go on
+ when re_start then
+ levels.push([line,$2])
+ # print ' '*levels.length + '>' + $2 + "\n"
+ when re_stop then
+ # print ' '*levels.length + '<' + $2 + "\n"
+ if levels && levels.last && (levels.last[1] == $2) then
+ levels.pop
+ elsif levels && levels.last then
+ message("#{str_stop}#{levels.last[1]} expected instead of #{str_stop}#{$2}",filename,line+1)
+ return true
+ else
+ message("missing #{str_start}#{$2} for #{str_stop}#{$2}",filename,line+1)
+ return true
+ end
+ else
+ # just go on
+ end
+ end
+ end
+ line += 1
+ end
+ if levels && levels.length>0 then
+ levels.each do |l|
+ text = l.pop
+ line = l.pop
+ message("missing #{str_stop}#{text} for #{str_start}#{text}",filename,line+1)
+ end
+ return true
+ else
+ return false
+ end
+end
+
+def some_sym_error (data, filename, symbol, template=false)
+ saved = Array.new
+ inside = false
+ level = 0
+ for line in 0..data.length-1 do
+ str = data[line]
+ column = 0
+ while column<str.length do
+ case str[column].chr
+ when "[" then
+ level += 1 if template
+ when "]" then
+ level -= 1 if template && level > 0
+ when "\%" then
+ break
+ when "\\" then
+ column += 1
+ when symbol then
+ if level == 0 then
+ inside = ! inside
+ saved = [line,column]
+ else
+ # we're in some kind of template or so
+ end
+ else
+ # go on
+ end
+ column += 1
+ end
+ end
+ if inside && saved && level == 0 then
+ column = saved.pop
+ line = saved.pop
+ message("missing #{symbol} for #{symbol}",filename,line+1)
+ return true
+ else
+ return false
+ end
+end
+
+def some_key_error(data, filename, valid)
+ return if (! valid) || (valid.length == 0)
+ error = false
+ # data.foreach do |line| ... end
+ for line in 0..data.length-1 do
+ data[line].scan(/\\([a-zA-Z]+)/io) do
+ unless valid.has_key?($1) then
+ message("unknown command \\#{$1}",filename,line+1)
+ error = true
+ end
+ end
+ end
+ return error
+end
+
+# todo : language dependent
+
+def check_file_tex (filename)
+ error = false
+ if data = load_file(filename) then
+ message("checking tex file", filename)
+ interface = guess_interface(data)
+ valid = load_valid(data,interface)
+ data = cleanup_data(data,interface)
+ # data.each do |d| print d end
+ $valid[interface].each do |v|
+ if some_wrd_error(data, filename, v[0], v[1] ,$valid_tex) then
+ error = true
+ break
+ end
+ end
+ # return false if some_wrd_error(data, filename, '\\\\start' , '\\\\stop' , $valid_tex)
+ # return false if some_wrd_error(data, filename, '\\\\Start' , '\\\\Stop' , $valid_tex)
+ # return false if some_wrd_error(data, filename, '\\\\beginvan', '\\\\eindvan', $valid_tex)
+ # return false if some_wrd_error(data, filename, '\\\\begin' , '\\\\end|\\\\eind', $valid_tex)
+ error = true if some_sym_error(data, filename, '$', false)
+ error = true if some_sym_error(data, filename, '|', true)
+ error = true if some_chr_error(data, filename, '{', '}')
+ error = true if some_chr_error(data, filename, '[', ']')
+ error = true if some_chr_error(data, filename, '(', ')')
+ error = true if some_key_error(data, filename, valid)
+ message("no errors in tex code", filename) unless error
+ return error
+ else
+ return false
+ end
+end
+
+def check_file_mp (filename)
+ error = false
+ if data = load_file(filename) then
+ message("checking metapost file", filename)
+ interface = guess_interface(data)
+ valid = load_valid(data,interface)
+ $valid[interface].each do |v|
+ if some_wrd_error(data, filename, v[0], v[1] ,$valid_tex) then
+ error = true
+ break
+ end
+ end
+ # return false if some_wrd_error(data, filename, '', 'begin', 'end', $valid_mp)
+ error = true if some_chr_error(data, filename, '{', '}')
+ error = true if some_chr_error(data, filename, '[', ']')
+ error = true if some_chr_error(data, filename, '(', ')')
+ error = true if some_key_error(data, filename, valid)
+ message("no errors in metapost code", filename) unless error
+ return error
+ else
+ return false
+ end
+end
+
+def check_file_text(filename='')
+ if data = load_file(filename) then
+ for line in 0..data.length-1 do
+ # case data[line]
+ # when /\s([\:\;\,\.\?\!])/ then
+ # message("space before #{$1}",filename,line+1)
+ # when /\D([\:\;\,\.\?\!])\S/ then
+ # message("no space after #{$1}",filename,line+1)
+ # end
+ if data[line] =~ /\s([\:\;\,\.\?\!])/ then
+ message("space before #{$1}",filename,line+1)
+ else
+ data[line].gsub!(/\[.*?\]/o, '')
+ data[line].gsub!(/\(.*?\)/o, '')
+ data[line].gsub!(/\[.*?$/o, '')
+ data[line].gsub!(/^.*?\]/o, '')
+ if data[line] =~ /\D([\:\;\,\.\?\!])\S/ then
+ message("no space after #{$1}",filename,line+1)
+ end
+ end
+ end
+ end
+end
+
+def check_file(filename='')
+ case filename
+ when '' then
+ message("provide filename")
+ return false
+ when /\.(tex|mk.+)$/i then
+ return check_file_tex(filename) # && check_file_text(filename)
+ when /\.mp$/i then
+ return check_file_mp(filename)
+ else
+ message("only tex and metapost files are checked")
+ return false
+ end
+end
+
+if ARGV.size > 0 then
+ someerror = false
+ ARGV.each do |filename|
+ somerror = true if check_file(filename)
+ end
+ exit (if someerror then 1 else 0 end)
+else
+ exit 1
+end
+
diff --git a/Master/texmf-dist/scripts/context/ruby/ctxtools.rb b/Master/texmf-dist/scripts/context/ruby/ctxtools.rb
new file mode 100644
index 00000000000..f6493a3fcd3
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/ctxtools.rb
@@ -0,0 +1,2779 @@
+#!/usr/bin/env ruby
+#encoding: ASCII-8BIT
+
+# program : ctxtools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2004-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# This script will harbor some handy manipulations on context
+# related files.
+
+# todo: move scite here
+#
+# todo: move kpse call to kpse class/module, faster and better
+
+# Taco Hoekwater on patterns and lig building (see 'agr'):
+#
+# Any direct use of a ligature (as accessed by \char or through active
+# characters) is wrong and will create faulty hyphenation. Normally,
+# when TeX sees "office", it has six tokens, and it knows from the
+# patterns that it can hyphenate between the "ff". It will build an
+# internal list of four nodes, like this:
+#
+# [char, o , ffi ]
+# [lig , ffi, c ,[f,f,i]]
+# [char, c , e ]
+# [char, e , NULL]
+#
+# as you can see from the ffi line, it has remembered the original
+# characters. While hyphenating, it temporarily changes back to
+# that, then re-instates the ligature afterwards.
+#
+# If you feed it the ligature directly, like so:
+#
+# [char, o , ffi ]
+# [char, ffi , c ]
+# [char, c , e ]
+# [char, e , NULL]
+#
+# it cannot do that (it tries to hyphenate as if the "ffi" was a
+# character), and the result is wrong hyphenation.
+
+banner = ['CtxTools', 'version 1.3.5', '2004/2008', 'PRAGMA ADE']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'base/switch'
+require 'base/logger'
+require 'base/system'
+require 'base/kpse'
+require 'base/file'
+
+require 'rexml/document'
+require 'net/http'
+require 'fileutils'
+# require 'ftools'
+require 'kconv'
+
+exit if defined?(REQUIRE2LIB)
+
+class String
+
+ def i_translate(element, attribute, category)
+ self.gsub!(/(<#{element}.*?#{attribute}=)([\"\'])(.*?)\2/) do
+ if category.key?($3) then
+ # puts "#{element} #{$3} -> #{category[$3]}\n" if element == 'cd:inherit'
+ # puts "#{element} #{$3} => #{category[$3]}\n" if element == 'cd:command'
+ "#{$1}#{$2}#{category[$3]}#{$2}"
+ else
+ # puts "#{element} #{$3} -> ?\n" if element == 'cd:inherit'
+ # puts "#{element} #{$3} => ?\n" if element == 'cd:command'
+ "#{$1}#{$2}#{$3}#{$2}" # unchanged
+ end
+ end
+ end
+
+ def i_load(element, category)
+ self.scan(/<#{element}.*?name=([\"\'])(.*?)\1.*?value=\1(.*?)\1/) do
+ category[$2] = $3
+ end
+ end
+
+ def nosuffix(suffix)
+ self.sub(/\.#{suffix}/,'') # no /o
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ public
+
+ def touchcontextfile
+ dowithcontextfile(1)
+ end
+
+ def contextversion
+ dowithcontextfile(2)
+ end
+
+ private
+
+ def dowithcontextfile(action)
+ maincontextfile = 'context.tex'
+ unless FileTest.file?(maincontextfile) then
+ begin
+ maincontextfile = Kpse.found(maincontextfile,'context')
+ rescue
+ maincontextfile = ''
+ end
+ end
+ unless maincontextfile.empty? then
+ nextcontextfile = maincontextfile.sub(/context\.tex$/,"cont-new.tex")
+ case action
+ when 1 then
+ touchfile(maincontextfile)
+ touchfile(nextcontextfile,@@newcontextversion)
+ when 2 then
+ reportversion(maincontextfile)
+ reportversion(nextcontextfile,@@newcontextversion)
+ end
+ end
+
+ end
+
+ @@contextversion = "\\\\contextversion"
+ @@newcontextversion = "\\\\newcontextversion"
+
+ def touchfile(filename,command=@@contextversion)
+
+ if FileTest.file?(filename) then
+ if data = IO.read(filename) then
+ timestamp = Time.now.strftime('%Y.%m.%d %H:%M')
+ prevstamp = ''
+ begin
+ data.gsub!(/#{command}\{(\d+\.\d+\.\d+.*?)\}/) do
+ prevstamp = $1
+ "#{command.sub(/(\\)+/,"\\")}{#{timestamp}}"
+ end
+ rescue
+ else
+ begin
+ File.delete(filename+'.old')
+ rescue
+ end
+ begin
+ File.copy(filename,filename+'.old')
+ rescue
+ end
+ begin
+ if f = File.open(filename,'w') then
+ f.puts(data)
+ f.close
+ end
+ rescue
+ end
+ end
+ if prevstamp.empty? then
+ report("#{filename} is not updated, no timestamp found")
+ else
+ report("#{filename} is updated from #{prevstamp} to #{timestamp}")
+ end
+ end
+ else
+ report("#{filename} is not found")
+ end
+
+ end
+
+ def reportversion(filename,command=@@contextversion)
+
+ version = 'unknown'
+ begin
+ if FileTest.file?(filename) && IO.read(filename).match(/#{command}\{(\d+\.\d+\.\d+.*?)\}/) then
+ version = $1
+ end
+ rescue
+ end
+ if @commandline.option("pipe") then
+ print version
+ else
+ report("context version: #{version} (#{filename})")
+ end
+
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ public
+
+ def jeditinterface
+ editinterface('jedit')
+ end
+
+ def bbeditinterface
+ editinterface('bbedit')
+ end
+
+ def sciteinterface
+ editinterface('scite')
+ end
+
+ def rawinterface
+ editinterface('raw')
+ end
+
+ private
+
+ def editinterface(type='raw')
+
+ return unless FileTest.file?("cont-en.xml")
+
+ interfaces = @commandline.arguments
+
+ if interfaces.empty? then
+ interfaces = ['en','cs','de','it','nl','ro','fr']
+ end
+
+ interfaces.each do |interface|
+ begin
+ collection = Hash.new
+ mappings = Hash.new
+ if f = open("keys-#{interface}.xml") then
+ while str = f.gets do
+ if str =~ /\<cd\:command\s+name=\"(.*?)\"\s+value=\"(.*?)\".*?\>/o then
+ mappings[$1] = $2
+ end
+ end
+ f.close
+ if f = open("cont-en.xml") then
+ while str = f.gets do
+ if str =~ /\<cd\:command\s+name=\"(.*?)\"\s+type=\"environment\".*?\>/o then
+ collection["start#{mappings[$1]}"] = ''
+ collection["stop#{mappings[$1]}"] = ''
+ elsif str =~ /\<cd\:command\s+name=\"(.*?)\".*?\>/o then
+ collection["#{mappings[$1]}"] = ''
+ end
+ end
+ f.close
+ case type
+ when 'jedit' then
+ if f = open("context-jedit-#{interface}.xml", 'w') then
+ f.puts("<?xml version='1.0'?>\n\n")
+ f.puts("<!DOCTYPE MODE SYSTEM 'xmode.dtd'>\n\n")
+ f.puts("<MODE>\n")
+ f.puts(" <RULES>\n")
+ f.puts(" <KEYWORDS>\n")
+ collection.keys.sort.each do |name|
+ f.puts(" <KEYWORD2>\\#{name}</KEYWORD2>\n") unless name.empty?
+ end
+ f.puts(" </KEYWORDS>\n")
+ f.puts(" </RULES>\n")
+ f.puts("</MODE>\n")
+ f.close
+ end
+ when 'bbedit' then
+ if f = open("context-bbedit-#{interface}.xml", 'w') then
+ f.puts("<?xml version='1.0'?>\n\n")
+ f.puts("<key>BBLMKeywordList</key>\n")
+ f.puts("<array>\n")
+ collection.keys.sort.each do |name|
+ f.puts(" <string>\\#{name}</string>\n") unless name.empty?
+ end
+ f.puts("</array>\n")
+ f.close
+ end
+ when 'scite' then
+ if f = open("cont-#{interface}-scite.properties", 'w') then
+ i = 0
+ f.write("keywordclass.macros.context.#{interface}=")
+ collection.keys.sort.each do |name|
+ unless name.empty? then
+ if i==0 then
+ f.write("\\\n ")
+ i = 5
+ else
+ i = i - 1
+ end
+ f.write("#{name} ")
+ end
+ end
+ f.write("\n")
+ f.close
+ end
+ else # raw
+ collection.keys.sort.each do |name|
+ puts("\\#{name}\n") unless name.empty?
+ end
+ end
+ end
+ end
+ end
+ end
+
+ end
+
+end
+
+# class Commands
+#
+# include CommandBase
+#
+# public
+#
+# def translateinterface
+#
+# # since we know what kind of file we're dealing with,
+# # we do it quick and dirty instead of using rexml or
+# # xslt
+#
+# interfaces = @commandline.arguments
+#
+# if interfaces.empty? then
+# interfaces = ['cs','de','it','nl','ro','fr']
+# else
+# interfaces.delete('en')
+# end
+#
+# interfaces.flatten.each do |interface|
+#
+# variables, constants, strings, list, data = Hash.new, Hash.new, Hash.new, '', ''
+#
+# keyfile, intfile, outfile = "keys-#{interface}.xml", "cont-en.xml", "cont-#{interface}.xml"
+#
+# report("generating #{keyfile}")
+#
+# begin
+# one = "texexec --make --all #{interface}"
+# two = "texexec --batch --silent --interface=#{interface} x-set-01"
+# if @commandline.option("force") then
+# system(one)
+# system(two)
+# elsif not system(two) then
+# system(one)
+# system(two)
+# end
+# rescue
+# end
+#
+# unless File.file?(keyfile) then
+# report("no #{keyfile} generated")
+# next
+# end
+#
+# report("loading #{keyfile}")
+#
+# begin
+# list = IO.read(keyfile)
+# rescue
+# list = empty
+# end
+#
+# if list.empty? then
+# report("error in loading #{keyfile}")
+# next
+# end
+#
+# list.i_load('cd:variable', variables)
+# list.i_load('cd:constant', constants)
+# list.i_load('cd:command' , strings)
+# # list.i_load('cd:element' , strings)
+#
+# report("loading #{intfile}")
+#
+# begin
+# data = IO.read(intfile)
+# rescue
+# data = empty
+# end
+#
+# if data.empty? then
+# report("error in loading #{intfile}")
+# next
+# end
+#
+# report("translating interface en to #{interface}")
+#
+# data.i_translate('cd:string' , 'value', strings)
+# data.i_translate('cd:variable' , 'value', variables)
+# data.i_translate('cd:parameter', 'name' , constants)
+# data.i_translate('cd:constant' , 'type' , variables)
+# data.i_translate('cd:variable' , 'type' , variables)
+# data.i_translate('cd:inherit' , 'name' , strings)
+# # data.i_translate('cd:command' , 'name' , strings)
+#
+# data.gsub!(/(\<cd\:interface[^\>]*?language=")en(")/) do
+# $1 + interface + $2
+# end
+#
+# report("saving #{outfile}")
+#
+# begin
+# if f = File.open(outfile, 'w') then
+# f.write(data)
+# f.close
+# end
+# rescue
+# end
+#
+# end
+#
+# end
+#
+# end
+
+class Commands
+
+ include CommandBase
+
+ public
+
+ # faster is to glob the whole dir and regexp over that list
+
+ def purgefiles
+
+ pattern = @commandline.arguments
+ purgeall = @commandline.option("all")
+ recurse = @commandline.option("recurse")
+
+ $dontaskprefixes.push(Dir.glob("mpx-*"))
+
+ if purgeall then
+ $dontaskprefixes.push(Dir.glob("*.tex.prep"))
+ $dontaskprefixes.push(Dir.glob("*.xml.prep"))
+ end
+
+ $dontaskprefixes.flatten!
+ $dontaskprefixes.sort!
+
+ if purgeall then
+ $forsuresuffixes.push($texnonesuffixes)
+ $texnonesuffixes = []
+ $forsuresuffixes.flatten!
+ end
+
+ if ! pattern || pattern.empty? then
+ globbed = if recurse then "**/*.*" else "*.*" end
+ files = Dir.glob(globbed)
+ report("purging#{if purgeall then ' all' end} temporary files : #{globbed}")
+ else
+ report("purging#{if purgeall then ' all' end} temporary files : #{pattern.join(' ')}")
+ pattern.each do |pat|
+ nosuf = File.unsuffixed(pat)
+ globbed = if recurse then "**/#{nosuf}-*.*" else "#{nosuf}-*.*" end
+ report("checking files that match '#{globbed}'")
+ files = Dir.glob(globbed)
+ globbed = if recurse then "**/#{nosuf}.*" else "#{nosuf}.*" end
+ report("checking files that match '#{globbed}'")
+ files.push(Dir.glob(globbed))
+ end
+ end
+ files.flatten!
+ files.sort!
+
+ $dontaskprefixes.each do |file|
+ removecontextfile(file)
+ end
+ $dontasksuffixes.each do |suffix|
+ files.each do |file|
+ removecontextfile(file) if file =~ /#{suffix}$/i
+ end
+ end
+ $forsuresuffixes.each do |suffix|
+ files.each do |file|
+ removecontextfile(file) if file =~ /\.#{suffix}$/i
+ end
+ end
+ files.each do |file|
+ if file =~ /(.*?)\.\d+$/o then
+ basename = $1
+ if file =~ /mp(graph|run)/o || FileTest.file?("#{basename}.mp") then
+ removecontextfile($file)
+ end
+ end
+ end
+ $dummyfiles.each do |file|
+ (File.delete(file) if (FileTest.size?(file) rescue 10) < 10) rescue false
+ end
+ $texnonesuffixes.each do |suffix|
+ files.each do |file|
+ if file =~ /(.*)\.#{suffix}$/i then
+ if FileTest.file?("#{$1}.tex") || FileTest.file?("#{$1}.xml") || FileTest.file?("#{$1}.fo") then
+ keepcontextfile(file)
+ else
+ strippedname = $1.gsub(/\-[a-z]$/io, '')
+ if FileTest.file?("#{strippedname}.tex") || FileTest.file?("#{strippedname}.xml") then
+ keepcontextfile("#{file} (potential result file)")
+ else
+ removecontextfile(file)
+ end
+ end
+ end
+ end
+ end
+
+ files = Dir.glob("*.*")
+ $dontasksuffixes.each do |suffix|
+ files.each do |file|
+ removecontextfile(file) if file =~ /^#{suffix}$/i
+ end
+ end
+
+ if $removedfiles || $keptfiles || $persistentfiles then
+ report("removed files : #{$removedfiles}")
+ report("kept files : #{$keptfiles}")
+ report("persistent files : #{$persistentfiles}")
+ report("reclaimed bytes : #{$reclaimedbytes}")
+ end
+
+ end
+
+ private
+
+ $removedfiles = 0
+ $keptfiles = 0
+ $persistentfiles = 0
+ $reclaimedbytes = 0
+
+ $dontaskprefixes = [
+ # "tex-form.tex", "tex-edit.tex", "tex-temp.tex",
+ "texexec.tex", "texexec.tui", "texexec.tuo",
+ "texexec.tuc", "texexec.tua",
+ "texexec.ps", "texexec.pdf", "texexec.dvi",
+ "cont-opt.tex", "cont-opt.bak"
+ ]
+ $dontasksuffixes = [
+ "mp(graph|run)\\.mp", "mp(graph|run)\\.mpd", "mp(graph|run)\\.mpo", "mp(graph|run)\\.mpy",
+ "mp(graph|run)\\.\\d+", "mp(graph|run)\\.mp.keep",
+ "xlscript\\.xsl"
+ ]
+ $forsuresuffixes = [
+ "tui", "tua", "tup", "ted", "tes", "top",
+ "log", "tmp", "run", "bck", "rlg",
+ "mpt", "mpx", "mpd", "mpo", "mpb",
+ "ctl",
+ "pgf", "synctex.gz",
+ "tmp.md5", "tmp.out"
+ ]
+ $texonlysuffixes = [
+ "dvi", "ps", "pdf"
+ ]
+ $texnonesuffixes = [
+ "tuo", "tub", "top", "tuc"
+ ]
+ $dummyfiles = [
+ # "mpgraph"
+ ]
+
+ def removecontextfile (filename)
+ if filename && FileTest.file?(filename) then
+ begin
+ filesize = FileTest.size(filename)
+ File.delete(filename)
+ rescue
+ report("problematic : #{filename}")
+ else
+ if FileTest.file?(filename) then
+ $persistentfiles += 1
+ report("persistent : #{filename}")
+ else
+ $removedfiles += 1
+ $reclaimedbytes += filesize
+ report("removed : #{filename}")
+ end
+ end
+ end
+ end
+
+ def keepcontextfile (filename)
+ if filename && FileTest.file?(filename) then
+ $keptfiles += 1
+ report("not removed : #{filename}")
+ end
+ end
+
+end
+
+#D Documentation can be woven into a source file. The next
+#D routine generates a new, \TEX\ ready file with the
+#D documentation and source fragments properly tagged. The
+#D documentation is included as comment:
+#D
+#D \starttypen
+#D %D ...... some kind of documentation
+#D %M ...... macros needed for documenation
+#D %S B begin skipping
+#D %S E end skipping
+#D \stoptypen
+#D
+#D The most important tag is \type {%D}. Both \TEX\ and \METAPOST\
+#D files use \type{%} as a comment chacacter, while \PERL, \RUBY\
+#D and alike use \type{#}. Therefore \type{#D} is also handled.
+#D
+#D The generated file gets the suffix \type{ted} and is
+#D structured as:
+#D
+#D \starttypen
+#D \startmoduledocumentation[type=suffix]
+#D \startdocumentation
+#D \stopdocumentation
+#D \startdefinition
+#D \stopdefinition
+#D \stopmoduledocumentation
+#D \stoptypen
+#D
+#D Macro definitions specific to the documentation are not
+#D surrounded by start||stop commands. The suffix specifaction
+#D can be overruled at runtime, but defaults to the file
+#D extension. This specification can be used for language
+#D depended verbatim typesetting.
+
+class Commands
+
+ include CommandBase
+
+ public
+
+ def documentation
+ files = @commandline.arguments
+ processtype = @commandline.option("type")
+ files.each do |fullname|
+ if fullname =~ /(.*)\.(.+?)$/o then
+ filename, filesuffix = $1, $2
+ else
+ filename, filesuffix = fullname, 'tex'
+ end
+ filesuffix = 'tex' if filesuffix.empty?
+ fullname, resultname = "#{filename}.#{filesuffix}", "#{filename}.ted"
+ if ! FileTest.file?(fullname)
+ report("empty input file #{fullname}")
+ elsif ! tex = File.open(fullname)
+ report("invalid input file #{fullname}")
+ elsif ! ted = File.open(resultname,'w') then
+ report("unable to openresult file #{resultname}")
+ else
+ report("input file : #{fullname}")
+ report("output file : #{resultname}")
+ nofdocuments, nofdefinitions, nofskips = 0, 0, 0
+ skiplevel, indocument, indefinition, skippingbang = 0, false, false, false
+ if processtype.empty? then
+ filetype = filesuffix.downcase.sub(/^mk.+$/,'tex') # make sure that mkii and mkiv files are handled
+ else
+ filetype = processtype.downcase
+ end
+ report("filetype : #{filetype}")
+ # we need to signal to texexec what interface to use
+ firstline = tex.gets
+ if firstline =~ /^\%.*interface\=/ then
+ ted.puts(firstline)
+ else
+ tex.rewind # seek(0)
+ end
+ ted.puts("\\startmoduledocumentation[type=#{filetype}]\n")
+ while str = tex.gets do
+ if skippingbang then
+ skippingbang = false
+ else
+ str.chomp!
+ str.sub!(/\s*$/o, '')
+ case str
+ when /^[%\#]D($| )/io then
+ if skiplevel == 0 then
+ someline = if str.length < 3 then "" else str[3,str.length-1] end
+ if indocument then
+ ted.puts("#{someline}\n")
+ else
+ if indefinition then
+ ted.puts("\\stopdefinition\n")
+ indefinition = false
+ end
+ unless indocument then
+ ted.puts("\n\\startdocumentation\n")
+ end
+ ted.puts("#{someline}\n")
+ indocument = true
+ nofdocuments += 1
+ end
+ end
+ when /^[%\#]M($| )/io then
+ if skiplevel == 0 then
+ someline = if str.length < 3 then "" else str[3,str.length-1] end
+ ted.puts("#{someline}\n")
+ end
+ when /^[%\%]S B/io then
+ skiplevel += 1
+ nofskips += 1
+ when /^[%\%]S E/io then
+ skiplevel -= 1
+ when /^[%\#]/io then
+ #nothing
+ when /^eval \'\(exit \$\?0\)\' \&\& eval \'exec perl/o then
+ skippingbang = true
+ else
+ if skiplevel == 0 then
+ inlocaldocument = indocument
+ inlocaldocument = false # else first line skipped when not empty
+ someline = str
+ if indocument then
+ ted.puts("\\stopdocumentation\n")
+ indocument = false
+ end
+ if indefinition then
+ if someline.empty? then
+ ted.puts("\\stopdefinition\n")
+ indefinition = false
+ else
+ ted.puts("#{someline}\n")
+ end
+ elsif ! someline.empty? then
+ ted.puts("\n\\startdefinition\n")
+ indefinition = true
+ if inlocaldocument then
+ # nothing
+ else
+ nofdefinitions += 1
+ ted.puts("#{someline}\n")
+ end
+ end
+ end
+ end
+ end
+ end
+ if indocument then
+ ted.puts("\\stopdocumentation\n")
+ end
+ if indefinition then
+ ted.puts("\\stopdefinition\n")
+ end
+ ted.puts("\\stopmoduledocumentation\n")
+ ted.close
+
+ if nofdocuments == 0 && nofdefinitions == 0 then
+ begin
+ File.delete(resultname)
+ rescue
+ end
+ end
+ report("documentation sections : #{nofdocuments}")
+ report("definition sections : #{nofdefinitions}")
+ report("skipped sections : #{nofskips}")
+ end
+ end
+ end
+
+end
+
+#D This feature was needed when \PDFTEX\ could not yet access page object
+#D numbers (versions prior to 1.11).
+
+class Commands
+
+ include CommandBase
+
+ public
+
+ def filterpages # temp feature / no reporting
+ filename = @commandline.argument('first')
+ filename.sub!(/\.([a-z]+?)$/io,'')
+ pdffile = "#{filename}.pdf"
+ tuofile = "#{filename}.tuo"
+ if FileTest.file?(pdffile) then
+ begin
+ prevline, n = '', 0
+ if (pdf = File.open(pdffile)) && (tuo = File.open(tuofile,'a')) then
+ report('filtering page object numbers')
+ pdf.binmode
+ while line = pdf.gets do
+ line.chomp
+ # typical pdftex search
+ if (line =~ /\/Type \/Page/o) && (prevline =~ /^(\d+)\s+0\s+obj/o) then
+ p = $1
+ n += 1
+ tuo.puts("\\objectreference{PDFP}{#{n}}{#{p}}{#{n}}\n")
+ else
+ prevline = line
+ end
+ end
+ end
+ pdf.close
+ tuo.close
+ report("number of pages : #{n}")
+ rescue
+ report("fatal error in filtering pages")
+ end
+ end
+ end
+
+end
+
+# This script is used to generate hyphenation pattern files
+# that suit ConTeXt. One reason for independent files is that
+# over the years too many uncommunicated changes took place
+# as well that inconsistency in content, naming, and location
+# in the texmf tree takes more time than I'm willing to spend
+# on it. Pattern files are normally shipped for LaTeX (and
+# partially plain). A side effect of independent files is that
+# we can make them encoding independent.
+#
+# Maybe I'll make this hyptools.tex
+
+class String
+
+ def markbraces
+ level = 0
+ self.gsub(/([\{\}])/o) do |chr|
+ if chr == '{' then
+ level = level + 1
+ chr = "((+#{level}))"
+ elsif chr == '}' then
+ chr = "((-#{level}))"
+ level = level - 1
+ end
+ chr
+ end
+ end
+
+ def unmarkbraces
+ self.gsub(/\(\(\+\d+?\)\)/o) do
+ "{"
+ end .gsub(/\(\(\-\d+?\)\)/o) do
+ "}"
+ end
+ end
+
+ def getargument(pattern)
+ if self =~ /(#{pattern})\s*\(\(\+(\d+)\)\)(.*?)\(\(\-\2\)\)/m then # no /o
+ return $3
+ else
+ return ""
+ end
+ end
+
+ def withargument(pattern, &block)
+ if self.markbraces =~ /^(.*)(#{pattern}\s*)\(\(\+(\d+)\)\)(.*?)\(\(\-\3\)\)(.*)$/m then # no /o
+ "#{$1.unmarkbraces}#{$2}{#{yield($4.unmarkbraces)}}#{$5.unmarkbraces}"
+ else
+ self
+ end
+ end
+
+ def filterargument(pattern, &block)
+ if self.markbraces =~ /^(.*)(#{pattern}\s*)\(\(\+(\d+)\)\)(.*?)\(\(\-\3\)\)(.*)$/m then # no /o
+ yield($4.unmarkbraces)
+ else
+ self
+ end
+ end
+
+end
+
+class Language
+
+ include CommandBase
+
+ def initialize(commandline=nil, language='en', filenames=nil, encoding='ec')
+ @commandline= commandline
+ @language = language
+ @filenames = filenames
+ @remapping = Array.new
+ @demapping = Array.new
+ @cloning = Array.new
+ @unicode = Hash.new
+ @encoding = encoding
+ @data = ''
+ @read = ''
+ preload_accents()
+ preload_unicode() if @commandline.option('utf8')
+ case @encoding.downcase
+ when 't1', 'ec', 'cork' then preload_vector('ec', 'enco-ec.tex')
+ when 'y', 'texnansi' then preload_vector('texnansi', 'enco-ans.tex')
+ when 'agr', 'agreek' then preload_vector('agr', 'enco-agr.tex')
+ when 't2a' then preload_vector('t2a', 'enco-cyr.tex')
+ when 'cyr' then preload_vector() # somehow loading t2a does not work out well
+ end
+ end
+
+ def report(str)
+ if @commandline then
+ @commandline.report(str)
+ else
+ puts("#{str}\n")
+ end
+ end
+
+ def remap(from, to)
+ @remapping.push([from,to])
+ end
+ def demap(from, to)
+ @demapping.push([from,to])
+ end
+ def clone(from, to)
+ @cloning.push([from,to])
+ end
+
+ def load(filenames=@filenames)
+ found = false
+ begin
+ if filenames then
+ @filenames.each do |fileset|
+ [fileset].flatten.each do |filename|
+ begin
+ if fname = located(filename) then
+ data = IO.read(fname)
+ @data += data.gsub(/\%.*$/, '').gsub(/\\message\{.*?\}/, '')
+ data.gsub!(/(\\patterns|\\hyphenation)\s*\{.*/mo) do '' end
+ @read += "\n% preamble of file #{fname}\n\n#{data}\n"
+ @data.gsub!(/^[\s\n]+$/moi, '')
+ report("file #{fname} is loaded")
+ found = true
+ break # next fileset
+ end
+ rescue
+ report("file #{filename} is not readable")
+ end
+ end
+ end
+ end
+ rescue
+ end
+ return found
+ end
+
+ def valid?
+ ! @data.empty?
+ end
+
+ def convert
+ if @data then
+ n = 0
+ if true then
+ report("")
+ ["\\patterns","\\hyphenation"].each do |what|
+ @data = @data.withargument(what) do |content|
+ report("converting #{what}")
+ report("")
+ @demapping.each_index do |i|
+ content.gsub!(@demapping[i][0], @demapping[i][1])
+ end
+ content.gsub!(/\\delete\{.*?\}/o) do '' end
+ content.gsub!(/\\keep\{(.*?)\}/o) do $1 end
+ done = false
+ @remapping.each_index do |i|
+ from, to, m = @remapping[i][0], @remapping[i][1], 0
+ content.gsub!(from) do
+ done = true
+ m += 1
+ "[#{i}]"
+ end
+ report("#{m.to_s.rjust(5)} entries remapped to #{to}") unless m == 0
+ n += m
+ end
+ content.gsub!(/\[(\d+)\]/o) do
+ @remapping[$1.to_i][1]
+ end
+ report(" nothing remapped") unless done
+ @cloning.each_index do |i|
+ c = 0
+ f, s = @cloning[i][0], @cloning[i][1]
+ str = "#{f}|#{s}"
+ str.gsub!(/([\[\]])/) do "\\" + "#{$1}" end
+ reg = /(#{str})/
+ content.gsub!(/(\S*(#{str})\S*)/) do
+ a, b = $1, $1
+ a.gsub!(reg, f)
+ b.gsub!(reg, s)
+ c = c + 1
+ "#{a} #{b}"
+ end
+ report("#{c.to_s.rjust(5)} times #{f} cloned to #{s}")
+ n += c
+ end
+ report("")
+ content.to_s
+ end
+ end
+ else
+ @remapping.each do |k|
+ from, to, m = k[0], k[1], 0
+ @data.gsub!(from) do
+ m += 1
+ to
+ end
+ report("#{m.to_s.rjust(5)} entries remapped to #{to}") unless m == 0
+ n += m
+ end
+ end
+ report("#{n} changes in patterns and exceptions")
+ if @commandline.option('utf8') then
+ n = 0
+ @data.gsub!(/\[(.*?)\]/o) do
+ n += 1
+ @unicode[$1] || $1
+ end
+ report("#{n} unicode utf8 entries")
+ end
+ return true
+ else
+ return false
+ end
+ end
+
+ def comment(str)
+ str.gsub!(/^\n/o, '')
+ str.chomp!
+ if @commandline.option('xml') then
+ "<!-- #{str.strip} -->\n\n"
+ else
+ "% #{str.strip}\n\n"
+ end
+ end
+
+ def content(tag, str)
+ lst = str.split(/\s+/)
+ lst.collect! do |l|
+ l.strip
+ end
+ if lst.length>0 then
+ lst = "\n#{lst.join("\n")}\n"
+ else
+ lst = ""
+ end
+ if @commandline.option('xml') then
+ lst.gsub!(/\[(.*?)\]/o) do
+ "&#{$1};"
+ end
+ "<#{tag}>#{lst}</#{tag}>\n\n"
+ else
+ "\\#{tag} \{#{lst}\}\n\n"
+ end
+ end
+
+ def banner
+ if @commandline.option('xml') then
+ "<?xml version='1.0' standalone='yes' ?>\n\n"
+ end
+ end
+
+ def triggerunicode
+ return
+ if @commandline.option('utf8') then
+ "% xetex needs utf8 encoded patterns and for patterns\n" +
+ "% coded as such we need to enable this regime when\n" +
+ "% not in xetex; this code will be moved into context\n" +
+ "% as soon as we've spread the generic patterns\n" +
+ "\n" +
+ "\\ifx\\XeTeXversion\\undefined \\else\n" +
+ " \\ifx\\enableregime\\undefined \\else\n" +
+ " \\enableregime[utf]\n" +
+ " \\fi\n" +
+ "\\fi\n" +
+ "\n"
+ end
+ end
+
+ def save
+ xml = @commandline.option("xml")
+
+ patname = "lang-#{@language}.pat"
+ hypname = "lang-#{@language}.hyp"
+ rmename = "lang-#{@language}.rme"
+ logname = "lang-#{@language}.log"
+
+ desname = "lang-all.xml"
+
+ @data.gsub!(/\\[nc]\{(.+?)\}/) do $1 end
+ @data.gsub!(/\{\}/) do '' end
+ @data.gsub!(/\n+/mo) do "\n" end
+ @read.gsub!(/\n+/mo) do "\n" end
+
+ description = ''
+ commentfile = rmename.dup
+
+ begin
+ desfile = Kpse.found(desname,'context')
+ if f = File.new(desfile) then
+ if doc = REXML::Document.new(f) then
+ if e = REXML::XPath.first(doc.root,"/descriptions/description[@language='#{@language}']") then
+ description = e.to_s
+ end
+ end
+ end
+ rescue
+ description = ''
+ else
+ unless description.empty? then
+ commentfile = desname.dup
+ str = "<!-- copied from lang-all.xml\n\n"
+ str << "<?xml version='1.0' standalone='yes'?>\n\n"
+ str << description.chomp
+ str << "\n\nend of copy -->\n"
+ str.gsub!(/^/io, "% ") unless @commandline.option('xml')
+ description = comment("begin description data")
+ description << str + "\n"
+ description << comment("end description data")
+ report("description found for language #{@language}")
+ end
+ end
+
+ begin
+ if description.empty? || @commandline.option('log') then
+ if f = File.open(logname,'w') then
+ report("saving #{@remapping.length} remap patterns in #{logname}")
+ @remapping.each do |m|
+ f.puts("#{m[0].inspect} => #{m[1]}\n")
+ end
+ f.close
+ end
+ else
+ File.delete(logname) if FileTest.file?(logname)
+ end
+ rescue
+ end
+
+ begin
+ if description.empty? || @commandline.option('log') then
+ if f = File.open(rmename,'w') then
+ data = @read.dup
+ data.gsub!(/(\s*\n\s*)+/mo, "\n")
+ f << comment("comment copied from public hyphenation files}")
+ f << comment("source of data: #{@filenames.join(' ')}")
+ f << comment("begin original comment")
+ f << "#{data}\n"
+ f << comment("end original comment")
+ f.close
+ report("comment saved in file #{rmename}")
+ else
+ report("file #{rmename} is not writable")
+ end
+ else
+ File.delete(rmename) if FileTest.file?(rmename)
+ end
+ rescue
+ end
+
+ begin
+ if f = File.open(patname,'w') then
+ data = ''
+ @data.filterargument('\\patterns') do |content|
+ report("merging patterns")
+ data += content.strip
+ end
+ data.gsub!(/(\s*\n\s*)+/mo, "\n")
+
+ f << banner
+ f << comment("context pattern file, see #{commentfile} for original comment")
+ f << comment("source of data: #{@filenames.join(' ')}")
+ f << description
+ f << comment("begin pattern data")
+ f << triggerunicode
+ f << content('patterns', data)
+ f << comment("end pattern data")
+ f.close
+ report("patterns saved in file #{patname}")
+ else
+ report("file #{patname} is not writable")
+ end
+ rescue
+ report("problems with file #{patname}")
+ end
+
+ begin
+ if f = File.open(hypname,'w') then
+ data = ''
+ @data.filterargument('\\hyphenation') do |content|
+ report("merging exceptions")
+ data += content.strip
+ end
+ data.gsub!(/(\s*\n\s*)+/mo, "\n")
+ f << banner
+ f << comment("context hyphenation file, see #{commentfile} for original comment")
+ f << comment("source of data: #{@filenames.join(' ')}")
+ f << description
+ f << comment("begin hyphenation data")
+ f << triggerunicode
+ f << content('hyphenation', data)
+ f << comment("end hyphenation data")
+ f.close
+ report("exceptions saved in file #{hypname}")
+ else
+ report("file #{hypname} is not writable")
+ end
+ rescue
+ report("problems with file #{hypname}")
+ end
+ end
+
+ def process
+ load
+ if valid? then
+ convert
+ save
+ else
+ report("aborted due to missing files")
+ end
+ end
+
+ def Language::generate(commandline, language='', filenames='', encoding='ec')
+ if ! language.empty? && ! filenames.empty? then
+ commandline.report("processing language #{language}")
+ commandline.report("")
+ language = Language.new(commandline,language,filenames,encoding)
+ if language.load then
+ language.convert
+ language.save
+ commandline.report("")
+ end
+ end
+ end
+
+ private
+
+ def located(filename)
+ begin
+ ["context","plain","latex"].each do |name| # fallbacks needed for czech patterns
+ fname = Kpse.found(filename, name)
+ if FileTest.file?(fname) then
+ report("using file #{fname}")
+ return fname
+ end
+ end
+ report("file #{filename} is not present")
+ return nil
+ rescue
+ report("file #{filename} cannot be located using kpsewhich")
+ return nil
+ end
+ end
+
+ def preload_accents
+
+ begin
+ if filename = located("enco-acc.tex") then
+ if data = IO.read(filename) then
+ report("preloading accent conversions")
+ data.scan(/\\defineaccent\s*\\*(.+?)\s*\{*(.+?)\}*\s*\{\\(.+?)\}/o) do
+ one, two, three = $1, $2, $3
+ one.gsub!(/[\`\~\!\^\*\_\-\+\=\:\;\"\'\,\.\?]/o) do
+ "\\#{one}"
+ end
+ remap(/\\#{one} #{two}/, "[#{three}]")
+ remap(/\\#{one}#{two}/, "[#{three}]") unless one =~ /[a-zA-Z]/o
+ remap(/\\#{one}\{#{two}\}/, "[#{three}]")
+ end
+ end
+ end
+ rescue
+ end
+
+ end
+
+ def preload_unicode
+
+ # \definecharacter Agrave {\uchar0{192}}
+
+ begin
+ if filename = located("enco-uc.tex") then
+ if data = IO.read(filename) then
+ report("preloading unicode conversions")
+ data.scan(/\\definecharacter\s*(.+?)\s*\{\\uchar\{*(\d+)\}*\s*\{(\d+)\}/o) do
+ one, two, three = $1, $2.to_i, $3.to_i
+ @unicode[one] = [(two*256 + three)].pack("U")
+ end
+ end
+ end
+ rescue
+ report("error in loading unicode mapping (#{$!})")
+ end
+
+ end
+
+ def preload_vector(encoding='', filename='')
+
+ # funny polish
+
+ case @language
+ when 'pl' then
+ remap(/\/a/, "[aogonek]") ; remap(/\/A/, "[Aogonek]")
+ remap(/\/c/, "[cacute]") ; remap(/\/C/, "[Cacute]")
+ remap(/\/e/, "[eogonek]") ; remap(/\/E/, "[Eogonek]")
+ remap(/\/l/, "[lstroke]") ; remap(/\/L/, "[Lstroke]")
+ remap(/\/n/, "[nacute]") ; remap(/\/N/, "[Nacute]")
+ remap(/\/o/, "[oacute]") ; remap(/\/O/, "[Oacute]")
+ remap(/\/s/, "[sacute]") ; remap(/\/S/, "[Sacute]")
+ remap(/\/x/, "[zacute]") ; remap(/\/X/, "[Zacute]")
+ remap(/\/z/, "[zdotaccent]") ; remap(/\/Z/, "[Zdotaccent]")
+ when 'sl' then
+ remap(/\"c/,"[ccaron]") ; remap(/\"C/,"[Ccaron]")
+ remap(/\"s/,"[scaron]") ; remap(/\"S/,"[Scaron]")
+ remap(/\"z/,"[zcaron]") ; remap(/\"Z/,"[Zcaron]")
+ when 'da' then
+ remap(/X/, "[aeligature]")
+ remap(/Y/, "[ostroke]")
+ remap(/Z/, "[aring]")
+ when 'hu' then
+ # nothing
+ when 'ca' then
+ demap(/\\c\{/, "\\delete{")
+ when 'de', 'deo' then
+ demap(/\\c\{/, "\\delete{")
+ demap(/\\n\{/, "\\keep{")
+ remap(/\\3/, "[ssharp]")
+ remap(/\\9/, "[ssharp]")
+ remap(/\"a/, "[adiaeresis]")
+ remap(/\"o/, "[odiaeresis]")
+ remap(/\"u/, "[udiaeresis]")
+ when 'fr' then
+ demap(/\\n\{/, "\\delete{")
+ remap(/\\ae/, "[aeligature]")
+ remap(/\\oe/, "[oeligature]")
+ when 'la' then
+ # \lccode`'=`' somewhere else, todo
+ demap(/\\c\{/, "\\delete{")
+ remap(/\\a\s*/, "[aeligature]")
+ remap(/\\o\s*/, "[oeligature]")
+ when 'agr' then
+ # bug fix
+ remap("a2|", "[greekalphaiotasub]")
+ remap("h2|", "[greeketaiotasub]")
+ remap("w2|", "[greekomegaiotasub]")
+ remap(">2r1<2r", "[2ῤ1ῥ]")
+ remap(">a2n1wdu'", "[ἀ2ν1ωδύ]")
+ remap(">e3s2ou'", "[ἐ3σ2ού]")
+ # main conversion
+ remap(/\<\'a\|/, "[greekalphaiotasubdasiatonos]")
+ # remap(/\<\'a\|/, "[greekdasiatonos][greekAlpha][greekiota]")
+ remap(/\>\'a\|/, "[greekalphaiotasubpsilitonos]")
+ remap(/\<\`a\|/, "[greekalphaiotasubdasiavaria]")
+ remap(/\>\`a\|/, "[greekalphaiotasubpsilivaria]")
+ remap(/\<\~a\|/, "[greekalphaiotasubdasiaperispomeni]")
+ remap(/\>\~a\|/, "[greekalphaiotasubpsiliperispomeni]")
+ remap(/\'a\|/, "[greekalphaiotasubtonos]")
+ remap(/\`a\|/, "[greekalphaiotasubvaria]")
+ remap(/\~a\|/, "[greekalphaiotasubperispomeni]")
+ remap(/\<a\|/, "[greekalphaiotasubdasia]")
+ remap(/\>a\|/, "[greekalphaiotasubpsili]")
+ remap(/a\|/, "[greekalphaiotasub]")
+ remap(/\<\'h\|/, "[greeketaiotasubdasiatonos]")
+ remap(/\>\'h\|/, "[greeketaiotasubpsilitonos]")
+ remap(/\<\`h\|/, "[greeketaiotasubdasiavaria]")
+ remap(/\>\`h\|/, "[greeketaiotasubpsilivaria]")
+ remap(/\<\~h\|/, "[greeketaiotasubdasiaperispomeni]")
+ remap(/\>\~h\|/, "[greeketaiotasubpsiliperispomeni]")
+ remap(/\'h\|/, "[greeketaiotasubtonos]")
+ remap(/\`h\|/, "[greeketaiotasubvaria]")
+ remap(/\~h\|/, "[greeketaiotasubperispomeni]")
+ remap(/\<h\|/, "[greeketaiotasubdasia]")
+ remap(/\>h\|/, "[greeketaiotasubpsili]")
+ remap(/h\|/, "[greeketaiotasub]")
+ remap(/\<'w\|/, "[greekomegaiotasubdasiatonos]")
+ remap(/\>'w\|/, "[greekomegaiotasubpsilitonos]")
+ remap(/\<`w\|/, "[greekomegaiotasubdasiavaria]")
+ remap(/\>`w\|/, "[greekomegaiotasubpsilivaria]")
+ remap(/\<~w\|/, "[greekomegaiotasubdasiaperispomeni]")
+ remap(/\>~w\|/, "[greekomegaiotasubpsiliperispomeni]")
+ remap(/\<w\|/, "[greekomegaiotasubdasia]")
+ remap(/\>w\|/, "[greekomegaiotasubpsili]")
+ remap(/\'w\|/, "[greekomegaiotasubtonos]")
+ remap(/\`w\|/, "[greekomegaiotasubvaria]")
+ remap(/\~w\|/, "[greekomegaiotasubperispomeni]")
+ remap(/w\|/, "[greekomegaiotasub]")
+ remap(/\<\'i/, "[greekiotadasiatonos]")
+ remap(/\>\'i/, "[greekiotapsilitonos]")
+ remap(/\<\`i/, "[greekiotadasiavaria]")
+ remap(/\>\`i/, "[greekiotapsilivaria]")
+ remap(/\<\~i/, "[greekiotadasiaperispomeni]")
+ remap(/\>\~i/, "[greekiotapsiliperispomeni]")
+ remap(/\"\'i/, "[greekiotadialytikatonos]")
+ remap(/\"\`i/, "[greekiotadialytikavaria]")
+ remap(/\"\~i/, "[greekiotadialytikaperispomeni]")
+ remap(/\<i/, "[greekiotadasia]")
+ remap(/\>i/, "[greekiotapsili]")
+ remap(/\'i/, "[greekiotaoxia]")
+ remap(/\`i/, "[greekiotavaria]")
+ remap(/\~i/, "[greekiotaperispomeni]")
+ remap(/\"i/, "[greekiotadialytika]")
+ remap(/\>\~e/, "[greekepsilonpsiliperispomeni]")
+ remap(/\<\~e/, "[greekepsilondasiaperispomeni]")
+ remap(/\<\'e/, "[greekepsilondasiatonos]")
+ remap(/\>\'e/, "[greekepsilonpsilitonos]")
+ remap(/\<\`e/, "[greekepsilondasiavaria]")
+ remap(/\>\`e/, "[greekepsilonpsilivaria]")
+ remap(/\<e/, "[greekepsilondasia]")
+ remap(/\>e/, "[greekepsilonpsili]")
+ remap(/\'e/, "[greekepsilonoxia]")
+ remap(/\`e/, "[greekepsilonvaria]")
+ remap(/\~e/, "[greekepsilonperispomeni]")
+ remap(/\<\'a/, "[greekalphadasiatonos]")
+ remap(/\>\'a/, "[greekalphapsilitonos]")
+ remap(/\<\`a/, "[greekalphadasiavaria]")
+ remap(/\>\`a/, "[greekalphapsilivaria]")
+ remap(/\<\~a/, "[greekalphadasiaperispomeni]")
+ remap(/\>\~a/, "[greekalphapsiliperispomeni]")
+ remap(/\<a/, "[greekalphadasia]")
+ remap(/\>a/, "[greekalphapsili]")
+ remap(/\'a/, "[greekalphaoxia]")
+ remap(/\`a/, "[greekalphavaria]")
+ remap(/\~a/, "[greekalphaperispomeni]")
+ remap(/\<\'h/, "[greeketadasiatonos]")
+ remap(/\>\'h/, "[greeketapsilitonos]")
+ remap(/\<\`h/, "[greeketadasiavaria]")
+ remap(/\>\`h/, "[greeketapsilivaria]")
+ remap(/\<\~h/, "[greeketadasiaperispomeni]")
+ remap(/\>\~h/, "[greeketapsiliperispomeni]")
+ remap(/\<h/, "[greeketadasia]")
+ remap(/\>h/, "[greeketapsili]")
+ remap(/\'h/, "[greeketaoxia]")
+ remap(/\`h/, "[greeketavaria]")
+ remap(/\~h/, "[greeketaperispomeni]")
+ remap(/\<\~o/, "[greekomicrondasiaperispomeni]")
+ remap(/\>\~o/, "[greekomicronpsiliperispomeni]")
+ remap(/\<\'o/, "[greekomicrondasiatonos]")
+ remap(/\>\'o/, "[greekomicronpsilitonos]")
+ remap(/\<\`o/, "[greekomicrondasiavaria]")
+ remap(/\>\`o/, "[greekomicronpsilivaria]")
+ remap(/\<o/, "[greekomicrondasia]")
+ remap(/\>o/, "[greekomicronpsili]")
+ remap(/\'o/, "[greekomicronoxia]")
+ remap(/\`o/, "[greekomicronvaria]")
+ remap(/\~o/, "[greekomicronperispomeni]")
+ remap(/\<\'u/, "[greekupsilondasiatonos]")
+ remap(/\>\'u/, "[greekupsilonpsilitonos]")
+ remap(/\<\`u/, "[greekupsilondasiavaria]")
+ remap(/\>\`u/, "[greekupsilonpsilivaria]")
+ remap(/\<\~u/, "[greekupsilondasiaperispomeni]")
+ remap(/\>\~u/, "[greekupsilonpsiliperispomeni]")
+ remap(/\"\'u/, "[greekupsilondialytikatonos]")
+ remap(/\"\`u/, "[greekupsilondialytikavaria]")
+ remap(/\"\~u/, "[greekupsilondialytikaperispomeni]")
+ remap(/\<u/, "[greekupsilondasia]")
+ remap(/\>u/, "[greekupsilonpsili]")
+ remap(/\'u/, "[greekupsilonoxia]")
+ remap(/\`u/, "[greekupsilonvaria]")
+ remap(/\~u/, "[greekupsilonperispomeni]")
+ remap(/\"u/, "[greekupsilondiaeresis]")
+ remap(/\<\'w/, "[greekomegadasiatonos]")
+ remap(/\>\'w/, "[greekomegapsilitonos]")
+ remap(/\<\`w/, "[greekomegadasiavaria]")
+ remap(/\>\`w/, "[greekomegapsilivaria]")
+ remap(/\<\~w/, "[greekomegadasiaperispomeni]")
+ remap(/\>\~w/, "[greekomegapsiliperispomeni]")
+ remap(/\<w/, "[greekomegadasia]")
+ remap(/\>w/, "[greekomegapsili]")
+ remap(/\'w/, "[greekomegaoxia]")
+ remap(/\`w/, "[greekomegavaria]")
+ remap(/\~w/, "[greekomegaperispomeni]")
+ remap(/\<r/, "[greekrhodasia]")
+ remap(/\>r/, "[greekrhopsili]")
+ remap(/\<\~/, "[greekdasiaperispomeni]")
+ remap(/\>\~/, "[greekpsiliperispomeni]")
+ remap(/\<\'/, "[greekdasiatonos]")
+ remap(/\>\'/, "[greekpsilitonos]")
+ remap(/\<\`/, "[greekdasiavaria]")
+ remap(/\>\`/, "[greekpsilivaria]")
+ remap(/\"\'/, "[greekdialytikatonos]")
+ remap(/\"\`/, "[greekdialytikavaria]")
+ remap(/\"\~/, "[greekdialytikaperispomeni]")
+ remap(/\</, "[greekdasia]")
+ remap(/\>/, "[greekpsili]")
+ remap(/\d.{0,2}''/, "")
+ remap(/\'/, "[greekoxia]")
+ remap(/\`/, "[greekvaria]")
+ remap(/\~/, "[perispomeni]")
+ remap(/\"/, "[greekdialytika]")
+ # unknown
+ # remap(/\|/, "[greekIotadialytika]")
+ # next
+ remap(/A/, "[greekAlpha]")
+ remap(/B/, "[greekBeta]")
+ remap(/D/, "[greekDelta]")
+ remap(/E/, "[greekEpsilon]")
+ remap(/F/, "[greekPhi]")
+ remap(/G/, "[greekGamma]")
+ remap(/H/, "[greekEta]")
+ remap(/I/, "[greekIota]")
+ remap(/J/, "[greekTheta]")
+ remap(/K/, "[greekKappa]")
+ remap(/L/, "[greekLambda]")
+ remap(/M/, "[greekMu]")
+ remap(/N/, "[greekNu]")
+ remap(/O/, "[greekOmicron]")
+ remap(/P/, "[greekPi]")
+ remap(/Q/, "[greekChi]")
+ remap(/R/, "[greekRho]")
+ remap(/S/, "[greekSigma]")
+ remap(/T/, "[greekTau]")
+ remap(/U/, "[greekUpsilon]")
+ remap(/W/, "[greekOmega]")
+ remap(/X/, "[greekXi]")
+ remap(/Y/, "[greekPsi]")
+ remap(/Z/, "[greekZeta]")
+ remap(/a/, "[greekalpha]")
+ remap(/b/, "[greekbeta]")
+ remap(/c/, "[greekfinalsigma]")
+ remap(/d/, "[greekdelta]")
+ remap(/e/, "[greekepsilon]")
+ remap(/f/, "[greekphi]")
+ remap(/g/, "[greekgamma]")
+ remap(/h/, "[greeketa]")
+ remap(/i/, "[greekiota]")
+ remap(/j/, "[greektheta]")
+ remap(/k/, "[greekkappa]")
+ remap(/l/, "[greeklambda]")
+ remap(/m/, "[greekmu]")
+ remap(/n/, "[greeknu]")
+ remap(/o/, "[greekomicron]")
+ remap(/p/, "[greekpi]")
+ remap(/q/, "[greekchi]")
+ remap(/r/, "[greekrho]")
+ remap(/s/, "[greeksigma]")
+ remap(/t/, "[greektau]")
+ remap(/u/, "[greekupsilon]")
+ remap(/w/, "[greekomega]")
+ remap(/x/, "[greekxi]")
+ remap(/y/, "[greekpsi]")
+ remap(/z/, "[greekzeta]")
+ clone("[greekalphatonos]", "[greekalphaoxia]")
+ clone("[greekepsilontonos]", "[greekepsilonoxia]")
+ clone("[greeketatonos]", "[greeketaoxia]")
+ clone("[greekiotatonos]", "[greekiotaoxia]")
+ clone("[greekomicrontonos]", "[greekomicronoxia]")
+ clone("[greekupsilontonos]", "[greekupsilonoxia]")
+ clone("[greekomegatonos]", "[greekomegaoxia]")
+ when 'ru' then
+ remap(/\xC1/, "[cyrillica]")
+ remap(/\xC2/, "[cyrillicb]")
+ remap(/\xD7/, "[cyrillicv]")
+ remap(/\xC7/, "[cyrillicg]")
+ remap(/\xC4/, "[cyrillicd]")
+ remap(/\xC5/, "[cyrillice]")
+ remap(/\xD6/, "[cyrilliczh]")
+ remap(/\xDA/, "[cyrillicz]")
+ remap(/\xC9/, "[cyrillici]")
+ remap(/\xCA/, "[cyrillicishrt]")
+ remap(/\xCB/, "[cyrillick]")
+ remap(/\xCC/, "[cyrillicl]")
+ remap(/\xCD/, "[cyrillicm]")
+ remap(/\xCE/, "[cyrillicn]")
+ remap(/\xCF/, "[cyrillico]")
+ remap(/\xD0/, "[cyrillicp]")
+ remap(/\xD2/, "[cyrillicr]")
+ remap(/\xD3/, "[cyrillics]")
+ remap(/\xD4/, "[cyrillict]")
+ remap(/\xD5/, "[cyrillicu]")
+ remap(/\xC6/, "[cyrillicf]")
+ remap(/\xC8/, "[cyrillich]")
+ remap(/\xC3/, "[cyrillicc]")
+ remap(/\xDE/, "[cyrillicch]")
+ remap(/\xDB/, "[cyrillicsh]")
+ remap(/\xDD/, "[cyrillicshch]")
+ remap(/\xDF/, "[cyrillichrdsn]")
+ remap(/\xD9/, "[cyrillicery]")
+ remap(/\xD8/, "[cyrillicsftsn]")
+ remap(/\xDC/, "[cyrillicerev]")
+ remap(/\xC0/, "[cyrillicyu]")
+ remap(/\xD1/, "[cyrillicya]")
+ remap(/\xA3/, "[cyrillicyo]")
+ when 'tr' then
+ remap(/\^\^11/, "[dotlessi]")
+ else
+ end
+
+ if ! encoding.empty? then
+ begin
+ filename = Kpse.found(filename, 'context')
+ if data = IO.readlines(filename.chomp) then
+ report("preloading #{encoding} character mappings")
+ accept = false
+ data.each do |line|
+ case line.chomp
+ when /\\start(en|)coding\s*\[(.*?)\]/io then
+ enc = $2
+ if accept = (enc == encoding) then
+ report("accepting vector #{enc}")
+ else
+ report("skipping vector #{enc}")
+ end
+ when /\\stop(en|)coding/io then
+ accept = false
+ when accept && /\\definecharacter\s*([a-zA-Z]+)\s*(\d+)\s*/o then
+ name, number = $1, $2
+ remap(/\^\^#{sprintf("%02x",number)}/, "[#{name}]")
+ if number.to_i > 127 then
+ remap(/#{sprintf("\\%03o",number)}/, "[#{name}]")
+ end
+ end
+ end
+ end
+ rescue
+ end
+ end
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ public
+
+ @@languagedata = Hash.new
+
+ def patternfiles
+ language = @commandline.argument('first')
+ if (language == 'all') || language.empty? then
+ languages = @@languagedata.keys.sort
+ elsif @@languagedata.key?(language) then
+ languages = [language]
+ else
+ languages = []
+ end
+ languages.each do |language|
+ encoding = @@languagedata[language][0] || ''
+ files = @@languagedata[language][1] || []
+ Language::generate(self,language,files,encoding)
+ end
+ end
+
+ private
+
+ # todo: filter the fallback list from context
+
+ # The first entry in the array is the encoding which will be used
+ # when interpreting the raw patterns. The second entry is a list of
+ # filesets (string|aray), each first match of a set is taken.
+
+ @@languagedata['ba' ] = [ 'ec' , ['bahyph.tex'] ]
+ @@languagedata['ca' ] = [ 'ec' , ['cahyph.tex'] ]
+ @@languagedata['cy' ] = [ 'ec' , ['cyhyph.tex'] ]
+ @@languagedata['cs' ] = [ 'ec' , ['czhyphen.tex','czhyphen.ex'] ]
+ @@languagedata['de' ] = [ 'ec' , ['dehyphn.tex'] ]
+ @@languagedata['deo'] = [ 'ec' , ['dehypht.tex'] ]
+ @@languagedata['da' ] = [ 'ec' , ['dkspecial.tex','dkcommon.tex'] ]
+ # elhyph.tex
+ @@languagedata['es' ] = [ 'ec' , ['eshyph.tex'] ]
+ @@languagedata['et' ] = [ 'ec' , ['ethyph.tex'] ]
+ @@languagedata['fi' ] = [ 'ec' , ['fihyph.tex'] ]
+ @@languagedata['fr' ] = [ 'ec' , ['frhyph.tex'] ]
+ # ghyphen.readme ghyph31.readme grphyph
+ @@languagedata['hr' ] = [ 'ec' , ['hrhyph.tex'] ]
+ @@languagedata['hu' ] = [ 'ec' , ['huhyphn.tex'] ]
+ @@languagedata['us' ] = [ 'default' , [['ushyphmax.tex'],['ushyph.tex'],['hyphen.tex']] ]
+ @@languagedata['us' ] = [ 'default' , [['ushyphmax.tex'],['ushyph.tex'],['hyphen.tex']] ]
+ # inhyph.tex
+ @@languagedata['is' ] = [ 'ec' , ['ishyph.tex'] ]
+ @@languagedata['it' ] = [ 'ec' , ['ithyph.tex'] ]
+ @@languagedata['la' ] = [ 'ec' , ['lahyph.tex'] ]
+ # mnhyph
+ @@languagedata['nl' ] = [ 'ec' , ['nehyph96.tex'] ]
+ # @@languagedata['no' ] = [ 'ec' , ['nohyphbx.tex'],['nohyphb.tex'],['nohyph2.tex'],['nohyph1.tex'],['nohyph.tex'] ]
+ @@languagedata['no' ] = [ 'ec' , [['asxsx.tex','nohyphbx.tex'],['nohyphb.tex'],['nohyph2.tex'],['nohyph1.tex'],['nohyph.tex']] ]
+ @@languagedata['agr'] = [ 'agr' , [['grahyph4.tex'], ['oldgrhyph.tex']] ] # new, todo
+ @@languagedata['pl' ] = [ 'ec' , ['plhyph.tex'] ]
+ @@languagedata['pt' ] = [ 'ec' , ['pthyph.tex'] ]
+ @@languagedata['ro' ] = [ 'ec' , ['rohyph.tex'] ]
+ @@languagedata['sl' ] = [ 'ec' , [['slhyph.tex'], ['sihyph.tex']] ]
+ @@languagedata['sk' ] = [ 'ec' , ['skhyphen.tex','skhyphen.ex'] ]
+ # sorhyph.tex / upper sorbian
+ # srhyphc.tex / cyrillic
+ @@languagedata['sv' ] = [ 'ec' , ['svhyph.tex'] ]
+ @@languagedata['tr' ] = [ 'ec' , ['tkhyph.tex'] ]
+ @@languagedata['gb' ] = [ 'default' , [['ukhyphen.tex'],['ukhyph.tex']] ]
+ # @@languagedata['ru' ] = [ 't2a' , ['ruhyphal.tex'] ] # t2a does not work
+ @@languagedata['ru' ] = [ 'cyr' , ['ruhyphal.tex'] ]
+end
+
+class Commands
+
+ include CommandBase
+
+ def dpxmapfiles
+
+ force = @commandline.option("force")
+
+ texmfroot = @commandline.argument('first')
+ texmfroot = '.' if texmfroot.empty?
+ if @commandline.option('maproot') != "" then
+ maproot = @commandline.option('maproot')
+ else
+ maproot = "#{texmfroot.gsub(/\\/,'/')}/fonts/map/pdftex/context"
+ end
+ if File.directory?(maproot) then
+ files = Dir.glob("#{maproot}/*.map")
+ if files.size > 0 then
+ files.each do |pdffile|
+ next if File.basename(pdffile) == 'pdftex.map'
+ pdffile = File.expand_path(pdffile)
+ dpxfile = File.expand_path(pdffile.sub(/(dvips|pdftex)/i,'dvipdfm'))
+ unless pdffile == dpxfile then
+ begin
+ if data = File.read(pdffile) then
+ report("< #{File.basename(pdffile)} - pdf(e)tex")
+ n = 0
+ data = data.collect do |line|
+ if line =~ /^[\%\#]+/mo then
+ ''
+ else
+ encoding = if line =~ /([a-z0-9\-]+)\.enc/io then $1 else '' end
+ fontfile = if line =~ /([a-z0-9\-]+)\.(pfb|ttf)/io then $1 else nil end
+ metrics = if line =~ /^([a-z0-9\-]+)[\s\<]+/io then $1 else nil end
+ slant = if line =~ /\"([\d\.]+)\s+SlantFont\"/io then "-s #{$1}" else '' end
+ if metrics && encoding && fontfile then
+ n += 1
+ "#{metrics} #{encoding} #{fontfile} #{slant}"
+ else
+ ''
+ end
+ end
+ end
+ data.delete_if do |line|
+ line.gsub(/\s+/,'').empty?
+ end
+ data.collect! do |line|
+ # remove line with "name name" lines
+ line.gsub(/^(\S+)\s+\1\s*$/) do
+ $1
+ end
+ end
+ begin
+ if force then
+ if n > 0 then
+ File.makedirs(File.dirname(dpxfile))
+ if f = File.open(dpxfile,'w') then
+ report("> #{File.basename(dpxfile)} - dvipdfm(x) - #{n}")
+ f.puts(data)
+ f.close
+ else
+ report("? #{File.basename(dpxfile)} - dvipdfm(x)")
+ end
+ else
+ report("- #{File.basename(dpxfile)} - dvipdfm(x) - no entries")
+ # begin File.delete(dpxname) ; rescue ; end
+ if f = File.open(dpxfile,'w') then
+ f.puts("% no map entries")
+ f.close
+ end
+ end
+ else
+ report(". #{File.basename(dpxfile)} - dvipdfm(x) - #{n}")
+ end
+ rescue
+ report("error in saving dvipdfm file")
+ end
+ else
+ report("error in loading pdftex file")
+ end
+ rescue
+ report("error in processing pdftex file")
+ end
+ end
+ end
+ if force then
+ begin
+ report("regenerating database for #{texmfroot}")
+ system("mktexlsr #{texmfroot}")
+ rescue
+ end
+ end
+ else
+ report("no mapfiles found in #{maproot}")
+ end
+ else
+ report("provide proper texmfroot")
+ end
+
+ end
+
+end
+
+class Array
+
+ def add_shebang(filename,program)
+ unless self[0] =~ /^\#/ then
+ self.insert(0,"\#!/usr/bin/env #{program}")
+ end
+ unless self[2] =~ /^\#.*?copyright\=/ then
+ self.insert(1,"\#")
+ self.insert(2,"\# copyright=pragma-ade readme=readme.pdf licence=cc-gpl")
+ self.insert(3,"") unless self[3].chomp.strip.empty?
+ self[2].gsub!(/ +/, ' ')
+ return true
+ else
+ return false
+ end
+ end
+
+ def add_directive(filename,program)
+ unless self[0] =~ /^\%/ then
+ self.insert(0,"\% content=#{program}")
+ end
+ unless self[2] =~ /^\%.*?copyright\=/ then
+ self.insert(1,"\%")
+ if File.expand_path(filename) =~ /[\\\/](doc|manuals)[\\\/]/ then
+ self.insert(2,"\% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa")
+ else
+ self.insert(2,"\% copyright=pragma-ade readme=readme.pdf licence=cc-gpl")
+ end
+ self.insert(3,"") unless self[3].chomp.strip.empty?
+ self[0].gsub!(/ +/, ' ')
+ return true
+ else
+ return false
+ end
+ end
+
+ def add_comment(filename)
+ if self[0] =~ /<\?xml.*?\?>/ && self[2] !~ /^<\!\-\-.*?copyright\=.*?\-\->/ then
+ self.insert(1,"")
+ if File.expand_path(filename) =~ /[\\\/](doc|manuals)[\\\/]/ then
+ self.insert(2,"<!-- copyright='pragma-ade' readme='readme.pdf' licence='cc-by-nc-sa' -->")
+ else
+ self.insert(2,"<!-- copyright='pragma-ade' readme='readme.pdf' licence='cc-gpl' -->")
+ end
+ self.insert(3,"") unless self[3].chomp.strip.empty?
+ return true
+ else
+ return false
+ end
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ def brandfiles
+
+ force = @commandline.option("force")
+ files = @commandline.arguments # Dir.glob("**/*.*")
+ done = false
+
+ files.each do |filename|
+ if FileTest.file?(filename) then
+ ok = false
+ begin
+ data = IO.readlines(filename)
+ case filename
+ when /\.rb$/ then
+ ok = data.add_shebang(filename,'ruby')
+ when /\.pl$/ then
+ ok = data.add_shebang(filename,'perl')
+ when /\.py$/ then
+ ok = data.add_shebang(filename,'python')
+ when /\.tex$/ then
+ ok = data.add_directive(filename,'tex')
+ when /\.mp$/ then
+ ok = data.add_directive(filename,'metapost')
+ when /\.mf$/ then
+ ok = data.add_directive(filename,'metafont')
+ when /\.(xml|xsl|fo|fx|rlx|rng|exa)$/ then
+ ok = data.add_comment(filename)
+ end
+ rescue
+ report("fatal error in processing #{filename}") # maybe this catches the mac problem taco reported
+ else
+ if ok then
+ report()
+ report(filename)
+ report()
+ for i in 0..4 do
+ report(' ' + data[i].chomp)
+ end
+ if force && f = File.open(filename,'w') then
+ f.puts data
+ f.close
+ end
+ done = true
+ end
+ end
+ else
+ report("no file named #{filename}")
+ end
+ end
+ report() if done
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ # usage : ctxtools --listentities entities.xml
+ # document: <!DOCTYPE something SYSTEM "entities.xml">
+
+ def flushentities(handle,entities,doctype=nil) # 'stylesheet'
+ if doctype then
+ tab = "\t"
+ handle << "<?xml version='1.0' encoding='utf-8'?>\n\n"
+ handle << "<!-- !DOCTYPE entities SYSTEM 'entities.xml' -->\n\n"
+ handle << "<!DOCTYPE #{doctype} [\n"
+ else
+ tab = ""
+ end
+ entities.keys.sort.each do |k|
+ handle << "#{tab}<!ENTITY #{k} \"\&\#x#{entities[k]};\">\n"
+ end
+ if doctype then
+ handle << "]>\n"
+ end
+ end
+
+ def listentities
+
+ filenames = ['enco-uc.tex','contextnames.txt']
+ outputname = @commandline.argument('first')
+ doctype = @commandline.option('doctype')
+ entities = Hash.new
+
+ filenames.each do |filename|
+ filename = Kpse.found(filename, 'context')
+ if filename and not filename.empty? and FileTest.file?(filename) then
+ report("loading #{filename.gsub(/\\/,'/')}") unless outputname.empty?
+ IO.readlines(filename).each do |line|
+ case line
+ when /^[\#\%]/io then
+ # skip comment line
+ when /\\definecharacter\s+([a-z]+)\s+\{\\uchar\{*(\d+)\}*\{(\d+)\}\}/io then
+ name, code = $1, sprintf("%04X",$2.to_i*256 + $3.to_i)
+ entities[name] = code.rjust(4,'0') unless entities.key?(name)
+ when /^([A-F0-9]+)\;([a-z][a-z]+)\;(.*?)\;(.*?)\s*$/io then
+ code, name, adobe, comment = $1, $2, $3, $4
+ entities[name] = code.rjust(4,'0') unless entities.key?(name)
+ end
+ end
+ end
+ end
+ if outputname and not outputname.empty? then
+ if f = File.open(outputname,'w') then
+ report("saving #{entities.size} entities in #{outputname}")
+ flushentities(f,entities,doctype)
+ f.close
+ else
+ flushentities($stdout,entities,doctype)
+ end
+ else
+ flushentities($stdout,entities,doctype)
+ end
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ def platformize
+
+ pattern = if @commandline.arguments.empty? then "*.{rb,pl,py}" else @commandline.arguments end
+ recurse = @commandline.option("recurse")
+ force = @commandline.option("force")
+ pattern = "#{if recurse then '**/' else '' end}#{pattern}"
+ Dir.glob(pattern).each do |file|
+ if File.file?(file) then
+ size = File.size(file)
+ data = IO.readlines(file)
+ if force then
+ if f = File.open(file,'w')
+ data.each do |line|
+ f.puts(line.chomp)
+ end
+ f.close
+ end
+ if File.size(file) == size then # not robust
+ report("file '#{file}' is unchanged")
+ else
+ report("file '#{file}' is platformized")
+ end
+ else
+ report("file '#{file}' is a candidate")
+ end
+ end
+ end
+ end
+
+end
+
+class TexDeps
+
+ @@cs_tex = %q/
+ above abovedisplayshortskip abovedisplayskip
+ abovewithdelims accent adjdemerits advance afterassignment
+ aftergroup atop atopwithdelims
+ badness baselineskip batchmode begingroup
+ belowdisplayshortskip belowdisplayskip binoppenalty botmark
+ box boxmaxdepth brokenpenalty
+ catcode char chardef cleaders closein closeout clubpenalty
+ copy count countdef cr crcr csname
+ day deadcycles def defaulthyphenchar defaultskewchar
+ delcode delimiter delimiterfactor delimeters
+ delimitershortfall delimeters dimen dimendef discretionary
+ displayindent displaylimits displaystyle
+ displaywidowpenalty displaywidth divide
+ doublehyphendemerits dp dump
+ edef else emergencystretch end endcsname endgroup endinput
+ endlinechar eqno errhelp errmessage errorcontextlines
+ errorstopmode escapechar everycr everydisplay everyhbox
+ everyjob everymath everypar everyvbox exhyphenpenalty
+ expandafter
+ fam fi finalhyphendemerits firstmark floatingpenalty font
+ fontdimen fontname futurelet
+ gdef global group globaldefs
+ halign hangafter hangindent hbadness hbox hfil horizontal
+ hfill horizontal hfilneg hfuzz hoffset holdinginserts hrule
+ hsize hskip hss horizontal ht hyphenation hyphenchar
+ hyphenpenalty hyphen
+ if ifcase ifcat ifdim ifeof iffalse ifhbox ifhmode ifinner
+ ifmmode ifnum ifodd iftrue ifvbox ifvmode ifvoid ifx
+ ignorespaces immediate indent input inputlineno input
+ insert insertpenalties interlinepenalty
+ jobname
+ kern
+ language lastbox lastkern lastpenalty lastskip lccode
+ leaders left lefthyphenmin leftskip leqno let limits
+ linepenalty line lineskip lineskiplimit long looseness
+ lower lowercase
+ mag mark mathaccent mathbin mathchar mathchardef mathchoice
+ mathclose mathcode mathinner mathop mathopen mathord
+ mathpunct mathrel mathsurround maxdeadcycles maxdepth
+ meaning medmuskip message mkern month moveleft moveright
+ mskip multiply muskip muskipdef
+ newlinechar noalign noboundary noexpand noindent nolimits
+ nonscript scriptscript nonstopmode nulldelimiterspace
+ nullfont number
+ omit openin openout or outer output outputpenalty over
+ overfullrule overline overwithdelims
+ pagedepth pagefilllstretch pagefillstretch pagefilstretch
+ pagegoal pageshrink pagestretch pagetotal par parfillskip
+ parindent parshape parskip patterns pausing penalty
+ postdisplaypenalty predisplaypenalty predisplaysize
+ pretolerance prevdepth prevgraf
+ radical raise read relax relpenalty right righthyphenmin
+ rightskip romannumeral
+ scriptfont scriptscriptfont scriptscriptstyle scriptspace
+ scriptstyle scrollmode setbox setlanguage sfcode shipout
+ show showbox showboxbreadth showboxdepth showlists showthe
+ skewchar skip skipdef spacefactor spaceskip span special
+ splitbotmark splitfirstmark splitmaxdepth splittopskip
+ string
+ tabskip textfont textstyle the thickmuskip thinmuskip time
+ toks toksdef tolerance topmark topskip tracingcommands
+ tracinglostchars tracingmacros tracingonline tracingoutput
+ tracingpages tracingparagraphs tracingrestores tracingstats
+ uccode uchyph underline unhbox unhcopy unkern unpenalty
+ unskip unvbox unvcopy uppercase
+ vadjust valign vbadness vbox vcenter vfil vfill vfilneg
+ vfuzz voffset vrule vsize vskip vsplit vss vtop
+ wd widowpenalty write
+ xdef xleaders xspaceskip
+ year
+ /.split
+
+ @@cs_etex = %q/
+ beginL beginR botmarks
+ clubpenalties currentgrouplevel currentgrouptype
+ currentifbranch currentiflevel currentiftype
+ detokenize dimexpr displaywidowpenalties
+ endL endR eTeXrevision eTeXversion everyeof
+ firstmarks fontchardp fontcharht fontcharic fontcharwd
+ glueexpr glueshrink glueshrinkorder gluestretch
+ gluestretchorder gluetomu
+ ifcsname ifdefined iffontchar interactionmode
+ interactionmode interlinepenalties
+ lastlinefit lastnodetype
+ marks topmarks middle muexpr mutoglue
+ numexpr
+ pagediscards parshapedimen parshapeindent parshapelength
+ predisplaydirection
+ savinghyphcodes savingvdiscards scantokens showgroups
+ showifs showtokens splitdiscards splitfirstmarks
+ TeXXeTstate tracingassigns tracinggroups tracingifs
+ tracingnesting tracingscantokens
+ unexpanded unless
+ widowpenalties
+ /.split
+
+ @@cs_pdftex = %q/
+ pdfadjustspacing pdfannot pdfavoidoverfull
+ pdfcatalog pdfcompresslevel
+ pdfdecimaldigits pdfdest pdfdestmargin
+ pdfendlink pdfendthread
+ pdffontattr pdffontexpand pdffontname pdffontobjnum pdffontsize
+ pdfhorigin
+ pdfimageresolution pdfincludechars pdfinfo
+ pdflastannot pdflastdemerits pdflastobj
+ pdflastvbreakpenalty pdflastxform pdflastximage
+ pdflastximagepages pdflastxpos pdflastypos
+ pdflinesnapx pdflinesnapy pdflinkmargin pdfliteral
+ pdfmapfile pdfmaxpenalty pdfminpenalty pdfmovechars
+ pdfnames
+ pdfobj pdfoptionpdfminorversion pdfoutline pdfoutput
+ pdfpageattr pdfpageheight pdfpageresources pdfpagesattr
+ pdfpagewidth pdfpkresolution pdfprotrudechars
+ pdfrefobj pdfrefxform pdfrefximage
+ pdfsavepos pdfsnaprefpoint pdfsnapx pdfsnapy pdfstartlink
+ pdfstartthread
+ pdftexrevision pdftexversion pdfthread pdfthreadmargin
+ pdfuniqueresname
+ pdfvorigin
+ pdfxform pdfximage
+ /.split
+
+ @@cs_omega = %q/
+ odelimiter omathaccent omathchar oradical omathchardef omathcode odelcode
+ leftghost rightghost
+ charwd charht chardp charit
+ localleftbox localrightbox
+ localinterlinepenalty localbrokenpenalty
+ pagedir bodydir pardir textdir mathdir
+ boxdir nextfakemath
+ pagewidth pageheight pagerightoffset pagebottomoffset
+ nullocp nullocplist ocp externalocp ocplist pushocplist popocplist clearocplists ocptracelevel
+ addbeforeocplist addafterocplist removebeforeocplist removeafterocplist
+ OmegaVersion
+ InputTranslation OutputTranslation DefaultInputTranslation DefaultOutputTranslation
+ noInputTranslation noOutputTranslation
+ InputMode OutputMode DefaultInputMode DefaultOutputMode
+ noInputMode noOutputMode noDefaultInputMode noDefaultOutputMode
+ /.split
+
+ @@cs_metatex = %q/
+ /.split
+
+ @@cs_xetex = %q/
+ /.split
+
+ @@cs_skip = %q/
+ v\! c\! s\! e\! m\! f\!
+ \!tf \!tt \!tq \!ta \?\?
+ csname endcsname relax
+ \!\!string[a-f] \!\!dimen[a-k] \!\!count[a-f] \!\!toks[a-e] \!\!box[a-e]
+ \!\!width[a-c] \!\!height[a-c] \!\!depth[a-c]
+ \!\!done[a-f] if\!\!done[a-f] if\:\!\!done[a-f]
+ scratch globalscratch
+ ascii[a-d] globalascii
+ @@expanded @@globalexpanded @EA @EAEA @EAEAEA
+ bgroup egroup par next nextnext docommand dodocommand dododocommand
+ \!\!width \!\!height \!\!depth \!\!plus \!\!minus \!\!to
+ /.split
+
+ @@cs_skip = %q/
+ [vcsemf]\! \?\?
+ \!t[ftqa]
+ csname endcsname relax
+ \!\!string[a-f] \!\!dimen[a-k] \!\!count[a-f] \!\!toks[a-e] \!\!box[a-e]
+ \!\!width[a-c] \!\!height[a-c] \!\!depth[a-c]
+ \!\!done[a-f] if\!\!done[a-f] if\:\!\!done[a-f]
+ scratch globalscratch
+ ascii[a-d] globalascii
+ @@expanded @@globalexpanded @(EA)+
+ [be]group par next nextnext (do)+command
+ \!\!(width|height|depth|plus|minus|to)
+ /.split
+
+ # let's ignore \dimendef etc
+
+ @@primitives_def = %q/
+ def edef xdef gdef let
+ newcount newdimen newskip newbox newtoks newmarks newif newinsert newmuskip
+ chardef mathchardef dimendef countdef toksdef
+ newconditional definecomplexorsimple definecomplexorsimpleempty
+ newcounter newpersistentmark
+ installinsertion installspecial\s*\\[* installoutput\s*\\[*
+ /.split
+
+ @@types = [['invalid','*'],['okay','='],['forward','>'],['backward','<'],['unknown','?']]
+
+ @@skips = /^(#{@@cs_skip.join('|')})/o
+
+ def initialize(logger=nil,compact=false)
+ @defined = Hash.new
+ @definitive = Hash.new
+ @used_before = Hash.new
+ @used_after = Hash.new
+ @dependencies = Hash.new
+ @fineorder = Hash.new
+ @forward = Hash.new
+ @backward = Hash.new
+ @disorder = Hash.new
+ @disordercs = Hash.new
+ @type = Hash.new
+ @filename = 'context.tex'
+ @files = Array.new # keep load order !
+ @order = Hash.new
+ @logger = logger
+ @filefilter = nil
+ @namefilter = nil
+ @compact = compact
+ #
+ @@cs_tex.each do |cs| @defined[cs] = ['-tex--------'] end
+ @@cs_etex.each do |cs| @defined[cs] = ['-etex-------'] end
+ @@cs_pdftex.each do |cs| @defined[cs] = ['-pdftex-----'] end
+ @@cs_omega.each do |cs| @defined[cs] = ['-omega------'] end
+ @@cs_xetex.each do |cs| @defined[cs] = ['-xetex------'] end
+ @@cs_metatex.each do |cs| @defined[cs] = ['-metatex----'] end
+ end
+
+ def report(str)
+ @logger.report(str) rescue false
+ end
+
+ def setfilter(data)
+ data.split(/\s*\,\s*/).each do |d|
+ if d =~ /\.tex$/ then
+ @filefilter = Array.new unless @filefilter
+ @filefilter << d
+ else
+ @namefilter = Array.new unless @namefilter
+ @namefilter << d
+ end
+ end
+ end
+
+ def load(filename='context.tex')
+ begin
+ @filename = filename
+ n = 0
+ File.open(filename) do |f|
+ f.each do |line|
+ if line =~ /^(\\input\s+|\\load[a-z]+\{)([a-z\-\.]+)(\}*)/ then
+ ante, name, post = $1, $2, $3
+ @files.push(name)
+ @order[name] = n += 1
+ end
+ end
+ end
+ rescue
+ @files = Array.new
+ @order = Hash.new
+ end
+ end
+
+ def save(filename='context.tex')
+ unless @filefilter || @namefilter then
+ begin
+ data = IO.readlines(filename).each do |line|
+ line.gsub!(/^(\\input\s+|\\load[a-z]+\{)([a-z\-\.]+)(\}*)\s*$/) do
+ ante, name, post = $1, $2, $3
+ fin = (@fineorder[name] || [])-[name]
+ dep = (@dependencies[name] || [])-[name]
+ dis = (@disorder[name] || [])-[name]
+ fin = if fin.size > 0 then " B[#{fin.join(' ')}]" else "" end
+ dep = if dep.size > 0 then " A[#{dep.join(' ')}]" else "" end
+ dis = if dis.size > 0 then " D[#{dis.join(' ')}]" else "" end
+ "#{ante}#{name}#{post} %#{fin}#{dep}#{dis}\n"
+ end
+ end
+ rescue
+ report("error: #{$!}")
+ else
+ begin
+ newname = filename.sub(/\..*$/,'.log')
+ report("")
+ report("writing to #{newname}")
+ report("")
+ File.open(newname,'w') do |f|
+ f << data
+ end
+ rescue
+ report("error: #{$!}")
+ end
+ end
+ end
+ end
+
+ def analyze
+ report('')
+ report("loading files")
+ report('')
+ n = 0
+# try tex and mkiv
+ @files.each do |filename|
+ if File.file?(filename) and f = File.open(filename) then
+ defs, uses, l = 0, 0, 0
+ n += 1
+ report("#{n.to_s.rjust(5,' ')} #{filename}")
+ f.each do |line|
+ l += 1
+ line.chomp!
+
+
+ line.sub!(/\%.*$/, '')
+ line.gsub!(/\\(unexpanded|unprotected|global|protected|long)\s*(\\)/, "\\")
+ # the superseded, overloaded, forwarded, and predefined macros
+ # are at the outer level anyway, so there we may ignore leading
+ # spaces (could be inside an \if); other definitions are only
+ # accepted when they start at the beginning of a line
+ case line
+ when /^\\ifx\s*\\[a-zA-Z\@\!\?]+\s*\\undefined\s*(\\else)*(.*?)$/ then
+ if $2 =~ /^\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})/o then
+ pushdef(filename,l,$2,5) # kind of auto-predefined
+ end
+ when /^\s*\\superseded\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o
+ name, rest = $2, $3
+ pushdef(filename,l,name,1)
+ moreuse(filename,l,rest)
+ when /^\s*\\overloaded\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o
+ name, rest = $2, $3
+ pushdef(filename,l,name,2)
+ moreuse(filename,l,rest)
+ when /^\s*\\forwarded\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o
+ name, rest = $2, $3
+ pushdef(filename,l,name,3)
+ moreuse(filename,l,rest)
+ when /^\s*\\predefined\s*\\(#{@@primitives_def.join('|')})\s*\\([a-zA-Z\@\?\!]{3,})(.*)$/o
+ name, rest = $2, $3
+ pushdef(filename,l,name,4)
+ moreuse(filename,l,rest)
+ when /^\\(#{@@primitives_def.join('|')})[\=\s]*\\([a-zA-Z\@\?\!]{3,})(.*)$/o
+ name, rest = $2, $3 # \=* catches the \let \a = \b
+ pushdef(filename,l,name,0)
+ moreuse(filename,l,rest)
+ when /\\newevery\s*\\([a-zA-Z\@\?\!]+)\s*\\([a-zA-Z\@\?\!]+)/ then
+ a, b = $1, $2
+ pushdef(filename,l,a,0)
+ pushdef(filename,l,b,0)
+ else
+ moreuse(filename,l,line)
+ end
+ end
+ f.close
+ end
+ end
+ @used_after.each do |cs,files|
+ (@defined[cs] || []).each do |name|
+ @dependencies[name] = Array.new unless @dependencies[name]
+ files.each do |file|
+ @dependencies[name] << file unless @dependencies[name].include?(file)
+ end
+ end
+ end
+ @used_before.each do |cs,files|
+ (@defined[cs] || []).each do |name|
+ @disorder[name] = Array.new unless @disorder[name]
+ @disordercs[name] = Array.new unless @disordercs[name]
+ @fineorder[name] = Array.new unless @fineorder[name]
+ files.each do |file|
+ unless @disorder[name].include?(file) || name == file then
+ unless @defined[cs].include?(file) then
+ if @order[name] > @order[file] then
+ @disorder[name] << file
+ @disordercs[name] << "#{file}:#{cs}"
+ end
+ end
+ end
+ @fineorder[name] << file unless @fineorder[name].include?(file) || name == file
+ end
+ end
+ end
+ end
+
+ def moreuse(filename,l,line)
+ line.scan(/\\if([a-zA-Z@\?\!]{3,})/) do |name, rest| # rest, else array
+ pushuse(filename,l,"if#{name}") unless name =~ /^(true|false)$/
+ end
+ line.scan(/\\([a-zA-Z@\?\!]{3,})/) do |name, rest| # rest, else array
+ if name =~ /(true|false)$/ then
+ pushuse(filename,l,"if#{name}") unless name =~ /^(if|set)$/
+ else
+ pushuse(filename,l,name)
+ end
+ end
+ end
+
+ def feedback
+ begin
+ # get max length
+ l = 0
+ list = @defined.keys.sort
+ list.each do |cs|
+ l = cs.length if cs.length > l
+ end
+ if ! @compact then
+ n = 0
+ report('')
+ report("defined: #{@defined.size}")
+ report('')
+ @defined.keys.sort.each do |cs|
+ next if @namefilter && ! @namefilter.include?(cs)
+ next if @filefilter && ! @defined[cs].include?(cs)
+ if @defined[cs].size > 1 then
+ dlist = @defined[cs].collect do |d|
+ if d == @definitive[cs] then d else "[#{d}]" end
+ end
+ else
+ dlist = @defined[cs]
+ end
+ report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{dlist.join(' ')}")
+ end
+ end
+ if true then
+ n = 0
+ report('')
+ report("used before defined: #{@used_before.size}")
+ report('')
+ @used_before.keys.sort.each do |cs|
+ next if @namefilter && ! @namefilter.include?(cs)
+ next if @filefilter && (@used_before[cs] & @filefilter).size == 0
+ used = @used_before[cs] - (@defined[cs] || [])
+ defined = (@defined[cs] || []).join(' ')
+ defined = "[ ? ]" if defined.empty?
+ if used.size > 0 then
+ report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined} -> #{used.join(' ')}")
+ else
+ report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined}")
+ end
+ end
+ report(' none') if n == 0
+ end
+ if ! @compact then
+ n = 0
+ report('')
+ report("used after defined: #{@used_after.size}")
+ report('')
+ @used_after.keys.sort.each do |cs|
+ next if @namefilter && ! @namefilter.include?(cs)
+ next if @filefilter && (@used_after[cs] & @filefilter).size == 0
+ used = @used_after[cs] - (@defined[cs] || [])
+ defined = (@defined[cs] || []).join(' ')
+ if used.size > 0 then
+ report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined} <- #{used.join(' ')}")
+ else
+ report("#{(n += 1).to_s.rjust(5,' ')} #{cs.ljust(l,' ')} == #{defined}")
+ end
+ end
+ report(' none') if n == 0
+ end
+ if ! @compact then
+ unless @filefilter || @namefilter then
+ [false,true].each do |mode|
+ n = 0
+ report("")
+ report("file dependecies #{if mode then '(critical)' end}")
+ [@dependencies].each do |dependencies|
+ report("")
+ dependencies.keys.sort.each do |f|
+ if dependencies[f].size > 0 then
+ dependencies[f].delete(f)
+ end
+ if mode then
+ dep = dependencies[f].delete_if do |d|
+ f[0..3] == d[0..3] # same xxxx- prefix
+ end
+ else
+ dep = dependencies[f]
+ end
+ if dep.size > 0 then
+ name = f.nosuffix('tex').ljust(8,' ')
+ list = dep.sort.collect do |k| k.nosuffix('tex') end
+ report("#{(n += 1).to_s.rjust(5,' ')} #{name} !! #{list.join(' ')}")
+ end
+ end
+ end
+ report(' none') if n == 0
+ end
+ end
+ end
+ if true then
+ unless @filefilter || @namefilter then
+ [false,true].each do |mode|
+ [@disorder,@disordercs].each do |disorder|
+ n = 0
+ report("")
+ report("file disorder #{if mode then '(critical)' end}")
+ report("")
+ disorder.keys.sort.each do |f|
+ if disorder[f].size > 0 then
+ disorder[f].delete(f)
+ end
+ if mode then
+ dis = disorder[f].delete_if do |d|
+ f[0..3] == d[0..3] # same xxxx- prefix
+ end
+ else
+ dis = disorder[f]
+ end
+ if dis.size > 0 then
+ name = f.nosuffix('tex').ljust(8,' ')
+ list = dis.sort.collect do |k| k.nosuffix('tex') end
+ report("#{(n += 1).to_s.rjust(3,' ')} #{name} ?? #{list.join(' ')}")
+ end
+ end
+ end
+ report(' none') if n == 0
+ end
+ end
+ end
+ rescue
+ puts("fatal error: #{$!} #{$@.join("\n")}")
+ end
+ end
+
+ private
+
+ def csdefined?(cs,filename)
+ @defined[cs] && @defined[cs].include?(filename)
+ end
+ def csbefore?(cs,filename)
+ @used_before[cs] && @used_before[cs].include?(filename)
+ end
+ def csafter?(cs,filename)
+ @used_after[cs] && @used_after[cs].include?(filename)
+ end
+
+ def csignored?(cs)
+ cs.to_s =~ @@skips
+ end
+
+ def pushdef(filename,n,cs,type)
+ if csignored?(cs) then
+ # nothing
+ elsif @defined[cs] then
+ case type
+ when 5 then
+ # if test, no definition done
+ else
+ @definitive[cs] = filename
+ unless @filefilter || @namefilter then
+ report("#{cs} is redefined") unless csdefined?(cs,filename) || @compact
+ end
+ end
+ @defined[cs] << filename unless @defined[cs].include?(filename)
+ else
+ @defined[cs] = Array.new
+ @defined[cs] << filename
+ @definitive[cs] = filename
+ @type[cs] = type
+ end
+ end
+
+ def pushuse(filename,n,cs)
+ if csignored?(cs) then
+ # nothing
+ elsif @defined[cs] then
+ @used_after[cs] = Array.new unless @used_after[cs]
+ @used_after[cs] << filename unless csafter?(cs,filename)
+ else
+ @used_before[cs] = Array.new unless @used_before[cs]
+ @used_before[cs] << filename unless csbefore?(cs,filename)
+ end
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ def dependencies
+
+ filename = if @commandline.arguments.empty? then 'context.tex' else @commandline.arguments.first end
+ compact = @commandline.option('compact')
+
+ ['context',''].each do |progname|
+ unless FileTest.file?(filename) then
+ name = Kpse.found(filename, progname)
+ if FileTest.file?(name) then
+ filename = name
+ break
+ end
+ end
+ end
+
+ if FileTest.file?(filename) && deps = TexDeps.new(logger,compact) then
+ deps.setfilter(@commandline.option('filter'))
+ deps.load
+ deps.analyze
+ deps.feedback
+ deps.save if @commandline.option('save')
+ else
+ report("unknown file #{filename}")
+ end
+
+ end
+
+end
+
+class Commands
+
+ @@re_utf_bom = /^\357\273\277/o # just utf-8
+
+ def disarmutfbom
+
+ if @commandline.arguments.empty? then
+ report("provide filename")
+ else
+ @commandline.arguments.each do |filename|
+ report("checking '#{filename}'")
+ if FileTest.file?(filename) then
+ begin
+ data = IO.read(filename)
+ if data.sub!(@@re_utf_bom,'') then
+ if @commandline.option('force') then
+ if f = File.open(filename,'wb') then
+ f << data
+ f.close
+ report("bom found and removed")
+ else
+ report("bom found and removed, but saving file fails")
+ end
+ else
+ report("bom found, use '--force' to remove it")
+ end
+ else
+ report("no bom found")
+ end
+ rescue
+ report("bom found, but removing it fails")
+ end
+ else
+ report("provide valid filename")
+ end
+ end
+ end
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ def updatecontext
+
+ def fetchfile(site, name, target=nil)
+ begin
+ proxy = @commandline.option('proxy')
+ if proxy && ! proxy.empty? then
+ address, port = proxy.split(":")
+ if address && port then
+ http = Net::HTTP::Proxy(address, port).new(site)
+ else
+ http = Net::HTTP::Proxy(proxy, 80).new(site)
+ end
+ else
+ http = Net::HTTP.new(site)
+ end
+ resp, data = http.get(name.gsub(/^\/*/, '/'))
+ rescue
+ return false
+ else
+ begin
+ if data then
+ name = File.basename(name)
+ File.open(target || name, 'wb') do |f|
+ f << data
+ end
+ else
+ return false
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+ end
+
+ def locatedlocaltree
+ tree = Kpse.used_path('TEXMFLOCAL')
+ unless tree && FileTest.directory?(tree) then
+ tree = Kpse.used_path('TEXMF')
+ end
+ return tree
+ end
+
+ def extractarchive(archive)
+ unless FileTest.file?(archive) then
+ report("fatal error, '#{archive}' has not been downloaded")
+ return false
+ end
+ # unless system("unzip -uo #{archive}") then
+ unless system("unzip -o #{archive}") then
+ report("fatal error, make sure that you have 'unzip' in your path")
+ return false
+ end
+ stubs = "scripts/context/stubs/unix/*"
+ if System.unix? and not system("chmod +x #{stubs}") then
+ report("change x-permissions of '#{stubs}' manually")
+ end
+ return true
+ end
+
+ def remakeformats
+ system("mktexlsr")
+ system("texmfstart texexec --make --all --fast --pdftex")
+ system("texmfstart texexec --make --all --fast --xetex")
+ return true
+ end
+
+ if localtree = locatedlocaltree then
+ report("updating #{localtree}")
+ begin
+ Dir.chdir(localtree)
+ rescue
+ report("unable to change to #{localtree}")
+ else
+ archive = 'cont-tmf.zip'
+ report("fetching #{archive}")
+ unless fetchfile("www.pragma-ade.com","/context/latest/#{archive}") then
+ report("unable to fetch #{archive}")
+ return
+ end
+ report("extracting #{archive}")
+ unless extractarchive(archive) then
+ report("unable to extract #{archive}")
+ return
+ end
+ report("remaking formats")
+ unless remakeformats then
+ report("unable to remak formats")
+ end
+ end
+ else
+ report("unable to locate local tree")
+ end
+
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('touchcontextfile' , 'update context version')
+commandline.registeraction('contextversion' , 'report context version')
+commandline.registeraction('jeditinterface' , 'generate jedit syntax files [--pipe]')
+commandline.registeraction('bbeditinterface' , 'generate bbedit syntax files [--pipe]')
+commandline.registeraction('sciteinterface' , 'generate scite syntax files [--pipe]')
+commandline.registeraction('rawinterface' , 'generate raw syntax files [--pipe]')
+# commandline.registeraction('translateinterface', 'generate interface files (xml) [nl de ..]')
+commandline.registeraction('purgefiles' , 'remove temporary files [--all --recurse] [basename]')
+commandline.registeraction('documentation' , 'generate documentation [--type=] [filename]')
+commandline.registeraction('filterpages' ) # no help, hidden temporary feature
+commandline.registeraction('patternfiles' , 'generate pattern files [--all --xml --utf8] [languagecode]')
+commandline.registeraction('dpxmapfiles' , 'convert pdftex mapfiles to dvipdfmx [--force] [texmfroot]')
+commandline.registeraction('listentities' , 'create doctype entity definition from enco-uc.tex')
+commandline.registeraction('brandfiles' , 'add context copyright notice [--force]')
+commandline.registeraction('platformize' , 'replace line-endings [--recurse --force] [pattern]')
+commandline.registeraction('dependencies' , 'analyze depedencies within context [--save --compact --filter=[macros|filenames]] [filename]')
+commandline.registeraction('updatecontext' , 'download latest version and remake formats [--proxy]')
+commandline.registeraction('disarmutfbom' , 'remove utf bom [--force]')
+
+commandline.registervalue('type','')
+commandline.registervalue('filter','')
+commandline.registervalue('maproot','')
+commandline.registervalue('proxy','')
+
+commandline.registerflag('recurse')
+commandline.registerflag('force')
+commandline.registerflag('compact')
+commandline.registerflag('pipe')
+commandline.registerflag('save')
+commandline.registerflag('all')
+commandline.registerflag('xml')
+commandline.registerflag('log')
+commandline.registerflag('utf8')
+commandline.registerflag('doctype')
+
+# general
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/Master/texmf-dist/scripts/context/ruby/graphics/gs.rb b/Master/texmf-dist/scripts/context/ruby/graphics/gs.rb
new file mode 100644
index 00000000000..6143c881232
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/graphics/gs.rb
@@ -0,0 +1,684 @@
+# module : graphics/gs
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/variables','../variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+# ['base/system', '../system', 'system' ].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/variables'
+require 'base/system'
+require 'fileutils'
+# Require 'ftools'
+
+class GhostScript
+
+ include Variables
+
+ @@pdftrimwhite = 'pdftrimwhite.pl'
+
+ @@pstopdfoptions = [
+ 'AntiAliasColorImages',
+ 'AntiAliasGrayImages',
+ 'AntiAliasMonoImages',
+ 'ASCII85EncodePages',
+ 'AutoFilterColorImages',
+ 'AutoFilterGrayImages',
+ 'AutoPositionEPSFiles',
+ 'AutoRotatePages',
+ 'Binding',
+ 'ColorConversionStrategy',
+ 'ColorImageDepth',
+ 'ColorImageDownsampleThreshold',
+ 'ColorImageDownsampleType',
+ 'ColorImageFilter',
+ 'ColorImageResolution',
+ 'CompatibilityLevel',
+ 'CompressPages',
+ #'ConvertCMYKImagesToRGB', # buggy
+ #'ConvertImagesToIndexed', # buggy
+ 'CreateJobTicket',
+ 'DetectBlends',
+ 'DoThumbnails',
+ 'DownsampleColorImages',
+ 'DownsampleGrayImages',
+ 'DownsampleMonoImages',
+ 'EmbedAllFonts',
+ 'EncodeColorImages',
+ 'EncodeGrayImages',
+ 'EncodeMonoImages',
+ 'EndPage',
+ 'FirstPage',
+ 'GrayImageDepth',
+ 'GrayImageDownsampleThreshold',
+ 'GrayImageDownsampleType',
+ 'GrayImageFilter',
+ 'GrayImageResolution',
+ 'MaxSubsetPct',
+ 'MonoImageDepth',
+ 'MonoImageDownsampleThreshold',
+ 'MonoImageDownsampleType',
+ 'MonoImageFilter',
+ 'MonoImageResolution',
+ 'Optimize',
+ 'ParseDCSComments',
+ 'ParseDCSCommentsForDocInfo',
+ 'PreserveCopyPage',
+ 'PreserveEPSInfo',
+ 'PreserveHalftoneInfo',
+ 'PreserveOPIComments',
+ 'PreserveOverprintSettings',
+ 'SubsetFonts',
+ 'UseFlateCompression'
+ ]
+
+ @@methods = Hash.new
+
+ @@methods['raw'] = '1'
+ @@methods['bound'] = '2'
+ @@methods['bounded'] = '2'
+ @@methods['crop'] = '3'
+ @@methods['cropped'] = '3'
+ @@methods['down'] = '4'
+ @@methods['downsample'] = '4'
+ @@methods['downsampled'] = '4'
+ @@methods['simplify'] = '5'
+ @@methods['simplified'] = '5'
+
+ @@tempfile = 'gstemp'
+ @@pstempfile = @@tempfile + '.ps'
+ @@pdftempfile = @@tempfile + '.pdf'
+
+ @@bboxspec = '\s*([\-\d\.]+)' + '\s+([\-\d\.]+)'*3
+
+ def initialize(logger=nil)
+
+ unless logger then
+ puts('gs class needs a logger')
+ exit
+ end
+
+ @variables = Hash.new
+ @psoptions = Hash.new
+ @logger = logger
+
+ setvariable('profile', 'gsprofile.ini')
+ setvariable('pipe', true)
+ setvariable('method', 2)
+ setvariable('force', false)
+ setvariable('colormodel', 'cmyk')
+ setvariable('inputfile', '')
+ setvariable('outputfile', '')
+
+ @@pstopdfoptions.each do |key|
+ @psoptions[key] = ''
+ end
+
+ reset
+
+ end
+
+ def reset
+ @llx = @lly = @ulx = @uly = 0
+ @oldbbox = [@llx,@lly,@urx,@ury]
+ @width = @height = @xoffset = @yoffset = @offset = 0
+ @rs = Tool.default_line_separator
+ end
+
+ def supported?(filename)
+ psfile?(filename) || pdffile?(filename)
+ end
+
+ def psfile?(filename)
+ filename =~ /\.(eps|epsf|ps|ai\d*)$/io
+ end
+
+ def pdffile?(filename)
+ filename =~ /\.(pdf)$/io
+ end
+
+ def setpsoption(key,value)
+ @psoptions[key] = value unless value.empty?
+ end
+
+ def setdimensions (llx,lly,urx,ury)
+ @oldbbox = [llx,lly,urx,ury]
+ @llx, @lly = llx.to_f-@offset, lly.to_f-@offset
+ @urx, @ury = urx.to_f+@offset, ury.to_f+@offset
+ @width, @height = @urx - @llx, @ury - @lly
+ @xoffset, @yoffset = 0 - @llx, 0 - @lly
+ end
+
+ def setoffset (offset=0)
+ @offset = offset.to_f
+ setdimensions(@llx,@lly,@urx,@ury) if dimensions?
+ end
+
+ def resetdimensions
+ setdimensions(0,0,0,0)
+ end
+
+ def dimensions?
+ (@width>0) && (@height>0)
+ end
+
+ def convert
+
+ inpfile = getvariable('inputfile')
+
+ if inpfile.empty? then
+ report('no inputfile specified')
+ return false
+ end
+
+ unless FileTest.file?(inpfile) then
+ report("unknown input file #{inpfile}")
+ return false
+ end
+
+ outfile = getvariable('outputfile')
+
+ if outfile.empty? then
+ outfile = inpfile
+ outfile = outfile.sub(/^.*[\\\/]/,'')
+ end
+
+ outfile = outfile.sub(/\.(pdf|eps|ps|ai)/i, "")
+ resultfile = outfile + '.pdf'
+ setvariable('outputfile', resultfile)
+
+ # flags
+
+ saveprofile(getvariable('profile'))
+
+ begin
+ gsmethod = method(getvariable('method')).to_i
+ report("conversion method #{gsmethod}")
+ rescue
+ gsmethod = 1
+ report("fallback conversion method #{gsmethod}")
+ end
+
+ debug('piping data') if getvariable('pipe')
+
+ ok = false
+ begin
+ case gsmethod
+ when 0, 1 then ok = convertasis(inpfile,resultfile)
+ when 2 then ok = convertbounded(inpfile,resultfile)
+ when 3 then ok = convertcropped(inpfile,resultfile)
+ when 4 then ok = downsample(inpfile,resultfile,'screen')
+ when 5 then ok = downsample(inpfile,resultfile,'prepress')
+ else report("invalid conversion method #{gsmethod}")
+ end
+ rescue
+ report("job aborted due to some error: #{$!}")
+ begin
+ File.delete(resultfile) if FileTest.file?(resultfile)
+ rescue
+ report("unable to delete faulty #{resultfile}")
+ end
+ ok = false
+ ensure
+ deleteprofile(getvariable('profile'))
+ File.delete(@@pstempfile) if FileTest.file?(@@pstempfile)
+ File.delete(@@pdftempfile) if FileTest.file?(@@pdftempfile)
+ end
+ return ok
+ end
+
+ # private
+
+ def method (str)
+ if @@methods.key?(str) then
+ @@methods[str]
+ else
+ str
+ end
+ end
+
+ def pdfmethod? (str)
+ case method(str).to_i
+ when 1, 3, 4, 5 then return true
+ end
+ return false
+ end
+
+ def pdfprefix (str)
+ case method(str).to_i
+ when 1 then return 'raw-'
+ when 4 then return 'lowres-'
+ when 5 then return 'normal-'
+ end
+ return ''
+ end
+
+ def psmethod? (str)
+ ! pdfmethod?(str)
+ end
+
+ def insertprofile (flags)
+ for key in flags.keys do
+ replacevariable("flag.#{key}", flags[key])
+ end
+ end
+
+ def deleteprofile (filename)
+ begin
+ File.delete(filename) if FileTest.file?(filename)
+ rescue
+ end
+ end
+
+ def saveprofile (filename)
+ return if filename.empty? || ! (ini = open(filename,"w"))
+ @@pstopdfoptions.each do |k|
+ str = @psoptions[k]
+ # beware, booleans are translated, but so are yes/no which is dangerous
+ if str.class == String then
+ if ! str.empty? && (str != 'empty') then
+ str.sub!(/(.+)\-/io, '')
+ str = "/" + str unless str =~ /^(true|false|none|[\d\.\-\+]+)$/
+ ini.puts("-d#{k}=#{str}\n")
+ end
+ end
+ end
+ ini.close
+ debug("gs profile #{filename} saved")
+ end
+
+ def gsstream # private
+ if getvariable('pipe') then '-' else @@pstempfile end
+ end
+
+ def gscolorswitch
+ case getvariable('colormodel')
+ when 'cmyk' then '-dProcessColorModel=/DeviceCMYK -dColorConversionStrategy=/CMYK '
+ when 'rgb' then '-dProcessColorModel=/DeviceRGB -dColorConversionStrategy=/RGB '
+ when 'gray' then '-dProcessColorModel=/DeviceGRAY -dColorConversionStrategy=/GRAY '
+ else
+ ''
+ end
+ end
+
+ def gsdefaults
+ defaults = ''
+ begin
+ defaults << '-dAutoRotatePages=/None ' if @psoptions['AutoRotatePages'].empty?
+ rescue
+ defaults << '-dAutoRotatePages=/None '
+ end
+ return defaults
+ end
+
+ def convertasis (inpfile, outfile)
+
+ report("converting #{inpfile} as-is")
+
+ @rs = Tool.line_separator(inpfile)
+ debug("platform mac") if @rs == "\r"
+
+ arguments = ''
+ arguments << "\@gsprofile.ini "
+ arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH "
+ arguments << "#{gsdefaults} "
+ arguments << "#{gscolorswitch} "
+ arguments << "-sOutputFile=#{outfile} #{inpfile} -c quit "
+
+ debug("ghostscript: #{arguments}")
+ unless ok = System.run('ghostscript',arguments) then
+ begin
+ report("removing file #{outfile}")
+ File.delete(outfile) if FileTest.file?(outfile)
+ rescue
+ debug("file #{outfile} may be invalid")
+ end
+ end
+ return ok
+
+ end
+
+ def convertbounded(inpfile, outfile)
+ report("converting #{inpfile} bounded")
+ do_convertbounded(inpfile, outfile)
+ end
+
+ def do_convertbounded(inpfile, outfile)
+
+ begin
+ return false if FileTest.file?(outfile) && (! File.delete(outfile))
+ rescue
+ return false
+ end
+
+ arguments = ''
+ arguments << "\@gsprofile.ini "
+ arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH -dSAFER "
+ arguments << "#{gscolorswitch} "
+ arguments << "#{gsdefaults} "
+ arguments << "-sOutputFile=#{outfile} #{gsstream} -c quit "
+
+ debug("ghostscript: #{arguments}")
+ debug('opening input file')
+
+ @rs = Tool.line_separator(inpfile)
+ debug("platform mac") if @rs == "\r"
+
+ if FileTest.file?(outfile) and not File.writable?(outfile) then
+ report("output file cannot be written")
+ return false
+ elsif not tmp = open(inpfile, 'rb') then
+ report("input file cannot be opened")
+ return false
+ end
+
+ debug('opening pipe/file')
+
+ if getvariable('pipe') then
+
+ return false unless eps = IO.popen(System.command('ghostscript',arguments),'wb')
+ debug('piping data')
+ unless pipebounded(tmp,eps) then
+ debug('something went wrong in the pipe')
+ File.delete(outfile) if FileTest.file?(outfile)
+ end
+ debug('closing pipe')
+ eps.close_write
+
+ else
+
+ return false unless eps = File.open(@@pstempfile, 'wb')
+
+ debug('copying data')
+
+ if pipebounded(tmp,eps) then
+ eps.close
+ debug('processing temp file')
+ begin
+ ok = System.run('ghostscript',arguments)
+ rescue
+ ok = false
+ # debug("fatal error: #{$!}")
+ ensure
+ end
+ else
+ eps.close
+ ok = false
+ end
+
+ unless ok then
+ begin
+ report('no output file due to error')
+ File.delete(outfile) if FileTest.file?(outfile)
+ rescue
+ # debug("fatal error: #{$!}")
+ debug('file',outfile,'may be invalid')
+ end
+ end
+
+ debug('deleting temp file')
+ begin
+ File.delete(@@pstempfile) if FileTest.file?(@@pstempfile)
+ rescue
+ end
+
+ end
+
+ tmp.close
+ return FileTest.file?(outfile)
+
+ end
+
+ # hm, strange, no execute here, todo ! ! !
+
+ def getdimensions (inpfile)
+
+ # -dEPSFitPage and -dEPSCrop behave weird (don't work)
+
+ arguments = "-sDEVICE=bbox -dSAFER -dNOPAUSE -dBATCH #{inpfile} "
+
+ debug("ghostscript: #{arguments}")
+
+ begin
+ bbox = System.run('ghostscript',arguments,true,true)
+ rescue
+ bbox = ''
+ end
+
+ resetdimensions
+
+ debug('bbox spec', bbox)
+
+ if bbox =~ /(Exact|HiRes)BoundingBox:#{@@bboxspec}/moi then
+ debug("high res bbox #{$2} #{$3} #{$4} #{$5}")
+ setdimensions($2,$3,$4,$5)
+ elsif bbox =~ /BoundingBox:#{@@bboxspec}/moi
+ debug("low res bbox #{$1} #{$2} #{$3} #{$4}")
+ setdimensions($1,$2,$3,$4)
+ end
+
+ return dimensions?
+
+ end
+
+ # def convertcropped (inpfile, outfile)
+ # report("converting #{inpfile} cropped")
+ # do_convertbounded(inpfile, @@pdftempfile)
+ # return unless FileTest.file?(@@pdftempfile)
+ # arguments = " --offset=#{@offset} #{@@pdftempfile} #{outfile}"
+ # report("calling #{@@pdftrimwhite}")
+ # unless ok = System.run(@@pdftrimwhite,arguments) then
+ # report('cropping failed')
+ # begin
+ # File.delete(outfile)
+ # rescue
+ # end
+ # begin
+ # File.move(@@pdftempfile,outfile)
+ # rescue
+ # File.copy(@@pdftempfile,outfile)
+ # File.delete(@@pdftempfile)
+ # end
+ # end
+ # return ok
+ # end
+
+ def convertcropped (inpfile, outfile)
+ report("converting #{inpfile} cropped")
+ if File.expand_path(inpfile) == File.expand_path(outfile) then
+ report("output filename must be different")
+ elsif inpfile =~ /\.pdf$/io then
+ System.run("pdftops -eps #{inpfile} #{@@pstempfile}")
+ if getdimensions(@@pstempfile) then
+ report("tight boundingbox found")
+ end
+ do_convertbounded(@@pstempfile, outfile)
+ File.delete(@@pstempfile) if FileTest.file?(@@pstempfile)
+ else
+ if getdimensions(inpfile) then
+ report("tight boundingbox found")
+ end
+ do_convertbounded(inpfile, outfile)
+ end
+ resetdimensions
+ return true
+ end
+
+
+ def pipebounded (eps, out)
+
+ epsbbox, skip, buffer = false, false, ''
+
+ while str = eps.gets(rs=@rs) do
+ if str =~ /^%!PS/oi then
+ debug("looks like a valid ps file")
+ break
+ elsif str =~ /%PDF\-\d+\.\d+/oi then
+ debug("looks like a pdf file, so let\'s quit")
+ return false
+ end
+ end
+
+ # why no BeginData check
+
+ eps.rewind
+
+if dimensions? then
+
+ debug('using found boundingbox')
+
+else
+
+ debug('locating boundingbox')
+ while str = eps.gets(rs=@rs) do
+ case str
+ when /^%%Page:/io then
+ break
+ when /^%%(Crop|HiResBounding|ExactBounding)Box:#{@@bboxspec}/moi then
+ debug('high res boundingbox found')
+ setdimensions($2,$3,$4,$5)
+ break
+ when /^%%BoundingBox:#{@@bboxspec}/moi then
+ debug('low res boundingbox found')
+ setdimensions($1,$2,$3,$4)
+ end
+ end
+ debug('no boundingbox found') if @width == 0
+
+end
+
+ eps.rewind
+
+ while str = eps.gets(rs=@rs) do
+ if str.sub!(/^(.*)%!PS/moi, "%!PS") then
+ debug("removing pre banner data")
+ out.puts(str)
+ break
+ end
+ end
+
+ while str = eps.gets(rs=@rs) do
+ if skip then
+ skip = false if str =~ /^%+(EndData|EndPhotoshop|BeginProlog).*$/o
+ out.puts(str) if $1 == "BeginProlog"
+ elsif str =~ /^%(BeginPhotoshop)\:\s*\d+.*$/o then
+ skip = true
+ elsif str =~ /^%%/mos then
+ if ! epsbbox && str =~ /^%%(Page:|EndProlog)/io then
+ out.puts(str) if $1 == "EndProlog"
+ debug('faking papersize')
+ # out.puts("<< /PageSize [#{@width} #{@height}] >> setpagedevice\n")
+ if ! dimensions? then
+ out.puts("<< /PageSize [1 1] >> setpagedevice\n")
+ else
+ out.puts("<< /PageSize [#{@width} #{@height}] >> setpagedevice\n")
+ end
+ out.puts("gsave #{@xoffset} #{@yoffset} translate\n")
+ epsbbox = true
+ elsif str =~ /^%%BeginBinary\:\s*\d+\s*$/o then
+ debug('copying binary data')
+ out.puts(str)
+ while str = eps.gets(rs=@rs)
+ if str =~ /^%%EndBinary\s*$/o then
+ out.puts(str)
+ else
+ out.write(str)
+ end
+ end
+ elsif str =~ /^%AI9\_PrivateDataBegin/o then
+ debug('ignore private ai crap')
+ break
+ elsif str =~ /^%%EOF/o then
+ debug('ignore post eof crap')
+ break
+ # elsif str =~ /^%%PageTrailer/o then
+ # debug('ignoring post page trailer crap')
+ # break
+ elsif str =~ /^%%Trailer/o then
+ debug('ignoring post trailer crap')
+ break
+ elsif str =~ /^%%Creator.*Illustrator.*$/io then
+ debug('getting rid of problematic creator spec')
+ str = "% Creator: Adobe Illustrator ..."
+ out.puts(str)
+ elsif str =~ /^%%AI.*(PaperRect|Margin)/io then
+ debug('removing AI paper crap')
+ elsif str =~ /^%%AI.*Version.*$/io then
+ debug('removing dangerous version info')
+ elsif str =~ /^(%+AI.*Thumbnail.*)$/o then
+ debug('skipping AI thumbnail')
+ skip = true
+ else
+ out.puts(str)
+ end
+ else
+ out.puts(str)
+ end
+ end
+
+ debug('done, sending EOF')
+
+ out.puts "grestore\n%%EOF\n"
+
+ # ok = $? == 0
+ # report('process aborted, broken pipe, fatal error') unless ok
+ # return ok
+
+resetdimensions
+
+ return true
+
+ end
+
+ def downsample (inpfile, outfile, method='screen')
+
+ # gs <= 8.50
+
+ report("downsampling #{inpfile}")
+
+ doit = true
+ unless getvariable('force') then
+ begin
+ if f = File.open(inpfile) then
+ f.binmode
+ while doit && (data = f.gets) do
+ if data =~ /\/ArtBox\s*\[\s*[\d\.]+\s+[\d\.]+\s+[\d\.]+\s+[\d\.]+\s*\]/io then
+ doit = false
+ end
+ end
+ f.close
+ end
+ rescue
+ end
+ end
+
+ if doit then
+ arguments = ''
+ arguments << "-dPDFSETTINGS=/#{method} -dEmbedAllFonts=true "
+ arguments << "#{gscolorswitch} "
+ arguments << "#{gsdefaults} "
+ arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH -dSAFER "
+ arguments << "-sOutputFile=#{outfile} #{inpfile} -c quit "
+ unless ok = System.run('ghostscript',arguments) then
+ begin
+ File.delete(outfile) if FileTest.file?(outfile)
+ report("removing file #{outfile}")
+ rescue
+ debug("file #{outfile} may be invalid")
+ end
+ end
+ return ok
+ else
+ report("crop problem, straight copying #{inpfile}")
+ File.copy(inpfile,outfile)
+ return false
+ end
+
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/graphics/inkscape.rb b/Master/texmf-dist/scripts/context/ruby/graphics/inkscape.rb
new file mode 100644
index 00000000000..8f22d9b7954
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/graphics/inkscape.rb
@@ -0,0 +1,113 @@
+# module : graphics/inkscape
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+# ['graphics/gs','gs'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/variables'
+require 'base/system'
+require 'graphics/gs'
+
+class InkScape
+
+ include Variables
+
+ def initialize(logger=nil)
+
+ unless logger then
+ puts('inkscape class needs a logger')
+ exit
+ end
+
+ @variables = Hash.new
+ @logger = logger
+
+ reset
+
+ end
+
+ def reset
+ # nothing yet
+ end
+
+ def supported?(filename)
+ filename =~ /.*\.(svg|svgz)/io
+ end
+
+ def convert(logfile=System.null)
+
+ directpdf = false
+
+ logfile = logfile.gsub(/\/+$/,"")
+
+ inpfilename = getvariable('inputfile').dup
+ outfilename = getvariable('outputfile').dup
+ outfilename = inpfilename.dup if outfilename.empty?
+ outfilename.gsub!(/(\.[^\.]*?)$/, ".pdf")
+ tmpfilename = outfilename.gsub(/(\.[^\.]*?)$/, ".ps")
+
+ if inpfilename.empty? || outfilename.empty? then
+ report("no filenames given")
+ return false
+ end
+ if inpfilename == outfilename then
+ report("filenames must differ (#{inpfilename} #{outfilename})")
+ return false
+ end
+ unless FileTest.file?(inpfilename) then
+ report("unknown file #{inpfilename}")
+ return false
+ end
+
+ # we need to redirect the error info else we get a pop up console
+
+ if directpdf then
+ report("converting #{inpfilename} to #{outfilename}")
+ # resultpipe = "--without-gui --export-pdf=\"#{outfilename}\" 2>#{logfile}"
+ resultpipe = "--without-gui --export-filename=\"#{outfilename}\" 2>#{logfile}"
+ else
+ report("converting #{inpfilename} to #{tmpfilename}")
+ resultpipe = "--without-gui --print=\">#{tmpfilename}\" 2>#{logfile}"
+ end
+
+ arguments = [resultpipe,inpfilename].join(' ').gsub(/\s+/,' ')
+
+ ok = true
+ begin
+ debug("inkscape: #{arguments}")
+ # should work
+ # ok = System.run('inkscape',arguments) # does not work here
+ # but 0.40 only works with this:
+ command = "inkscape #{arguments}"
+ report(command)
+ ok = system(command)
+ # and 0.41 fails with everything
+ # and 0.45 is better
+ rescue
+ report("aborted due to error")
+ return false
+ else
+ return false unless ok
+ end
+
+ if not directpdf then
+ ghostscript = GhostScript.new(@logger)
+ ghostscript.setvariable('inputfile',tmpfilename)
+ ghostscript.setvariable('outputfile',outfilename)
+ report("converting #{tmpfilename} to #{outfilename}")
+ ghostscript.convert
+ begin
+ File.delete(tmpfilename)
+ rescue
+ end
+ end
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/graphics/magick.rb b/Master/texmf-dist/scripts/context/ruby/graphics/magick.rb
new file mode 100644
index 00000000000..f59087bdf44
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/graphics/magick.rb
@@ -0,0 +1,161 @@
+# module : graphics/inkscape
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/variables'
+
+class ImageMagick
+
+ include Variables
+
+ def initialize(logger=nil)
+
+ unless logger then
+ puts('magick class needs a logger')
+ exit
+ end
+
+ @variables = Hash.new
+ @logger = logger
+
+ reset
+
+ end
+
+ def reset
+ ['compression','depth','colorspace','quality'].each do |key|
+ setvariable(key)
+ end
+ end
+
+ def supported?(filename) # ? pdf
+ filename =~ /.*\.(png|gif|tif|tiff|jpg|jpeg|eps|ai\d*)/io
+ end
+
+ def convert(suffix='pdf')
+
+ inpfilename = getvariable('inputfile').dup
+ outfilename = getvariable('outputfile').dup
+ outfilename = inpfilename.dup if outfilename.empty?
+ outfilename.gsub!(/(\.[^\.]*?)$/, ".#{suffix}")
+
+ if inpfilename.empty? || outfilename.empty? then
+ report("no filenames given")
+ return false
+ end
+ if inpfilename == outfilename then
+ report("filenames must differ (#{inpfilename} #{outfilename})")
+ return false
+ end
+ unless FileTest.file?(inpfilename) then
+ report("unknown file #{inpfilename}")
+ return false
+ end
+
+ if inpfilename =~ /\.tif+$/io then
+ tmpfilename = 'temp.png'
+ arguments = "#{inpfilename} #{tmpfilename}"
+ begin
+ debug("imagemagick: #{arguments}")
+ ok = System.run('imagemagick',arguments)
+ rescue
+ report("aborted due to error")
+ return false
+ else
+ return false unless ok
+ end
+ inpfilename = tmpfilename
+ end
+
+ compression = depth = colorspace = quality = ''
+
+ if getvariable('compression') =~ /(zip|jpeg)/o then
+ compression = " -compress #{$1}"
+ end
+ if getvariable('depth') =~ /(8|16)/o then
+ depth = "-depth #{$1}"
+ end
+ if getvariable('colorspace') =~ /(gray|rgb|cmyk)/o then
+ colorspace = "-colorspace #{$1}"
+ end
+ case getvariable('quality')
+ when 'low' then quality = '-quality 0'
+ when 'medium' then quality = '-quality 75'
+ when 'high' then quality = '-quality 100'
+ end
+
+ report("converting #{inpfilename} to #{outfilename}")
+
+ arguments = [compression,depth,colorspace,quality,inpfilename,outfilename].join(' ').gsub(/\s+/,' ')
+
+ begin
+ debug("imagemagick: #{arguments}")
+ ok = System.run('imagemagick',arguments)
+ rescue
+ report("aborted due to error")
+ return false
+ else
+ return ok
+ end
+
+ end
+
+ def autoconvert
+
+ inpfilename = getvariable('inputfile')
+ outfilename = getvariable('outputfile')
+
+ if inpfilename.empty? || ! FileTest.file?(inpfilename) then
+ report("missing file #{inpfilename}")
+ return
+ end
+
+ outfilename = inpfilename.dup if outfilename.empty?
+ tmpfilename = 'temp.jpg'
+
+ reset
+
+ megabyte = 1024*1024
+
+ ok = false
+
+ if FileTest.size(inpfilename)>2*megabyte
+ setvariable('compression','zip')
+ ok = convert
+ else
+ setvariable('compression','jpeg')
+ if FileTest.size(inpfilename)>10*megabyte then
+ setvariable('quality',85)
+ elsif FileTest.size(inpfilename)>5*megabyte then
+ setvariable('quality',90)
+ else
+ setvariable('quality',95)
+ end
+ report("auto quality #{getvariable('quality')}")
+ setvariable('outputfile', tmpfilename)
+ ok = convert('jpg')
+ setvariable('inputfile', tmpfilename)
+ setvariable('outputfile', outfilename)
+ ok = convert
+ begin
+ File.delete(tmpfilename)
+ rescue
+ report("#{tmpfilename} cannot be deleted")
+ end
+ end
+
+ reset
+
+ return ok
+
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/imgtopdf.rb b/Master/texmf-dist/scripts/context/ruby/imgtopdf.rb
new file mode 100644
index 00000000000..98a36c17fd9
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/imgtopdf.rb
@@ -0,0 +1,86 @@
+#!/usr/bin/env ruby
+
+# program : newimgtopdf
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2006
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'')
+ $: << ownpath
+end
+
+require 'base/switch'
+require 'base/logger'
+
+require 'graphics/magick'
+
+banner = ['ImgToPdf', 'version 1.1.2', '2002-2006', 'PRAGMA ADE/POD']
+
+class Commands
+
+ include CommandBase
+
+ # nowadays we would force a directive, but
+ # for old times sake we handle default usage
+
+ def main
+ filename = @commandline.argument('first')
+
+ if filename.empty? then
+ help
+ else
+ convert
+ end
+ end
+
+ # actions
+
+ def convert
+
+ magick = Magick.new(session)
+
+ ['compression','depth','colorspace','quality','inputpath','outputpath'].each do |v|
+ magick.setvariable(v,@commandline.option(v))
+ end
+
+ @commandline.arguments.each do |fullname|
+ magick.setvariable('inputfile',fullname)
+ magick.setvariable('outputfile',fullname.gsub(/(\..*?$)/io, '.pdf'))
+ if @commandline.option('auto') then
+ magick.autoconvert
+ else
+ magick.convert
+ end
+ end
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registerflag('auto')
+
+commandline.registervalue('compression')
+commandline.registervalue('depth')
+commandline.registervalue('colorspace')
+commandline.registervalue('quality')
+
+commandline.registervalue('inputpath')
+commandline.registervalue('outputpath')
+
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registeraction('convert', 'convert image into pdf')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'main')
diff --git a/Master/texmf-dist/scripts/context/ruby/pdftools.rb b/Master/texmf-dist/scripts/context/ruby/pdftools.rb
new file mode 100644
index 00000000000..8ad74ec4f36
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/pdftools.rb
@@ -0,0 +1,861 @@
+#!/usr/bin/env ruby
+
+# program : pdftools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2003-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# This script will harbor some handy manipulations on tex
+# related files.
+
+banner = ['PDFTools', 'version 1.2.1', '2003/2005', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'base/switch'
+require 'base/logger'
+
+require 'fileutils'
+# require 'ftools'
+
+class File
+
+ def File.deletefiles(*filenames)
+ filenames.flatten.each do |filename|
+ begin
+ delete(filename) if FileTest.file?(filename)
+ rescue
+ end
+ end
+ end
+
+ def File.needsupdate(oldname,newname)
+ begin
+ return File.stat(oldname).mtime != File.stat(newname).mtime
+ rescue
+ return true
+ end
+ end
+
+ def File.syncmtimes(oldname,newname)
+ begin
+ t = Time.now # i'm not sure if the time is frozen, so we do it here
+ File.utime(0,t,oldname,newname)
+ rescue
+ end
+ end
+
+ def File.replacesuffix(oldname,subpath='')
+ newname = File.expand_path(oldname.sub(/\.\w+?$/,'.pdf'))
+ File.join(File.dirname(newname),subpath,File.basename(newname))
+ end
+
+end
+
+class ImageMagick
+
+ def initialize
+
+ begin
+ version = `convert -version`
+ rescue
+ @binary = nil
+ ensure
+ if (version) && (! version.empty?) && (version =~ /ImageMagick/mo) && (version =~ /version/mio) then
+ @binary = 'convert'
+ else
+ @binary = 'imagemagick'
+ end
+ end
+
+ end
+
+ def process(arguments)
+ begin
+ @binary && system("#{@binary} #{arguments}")
+ rescue
+ false
+ end
+ end
+
+end
+
+class TexExec
+
+ def initialize
+ @binary = 'texmfstart texexec.pl --pdf --batch --silent --purge'
+ end
+
+ def process(arguments,once=true)
+ begin
+ if once then
+ @binary && system("#{@binary} --once #{arguments}")
+ else
+ @binary && system("#{@binary} #{arguments}")
+ end
+ rescue
+ false
+ end
+ end
+
+end
+
+class PdfImages
+
+ def initialize
+ @binary = "pdfimages"
+ end
+
+ def process(arguments)
+ begin
+ @binary && system("#{@binary} #{arguments}")
+ rescue
+ false
+ end
+ end
+
+end
+
+class ConvertImage
+
+ def initialize(command=nil)
+ @command = command
+ end
+
+ def convertimage(filename)
+
+ return if filename =~ /\.(pdf)$/io
+
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ if filename =~ /\s/ then
+ @command.report("skipping strange filename '#{filename}'")
+ else
+ newname = File.replacesuffix(filename,subpath)
+ # newname.gsub!(s/[^a-zA-Z0-9\_-\.]/o, '-')
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ imagemagick = ImageMagick.new
+ if imagemagick then
+ ok = imagemagick.process("-compress zip -quality 99 #{filename} #{newname}")
+ File.syncmtimes(oldname,newname) if retain
+ end
+ end
+ end
+ end
+
+end
+
+class DownsampleImage
+
+ def initialize(command=nil)
+ @command = command
+ end
+
+ def convertimage(filename)
+
+ return if filename =~ /\.(pdf)$/io
+
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ if @command.option('lowres') then
+ method = '4'
+ elsif @command.option('medres') || @command.option('normal') then
+ method = '5'
+ else
+ method = '4'
+ end
+
+ if filename =~ /\s/ then
+ @command.report("skipping strange filename '#{filename}'")
+ else
+ newname = File.replacesuffix(filename,subpath)
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ ok = system("texmfstart pstopdf.rb --method=#{method} #{filename} #{newname}")
+ File.syncmtimes(oldname,newname) if retain
+ end
+ end
+ end
+
+end
+
+class ColorImage
+
+ def initialize(command=nil,tmpname='pdftools')
+ @command = command
+ @tmpname = tmpname
+ @colorname = nil
+ @colorspec = nil
+ @colorspace = nil
+ end
+
+ def registercolor(spec='.5',name='c')
+ name = name || 'c'
+ spec = spec.split(',')
+ case spec.length
+ when 4
+ @colorname, @colorspec, @colorspace = name, spec.join('/'), 'cmyk'
+ when 3
+ @colorname, @colorspec, @colorspace = name, spec.join('/'), 'rgb'
+ when 1
+ @colorname, @colorspec, @colorspace = name, spec.join('/'), 'gray'
+ else
+ @colorname, @colorspec, @colorspace = nil, nil, nil
+ end
+ end
+
+ def convertimage(filename)
+
+ invert = @command.option('invert')
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ subpath += '/' unless subpath.empty?
+
+ if @colorname && ! @colorname.empty? && @colorspec && ! @colorspec.empty? then
+ basename = filename.sub(/\.\w+?$/,'')
+ oldname = filename
+ ppmname = @tmpname + '-000.ppm'
+ jpgname = @tmpname + '-000.jpg'
+ newname = File.expand_path(oldname)
+ newname = File.dirname(newname) + '/' + subpath + @colorname + '-' + File.basename(newname)
+ newname.sub!(/\.\w+?$/, '.pdf')
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ pdfimages = PdfImages.new
+ imagemagick = ImageMagick.new
+ if pdfimages && imagemagick then
+ File.deletefiles(ppmname,jpgname,newname)
+ if filename =~ /\.(pdf)$/io then
+ ok = pdfimages.process("-j -f 1 -l 1 #{filename} #{@tmpname}")
+ if ok then
+ if FileTest.file?(ppmname) then
+ inpname = ppmname
+ elsif FileTest.file?(jpgname) then
+ inpname = jpgname
+ else
+ ok = false
+ end
+ if ok then
+ switch = if ! invert then '-negate' else '' end
+ # make sure that we keep the format
+ tmpname = File.basename(inpname)
+ tmpname = tmpname.sub(/(.*)\..*?$/,@tmpname) # somehow sub! fails here
+ ok = imagemagick.process("-colorspace gray #{switch} #{inpname} #{tmpname}")
+ if ! ok || ! FileTest.file?(tmpname) then
+ # problems
+ else
+ ok = imagemagick.process("-colorspace #{switch} #{@colorspace} -colorize #{@colorspec} -compress zip #{tmpname} #{newname}")
+ if ! ok || ! FileTest.file?(newname) then
+ # unable to colorize image
+ else
+ # conversion done
+ end
+ end
+ end
+ end
+ else
+ # make sure that we keep the format
+ tmpname = File.basename(basename)
+ tmpname = tmpname.sub(/(.*)\..*?$/,@tmpname) # somehow sub! fails here
+ ok = imagemagick.process("-colorspace gray #{oldname} #{tmpname}")
+ if ! ok || ! FileTest.file?(tmpname) then
+ # unable to convert color to gray
+ else
+ ok = imagemagick.process("-colorspace #{@colorspace} -colorize #{@colorspec} -compress zip #{tmpname} #{newname}")
+ if ! ok || ! FileTest.file?(newname) then
+ # unable to colorize image
+ else
+ # conversion done
+ end
+ end
+ end
+ File.deletefiles(ppmname,jpgname,tmpname)
+ File.syncmtimes(filename,newname) if retain
+ end
+ end
+ end
+ end
+
+end
+
+class SpotColorImage
+
+ def initialize(command=nil, tmpname='pdftools')
+ @command = command
+ @tmpname = tmpname
+ @colorname = nil
+ @colorspec = nil
+ @colorspace = nil
+ @colorfile = nil
+ end
+
+ def registercolor(spec='.5',name='unknown')
+ name = name || 'unknown'
+ if spec =~ /^[\d\.\,]+$/ then
+ spec = spec.split(',')
+ case spec.length
+ when 4
+ @colorname, @colorspec, @colorspace = name, ["c=#{spec[0]}","m=#{spec[1]}","y=#{spec[2]}","k=#{spec[3]}"].join(','), 'cmyk'
+ when 3
+ @colorname, @colorspec, @colorspace = name, ["r=#{spec[0]}","g=#{spec[1]}","b=#{spec[2]}"].join(','), 'rgb'
+ when 1
+ @colorname, @colorspec, @colorspace = name, ["s=#{spec[0]}"].join(','), 'gray'
+ else
+ @colorname, @colorspec, @colorspace = nil, nil, nil
+ end
+ else
+ @colorname, @colorfile = name, spec
+ end
+ end
+
+ def convertgrayimage(filename)
+
+ invert = @command.option('invert')
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ subpath += '/' unless subpath.empty?
+
+ if @colorname && ! @colorname.empty? && ((@colorspec && ! @colorspec.empty?) || (@colorfile && ! @colorfile.empty?)) then
+ basename = filename.sub(/\.\w+?$/,'')
+ oldname = filename # png jpg pdf
+ newname = File.expand_path(oldname)
+ ppmname = @tmpname + '-000.ppm'
+ jpgname = @tmpname + '-000.jpg'
+ outname = @tmpname + '-000.pdf'
+ texname = @tmpname + '-temp.tex'
+ pdfname = @tmpname + '-temp.pdf'
+ newname = File.dirname(newname) + '/' + subpath + @colorname + '-' + File.basename(newname)
+ newname.sub!(/\.\w+?$/, '.pdf')
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ pdfimages = PdfImages.new
+ imagemagick = ImageMagick.new
+ texexec = TexExec.new
+ if pdfimages && imagemagick && texexec then
+ if filename =~ /\.(jpg|png|pdf)$/io then
+ @command.report("processing #{basename}")
+ File.deletefiles(ppmname,jpgname,newname)
+ switch = if ! invert then '-negate' else '' end
+ if filename =~ /\.(pdf)$/io then
+ ok = pdfimages.process("-j -f 1 -l 1 #{oldname} #{@tmpname}")
+ if ok then
+ if FileTest.file?(ppmname) then
+ inpname = ppmname
+ elsif FileTest.file?(jpgname) then
+ inpname = jpgname
+ else
+ ok = false
+ end
+ if ok then
+ ok = imagemagick.process("-colorspace gray #{switch} -compress zip #{inpname} #{outname}")
+ end
+ end
+ else
+ ok = imagemagick.process("-colorspace gray #{switch} -compress zip #{oldname} #{outname}")
+ end
+ if ok then
+ ok = false unless FileTest.file?(outname)
+ end
+ if ok then
+ if f = File.open(texname, 'w') then
+ f.puts(conversionfile(filename,outname,newname))
+ f.close
+ ok = texexec.process(texname)
+ else
+ ok = false
+ end
+ @command.report("error in processing #{newname}") unless ok
+ if FileTest.file?(pdfname) then
+ if f = File.open(pdfname,'r') then
+ f.binmode
+ begin
+ if g = File.open(newname,'w') then
+ g.binmode
+ data = f.read
+ # pdftex (direct) & imagemagick (indirect)
+ if data =~ /(\d+)\s+0\s+obj\s+\[\/Separation\s+\/#{@colorname}/mos then
+ @command.report("replacing separation color")
+ object = $1
+ data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/moi) do
+ $1 + "/ColorSpace #{object} 0 R".ljust($2.length)
+ end
+ elsif data =~ /(\d+)\s+0\s+obj\s+\[\/Indexed\s*\[/mos then
+ @command.report("replacing indexed color")
+ # todo: more precise check on color
+ object = $1
+ data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/moi) do
+ $1 + "/ColorSpace #{object} 0 R".ljust($2.length)
+ end
+ elsif data =~ /(\d+)\s+0\s+obj\s+\[\/Separation/mos then
+ @command.report("replacing separation color")
+ object = $1
+ data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/moi) do
+ $1 + "/ColorSpace #{object} 0 R".ljust($2.length)
+ end
+ end
+ g.write(data)
+ g.close
+ end
+ rescue
+ @command.report("error in converting #{newname}")
+ else
+ @command.report("#{newname} is converted")
+ end
+ f.close
+ end
+ else
+ @command.report("error in writing #{newname}")
+ end
+ else
+ @command.report("error in producing #{newname}")
+ end
+ File.deletefiles(ppmname,jpgname,outname)
+ # File.deletefiles(texname,pdfname)
+ File.syncmtimes(filename,newname) if retain
+ end
+ else
+ @command.report("error in locating binaries")
+ end
+ else
+ @command.report("#{newname} is not changed")
+ end
+ end
+ end
+
+ private
+
+ # % example colorfile:
+ #
+ # \definecolor [darkblue] [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m
+ # \definecolor [darkyellow] [c=0,m=.28,y=1,k=.06] % pantone pms 124 uncoated m
+ #
+ # % \definecolor [darkblue-100] [darkblue] [p=1]
+ # % \definecolor [darkyellow-100] [darkyellow] [p=1]
+ #
+ # \definecolorcombination [pdftoolscolor] [darkblue=.12,darkyellow=.28] [c=.1,m=.1,y=.3,k=.1]
+
+ def conversionfile(originalname,filename,finalname)
+ tex = "\\setupcolors[state=start]\n"
+ if @colorfile then
+ tex += "\\readfile{#{@colorfile}}{}{}\n"
+ tex += "\\starttext\n"
+ # tex += "\\predefineindexcolor[pdftoolscolor]\n"
+ tex += "\\startTEXpage\n"
+ tex += "\\pdfimage{#{filename}}\n"
+ tex += "\\stopTEXpage\n"
+ tex += "\\stoptext\n"
+ else
+ tex += "\\definecolor[#{@colorname}][#{@colorspec}]\n"
+ tex += "\\definecolor[pdftoolscolor][#{@colorname}][p=1]\n"
+ tex += "\\starttext\n"
+ tex += "\\startTEXpage\n"
+ tex += "\\hbox{\\color[pdftoolscolor]{\\pdfimage{#{filename}}}}\n"
+ tex += "\\stopTEXpage\n"
+ tex += "\\stoptext\n"
+ end
+ tex += "\n"
+ tex += "% old: #{originalname}\n"
+ tex += "% new: #{finalname}\n"
+ return tex
+ end
+
+end
+
+module XML
+
+ def XML::version
+ "<?xml version='1.0'?>"
+ end
+
+ def XML::start(element, attributes='')
+ if attributes.empty? then
+ "<#{element}>"
+ else
+ "<#{element} #{attributes}>"
+ end
+ end
+
+ def XML::end(element)
+ "</#{element}>"
+ end
+
+ def XML::empty(element, attributes='')
+ if attributes && attributes.empty? then
+ "<#{element}/>"
+ else
+ "<#{element} #{attributes}/>"
+ end
+ end
+
+ def XML::element(element, attributes='', content='')
+ if content && ! content.empty? then
+ XML::start(element,attributes) + content + XML::end(element)
+ else
+ XML::empty(element,attributes)
+ end
+ end
+
+ def XML::box(tag, rect, type=1)
+ case type
+ when 1
+ if rect && ! rect.empty? then
+ rect = rect.split(' ')
+ XML::element("#{tag}box", '',
+ XML::element("llx", '', rect[0]) +
+ XML::element("lly", '', rect[1]) +
+ XML::element("ulx", '', rect[2]) +
+ XML::element("uly", '', rect[3]) )
+ else
+ XML::empty("#{tag}box")
+ end
+ when 2
+ if rect && ! rect.empty? then
+ rect = rect.split(' ')
+ XML::element("box", "type='#{tag}'",
+ XML::element("llx", '', rect[0]) +
+ XML::element("lly", '', rect[1]) +
+ XML::element("ulx", '', rect[2]) +
+ XML::element("uly", '', rect[3]) )
+ else
+ XML::empty("box", "type='#{tag}'")
+ end
+ when 3
+ if rect && ! rect.empty? then
+ rect = rect.split(' ')
+ XML::element("box", "type='#{tag}' llx='#{rect[0]}' lly='#{rect[1]}' ulx='#{rect[2]}' uly='#{rect[3]}'")
+ else
+ XML::empty("box", "type='#{tag}'")
+ end
+ else
+ ''
+ end
+ end
+
+ def XML::crlf
+ "\n"
+ end
+
+ def XML::skip(n=1)
+ ' '*n
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ # alias savedhelp :help
+
+ # def help
+ # savedhelp
+ # report("under construction (still separate tools)")
+ # end
+
+ # filename.pdf --spotimage --colorname=darkblue --colorspec=1,0.38,0,0.64
+
+ def spotimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ colorname = @commandline.option('colorname')
+ colorspec = @commandline.option('colorspec')
+ if colorname && ! colorname.empty? && colorspec && ! colorspec.empty? then
+ files.each do |filename|
+ s = SpotColorImage.new(self)
+ s.registercolor(colorspec,colorname)
+ s.convertgrayimage(filename)
+ end
+ else
+ report("provide --colorname=somename --colorspec=c,m,y,k")
+ end
+ else
+ report("provide filename (png, jpg, pdf)")
+ end
+
+ end
+
+ def colorimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ colorname = @commandline.option('colorname')
+ colorspec = @commandline.option('colorspec')
+ if colorspec && ! colorspec.empty? then
+ files.each do |filename|
+ s = ColorImage.new(self)
+ s.registercolor(colorspec,colorname) # name optional
+ s.convertimage(filename)
+ end
+ else
+ report("provide --colorspec=c,m,y,k")
+ end
+ else
+ report("provide filename")
+ end
+
+ end
+
+ def convertimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ files.each do |filename|
+ s = ConvertImage.new(self)
+ s.convertimage(filename)
+ end
+ else
+ report("provide filename")
+ end
+
+ end
+
+ def downsampleimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ files.each do |filename|
+ s = DownsampleImage.new(self)
+ s.convertimage(filename)
+ end
+ else
+ report("provide filename")
+ end
+
+ end
+
+ def info
+
+ if files = findfiles() then
+
+ print(XML.version + XML.crlf)
+ print(XML.start('pdfinfo', "xmlns='http://www.pragma-ade.com/schemas/pdfinfo.rng'") + XML.crlf)
+
+ files.each do |filename|
+
+ if filename =~ /\.pdf$/io then
+
+ begin
+ data = `pdfinfo -box #{filename}`.chomp.split("\n")
+ rescue
+ data = nil
+ end
+
+ if data then
+
+ pairs = Hash.new
+
+ data.each do |d|
+ if (d =~ /^\s*(.*?)\s*\:\s*(.*?)\s*$/moi) then
+ key, val = $1, $2
+ pairs[key.downcase.sub(/ /,'')] = val
+ end
+ end
+
+ print(XML.skip(1) + XML.start('pdffile', "filename='#{filename}'") + XML.crlf)
+
+ print(XML.skip(2) + XML.element('path', '', File.expand_path(filename)) + XML.crlf)
+
+ if pairs.key?('error') then
+
+ print(XML.skip(2) + XML.element('comment', '', pairs['error']) + XML.crlf)
+
+ else
+
+ print(XML.skip(2) + XML.element('version', '', pairs['pdfversion']) + XML.crlf)
+ print(XML.skip(2) + XML.element('pages', '', pairs['pages' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('title', '', pairs['title' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('subject', '', pairs['subject' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('author', '', pairs['author' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('producer', '', pairs['producer' ]) + XML.crlf)
+
+ if pairs.key?('creationdate') then
+ pairs['creationdate'].sub!(/(\d\d)\/(\d\d)\/(\d\d)/) do
+ '20' + $3 + '-' + $1 + '-' +$2
+ end
+ pairs['creationdate'].sub!(/(\d\d)\/(\d\d)\/(\d\d\d\d)/) do
+ $3 + '-' + $1 + '-' + $2
+ end
+ print(XML.skip(2) + XML.element('creationdate', '', pairs['creationdate']) + XML.crlf)
+ end
+
+ if pairs.key?('moddate') then
+ if pairs['moddate'] =~ /(\d\d\d\d)(\d\d)(\d\d)/ then
+ pairs['moddate'] = "#{$1}-#{$2}-#{$3}"
+ end
+ print(XML.skip(2) + XML.element('modificationdate', '', pairs['moddate']) + XML.crlf)
+ end
+
+ print(XML.skip(2) + XML.element('tagged', '', pairs['tagged' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('encrypted', '', pairs['encrypted']) + XML.crlf)
+ print(XML.skip(2) + XML.element('optimized', '', pairs['optimized']) + XML.crlf)
+
+ if pairs.key?('PageSize') then
+ print(XML.skip(2) + XML.element('width', '', pairs['pagesize'].sub(/\s*(.*?)\s+(.*?)\s+.*/, $1)) + XML.crlf)
+ print(XML.skip(2) + XML.element('height', '', pairs['pagesize'].sub(/\s*(.*?)\s+(.*?)\s+.*/, $2)) + XML.crlf)
+ end
+
+ if pairs.key?('FileSize') then
+ print(XML.skip(2) + XML.element('size', '', pairs['filesize'].sub(/\s*(.*?)\s+.*/, $1)) + XML.crlf)
+ end
+
+ print(XML.skip(2) + XML.box('media', pairs['mediabox']) + XML.crlf)
+ print(XML.skip(2) + XML.box('crop' , pairs['cropbox' ]) + XML.crlf)
+ print(XML.skip(2) + XML.box('bleed', pairs['bleedbox']) + XML.crlf)
+ print(XML.skip(2) + XML.box('trim' , pairs['trimBox' ]) + XML.crlf)
+ print(XML.skip(2) + XML.box('art' , pairs['artbox' ]) + XML.crlf)
+
+ end
+
+ print(XML.skip(1) + XML.end('pdffile') + XML.crlf)
+
+ end
+
+ end
+
+ end
+
+ print(XML.end('pdfinfo') + XML.crlf)
+
+ end
+
+ end
+
+ # name type emb sub uni object ID
+ # ------------------------------------ ------------ --- --- --- ---------
+ # EOPLBP+TimesNewRomanPSMT TrueType yes yes no 167 0
+ # Times-Roman TrueType no no no 95 0
+ # EPBAAB+Helvetica Type 1C yes yes yes 108 0
+ # EPBMLE+Helvetica-Oblique Type 1C yes yes yes 111 0
+ # Helvetica TrueType no no no 112 0
+
+ def checkembedded
+ $stderr = $stdout
+ $stdout.flush
+ if @commandline.option('pattern') then
+ # **/*.pdf
+ filenames, n = globfiles(@commandline.option('pattern'),'pdf'), 0
+ else
+ filenames, n = findfiles('pdf'), 0
+ end
+ filenames.sort.each do |file|
+ report("= checking #{File.expand_path(file)}")
+ result = `pdffonts #{file}`.chomp
+ lines = result.split(/\n/)
+ if result =~ /emb\s+sub\s+uni/io then
+ lines.each do |line|
+ report("! #{line}") if line =~ /no\s+(no|yes)\s+(no|yes)/io
+ end
+ else
+ lines.each do |line|
+ report("? #{line}")
+ end
+ end
+ report("")
+ end
+ end
+
+ def countpages
+ if @commandline.option('pattern') then
+ filenames, n = globfiles(@commandline.option('pattern'),'pdf'), 0
+ else
+ filenames, n = findfiles('pdf'), 0
+ end
+ threshold = @commandline.option('threshold').to_i rescue 0
+ filenames.each do |filename|
+ if `pdfinfo #{filename}`.chomp =~ /^pages\s*\:\s*(\d+)/moi then
+ p = $1
+ m = p.to_i rescue 0
+ if threshold == 0 or m > threshold then
+ report("#{p.rjust(4)} pages found in #{filename}")
+ n += m
+ end
+ end
+ end
+ report("")
+ report("#{n.to_s.rjust(4)} pages in total")
+ end
+
+ def analyzefile
+ # needs an update
+ filenames = @commandline.arguments
+ filenames.each do |filename|
+ if filename && FileTest.file?(filename) && filename =~ /\.pdf/io then
+ filesize = FileTest.size(filename)
+ report("analyzing file : #{filename}")
+ report("file size : #{filesize}")
+ if pdf = File.open(filename) then
+ pdf.binmode
+ nofobject, nofxform, nofannot, noflink, nofwidget, nofnamed, nofscript, nofcross = 0, 0, 0, 0, 0, 0, 0, 0
+ while data = pdf.gets do
+ data.scan(/\d+\s+\d+\s+obj/o) do nofobject += 1 end
+ data.scan(/\/Type\s*\/XObject/o) do nofxform += 1 end
+ data.scan(/\/Type\s*\/Annot/o) do nofannot += 1 end
+ data.scan(/\/GoToR\s*\/F/o) do nofcross += 1 end
+ data.scan(/\/Subtype\s*\/Link/o) do noflink += 1 end
+ data.scan(/\/Subtype\s*\/Widget/o) do nofwidget += 1 end
+ data.scan(/\/S\s*\/Named/o) do nofnamed += 1 end
+ data.scan(/\/S\s*\/JavaScript/o) do nofscript += 1 end
+ end
+ pdf.close
+ report("objects : #{nofobject}")
+ report("xforms : #{nofxform}")
+ report("annotations : #{nofannot}")
+ report("links : #{noflink} (#{nofnamed} named / #{nofscript} scripts / #{nofcross} files)")
+ report("widgets : #{nofwidget}")
+ end
+ end
+ end
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('spotimage' , 'filename --colorspec= --colorname= [--retain --invert --subpath=]')
+commandline.registeraction('colorimage', 'filename --colorspec= [--retain --invert --colorname= ]')
+commandline.registeraction('convertimage', 'filename [--retain --subpath]')
+commandline.registeraction('downsampleimage', 'filename [--retain --subpath --lowres --normal]')
+commandline.registeraction('info', 'filename')
+commandline.registeraction('countpages', '[--pattern --threshold]')
+commandline.registeraction('checkembedded', '[--pattern]')
+
+commandline.registeraction('analyzefile' , 'filename')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registervalue('colorname')
+commandline.registervalue('colorspec')
+commandline.registervalue('subpath')
+commandline.registervalue('pattern')
+commandline.registervalue('threshold',0)
+
+commandline.registerflag('lowres')
+commandline.registerflag('medres')
+commandline.registerflag('normal')
+commandline.registerflag('invert')
+commandline.registerflag('retain')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/Master/texmf-dist/scripts/context/ruby/pstopdf.rb b/Master/texmf-dist/scripts/context/ruby/pstopdf.rb
new file mode 100644
index 00000000000..73e628df23b
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/pstopdf.rb
@@ -0,0 +1,533 @@
+#!/usr/bin/env ruby
+
+# program : pstopdf
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+banner = ['PsToPdf', 'version 2.0.1', '2002-2006', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+# todo: paden/prefix in magick and inkscape
+# todo: clean up method handling (pass strings, no numbers)
+# --method=crop|bounded|raw|...
+# --resolution=low|normal|medium|high|printer|print|screen|ebook|default
+# + downward compatible flag handling
+
+require 'base/switch'
+require 'base/tool'
+require 'base/logger'
+
+require 'graphics/gs'
+require 'graphics/magick'
+require 'graphics/inkscape'
+
+require 'rexml/document'
+
+exit if defined?(REQUIRE2LIB)
+
+class Commands
+
+ include CommandBase
+
+ # nowadays we would force a directive, but
+ # for old times sake we handle default usage
+
+ def main
+ filename = @commandline.argument('first')
+ pattern = @commandline.option('pattern')
+ if filename.empty? && ! pattern.empty? then
+ pattern = "**/#{pattern}" if @commandline.option('recurse')
+ globfiles(pattern)
+ end
+ filename = @commandline.argument('first')
+ if filename.empty? then
+ help
+ elsif filename =~ /\.exa$/ then
+ request
+ else
+ convert
+ end
+ end
+
+ # actions
+
+ def convert
+
+ ghostscript = GhostScript.new(logger)
+ magick = ImageMagick.new(logger)
+ inkscape = InkScape.new(logger)
+
+ outpath = @commandline.option('outputpath')
+ unless outpath.empty? then
+ begin
+ File.expand_path(outpath)
+ outpath = File.makedirs(outpath) unless FileTest.directory?(outpath)
+ rescue
+ # sorry
+ end
+ end
+
+ @commandline.arguments.each do |filename|
+
+ filename = Tool.cleanfilename(filename,@commandline) # brrrr
+ inppath = @commandline.option('inputpath')
+ if inppath.empty? then
+ inppath = '.'
+ fullname = filename # avoid duplicate './'
+ else
+ fullname = File.join(inppath,filename)
+ end
+ if FileTest.file?(fullname) then
+ handle_whatever(ghostscript,inkscape,magick,filename)
+ else
+ report("file #{fullname} does not exist")
+ end
+
+ end
+
+ end
+
+ def request
+
+ # <exa:request>
+ # <exa:application>
+ # <exa:command>pstopdf</exa:command>
+ # <exa:filename>E:/tmp/demo.ps</exa:filename>
+ # </exa:application>
+ # <exa:data>
+ # <exa:variable label='gs:DoThumbnails'>false</exa:variable>
+ # <exa:variable label='gs:ColorImageDepth'>-1</exa:variable>
+ # </exa:data>
+ # </exa:request>
+
+ ghostscript = GhostScript.new(logger)
+ magick = ImageMagick.new(logger)
+ inkscape = InkScape.new(logger)
+
+ dataname = @commandline.argument('first') || ''
+ filename = @commandline.argument('second') || ''
+
+ if dataname.empty? || ! FileTest.file?(dataname) then
+ report('provide valid exa file')
+ return
+ else
+ begin
+ request = REXML::Document.new(File.new(dataname))
+ rescue
+ report('provide valid exa file (xml error)')
+ return
+ end
+ end
+ if filename.empty? then
+ begin
+ if filename = REXML::XPath.first(request.root,"exa:request/exa:application/exa:filename/text()") then
+ filename = filename.to_s
+ else
+ report('no filename found in exa file')
+ return
+ end
+ rescue
+ filename = ''
+ end
+ end
+ if filename.empty? then
+ report('provide valid filename')
+ return
+ elsif ! FileTest.file?(filename) then
+ report("invalid filename #{filename}")
+ return
+ end
+
+ [ghostscript,inkscape,magick].each do |i|
+ i.setvariable('inputfile',filename)
+ end
+
+ # set ghostscript variables
+ REXML::XPath.each(request.root,"/exa:request/exa:data/exa:variable") do |v|
+ begin
+ if (key = v.attributes['label']) and (value = v.text.to_s) then
+ case key
+ when /gs[\:\.](var[\:\.])*(offset)/io then ghostscript.setoffset(value)
+ when /gs[\:\.](var[\:\.])*(method)/io then ghostscript.setvariable('method',value)
+ when /gs[\:\.](var[\:\.])*(.*)/io then ghostscript.setpsoption($2,value)
+ end
+ end
+ rescue
+ end
+ end
+
+ # no inkscape and magick variables (yet)
+
+ handle_whatever(ghostscript,inkscape,magick,filename)
+
+ end
+
+ def watch
+
+ ghostscript = GhostScript.new(logger)
+ magick = ImageMagick.new(logger)
+ inkscape = InkScape.new(logger)
+
+ pathname = commandline.option('watch')
+
+ unless pathname and not pathname.empty? then
+ report('empty watchpath is not supported')
+ exit
+ end
+
+ if pathname == '.' then
+ report("watchpath #{pathname} is not supported")
+ exit
+ end
+
+ if FileTest.directory?(pathname) then
+ if Dir.chdir(pathname) then
+ report("watching path #{pathname}")
+ else
+ report("unable to change to path #{pathname}")
+ exit
+ end
+ else
+ report("invalid path #{pathname}")
+ exit
+ end
+
+ waiting = false
+
+ loop do
+
+ if waiting then
+ report("waiting #{getvariable('delay')}")
+ waiting = false
+ sleep(getvariable('delay').to_i)
+ end
+
+ files = Dir.glob("**/*.*")
+
+ if files and files.length > 0 then
+
+ files.each do |fullname|
+
+ next unless fullname
+
+ if FileTest.directory?(fullname) then
+ debug('skipping path', fullname)
+ next
+ end
+
+ unless magick.supported(fullname) then
+ debug('not supported', fullname)
+ next
+ end
+
+ if (! FileTest.file?(fullname)) || (FileTest.size(fullname) < 100) then
+ debug("skipping small crap file #{fullname}")
+ next
+ end
+
+ debug("handling file #{fullname}")
+
+ begin
+ next unless File.rename(fullname,fullname) # access trick
+ rescue
+ next # being written
+ end
+
+ fullname = Tool.cleanfilename(fullname,@commandline)
+
+ fullname.gsub!(/\\/io, '/')
+
+ filename = File.basename(fullname)
+ filepath = File.dirname(fullname)
+
+ next if filename =~ /gstemp.*/io
+
+ if filepath !~ /(result|done|raw|crop|bound|bitmap)/io then
+ begin
+ File.makedirs(filepath+'/raw')
+ File.makedirs(filepath+'/bound')
+ File.makedirs(filepath+'/crop')
+ File.makedirs(filepath+'/bitmap')
+ debug("creating prefered input paths on #{filepath}")
+ rescue
+ debug("creating input paths on #{filepath} failed")
+ end
+ end
+
+ if filepath =~ /^(.*\/|)(done|result)$/io then
+ debug("skipping file #{fullname}")
+ else
+ report("start processing file #{fullname}")
+ if filepath =~ /^(.*\/*)(raw|crop|bound)$/io then
+ donepath = $1 + 'done'
+ resultpath = $1 + 'result'
+ case $2
+ when 'raw' then method = 1
+ when 'bound' then method = 2
+ when 'crop' then method = 3
+ else method = 2
+ end
+ report("forcing method #{method}")
+ else
+ method = 2
+ donepath = filepath + '/done'
+ resultpath = filepath + '/result'
+ report("default method #{method}")
+ end
+
+ begin
+ File.makedirs(donepath)
+ File.makedirs(resultpath)
+ rescue
+ report('result path creation fails')
+ end
+
+ if FileTest.directory?(donepath) && FileTest.directory?(resultpath) then
+
+ resultname = resultpath + '/' + filename.sub(/\.[^\.]*$/,'') + '.pdf'
+
+ @commandline.setoption('inputpath', filepath)
+ @commandline.setoption('outputpath', resultpath)
+ @commandline.setoption('method', method)
+
+ if ghostscript.psfile?(fullname) then
+ handle_ghostscript(ghostscript,filename)
+ else
+ handle_magick(magick,filename)
+ end
+
+ sleep(1) # calm down
+
+ if FileTest.file?(fullname) then
+ begin
+ File.copy(fullname,donepath + '/' + filename)
+ File.delete(fullname)
+ rescue
+ report('cleanup fails')
+ end
+ end
+
+ end
+
+ end
+
+ end
+
+ end
+
+ waiting = true
+ end
+
+ end
+
+ private
+
+ def handle_whatever(ghostscript,inkscape,magick,filename)
+ if ghostscript.psfile?(filename) then
+ # report("processing ps file #{filename}")
+ ghostscript.setvariable('pipe',false) if @commandline.option('nopipe')
+ # ghostscript.setvariable('pipe',not @commandline.option('nopipe'))
+ ghostscript.setvariable('colormodel',@commandline.option('colormodel'))
+ ghostscript.setvariable('offset',@commandline.option('offset'))
+ handle_ghostscript(ghostscript,filename)
+ elsif ghostscript.pdffile?(filename) && ghostscript.pdfmethod?(@commandline.option('method')) then
+ # report("processing pdf file #{filename}")
+ handle_ghostscript(ghostscript,filename)
+ elsif inkscape.supported?(filename) then
+ # report("processing non ps/pdf file #{filename}")
+ handle_inkscape(inkscape,filename)
+ elsif magick.supported?(filename) then
+ # report("processing non ps/pdf file #{filename}")
+ handle_magick(magick,filename)
+ else
+ report("option not supported for #{filename}")
+ end
+ end
+
+ def handle_magick(magick,filename)
+
+ report("converting non-ps file #{filename} into pdf")
+
+ inppath = @commandline.option('inputpath')
+ outpath = @commandline.option('outputpath')
+
+ inppath = inppath + '/' if not inppath.empty?
+ outpath = outpath + '/' if not outpath.empty?
+
+ prefix = @commandline.option('prefix')
+ suffix = @commandline.option('suffix')
+
+ inpfilename = "#{inppath}#{filename}"
+ outfilename = "#{outpath}#{prefix}#{filename.sub(/\.([^\.]*?)$/, '')}#{suffix}.pdf"
+
+ magick.setvariable('inputfile' , inpfilename)
+ magick.setvariable('outputfile', outfilename)
+
+ magick.autoconvert
+
+ end
+
+ def handle_inkscape(inkscape,filename)
+
+ report("converting svg(z) file #{filename} into pdf")
+
+ inppath = @commandline.option('inputpath')
+ outpath = @commandline.option('outputpath')
+
+ inppath = inppath + '/' if not inppath.empty?
+ outpath = outpath + '/' if not outpath.empty?
+
+ prefix = @commandline.option('prefix')
+ suffix = @commandline.option('suffix')
+
+ inpfilename = "#{inppath}#{filename}"
+ outfilename = "#{outpath}#{prefix}#{filename.sub(/\.([^\.]*?)$/, '')}#{suffix}.pdf"
+
+ inkscape.setvariable('inputfile' , inpfilename)
+ inkscape.setvariable('outputfile', outfilename)
+
+ if @commandline.option('verbose') || @commandline.option('debug') then
+ logname = filename.gsub(/\.[^\.]*?$/, '.log')
+ report("log info saved in #{logname}")
+ inkscape.convert(logname) # logname ook doorgeven
+ else
+ inkscape.convert
+ end
+
+ end
+
+ def handle_ghostscript(ghostscript,filename)
+
+ ghostscript.reset
+
+ method = ghostscript.method(@commandline.option('method'))
+ force = ghostscript.method(@commandline.option('force'))
+
+ ghostscript.setvariable('method', method)
+ ghostscript.setvariable('force', force)
+
+ # report("conversion method #{method}")
+
+ inppath = @commandline.option('inputpath')
+ outpath = @commandline.option('outputpath')
+
+ inppath = inppath + '/' if not inppath.empty?
+ outpath = outpath + '/' if not outpath.empty?
+
+ prefix = @commandline.option('prefix')
+ suffix = @commandline.option('suffix')
+
+ ok = false
+
+ if ghostscript.pdfmethod?(method) then
+
+ report("converting pdf file #{filename} into pdf")
+
+ if prefix.empty? && suffix.empty? && inppath.empty? && outpath.empty? then
+ prefix = ghostscript.pdfprefix(method)
+ end
+
+ if ghostscript.pdffile?(filename) then
+
+ filename = filename.sub(/\.pdf$/, '')
+
+ inpfilename = "#{inppath}#{filename}.pdf"
+ outfilename = "#{outpath}#{prefix}#{filename}#{suffix}.pdf"
+
+ ghostscript.setvariable('inputfile' ,inpfilename)
+ ghostscript.setvariable('outputfile',outfilename)
+
+ if FileTest.file?(inpfilename) then
+ ok = ghostscript.convert
+ else
+ report("no file found #{filename}")
+ end
+
+ else
+ report("no pdf file #{filename}")
+ end
+
+ elsif ghostscript.psfile?(filename) then
+
+ if filename =~ /(.*)\.([^\.]*?)$/io then
+ filename, filesuffix = $1, $2
+ else
+ filesuffix = 'eps'
+ end
+
+ report("converting #{filesuffix} (ps) into pdf")
+
+ inpfilename = "#{inppath}#{filename}.#{filesuffix}"
+ outfilename = "#{outpath}#{prefix}#{filename}#{suffix}.pdf"
+
+ ghostscript.setvariable('inputfile' , inpfilename)
+ ghostscript.setvariable('outputfile', outfilename)
+
+ if FileTest.file?(inpfilename) then
+ ok = ghostscript.convert
+ if ! ok && FileTest.file?(outfilename) then
+ begin
+ File.delete(outfilename)
+ rescue
+ end
+ end
+ else
+ report("no file with name #{filename} found")
+ end
+
+ else
+ report('file must be of type eps/ps/ai/pdf')
+ end
+
+ return ok
+
+ end
+
+end
+
+# ook pdf -> pdf onder optie 0, andere kleurruimte
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registerflag('debug')
+commandline.registerflag('verbose')
+commandline.registerflag('nopipe')
+
+commandline.registervalue('method',2)
+commandline.registervalue('offset',0)
+
+commandline.registervalue('prefix')
+commandline.registervalue('suffix')
+
+commandline.registervalue('inputpath')
+commandline.registervalue('outputpath')
+
+commandline.registerflag('watch')
+commandline.registerflag('force')
+commandline.registerflag('recurse')
+
+commandline.registervalue('delay',2)
+
+commandline.registervalue('colormodel','cmyk')
+commandline.registervalue('pattern','')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registeraction('convert', 'convert ps into pdf')
+commandline.registeraction('request', 'handles exa request file')
+commandline.registeraction('watch', 'watch folders for conversions (untested)')
+
+commandline.expand
+
+logger.verbose if (commandline.option('verbose') || commandline.option('debug'))
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'main')
diff --git a/Master/texmf-dist/scripts/context/ruby/rlxtools.rb b/Master/texmf-dist/scripts/context/ruby/rlxtools.rb
new file mode 100644
index 00000000000..6a5c5ca2098
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/rlxtools.rb
@@ -0,0 +1,368 @@
+#!/usr/bin/env ruby
+
+# program : rlxtools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2004-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+banner = ['RlxTools', 'version 1.0.1', '2004/2005', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'base/switch'
+require 'base/logger'
+require 'base/system'
+require 'base/kpse'
+
+require 'fileutils'
+# require 'ftools'
+require 'rexml/document'
+
+class Commands
+
+ include CommandBase
+
+ # <?xml version='1.0 standalone='yes'?>
+ # <rl:manipulators>
+ # <rl:manipulator name='lowres' suffix='pdf'>
+ # <rl:step>
+ # texmfstart
+ # --verbose
+ # --iftouched=<rl:value name='path'/>/<rl:value name='file'/>,<rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file'/>
+ # pstopdf
+ # --method=5
+ # --inputpath=<rl:value name='path'/>
+ # --outputpath=<rl:value name='path'/>/<rl:value name='prefix'/>
+ # <rl:value name='file'/>
+ # </rl:step>
+ # </rl:manipulator>
+ # </rl:manipulators>
+ #
+ # <?xml version='1.0' standalone='yes'?>
+ # <rl:library>
+ # <rl:usage>
+ # <rl:type>figure</rl:type>
+ # <rl:state>found</rl:state>
+ # <rl:file>cow.pdf</rl:file>
+ # <rl:suffix>pdf</rl:suffix>
+ # <rl:path>.</rl:path>
+ # <rl:conversion>lowres</rl:conversion>
+ # <rl:prefix>lowres/</rl:prefix>
+ # <rl:width>276.03125pt</rl:width>
+ # <rl:height>200.75pt</rl:height>
+ # </rl:usage>
+ # </r:library>
+
+ def manipulate
+
+ procname = @commandline.argument('first') || ''
+ filename = @commandline.argument('second') || ''
+
+ procname = Kpse.found(procname)
+
+ if procname.empty? || ! FileTest.file?(procname) then
+ report('provide valid manipulator file')
+ elsif filename.empty? || ! FileTest.file?(filename) then
+ report('provide valid resource log file')
+ else
+ begin
+ data = REXML::Document.new(File.new(filename))
+ rescue
+ report('provide valid resource log file (xml error)')
+ return
+ end
+ begin
+ proc = REXML::Document.new(File.new(procname))
+ rescue
+ report('provide valid manipulator file (xml error)')
+ return
+ end
+ report("manipulator file: #{procname}")
+ report("resourcelog file: #{filename}")
+ begin
+ nofrecords, nofdone = 0, 0
+ REXML::XPath.each(data.root,"/rl:library/rl:usage") do |usage|
+ nofrecords += 1
+ variables = Hash.new
+ usage.elements.each do |e|
+ variables[e.name] = e.text.to_s
+ end
+ report("processing record #{nofrecords} (#{variables['file'] || 'noname'}: #{variables.size} entries)")
+ if conversion = variables['conversion'] then
+ report("testing for conversion #{conversion}")
+ if suffix = variables['suffix'] then
+ suffix.downcase!
+ if ! suffix.empty? && variables['file'] && variables['file'] !~ /\.([a-z]+)$/i then
+ variables['file'] += ".#{suffix}"
+ end
+ if file = variables['file'] then
+ report("conversion #{conversion} for suffix #{suffix} for file #{file}")
+ else
+ report("conversion #{conversion} for suffix #{suffix}")
+ end
+ pattern = "@name='#{conversion}' and @suffix='#{suffix}'"
+ if steps = REXML::XPath.first(proc.root,"/rl:manipulators/rl:manipulator[#{pattern}]") then
+ localsteps = steps.deep_clone
+ ['rl:old','rl:new'].each do |tag|
+ REXML::XPath.each(localsteps,tag) do |extras|
+ REXML::XPath.each(extras,"rl:value") do |value|
+ if name = value.attributes['name'] then
+ substitute(value,variables[name.to_s] || '')
+ end
+ end
+ end
+ end
+ old = REXML::XPath.first(localsteps,"rl:old")
+ new = REXML::XPath.first(localsteps,"rl:new")
+ if old && new then
+ old, new = justtext(old.to_s), justtext(new.to_s)
+ variables['old'], variables['new'] = old, new
+ begin
+ [old,new].each do |d|
+ File.makedirs(File.dirname(d))
+ end
+ rescue
+ report("error during path creation")
+ end
+ report("old file #{old}")
+ report("new file #{new}")
+ level = if File.needsupdate(old,new) then 2 else 0 end
+ else
+ level = 1
+ end
+ if level>0 then
+ REXML::XPath.each(localsteps,"rl:step") do |command|
+ REXML::XPath.each(command,"rl:old") do |value|
+ replace(value,old)
+ end
+ REXML::XPath.each(command,"rl:new") do |value|
+ replace(value,new)
+ end
+ REXML::XPath.each(command,"rl:value") do |value|
+ if name = value.attributes['name'] then
+ substitute(value,variables[name.to_s])
+ end
+ end
+ str = justtext(command.to_s)
+ # str.gsub!(/(\.\/)+/io, '')
+ report("command #{str}")
+ System.run(str) unless @commandline.option('test')
+ report("synchronizing #{old} and #{new}")
+ File.syncmtimes(old,new) if level > 1
+ nofdone += 1
+ end
+ else
+ report("no need for a manipulation")
+ end
+ else
+ report("no manipulator found")
+ end
+ else
+ report("no suffix specified")
+ end
+ else
+ report("no conversion needed")
+ end
+ end
+ if nofdone > 0 then
+ jobname = filename.gsub(/\.(.*?)$/,'') # not 'tuo' here
+ tuoname = jobname + '.tuo'
+ if FileTest.file?(tuoname) && (f = File.open(tuoname,'a')) then
+ f.puts("%\n% number of rlx manipulations: #{nofdone}\n")
+ f.close
+ end
+ end
+ rescue
+ report("error in manipulating files: #{$!}")
+ end
+ begin
+ logname = "#{filename}.log"
+ File.delete(logname) if FileTest.file?(logname)
+ File.copy(filename,logname)
+ rescue
+ end
+ end
+
+ end
+
+ private
+
+ def justtext(str)
+ str = str.to_s
+ str.gsub!(/<[^>]*?>/o, '')
+ str.gsub!(/\s+/o, ' ')
+ str.gsub!(/&lt;/o, '<')
+ str.gsub!(/&gt;/o, '>')
+ str.gsub!(/&amp;/o, '&')
+ str.gsub!(/&quot;/o, '"')
+ str.gsub!(/[\/\\]+/o, '/')
+ return str.strip
+ end
+
+ def substitute(value,str='')
+ if str then
+ begin
+ if value.attributes.key?('method') then
+ str = filtered(str.to_s,value.attributes['method'].to_s)
+ end
+ if str.empty? && value.attributes.key?('default') then
+ str = value.attributes['default'].to_s
+ end
+ value.insert_after(value,REXML::Text.new(str.to_s))
+ rescue Exception
+ end
+ end
+ end
+
+ def replace(value,str)
+ if str then
+ begin
+ value.insert_after(value,REXML::Text.new(str.to_s))
+ rescue Exception
+ end
+ end
+ end
+
+ def filtered(str,method)
+
+ str = str.to_s # to be sure
+ case method
+ when 'name' then # no path, no suffix
+ case str
+ when /^.*[\\\/](.+?)\..*?$/o then $1
+ when /^.*[\\\/](.+?)$/o then $1
+ when /^(.*)\..*?$/o then $1
+ else str
+ end
+ when 'path' then if str =~ /^(.+)([\\\/])(.*?)$/o then $1 else '' end
+ when 'suffix' then if str =~ /^.*\.(.*?)$/o then $1 else '' end
+ when 'nosuffix' then if str =~ /^(.*)\..*?$/o then $1 else str end
+ when 'nopath' then if str =~ /^.*[\\\/](.*?)$/o then $1 else str end
+ else str
+ end
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ @@xmlbanner = "<?xml version='1.0' standalone='yes'?>"
+
+ def identify(resultfile='rlxtools.rli')
+ if @commandline.option('collect') then
+ begin
+ File.open(resultfile,'w') do |f|
+ f << "#{@@xmlbanner}\n"
+ f << "<rl:identification>\n"
+ @commandline.arguments.each do |filename|
+ if state = do_identify(filename) then
+ report("#{filename} is identified")
+ f << state
+ else
+ report("unable to identify #{filename}")
+ end
+ end
+ f << "</rl:identification>\n"
+ report("result saved in #{resultfile}")
+ end
+ rescue
+ report("error in writing result")
+ end
+ else
+ @commandline.arguments.each do |filename|
+ if state = do_identify(filename) then
+ begin
+ File.open(filename+'.rli','w') do |f|
+ f << "#{@@xmlbanner}\n"
+ f << state
+ end
+ rescue
+ report("error in identifying #{filename}")
+ else
+ report("#{filename} is identified")
+ end
+ else
+ report("unable to identify #{filename}")
+ end
+ end
+ end
+ end
+
+ private
+
+ def do_identify(filename,centimeters=false)
+ begin
+ str = nil
+ if FileTest.file?(filename) then
+ # todo: use pdfinto for pdf files, identify is bugged
+ if centimeters then
+ result = `identify -units PixelsPerCentimeter -format \"x=%x,y=%y,w=%w,h=%h,b=%b\" #{filename}`.chomp.split(',')
+ else
+ result = `identify -units PixelsPerInch -format \"x=%x,y=%y,w=%w,h=%h,b=%b\" #{filename}`.chomp.split(',')
+ end
+ tags = Hash.new
+ result.each do |r|
+ if rr = r.split("=") then
+ tags[rr[0]] = rr[1]
+ end
+ end
+ size = (tags['b']||0).to_i
+ width = unified(tags['w']||0,tags['x']||'1')
+ height = unified(tags['h']||0,tags['y']||'1')
+ if size > 0 then
+ str = ''
+ str << "<rl:identify name='#{File.basename(filename)}'>\n"
+ str << " <rl:size>#{size}</rl:size>\n"
+ str << " <rl:path>#{File.dirname(filename).sub(/\\/o,'/')}</rl:path>\n"
+ str << " <rl:width>#{width}</rl:width>\n"
+ str << " <rl:height>#{height}</rl:height>\n"
+ str << "</rl:identify>\n"
+ end
+ else
+ str = nil
+ end
+ rescue
+ str = nil
+ end
+ return str
+ end
+
+ def unified(dim,res)
+ case res
+ when /([\d\.]+)\s*PixelsPerInch/io then
+ sprintf("%.4fin",dim.to_f/$1.to_f)
+ when /([\d\.]+)\s*PixelsPerCentimeter/io then
+ sprintf("%.4fcm",dim.to_f/$1.to_f)
+ when /([\d\.]+)\s*PixelsPerMillimeter/io then
+ sprintf("%.4fmm",dim.to_f/$1.to_f)
+ when /([\d\.]+)\s*PixelsPerPoint/io then
+ sprintf("%.4fbp",dim.to_f/$1.to_f)
+ else
+ sprintf("%.4fbp",dim.to_f)
+ end
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('manipulate', '[--test] manipulatorfile resourselog')
+commandline.registeraction('identify' , '[--collect] filename')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registerflag('test')
+commandline.registerflag('collect')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/Master/texmf-dist/scripts/context/ruby/rscortool.rb b/Master/texmf-dist/scripts/context/ruby/rscortool.rb
new file mode 100644
index 00000000000..c656fed8547
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/rscortool.rb
@@ -0,0 +1,63 @@
+# program : rscortool
+# copyright : PRAGMA Publishing On Demand
+# version : 1.00 - 2002
+# author : Hans Hagen
+#
+# project : eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-pod.com / www.pragma-ade.com
+
+require 'rexml/document.rb'
+
+class Array
+
+ def downcase
+ self.collect { |l| l.to_s.downcase }
+ end
+
+end
+
+class SortedXML
+
+ def initialize (filename)
+ return nil if not filename or filename.empty? or not test(?e,filename)
+ @data = REXML::Document.new(File.new(filename),
+ {:ignore_whitespace_nodes => :all,
+ :compress_whitespace => :all})
+ end
+
+ def save (filename)
+ # filename += '.xml' unless filename.match(/\..*?$/)
+ filename += '.xml' unless filename =~ /\..*?$/
+ if not filename.empty? and f = open(filename,'w')
+ @data.write(f,0)
+ f.close
+ end
+ end
+
+ def sort
+ keys = REXML::XPath.match(@data.root,"/contacts/contact/@label")
+ return unless keys
+ keys = keys.downcase
+ records = @data.elements.to_a("/contacts/contact")
+ @data.elements.delete_all("/contacts/contact")
+ keys = keys.collect do |l| # prepare numbers
+ l.gsub(/(\d+)/) do |d| sprintf('%05d', d) end
+ end
+ keys.sort.each do |s|
+ @data.root.add_element(records[keys.index(s)])
+ end
+ end
+
+end
+
+def sortfile (filename)
+ c = SortedXML.new(filename)
+ c.sort
+ c.save('test.xml')
+end
+
+exit if ARGV[0] == nil or ARGV[0].empty?
+
+sortfile(ARGV[0])
diff --git a/Master/texmf-dist/scripts/context/ruby/rsfiltool.rb b/Master/texmf-dist/scripts/context/ruby/rsfiltool.rb
new file mode 100644
index 00000000000..6d7c7aba0a5
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/rsfiltool.rb
@@ -0,0 +1,341 @@
+# program : rsfiltool
+# copyright : PRAGMA Publishing On Demand
+# version : 1.01 - 2002
+# author : Hans Hagen
+#
+# project : eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-pod.com / www.pragma-ade.com
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'')
+ $: << ownpath
+end
+
+# --name=a,b,c.xml wordt names [a.xml, b.xml, c.xml]
+# --path=x/y/z/a,b,c.xml wordt [x/y/z/a.xml, x/y/z/b.xml, x/y/z/c.xml]
+
+# todo : split session stuff from xmpl/base into an xmpl/session module and "include xmpl/session" into base and here and ...
+
+require 'fileutils'
+# require 'ftools'
+require 'xmpl/base'
+require 'xmpl/switch'
+require 'xmpl/request'
+
+session = Example.new('rsfiltool', '1.01', 'PRAGMA POD')
+
+filterprefix = 'rsfil-'
+
+commandline = CommandLine.new
+
+commandline.registerflag('submit')
+commandline.registerflag('fetch')
+commandline.registerflag('report')
+#commandline.registerflag('split')
+commandline.registerflag('stamp')
+commandline.registerflag('silent')
+commandline.registerflag('request')
+commandline.registerflag('nobackup')
+
+commandline.registervalue('filter')
+
+commandline.registervalue('root')
+commandline.registervalue('path')
+commandline.registervalue('name')
+
+commandline.expand
+
+session.set('log.silent',true) if commandline.option('silent')
+
+session.inherit(commandline)
+
+session.identify
+
+# session.exit unless session.loadenvironment
+
+def prepare (session)
+
+ # Normally the system provides the file, but a user can provide the rest; in
+ # order to prevent problems with keying in names, we force lowercase names.
+
+ session.set('option.file',session.get('argument.first')) if session.get('option.file').empty?
+
+ root = session.get('option.root').downcase
+ path = session.get('option.path').downcase
+ name = session.get('option.name').downcase
+ file = session.get('option.file').downcase
+
+ session.error('provide file') if file.empty?
+ session.error('provide root') if root.empty?
+
+ filter = session.get('option.filter').downcase
+ trash = session.get('option.trash').downcase
+
+ trash = '' unless FileTest.directory?(trash)
+
+ if not filter.empty? then
+ begin
+ require filter
+ rescue Exception
+ begin
+ require filterprefix + filter
+ rescue Exception
+ session.error('invalid filter')
+ end
+ end
+ begin
+ if RSFIL::valid?(file) then
+ split = RSFIL::split(file,name)
+ path = if split[0].downcase then split[0] else '' end
+ file = if split[1].downcase then split[1] else '' end
+ name = if split[2].downcase then split[2] else '' end
+ session.report('split result',split.inspect)
+ session.error('unable to split off path') if path.empty?
+ session.error('unable to split off file') if file.empty?
+ session.error('unable to split off name') if name.empty?
+ session.set('option.path',path) if path
+ session.set('option.file',file) if file
+ session.set('option.name',name) if name
+ else
+ session.error('invalid filename', file)
+ unless trash.empty? then
+ File.copy(file,trash + '/' + file)
+ end
+ end
+ rescue
+ session.error('unable to split',file,'with filter',filter)
+ end
+ end
+
+ session.error('provide path') if path.empty?
+
+ session.error('invalid root') unless test(?d,root)
+
+ exit if session.error?
+
+ session.set('fb.filename',file)
+
+ path.gsub!(/\\/o, '/')
+ path.gsub!(/\s/o, '')
+
+ path = root + '/' + path
+
+ # multiple paths
+
+ if path =~ /^(.*)\/(.*?)$/o then
+ prepath = $1
+ postpath = $2
+ paths = postpath.split(/\,/)
+ paths.collect! do |p|
+ prepath + '/' + p
+ end
+ else
+ paths = Array.new
+ paths.push(path)
+ end
+
+ paths.collect! do |p|
+ p.gsub(/[^a-zA-Z0-9\s\-\_\/\.\:]/o, '-')
+ end
+
+ file.gsub!(/\\/o, '/')
+ file.gsub!(/[^a-zA-Z0-9\s\-\_\/\.\:]/o, '-')
+
+# if session.get('option.split')
+# if file =~ /(.*)\.(.*?)$/o
+# path = path + '/' + $1
+# else
+# session.error('nothing to split in filename')
+# end
+# end
+
+ paths.each do |p|
+ begin
+ session.report('creating path', p)
+ File.makedirs(p)
+ rescue
+ session.error('unable to create path', p)
+ end
+ end
+
+ name.gsub!(/\s+/,'')
+
+ # can be a,b,c.exa.saved => a.exa.saved,b.exa.saved,c.exa.saved
+
+ if name =~ /(.*?)\.(.*)$/
+ name = $1
+ suffix = $2
+ names = name.split(/\,/)
+ names.collect! do |n|
+ n + '.' + suffix
+ end
+ name = names.join(',')
+ else
+ names = name.split(/\,/)
+ end
+
+ session.set('fb.path',path)
+ session.set('fb.paths',paths)
+ session.set('fb.name',name)
+ session.set('fb.names',names)
+
+end
+
+def thefullname(path,file,name='')
+
+ filename = file.gsub(/.*?\//, '')
+
+ if name.empty?
+ path + '/' + filename
+ else
+ unless name =~ /\..+$/o # unless name.match(/\..+$/o)
+ if filename =~ /(\..+)$/o # if file.match(/(\..+)$/o)
+ name = name + $1
+ end
+ end
+ path + '/' + name
+ end
+
+end
+
+def submitfile (session)
+
+ filename = session.get('fb.filename')
+ paths = session.get('fb.paths')
+ names = session.get('fb.names')
+
+ paths.each do |path|
+ session.report('submitting path',path)
+ names.each do |name|
+ session.report('submitting file',filename,'to',name)
+ submit(session,path,filename,name)
+ end
+ end
+
+end
+
+def submitlist (session)
+
+ requestname = session.get('fb.filename')
+ paths = session.get('fb.paths')
+
+ if test(?e,requestname)
+ session.report('loading request file', requestname)
+ if request = ExaRequest.new(requestname)
+ filelist = request.files
+ if filelist && (filelist.size > 0)
+ filelist.each do |filename|
+ paths.each do |path|
+ session.report('submitting file from list', filename)
+ submit(session,path,filename,request.naturalname(filename))
+ end
+ end
+ else
+ session.warning('no filelist in', requestname)
+ end
+ else
+ session.warning('unable to load', requestname)
+ end
+ else
+ session.warning('no file', requestname)
+ end
+
+end
+
+def submit (session, path, filename, newname)
+
+ fullname = thefullname(path,newname)
+
+ unless test(?e,filename)
+ session.warning('no file to submit', filename)
+ return
+ end
+
+ begin
+ File.copy(fullname,fullname+'.old') if ! session.get('nobackup') && test(?e,fullname)
+ if test(?e,filename)
+ File.copy(filename,fullname)
+ session.report('submit', filename, 'in', fullname)
+ if session.get('option.stamp')
+ f = open(fullname+'.tim','w')
+ f.puts(Time.now.gmtime.strftime("%a %b %d %H:%M:%S %Y"))
+ f.close
+ end
+ else
+ session.error('unable to locate', filename)
+ end
+ rescue
+ session.error('unable to move', filename, 'to', fullname)
+ end
+
+end
+
+def fetch (session)
+
+ filename = session.get('fb.filename')
+ paths = session.get('fb.paths')
+ name = session.get('fb.name')
+
+ begin
+ File.copy(filename,filename+'.old') if ! session.get('nobackup') && test(?e,filename)
+ paths.each do |path|
+ # fullname = thefullname(path,request.naturalname(filename))
+ # fullname = thefullname(path,filename)
+ fullname = thefullname(path,name)
+ if test(?e,fullname)
+ File.copy(fullname,filename)
+ session.report('fetch', filename, 'from', fullname)
+ return
+ else
+ session.report('file',fullname, 'is not present')
+ end
+ end
+ rescue
+ session.error('unable to fetch file from path')
+ end
+ session.error('no file',filename, 'fetched') unless test(?e,filename)
+
+end
+
+def report (session)
+
+ filename = session.get('fb.filename')
+ paths = session.get('fb.paths')
+
+ paths.each do |path|
+ fullname = thefullname(path,request.naturalname(filename))
+ if test(?e,fullname)
+ begin
+ session.report('file', fullname)
+ session.report('size', test(?s,fullname))
+ if test(?e,fullname+'.tim')
+ str = IO.readlines(fullname+'.tim')
+ # str = IO.read(fullname+'.tim')
+ session.report('time', str)
+ end
+ rescue
+ session.error('unable to report about', fullname)
+ end
+ end
+ end
+
+end
+
+if session.get('option.submit')
+ prepare(session)
+ if session.get('option.request')
+ submitlist(session)
+ else
+ submitfile(session)
+ end
+elsif session.get('option.fetch')
+ prepare(session)
+ fetch(session)
+elsif session.get('option.report')
+ prepare(session)
+ report(session)
+else
+ session.report('provide action')
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/rslb/base.rb b/Master/texmf-dist/scripts/context/ruby/rslb/base.rb
new file mode 100644
index 00000000000..66ce3a19e71
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/rslb/base.rb
@@ -0,0 +1,270 @@
+# hans hagen, pragma-ade, hasselt nl
+# experimental code, don't touch it
+
+require 'rexml/document.rb'
+
+class Array
+
+ def downcase
+ self.collect do |l|
+ l.to_s.downcase
+ end
+ end
+
+end
+
+class Resource
+
+ @@rslburl = 'http://www.pragma-ade.com/rng/rslb.rng'
+ @@rslbns = 'rl'
+ @@rslbtmp = 'rslbtool-tmp.xml'
+
+ def initialize (filename='',namespace=@@rslbns)
+ @ns = if namespace then @@rslbns + ':' else '' end
+ set_filename(filename)
+ @library = REXML::Document.new(skeleton,
+ {:ignore_whitespace_nodes => :all,
+ :compress_whitespace => :all})
+ @lastindex = 0
+ @texexec = 'texexec'
+ @downcaselabels = true
+ @downcasefilenames = true
+ end
+
+ def keeplabelcase
+ @downcaselabels = false
+ end
+
+ def keepfilenamecase
+ @downcasefilenames = false
+ end
+
+ def outer_skeleton (str)
+ tmp = if @ns.empty? then '' else " xmlns:#{@ns.sub(':','')}='#{@@rslburl}'" end
+ "<?xml version='1.0'?>\n" + "<#{@ns}library#{tmp}>\n" + str + "\n</#{@ns}library>"
+ end
+
+ def skeleton
+ outer_skeleton("<#{@ns}description>" +
+ "<#{@ns}organization>unknown</#{@ns}organization>" +
+ "<#{@ns}project>unknown</#{@ns}project>" +
+ "<#{@ns}product>unknown</#{@ns}product>" +
+ "<#{@ns}comment>unknown</#{@ns}comment>" +
+ "</#{@ns}description>")
+ end
+
+ def set_filename (filename)
+ @filename = if filename.empty? then 'unknown' else filename end
+ @fullname = @filename
+ @filename = File.basename(@filename).sub(/\..*$/,'')
+ end
+
+ def set_texexec (filename)
+ print "setting texexec binary to: #{filename}\n"
+ @texexec = filename
+ end
+
+ def load (filename='')
+ set_filename(filename)
+ if not filename.empty? and FileTest.file?(filename) # todo: test op valide fig base
+ @library = REXML::Document.new(File.new(filename),
+ {:ignore_whitespace_nodes => :all,
+ :compress_whitespace => :all})
+ unless @library.root.prefix.empty?
+ @ns = @library.root.prefix + ':'
+ end
+ else
+ initialize(filename,!@ns.empty?)
+ end
+ end
+
+ def save (filename)
+ filename += '.xml' unless filename =~ /\..*?$/
+ if not filename.empty? and f = open(filename,'w')
+ @library.write(f,0)
+ f.close
+ end
+ end
+
+ def figure_labels
+ REXML::XPath.match(@library.root,"/#{@ns}library/#{@ns}figure/#{@ns}label/text()")
+ end
+
+ def figure_records
+ @library.elements.to_a("/#{@ns}library/#{@ns}figure")
+ end
+
+ def figure_files
+ REXML::XPath.match(@library.root,"/#{@ns}library/#{@ns}figure/#{@ns}file/text()")
+ end
+
+ def delete_figure (label='')
+ return if label.empty?
+ labels = figure_labels
+ labels.each_index do |i|
+ if labels[i].to_s.downcase == label.downcase
+ @library.elements.delete_all("/#{@ns}library/#{@ns}figure[#{i+1}]")
+ end
+ end
+ end
+
+ def add_figure (file='',label='',prefix='')
+ return if file.empty? or file.match(/^#{@filename}\..*$/i)
+ labels = figure_labels
+ prefix = @filename if prefix.empty?
+ if label.empty?
+ i = @lastindex
+ loop do
+ i += 1
+ label = prefix + ' ' + i.to_s
+ break unless labels.include?(label)
+ end
+ else
+ delete_figure(label) unless label.empty?
+ end
+ e = REXML::Element.new("#{@ns}figure")
+ l = REXML::Element.new("#{@ns}label")
+ f = REXML::Element.new("#{@ns}file")
+ l.text, f.text = label, file
+ e.add_element(l)
+ e.add_element(f)
+ @library.root.add_element(e)
+ end
+
+ def add_figures (list='',prefix='')
+ if @downcasefilenames then
+ files = figure_files.downcase
+ [list].flatten.downcase.each do |f|
+ next unless FileTest.file?(f)
+ add_figure(f,'',prefix) unless files.include?(f)
+ end
+ else
+ files = figure_files
+ [list].flatten.each do |f|
+ next unless FileTest.file?(f)
+ add_figure(f,'',prefix) unless files.include?(f)
+ end
+ end
+ end
+
+ def delete_figures (list='')
+ [list].flatten.downcase.each do |l|
+ delete_figure(l)
+ end
+ end
+
+ def sort_figures
+ if @downcaselabels then
+ labels = figure_labels.downcase
+ else
+ labels = figure_labels
+ end
+ return unless labels
+ figures = figure_records
+ @library.elements.delete_all("/#{@ns}library/#{@ns}figure")
+ labels = labels.collect do |l| # prepare numbers
+ l.gsub(/(\d+)/) do |d| sprintf('%05d', d) end
+ end
+ labels.sort.each do |s|
+ @library.root.add_element(figures[labels.index(s)])
+ end
+ end
+
+ def purge_figures
+ REXML::XPath.each(@library.root,"/#{@ns}library/#{@ns}figure") do |e|
+ filename = REXML::XPath.match(e,"#{@ns}file/text()").to_s
+ e.parent.delete(e) unless FileTest.file?(filename)
+ end
+ end
+
+ def run_command(command)
+ print "calling #{command}\n"
+ print "\n"
+ begin
+ system(command)
+ rescue
+ # sorry again
+ end
+ print "\n"
+ end
+
+ def create_dummies(process=false,result='',zipalso='')
+ result = @filename if result.empty?
+ list = REXML::XPath.match(@library.root,"/#{@ns}library/#{@ns}usage")
+ begin
+ File.delete(result+'.pdf')
+ rescue
+ # no way
+ end
+ return unless list && list.length>0
+ done = Array.new
+ list.each do |e|
+ t = REXML::XPath.match(e,"#{@ns}type/text()")
+ s = REXML::XPath.match(e,"#{@ns}state/text()")
+ if t && (t.to_s == 'figure') && s && (s.to_s == 'missing')
+ begin
+ f = REXML::XPath.match(e,"#{@ns}file/text()").to_s
+ if done.index(f)
+ print "skipping dummy figure: " + f + "\n"
+ elsif f =~ /\s/o
+ print "skipping crappy fname: " + f + "\n"
+ elsif f == 'dummy'
+ print "skipping dummy figure: " + f + "\n"
+ else
+ print "creating dummy figure: " + f + "\n"
+ if process && (x = open(@@rslbtmp,'w'))
+ x.puts(outer_skeleton(e.to_s))
+ x.close
+ run_command ("#{@texexec} --pdf --once --batch --silent --random --use=res-10 --xml --result=#{f} #{@@rslbtmp}")
+ end
+ done.push(f+'.pdf')
+ begin
+ File.delete(@@rslbtmp)
+ rescue
+ # sorry once more
+ end
+ end
+ rescue
+ # sorry, skip 'm
+ end
+ end
+ end
+ if process && (done.length>0)
+ begin
+ File.delete(result + '.zip')
+ rescue
+ # ok
+ end
+ run_command("zip #{result+'.zip'} #{@fullname}")
+ unless zipalso.empty?
+ begin
+ zipalso.split(',').each do |name|
+ run_command("zip #{result+'.zip'} #{name}")
+ end
+ end
+ end
+ done.each do |name|
+ run_command("zip #{result+'.zip'} #{name}")
+ end
+ run_command("#{@texexec} --pdf --batch --silent --use=res-11 --xml --result=#{result} #{@fullname}")
+ done.each do |name|
+ begin
+ File.delete(name)
+ rescue
+ # sorry
+ end
+ end
+ end
+ end
+
+end
+
+# reslib = Resource.new
+# reslib.load('f.xml') # reslib.load('figbase.xml')
+# reslib.delete_figure('figbase 5')
+# reslib.delete_figure('figbase 5')
+# reslib.add_figure('a.pdf')
+# reslib.add_figure('b.pdf','something')
+# reslib.add_figure('c.pdf')
+# reslib.add_files('x.pdf')
+# reslib.save('figbase.tmp')
diff --git a/Master/texmf-dist/scripts/context/ruby/rslibtool.rb b/Master/texmf-dist/scripts/context/ruby/rslibtool.rb
new file mode 100644
index 00000000000..7ae5efb647e
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/rslibtool.rb
@@ -0,0 +1,114 @@
+# program : rslibtool
+# copyright : PRAGMA Publishing On Demand
+# version : 1.00 - 2002
+# author : Hans Hagen
+#
+# project : eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-pod.com / www.pragma-ade.com
+
+# --add --base=filename --path=directory pattern
+# --remove --base=filename --path=directory label
+# --sort --base=filename --path=directory
+# --purge --base=filename --path=directory
+# --dummy --base=filename
+# --namespace
+
+# rewrite
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'')
+ $: << ownpath
+end
+
+require 'rslb/base'
+require 'xmpl/base'
+require 'xmpl/switch'
+
+session = Example.new('rslbtool', '1.0', 'PRAGMA POD')
+
+session.identify
+
+commandline = CommandLine.new
+
+commandline.registerflag('add')
+commandline.registerflag('remove')
+commandline.registerflag('delete')
+commandline.registerflag('sort')
+commandline.registerflag('purge')
+commandline.registerflag('dummy')
+commandline.registerflag('process')
+commandline.registerflag('namespace')
+
+commandline.registervalue('prefix')
+commandline.registervalue('base')
+commandline.registervalue('path')
+commandline.registervalue('result')
+commandline.registervalue('texexec')
+commandline.registervalue('zipalso')
+
+commandline.expand
+
+session.inherit(commandline)
+
+base = session.get('option.base')
+path = session.get('option.path')
+
+base = 'rslbtool.xml' if base.empty?
+
+# when path is given, assume that arg list is list of
+# suffixes, else assume it is a list of globbed filespec
+
+if path.empty?
+ base += '.xml' unless base =~ /\..+$/
+ list = commandline.arguments
+else
+ Dir.chdir(File.dirname(path))
+ list = Dir.glob("*.{#{commandline.arguments.join(',')}}")
+end
+
+begin
+ reslib = Resource.new(base,session.get('option.namespace'))
+ reslib.load(base)
+rescue
+ session.error('problems with loading base')
+ exit
+end
+
+unless session.get('option.texexec').empty?
+ reslib.set_texexec(session.get('option.texexec'))
+end
+
+if session.get('option.add')
+
+ session.report('adding records', list)
+ reslib.add_figures(list,session.get('option.prefix'))
+
+elsif session.get('option.remove') or session.get('option.delete')
+
+ session.report('removing records')
+ reslib.delete_figures(list)
+
+elsif session.get('option.sort')
+
+ session.report('sorting records')
+ reslib.sort_figures()
+
+elsif session.get('option.purge')
+
+ session.report('purging records')
+ reslib.purge_figures()
+
+elsif session.get('option.dummy')
+
+ session.report('creating dummy records')
+ reslib.create_dummies(session.get('option.process'),session.get('option.result'),session.get('option.zipalso'))
+
+else
+
+ session.warning('provide action')
+
+end
+
+reslib.save(base)
diff --git a/Master/texmf-dist/scripts/context/ruby/runtools.rb b/Master/texmf-dist/scripts/context/ruby/runtools.rb
new file mode 100644
index 00000000000..77f805221aa
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/runtools.rb
@@ -0,0 +1,506 @@
+require 'timeout'
+require 'fileutils'
+# require 'ftools'
+require 'rbconfig'
+
+class File
+
+ # we don't want a/b//c
+ #
+ # puts File.join('a','b','c')
+ # puts File.join('/a','b','c')
+ # puts File.join('a:','b','c')
+ # puts File.join('a/','/b/','c')
+ # puts File.join('/a','/b/','c')
+ # puts File.join('//a/','/b/','c')
+
+ def File.join(*list)
+ path, prefix = [*list].flatten.join(File::SEPARATOR), ''
+ path.sub!(/^([\/]+)/) do
+ prefix = $1
+ ''
+ end
+ path.gsub!(/([\\\/]+)/) do
+ File::SEPARATOR
+ end
+ prefix + path
+ end
+
+end
+
+
+class Job
+
+ $ownfile, $ownpath = '', ''
+
+ def Job::set_own_path(file)
+ $ownfile, $ownpath = File.basename(file), File.expand_path(File.dirname(file))
+ $: << $ownpath
+ end
+
+ def Job::ownfile
+ $ownfile
+ end
+
+ def Job::ownpath
+ $ownpath
+ end
+
+end
+
+class Job
+
+ def initialize
+ @startuppath = Dir.getwd
+ @log = Array.new
+ @testmode = false
+ @ownpath = $ownpath
+ @paths = Array.new
+ end
+
+ def exit(showlog=false)
+ Dir.chdir(@startuppath)
+ show_log if showlog
+ Kernel::exit
+ end
+
+ def platform
+ case RbConfig::CONFIG['host_os']
+ when /mswin/ then :windows
+ else :unix
+ end
+ end
+
+ def path(*components)
+ File.join([*components].flatten)
+ end
+
+ def found(name)
+ FileTest.file?(path(name)) || FileTest.directory?(path(name))
+ end
+
+ def binary(name)
+ if platform == :windows then
+ name.sub(/\.[^\/]+$/o,'') + '.exe'
+ else
+ name
+ end
+ end
+
+ def suffixed(name,suffix)
+ if name =~ /\.[^\/]+$/o then
+ name
+ else
+ name + '.' + suffix
+ end
+ end
+
+ def expanded(*name)
+ File.expand_path(File.join(*name))
+ end
+
+ def argument(n,default=nil)
+ ARGV[n] || default
+ end
+
+ def variable(name,default='')
+ ENV[name] || default
+ end
+
+ def change_dir(*dir)
+ dir, old = expanded(path(*dir)), expanded(Dir.getwd)
+ unless old == dir then
+ begin
+ Dir.chdir(dir)
+ rescue
+ error("unable to change to path #{dir}")
+ else
+ if old == dir then
+ error("error in changing to path #{dir}")
+ else
+ message("changed to path #{dir}")
+ end
+ end
+ end
+ # return File.expand_path(Dir.getwd)
+ end
+
+ def delete_dir(*dir)
+ begin
+ dir = path(*dir)
+ pattern = "#{dir}/**/*"
+ puts("analyzing dir #{pattern}")
+ files = Dir.glob(pattern).sort.reverse
+ files.each do |f|
+ begin
+ # FileTest.file?(f) fails on .whatever files
+ File.delete(f)
+ rescue
+ # probably directory
+ else
+ puts("deleting file #{f}")
+ end
+ end
+ files.each do |f|
+ begin
+ Dir.rmdir(f)
+ rescue
+ # strange
+ else
+ message("deleting path #{f}")
+ end
+ end
+ begin
+ Dir.rmdir(dir)
+ rescue
+ # strange
+ else
+ message("deleting parent #{dir}")
+ end
+ Dir.glob(pattern).sort.each do |f|
+ warning("unable to delete #{f}")
+ end
+ rescue
+ warning("unable to delete path #{File.expand_path(dir)} (#{$!})")
+ else
+ message("path #{File.expand_path(dir)} removed")
+ end
+ end
+
+
+ def create_dir(*dir)
+ begin
+ dir = path(*dir)
+ unless FileTest.directory?(dir) then
+ File.makedirs(dir)
+ else
+ return
+ end
+ rescue
+ error("unable to create path #{File.expand_path(dir)}")
+ else
+ message("path #{File.expand_path(dir)} created")
+ end
+ end
+
+ def show_dir(delay=0)
+ _puts_("\n")
+ print Dir.getwd + ' '
+ begin
+ timeout(delay) do
+ loop do
+ print '.'
+ sleep(1)
+ end
+ end
+ rescue TimeoutError
+ # ok
+ end
+ _puts_("\n\n")
+ end
+
+ def copy_file(from,to='.',exclude=[])
+ to, ex = path(to), [exclude].flatten
+ Dir.glob(path(from)).each do |file|
+ tofile = to.sub(/[\.\*]$/o) do File.basename(file) end
+ _do_copy_(file,tofile) unless ex.include?(File.extname(file))
+ end
+ end
+
+ def clone_file(from,to)
+ if from and to then
+ to = File.join(File.basename(from),to) if File.basename(to).empty?
+ _do_copy_(from,to)
+ end
+ end
+
+ def copy_dir(from,to,pattern='*',exclude=[]) # recursive
+ pattern = '*' if ! pattern or pattern.empty?
+ if from and to and File.expand_path(from) != File.expand_path(to) then
+ ex = [exclude].flatten
+ Dir.glob("#{from}/**/#{pattern}").each do |file|
+ unless ex.include?(File.extname(file)) then
+ _do_copy_(file,File.join(to,file.sub(/^#{from}/, '')))
+ end
+ end
+ end
+ end
+
+ def copy_path(from,to,pattern='*',exclude=[]) # non-recursive
+ pattern = '*' if ! pattern or pattern.empty?
+ if from and to and File.expand_path(from) != File.expand_path(to) then
+ ex = [exclude].flatten
+ Dir.glob("#{from}/#{pattern}").each do |file|
+ unless ex.include?(File.extname(file)) then
+ _do_copy_(file,File.join(to,file.sub(/^#{from}/, '')))
+ end
+ end
+ end
+ end
+
+ def _do_copy_(file,tofile)
+ if FileTest.file?(file) and File.expand_path(file) != File.expand_path(tofile) then
+ begin
+ create_dir(File.dirname(tofile))
+ File.copy(file,tofile)
+ rescue
+ error("unable to copy #{file} to #{tofile}")
+ else
+ message("file #{file} copied to #{tofile}")
+ end
+ else
+ puts("file #{file} is not copied")
+ end
+ end
+
+ def rename_file(from,to)
+ from, to = path(from), path(to)
+ begin
+ File.move(from,to)
+ rescue
+ error("unable to rename #{from} to #{to}")
+ else
+ message("#{from} renamed to #{to}")
+ end
+ end
+
+ def delete_file(pattern)
+ Dir.glob(path(pattern)).each do |file|
+ _do_delete_(file)
+ end
+ end
+
+ def delete_files(*files)
+ [*files].flatten.each do |file|
+ _do_delete_(file)
+ end
+ end
+
+ def _do_delete_(file)
+ if FileTest.file?(file) then
+ begin
+ File.delete(file)
+ rescue
+ error("unable to delete file #{file}")
+ else
+ message("file #{file} deleted")
+ end
+ else
+ message("no file #{File.expand_path(file)}")
+ end
+ end
+
+ def show_log(filename=nil)
+ if filename then
+ begin
+ if f = File.open(filename,'w') then
+ @log.each do |line|
+ f.puts(line)
+ end
+ f.close
+ end
+ message("log data written to #{filename}")
+ rescue
+ error("unable to write log to #{filename}")
+ end
+ else
+ @log.each do |line|
+ _puts_(line)
+ end
+ end
+ end
+
+ def _puts_(str)
+ begin
+ STDOUT.puts( str)
+ rescue
+ STDERR.puts("error while writing '#{str}' to terminal")
+ end
+ end
+
+ def puts(message)
+ @log << message
+ _puts_(message)
+ end
+
+ def error(message)
+ puts("! #{message}")
+ exit
+ end
+
+ def warning(message)
+ puts("- #{message}")
+ end
+
+ def message(message)
+ puts("+ #{message}")
+ end
+
+ def export_variable(variable,value)
+ value = path(value) if value.class == Array
+ ENV[variable] = value
+ message("environment variable #{variable} set to #{value}")
+ return value
+ end
+
+ def execute_command(*command)
+ begin
+ command = [*command].flatten.join(' ')
+ message("running '#{command}'")
+ _puts_("\n")
+ ok = system(command)
+ _puts_("\n")
+ if true then # ok then
+ message("finished '#{command}'")
+ else
+ error("error in running #{command}")
+ end
+ rescue
+ error("unable to run #{command}")
+ end
+ end
+
+ def pipe_command(*command)
+ begin
+ command = [*command].flatten.join(' ')
+ message("running '#{command}'")
+ result = `#{command}`
+ _puts_("\n")
+ _puts_(result)
+ _puts_("\n")
+ rescue
+ error("unable to run #{command}")
+ end
+ end
+
+ def execute_script(script)
+ script = suffixed(script,'rb')
+ script = path(script_path,File.basename(script)) unless found(script)
+ if found(script) then
+ begin
+ message("loading script #{script}")
+ load(script)
+ rescue
+ error("error in loading script #{script} (#{$!})")
+ else
+ message("script #{script} finished")
+ end
+ else
+ warning("no script #{script}")
+ end
+ end
+
+ def execute_binary(*command)
+ command = [*command].flatten.join(' ').split(' ')
+ command[0] = binary(command[0])
+ execute_command(command)
+ end
+
+ def extend_path(pth)
+ export_variable('PATH',"#{path(pth)}#{File::PATH_SEPARATOR}#{ENV['PATH']}")
+ end
+
+ def startup_path
+ @startuppath
+ end
+
+ def current_path
+ Dir.getwd
+ end
+
+ def script_path
+ @ownpath
+ end
+
+ def push_path(newpath)
+ newpath = File.expand_path(newpath)
+ @paths.push(newpath)
+ change_dir(newpath)
+ end
+
+ def pop_path
+ change_dir(if @paths.length > 0 then @paths.pop else @startuppath end)
+ end
+
+ # runner = Runner.new
+ # runner.texmfstart('texexec','--help')
+
+ def texmfstart(name,args,verbose=false)
+ command = ['texmfstart',"#{'--verbose' if verbose}",name,args].flatten.join(' ')
+ system(command)
+ end
+
+end
+
+class Job
+
+ # copied from texmfstart and patched (message/error), different name
+
+ def use_tree(tree)
+ unless tree.empty? then
+ begin
+ setuptex = File.join(tree,'setuptex.tmf')
+ if FileTest.file?(setuptex) then
+ message("tex tree : #{setuptex}")
+ ENV['TEXPATH'] = tree.sub(/\/+$/,'') # + '/'
+ ENV['TMP'] = ENV['TMP'] || ENV['TEMP'] || ENV['TMPDIR'] || ENV['HOME']
+ case RUBY_PLATFORM
+ when /(mswin|bccwin|mingw|cygwin)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-mswin'
+ when /(linux)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-linux'
+ when /(darwin|rhapsody|nextstep)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-macosx'
+ # when /(netbsd|unix)/i then # todo
+ else # todo
+ end
+ ENV['TEXMFOS'] = "#{ENV['TEXPATH']}/#{ENV['TEXOS']}"
+ message("preset : TEXPATH => #{ENV['TEXPATH']}")
+ message("preset : TEXOS => #{ENV['TEXOS']}")
+ message("preset : TEXMFOS => #{ENV['TEXMFOS']}")
+ message("preset : TMP => #{ENV['TMP']}")
+ IO.readlines(File.join(tree,'setuptex.tmf')).each do |line|
+ case line
+ when /^[\#\%]/ then
+ # comment
+ when /^(.*?)\s+\=\s+(.*)\s*$/ then
+ k, v = $1, $2
+ ENV[k] = v.gsub(/\%(.*?)\%/) do
+ ENV[$1] || ''
+ end
+ message("user set : #{k} => #{ENV[k]}")
+ end
+ end
+ else
+ warning("no setup file '#{setuptex}', tree not initialized") # no error
+ end
+ rescue
+ warning("error in setup: #{$!}")
+ end
+ end
+ end
+
+end
+
+Job::set_own_path($0)
+
+if Job::ownfile == 'runtools.rb' then
+
+ begin
+ script = ARGV.shift
+ if script then
+ script += '.rb' if File.extname(script).empty?
+ fullname = File.expand_path(script)
+ fullname = File.join(Job::ownpath,script) unless FileTest.file?(fullname)
+ if FileTest.file?(fullname) then
+ puts("loading script #{fullname}")
+ Job::set_own_path(fullname)
+ load(fullname)
+ else
+ puts("unknown script #{fullname}")
+ end
+ else
+ puts("provide script name")
+ end
+ rescue
+ puts("fatal error: #{$!}")
+ end
+
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/texexec.rb b/Master/texmf-dist/scripts/context/ruby/texexec.rb
new file mode 100644
index 00000000000..7f8298c0918
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/texexec.rb
@@ -0,0 +1,791 @@
+#!/usr/bin/env ruby
+#encoding: ASCII-8BIT
+
+banner = ['TeXExec', 'version 6.2.1', '1997-2009', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'fileutils'
+# require 'ftools' # needed ?
+
+require 'base/switch'
+require 'base/logger'
+require 'base/variables'
+require 'base/system'
+
+require 'base/state' # needed ?
+require 'base/file' # needed ?
+
+require 'base/tex'
+require 'base/texutil'
+require 'base/kpse'
+
+class Commands
+
+ include CommandBase
+
+ def make
+ if job = TEX.new(logger) then
+ prepare(job)
+ # bonus, overloads language switch !
+ job.setvariable('language','all') if @commandline.option('all')
+ if @commandline.arguments.length > 0 then
+ if @commandline.arguments.first == 'all' then
+ job.setvariable('texformats',job.defaulttexformats)
+ job.setvariable('mpsformats',job.defaultmpsformats)
+ else
+ job.setvariable('texformats',@commandline.arguments)
+ job.setvariable('mpsformats',@commandline.arguments)
+ end
+ end
+ job.makeformats
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ seterror if job.error?
+ end
+ end
+
+ def check
+ if job = TEX.new(logger) then
+ job.checkcontext
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ end
+ end
+
+ def main
+ if @commandline.arguments.length>0 then
+ process
+ else
+ help
+ end
+ end
+
+ def process
+ if job = TEX.new(logger) then
+ job.setvariable('files',@commandline.arguments)
+ prepare(job)
+ job.processtex
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ seterror if job.error?
+ end
+ end
+
+ def mptex
+ if job = TEX.new(logger) then
+ job.setvariable('files',@commandline.arguments)
+ prepare(job)
+ job.processmptex
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ seterror if job.error?
+ end
+ end
+
+ def mpxtex
+ if job = TEX.new(logger) then
+ job.setvariable('files',@commandline.arguments)
+ prepare(job)
+ job.processmpxtex
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ seterror if job.error?
+ end
+ end
+
+ def mpgraphic
+ if job = TEX.new(logger) then
+ job.setvariable('files',@commandline.arguments)
+ prepare(job)
+ job.processmpgraphic
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ seterror if job.error?
+ end
+ end
+
+ def mpstatic
+ if job = TEX.new(logger) then
+ job.setvariable('filename',@commandline.arguments.first)
+ prepare(job)
+ job.processmpstatic
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ seterror if job.error?
+ end
+ end
+
+ # hard coded goodies # to be redone as s-ctx-.. with vars passed as such
+
+ def listing
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ backspace = @commandline.checkedoption('backspace', '1.5cm')
+ topspace = @commandline.checkedoption('topspace', '1.5cm')
+ pretty = @commandline.option('pretty')
+ f << "% interface=english\n"
+ f << "\\setupbodyfont[11pt,tt]\n"
+ f << "\\setuplayout\n"
+ f << " [topspace=#{topspace},backspace=#{backspace},\n"
+ f << " header=0cm,footer=1.5cm,\n"
+ f << " width=middle,height=middle]\n"
+ f << "\\setuptyping[lines=yes]\n"
+ f << "\\setuptyping[option=color]\n" if pretty
+ f << "\\starttext\n";
+ files.each do |filename|
+ report("list file: #{filename}")
+ cleanname = cleantexfilename(filename).downcase
+ f << "\\page\n"
+ f << "\\setupfootertexts[\\tttf #{cleanname}][\\tttf \\pagenumber]\n"
+ f << "\\typefile{#{filename}}\n"
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ # job.setvariable('nooptionfile',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to list')
+ end
+ else
+ report('no files to list')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def figures
+ # we replaced "texutil --figures ..."
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ fast = @commandline.option('fast')
+ files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end
+ if fast or (files.length > 0) then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ files.delete("texexec.pdf")
+ # Kpse.runscript('rlxtools', ['--identify','--collect'], files.join(' ')) unless fast
+ system("texmfstart rlxtools --identify --collect #{files.join(' ')}")
+ figures = @commandline.checkedoption('method', 'a').downcase
+ paperoffset = @commandline.checkedoption('paperoffset', '0pt')
+ backspace = @commandline.checkedoption('backspace', '1.5cm')
+ topspace = @commandline.checkedoption('topspace', '1.5cm')
+ boxtype = @commandline.checkedoption('boxtype','')
+ f << "% format=english\n";
+ f << "\\usemodule[res-20]\n"
+ f << "\\setuplayout\n";
+ f << " [topspace=#{topspace},backspace=#{backspace},\n"
+ f << " header=1.5cm,footer=0pt,\n";
+ f << " width=middle,height=middle]\n";
+ if @commandline.option('fullscreen') then
+ f << "\\setupinteraction\n";
+ f << " [state=start]\n";
+ f << "\\setupinteractionscreen\n";
+ f << " [option=max]\n";
+ end
+ boxtype += "box" unless boxtype.empty? || (boxtype =~ /box$/io)
+ f << "\\starttext\n";
+ f << "\\showexternalfigures[alternative=#{figures},offset=#{paperoffset},size=#{boxtype}]\n";
+ f << "\\stoptext\n";
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ # File.silentdelete('rlxtools.rli') unless job.getvariable('keep')
+ else
+ report('no figures to show')
+ end
+ else
+ report('no figures to show')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def modules
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end
+ msuffixes = ['tex','mkii','mkiv','mp','pl','pm','rb']
+ if files.length > 0 then
+ files.each do |fname|
+ fnames = Array.new
+ if FileTest.file?(fname) then
+ fnames << fname
+ else
+ msuffixes.each do |fsuffix|
+ fnames << File.suffixed(fname,fsuffix)
+ end
+ end
+ fnames.each do |ffname|
+ if msuffixes.include?(File.splitname(ffname)[1]) && FileTest.file?(ffname) then
+ if mod = File.open(job.tempfilename('tex'),'w') then
+ if File.suffix(ffname) =~ /^(mkii|mkiv)$/o then
+ markfile = $1
+ else
+ markfile = nil
+ end
+ # Kpse.runscript('ctxtools',['--document'],ffname)
+ system("texmfstart ctxtools --document #{ffname}")
+ if ted = File.silentopen(File.suffixed(ffname,'ted')) then
+ firstline = ted.gets
+ if firstline =~ /interface=/o then
+ mod << firstline
+ else
+ mod << "% interface=en\n"
+ end
+ ted.close
+ else
+ mod << "% interface=en\n"
+ end
+ mod << "\\usemodule[mod-01]\n"
+ mod << "\\def\\ModuleNumber{1}\n"
+ mod << "\\starttext\n"
+ # todo: global file too
+ mod << "\\readlocfile{#{File.suffixed(ffname,'ted')}}{}{}\n"
+ mod << "\\stoptext\n"
+ mod.close
+ job.setvariable('interface','english') # redundant
+ # job.setvariable('simplerun',true)
+ # job.setvariable('nooptionfile',true)
+ job.setvariable('files',[job.tempfilename])
+ result = File.unsuffixed(File.basename(ffname))
+ if markfile then
+ result = result+'-'+markfile
+ end
+ job.setvariable('result',result)
+ job.processtex
+ # ["dvi", "pdf","ps"].each do |s|
+ # File.silentrename(job.tempfilename(s),File.suffixed(ffname,s));
+ # end
+ end
+ end
+ end
+ end
+ else
+ report('no modules to process')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def pdfsplit
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ filename = File.expand_path(@commandline.arguments.first)
+ if FileTest.file?(filename) then
+ basename = filename.sub(/\..*?$/,'')
+ tempfile = File.suffixed(job.tempfilename,'tex')
+ if basename != filename then
+ info = `pdfinfo #{filename}`
+ if info =~ /Pages:\s*(\d+)/ then
+ nofpages = $1.to_i
+ result = @commandline.checkedoption('result','texexec')
+ nofpages.times do |i|
+ if f = File.open(tempfile,"w") then
+ n = i + 1
+ report("extracting page #{n}")
+ f << "\\starttext\\startTEXpage\n"
+ f << "\\externalfigure[#{filename}][object=no,page=#{n}]\n"
+ f << "\\stopTEXpage\\stoptext\n"
+ f.close
+ job.setvariable('result',"#{result}-#{n}")
+ job.setvariable('interface','english') # redundant
+ job.setvariable('simplerun',true)
+ job.setvariable('purge',true)
+ job.setvariable('files',[tempfile])
+ job.processtex
+ end
+ end
+ end
+ end
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def arrangeoutput
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ emptypages = @commandline.checkedoption('addempty', '')
+ paperoffset = @commandline.checkedoption('paperoffset', '0cm')
+ textwidth = @commandline.checkedoption('textwidth', '0cm')
+ backspace = @commandline.checkedoption('backspace', '0cm')
+ topspace = @commandline.checkedoption('topspace', '0cm')
+ f << "\\definepapersize\n"
+ f << " [offset=#{paperoffset}]\n"
+ f << "\\setuplayout\n"
+ f << " [backspace=#{backspace},\n"
+ f << " topspace=#{topspace},\n"
+ f << " marking=on,\n" if @commandline.option('marking')
+ f << " width=middle,\n"
+ f << " height=middle,\n"
+ f << " location=middle,\n"
+ f << " header=0pt,\n"
+ f << " footer=0pt]\n"
+ unless @commandline.option('noduplex') then
+ f << "\\setuppagenumbering\n"
+ f << " [alternative=doublesided]\n"
+ end
+ f << "\\starttext\n"
+ files.each do |filename|
+ report("arranging file #{filename}")
+ f << "\\insertpages\n"
+ f << " [#{filename}]\n"
+ f << " [#{emptypages}]\n" unless emptypages.empty?
+ f << " [width=#{textwidth}]\n"
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('arrange',true)
+ # job.setvariable('nooptionfile',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to arrange')
+ end
+ else
+ report('no files to arrange')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def selectoutput
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ selection = @commandline.checkedoption('selection', '')
+ paperoffset = @commandline.checkedoption('paperoffset', '0cm')
+ textwidth = @commandline.checkedoption('textwidth', '0cm')
+ backspace = @commandline.checkedoption('backspace', '0cm')
+ topspace = @commandline.checkedoption('topspace', '0cm')
+ paperformat = @commandline.checkedoption('paperformat', 'A4*A4').split(/[\*x]/o)
+ from, to = paperformat[0] || 'A4', paperformat[1] || paperformat[0] || 'A4'
+ if from == 'fit' or to == 'fit' then
+ f << "\\getfiguredimensions[#{files.first}]\n"
+ if from == 'fit' then
+ f << "\\expanded{\\definepapersize[from-fit][width=\\figurewidth,height=\\figureheight]}\n"
+ from = 'from-fit'
+ end
+ if to == 'fit' then
+ f << "\\expanded{\\definepapersize[to-fit][width=\\figurewidth,height=\\figureheight]}\n"
+ to = 'to-fit'
+ end
+ end
+ job.setvariable('paperformat','') # else overloaded later on
+ f << "\\setuppapersize[#{from}][#{to}]\n"
+ f << "\\definepapersize\n";
+ f << " [offset=#{paperoffset}]\n";
+ f << "\\setuplayout\n";
+ f << " [backspace=#{backspace},\n";
+ f << " topspace=#{topspace},\n";
+ f << " marking=on,\n" if @commandline.option('marking')
+ f << " width=middle,\n";
+ f << " height=middle,\n";
+ f << " location=middle,\n";
+ f << " header=0pt,\n";
+ f << " footer=0pt]\n";
+ f << "\\setupexternalfigures\n";
+ f << " [directory=]\n";
+ f << "\\starttext\n";
+ unless selection.empty? then
+ f << "\\filterpages\n"
+ f << " [#{files.first}][#{selection}][width=#{textwidth}]\n"
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ # job.setvariable('nooptionfile',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to selectt')
+ end
+ else
+ report('no files to select')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def copyoutput
+ copyortrim(false,'copy')
+ end
+
+ def trimoutput
+ copyortrim(true,'trim')
+ end
+
+ def copyortrim(trim=false,what='unknown')
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ scale = @commandline.checkedoption('scale')
+ begin
+ scale = (scale.to_f * 1000.0).to_i if scale.to_i < 10
+ rescue
+ scale = 1000
+ end
+ scale = scale.to_i
+ paperoffset = @commandline.checkedoption('paperoffset', '0cm')
+ f << "\\starttext\n"
+ files.each do |filename|
+ result = @commandline.checkedoption('result','texexec')
+ begin
+ if (filename !~ /^texexec/io) && (filename !~ /^#{result}/) then
+ report("copying file: #{filename}")
+ f << "\\getfiguredimensions\n"
+ f << " [#{filename}]\n"
+ f << " [scale=#{scale},\n"
+ f << " page=1,\n"
+ f << " size=trimbox\n" if trim
+ f << "]\n"
+ f << "\\definepapersize\n"
+ f << " [copy]\n"
+ f << " [width=\\figurewidth,\n"
+ f << " height=\\figureheight]\n"
+ f << "\\setuppapersize\n"
+ f << " [copy][copy]\n"
+ f << "\\setuplayout\n"
+ f << " [page]\n"
+ f << "\\setupexternalfigures\n"
+ f << " [directory=]\n"
+ f << "\\copypages\n"
+ f << " [#{filename}]\n"
+ f << " [scale=#{scale},\n"
+ f << " marking=on,\n" if @commandline.option('markings')
+ f << " size=trimbox,\n" if trim
+ f << " offset=#{paperoffset}]\n"
+ end
+ rescue
+ report("wrong specification")
+ end
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ # job.setvariable('nooptionfile',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report("no files to #{what}")
+ end
+ else
+ report("no files to #{what}")
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ # todo: make this styles
+
+ def combineoutput
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = if @commandline.option('sort') then @commandline.arguments.sort else @commandline.arguments end
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ paperoffset = @commandline.checkedoption('paperoffset', '0cm')
+ combination = @commandline.checkedoption('combination','2*2').split(/[\*x]/o)
+ paperformat = @commandline.checkedoption('paperformat', 'A4*A4').split(/[\*x]/o)
+ bannerheight = @commandline.checkedoption('bannerheight', '')
+ pdftitle = @commandline.checkedoption('pdftitle', '')
+ nx, ny = combination[0] || '2', combination[1] || combination[0] || '2'
+ from, to = paperformat[0] || 'A4', paperformat[1] || paperformat[0] || 'A4'
+ f << "\\setuppapersize[#{from}][#{to}]\n"
+ f << "\\setuplayout\n"
+ f << " [topspace=#{paperoffset},backspace=#{paperoffset},\n"
+ f << " header=0pt,footer=0pt,\n"
+ f << " width=middle,height=middle]\n"
+ if bannerheight.empty? then
+ f << "\\setuplayout[footer=1cm]\n"
+ else
+ f << "\\definelayer[page][width=\\paperwidth,height=\\paperheight]\n"
+ f << "\\setupbackgrounds[page][background=page]\n"
+ end
+ if @commandline.option('nobanner') then
+ f << "\\setuplayout[footer=0cm]\n"
+ f << "\\setupbackgrounds[page][background=]\n"
+ end
+ f << "\\setupexternalfigures[directory=]\n"
+ if not pdftitle.empty? then
+ f << "\\setupinteraction[state=start,title={#{pdftitle}}]\n"
+ end
+ f << "\\starttext\n"
+ files.each do |filename|
+ result = @commandline.checkedoption('result','texexec')
+ if (filename !~ /^texexec/io) && (filename !~ /^#{result}/) then
+ report("combination file: #{filename}")
+ cleanname = cleantexfilename(filename).downcase
+ bannerstring = "\\tttf #{cleanname}\\quad\\quad\\currentdate\\quad\\quad\\pagenumber"
+ if bannerheight.empty? then
+ f << "\\setupfootertexts\n"
+ f << " [#{bannerstring}]\n"
+ else
+ # for the moment we lack a better hook
+ f << "\\setuptexttexts\n"
+ f << " [{\\setlayerframed[page][preset=middlebottom][frame=off,height=#{bannerheight}]{#{bannerstring}}}]\n"
+ end
+ f << "\\combinepages[#{filename}][nx=#{nx},ny=#{ny}]\n"
+ f << "\\page\n"
+ end
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ # job.setvariable('nooptionfile',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to list')
+ end
+ else
+ report('no files to list')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ private
+
+ def prepare(job)
+
+ job.booleanvars.each do |k|
+ job.setvariable(k,@commandline.option(k))
+ end
+ job.stringvars.each do |k|
+ job.setvariable(k,@commandline.option(k)) unless @commandline.option(k).empty?
+ end
+ job.standardvars.each do |k|
+ job.setvariable(k,@commandline.option(k)) unless @commandline.option(k).empty?
+ end
+ job.knownvars.each do |k|
+ job.setvariable(k,@commandline.option(k)) unless @commandline.option(k).empty?
+ end
+
+job.setvariable('given.backend',job.getvariable('backend'))
+
+ if (str = @commandline.option('engine')) && ! str.standard? && ! str.empty? then
+ job.setvariable('texengine',str)
+ elsif @commandline.oneof('pdfetex','pdftex','pdf') then
+ job.setvariable('texengine','pdftex')
+ elsif @commandline.oneof('xetex','xtx') then
+ job.setvariable('texengine','xetex')
+ elsif @commandline.oneof('aleph') then
+ job.setvariable('texengine','aleph')
+ elsif @commandline.oneof('petex') then
+ job.setvariable('texengine','petex')
+ else
+ job.setvariable('texengine','standard')
+ end
+
+ if (str = @commandline.option('backend')) && ! str.standard? && ! str.empty? then
+ job.setvariable('backend',str)
+ elsif @commandline.oneof('pdfetex','pdftex','pdf') then
+ job.setvariable('backend','pdftex')
+ elsif @commandline.oneof('dvipdfmx','dvipdfm','dpx','dpm') then
+ job.setvariable('backend','dvipdfmx')
+ elsif @commandline.oneof('xetex','xtx') then
+ job.setvariable('backend','xetex')
+ elsif @commandline.oneof('aleph') then
+ job.setvariable('backend','dvipdfmx')
+ elsif @commandline.oneof('petex') then
+ job.setvariable('backend','dvipdfmx')
+ elsif @commandline.oneof('dvips','ps') then
+ job.setvariable('backend','dvips')
+ elsif @commandline.oneof('xdv') then
+ job.setvariable('backend','xdv')
+ else
+ case job.getvariable('texengine')
+ when 'pdfetex' then job.setvariable('backend','pdftex')
+ when 'pdftex' then job.setvariable('backend','pdftex')
+ when 'xetex' then job.setvariable('backend','xetex')
+ when 'petex' then job.setvariable('backend','dvipdfmx')
+ when 'aleph' then job.setvariable('backend','dvipdfmx')
+ else
+ job.setvariable('backend','standard')
+ end
+ end
+
+ if (str = @commandline.option('engine')) && ! str.standard? && ! str.empty? then
+ job.setvariable('mpsengine',@commandline.option('engine'))
+ else
+ job.setvariable('mpsengine','standard')
+ end
+
+ end
+
+ def cleantexfilename(filename)
+ filename.gsub(/([\$\_\#])/) do "\\$1" end.gsub(/([\~])/) do "\\string$1" end
+ end
+
+end
+
+# we will make this pluggable, i.e. load plugins from base/tex that
+# extend the class and may even add switches
+#
+# commandline.load_plugins('base/tex')
+#
+# maybe it's too slow so for a while keep the --pdf* in here
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('make', 'make formats')
+commandline.registeraction('check', 'check versions')
+commandline.registeraction('process', 'process file')
+commandline.registeraction('mptex', 'process mp file')
+commandline.registeraction('mpxtex', 'process mpx file')
+commandline.registeraction('mpgraphic', 'process mp file to stand-alone graphics')
+commandline.registeraction('mpstatic', 'process mp/ctx file to stand-alone graphics')
+
+commandline.registeraction('listing', 'list of file content')
+commandline.registeraction('figures', 'generate overview of figures')
+commandline.registeraction('modules', 'generate module documentation')
+commandline.registeraction('pdfarrange', 'impose pages (booklets)')
+commandline.registeraction('pdfselect', 'select pages from file(s)')
+commandline.registeraction('pdfcopy', 'copy pages from file(s)')
+commandline.registeraction('pdftrim', 'trim pages from file(s)')
+commandline.registeraction('pdfcombine', 'combine multiple pages')
+commandline.registeraction('pdfsplit', 'split file in pages')
+
+# compatibility switch
+
+class Commands
+
+ include CommandBase
+
+ alias pdfarrange :arrangeoutput
+ alias pdfselect :selectoutput
+ alias pdfcopy :copyoutput
+ alias pdftrim :trimoutput
+ alias pdfcombine :combineoutput
+
+end
+
+# so far for compatibility, will move to tex
+
+extrastringvars = [
+ 'pages', 'background', 'backspace', 'topspace', 'boxtype', 'tempdir','bannerheight',
+ 'printformat', 'method', 'scale', 'selection',
+ 'combination', 'textwidth', 'addempty', 'logfile',
+ 'startline', 'endline', 'startcolumn', 'endcolumn', 'scale'
+]
+
+extrabooleanvars = [
+ 'centerpage', 'noduplex', 'color', 'pretty',
+ 'fullscreen', 'screensaver', 'markings'
+]
+
+if job = TEX.new(logger) then
+
+ job.setextrastringvars(extrastringvars)
+ job.setextrabooleanvars(extrabooleanvars)
+
+ job.booleanvars.each do |k|
+ commandline.registerflag(k)
+ end
+ job.stringvars.each do |k|
+ commandline.registervalue(k,'')
+ end
+ job.standardvars.each do |k|
+ commandline.registervalue(k,'standard')
+ end
+ job.knownvars.each do |k|
+ commandline.registervalue(k,'')
+ end
+
+end
+
+class Commands
+
+ alias saved_help help
+
+ def wrap_help(title, vars)
+ report("")
+ report(title)
+ report("")
+ r, n = '', 0
+ vars.sort.each do |s|
+ if n == 5 then
+ report(r)
+ r, n = '', 1
+ else
+ n += 1
+ end
+ r << ' ' + s.to_s
+ end
+ report(r) unless r.empty?
+ end
+
+ def help
+ saved_help
+ if @commandline.option('all') then
+ if job = TEX.new(logger) then
+ wrap_help("boolean switches:", job.allbooleanvars)
+ wrap_help("string switches:", job.allstringvars)
+ end
+ else
+ report('')
+ report('--help --all shows all switches')
+ end
+ end
+
+end
+
+# todo: register flags -> first one true
+
+commandline.registerflag('pdf')
+commandline.registerflag('pdftex')
+commandline.registerflag('pdfetex')
+
+commandline.registerflag('dvipdfmx')
+commandline.registerflag('dvipdfm')
+commandline.registerflag('dpx')
+commandline.registerflag('dpm')
+
+commandline.registerflag('dvips')
+commandline.registerflag('ps')
+
+commandline.registerflag('xetex')
+commandline.registerflag('xtx')
+commandline.registerflag('xdv')
+
+commandline.registerflag('aleph')
+
+commandline.registerflag('petex')
+
+commandline.registerflag('all')
+commandline.registerflag('fast')
+commandline.registerflag('sort')
+
+# generic
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registerflag('verbose')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).execute(commandline.action || 'main') # or just execute()
diff --git a/Master/texmf-dist/scripts/context/ruby/texmfstart.rb b/Master/texmf-dist/scripts/context/ruby/texmfstart.rb
new file mode 100644
index 00000000000..6e508eeb9a5
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/texmfstart.rb
@@ -0,0 +1,1271 @@
+#!/usr/bin/env ruby
+#encoding: ASCII-8BIT
+
+# We have removed the fast, server and client variants and no longer
+# provide the distributed 'serve trees' option. After all, we're now
+# using luatex.
+
+# program : texmfstart
+# copyright : PRAGMA Advanced Document Engineering
+# version : 1.9.0 - 2003/2006
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# info : j.hagen@xs4all.nl
+# www : www.pragma-pod.com / www.pragma-ade.com
+
+# no special requirements, i.e. no exa modules/classes used
+
+# texmfstart [switches] filename [optional arguments]
+#
+# ruby2exe texmfstart --help -> avoids stub test
+#
+# Of couse I can make this into a nice class, which i'll undoubtely will
+# do when I feel the need. In that case it will be part of a bigger game.
+
+# --locate => provides location
+# --exec => exec instead of system
+# --iftouched=a,b => only if timestamp a<>b
+# --ifchanged=a,b => only if checksum changed
+#
+# file: path: bin:
+
+# texmfstart --exec bin:scite *.tex
+
+# we don't depend on other libs
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require "rbconfig"
+require "fileutils"
+
+require "digest/md5"
+
+# kpse_merge_start
+
+class File
+ def File::makedirs(*x)
+ FileUtils.makedirs(x)
+ end
+end
+
+class String
+
+ def split_path
+ if self =~ /\;/o || self =~ /^[a-z]\:/io then
+ self.split(";")
+ else
+ self.split(":")
+ end
+ end
+
+end
+
+class Array
+
+ def join_path
+ self.join(File::PATH_SEPARATOR)
+ end
+
+end
+
+class File
+
+ def File.locate_file(path,name)
+ begin
+ files = Dir.entries(path)
+ if files.include?(name) then
+ fullname = File.join(path,name)
+ return fullname if FileTest.file?(fullname)
+ end
+ files.each do |p|
+ fullname = File.join(path,p)
+ if p != '.' and p != '..' and FileTest.directory?(fullname) and result = locate_file(fullname,name) then
+ return result
+ end
+ end
+ rescue
+ # bad path
+ end
+ return nil
+ end
+
+ def File.glob_file(pattern)
+ return Dir.glob(pattern).first
+ end
+
+end
+
+# kpse_merge_file: 't:/ruby/base/kpsedirect.rb'
+
+class KpseDirect
+
+ attr_accessor :progname, :format, :engine
+
+ def initialize
+ @progname, @format, @engine = '', '', ''
+ end
+
+ def expand_path(str)
+ clean_name(`kpsewhich -expand-path=#{str}`.chomp)
+ end
+
+ def expand_var(str)
+ clean_name(`kpsewhich -expand-var=#{str}`.chomp)
+ end
+
+ def find_file(str)
+ clean_name(`kpsewhich #{_progname_} #{_format_} #{str}`.chomp)
+ end
+
+ def _progname_
+ if @progname.empty? then '' else "-progname=#{@progname}" end
+ end
+ def _format_
+ if @format.empty? then '' else "-format=\"#{@format}\"" end
+ end
+
+ private
+
+ def clean_name(str)
+ str.gsub(/\\/,'/')
+ end
+
+end
+
+# kpse_merge_stop
+
+$mswindows = RbConfig::CONFIG['host_os'] =~ /mswin/
+$separator = File::PATH_SEPARATOR
+$version = "2.1.0"
+$ownpath = File.dirname($0)
+
+if $mswindows then
+ require "win32ole"
+ require "Win32API"
+end
+
+# exit if defined?(REQUIRE2LIB)
+
+$stdout.sync = true
+$stderr.sync = true
+
+$applications = Hash.new
+$suffixinputs = Hash.new
+$predefined = Hash.new
+$runners = Hash.new
+
+$suffixinputs['pl'] = 'PERLINPUTS'
+$suffixinputs['rb'] = 'RUBYINPUTS'
+$suffixinputs['py'] = 'PYTHONINPUTS'
+$suffixinputs['jar'] = 'JAVAINPUTS'
+$suffixinputs['pdf'] = 'PDFINPUTS'
+
+$predefined['texexec'] = 'texexec.rb'
+$predefined['texutil'] = 'texutil.rb'
+$predefined['texfont'] = 'texfont.pl'
+$predefined['texshow'] = 'texshow.pl'
+
+$predefined['makempy'] = 'makempy.pl'
+$predefined['mptopdf'] = 'mptopdf.pl'
+$predefined['pstopdf'] = 'pstopdf.rb'
+
+$predefined['examplex'] = 'examplex.rb'
+$predefined['concheck'] = 'concheck.rb'
+
+$predefined['runtools'] = 'runtools.rb'
+$predefined['textools'] = 'textools.rb'
+$predefined['tmftools'] = 'tmftools.rb'
+$predefined['ctxtools'] = 'ctxtools.rb'
+$predefined['rlxtools'] = 'rlxtools.rb'
+$predefined['pdftools'] = 'pdftools.rb'
+$predefined['mpstools'] = 'mpstools.rb'
+# $predefined['exatools'] = 'exatools.rb'
+$predefined['xmltools'] = 'xmltools.rb'
+# $predefined['mtxtools'] = 'mtxtools.rb'
+
+$predefined['newpstopdf'] = 'pstopdf.rb'
+$predefined['newtexexec'] = 'texexec.rb'
+$predefined['pdftrimwhite'] = 'pdftrimwhite.pl'
+
+$makelist = [
+ # context
+ 'texexec',
+ 'texutil',
+ 'texfont',
+ # mp/ps
+ 'pstopdf',
+ 'mptopdf',
+ 'makempy',
+ # misc
+ 'ctxtools',
+ 'pdftools',
+ 'xmltools',
+ 'textools',
+ 'mpstools',
+ 'tmftools',
+ 'exatools',
+ 'runtools',
+ 'rlxtools',
+ 'pdftrimwhite',
+ 'texfind',
+ 'texshow'
+ #
+ # no 'mtxtools',
+ # no, 'texmfstart'
+]
+
+$scriptlist = 'rb|pl|py|jar'
+$documentlist = 'pdf|ps|eps|htm|html'
+
+$editor = ENV['TEXMFSTART_EDITOR'] || ENV['EDITOR'] || ENV['editor'] || 'scite'
+
+$crossover = true # to other tex tools, else only local
+$kpse = nil
+
+def set_applications(page=1)
+
+ $applications['unknown'] = ''
+ $applications['ruby'] = $applications['rb'] = 'ruby'
+ $applications['perl'] = $applications['pl'] = 'perl'
+ $applications['python'] = $applications['py'] = 'python'
+ $applications['java'] = $applications['jar'] = 'java'
+
+ if $mswindows then
+ $applications['pdf'] = ['',"pdfopen --page #{page} --file",'acroread']
+ $applications['html'] = ['','netscape','mozilla','opera','iexplore']
+ $applications['ps'] = ['','gview32','gv','gswin32','gs']
+ else
+ $applications['pdf'] = ["pdfopen --page #{page} --file",'acroread']
+ $applications['html'] = ['netscape','mozilla','opera']
+ $applications['ps'] = ['gview','gv','gs']
+ end
+
+ $applications['htm'] = $applications['html']
+ $applications['eps'] = $applications['ps']
+
+end
+
+set_applications()
+
+def check_kpse
+ if $kpse then
+ # already done
+ else
+ $kpse = KpseDirect.new
+ end
+end
+
+if $mswindows then
+
+ GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', ['P','P','N'], 'N')
+ GetLongPathName = Win32API.new('kernel32', 'GetLongPathName', ['P','P','N'], 'N')
+
+ def dowith_pathname (filename,filemethod)
+ filename = filename.gsub(/\\/o,'/') # no gsub! because filename can be frozen
+ case filename
+ when /\;/o then
+ # could be a path spec
+ return filename
+ when /\s+/o then
+ # danger lurking
+ buffer = ' ' * 260
+ length = filemethod.call(filename,buffer,buffer.size)
+ if length>0 then
+ return buffer.slice(0..length-1)
+ else
+ # when the path or file does not exist, nothing is returned
+ # so we try to handle the path separately from the basename
+ basename = File.basename(filename)
+ pathname = File.dirname(filename)
+ length = filemethod.call(pathname,buffer,260)
+ if length>0 then
+ return buffer.slice(0..length-1) + '/' + basename
+ else
+ return filename
+ end
+ end
+ else
+ # no danger
+ return filename
+ end
+ end
+
+ def longpathname (filename)
+ dowith_pathname(filename,GetLongPathName)
+ end
+
+ def shortpathname (filename)
+ dowith_pathname(filename,GetShortPathName)
+ end
+
+else
+
+ def longpathname (filename)
+ filename
+ end
+
+ def shortpathname (filename)
+ filename
+ end
+
+end
+
+class File
+
+ @@update_eps = 1
+
+ def File.needsupdate(oldname,newname)
+ begin
+ oldtime = File.stat(oldname).mtime.to_i
+ newtime = File.stat(newname).mtime.to_i
+ if newtime >= oldtime then
+ return false
+ elsif oldtime-newtime < @@update_eps then
+ return false
+ else
+ return true
+ end
+ rescue
+ return true
+ end
+ end
+
+ def File.syncmtimes(oldname,newname)
+ return
+ begin
+ if $mswindows then
+ # does not work (yet) / gives future timestamp
+ # t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
+ # File.utime(0,t,oldname,newname)
+ else
+ t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
+ File.utime(0,t,oldname,newname)
+ end
+ rescue
+ end
+ end
+
+ def File.timestamp(name)
+ begin
+ "#{File.stat(name).mtime}"
+ rescue
+ return 'unknown'
+ end
+ end
+
+end
+
+def hashed (arr=[])
+ arg = if arr.class == String then arr.split(' ') else arr.dup end
+ hsh = Hash.new
+ if arg.length > 0
+ hsh['arguments'] = ''
+ done = false
+ arg.each do |s|
+ if done then
+ if s =~ /\s/ then
+ kvl = s.split('=')
+ if kvl[1] and kvl[1] !~ /^[\"\']/ then
+ hsh['arguments'] += ' ' + kvl[0] + "=" + '"' + kvl[1] + '"'
+ elsif s =~ /\s/ then
+ hsh['arguments'] += ' "' + s + '"'
+ else
+ hsh['arguments'] += ' ' + s
+ end
+ else
+ hsh['arguments'] += ' ' + s
+ end
+ else
+ kvl = s.split('=')
+ if kvl[0].sub!(/^\-+/,'') then
+ hsh[kvl[0]] = if kvl.length > 1 then kvl[1] else true end
+ else
+ hsh['file'] = s
+ done = true
+ end
+ end
+ end
+ end
+ return hsh
+end
+
+
+def launch(filename)
+ if $browser && $mswindows then
+ filename = filename.gsub(/\.[\/\\]/) do
+ Dir.getwd + '/'
+ end
+ report("launching #{filename}")
+ ie = WIN32OLE.new("InternetExplorer.Application")
+ ie.visible = true
+ ie.navigate(filename)
+ return true
+ else
+ return false
+ end
+end
+
+# env|environment
+# rel|relative
+# loc|locate|kpse|path|file
+
+def quoted(str)
+ if str =~ /^\"/ then
+ return str
+ elsif str =~ / / then
+ return "\"#{str}\""
+ else
+ return str
+ end
+end
+
+def expanded(arg) # no "other text files", too restricted
+ arg.gsub(/(env|environment)\:([a-zA-Z\-\_\.0-9]+)/o) do
+ method, original, resolved = $1, $2, ''
+ if resolved = ENV[original] then
+ report("environment variable #{original} expands to #{resolved}") unless $report
+ quoted(resolved)
+ else
+ report("environment variable #{original} cannot be resolved") unless $report
+ quoted(original)
+ end
+ end . gsub(/(rel|relative)\:([a-zA-Z\-\_\.0-9]+)/o) do
+ method, original, resolved = $1, $2, ''
+ ['.','..','../..'].each do |r|
+ if FileTest.file?(File.join(r,original)) then
+ resolved = File.join(r,original)
+ break
+ end
+ end
+ if resolved.empty? then
+ quoted(original)
+ else
+ quoted(resolved)
+ end
+ end . gsub(/(kpse|loc|locate|file|path)\:([a-zA-Z\-\_\.0-9]+)/o) do
+ method, original, resolved = $1, $2, ''
+ if $program && ! $program.empty? then
+ # pstrings = ["-progname=#{$program}"]
+ pstrings = [$program]
+ else
+ # pstrings = ['','-progname=context']
+ pstrings = ['','context']
+ end
+ # auto suffix with texinputs as fall back
+ if ENV["_CTX_K_V_#{original}_"] then
+ resolved = ENV["_CTX_K_V_#{original}_"]
+ report("environment provides #{original} as #{resolved}") unless $report
+ quoted(resolved)
+ else
+ check_kpse
+ pstrings.each do |pstr|
+ if resolved.empty? then
+ # command = "kpsewhich #{pstr} #{original}"
+ # report("running #{command}")
+ report("locating '#{original}' in program space '#{pstr}'")
+ begin
+ # resolved = `#{command}`.chomp
+ $kpse.progname = pstr
+ $kpse.format = ''
+ resolved = $kpse.find_file(original).gsub(/\\/,'/')
+ rescue
+ resolved = ''
+ end
+ end
+ # elsewhere in the tree
+ if resolved.empty? then
+ # command = "kpsewhich #{pstr} -format=\"other text files\" #{original}"
+ # report("running #{command}")
+ report("locating '#{original}' in program space '#{pstr}' using format 'other text files'")
+ begin
+ # resolved = `#{command}`.chomp
+ $kpse.progname = pstr
+ $kpse.format = 'other text files'
+ resolved = $kpse.find_file(original).gsub(/\\/,'/')
+ rescue
+ resolved = ''
+ end
+ end
+ end
+ if resolved.empty? then
+ original = File.dirname(original) if method =~ /path/
+ report("#{original} is not resolved") unless $report
+ ENV["_CTX_K_V_#{original}_"] = original if $crossover
+ quoted(original)
+ else
+ resolved = File.dirname(resolved) if method =~ /path/
+ report("#{original} is resolved to #{resolved}") unless $report
+ ENV["_CTX_K_V_#{original}_"] = resolved if $crossover
+ quoted(resolved)
+ end
+ end
+ end
+end
+
+def changeddir?(path)
+ if path.empty? then
+ return true
+ else
+ oldpath = File.expand_path(path)
+ begin
+ Dir.chdir(path) if not path.empty?
+ rescue
+ report("unable to change to directory: #{path}")
+ else
+ report("changed to directory: #{path}")
+ end
+ newpath = File.expand_path(Dir.getwd)
+ return oldpath == newpath
+ end
+end
+
+def runcommand(command)
+ if $locate then
+ command = command.split(' ').collect do |c|
+ if c =~ /\//o then
+ begin
+ cc = File.expand_path(c)
+ c = cc if FileTest.file?(cc)
+ rescue
+ end
+ end
+ c
+ end . join(' ')
+ print command # to stdout and no newline
+ elsif $execute then
+ report("using 'exec' instead of 'system' call: #{command}")
+ exec(command) if changeddir?($path)
+ else
+ report("using 'system' call: #{command}")
+ system(command) if changeddir?($path)
+ end
+end
+
+def join_command(args)
+ args[0] = $runners[args[0]] || args[0]
+ [args].join(' ')
+end
+
+def runoneof(application,fullname,browserpermitted)
+ if browserpermitted && launch(fullname) then
+ return true
+ else
+ fullname = quoted(fullname) # added because MM ran into problems
+ report("starting #{$filename}") unless $report
+ output("\n") if $report && $verbose
+ applications = $applications[application.downcase]
+ if ! applications then
+ output("problems with determining application type")
+ return true
+ elsif applications.class == Array then
+ if $report then
+ output(join_command([fullname,expanded($arguments)]))
+ return true
+ else
+ applications.each do |a|
+ return true if runcommand(join_command([a,fullname,expanded($arguments)]))
+ end
+ end
+ elsif applications.empty? then
+ if $report then
+ output(join_command([fullname,expanded($arguments)]))
+ return true
+ else
+ return runcommand(join_command([fullname,expanded($arguments)]))
+ end
+ else
+ if $report then
+ output(join_command([applications,fullname,expanded($arguments)]))
+ return true
+ else
+ return runcommand(join_command([applications,fullname,expanded($arguments)]))
+ end
+ end
+ return false
+ end
+end
+
+def report(str)
+ $stdout.puts(str) if $verbose
+end
+
+def output(str)
+ $stdout.puts(str)
+end
+
+def usage
+ print "version : #{$version} - 2003/2006 - www.pragma-ade.com\n"
+ print("\n")
+ print("usage : texmfstart [switches] filename [optional arguments]\n")
+ print("\n")
+ print("switches : --verbose --report --browser --direct --execute --locate --iftouched --ifchanged\n")
+ print(" --program --file --page --arguments --batch --edit --report --clear\n")
+ print(" --make --lmake --wmake --path --stubpath --indirect --before --after\n")
+ print(" --tree --autotree --environment --showenv\n")
+ print("\n")
+ print("example : texmfstart pstopdf.rb cow.eps\n")
+ print(" texmfstart --locate examplex.rb\n")
+ print(" texmfstart --execute examplex.rb\n")
+ print(" texmfstart --browser examplap.pdf\n")
+ print(" texmfstart showcase.pdf\n")
+ print(" texmfstart --page=2 --file=showcase.pdf\n")
+ print(" texmfstart --program=yourtex yourscript.rb arg-1 arg-2\n")
+ print(" texmfstart --direct xsltproc kpse:somefile.xsl somefile.xml\n")
+ print(" texmfstart --direct ruby rel:wn-cleanup-1.rb oldfile.xml newfile.xml\n")
+ print(" texmfstart bin:xsltproc env:somepreset path:somefile.xsl somefile.xml\n")
+ print(" texmfstart --iftouched=normal,lowres downsample.rb normal lowres\n")
+ print(" texmfstart --ifchanged=somefile.dat --direct processit somefile.dat\n")
+ print(" texmfstart bin:scite kpse:texmf.cnf\n")
+ print(" texmfstart --exec bin:scite *.tex\n")
+ print(" texmfstart --edit texmf.cnf\n")
+ print(" texmfstart --edit kpse:texmf.cnf\n")
+ print(" texmfstart --serve\n")
+ print("\n")
+ print(" texmfstart --stubpath=/usr/local/bin [--make --remove] --verbose all\n")
+ print(" texmfstart --stubpath=auto [--make --remove] all\n")
+ print("\n")
+ check_kpse
+end
+
+# somehow registration does not work out (at least not under windows)
+# the . is also not accepted by unix as seperator
+
+def tag(name)
+ if $crossover then "_CTX_K_S_#{name}_" else "TEXMFSTART.#{name}" end
+end
+
+def registered?(filename)
+ return ENV[tag(filename)] != nil
+end
+
+def registered(filename)
+ return ENV[tag(filename)] || 'unknown'
+end
+
+def register(filename,fullname)
+ if fullname && ! fullname.empty? then # && FileTest.file?(fullname)
+ ENV[tag(filename)] = fullname
+ report("registering '#{filename}' as '#{fullname}'")
+ return true
+ else
+ return false
+ end
+end
+
+def find(filename,program)
+ begin
+ filename = filename.sub(/script:/o, '') # so we have bin: and script: and nothing
+ if $predefined.key?(filename) then
+ report("expanding '#{filename}' to '#{$predefined[filename]}'")
+ filename = $predefined[filename]
+ end
+ if registered?(filename) then
+ report("already located '#{filename}'")
+ return registered(filename)
+ end
+ # create suffix list
+ if filename =~ /^(.*)\.(.+)$/ then
+ filename = $1
+ suffixlist = [$2]
+ else
+ suffixlist = [$scriptlist.split('|'),$documentlist.split('|')].flatten
+ end
+ # first we honor a given path
+ if filename =~ /[\\\/]/ then
+ report("trying to honor '#{filename}'")
+ suffixlist.each do |suffix|
+ fullname = filename+'.'+suffix
+ if FileTest.file?(fullname) && register(filename,fullname)
+ return shortpathname(fullname)
+ end
+ end
+ end
+ filename.sub!(/^.*[\\\/]/, '')
+ # next we look at the current path and the callerpath
+ pathlist = [ ]
+ progpath = $applications[suffixlist[0]]
+ threadok = registered("THREAD") !~ /unknown/
+ pathlist << ['.','current']
+ pathlist << [$ownpath,'caller'] if $ownpath != '.'
+ pathlist << ["#{$ownpath}/../#{progpath}",'caller'] if progpath
+ pathlist << [registered("THREAD"),'thread'] if threadok
+ pathlist << ["#{registered("THREAD")}/../#{progpath}",'thread'] if progpath && threadok
+ pathlist.each do |p|
+ if p && ! p.empty? && ! (p[0] == 'unknown') then
+ suffixlist.each do |suffix|
+ fname = "#{filename}.#{suffix}"
+ fullname = File.expand_path(File.join(p[0],fname))
+ report("locating '#{fname}' in #{p[1]} path '#{p[0]}'")
+ if FileTest.file?(fullname) && register(filename,fullname) then
+ report("'#{fname}' located in #{p[1]} path")
+ return shortpathname(fullname)
+ end
+ end
+ end
+ end
+ # now we consult environment settings
+ fullname = nil
+ check_kpse
+ $kpse.progname = program
+ suffixlist.each do |suffix|
+ begin
+ break unless $suffixinputs[suffix]
+ environment = ENV[$suffixinputs[suffix]] || ENV[$suffixinputs[suffix]+".#{$program}"]
+ if ! environment || environment.empty? then
+ begin
+ # environment = `kpsewhich -expand-path=\$#{$suffixinputs[suffix]}`.chomp
+ environment = $kpse.expand_path("\$#{$suffixinputs[suffix]}")
+ rescue
+ environment = nil
+ else
+ if environment && ! environment.empty? then
+ report("using kpsewhich variable #{$suffixinputs[suffix]}")
+ end
+ end
+ elsif environment && ! environment.empty? then
+ report("using environment variable #{$suffixinputs[suffix]}")
+ end
+ if environment && ! environment.empty? then
+ environment.split($separator).each do |e|
+ e.strip!
+ e = '.' if e == '\.' # somehow . gets escaped
+ e += '/' unless e =~ /[\\\/]$/
+ fullname = e + filename + '.' + suffix
+ report("testing '#{fullname}'")
+ if FileTest.file?(fullname) then
+ break
+ else
+ fullname = nil
+ end
+ end
+ end
+ rescue
+ report("environment string '#{$suffixinputs[suffix]}' cannot be used to locate '#{filename}'")
+ fullname = nil
+ else
+ return shortpathname(fullname) if register(filename,fullname)
+ end
+ end
+ return shortpathname(fullname) if register(filename,fullname)
+ # then we fall back on kpsewhich
+ suffixlist.each do |suffix|
+ # TDS script scripts location as per 2004
+ if suffix =~ /(#{$scriptlist})/ then
+ begin
+ report("using 'kpsewhich' to locate '#{filename}' in suffix space '#{suffix}' (1)")
+ # fullname = `kpsewhich -progname=#{program} -format=texmfscripts #{filename}.#{suffix}`.chomp
+ $kpse.format = 'texmfscripts'
+ fullname = $kpse.find_file("#{filename}.#{suffix}").gsub(/\\/,'/')
+ rescue
+ report("kpsewhich cannot locate '#{filename}' in suffix space '#{suffix}' (1)")
+ fullname = nil
+ else
+ return shortpathname(fullname) if register(filename,fullname)
+ end
+ end
+ # old TDS location: .../texmf/context/...
+ begin
+ report("using 'kpsewhich' to locate '#{filename}' in suffix space '#{suffix}' (2)")
+ # fullname = `kpsewhich -progname=#{program} -format="other text files" #{filename}.#{suffix}`.chomp
+ $kpse.format = 'other text files'
+ fullname = $kpse.find_file("#{filename}.#{suffix}").gsub(/\\/,'/')
+ rescue
+ report("kpsewhich cannot locate '#{filename}' in suffix space '#{suffix}' (2)")
+ fullname = nil
+ else
+ return shortpathname(fullname) if register(filename,fullname)
+ end
+ end
+ return shortpathname(fullname) if register(filename,fullname)
+ # let's take a look at the path
+ paths = ENV['PATH'].split($separator)
+ suffixlist.each do |s|
+ paths.each do |p|
+ suffixedname = "#{filename}.#{s}"
+ report("checking #{p} for #{filename}")
+ if FileTest.file?(File.join(p,suffixedname)) then
+ fullname = File.join(p,suffixedname)
+ return shortpathname(fullname) if register(filename,fullname)
+ end
+ end
+ end
+ # bad luck, we need to search the tree ourselves
+ if (suffixlist.length == 1) && (suffixlist.first =~ /(#{$documentlist})/) then
+ report("aggressively locating '#{filename}' in document trees")
+ begin
+ # texroot = `kpsewhich -expand-var=$SELFAUTOPARENT`.chomp
+ texroot = $kpse.expand_var("$SELFAUTOPARENT")
+ rescue
+ texroot = ''
+ else
+ texroot.sub!(/[\\\/][^\\\/]*?$/, '')
+ end
+ if not texroot.empty? then
+ sffxlst = suffixlist.join(',')
+ begin
+ report("locating '#{filename}' in document tree '#{texroot}/doc*'")
+ if (result = Dir.glob("#{texroot}/doc*/**/#{filename}.{#{sffxlst}}")) && result && result[0] && FileTest.file?(result[0]) then
+ fullname = result[0]
+ end
+ rescue
+ report("locating '#{filename}.#{suffixlist.join('|')}' in tree '#{texroot}' aborted")
+ end
+ end
+ return shortpathname(fullname) if register(filename,fullname)
+ end
+ report("aggressively locating '#{filename}' in tex trees")
+ begin
+ # textrees = `kpsewhich -expand-var=$TEXMF`.chomp
+ textrees = $kpse.expand_var("$TEXMF")
+ rescue
+ textrees = ''
+ end
+ if not textrees.empty? then
+ textrees.gsub!(/[\{\}\!]/, '')
+ textrees = textrees.split(',')
+ if (suffixlist.length == 1) && (suffixlist.first =~ /(#{$documentlist})/) then
+ speedup = ['doc**','**']
+ else
+ speedup = ['**']
+ end
+ sffxlst = suffixlist.join(',')
+ speedup.each do |speed|
+ textrees.each do |tt|
+ tt.gsub!(/[\\\/]$/, '')
+ if FileTest.directory?(tt) then
+ begin
+ report("locating '#{filename}' in tree '#{tt}/#{speed}/#{filename}.{#{sffxlst}}'")
+ if (result = Dir.glob("#{tt}/#{speed}/#{filename}.{#{sffxlst}}")) && result && result[0] && FileTest.file?(result[0]) then
+ fullname = result[0]
+ break
+ end
+ rescue
+ report("locating '#{filename}' in tree '#{tt}' aborted")
+ next
+ end
+ end
+ end
+ break if fullname && ! fullname.empty?
+ end
+ end
+ if register(filename,fullname) then
+ return shortpathname(fullname)
+ else
+ return ''
+ end
+ rescue
+ error, trace = $!, $@.join("\n")
+ report("fatal error: #{error}\n#{trace}")
+ # report("fatal error")
+ end
+end
+
+def run(fullname)
+ if ! fullname || fullname.empty? then
+ output("the file '#{$filename}' is not found")
+ elsif FileTest.file?(fullname) then
+ begin
+ case fullname
+ when /\.(#{$scriptlist})$/i then
+ return runoneof($1,fullname,false)
+ when /\.(#{$documentlist})$/i then
+ return runoneof($1,fullname,true)
+ else
+ return runoneof('unknown',fullname,false)
+ end
+ rescue
+ report("starting '#{$filename}' in program space '#{$program}' fails (#{$!})")
+ end
+ else
+ report("the file '#{$filename}' in program space '#{$program}' is not accessible")
+ end
+ return false
+end
+
+def direct(fullname)
+ begin
+ return runcommand([fullname.sub(/^(bin|binary)\:/, ''),expanded($arguments)].join(' '))
+ rescue
+ return false
+ end
+end
+
+def edit(filename)
+ begin
+ return runcommand([$editor,expanded(filename),expanded($arguments)].join(' '))
+ rescue
+ return false
+ end
+end
+
+def make(filename,windows=false,linux=false,remove=false)
+ basename = File.basename(filename).gsub(/\.[^.]+?$/, '')
+ if $stubpath == 'auto' then
+ basename = File.dirname($0) + '/' + basename
+ else
+ basename = $stubpath + '/' + basename unless $stubpath.empty?
+ end
+ if filename == 'texmfstart' then
+ program = 'ruby'
+ command = 'kpsewhich --format=texmfscripts --progname=context texmfstart.rb'
+ filename = `#{command}`.chomp.gsub(/\\/, '/')
+ if filename.empty? then
+ report("failure: #{command}")
+ return
+ elsif not remove then
+ if windows then
+ ['bat','cmd','exe'].each do |suffix|
+ if FileTest.file?("#{basename}.#{suffix}") then
+ report("windows stub '#{basename}.#{suffix}' skipped (already present)")
+ return
+ end
+ end
+ elsif linux && FileTest.file?(basename) then
+ report("unix stub '#{basename}' skipped (already present)")
+ return
+ end
+ end
+ else
+ program = nil
+ if filename =~ /[\\\/]/ && filename =~ /\.(#{$scriptlist})$/ then
+ program = $applications[$1]
+ end
+ filename = "\"#{filename}\"" if filename =~ /\s/
+ program = 'texmfstart' if $indirect || ! program || program.empty?
+ end
+ begin
+ callname = $predefined[filename.sub(/\.*?$/,'')] || filename
+ if remove then
+ if windows && (File.delete(basename+'.bat') rescue false) then
+ report("windows stub '#{basename}.bat' removed (calls #{callname})")
+ elsif linux && (File.delete(basename) rescue false) then
+ report("unix stub '#{basename}' removed (calls #{callname})")
+ end
+ else
+ if windows && f = open(basename+'.bat','w') then
+ f.binmode
+ f.write("@echo off\015\012")
+ f.write("#{program} #{callname} %*\015\012")
+ f.close
+ report("windows stub '#{basename}.bat' made (calls #{callname})")
+ elsif linux && f = open(basename,'w') then
+ f.binmode
+ f.write("#!/bin/sh\012")
+ f.write("#{program} #{callname} \"$@\"\012")
+ f.close
+ report("unix stub '#{basename}' made (calls #{callname})")
+ end
+ end
+ rescue
+ report("failed to make stub '#{basename}' #{$!}")
+ return false
+ else
+ return true
+ end
+end
+
+def process(&block)
+ if $iftouched then
+ files = $directives['iftouched'].split(',')
+ oldname, newname = files[0], files[1]
+ if oldname && newname && File.needsupdate(oldname,newname) then
+ report("file #{oldname}: #{File.timestamp(oldname)}")
+ report("file #{newname}: #{File.timestamp(newname)}")
+ report("file is touched, processing started")
+ yield
+ File.syncmtimes(oldname,newname)
+ else
+ report("file #{oldname} is untouched")
+ end
+ elsif $ifchanged then
+ filename = $directives['ifchanged']
+ checkname = filename + ".md5"
+ oldchecksum, newchecksum = "old", "new"
+ begin
+ newchecksum = Digest::MD5.hexdigest(IO.read(filename)).upcase
+ rescue
+ newchecksum = "new"
+ else
+ begin
+ oldchecksum = IO.read(checkname).chomp
+ rescue
+ oldchecksum = "old"
+ end
+ end
+ if $verbose then
+ report("old checksum #{filename}: #{oldchecksum}")
+ report("new checksum #{filename}: #{newchecksum}")
+ end
+ if oldchecksum != newchecksum then
+ report("file is changed, processing started")
+ begin
+ File.open(checkname,'w') do |f|
+ f << newchecksum
+ end
+ rescue
+ end
+ yield
+ else
+ report("file #{filename} is unchanged")
+ end
+ else
+ yield
+ end
+end
+
+def checkenvironment(tree)
+ report('')
+ ENV['TMP'] = ENV['TMP'] || ENV['TEMP'] || ENV['TMPDIR'] || ENV['HOME']
+ case RUBY_PLATFORM
+ when /(mswin|bccwin|mingw|cygwin)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-mswin'
+ when /(linux)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-linux'
+ when /(darwin|rhapsody|nextstep)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-macosx'
+ # when /(netbsd|unix)/i then # todo
+ else # todo
+ end
+ ENV['TEXOS'] = "#{ENV['TEXOS'].sub(/^[\\\/]*/, '').sub(/[\\\/]*$/, '')}"
+ ENV['TEXPATH'] = tree.sub(/\/+$/,'') # + '/'
+ ENV['TEXMFOS'] = "#{ENV['TEXPATH']}/#{ENV['TEXOS']}"
+ report('')
+ report("preset : TEXPATH => #{ENV['TEXPATH']}")
+ report("preset : TEXOS => #{ENV['TEXOS']}")
+ report("preset : TEXMFOS => #{ENV['TEXMFOS']}")
+ report("preset : TMP => #{ENV['TMP']}")
+ report('')
+end
+
+def loadfile(filename)
+ begin
+ IO.readlines(filename).each do |line|
+ case line.chomp
+ when /^[\#\%]/ then
+ # comment
+ when /^(.*?)\s*(\>|\=|\<)\s*(.*)\s*$/ then
+ # = assign | > prepend | < append
+ key, how, value = $1, $2, $3
+ begin
+ # $SAFE = 0
+ value.gsub!(/\%(.*?)\%/) do
+ ENV[$1] || ''
+ end
+ # value.gsub!(/\;/,$separator) if key =~ /PATH/i then
+ case how
+ when '=', '<<' then ENV[key] = value
+ when '?', '??' then ENV[key] = ENV[key] || value
+ when '<', '+=' then ENV[key] = (ENV[key] || '') + $separator + value
+ when '>', '=+' then ENV[key] = value + $separator + (ENV[key] ||'')
+ end
+ rescue
+ report("user set failed : #{key} (#{$!})")
+ else
+ report("user set : #{key} => #{ENV[key]}")
+ end
+ end
+ end
+ rescue
+ report("error in reading file '#{filename}'")
+ end
+end
+
+def loadtree(tree)
+ begin
+ unless tree.empty? then
+ if File.directory?(tree) then
+ setuptex = File.join(tree,'setuptex.tmf')
+ else
+ setuptex = tree.dup
+ end
+ if FileTest.file?(setuptex) then
+ report("tex tree definition: #{setuptex}")
+ checkenvironment(File.dirname(setuptex))
+ loadfile(setuptex)
+ else
+ report("no setup file '#{setuptex}'")
+ end
+ end
+ rescue
+ # maybe tree is empty or boolean (no arg given)
+ end
+end
+
+def loadenvironment(environment)
+ begin
+ unless environment.empty? then
+ filename = if $path.empty? then environment else File.expand_path(File.join($path,environment)) end
+ if FileTest.file?(filename) then
+ report("environment : #{environment}")
+ loadfile(filename)
+ else
+ report("no environment file '#{environment}'")
+ end
+ end
+ rescue
+ report("problem while loading '#{environment}'")
+ end
+end
+
+def show_environment
+ if $showenv then
+ keys = ENV.keys.sort
+ size = 0
+ keys.each do |k|
+ size = k.size if k.size > size
+ end
+ report('')
+ keys.each do |k|
+ report("#{k.rjust(size)} => #{ENV[k]}")
+ end
+ report('')
+ end
+end
+
+def execute(arguments) # br global
+
+ arguments = arguments.split(/\s+/) if arguments.class == String
+ $directives = hashed(arguments)
+
+ $help = $directives['help'] || false
+ $batch = $directives['batch'] || false
+ $filename = $directives['file'] || ''
+ $program = $directives['program'] || 'context'
+ $direct = $directives['direct'] || false
+ $edit = $directives['edit'] || false
+ $page = $directives['page'] || 1
+ $browser = $directives['browser'] || false
+ $report = $directives['report'] || false
+ $verbose = $directives['verbose'] || false
+ $arguments = $directives['arguments'] || ''
+ $execute = $directives['execute'] || $directives['exec'] || false
+ $locate = $directives['locate'] || false
+
+ $autotree = if $directives['autotree'] then (ENV['TEXMFSTART_TREE'] || ENV['TEXMFSTARTTREE'] || '') else '' end
+
+ $path = $directives['path'] || ''
+ $tree = $directives['tree'] || $autotree || ''
+ $environment = $directives['environment'] || ''
+
+ $make = $directives['make'] || false
+ $remove = $directives['remove'] || $directives['delete'] || false
+ $unix = $directives['unix'] || false
+ $windows = $directives['windows'] || $directives['mswin'] || false
+ $stubpath = $directives['stubpath'] || ''
+ $indirect = $directives['indirect'] || false
+
+ $before = $directives['before'] || ''
+ $after = $directives['after'] || ''
+
+ $iftouched = $directives['iftouched'] || false
+ $ifchanged = $directives['ifchanged'] || false
+
+ $openoffice = $directives['oo'] || false
+
+ $crossover = false if $directives['clear']
+
+ $showenv = $directives['showenv'] || false
+ $verbose = true if $showenv
+
+ $serve = $directives['serve'] || false
+
+ $verbose = true if (ENV['_CTX_VERBOSE_'] =~ /(y|yes|t|true|on)/io) && ! $locate && ! $report
+
+ set_applications($page)
+
+ # private:
+
+ $selfmerge = $directives['selfmerge'] || false
+ $selfcleanup = $directives['selfclean'] || $directives['selfcleanup'] || false
+
+ ENV['_CTX_VERBOSE_'] = 'yes' if $verbose
+
+ if $openoffice then
+ if ENV['OOPATH'] then
+ if FileTest.directory?(ENV['OOPATH']) then
+ report("using open office python")
+ if $mswindows then
+ $applications['python'] = $applications['py'] = "\"#{File.join(ENV['OOPATH'],'program','python.bat')}\""
+ else
+ $applications['python'] = $applications['py'] = File.join(ENV['OOPATH'],'python')
+ end
+ report("python path #{$applications['python']}")
+ else
+ report("environment variable 'OOPATH' does not exist")
+ end
+ else
+ report("environment variable 'OOPATH' is not set")
+ end
+ end
+
+ if $selfmerge then
+ output("ruby libraries are cleaned up") if SelfMerge::cleanup
+ output("ruby libraries are merged") if SelfMerge::merge
+ return true
+ elsif $selfcleanup then
+ output("ruby libraries are cleaned up") if SelfMerge::cleanup
+ return true
+ elsif $help || ! $filename || $filename.empty? then
+ usage
+ loadtree($tree)
+ loadenvironment($environment)
+ show_environment()
+ return true
+ elsif $batch && $filename && ! $filename.empty? then
+ # todo, take commands from file and avoid multiple starts and checks
+ return false
+ else
+ report("texmfstart version #{$version}")
+ loadtree($tree)
+ loadenvironment($environment)
+ show_environment()
+ if $make || $remove then
+ if $filename == 'all' then
+ makelist = $makelist
+ else
+ makelist = [$filename]
+ end
+ makelist.each do |filename|
+ if $windows then
+ make(filename,true,false,$remove)
+ elsif $unix then
+ make(filename,false,true,$remove)
+ else
+ make(filename,$mswindows,!$mswindows,$remove)
+ end
+ end
+ return true # guess
+ elsif $browser && $filename =~ /^http\:\/\// then
+ return launch($filename)
+ else
+ begin
+ process do
+ if $direct || $filename =~ /^bin\:/ then
+ return direct($filename)
+ elsif $edit && ! $editor.empty? then
+ return edit($filename)
+ else # script: or no prefix
+ command = find(shortpathname($filename),$program)
+ if command then
+ register("THREAD",File.dirname(File.expand_path(command)))
+ return run(command)
+ else
+ report('unable to locate program')
+ return false
+ end
+ end
+ end
+ rescue
+ report('fatal error in starting process')
+ return false
+ end
+ end
+ end
+
+end
+
+if execute(ARGV) then
+ report("\nexecution was successful") if $verbose
+ exit(0)
+else
+ report("\nexecution failed") if $verbose
+ exit(1)
+end
diff --git a/Master/texmf-dist/scripts/context/ruby/textools.rb b/Master/texmf-dist/scripts/context/ruby/textools.rb
new file mode 100644
index 00000000000..a5858c5caf5
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/textools.rb
@@ -0,0 +1,1033 @@
+#!/usr/bin/env ruby
+
+# program : textools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# This script will harbor some handy manipulations on tex
+# related files.
+
+banner = ['TeXTools', 'version 1.3.1', '2002/2006', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'base/switch'
+require 'base/logger'
+
+require 'fileutils'
+# require 'ftools'
+
+# Remark
+#
+# The fixtexmftrees feature does not realy belong in textools, but
+# since it looks like no measures will be taken to make texlive (and
+# tetex) downward compatible with respect to fonts installed by
+# users, we provide this fixer. This option also moves script files
+# to their new location (only for context) in the TDS. Beware: when
+# locating scripts, the --format switch in kpsewhich should now use
+# 'texmfscripts' instead of 'other text files' (texmfstart is already
+# aware of this). Files will only be moved when --force is given. Let
+# me know if more fixes need to be made.
+
+class Commands
+
+ include CommandBase
+
+ def tpmmake
+ if filename = @commandline.argument('first') then
+ filename = File.join('tpm',filename) unless filename =~ /^tpm[\/\\]/
+ filename += '.tpm' unless filename =~ /\.tpm$/
+ if FileTest.file?(filename) then
+ data = IO.read(filename) rescue ''
+ data, fn, n = calculate_tpm(data,"TPM:RunFiles")
+ data, fm, m = calculate_tpm(data,"TPM:DocFiles")
+ data = replace_tpm(data,"TPM:Size",n+m)
+ report("total size #{n+m}")
+ begin
+ File.open(filename, 'w') do |f|
+ f << data
+ end
+ rescue
+ report("unable to save '#{filename}'")
+ else
+ report("file '#{filename}' is updated")
+ filename = File.basename(filename).sub(/\..*$/,'')
+ zipname = sprintf("%s-%04i.%02i.%02i%s",filename,Time.now.year,Time.now.month,Time.now.day,'.zip')
+ File.delete(zipname) rescue true
+ report("zipping file '#{zipname}'")
+ system("zip -r -9 -q #{zipname} #{[fn,fm].flatten.join(' ')}")
+ end
+ else
+ report("no file '#{filename}'")
+ end
+ end
+ end
+
+ def calculate_tpm(data, tag='')
+ size, ok = 0, Array.new
+ data.gsub!(/<#{tag}.*>(.*?)<\/#{tag}>/m) do
+ content = $1
+ files = content.split(/\s+/)
+ files.each do |file|
+ unless file =~ /^\s*$/ then
+ if FileTest.file?(file) then
+ report("found file #{file}")
+ size += FileTest.size(file) rescue 0
+ ok << file
+ else
+ report("missing file #{file}")
+ end
+ end
+ end
+ "<#{tag} size=\"#{size}\">#{content}</#{tag}>"
+ end
+ [data, ok, size]
+ end
+
+ def replace_tpm(data, tag='', txt='')
+ data.gsub(/(<#{tag}.*>)(.*?)(<\/#{tag}>)/m) do
+ $1 + txt.to_s + $3
+ end
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ def hidemapnames
+ report('hiding FontNames in map files')
+ xidemapnames(true)
+ end
+
+ def videmapnames
+ report('unhiding FontNames in map files')
+ xidemapnames(false)
+ end
+
+ def removemapnames
+
+ report('removing FontNames from map files')
+
+ if files = findfiles('map') then
+ report
+ files.sort.each do |fn|
+ gn = fn # + '.nonames'
+ hn = fn + '.original'
+ begin
+ if FileTest.file?(fn) && ! FileTest.file?(hn) then
+ if File.rename(fn,hn) then
+ if (fh = File.open(hn,'r')) && (gh = File.open(gn,'w')) then
+ report("processing #{fn}")
+ while str = fh.gets do
+ str.sub!(/^([^\%]+?)(\s+)([^\"\<\s]*?)(\s)/) do
+ $1 + $2 + " "*$3.length + $4
+ end
+ gh.puts(str)
+ end
+ fh.close
+ gh.close
+ else
+ report("no permissions to handle #{fn}")
+ end
+ else
+ report("unable to rename #{fn} to #{hn}")
+ end
+ else
+ report("not processing #{fn} due to presence of #{hn}")
+ end
+ rescue
+ report("error in handling #{fn}")
+ end
+ end
+ end
+
+ end
+
+ def restoremapnames
+
+ report('restoring FontNames in map files')
+
+ if files = findfiles('map') then
+ report
+ files.sort.each do |fn|
+ hn = fn + '.original'
+ begin
+ if FileTest.file?(hn) then
+ File.delete(fn) if FileTest.file?(fn)
+ report("#{fn} restored") if File.rename(hn,fn)
+ else
+ report("no original found for #{fn}")
+ end
+ rescue
+ report("error in restoring #{fn}")
+ end
+ end
+ end
+
+ end
+
+ def findfile
+
+ report('locating file in texmf tree')
+
+ # ! not in tree
+ # ? fuzzy
+ # . in tree
+ # > in tree and used
+
+ if filename = @commandline.argument('first') then
+ if filename && ! filename.empty? then
+ report
+ used = kpsefile(filename) || pathfile(filename)
+ if paths = texmfroots then
+ found, prefered = false, false
+ paths.each do |p|
+ if files = texmffiles(p,filename) then
+ found = true
+ files.each do |f|
+ # unreadable: report("#{if f == used then '>' else '.' end} #{f}")
+ if f == used then
+ prefered = true
+ report("> #{f}")
+ else
+ report(". #{f}")
+ end
+ end
+ end
+ end
+ if prefered then
+ report("! #{used}") unless found
+ else
+ report("> #{used}")
+ end
+ elsif used then
+ report("? #{used}")
+ else
+ report('no file found')
+ end
+ else
+ report('no file specified')
+ end
+ else
+ report('no file specified')
+ end
+
+ end
+
+ def unzipfiles
+
+ report('g-unzipping files')
+
+ if files = findfiles('gz') then
+ report
+ files.each do |f|
+ begin
+ system("gunzip -d #{f}")
+ rescue
+ report("unable to unzip file #{f}")
+ else
+ report("file #{f} is unzipped")
+ end
+ end
+ end
+
+ end
+
+ def fixafmfiles
+
+ report('fixing afm files')
+
+ if files = findfiles('afm') then
+ report
+ ok = false
+ files.each do |filename|
+ if filename =~ /\.afm$/io then
+ if f = File.open(filename) then
+ result = ''
+ done = false
+ while str = f.gets do
+ str.chomp!
+ str.strip!
+ if str.empty? then
+ # skip
+ elsif (str.length > 200) && (str =~ /^(comment|notice)\s(.*)\s*$/io) then
+ done = true
+ tag, words, len = $1, $2.split(' '), 0
+ result += tag
+ while words.size > 0 do
+ str = words.shift
+ len += str.length + 1
+ result += ' ' + str
+ if len > (70 - tag.length) then
+ result += "\n"
+ result += tag if words.size > 0
+ len = 0
+ end
+ end
+ result += "\n" if len>0
+ else
+ result += str + "\n"
+ end
+ end
+ f.close
+ if done then
+ ok = true
+ begin
+ if File.rename(filename,filename+'.original') then
+ if FileTest.file?(filename) then
+ report("something to fix in #{filename} but error in renaming (3)")
+ elsif f = File.open(filename,'w') then
+ f.puts(result)
+ f.close
+ report('file', filename, 'has been fixed')
+ else
+ report("something to fix in #{filename} but error in opening (4)")
+ File.rename(filename+'.original',filename) # gamble
+ end
+ else
+ report("something to fix in #{filename} but error in renaming (2)")
+ end
+ rescue
+ report("something to fix in #{filename} but error in renaming (1)")
+ end
+ else
+ report("nothing to fix in #{filename}")
+ end
+ else
+ report("error in opening #{filename}")
+ end
+ end
+ end
+ report('no files match the pattern') unless ok
+ end
+
+ end
+
+ def mactodos
+
+ report('fixing mac newlines')
+
+ if files = findfiles('tex') then
+ report
+ files.each do |filename|
+ begin
+ report("converting file #{filename}")
+ tmpfilename = filename + '.tmp'
+ if f = File.open(filename) then
+ if g = File.open(tmpfilename, 'w')
+ while str = f.gets do
+ g.puts(str.gsub(/\r/,"\n"))
+ end
+ if f.close && g.close && FileTest.file?(tmpfilename) then
+ File.delete(filename)
+ File.rename(tmpfilename,filename)
+ end
+ else
+ report("unable to open temporary file #{tmpfilename}")
+ end
+ else
+ report("unable to open #{filename}")
+ end
+ rescue
+ report("problems with fixing #{filename}")
+ end
+ end
+ end
+
+ end
+
+ def fixtexmftrees
+
+ if paths = @commandline.argument('first') then
+ paths = [paths] if ! paths.empty?
+ end
+ paths = texmfroots if paths.empty?
+
+ if paths then
+
+ moved = 0
+ force = @commandline.option('force')
+
+ report
+ report("checking TDS 2003 => TDS 2004 : map files")
+ # report
+
+ # move [map,enc] files from /texmf/[dvips,pdftex,dvipdfmx] -> /texmf/fonts/[*]
+
+ ['map','enc'].each do |suffix|
+ paths.each do |path|
+ ['dvips','pdftex','dvipdfmx'].each do |program|
+ report
+ report("checking #{suffix} files for #{program} on #{path}")
+ report
+ moved += movefiles("#{path}/#{program}","#{path}/fonts/#{suffix}/#{program}",suffix) do
+ # nothing
+ end
+ end
+ end
+ end
+
+ report
+ report("checking TDS 2003 => TDS 2004 : scripts")
+ # report
+
+ # move [rb,pl,py] files from /texmf/someplace -> /texmf/scripts/someplace
+
+ ['rb','pl','py'].each do |suffix|
+ paths.each do |path|
+ ['context'].each do |program|
+ report
+ report("checking #{suffix} files for #{program} on #{path}")
+ report
+ moved += movefiles("#{path}/#{program}","#{path}/scripts/#{program}",suffix) do |f|
+ f.gsub!(/\/(perl|ruby|python)tk\//o) do
+ "/#{$1}/"
+ end
+ end
+ end
+ end
+ end
+
+ begin
+ if moved>0 then
+ report
+ if force then
+ system('mktexlsr')
+ report
+ report("#{moved} files moved")
+ else
+ report("#{moved} files will be moved")
+ end
+ else
+ report('no files need to be moved')
+ end
+ rescue
+ report('you need to run mktexlsr')
+ end
+
+ end
+
+ end
+
+ def replacefile
+
+ report('replace file')
+
+ if newname = @commandline.argument('first') then
+ if newname && ! newname.empty? then
+ report
+ report("replacing #{newname}")
+ report
+ oldname = kpsefile(File.basename(newname))
+ force = @commandline.option('force')
+ if oldname && ! oldname.empty? then
+ oldname = File.expand_path(oldname)
+ newname = File.expand_path(newname)
+ report("old: #{oldname}")
+ report("new: #{newname}")
+ report
+ if newname == oldname then
+ report('unable to replace itself')
+ elsif force then
+ begin
+ File.copy(newname,oldname)
+ rescue
+ report('error in replacing the old file')
+ end
+ else
+ report('the old file will be replaced (use --force)')
+ end
+ else
+ report('nothing to replace')
+ end
+ else
+ report('no file specified')
+ end
+ else
+ report('no file specified')
+ end
+
+ end
+
+ private # general
+
+ def texmfroots
+ begin
+ paths = `kpsewhich -expand-path=\$TEXMF`.chomp
+ rescue
+ else
+ return paths.split(/#{File::PATH_SEPARATOR}/) if paths && ! paths.empty?
+ end
+ return nil
+ end
+
+ def texmffiles(root, filename)
+ begin
+ files = Dir.glob("#{root}/**/#{filename}")
+ rescue
+ else
+ return files if files && files.length>0
+ end
+ return nil
+ end
+
+ def pathfile(filename)
+ used = nil
+ begin
+ if ! filename || filename.empty? then
+ return nil
+ else
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+ if FileTest.file?(File.join(path,filename)) then
+ used = File.join(path,filename)
+ break
+ end
+ end
+ end
+ rescue
+ used = nil
+ else
+ used = nil if used && used.empty?
+ end
+ return used
+ end
+
+ def kpsefile(filename)
+ used = nil
+ begin
+ if ! filename || filename.empty? then
+ return nil
+ else
+ used = `kpsewhich #{filename}`.chomp
+ end
+ if used && used.empty? then
+ used = `kpsewhich -progname=context #{filename}`.chomp
+ end
+ if used && used.empty? then
+ used = `kpsewhich -format=texmfscripts #{filename}`.chomp
+ end
+ if used && used.empty? then
+ used = `kpsewhich -progname=context -format=texmfscripts #{filename}`.chomp
+ end
+ if used && used.empty? then
+ used = `kpsewhich -format="other text files" #{filename}`.chomp
+ end
+ if used && used.empty? then
+ used = `kpsewhich -progname=context -format="other text files" #{filename}`.chomp
+ end
+ rescue
+ used = nil
+ else
+ used = nil if used && used.empty?
+ end
+ return used
+ end
+
+ def downcasefilenames
+
+ report('downcase filenames')
+
+ force = @commandline.option('force')
+
+ # if @commandline.option('recurse') then
+ # files = Dir.glob('**/*')
+ # else
+ # files = Dir.glob('*')
+ # end
+ # if files && files.length>0 then
+
+ if files = findfiles() then
+ files.each do |oldname|
+ if FileTest.file?(oldname) then
+ newname = oldname.downcase
+ if oldname != newname then
+ if force then
+ begin
+ File.rename(oldname,newname)
+ rescue
+ report("#{oldname} == #{oldname}\n")
+ else
+ report("#{oldname} => #{newname}\n")
+ end
+ else
+ report("(#{oldname} => #{newname})\n")
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def stripformfeeds
+
+ report('strip formfeeds')
+
+ force = @commandline.option('force')
+
+ if files = findfiles() then
+ files.each do |filename|
+ if FileTest.file?(filename) then
+ begin
+ data = IO.readlines(filename).join('')
+ rescue
+ else
+ if data.gsub!(/\n*\f\n*/io,"\n\n") then
+ if force then
+ if f = open(filename,'w') then
+ report("#{filename} is stripped\n")
+ f.puts(data)
+ f.close
+ else
+ report("#{filename} cannot be stripped\n")
+ end
+ else
+ report("#{filename} will be stripped\n")
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ public
+
+ def showfont
+
+ file = @commandline.argument('first')
+
+ if file.empty? then
+ report('provide filename')
+ else
+ file.sub!(/\.afm$/,'')
+ begin
+ report("analyzing afm file #{file}.afm")
+ file = `kpsewhich #{file}.afm`.chomp
+ rescue
+ report('unable to run kpsewhich')
+ return
+ end
+
+ names = Array.new
+
+ if FileTest.file?(file) then
+ File.new(file).each do |line|
+ if line.match(/^C\s*([\-\d]+)\s*\;.*?\s*N\s*(.+?)\s*\;/o) then
+ names.push($2)
+ end
+ end
+ ranges = names.size
+ report("number of glyphs: #{ranges}")
+ ranges = ranges/256 + 1
+ report("number of subsets: #{ranges}")
+ file = File.basename(file).sub(/\.afm$/,'')
+ tex = File.open("textools.tex",'w')
+ map = File.open("textools.map",'w')
+ tex.puts("\\starttext\n")
+ tex.puts("\\loadmapfile[textools.map]\n")
+ for i in 1..ranges do
+ rfile = "#{file}-range-#{i}"
+ report("generating enc file #{rfile}.enc")
+ flushencoding("#{rfile}", (i-1)*256, i*256-1, names)
+ # catch console output
+ report("generating tfm file #{rfile}.tfm")
+ mapline = `afm2tfm #{file}.afm -T #{rfile}.enc #{rfile}.tfm`
+ # more robust replacement
+ mapline = "#{rfile} <#{rfile}.enc <#{file}.pfb"
+ # final entry in map file
+ mapline = "#{mapline} <#{file}.pfb"
+ map.puts("#{mapline}\n")
+ tex.puts("\\showfont[#{rfile}][unknown]\n")
+ end
+ tex.puts("\\stoptext\n")
+ report("generating map file textools.map")
+ report("generating tex file textools.tex")
+ map.close
+ tex.close
+ else
+ report("invalid file #{file}")
+ end
+ end
+
+ end
+
+ @@knownchars = Hash.new
+
+ @@knownchars['ae'] = 'aeligature' ; @@knownchars['oe'] = 'oeligature'
+ @@knownchars['AE'] = 'AEligature' ; @@knownchars['OE'] = 'OEligature'
+
+ @@knownchars['acute' ] = 'textacute'
+ @@knownchars['breve' ] = 'textbreve'
+ @@knownchars['caron' ] = 'textcaron'
+ @@knownchars['cedilla' ] = 'textcedilla'
+ @@knownchars['circumflex' ] = 'textcircumflex'
+ @@knownchars['diaeresis' ] = 'textdiaeresis'
+ @@knownchars['dotaccent' ] = 'textdotaccent'
+ @@knownchars['grave' ] = 'textgrave'
+ @@knownchars['hungarumlaut'] = 'texthungarumlaut'
+ @@knownchars['macron' ] = 'textmacron'
+ @@knownchars['ogonek' ] = 'textogonek'
+ @@knownchars['ring' ] = 'textring'
+ @@knownchars['tilde' ] = 'texttilde'
+
+ @@knownchars['cent' ] = 'textcent'
+ @@knownchars['currency'] = 'textcurrency'
+ @@knownchars['euro' ] = 'texteuro'
+ @@knownchars['florin' ] = 'textflorin'
+ @@knownchars['sterling'] = 'textsterling'
+ @@knownchars['yen' ] = 'textyen'
+
+ @@knownchars['brokenbar'] = 'textbrokenbar'
+ @@knownchars['bullet' ] = 'textbullet'
+ @@knownchars['dag' ] = 'textdag'
+ @@knownchars['ddag' ] = 'textddag'
+ @@knownchars['degree' ] = 'textdegree'
+ @@knownchars['div' ] = 'textdiv'
+ @@knownchars['ellipsis' ] = 'textellipsis'
+ @@knownchars['fraction' ] = 'textfraction'
+ @@knownchars['lognot' ] = 'textlognot'
+ @@knownchars['minus' ] = 'textminus'
+ @@knownchars['mu' ] = 'textmu'
+ @@knownchars['multiply' ] = 'textmultiply'
+ @@knownchars['pm' ] = 'textpm'
+
+ def encmake
+ afmfile = @commandline.argument('first')
+ encoding = @commandline.argument('second') || 'dummy'
+ if afmfile && FileTest.file?(afmfile) then
+ chars = Array.new
+ IO.readlines(afmfile).each do |line|
+ if line =~ /C\s+(\d+).*?N\s+([a-zA-Z\-\.]+?)\s*;/ then
+ chars[$1.to_i] = $2
+ end
+ end
+ if f = File.open(encoding+'.enc','w') then
+ f << "% Encoding file, generated by textools.rb from #{afmfile}\n"
+ f << "\n"
+ f << "/#{encoding.gsub(/[^a-zA-Z]/,'')}encoding [\n"
+ 256.times do |i|
+ f << " /#{chars[i] || '.notdef'} % #{i}\n"
+ end
+ f << "] def\n"
+ f.close
+ end
+ if f = File.open('enco-'+encoding+'.tex','w') then
+ f << "% ConTeXt file, generated by textools.rb from #{afmfile}\n"
+ f << "\n"
+ f << "\\startencoding[#{encoding}]\n\n"
+ 256.times do |i|
+ if str = chars[i] then
+ tmp = str.gsub(/dieresis/,'diaeresis')
+ if chr = @@knownchars[tmp] then
+ f << " \\definecharacter #{chr} #{i}\n"
+ elsif tmp.length > 5 then
+ f << " \\definecharacter #{tmp} #{i}\n"
+ end
+ end
+ end
+ f << "\n\\stopencoding\n"
+ f << "\n\\endinput\n"
+ f.close
+ end
+ end
+ end
+
+ private
+
+ def flushencoding (file, from, to, names)
+ n = 0
+ out = File.open("#{file}.enc",'w')
+ out.puts("/#{file.gsub(/\-/,'')} [\n")
+ for i in from..to do
+ if names[i] then
+ n += 1
+ out.puts("/#{names[i]}\n")
+ else
+ out.puts("/.notdef\n")
+ end
+ end
+ out.puts("] def\n")
+ out.close
+ return n
+ end
+
+ private # specific
+
+ def movefiles(from_path,to_path,suffix,&block)
+ obsolete = 'obsolete'
+ force = @commandline.option('force')
+ moved = 0
+ if files = texmffiles(from_path, "*.#{suffix}") then
+ files.each do |filename|
+ newfilename = filename.sub(/^#{from_path}/, to_path)
+ yield(newfilename) if block
+ if FileTest.file?(newfilename) then
+ begin
+ File.rename(filename,filename+'.obsolete') if force
+ rescue
+ report("#{filename} cannot be made obsolete") if force
+ else
+ if force then
+ report("#{filename} is made obsolete")
+ else
+ report("#{filename} will become obsolete")
+ end
+ end
+ else
+ begin
+ File.makedirs(File.dirname(newfilename)) if force
+ rescue
+ end
+ begin
+ File.copy(filename,newfilename) if force
+ rescue
+ report("#{filename} cannot be copied to #{newfilename}")
+ else
+ begin
+ File.delete(filename) if force
+ rescue
+ report("#{filename} cannot be deleted") if force
+ else
+ if force then
+ report("#{filename} is moved to #{newfilename}")
+ moved += 1
+ else
+ report("#{filename} will be moved to #{newfilename}")
+ end
+ end
+ end
+ end
+ end
+ else
+ report('no matches found')
+ end
+ return moved
+ end
+
+ def xidemapnames(hide)
+
+ filter = /^([^\%]+?)(\s+)([^\"\<\s]*?)(\s)/
+ banner = '% textools:nn '
+
+ if files = findfiles('map') then
+ report
+ files.sort.each do |fn|
+ if fn.has_suffix?('map') then
+ begin
+ lines = IO.read(fn)
+ report("processing #{fn}")
+ if f = File.open(fn,'w') then
+ skip = false
+ if hide then
+ lines.each do |str|
+ if skip then
+ skip = false
+ elsif str =~ /#{banner}/ then
+ skip = true
+ elsif str =~ filter then
+ f.puts(banner+str)
+ str.sub!(filter) do
+ $1 + $2 + " "*$3.length + $4
+ end
+ end
+ f.puts(str)
+ end
+ else
+ lines.each do |str|
+ if skip then
+ skip = false
+ elsif str.sub!(/#{banner}/, '') then
+ f.puts(str)
+ skip = true
+ else
+ f.puts(str)
+ end
+ end
+ end
+ f.close
+ end
+ rescue
+ report("error in handling #{fn}")
+ end
+ end
+ end
+ end
+
+ end
+
+ public
+
+ def updatetree
+
+ nocheck = @commandline.option('nocheck')
+ merge = @commandline.option('merge')
+ delete = @commandline.option('delete')
+ force = @commandline.option('force')
+ root = @commandline.argument('first').gsub(/\\/,'/')
+ path = @commandline.argument('second').gsub(/\\/,'/')
+
+ if FileTest.directory?(root) then
+ report("scanning #{root}")
+ rootfiles = Dir.glob("#{root}/**/*")
+ else
+ report("provide source root")
+ return
+ end
+ if rootfiles.size > 0 then
+ report("#{rootfiles.size} files")
+ else
+ report("no files")
+ return
+ end
+ rootfiles.collect! do |rf|
+ rf.gsub(/\\/o, '/').sub(/#{root}\//o, '')
+ end
+ rootfiles = rootfiles.delete_if do |rf|
+ FileTest.directory?(File.join(root,rf))
+ end
+
+ if FileTest.directory?(path) then
+ report("scanning #{path}")
+ pathfiles = Dir.glob("#{path}/**/*")
+ else
+ report("provide destination root")
+ return
+ end
+ if pathfiles.size > 0 then
+ report("#{pathfiles.size} files")
+ else
+ report("no files")
+ return
+ end
+ pathfiles.collect! do |pf|
+ pf.gsub(/\\/o, '/').sub(/#{path}\//o, '')
+ end
+ pathfiles = pathfiles.delete_if do |pf|
+ FileTest.directory?(File.join(path,pf))
+ end
+
+ root = File.expand_path(root)
+ path = File.expand_path(path)
+
+ donepaths = Hash.new
+ copiedfiles = Hash.new
+
+ # update existing files, assume similar paths
+
+ report("")
+ pathfiles.each do |f| # destination
+ p = File.join(path,f)
+ if rootfiles.include?(f) then
+ r = File.join(root,f)
+ if p != r then
+ if nocheck or File.mtime(p) < File.mtime(r) then
+ copiedfiles[File.expand_path(p)] = true
+ report("updating '#{r}' to '#{p}'")
+ begin
+ begin File.makedirs(File.dirname(p)) if force ; rescue ; end
+ File.copy(r,p) if force
+ rescue
+ report("updating failed")
+ end
+ else
+ report("not updating '#{r}'")
+ end
+ end
+ end
+ end
+
+ # merging non existing files
+
+ report("")
+ rootfiles.each do |f|
+ donepaths[File.dirname(f)] = true
+ r = File.join(root,f)
+ if not pathfiles.include?(f) then
+ p = File.join(path,f)
+ if p != r then
+ if merge then
+ copiedfiles[File.expand_path(p)] = true
+ report("merging '#{r}' to '#{p}'")
+ begin
+ begin File.makedirs(File.dirname(p)) if force ; rescue ; end
+ File.copy(r,p) if force
+ rescue
+ report("merging failed")
+ end
+ else
+ report("not merging '#{r}'")
+ end
+ end
+ end
+ end
+
+ # deleting obsolete files
+
+ report("")
+ donepaths.keys.sort.each do |d|
+ pathfiles = Dir.glob("#{path}/#{d}/**/*")
+ pathfiles.each do |p|
+# puts(File.dirname(p))
+# if donepaths[File.dirname(p)] then
+ r = File.join(root,d,File.basename(p))
+ if FileTest.file?(p) and not FileTest.file?(r) and not copiedfiles.key?(File.expand_path(p)) then
+ if delete then
+ report("deleting '#{p}'")
+ begin
+ File.delete(p) if force
+ rescue
+ report("deleting failed")
+ end
+ else
+ report("not deleting '#{p}'")
+ end
+ end
+ end
+# end
+ end
+
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('removemapnames' , '[pattern] [--recurse]')
+commandline.registeraction('restoremapnames' , '[pattern] [--recurse]')
+commandline.registeraction('hidemapnames' , '[pattern] [--recurse]')
+commandline.registeraction('videmapnames' , '[pattern] [--recurse]')
+commandline.registeraction('findfile' , 'filename [--recurse]')
+commandline.registeraction('unzipfiles' , '[pattern] [--recurse]')
+commandline.registeraction('fixafmfiles' , '[pattern] [--recurse]')
+commandline.registeraction('mactodos' , '[pattern] [--recurse]')
+commandline.registeraction('fixtexmftrees' , '[texmfroot] [--force]')
+commandline.registeraction('replacefile' , 'filename [--force]')
+commandline.registeraction('updatetree' , 'fromroot toroot [--force --nocheck --merge --delete]')
+commandline.registeraction('downcasefilenames', '[--recurse] [--force]') # not yet documented
+commandline.registeraction('stripformfeeds' , '[--recurse] [--force]') # not yet documented
+commandline.registeraction('showfont' , 'filename')
+commandline.registeraction('encmake' , 'afmfile encodingname')
+
+commandline.registeraction('tpmmake' , 'tpm file (run in texmf root)')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registerflag('recurse')
+commandline.registerflag('force')
+commandline.registerflag('merge')
+commandline.registerflag('delete')
+commandline.registerflag('nocheck')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/Master/texmf-dist/scripts/context/ruby/texutil.rb b/Master/texmf-dist/scripts/context/ruby/texutil.rb
new file mode 100644
index 00000000000..ee0fc1e5e40
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/texutil.rb
@@ -0,0 +1,93 @@
+banner = ['TeXUtil ', 'version 9.1.0', '1997-2005', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'base/switch'
+require 'base/logger'
+require 'base/file'
+require 'base/texutil'
+
+class Commands
+
+ include CommandBase
+
+ def references
+ filename = @commandline.argument('first')
+ if not filename.empty? and FileTest.file?(File.suffixed(filename,'tuo')) then
+ if tu = TeXUtil::Converter.new(logger) and tu.loaded(filename) then
+ tu.saved if tu.processed
+ end
+ end
+ end
+
+ def main
+ if @commandline.arguments.length>0 then
+ references
+ else
+ help
+ end
+ end
+
+ def purgefiles
+ system("texmfstart ctxtools --purge #{@commandline.arguments.join(' ')}")
+ end
+
+ def purgeallfiles
+ system("texmfstart ctxtools --purge --all #{@commandline.arguments.join(' ')}")
+ end
+
+ def documentation
+ system("texmfstart ctxtools --document #{@commandline.arguments.join(' ')}")
+ end
+
+ def analyzefile
+ system("texmfstart pdftools --analyze #{@commandline.arguments.join(' ')}")
+ end
+
+ def filterpages # obsolete
+ system("texmfstart ctxtools --purge #{@commandline.arguments.join(' ')}")
+ end
+
+ def figures
+ report("this code is not yet converted from perl to ruby")
+ end
+
+ def logfile
+ report("this code is not yet converted from perl to ruby")
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+# main feature
+
+commandline.registeraction('references', 'convert tui file into tuo file')
+
+# todo features
+
+commandline.registeraction('figures', 'generate figure dimensions file')
+commandline.registeraction('logfile', 'filter essential log messages')
+
+# backward compatibility features
+
+commandline.registeraction('purgefiles', 'remove most temporary files')
+commandline.registeraction('purgeallfiles', 'remove all temporary files')
+commandline.registeraction('documentation', 'generate documentation file from source')
+commandline.registeraction('analyzefile', 'analyze pdf file')
+
+# old feature, not needed any longer due to extension of pdftex
+
+commandline.registeraction('filterpages')
+
+# generic features
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registerflag('verbose')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'main')
diff --git a/Master/texmf-dist/scripts/context/ruby/tmftools.rb b/Master/texmf-dist/scripts/context/ruby/tmftools.rb
new file mode 100644
index 00000000000..626ef1f4a33
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/tmftools.rb
@@ -0,0 +1,165 @@
+#!/usr/bin/env ruby
+
+# program : tmftools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2005
+# author : Hans Hagen
+#
+# project : ConTeXt
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# The script based alternative is not slower than the kpse one.
+# Loading is a bit faster when the log file is used.
+
+# todo: create database
+
+# tmftools [some of the kpsewhich switches]
+
+# tmftools --analyze
+# tmftools --analyze > kpsewhat.log
+# tmftools --analyze --strict > kpsewhat.log
+# tmftools --analyze --delete --force "texmf-local/fonts/.*/somename"
+# tmftools --serve
+
+# the real thing
+
+banner = ['TMFTools', 'version 1.1.0 (experimental, no help yet)', '2005/2006', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'base/switch'
+require 'base/logger'
+
+class Commands
+
+ include CommandBase
+
+ def init_kpse
+ # require 'base/kpseremote'
+ # if KpseRemote::available? then
+ if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then
+ require 'base/kpseremote'
+ k = KpseRemote.new
+ else
+ k = nil
+ end
+ if k && k.okay? then
+ k.progname = @commandline.option('progname')
+ k.engine = @commandline.option('engine')
+ k.format = @commandline.option('format')
+ else
+ require 'base/kpsefast'
+ k = KpseFast.new
+ k.rootpath = @commandline.option('rootpath')
+ k.treepath = @commandline.option('treepath')
+ k.progname = @commandline.option('progname')
+ k.engine = @commandline.option('engine')
+ k.format = @commandline.option('format')
+ k.diskcache = @commandline.option('diskcache')
+ k.renewcache = @commandline.option('renewcache')
+ k.load_cnf
+ k.expand_variables
+ k.load_lsr
+ end
+ return k
+ end
+
+ def serve
+ if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then
+ require 'base/kpseremote'
+ begin
+ KpseRemote::start_server
+ rescue
+ end
+ end
+ end
+
+ def reload
+ begin
+ init_kpse.load
+ rescue
+ end
+ end
+
+ def main
+ if option = @commandline.option('expand-braces') and not option.empty? then
+ puts init_kpse.expand_braces(option)
+ elsif option = @commandline.option('expand-path') and not option.empty? then
+ puts init_kpse.expand_path(option)
+ elsif option = @commandline.option('expand-var') and not option.empty? then
+ if option == '*' then
+ init_kpse.list_expansions()
+ else
+ puts init_kpse.expand_var(option)
+ end
+ elsif option = @commandline.option('show-path') and not option.empty? then
+ puts init_kpse.show_path(option)
+ elsif option = @commandline.option('var-value') and not option.empty? then
+ if option == '*' then
+ init_kpse.list_variables()
+ else
+ puts init_kpse.expand_var(option)
+ end
+ elsif @commandline.arguments.size > 0 then
+ kpse = init_kpse
+ @commandline.arguments.each do |option|
+ puts kpse.find_file(option)
+ end
+ else
+ help
+ end
+ end
+
+ def analyze
+ pattern = @commandline.argument('first')
+ strict = @commandline.option('strict')
+ sort = @commandline.option('sort')
+ delete = @commandline.option('delete') and @commandline.option('force')
+ init_kpse.analyze_files(pattern, strict, sort, delete)
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+# kpsewhich compatible options
+
+commandline.registervalue('expand-braces','')
+commandline.registervalue('expand-path','')
+commandline.registervalue('expand-var','')
+commandline.registervalue('show-path','')
+commandline.registervalue('var-value','')
+
+commandline.registervalue('engine','')
+commandline.registervalue('progname','')
+commandline.registervalue('format','')
+
+# additional goodies
+
+commandline.registervalue('rootpath','')
+commandline.registervalue('treepath','')
+commandline.registervalue('sort','')
+
+commandline.registerflag('diskcache')
+commandline.registerflag('renewcache')
+commandline.registerflag('strict')
+commandline.registerflag('delete')
+commandline.registerflag('force')
+
+commandline.registeraction('analyze', "[--strict --sort --rootpath --treepath]\n[--delete [--force]] [pattern]")
+
+# general purpose options
+
+commandline.registerflag('verbose')
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registeraction('reload', 'reload file database')
+commandline.registeraction('serve', 'act as kpse server')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'main')
diff --git a/Master/texmf-dist/scripts/context/ruby/xmltools.rb b/Master/texmf-dist/scripts/context/ruby/xmltools.rb
new file mode 100644
index 00000000000..c28df200dd6
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/xmltools.rb
@@ -0,0 +1,656 @@
+#!/usr/bin/env ruby
+
+# program : xmltools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# todo : use kpse lib
+
+# This script will harbor some handy manipulations on tex
+# related files.
+
+banner = ['XMLTools', 'version 1.2.2', '2002/2007', 'PRAGMA ADE/POD']
+
+$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq!
+
+require 'base/switch'
+require 'base/logger'
+
+class String
+
+ def astring(n=10)
+ gsub(/(\d+)/o) do $1.to_s.rjust(n) end.gsub(/ /o, '0')
+ end
+
+ def xstring
+ if self =~ /\'/o then
+ "\"#{self.gsub(/\"/, '&quot;')}\""
+ else
+ "\'#{self}\'"
+ end
+ end
+
+end
+
+class Array
+
+ def asort(n=10)
+ sort {|x,y| x.astring(n) <=> y.astring(n)}
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ def dir
+
+ @xmlns = "xmlns='http://www.pragma-ade.com/rlg/xmldir.rng'"
+
+ pattern = @commandline.option('pattern')
+ recurse = @commandline.option('recurse')
+ stripname = @commandline.option('stripname')
+ longname = @commandline.option('longname')
+ url = @commandline.option('url')
+ outputfile = @commandline.option('output')
+ root = @commandline.option('root')
+
+ def generate(output,files,url,root,longname)
+
+ class << output
+ def xputs(str,n=0)
+ puts("#{' '*n}#{str}")
+ end
+ end
+
+ dirname = ''
+ output.xputs("<?xml version='1.0'?>\n\n")
+ if ! root || root.empty? then
+ rootatt = @xmlns
+ else
+ rootatt = " #{@xmlns} root='#{root}'"
+ end
+ rootatt += " timestamp='#{Time.now}'"
+ if url.empty? then
+ output.xputs("<files #{rootatt}>\n")
+ else
+ output.xputs("<files url='#{url}'#{rootatt}>\n")
+ end
+ files.each do |f|
+ bn, dn = File.basename(f), File.dirname(f)
+ if dirname != dn then
+ output.xputs("</directory>\n", 2) if dirname != ''
+ output.xputs("<directory name='#{dn}'>\n", 2)
+ dirname = dn
+ end
+ if longname && dn != '.' then
+ output.xputs("<file name='#{dn}/#{bn}'>\n", 4)
+ else
+ output.xputs("<file name='#{bn}'>\n", 4)
+ end
+ output.xputs("<base>#{bn.sub(/\..*$/,'')}</base>\n", 6)
+ if File.stat(f).file? then
+ bt = bn.sub(/^.*\./,'')
+ if bt != bn then
+ output.xputs("<type>#{bt}</type>\n", 6)
+ end
+ output.xputs("<size>#{File.stat(f).size}</size>\n", 6)
+ permissions = ''
+ permissions << 'r' if File.readable?(f)
+ permissions << 'w' if File.writable?(f)
+ permissions << 'x' if File.executable?(f)
+ output.xputs("<permissions>#{permissions}</permissions>\n", 6) unless permissions.empty?
+ end
+ output.xputs("<date>#{File.stat(f).mtime.strftime("%Y-%m-%d %H:%M")}</date>\n", 6)
+ output.xputs("</file>\n", 4)
+ end
+ output.xputs("</directory>\n", 2) if dirname != ''
+ output.xputs("</files>\n")
+
+ end
+
+ if pattern.empty? then
+ report('provide --pattern=')
+ return
+ end
+
+ unless outputfile.empty? then
+ begin
+ output = File.open(outputfile,'w')
+ rescue
+ report("unable to open #{outputfile}")
+ return
+ end
+ else
+ report('provide --output')
+ return
+ end
+
+ if stripname && pattern.class == String && ! pattern.empty? then
+ pattern = File.dirname(pattern)
+ end
+
+ pattern = '*' if pattern.empty?
+
+ unless root.empty? then
+ unless FileTest.directory?(root) then
+ report("unknown root #{root}")
+ return
+ end
+ begin
+ Dir.chdir(root)
+ rescue
+ report("unable to change to root #{root}")
+ return
+ end
+ end
+
+ generate(output, globbed(pattern, recurse), url, root, longname)
+
+ output.close if output
+
+ end
+
+ alias ls :dir
+
+ def mmlpages
+
+ file = @commandline.argument('first')
+ eps = @commandline.option('eps')
+ jpg = @commandline.option('jpg')
+ png = @commandline.option('png')
+ style = @commandline.option('style')
+ modes = @commandline.option('modes')
+
+ file = file.sub(/\.xml/io, '')
+ long = "#{file}-mmlpages"
+ if FileTest.file?(file+'.xml') then
+ style = "--arg=\"style=#{style}\"" unless style.empty?
+ modes = "--mode=#{modes}" unless modes.empty?
+ if system("texmfstart texexec --batch --pdf --once --result=#{long} --use=mmlpag #{style} #{modes} #{file}.xml") then
+ if eps then
+ if f = open("#{file}-mmlpages.txt") then
+ while line = f.gets do
+ data = Hash.new
+ if fields = line.split then
+ fields.each do |fld|
+ key, value = fld.split('=')
+ data[key] = value if key && value
+ end
+ if data.key?('p') then
+ page = data['p']
+ name = "#{long}-#{page.to_i-1}"
+ if eps then
+ report("generating eps file #{name}")
+ if system("pdftops -eps -f #{page} -l #{page} #{long}.pdf #{name}.eps") then
+ if data.key?('d') then
+ if epsfile = IO.read("#{name}.eps") then
+ epsfile.sub!(/^(\%\%BoundingBox:.*?$)/i) do
+ newline = $1 + "\n%%Baseline: #{data['d']}\n"
+ if data.key?('w') && data.key?('h') then
+ newline += "%%PositionWidth: #{data['w']}\n"
+ newline += "%%PositionHeight: #{data['h']}\n"
+ newline += "%%PositionDepth: #{data['d']}"
+ end
+ newline
+ end
+ if g = File.open("#{name}.eps",'wb') then
+ g.write(epsfile)
+ g.close
+ end
+ end
+ end
+ else
+ report("error in generating eps from #{name}")
+ end
+ end
+ end
+ end
+ end
+ f.close
+ else
+ report("missing data log file #{file}")
+ end
+ end
+ if png then
+ report("generating png file for #{long}")
+ system("imagemagick #{long}.pdf #{long}-%d.png")
+ end
+ if jpg then
+ report("generating jpg files for #{long}")
+ system("imagemagick #{long}.pdf #{long}-%d.jpg")
+ end
+ else
+ report("error in processing file #{file}")
+ end
+ system("texmfstart ctxtools --purge")
+ else
+ report("error in processing file #{file}")
+ end
+
+ end
+
+ def analyze
+
+ file = @commandline.argument('first')
+ result = @commandline.option('output')
+ utf = @commandline.option('utf')
+ process = @commandline.option('process')
+
+ if FileTest.file?(file) then
+ if data = IO.read(file) then
+ if data =~ /<?xml.*?version\=/ then
+ report("xml file #{file} loaded")
+ elements = Hash.new
+ attributes = Hash.new
+ entities = Hash.new
+ chars = Hash.new
+ unicodes = Hash.new
+ names = Hash.new
+ data.scan(/<([^>\s\/\!\?]+)([^>]*?)>/o) do
+ element, attributelist = $1, $2
+ if elements.key?(element) then
+ elements[element] += 1
+ else
+ elements[element] = 1
+ end
+ attributelist.scan(/\s*([^\=]+)\=([\"\'])(.*?)(\2)/) do
+ key, value = $1, $3
+ attributes[element] = Hash.new unless attributes.key?(element)
+ attributes[element][key] = Hash.new unless attributes[element].key?(key)
+ if attributes[element][key].key?(value) then
+ attributes[element][key][value] += 1
+ else
+ attributes[element][key][value] = 1
+ end
+ end
+ end
+ data.scan(/\&([^\;]+)\;/o) do
+ entity = $1
+ if entities.key?(entity) then
+ entities[entity] += 1
+ else
+ entities[entity] = 1
+ end
+ end
+ if utf then
+ data.scan(/(\w)/u) do
+ chars[$1] = (chars[$1] || 0) + 1
+ end
+ if chars.size > 0 then
+ begin
+ # todo : use kpse lib
+ filename, ownpath, foundpath = 'contextnames.txt', File.dirname($0), ''
+ begin
+ foundpath = File.dirname(`kpsewhich -progname=context -format=\"other text files\" #{filename}`.chomp)
+ rescue
+ foundpath = '.'
+ else
+ foundpath = '.' if foundpath.empty?
+ end
+ [foundpath,ownpath,File.join(ownpath,'../../../context/data')].each do |path|
+ fullname = File.join(path,filename)
+ if FileTest.file?(fullname) then
+ report("loading '#{fullname}'")
+ # rough scan, we assume no valid lines after comments
+ IO.read(fullname).scan(/^([0-9A-F][0-9A-F][0-9A-F][0-9A-F])\s*\;\s*(.*?)\s*\;\s*(.*?)\s*\;\s*(.*?)\s*$/) do
+ names[$1.hex.to_i.to_s] = [$2,$3,$4]
+ end
+ break
+ end
+ end
+ rescue
+ end
+ end
+ end
+ result = file.gsub(/\..*?$/, '') + '.xlg' if result.empty?
+ if f = File.open(result,'w') then
+ report("saving report in #{result}")
+ f.puts "<?xml version='1.0'?>\n"
+ f.puts "<document>\n"
+ if entities.length>0 then
+ total = 0
+ entities.each do |k,v|
+ total += v
+ end
+ f.puts " <entities n=#{total.to_s.xstring}>\n"
+ entities.keys.asort.each do |entity|
+ f.puts " <entity name=#{entity.xstring} n=#{entities[entity].to_s.xstring}/>\n"
+ end
+ f.puts " </entities>\n"
+ end
+ if utf && (chars.size > 0) then
+ total = 0
+ chars.each do |k,v|
+ total += v
+ end
+ f.puts " <characters n=#{total.to_s.xstring}>\n"
+ chars.each do |k,v|
+ if k.length > 1 then
+ begin
+ u = k.unpack('U')
+ unicodes[u] = (unicodes[u] || 0) + v
+ rescue
+ report("invalid utf codes")
+ end
+ end
+ end
+ unicodes.keys.sort.each do |u|
+ ustr = u.to_s
+ if names[ustr] then
+ f.puts " <character number=#{ustr.xstring} pname=#{names[ustr][0].xstring} cname=#{names[ustr][1].xstring} uname=#{names[ustr][2].xstring} n=#{unicodes[u].to_s.xstring}/>\n"
+ else
+ f.puts " <character number=#{ustr.xstring} n=#{unicodes[u].to_s.xstring}/>\n"
+ end
+ end
+ f.puts " </characters>\n"
+ end
+ if elements.length>0 then
+ f.puts " <elements>\n"
+ elements.keys.sort.each do |element|
+ if attributes.key?(element) then
+ f.puts " <element name=#{element.xstring} n=#{elements[element].to_s.xstring}>\n"
+ if attributes.key?(element) then
+ attributes[element].keys.asort.each do |attribute|
+ f.puts " <attribute name=#{attribute.xstring}>\n"
+ if attribute =~ /id$/o then
+ nn = 0
+ attributes[element][attribute].keys.asort.each do |value|
+ nn += attributes[element][attribute][value].to_i
+ end
+ f.puts " <instance value=#{"*".xstring} n=#{nn.to_s.xstring}/>\n"
+ else
+ attributes[element][attribute].keys.asort.each do |value|
+ f.puts " <instance value=#{value.xstring} n=#{attributes[element][attribute][value].to_s.xstring}/>\n"
+ end
+ end
+ f.puts " </attribute>\n"
+ end
+ end
+ f.puts " </element>\n"
+ else
+ f.puts " <element name=#{element.xstring} n=#{elements[element].to_s.xstring}/>\n"
+ end
+ end
+ f.puts " </elements>\n"
+ end
+ f.puts "</document>\n"
+ f.close
+ if process then
+ system("texmfstart texexec --purge --pdf --use=xml-analyze #{result}")
+ end
+ else
+ report("unable to open file '#{result}'")
+ end
+ else
+ report("invalid xml file '#{file}'")
+ end
+ else
+ report("unable to load file '#{file}'")
+ end
+ else
+ report("unknown file '#{file}'")
+ end
+ end
+
+ def filter
+
+ require "rexml/document"
+
+ element = @commandline.option('element')
+ files = @commandline.arguments
+ result = "xmltools.xlg"
+
+ if element.empty? then
+ report("provide element using --element")
+ elsif files.length == 0 then
+ report("provide filename(s)")
+ else
+ begin
+ File.open(result,'w') do |f|
+ f << "<?xml version='1.0'?>\n\n"
+ f << "<xlg:document>\n\n"
+ total = 0
+ files.sort.each do |file|
+ begin
+ report("loading: #{file}")
+ data = REXML::Document.new(IO.read(file))
+ rescue
+ report("error: invalid xml")
+ else
+ found = 0
+ report("filtering: #{element}")
+ REXML::XPath.each(data,"//#{element}") do |table|
+ str = table.to_s
+ if str.length > 0 then
+ total += 1
+ found += 1
+ report("found: #{total} / #{found} / #{str.length} bytes")
+ f << "<xlg:file name='#{file}'>\n\n" unless found > 1
+ f << "<xlg:filtered n='#{total}' m='#{found}'>"
+ f << "#{str.gsub(/^\s*/m,'').gsub(/\s*$/m,'')}"
+ f << "</xlg:filtered>\n\n"
+ end
+ end
+ f << "</xlg:file>\n\n" if found > 0
+ end
+ end
+ f << "</xlg:document>\n"
+ end
+ report("result: #{result}")
+ rescue
+ report("error in opening #{result}")
+ end
+ end
+
+ end
+
+ def enhance
+ oldname = @commandline.argument('first')
+ newname = @commandline.argument('second')
+ verbose = @commandline.option('verbose')
+ # todo: options, maybe a config file
+ if ! newname || newname.empty? then
+ newname = oldname + ".prep"
+ end
+ if FileTest.file?(oldname) then
+ report("") if verbose
+ data = IO.read(oldname)
+ elements = Array.new
+ preamble = ""
+ done = false
+ data.sub!(/^(.*?)\s*(<[a-z])/moi) do
+ preamble = $1
+ $2
+ end
+ # hide elements
+ data.gsub!(/<([^>]*?)>/moi) do
+ elements << $1
+ "<#{elements.length}>"
+ end
+ # abc[-/]def
+ data.gsub!(/([a-z]{3,})([\/\-\(\)]+)([a-z]{3,})/moi) do
+ done = true
+ report("compound: #{$1}#{$2}#{$3}") if verbose
+ "#{$1}<compound token='#{$2}'/>#{$3}"
+ end
+ # (abcd
+ # data.gsub!(/(\()([a-z]{4,})/moi) do
+ # done = true
+ # report("compound: #{$1}#{$2}") if verbose
+ # "<compound token='#{$1}'/>#{$2}"
+ # end
+ # abcd)
+ # data.gsub!(/(\()([a-z]{4,})/moi) do
+ # done = true
+ # report("compound: #{$1}#{$2}") if verbose
+ # "#{$2}<compound token='#{$2}'/>"
+ # end
+ # roll back elements
+ data.gsub!(/<(\d+)>/moi) do
+ "<#{elements.shift}>"
+ end
+ File.open(newname,'wb') do |f|
+ f << preamble
+ f << "\n"
+ f << data
+ end
+ if verbose then
+ if done then
+ report("")
+ report(oldname," converted to ",newname)
+ else
+ report(oldname," copied to ",newname)
+ end
+ end
+ end
+ end
+
+ def cleanup # todo, share loading/saving with previous
+
+ file = @commandline.argument('first')
+ force = @commandline.option('force')
+ verbose = @commandline.option('verbose')
+
+ if FileTest.file?(file) then
+ if data = IO.read(file) then
+ if data =~ /<?xml.*?version\=/ then
+ data = doxmlcleanup(data,verbose)
+ result = if force then file else file.gsub(/\..*?$/, '') + '.xlg' end
+ begin
+ if f = File.open(result,'w') then
+ f << data
+ f.close
+ end
+ rescue
+ report("unable to open file '#{result}'")
+ end
+ else
+ report("invalid xml file '#{file}'")
+ end
+ else
+ report("unable to load file '#{file}'")
+ end
+ else
+ report("unknown file '#{file}'")
+ end
+
+ end
+
+ def doxmlreport(str,verbose=false)
+ if verbose then
+ result = str
+ report(result)
+ return result
+ else
+ return str
+ end
+ end
+
+ def doxmlcleanup(data="",verbose=false)
+
+ # remove funny spaces (looks cleaner)
+ #
+ # data = "<whatever ></whatever ><whatever />"
+
+ data.gsub!(/\<(\/*\w+)\s*(\/*)>/o) do
+ "<#{$1}#{$2}>"
+ end
+
+ # remove funny ampersands
+ #
+ # data = "<x> B&W </x>"
+
+ data.gsub!(/\&([^\<\>\&]*?)\;/mo) do
+ "<entity name='#{$1}'/>"
+ end
+ data.gsub!(/\&/o) do
+ doxmlreport("&amp;",verbose)
+ end
+ data.gsub!(/\<entity name=\'(.*?)\'\/\>/o) do
+ doxmlreport("&#{$1};",verbose)
+ end
+
+ # remove funny < >
+ #
+ # data = "<x> < 5% </x>"
+
+ data.gsub!(/<([^>].*?)>/o) do
+ tag = $1
+ case tag
+ when /^\//o then
+ "<#{tag}>" # funny tag but ok
+ when /\/$/o then
+ "<#{tag}>" # funny tag but ok
+ when /</o then
+ doxmlreport("&lt;#{tag}>",verbose)
+ else
+ "<#{tag}>"
+ end
+ end
+
+ # remove funny < >
+ #
+ # data = "<x> > 5% </x>"
+
+ data.gsub!(/<([^>].*?)>([^\>\<]*?)>/o) do
+ doxmlreport("<#{$1}>#{$2}&gt;",verbose)
+ end
+
+ return data
+ end
+
+ # puts doxmlcleanup("<whatever ></whatever ><whatever />")
+ # puts doxmlcleanup("<x> B&W </x>")
+ # puts doxmlcleanup("<x> < 5% </x>")
+ # puts doxmlcleanup("<x> > 5% </x>")
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('dir', 'generate directory listing')
+commandline.registeraction('mmlpages','generate graphic from mathml')
+commandline.registeraction('analyze', 'report entities and elements [--utf --process]')
+commandline.registeraction('cleanup', 'cleanup xml file [--force]')
+commandline.registeraction('enhance', 'enhance xml file (partial)')
+commandline.registeraction('filter', 'filter elements from xml file [element=]')
+
+# commandline.registeraction('dir', 'filename --pattern= --output= [--recurse --stripname --longname --url --root]')
+# commandline.registeraction('mmlpages','filename [--eps --jpg --png --style= --mode=]')
+
+commandline.registeraction('ls')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registerflag('stripname')
+commandline.registerflag('longname')
+commandline.registerflag('recurse')
+commandline.registerflag('verbose')
+
+commandline.registervalue('pattern')
+commandline.registervalue('element')
+commandline.registervalue('url')
+commandline.registervalue('output')
+commandline.registervalue('root')
+
+commandline.registerflag('eps')
+commandline.registerflag('png')
+commandline.registerflag('jpg')
+commandline.registerflag('utf')
+commandline.registerflag('process')
+commandline.registervalue('style')
+commandline.registervalue('modes')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/Master/texmf-dist/scripts/context/stubs-mkiv/unix/contextjit b/Master/texmf-dist/scripts/context/stubs-mkiv/unix/contextjit
new file mode 100755
index 00000000000..d1374801b2e
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs-mkiv/unix/contextjit
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+luajittex --luaonly `kpsewhich mtxrun.lua` --script context "$@"
diff --git a/Master/texmf-dist/scripts/context/stubs-mkiv/unix/luatools b/Master/texmf-dist/scripts/context/stubs-mkiv/unix/luatools
new file mode 100755
index 00000000000..c17b483be53
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs-mkiv/unix/luatools
@@ -0,0 +1,2 @@
+#!/bin/sh
+mtxrun --script base "$@"
diff --git a/Master/texmf-dist/scripts/context/stubs-mkiv/unix/mtxrunjit b/Master/texmf-dist/scripts/context/stubs-mkiv/unix/mtxrunjit
new file mode 100755
index 00000000000..06cd8a8acbb
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs-mkiv/unix/mtxrunjit
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+luajittex --luaonly `kpsewhich mtxrun.lua` "$@"
diff --git a/Master/texmf-dist/scripts/context/stubs-mkiv/win64/contextjit.cmd b/Master/texmf-dist/scripts/context/stubs-mkiv/win64/contextjit.cmd
new file mode 100755
index 00000000000..83cb10f44d3
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs-mkiv/win64/contextjit.cmd
@@ -0,0 +1,4 @@
+@echo off
+
+for /f "usebackq tokens=*" %%M in (`kpsewhich mtxrun.lua`) do set MTX=%%M
+luajittex --luaonly %MTX% --script context %*
diff --git a/Master/texmf-dist/scripts/context/stubs-mkiv/win64/luatools.cmd b/Master/texmf-dist/scripts/context/stubs-mkiv/win64/luatools.cmd
new file mode 100755
index 00000000000..a20c7e0c901
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs-mkiv/win64/luatools.cmd
@@ -0,0 +1,2 @@
+@echo off
+mtxrun --script base %*
diff --git a/Master/texmf-dist/scripts/context/stubs-mkiv/win64/mtxrunjit.cmd b/Master/texmf-dist/scripts/context/stubs-mkiv/win64/mtxrunjit.cmd
new file mode 100755
index 00000000000..1ba91eef85f
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs-mkiv/win64/mtxrunjit.cmd
@@ -0,0 +1,4 @@
+@echo off
+
+for /f "usebackq tokens=*" %%M in (`kpsewhich mtxrun.lua`) do set MTX=%%M
+luajittex --luaonly %MTX% %*
diff --git a/Master/texmf-dist/scripts/context/stubs/unix/ctxtools b/Master/texmf-dist/scripts/context/stubs/unix/ctxtools
new file mode 100755
index 00000000000..048e0ff8561
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/unix/ctxtools
@@ -0,0 +1,2 @@
+#!/bin/sh
+mtxrun --script ctxtools --usekpse "$@"
diff --git a/Master/texmf-dist/scripts/context/stubs/unix/pstopdf b/Master/texmf-dist/scripts/context/stubs/unix/pstopdf
new file mode 100755
index 00000000000..116f5f4a32e
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/unix/pstopdf
@@ -0,0 +1,2 @@
+#!/bin/sh
+mtxrun --script pstopdf "$@"
diff --git a/Master/texmf-dist/scripts/context/stubs/unix/texexec b/Master/texmf-dist/scripts/context/stubs/unix/texexec
new file mode 100755
index 00000000000..083e500c69c
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/unix/texexec
@@ -0,0 +1,2 @@
+#!/bin/sh
+mtxrun --usekpse --execute texexec.rb "$@"
diff --git a/Master/texmf-dist/scripts/context/stubs/unix/texmfstart b/Master/texmf-dist/scripts/context/stubs/unix/texmfstart
new file mode 100755
index 00000000000..1799b357915
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/unix/texmfstart
@@ -0,0 +1,2 @@
+#!/bin/sh
+mtxrun --usekpse "$@"
diff --git a/Master/texmf-dist/scripts/context/stubs/win64/ctxtools.cmd b/Master/texmf-dist/scripts/context/stubs/win64/ctxtools.cmd
new file mode 100755
index 00000000000..ed7a9c561c4
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/win64/ctxtools.cmd
@@ -0,0 +1,2 @@
+@echo off
+mtxrun --script ctxtools %*
diff --git a/Master/texmf-dist/scripts/context/stubs/win64/pstopdf.cmd b/Master/texmf-dist/scripts/context/stubs/win64/pstopdf.cmd
new file mode 100755
index 00000000000..2296b6d9e6c
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/win64/pstopdf.cmd
@@ -0,0 +1,2 @@
+@echo off
+mtxrun --script pstopdf %*
diff --git a/Master/texmf-dist/scripts/context/stubs/win64/texexec.cmd b/Master/texmf-dist/scripts/context/stubs/win64/texexec.cmd
new file mode 100755
index 00000000000..0baa4cc5d57
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/win64/texexec.cmd
@@ -0,0 +1,2 @@
+@echo off
+mtxrun --usekpse --execute texexec.rb %*
diff --git a/Master/texmf-dist/scripts/context/stubs/win64/texmfstart.cmd b/Master/texmf-dist/scripts/context/stubs/win64/texmfstart.cmd
new file mode 100755
index 00000000000..12b243cbdda
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/stubs/win64/texmfstart.cmd
@@ -0,0 +1,2 @@
+@echo off
+mtxrun --usekpse %*